From 6cd6277714d0b7e7dd51fe09d953bbe05b82e20f Mon Sep 17 00:00:00 2001 From: akmubi Date: Fri, 28 Aug 2026 16:07:44 +0500 Subject: [PATCH 1/9] add FProperty helpers --- include/unreal.h | 403 ++++++++++++++++------- include/unreal_funcs.inc | 7 + src/signatures.c | 7 + src/unreal.c | 690 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 976 insertions(+), 131 deletions(-) diff --git a/include/unreal.h b/include/unreal.h index d6e63ed..e772b88 100644 --- a/include/unreal.h +++ b/include/unreal.h @@ -613,10 +613,10 @@ struct finput_key_event_args_s { float amount_depressed; bool is_touch_event; }; -STATIC_ASSERT(offsetof(finput_key_event_args_t, key) == 0x10, "invalid offset"); -STATIC_ASSERT(offsetof(finput_key_event_args_t, event) == 0x28, "invalid offset"); +STATIC_ASSERT(offsetof(finput_key_event_args_t, key) == 0x10, "invalid offset"); +STATIC_ASSERT(offsetof(finput_key_event_args_t, event) == 0x28, "invalid offset"); STATIC_ASSERT(offsetof(finput_key_event_args_t, amount_depressed) == 0x2C, "invalid offset"); -STATIC_ASSERT(offsetof(finput_key_event_args_t, is_touch_event) == 0x30, "invalid offset"); +STATIC_ASSERT(offsetof(finput_key_event_args_t, is_touch_event) == 0x30, "invalid offset"); typedef struct fvector2d_s fvector2d_t; struct fvector2d_s { @@ -659,11 +659,11 @@ struct finput_event_s { uint32_t user_idx; void *event_path; }; -STATIC_ASSERT(sizeof(finput_event_t) == 0x18, "size mismatch"); +STATIC_ASSERT(sizeof(finput_event_t) == 0x18, "size mismatch"); STATIC_ASSERT(offsetof(finput_event_t, modifier_keys) == 0x08, "invalid offset"); -STATIC_ASSERT(offsetof(finput_event_t, is_repeat) == 0x0A, "invalid offset"); -STATIC_ASSERT(offsetof(finput_event_t, user_idx) == 0x0C, "invalid offset"); -STATIC_ASSERT(offsetof(finput_event_t, event_path) == 0x10, "invalid offset"); +STATIC_ASSERT(offsetof(finput_event_t, is_repeat) == 0x0A, "invalid offset"); +STATIC_ASSERT(offsetof(finput_event_t, user_idx) == 0x0C, "invalid offset"); +STATIC_ASSERT(offsetof(finput_event_t, event_path) == 0x10, "invalid offset"); typedef struct fkey_event_s fkey_event_t; struct fkey_event_s { @@ -672,10 +672,10 @@ struct fkey_event_s { uint32_t character_code; uint32_t key_code; }; -STATIC_ASSERT(sizeof(fkey_event_t) == 0x38, "size mismatch"); -STATIC_ASSERT(offsetof(fkey_event_t, key) == 0x18, "invalid offset"); +STATIC_ASSERT(sizeof(fkey_event_t) == 0x38, "size mismatch"); +STATIC_ASSERT(offsetof(fkey_event_t, key) == 0x18, "invalid offset"); STATIC_ASSERT(offsetof(fkey_event_t, character_code) == 0x30, "invalid offset"); -STATIC_ASSERT(offsetof(fkey_event_t, key_code) == 0x34, "invalid offset"); +STATIC_ASSERT(offsetof(fkey_event_t, key_code) == 0x34, "invalid offset"); typedef struct fanalog_input_event_s fanalog_input_event_t; struct fanalog_input_event_s { @@ -683,7 +683,7 @@ struct fanalog_input_event_s { float analog_value; uint8_t _pad0[4]; }; -STATIC_ASSERT(sizeof(fanalog_input_event_t) == 0x40, "size mismatch"); +STATIC_ASSERT(sizeof(fanalog_input_event_t) == 0x40, "size mismatch"); STATIC_ASSERT(offsetof(fanalog_input_event_t, analog_value) == 0x38, "invalid offset"); typedef struct fcharacter_event_s fcharacter_event_t; @@ -692,7 +692,7 @@ struct fcharacter_event_s { uint16_t character; uint8_t _pad0[6]; }; -STATIC_ASSERT(sizeof(fcharacter_event_t) == 0x20, "size mismatch"); +STATIC_ASSERT(sizeof(fcharacter_event_t) == 0x20, "size mismatch"); STATIC_ASSERT(offsetof(fcharacter_event_t, character) == 0x18, "invalid offset"); typedef struct fpointer_event_s fpointer_event_t; @@ -715,21 +715,21 @@ struct fpointer_event_s { bool is_touch_first_move; uint8_t _pad1[5]; }; -STATIC_ASSERT(sizeof(fpointer_event_t) == 0x70, "size mismatch"); -STATIC_ASSERT(offsetof(fpointer_event_t, screen_space_pos) == 0x18, "invalid offset"); -STATIC_ASSERT(offsetof(fpointer_event_t, last_screen_space_pos) == 0x20, "invalid offset"); -STATIC_ASSERT(offsetof(fpointer_event_t, cursor_delta) == 0x28, "invalid offset"); -STATIC_ASSERT(offsetof(fpointer_event_t, pressed_buttons) == 0x30, "invalid offset"); -STATIC_ASSERT(offsetof(fpointer_event_t, effecting_button) == 0x38, "invalid offset"); -STATIC_ASSERT(offsetof(fpointer_event_t, pointer_idx) == 0x50, "invalid offset"); -STATIC_ASSERT(offsetof(fpointer_event_t, touchpad_idx) == 0x54, "invalid offset"); -STATIC_ASSERT(offsetof(fpointer_event_t, force) == 0x58, "invalid offset"); -STATIC_ASSERT(offsetof(fpointer_event_t, is_touch_event) == 0x5C, "invalid offset"); -STATIC_ASSERT(offsetof(fpointer_event_t, gesture_type) == 0x5D, "invalid offset"); -STATIC_ASSERT(offsetof(fpointer_event_t, wheel_or_gesture_delta) == 0x60, "invalid offset"); +STATIC_ASSERT(sizeof(fpointer_event_t) == 0x70, "size mismatch"); +STATIC_ASSERT(offsetof(fpointer_event_t, screen_space_pos) == 0x18, "invalid offset"); +STATIC_ASSERT(offsetof(fpointer_event_t, last_screen_space_pos) == 0x20, "invalid offset"); +STATIC_ASSERT(offsetof(fpointer_event_t, cursor_delta) == 0x28, "invalid offset"); +STATIC_ASSERT(offsetof(fpointer_event_t, pressed_buttons) == 0x30, "invalid offset"); +STATIC_ASSERT(offsetof(fpointer_event_t, effecting_button) == 0x38, "invalid offset"); +STATIC_ASSERT(offsetof(fpointer_event_t, pointer_idx) == 0x50, "invalid offset"); +STATIC_ASSERT(offsetof(fpointer_event_t, touchpad_idx) == 0x54, "invalid offset"); +STATIC_ASSERT(offsetof(fpointer_event_t, force) == 0x58, "invalid offset"); +STATIC_ASSERT(offsetof(fpointer_event_t, is_touch_event) == 0x5C, "invalid offset"); +STATIC_ASSERT(offsetof(fpointer_event_t, gesture_type) == 0x5D, "invalid offset"); +STATIC_ASSERT(offsetof(fpointer_event_t, wheel_or_gesture_delta) == 0x60, "invalid offset"); STATIC_ASSERT(offsetof(fpointer_event_t, is_direction_inverted_from_device) == 0x68, "invalid offset"); -STATIC_ASSERT(offsetof(fpointer_event_t, is_touch_force_changed) == 0x69, "invalid offset"); -STATIC_ASSERT(offsetof(fpointer_event_t, is_touch_first_move) == 0x6A, "invalid offset"); +STATIC_ASSERT(offsetof(fpointer_event_t, is_touch_force_changed) == 0x69, "invalid offset"); +STATIC_ASSERT(offsetof(fpointer_event_t, is_touch_first_move) == 0x6A, "invalid offset"); typedef struct fname_entry_header_s fname_entry_header_t; struct fname_entry_header_s { @@ -1323,15 +1323,15 @@ struct fprop_s { struct fprop_s *post_ctor_link_next; }; -STATIC_ASSERT(offsetof(fprop_t, array_dim) == 0x38, "invalid offset"); -STATIC_ASSERT(offsetof(fprop_t, elem_size) == 0x3C, "invalid offset"); -STATIC_ASSERT(offsetof(fprop_t, prop_flags) == 0x40, "invalid offset"); -STATIC_ASSERT(offsetof(fprop_t, rep_idx) == 0x48, "invalid offset"); -STATIC_ASSERT(offsetof(fprop_t, offset_internal) == 0x4C, "invalid offset"); -STATIC_ASSERT(offsetof(fprop_t, rep_notify_func) == 0x50, "invalid offset"); -STATIC_ASSERT(offsetof(fprop_t, prop_link_next) == 0x58, "invalid offset"); -STATIC_ASSERT(offsetof(fprop_t, next_ref) == 0x60, "invalid offset"); -STATIC_ASSERT(offsetof(fprop_t, dtor_link_next) == 0x68, "invalid offset"); +STATIC_ASSERT(offsetof(fprop_t, array_dim) == 0x38, "invalid offset"); +STATIC_ASSERT(offsetof(fprop_t, elem_size) == 0x3C, "invalid offset"); +STATIC_ASSERT(offsetof(fprop_t, prop_flags) == 0x40, "invalid offset"); +STATIC_ASSERT(offsetof(fprop_t, rep_idx) == 0x48, "invalid offset"); +STATIC_ASSERT(offsetof(fprop_t, offset_internal) == 0x4C, "invalid offset"); +STATIC_ASSERT(offsetof(fprop_t, rep_notify_func) == 0x50, "invalid offset"); +STATIC_ASSERT(offsetof(fprop_t, prop_link_next) == 0x58, "invalid offset"); +STATIC_ASSERT(offsetof(fprop_t, next_ref) == 0x60, "invalid offset"); +STATIC_ASSERT(offsetof(fprop_t, dtor_link_next) == 0x68, "invalid offset"); STATIC_ASSERT(offsetof(fprop_t, post_ctor_link_next) == 0x70, "invalid offset"); /* ByteProperty */ @@ -1406,15 +1406,96 @@ struct fprop_bool_s { uint8_t byte_mask; uint8_t field_mask; }; -STATIC_ASSERT(offsetof(fprop_bool_t, field_size) == 0x78, "invalid offset"); +STATIC_ASSERT(offsetof(fprop_bool_t, field_size) == 0x78, "invalid offset"); STATIC_ASSERT(offsetof(fprop_bool_t, byte_offset) == 0x79, "invalid offset"); -STATIC_ASSERT(offsetof(fprop_bool_t, byte_mask) == 0x7a, "invalid offset"); -STATIC_ASSERT(offsetof(fprop_bool_t, field_mask) == 0x7b, "invalid offset"); +STATIC_ASSERT(offsetof(fprop_bool_t, byte_mask) == 0x7a, "invalid offset"); +STATIC_ASSERT(offsetof(fprop_bool_t, field_mask) == 0x7b, "invalid offset"); -/* ObjectPropertyBase */ typedef struct fprop_obj_base_s fprop_obj_base_t; + +typedef fstring_t (__fastcall *fprop_obj_get_cpp_type_custom_fn_t) (fprop_obj_base_t *, fstring_t *extended_type_text, uint32_t cpp_export_flags, const fstring_t *inner_native_type_name); +typedef uobject_t *(__fastcall *fprop_obj_load_object_prop_value_fn_t)(fprop_obj_base_t *, const void *prop_value_addr); +typedef uobject_t *(__fastcall *fprop_obj_get_object_prop_value_fn_t) (fprop_obj_base_t *, const void *prop_value_addr); +typedef void (__fastcall *fprop_obj_set_object_prop_value_fn_t) (fprop_obj_base_t *, void* prop_value_addr, uobject_t *value); +typedef bool (__fastcall *fprop_obj_allow_cross_level_fn_t) (fprop_obj_base_t *); +typedef void (__fastcall *fprop_obj_check_valid_object_fn_t) (fprop_obj_base_t *, void *value); + +typedef struct fprop_obj_base_vtable_s fprop_obj_base_vtable_t; +struct fprop_obj_base_vtable_s { + ffield_destructor_fn_t destructor; + ffield_serialize_fn_t serialize; + ffield_post_load_fn_t post_load; + ffield_get_preload_deps_fn_t get_preload_deps; + ffield_begin_destroy_fn_t begin_destroy; + ffield_add_referenced_objs_fn_t add_referenced_objs; + ffield_add_cpp_prop_fn_t add_cpp_prop; + ffield_bind_fn_t bind; + ffield_post_duplicate_fn_t post_duplicate; + ffield_get_inner_field_by_name_fn_t get_inner_field_by_name; + ffield_get_inner_fields_fn_t get_inner_fields; + fprop_get_cpp_macro_type_fn_t get_cpp_macro_type; + fprop_pass_cpp_args_by_ref_fn_t pass_cpp_args_by_ref; + fprop_get_cpp_type_fn_t get_cpp_type; + fprop_get_cpp_type_forward_declaration_fn_t get_cpp_type_forward_declaration; + fprop_link_internal_fn_t link_internal; + fprop_convert_from_type_fn_t convert_from_type; + fprop_identical_fn_t identical; + fprop_serialize_item_fn_t serialize_item; + fprop_netserialize_item_fn_t netserialize_item; + fprop_supports_net_shared_serialization_fn_t supports_net_shared_serialization; + fprop_export_text_item_fn_t export_text_item; + fprop_import_text_internal_fn_t import_text_internal; + fprop_copy_values_internal_fn_t copy_values_internal; + fprop_get_value_type_hash_internal_fn_t get_value_type_hash_internal; + fprop_copy_single_value_to_script_vm_fn_t copy_single_value_to_script_vm; + fprop_copy_complete_value_to_script_vm_fn_t copy_complete_value_to_script_vm; + fprop_copy_single_value_from_script_vm_fn_t copy_single_value_from_script_vm; + fprop_copy_complete_value_from_script_vm_fn_t copy_complete_value_from_script_vm; + fprop_clear_value_internal_fn_t clear_value_internal; + fprop_destroy_value_internal_fn_t destroy_value_internal; + fprop_initialize_value_internal_fn_t initialize_value_internal; + fprop_get_id_fn_t get_id; + fprop_instance_subobjects_fn_t instance_subobjects; + fprop_get_min_alignment_fn_t get_min_alignment; + fprop_contains_object_reference_fn_t contains_object_reference; + fprop_emit_reference_info_fn_t emit_reference_info; + fprop_same_type_fn_t same_type; + fprop_obj_get_cpp_type_custom_fn_t get_cpp_type_custom; + fprop_obj_load_object_prop_value_fn_t load_object_prop_value; + fprop_obj_get_object_prop_value_fn_t get_object_prop_value; + fprop_obj_set_object_prop_value_fn_t set_object_prop_value; + fprop_obj_allow_cross_level_fn_t allow_cross_level; + fprop_obj_check_valid_object_fn_t check_valid_object; +}; +STATIC_ASSERT(offsetof(fprop_obj_base_vtable_t, load_object_prop_value) == 0x138, "invalid offset"); +STATIC_ASSERT(offsetof(fprop_obj_base_vtable_t, get_object_prop_value) == 0x140, "invalid offset"); +STATIC_ASSERT(offsetof(fprop_obj_base_vtable_t, set_object_prop_value) == 0x148, "invalid offset"); +STATIC_ASSERT(sizeof(fprop_obj_base_vtable_t) == 0x160, "size mismatch"); + struct fprop_obj_base_s { - fprop_t base; + /* ffield_t */ + fprop_obj_base_vtable_t *vtable; + ffield_class_t *cls; + ffield_variant_t owner; + struct ffield_s *next; + fname_t name; + uint32_t flags; + uint32_t pad; + + /* fprop_t */ + int32_t array_dim; + int32_t elem_size; + eprop_flags_t prop_flags; + uint16_t rep_idx; + uint8_t bp_rep_cond; + int32_t offset_internal; + fname_t rep_notify_func; + struct fprop_s *prop_link_next; + struct fprop_s *next_ref; + struct fprop_s *dtor_link_next; + struct fprop_s *post_ctor_link_next; + + /* fprop_obj_base_t */ struct uclass_s *prop_class; }; STATIC_ASSERT(offsetof(fprop_obj_base_t, prop_class) == 0x78, "invalid offset"); @@ -1492,9 +1573,39 @@ struct fprop_array_s { fprop_t *inner; earray_prop_flags_t array_flags; }; -STATIC_ASSERT(offsetof(fprop_array_t, inner) == 0x78, "invalid offset"); +STATIC_ASSERT(offsetof(fprop_array_t, inner) == 0x78, "invalid offset"); STATIC_ASSERT(offsetof(fprop_array_t, array_flags) == 0x80, "invalid offset"); +/* Non-owning views of UE 4.27's heap-backed FScript containers. Mutation must + * still go through FProperty/FScript helper operations so element lifetimes + * and set/map hashes remain valid. */ +typedef TARRAY(void) fscript_array_t; + +typedef struct fscript_sparse_array_s fscript_sparse_array_t; +struct fscript_sparse_array_s { + fscript_array_t data; + tbit_array_t alloc_flags; + int32_t first_free_idx; + int32_t num_free_idx; +}; + +typedef struct fscript_set_s fscript_set_t; +struct fscript_set_s { + fscript_sparse_array_t elems; + hash_allocator_t hash; + int32_t hash_size; +}; + +typedef struct fscript_map_s fscript_map_t; +struct fscript_map_s { + fscript_set_t pairs; +}; + +STATIC_ASSERT(sizeof(fscript_array_t) == 0x10, "size mismatch"); +STATIC_ASSERT(sizeof(fscript_sparse_array_t) == 0x38, "size mismatch"); +STATIC_ASSERT(sizeof(fscript_set_t) == 0x50, "size mismatch"); +STATIC_ASSERT(sizeof(fscript_map_t) == 0x50, "size mismatch"); + typedef uint32_t emap_prop_flags_t; enum { EMPF_NONE, @@ -1515,6 +1626,18 @@ struct fscript_set_layout_s { fscript_sparse_array_layout_t sparse_array_layout; }; +typedef struct fscript_set_helper_s fscript_set_helper_t; +struct fscript_set_helper_s { + fprop_t *elem_prop; + void *set; + fscript_set_layout_t layout; + uint32_t pad; +}; +STATIC_ASSERT(offsetof(fscript_set_helper_t, elem_prop) == 0x00, "invalid offset"); +STATIC_ASSERT(offsetof(fscript_set_helper_t, set) == 0x08, "invalid offset"); +STATIC_ASSERT(offsetof(fscript_set_helper_t, layout) == 0x10, "invalid offset"); +STATIC_ASSERT(sizeof(fscript_set_helper_t) == 0x28, "size mismatch"); + typedef struct fscript_map_layout_s fscript_map_layout_t; struct fscript_map_layout_s { int32_t value_offset; @@ -1576,7 +1699,7 @@ struct fprop_set_s { fprop_t *elem_prop; fscript_set_layout_t set_layout; }; -STATIC_ASSERT(offsetof(fprop_set_t, elem_prop) == 0x78, "invalid offset"); +STATIC_ASSERT(offsetof(fprop_set_t, elem_prop) == 0x78, "invalid offset"); STATIC_ASSERT(offsetof(fprop_set_t, set_layout) == 0x80, "invalid offset"); /* StructProperty */ @@ -1633,7 +1756,7 @@ struct fprop_enum_s { struct uenum_s *uenum; }; STATIC_ASSERT(offsetof(fprop_enum_t, underlying_prop) == 0x78, "invalid offset"); -STATIC_ASSERT(offsetof(fprop_enum_t, uenum) == 0x80, "invalid offset"); +STATIC_ASSERT(offsetof(fprop_enum_t, uenum) == 0x80, "invalid offset"); /* FieldPathProperty */ typedef struct fprop_field_path_s fprop_field_path_t; @@ -1846,7 +1969,7 @@ struct icpp_struct_ops_s { int32_t size; int32_t alignment; }; -STATIC_ASSERT(offsetof(icpp_struct_ops_t, size) == 0x08, "invalid offset"); +STATIC_ASSERT(offsetof(icpp_struct_ops_t, size) == 0x08, "invalid offset"); STATIC_ASSERT(offsetof(icpp_struct_ops_t, alignment) == 0x0c, "invalid offset"); typedef struct uscript_struct_s uscript_struct_t; @@ -1880,9 +2003,9 @@ struct uscript_struct_s { bool prep_cpp_struct_ops_completed; icpp_struct_ops_t *cpp_struct_ops; }; -STATIC_ASSERT(offsetof(uscript_struct_t, struct_flags) == 0xb0, "invalid offset"); +STATIC_ASSERT(offsetof(uscript_struct_t, struct_flags) == 0xb0, "invalid offset"); STATIC_ASSERT(offsetof(uscript_struct_t, prep_cpp_struct_ops_completed) == 0xb4, "invalid offset"); -STATIC_ASSERT(offsetof(uscript_struct_t, cpp_struct_ops) == 0xb8, "invalid offset"); +STATIC_ASSERT(offsetof(uscript_struct_t, cpp_struct_ops) == 0xb8, "invalid offset"); typedef struct ufunc_s ufunc_t; struct ufunc_s { @@ -2466,18 +2589,18 @@ struct fframe_s { ufunc_t *current_native_func; uint8_t array_ctx_failed; }; -STATIC_ASSERT(offsetof(fframe_t, node) == 0x10, "invalid offset"); -STATIC_ASSERT(offsetof(fframe_t, obj) == 0x18, "invalid offset"); -STATIC_ASSERT(offsetof(fframe_t, code) == 0x20, "invalid offset"); -STATIC_ASSERT(offsetof(fframe_t, locals) == 0x28, "invalid offset"); -STATIC_ASSERT(offsetof(fframe_t, most_recent_prop) == 0x30, "invalid offset"); -STATIC_ASSERT(offsetof(fframe_t, most_recent_prop_addr) == 0x38, "invalid offset"); -STATIC_ASSERT(offsetof(fframe_t, flow_stack) == 0x40, "invalid offset"); -STATIC_ASSERT(offsetof(fframe_t, prev_frame) == 0x70, "invalid offset"); -STATIC_ASSERT(offsetof(fframe_t, out_params) == 0x78, "invalid offset"); +STATIC_ASSERT(offsetof(fframe_t, node) == 0x10, "invalid offset"); +STATIC_ASSERT(offsetof(fframe_t, obj) == 0x18, "invalid offset"); +STATIC_ASSERT(offsetof(fframe_t, code) == 0x20, "invalid offset"); +STATIC_ASSERT(offsetof(fframe_t, locals) == 0x28, "invalid offset"); +STATIC_ASSERT(offsetof(fframe_t, most_recent_prop) == 0x30, "invalid offset"); +STATIC_ASSERT(offsetof(fframe_t, most_recent_prop_addr) == 0x38, "invalid offset"); +STATIC_ASSERT(offsetof(fframe_t, flow_stack) == 0x40, "invalid offset"); +STATIC_ASSERT(offsetof(fframe_t, prev_frame) == 0x70, "invalid offset"); +STATIC_ASSERT(offsetof(fframe_t, out_params) == 0x78, "invalid offset"); STATIC_ASSERT(offsetof(fframe_t, prop_chain_for_compiled_in) == 0x80, "invalid offset"); -STATIC_ASSERT(offsetof(fframe_t, current_native_func) == 0x88, "invalid offset"); -STATIC_ASSERT(offsetof(fframe_t, array_ctx_failed) == 0x90, "invalid offset"); +STATIC_ASSERT(offsetof(fframe_t, current_native_func) == 0x88, "invalid offset"); +STATIC_ASSERT(offsetof(fframe_t, array_ctx_failed) == 0x90, "invalid offset"); typedef void(__fastcall *fnative_func_ptr_t)(uobject_t *context, fframe_t *stack, void *result); @@ -2725,11 +2848,11 @@ struct begin_actor_spawn_s { void *owner; void *return_value; }; -STATIC_ASSERT(offsetof(begin_actor_spawn_params_t, actor_class) == 8, "invalid offset"); -STATIC_ASSERT(offsetof(begin_actor_spawn_params_t, spawn_transform) == 16, "invalid offset"); +STATIC_ASSERT(offsetof(begin_actor_spawn_params_t, actor_class) == 8, "invalid offset"); +STATIC_ASSERT(offsetof(begin_actor_spawn_params_t, spawn_transform) == 16, "invalid offset"); STATIC_ASSERT(offsetof(begin_actor_spawn_params_t, collision_handling_override) == 64, "invalid offset"); -STATIC_ASSERT(offsetof(begin_actor_spawn_params_t, owner) == 72, "invalid offset"); -STATIC_ASSERT(offsetof(begin_actor_spawn_params_t, return_value) == 80, "invalid offset"); +STATIC_ASSERT(offsetof(begin_actor_spawn_params_t, owner) == 72, "invalid offset"); +STATIC_ASSERT(offsetof(begin_actor_spawn_params_t, return_value) == 80, "invalid offset"); typedef struct finish_actor_spawn_s finish_actor_spawn_params_t; struct finish_actor_spawn_s { @@ -3194,70 +3317,69 @@ unreal_uprop_ptr(fprop_t *prop, void *container) return (uint8_t *)container + prop->offset_internal; } -static inline bool -unreal_uprop_get_bool(fprop_bool_t *prop, void *container) -{ - uint8_t *byte = (uint8_t *)container + prop->base.offset_internal + prop->byte_offset; - return (*byte & prop->field_mask) != 0; -} - -static inline void -unreal_uprop_set_bool(fprop_bool_t *prop, void *container, bool val) -{ - uint8_t *byte = (uint8_t *)container + prop->base.offset_internal + prop->byte_offset; - if (val) { - *byte |= prop->field_mask; - } else { - *byte &= ~prop->field_mask; - } -} - -static inline fname_t -unreal_uprop_get_fname(fprop_t *prop, void *container) -{ - return *(fname_t *)unreal_uprop_ptr(prop, container); -} - -static inline void -unreal_uprop_set_fname(fprop_t *prop, void *container, fname_t val) -{ - *(fname_t *)unreal_uprop_ptr(prop, container) = val; -} +bool +unreal_fprop_class_is(fprop_t *prop, fname_t name); +bool +unreal_fprop_class_is_a(fprop_t *prop, fname_t name); +str_t +unreal_fprop_push_type_name(fprop_t *prop, arena_t *arena); -static inline fstring_t -unreal_uprop_get_fstr(fprop_t *prop, void *container) -{ - return *(fstring_t *)unreal_uprop_ptr(prop, container); -} +uint64_t +unreal_fprop_complete_size(fprop_t *prop); +int32_t +unreal_fprop_min_alignment(fprop_t *prop); +void * +unreal_fprop_value_at(fprop_t *prop, void *value, int32_t array_idx); +void * +unreal_fprop_value_in_container(fprop_t *prop, void *container, int32_t array_idx); -static inline uobject_t * -unreal_uprop_get_obj(fprop_t *prop, void *container) -{ - return *(uobject_t **)unreal_uprop_ptr(prop, container); -} +bool +unreal_fprop_initialize_value(fprop_t *prop, void *value); +bool +unreal_fprop_destroy_value(fprop_t *prop, void *value); +bool +unreal_fprop_clear_single_value(fprop_t *prop, void *value); +bool +unreal_fprop_clear_complete_value(fprop_t *prop, void *value); +bool +unreal_fprop_copy_single_value(fprop_t *prop, void *dst, const void *src); +bool +unreal_fprop_copy_complete_value(fprop_t *prop, void *dst, const void *src); -static inline void -unreal_uprop_set_obj(fprop_t *prop, void *container, uobject_t *val) -{ - *(uobject_t **)unreal_uprop_ptr(prop, container) = val; -} +bool +unreal_fprop_copy_single_value_to_script_vm(fprop_t *prop, void *dst, const void *src); +bool +unreal_fprop_copy_complete_value_to_script_vm(fprop_t *prop, void *dst, const void *src); +bool +unreal_fprop_copy_single_value_from_script_vm(fprop_t *prop, void *dst, const void *src); +bool +unreal_fprop_copy_complete_value_from_script_vm(fprop_t *prop, void *dst, const void *src); +bool +unreal_fprop_single_values_identical(fprop_t *prop, const void *a, const void *b, uint32_t port_flags); +bool +unreal_fprop_complete_values_identical(fprop_t *prop, const void *a, const void *b, uint32_t port_flags); +bool +unreal_fprop_value_hash(fprop_t *prop, const void *value, uint32_t *out_hash); +bool +unreal_fprop_same_type(fprop_t *prop, fprop_t *other); +uobject_t * +unreal_fprop_get_object(fprop_obj_base_t *prop, const void *value); bool -unreal_fprop_class_is(fprop_t *prop, fname_t name); -str_t -unreal_fprop_push_type_name(fprop_t *prop, arena_t *arena); +unreal_fprop_object_is_compatible(fprop_obj_base_t *prop, uobject_t *object); +bool +unreal_fprop_set_object(fprop_obj_base_t *prop, void *value, uobject_t *object); -/* FProperty value lifecycle helpers. `container` is the owner buffer, not the - * address of the property value. These cover the property's complete static - * array dimension. */ void unreal_fprop_initialize_in_container(fprop_t *prop, void *container); void unreal_fprop_destroy_in_container(fprop_t *prop, void *container); -/* Imports one direct property value. `value` points at the property value, - * rather than its containing struct. The returned pointer is inside `text`, or - * NULL when Unreal rejected the input. */ +bool +unreal_ustruct_initialize_struct(ustruct_t *struct_type, void *memory, int32_t array_dim); +bool +unreal_ustruct_destroy_struct(ustruct_t *struct_type, void *memory, int32_t array_dim); + const wchar_t * unreal_fprop_import_text_direct(fprop_t *prop, const wchar_t *text, void *value, uobject_t *owner); @@ -3270,6 +3392,59 @@ unreal_tbit_array_find_next_set(tbit_array_t *bits, int32_t start_idx); int32_t unreal_tset_hash_head(hash_allocator_t *hash, int32_t hash_size, uint32_t key_hash); +int32_t +unreal_array_num(const void *array, fprop_array_t *prop); +void * +unreal_array_get(void *array, fprop_array_t *prop, int32_t idx); +int32_t +unreal_array_add(void *array, fprop_array_t *prop, const void *value); +void +unreal_array_insert(void *array, fprop_array_t *prop, int32_t idx, const void *value); +void +unreal_array_remove(void *array, fprop_array_t *prop, int32_t idx); +void +unreal_array_resize(void *array, fprop_array_t *prop, int32_t size); +void +unreal_array_set(void *array, fprop_array_t *prop, int32_t idx, const void *value, bool size_to_fit); +bool +unreal_array_clear(void *array, fprop_array_t *prop); + +int32_t +unreal_set_num(const void *set, fprop_set_t *prop); +int32_t +unreal_set_max_index(const void *set, fprop_set_t *prop); +bool +unreal_set_is_valid_index(const void *set, fprop_set_t *prop, int32_t idx); +const void * +unreal_set_get(const void *set, fprop_set_t *prop, int32_t idx); +int32_t +unreal_set_find_index(const void *set, fprop_set_t *prop, const void *value); +bool +unreal_set_contains(const void *set, fprop_set_t *prop, const void *value); +void +unreal_set_add(void *set, fprop_set_t *prop, const void *value); +bool +unreal_set_remove(void *set, fprop_set_t *prop, const void *value); +bool +unreal_set_clear(void *set, fprop_set_t *prop); + +int32_t +unreal_map_num(const void *map, fprop_map_t *prop); +int32_t +unreal_map_max_index(const void *map, fprop_map_t *prop); +bool +unreal_map_is_valid_index(const void *map, fprop_map_t *prop, int32_t idx); +const void * +unreal_map_get_key(const void *map, fprop_map_t *prop, int32_t idx); +void * +unreal_map_get_value(void *map, fprop_map_t *prop, int32_t idx); +int32_t +unreal_map_find_index(const void *map, fprop_map_t *prop, const void *key); +void * +unreal_map_find_value_ptr(void *map, fprop_map_t *prop, const void *key); +bool +unreal_map_clear(void *map, fprop_map_t *prop); + void unreal_map_add(void *map, fprop_map_t *prop, const void *key, const void *val); bool diff --git a/include/unreal_funcs.inc b/include/unreal_funcs.inc index d286ee7..04df2d1 100644 --- a/include/unreal_funcs.inc +++ b/include/unreal_funcs.inc @@ -20,6 +20,13 @@ UE_FUNC_NORMAL(generic_map_find, bool, void *map, fprop_map_t *map_prop, const v UE_FUNC_NORMAL(add_tag_table_row, void, ugameplay_tags_manager_t *self, fgameplay_tag_table_row_t *tag_row, fname_t source_name, bool is_restricted_tag) UE_FUNC_NORMAL(tmulticast_delegate_broadcast, void, tmulticast_delegate_t *self) UE_FUNC_NORMAL(request_gameplay_tag, fgameplay_tag_t *, ugameplay_tags_manager_t *self, fgameplay_tag_t *, fname_t tag_name, bool error_if_not_found); +UE_FUNC_NORMAL(generic_array_resize, void, void *target, fprop_array_t *prop, int32_t size); +UE_FUNC_NORMAL(generic_array_add, int32_t, void *target, fprop_array_t *prop, const void *new_item); +UE_FUNC_NORMAL(generic_array_insert, void, void *target, fprop_array_t *prop, const void *new_item, int32_t idx); +UE_FUNC_NORMAL(generic_array_remove, void, void *target, fprop_array_t *prop, int32_t idx); +UE_FUNC_NORMAL(generic_array_set, void, void *target, fprop_array_t *prop, int32_t idx, const void *new_item, bool size_to_fit); +UE_FUNC_NORMAL(fscript_set_add_elem, void, fscript_set_helper_t *helper, const void *item_ptr); +UE_FUNC_NORMAL(generic_set_remove, bool, void *target, fprop_set_t *prop, const void *item_ptr); #undef UE_FUNC_NORMAL diff --git a/src/signatures.c b/src/signatures.c index 0dce17b..f80d26d 100644 --- a/src/signatures.c +++ b/src/signatures.c @@ -137,6 +137,13 @@ static signature_t g_main_sigs[] = { SIG_ENTRY_NORMAL(DIRECT, add_tag_table_row, "48 8B C4 55 57 48 8D 68 ? 48 81 EC ? ? ? ? 48 89 58 ? 48 89 70 ? 4C 89 60 ? 4C 89 68 ? 4C 89 78", 0x03FC7410, 0x03DDDA60), SIG_ENTRY_NORMAL(DIRECT, tmulticast_delegate_broadcast, "40 56 48 83 EC ? FF 41 ? 48 8B F1 8B 49 ? 48 89 5C 24", 0x00E6BEA0, 0x00E1FD30), SIG_ENTRY_NORMAL(DIRECT, request_gameplay_tag, "40 53 55 56 57 48 83 EC ? 8B 81", 0x03FC8DC0, 0x03DDF410), + SIG_ENTRY_NORMAL(DIRECT, generic_array_resize, "48 85 C9 0F 84 ? ? ? ? 48 8B C4 44 89 40", 0x00000000, 0x00000000), + SIG_ENTRY_NORMAL(DIRECT, generic_array_add, "48 8B C4 4C 89 40 ? 53 48 83 EC ? 48 8B D9", 0x00000000, 0x00000000), + SIG_ENTRY_NORMAL(DIRECT, generic_array_insert, "48 85 C9 0F 84 ? ? ? ? 48 89 74 24 ? 57 48 83 EC ? 44 8B 92", 0x00000000, 0x00000000), + SIG_ENTRY_NORMAL(DIRECT, generic_array_remove, "48 85 C9 0F 84 ? ? ? ? 48 89 5C 24 ? 56 48 83 EC ? 4C 8B 4A", 0x00000000, 0x00000000), + SIG_ENTRY_NORMAL(DIRECT, generic_array_set, "48 85 C9 0F 84 ? ? ? ? 48 8B C4 4C 89 48 ? 53", 0x00000000, 0x00000000), + SIG_ENTRY_NORMAL(DIRECT, fscript_set_add_elem, "4C 8B DC 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 84 24 ? ? ? ? ? ? ? 4C 8D 41", 0x00000000, 0x00000000), + SIG_ENTRY_NORMAL(DIRECT, generic_set_remove, "4C 8B DC 49 89 5B ? 57 48 83 EC ? 49 8B F8", 0x00000000, 0x00000000), }; static signature_t g_input_sigs[] = { diff --git a/src/unreal.c b/src/unreal.c index a1ce032..5a73ac5 100644 --- a/src/unreal.c +++ b/src/unreal.c @@ -1414,6 +1414,17 @@ unreal_fprop_class_is(fprop_t *prop, fname_t name) return false; } +bool +unreal_fprop_class_is_a(fprop_t *prop, fname_t name) +{ + for (ffield_class_t *cls = prop ? prop->cls : NULL; cls; cls = cls->super_class) { + if (unreal_fname_equal(cls->name, name, false)) { + return true; + } + } + return false; +} + str_t unreal_fprop_push_type_name(fprop_t *prop, arena_t *arena) { @@ -1554,43 +1565,360 @@ unreal_fprop_push_type_name(fprop_t *prop, arena_t *arena) } -void -unreal_fprop_initialize_in_container(fprop_t *prop, void *container) +static bool +unreal_fprop_has_valid_layout(fprop_t *prop) { - if (!prop || !container || prop->elem_size <= 0 || prop->array_dim <= 0) { - return; + return prop && prop->elem_size > 0 && prop->array_dim > 0; +} + +uint64_t +unreal_fprop_complete_size(fprop_t *prop) +{ + if (!unreal_fprop_has_valid_layout(prop)) { + return 0; + } + return (uint64_t)prop->elem_size * (uint64_t)prop->array_dim; +} + +int32_t +unreal_fprop_min_alignment(fprop_t *prop) +{ + if (!unreal_fprop_has_valid_layout(prop) || !prop->vtable || !prop->vtable->get_min_alignment) { + return 0; + } + + int32_t alignment = prop->vtable->get_min_alignment(prop); + return alignment > 0 ? alignment : 0; +} + +void * +unreal_fprop_value_at(fprop_t *prop, void *value, int32_t array_idx) +{ + if (!unreal_fprop_has_valid_layout(prop) || !value || array_idx < 0 || array_idx >= prop->array_dim) { + return NULL; + } + return (uint8_t *)value + (uint64_t)array_idx * (uint64_t)prop->elem_size; +} + +void * +unreal_fprop_value_in_container(fprop_t *prop, void *container, int32_t array_idx) +{ + if (!prop || !container || prop->offset_internal < 0) { + return NULL; + } + return unreal_fprop_value_at(prop, (uint8_t *)container + prop->offset_internal, array_idx); +} + +bool +unreal_fprop_initialize_value(fprop_t *prop, void *value) +{ + uint64_t size = unreal_fprop_complete_size(prop); + if (size == 0 || !value) { + return false; } - uint8_t *value = (uint8_t *)container + prop->offset_internal; if (prop->prop_flags & CPF_ZERO_CONSTRUCTOR) { - mem_zero(value, (uint64_t)prop->elem_size * (uint64_t)prop->array_dim); - return; + mem_zero(value, size); + return true; } if (!prop->vtable || !prop->vtable->initialize_value_internal) { - return; + return false; + } + + prop->vtable->initialize_value_internal(prop, value); + return true; +} + +bool +unreal_fprop_destroy_value(fprop_t *prop, void *value) +{ + if (!unreal_fprop_has_valid_layout(prop) || !value) { + return false; + } + + if (prop->prop_flags & CPF_NO_DESTRUCTOR) { + return true; + } + + if (!prop->vtable || !prop->vtable->destroy_value_internal) { + return false; + } + + /* UE 4.27's virtual destroys the complete fixed ArrayDim itself. */ + prop->vtable->destroy_value_internal(prop, value); + return true; +} + +bool +unreal_fprop_clear_single_value(fprop_t *prop, void *value) +{ + if (!unreal_fprop_has_valid_layout(prop) || !value) { + return false; + } + + if ((prop->prop_flags & (CPF_NO_DESTRUCTOR | CPF_ZERO_CONSTRUCTOR)) == + (CPF_NO_DESTRUCTOR | CPF_ZERO_CONSTRUCTOR)) { + mem_zero(value, (uint64_t)prop->elem_size); + return true; + } + + if (!prop->vtable || !prop->vtable->clear_value_internal) { + return false; + } + + prop->vtable->clear_value_internal(prop, value); + return true; +} + +bool +unreal_fprop_clear_complete_value(fprop_t *prop, void *value) +{ + if (!unreal_fprop_has_valid_layout(prop) || !value) { + return false; + } + + for (int32_t i = 0; i < prop->array_dim; ++i) { + void *elem = unreal_fprop_value_at(prop, value, i); + if (!unreal_fprop_clear_single_value(prop, elem)) { + return false; + } + } + return true; +} + +bool +unreal_fprop_copy_single_value(fprop_t *prop, void *dst, const void *src) +{ + if (!unreal_fprop_has_valid_layout(prop) || !dst || !src) { + return false; + } + + if (dst == src) { + return true; + } + + if (prop->prop_flags & CPF_IS_PLAIN_OLD_DATA) { + mem_copy(dst, (void *)src, (uint64_t)prop->elem_size); + return true; + } + + if (!prop->vtable || !prop->vtable->copy_values_internal) { + return false; + } + + prop->vtable->copy_values_internal(prop, dst, src, 1); + return true; +} + +bool +unreal_fprop_copy_complete_value(fprop_t *prop, void *dst, const void *src) +{ + uint64_t size = unreal_fprop_complete_size(prop); + if (size == 0 || !dst || !src) { + return false; + } + + if (dst == src) { + return true; + } + + if (prop->prop_flags & CPF_IS_PLAIN_OLD_DATA) { + mem_copy(dst, (void *)src, size); + return true; + } + + if (!prop->vtable || !prop->vtable->copy_values_internal) { + return false; + } + + prop->vtable->copy_values_internal(prop, dst, src, prop->array_dim); + return true; +} + +bool +unreal_fprop_copy_single_value_to_script_vm(fprop_t *prop, void *dst, const void *src) +{ + if (!unreal_fprop_has_valid_layout(prop) || !dst || !src || + !prop->vtable || !prop->vtable->copy_single_value_to_script_vm) { + return false; + } + + prop->vtable->copy_single_value_to_script_vm(prop, dst, src); + return true; +} + +bool +unreal_fprop_copy_complete_value_to_script_vm(fprop_t *prop, void *dst, const void *src) +{ + if (!unreal_fprop_has_valid_layout(prop) || !dst || !src || + !prop->vtable || !prop->vtable->copy_complete_value_to_script_vm) { + return false; + } + + prop->vtable->copy_complete_value_to_script_vm(prop, dst, src); + return true; +} + +bool +unreal_fprop_copy_single_value_from_script_vm(fprop_t *prop, void *dst, const void *src) +{ + if (!unreal_fprop_has_valid_layout(prop) || !dst || !src || + !prop->vtable || !prop->vtable->copy_single_value_from_script_vm) { + return false; + } + + prop->vtable->copy_single_value_from_script_vm(prop, dst, src); + return true; +} + +bool +unreal_fprop_copy_complete_value_from_script_vm(fprop_t *prop, void *dst, const void *src) +{ + if (!unreal_fprop_has_valid_layout(prop) || !dst || !src || + !prop->vtable || !prop->vtable->copy_complete_value_from_script_vm) { + return false; + } + + prop->vtable->copy_complete_value_from_script_vm(prop, dst, src); + return true; +} + +bool +unreal_fprop_single_values_identical(fprop_t *prop, const void *a, const void *b, uint32_t port_flags) +{ + if (!unreal_fprop_has_valid_layout(prop) || !a || !prop->vtable || !prop->vtable->identical) { + return false; + } + return prop->vtable->identical(prop, a, b, port_flags); +} + +bool +unreal_fprop_complete_values_identical(fprop_t *prop, const void *a, const void *b, uint32_t port_flags) +{ + if (!unreal_fprop_has_valid_layout(prop) || !a || !prop->vtable || !prop->vtable->identical) { + return false; } for (int32_t i = 0; i < prop->array_dim; ++i) { - prop->vtable->initialize_value_internal(prop, value + (uint64_t)i * (uint64_t)prop->elem_size); + const void *a_elem = unreal_fprop_value_at(prop, (void *)a, i); + const void *b_elem = b ? unreal_fprop_value_at(prop, (void *)b, i) : NULL; + if (!prop->vtable->identical(prop, a_elem, b_elem, port_flags)) { + return false; + } + } + return true; +} + +bool +unreal_fprop_value_hash(fprop_t *prop, const void *value, uint32_t *out_hash) +{ + if (!unreal_fprop_has_valid_layout(prop) || !value || !out_hash || + !(prop->prop_flags & CPF_HAS_GET_VALUE_TYPE_HASH) || + !prop->vtable || !prop->vtable->get_value_type_hash_internal) { + return false; + } + + *out_hash = prop->vtable->get_value_type_hash_internal(prop, value); + return true; +} + +bool +unreal_fprop_same_type(fprop_t *prop, fprop_t *other) +{ + return prop && other && prop->vtable && prop->vtable->same_type && + prop->vtable->same_type(prop, other); +} + +uobject_t * +unreal_fprop_get_object(fprop_obj_base_t *prop, const void *value) +{ + if (!prop || !value || !prop->vtable) { + return NULL; + } + + return prop->vtable->get_object_prop_value ? prop->vtable->get_object_prop_value(prop, value) : NULL; +} + +bool +unreal_fprop_object_is_compatible(fprop_obj_base_t *prop, uobject_t *object) +{ + if (!prop || (object && (!prop->prop_class || !unreal_uobject_is_a(object, prop->prop_class)))) { + return false; + } + + if (!object) { + return true; + } + + uclass_t *meta_class = NULL; + if (unreal_fprop_class_is((fprop_t *)prop, globals.unreal.class_prop)) { + meta_class = ((fprop_class_t *)prop)->meta_class; + } else if (unreal_fprop_class_is((fprop_t *)prop, globals.unreal.soft_class_prop)) { + meta_class = ((fprop_class_soft_t *)prop)->meta_class; + } + + if (meta_class && !unreal_uclass_is_child_of((uclass_t *)object, meta_class)) { + return false; + } + return true; +} + +bool +unreal_fprop_set_object(fprop_obj_base_t *prop, void *value, uobject_t *object) +{ + if (!prop || !value || !prop->vtable || !unreal_fprop_object_is_compatible(prop, object)) { + return false; + } + + if (!prop->vtable->set_object_prop_value) { + return false; + } + + prop->vtable->set_object_prop_value(prop, value, object); + return true; +} + +void +unreal_fprop_initialize_in_container(fprop_t *prop, void *container) +{ + void *value = unreal_fprop_value_in_container(prop, container, 0); + if (value) { + unreal_fprop_initialize_value(prop, value); } } void unreal_fprop_destroy_in_container(fprop_t *prop, void *container) { - if (!prop || !container || prop->elem_size <= 0 || prop->array_dim <= 0 || (prop->prop_flags & CPF_NO_DESTRUCTOR)) { - return; + void *value = unreal_fprop_value_in_container(prop, container, 0); + if (value) { + unreal_fprop_destroy_value(prop, value); } +} - if (!prop->vtable || !prop->vtable->destroy_value_internal) { - return; +bool +unreal_ustruct_initialize_struct(ustruct_t *struct_type, void *memory, int32_t array_dim) +{ + if (!struct_type || !memory || array_dim <= 0 || struct_type->props_size < 0 || + !struct_type->vtable || !struct_type->vtable->init_struct) { + return false; } - uint8_t *value = (uint8_t *)container + prop->offset_internal; - for (int32_t i = 0; i < prop->array_dim; ++i) { - prop->vtable->destroy_value_internal(prop, value + (uint64_t)i * (uint64_t)prop->elem_size); + struct_type->vtable->init_struct(struct_type, memory, array_dim); + return true; +} + +bool +unreal_ustruct_destroy_struct(ustruct_t *struct_type, void *memory, int32_t array_dim) +{ + if (!struct_type || !memory || array_dim <= 0 || struct_type->props_size < 0 || + !struct_type->vtable || !struct_type->vtable->destroy_struct) { + return false; } + + struct_type->vtable->destroy_struct(struct_type, memory, array_dim); + return true; } const wchar_t * @@ -2047,6 +2375,334 @@ unreal_tset_hash_head(hash_allocator_t *hash, int32_t hash_size, uint32_t key_ha return data[key_hash & (uint32_t)(hash_size - 1)]; } +static bool +unreal_array_prop_is_valid(fprop_array_t *prop) +{ + return prop && unreal_fprop_has_valid_layout(&prop->base) && prop->inner && unreal_fprop_has_valid_layout(prop->inner); +} + +static bool +unreal_array_view_is_valid(const void *array, fprop_array_t *prop) +{ + if (!array || !unreal_array_prop_is_valid(prop) || (prop->array_flags & EAPF_USES_MEM_IMAGE_ALLOCATOR)) { + return false; + } + + const fscript_array_t *script_array = (const fscript_array_t *)array; + return script_array->num >= 0 && script_array->max >= script_array->num && (script_array->num == 0 || script_array->data != NULL); +} + +int32_t +unreal_array_num(const void *array, fprop_array_t *prop) +{ + if (!unreal_array_view_is_valid(array, prop)) { + return -1; + } + return ((const fscript_array_t *)array)->num; +} + +void * +unreal_array_get(void *array, fprop_array_t *prop, int32_t idx) +{ + if (!unreal_array_view_is_valid(array, prop)) { + return NULL; + } + + fscript_array_t *script_array = (fscript_array_t *)array; + if (idx < 0 || idx >= script_array->num) { + return NULL; + } + + return (uint8_t *)script_array->data + (uint64_t)idx * (uint64_t)prop->inner->elem_size; +} + +int32_t +unreal_array_add(void *array, fprop_array_t *prop, const void *value) +{ + if (!array || !unreal_array_prop_is_valid(prop) || !value || !generic_array_add) { + return -1; + } + return generic_array_add(array, prop, value); +} + +void +unreal_array_insert(void *array, fprop_array_t *prop, int32_t idx, const void *value) +{ + if (array && unreal_array_prop_is_valid(prop) && idx >= 0 && value && generic_array_insert) { + generic_array_insert(array, prop, value, idx); + } +} + +void +unreal_array_remove(void *array, fprop_array_t *prop, int32_t idx) +{ + if (array && unreal_array_prop_is_valid(prop) && idx >= 0 && generic_array_remove) { + generic_array_remove(array, prop, idx); + } +} + +void +unreal_array_resize(void *array, fprop_array_t *prop, int32_t size) +{ + if (array && unreal_array_prop_is_valid(prop) && size >= 0 && generic_array_resize) { + generic_array_resize(array, prop, size); + } +} + +void +unreal_array_set(void *array, fprop_array_t *prop, int32_t idx, const void *value, bool size_to_fit) +{ + if (array && unreal_array_prop_is_valid(prop) && idx >= 0 && value && generic_array_set) { + generic_array_set(array, prop, idx, value, size_to_fit); + } +} + +bool +unreal_array_clear(void *array, fprop_array_t *prop) +{ + return array && unreal_array_prop_is_valid(prop) && unreal_fprop_clear_single_value(&prop->base, array); +} + +static bool +unreal_script_set_view_is_valid(const fscript_set_t *set, const fscript_set_layout_t *layout) +{ + if (!set || !layout || layout->size <= 0 || layout->sparse_array_layout.size < layout->size || + layout->sparse_array_layout.alignment <= 0) { + return false; + } + + const fscript_sparse_array_t *sparse = &set->elems; + return sparse->data.num >= 0 && + sparse->data.max >= sparse->data.num && + sparse->num_free_idx >= 0 && + sparse->num_free_idx <= sparse->data.num && + sparse->alloc_flags.num_bits >= sparse->data.num && + sparse->alloc_flags.max_bits >= sparse->alloc_flags.num_bits && + (sparse->data.num == 0 || sparse->data.data != NULL); +} + +static int32_t +unreal_script_set_num(const fscript_set_t *set, const fscript_set_layout_t *layout) +{ + if (!unreal_script_set_view_is_valid(set, layout)) { + return -1; + } + return set->elems.data.num - set->elems.num_free_idx; +} + +static int32_t +unreal_script_set_max_index(const fscript_set_t *set, const fscript_set_layout_t *layout) +{ + if (!unreal_script_set_view_is_valid(set, layout)) { + return -1; + } + return set->elems.data.num; +} + +static bool +unreal_script_set_is_valid_index(const fscript_set_t *set, const fscript_set_layout_t *layout, int32_t idx) +{ + return unreal_script_set_view_is_valid(set, layout) && idx >= 0 && idx < set->elems.data.num && + unreal_tbit_array_is_set((tbit_array_t *)&set->elems.alloc_flags, idx); +} + +static void * +unreal_script_set_get(void *set, const fscript_set_layout_t *layout, int32_t index) +{ + fscript_set_t *script_set = (fscript_set_t *)set; + if (!unreal_script_set_is_valid_index(script_set, layout, index)) { + return NULL; + } + + return (uint8_t *)script_set->elems.data.data + (uint64_t)index * (uint64_t)layout->sparse_array_layout.size; +} + +static bool +unreal_set_prop_is_valid(fprop_set_t *prop) +{ + return prop && unreal_fprop_has_valid_layout(&prop->base) && prop->elem_prop && + unreal_fprop_has_valid_layout(prop->elem_prop) && prop->set_layout.size > 0 && + prop->set_layout.sparse_array_layout.size >= prop->set_layout.size; +} + +int32_t +unreal_set_num(const void *set, fprop_set_t *prop) +{ + if (!unreal_set_prop_is_valid(prop)) { + return -1; + } + return unreal_script_set_num((const fscript_set_t *)set, &prop->set_layout); +} + +int32_t +unreal_set_max_index(const void *set, fprop_set_t *prop) +{ + if (!unreal_set_prop_is_valid(prop)) { + return -1; + } + return unreal_script_set_max_index((const fscript_set_t *)set, &prop->set_layout); +} + +bool +unreal_set_is_valid_index(const void *set, fprop_set_t *prop, int32_t idx) +{ + return unreal_set_prop_is_valid(prop) && unreal_script_set_is_valid_index((const fscript_set_t *)set, &prop->set_layout, idx); +} + +const void * +unreal_set_get(const void *set, fprop_set_t *prop, int32_t idx) +{ + if (!unreal_set_prop_is_valid(prop)) { + return NULL; + } + return unreal_script_set_get((void *)set, &prop->set_layout, idx); +} + +int32_t +unreal_set_find_index(const void *set, fprop_set_t *prop, const void *value) +{ + int32_t max_index = unreal_set_max_index(set, prop); + if (max_index < 0 || !value) { + return TSET_INVALID_ID; + } + + for (int32_t index = 0; index < max_index; ++index) { + const void *elem = unreal_set_get(set, prop, index); + if (elem && unreal_fprop_single_values_identical(prop->elem_prop, elem, value, 0)) { + return index; + } + } + return TSET_INVALID_ID; +} + +bool +unreal_set_contains(const void *set, fprop_set_t *prop, const void *value) +{ + return unreal_set_find_index(set, prop, value) != TSET_INVALID_ID; +} + +void +unreal_set_add(void *set, fprop_set_t *prop, const void *value) +{ + if (!set || !unreal_set_prop_is_valid(prop) || !value || !fscript_set_add_elem) { + return; + } + + fscript_set_helper_t helper = { + .elem_prop = prop->elem_prop, + .set = set, + .layout = prop->set_layout, + }; + fscript_set_add_elem(&helper, value); +} + +bool +unreal_set_remove(void *set, fprop_set_t *prop, const void *value) +{ + if (!set || !unreal_set_prop_is_valid(prop) || !value || !generic_set_remove) { + return false; + } + return generic_set_remove(set, prop, value); +} + +bool +unreal_set_clear(void *set, fprop_set_t *prop) +{ + return set && unreal_set_prop_is_valid(prop) && unreal_fprop_clear_single_value(&prop->base, set); +} + +static bool +unreal_map_prop_is_valid(fprop_map_t *prop) +{ + if (!prop || !unreal_fprop_has_valid_layout(&prop->base) || !prop->key_prop || !prop->val_prop || + !unreal_fprop_has_valid_layout(prop->key_prop) || !unreal_fprop_has_valid_layout(prop->val_prop)) { + return false; + } + + const fscript_map_layout_t *layout = &prop->map_layout; + return layout->set_layout.size > 0 && + layout->set_layout.sparse_array_layout.size >= layout->set_layout.size && + layout->value_offset >= prop->key_prop->elem_size && + (uint64_t)layout->value_offset + (uint64_t)prop->val_prop->elem_size <= (uint64_t)layout->set_layout.size; +} + +static bool +unreal_map_view_prop_is_valid(fprop_map_t *prop) +{ + return unreal_map_prop_is_valid(prop) && !(prop->map_flags & EMPF_USES_MEM_IMAGE_ALLOCATOR); +} + +int32_t +unreal_map_num(const void *map, fprop_map_t *prop) +{ + if (!map || !unreal_map_view_prop_is_valid(prop)) { + return -1; + } + return unreal_script_set_num(&((const fscript_map_t *)map)->pairs, &prop->map_layout.set_layout); +} + +int32_t +unreal_map_max_index(const void *map, fprop_map_t *prop) +{ + if (!map || !unreal_map_view_prop_is_valid(prop)) { + return -1; + } + return unreal_script_set_max_index(&((const fscript_map_t *)map)->pairs, &prop->map_layout.set_layout); +} + +bool +unreal_map_is_valid_index(const void *map, fprop_map_t *prop, int32_t idx) +{ + return unreal_map_view_prop_is_valid(prop) && map && + unreal_script_set_is_valid_index(&((const fscript_map_t *)map)->pairs, &prop->map_layout.set_layout, idx); +} + +const void * +unreal_map_get_key(const void *map, fprop_map_t *prop, int32_t idx) +{ + if (!unreal_map_view_prop_is_valid(prop) || !map) { + return NULL; + } + return unreal_script_set_get(&((fscript_map_t *)map)->pairs, &prop->map_layout.set_layout, idx); +} + +void * +unreal_map_get_value(void *map, fprop_map_t *prop, int32_t idx) +{ + uint8_t *key = (uint8_t *)unreal_map_get_key(map, prop, idx); + return key ? key + prop->map_layout.value_offset : NULL; +} + +int32_t +unreal_map_find_index(const void *map, fprop_map_t *prop, const void *key) +{ + int32_t max_idx = unreal_map_max_index(map, prop); + if (max_idx < 0 || !key) { + return TSET_INVALID_ID; + } + + for (int32_t idx = 0; idx < max_idx; ++idx) { + const void *candidate = unreal_map_get_key(map, prop, idx); + if (candidate && unreal_fprop_single_values_identical(prop->key_prop, candidate, key, 0)) { + return idx; + } + } + return TSET_INVALID_ID; +} + +void * +unreal_map_find_value_ptr(void *map, fprop_map_t *prop, const void *key) +{ + int32_t idx = unreal_map_find_index(map, prop, key); + return idx != TSET_INVALID_ID ? unreal_map_get_value(map, prop, idx) : NULL; +} + +bool +unreal_map_clear(void *map, fprop_map_t *prop) +{ + return map && unreal_map_prop_is_valid(prop) && unreal_fprop_clear_single_value(&prop->base, map); +} + void unreal_map_add(void *map, fprop_map_t *prop, const void *key, const void *val) { @@ -2100,7 +2756,7 @@ unreal_map_remove(void *map, fprop_map_t *prop, const void *key) bool unreal_map_find(void *map, fprop_map_t *prop, const void *key, void *out_val) { - if (!map || !prop || !key || !out_val || !generic_map_find) { + if (!map || !prop || !key || !generic_map_find) { return false; } return generic_map_find(map, prop, key, out_val); From 575845a36cd4cb304f263c3d2e2606406a94d359 Mon Sep 17 00:00:00 2001 From: akmubi Date: Fri, 28 Aug 2026 17:32:11 +0500 Subject: [PATCH 2/9] move FProperty functions into a separate file --- Makefile | 2 +- include/unreal.h | 135 --- include/unreal_prop.h | 218 ++++ overdub.vcxproj | 4 + src/builtin/details_panel.c | 1203 +++++--------------- src/builtin/search.c | 103 +- src/builtin/ufunction_call.c | 214 ++-- src/mod_host.c | 1 + src/unreal.c | 928 ---------------- src/unreal_prop.c | 1989 ++++++++++++++++++++++++++++++++++ 10 files changed, 2633 insertions(+), 2164 deletions(-) create mode 100644 include/unreal_prop.h create mode 100644 src/unreal_prop.c diff --git a/Makefile b/Makefile index c7b7e50..b2d0c76 100644 --- a/Makefile +++ b/Makefile @@ -47,6 +47,7 @@ SRCS_TEST_UI := \ src/ui_mod_manager.c \ src/ui_nuklear.c \ src/unreal.c \ + src/unreal_prop.c \ src/vendor.c \ src/vendor_kb.c \ src/builtin/cache.c \ @@ -125,4 +126,3 @@ clean: -include $(OBJS_RELEASE:.o=.d) -include $(OBJS_TEST_UI:.o=.d) -include $(OBJS_TEST_LUA:.o=.d) - diff --git a/include/unreal.h b/include/unreal.h index e772b88..e9dc963 100644 --- a/include/unreal.h +++ b/include/unreal.h @@ -3299,8 +3299,6 @@ bool unreal_fframe_step(fframe_t *stack, void *result); /* ================================================ CLASS INTROSPECTION ============================================= */ -fprop_t * -unreal_ustruct_find_prop(ustruct_t *s, str_t name); ufunc_t * unreal_ustruct_find_func(ustruct_t *s, str_t name); @@ -3310,79 +3308,6 @@ unreal_ustruct_find_func_fname(ustruct_t *s, fname_t name, bool ignore_num); void * unreal_get_mcast_sparse_delegate(uobject_t *s, fname_t name); -/* ================================================= PROPERTY ACCESS ================================================ */ -static inline void * -unreal_uprop_ptr(fprop_t *prop, void *container) -{ - return (uint8_t *)container + prop->offset_internal; -} - -bool -unreal_fprop_class_is(fprop_t *prop, fname_t name); -bool -unreal_fprop_class_is_a(fprop_t *prop, fname_t name); -str_t -unreal_fprop_push_type_name(fprop_t *prop, arena_t *arena); - -uint64_t -unreal_fprop_complete_size(fprop_t *prop); -int32_t -unreal_fprop_min_alignment(fprop_t *prop); -void * -unreal_fprop_value_at(fprop_t *prop, void *value, int32_t array_idx); -void * -unreal_fprop_value_in_container(fprop_t *prop, void *container, int32_t array_idx); - -bool -unreal_fprop_initialize_value(fprop_t *prop, void *value); -bool -unreal_fprop_destroy_value(fprop_t *prop, void *value); -bool -unreal_fprop_clear_single_value(fprop_t *prop, void *value); -bool -unreal_fprop_clear_complete_value(fprop_t *prop, void *value); -bool -unreal_fprop_copy_single_value(fprop_t *prop, void *dst, const void *src); -bool -unreal_fprop_copy_complete_value(fprop_t *prop, void *dst, const void *src); - -bool -unreal_fprop_copy_single_value_to_script_vm(fprop_t *prop, void *dst, const void *src); -bool -unreal_fprop_copy_complete_value_to_script_vm(fprop_t *prop, void *dst, const void *src); -bool -unreal_fprop_copy_single_value_from_script_vm(fprop_t *prop, void *dst, const void *src); -bool -unreal_fprop_copy_complete_value_from_script_vm(fprop_t *prop, void *dst, const void *src); -bool -unreal_fprop_single_values_identical(fprop_t *prop, const void *a, const void *b, uint32_t port_flags); -bool -unreal_fprop_complete_values_identical(fprop_t *prop, const void *a, const void *b, uint32_t port_flags); -bool -unreal_fprop_value_hash(fprop_t *prop, const void *value, uint32_t *out_hash); -bool -unreal_fprop_same_type(fprop_t *prop, fprop_t *other); - -uobject_t * -unreal_fprop_get_object(fprop_obj_base_t *prop, const void *value); -bool -unreal_fprop_object_is_compatible(fprop_obj_base_t *prop, uobject_t *object); -bool -unreal_fprop_set_object(fprop_obj_base_t *prop, void *value, uobject_t *object); - -void -unreal_fprop_initialize_in_container(fprop_t *prop, void *container); -void -unreal_fprop_destroy_in_container(fprop_t *prop, void *container); - -bool -unreal_ustruct_initialize_struct(ustruct_t *struct_type, void *memory, int32_t array_dim); -bool -unreal_ustruct_destroy_struct(ustruct_t *struct_type, void *memory, int32_t array_dim); - -const wchar_t * -unreal_fprop_import_text_direct(fprop_t *prop, const wchar_t *text, void *value, uobject_t *owner); - /* =============================================== CONTAINER UTILITIES ============================================== */ bool @@ -3392,66 +3317,6 @@ unreal_tbit_array_find_next_set(tbit_array_t *bits, int32_t start_idx); int32_t unreal_tset_hash_head(hash_allocator_t *hash, int32_t hash_size, uint32_t key_hash); -int32_t -unreal_array_num(const void *array, fprop_array_t *prop); -void * -unreal_array_get(void *array, fprop_array_t *prop, int32_t idx); -int32_t -unreal_array_add(void *array, fprop_array_t *prop, const void *value); -void -unreal_array_insert(void *array, fprop_array_t *prop, int32_t idx, const void *value); -void -unreal_array_remove(void *array, fprop_array_t *prop, int32_t idx); -void -unreal_array_resize(void *array, fprop_array_t *prop, int32_t size); -void -unreal_array_set(void *array, fprop_array_t *prop, int32_t idx, const void *value, bool size_to_fit); -bool -unreal_array_clear(void *array, fprop_array_t *prop); - -int32_t -unreal_set_num(const void *set, fprop_set_t *prop); -int32_t -unreal_set_max_index(const void *set, fprop_set_t *prop); -bool -unreal_set_is_valid_index(const void *set, fprop_set_t *prop, int32_t idx); -const void * -unreal_set_get(const void *set, fprop_set_t *prop, int32_t idx); -int32_t -unreal_set_find_index(const void *set, fprop_set_t *prop, const void *value); -bool -unreal_set_contains(const void *set, fprop_set_t *prop, const void *value); -void -unreal_set_add(void *set, fprop_set_t *prop, const void *value); -bool -unreal_set_remove(void *set, fprop_set_t *prop, const void *value); -bool -unreal_set_clear(void *set, fprop_set_t *prop); - -int32_t -unreal_map_num(const void *map, fprop_map_t *prop); -int32_t -unreal_map_max_index(const void *map, fprop_map_t *prop); -bool -unreal_map_is_valid_index(const void *map, fprop_map_t *prop, int32_t idx); -const void * -unreal_map_get_key(const void *map, fprop_map_t *prop, int32_t idx); -void * -unreal_map_get_value(void *map, fprop_map_t *prop, int32_t idx); -int32_t -unreal_map_find_index(const void *map, fprop_map_t *prop, const void *key); -void * -unreal_map_find_value_ptr(void *map, fprop_map_t *prop, const void *key); -bool -unreal_map_clear(void *map, fprop_map_t *prop); - -void -unreal_map_add(void *map, fprop_map_t *prop, const void *key, const void *val); -bool -unreal_map_remove(void *map, fprop_map_t *prop, const void *key); -bool -unreal_map_find(void *map, fprop_map_t *prop, const void *key, void *out_val); - /* =================================================== DATA TABLE =================================================== */ tmap_fname_uint8ptr_t * diff --git a/include/unreal_prop.h b/include/unreal_prop.h new file mode 100644 index 0000000..78678d7 --- /dev/null +++ b/include/unreal_prop.h @@ -0,0 +1,218 @@ +#ifndef UNREAL_PROP_H +#define UNREAL_PROP_H + +#include "unreal.h" + +/* FProperty metadata and lookup. */ +typedef enum unreal_prop_kind_e { + UNREAL_PROP_KIND_UNKNOWN, + UNREAL_PROP_KIND_BOOL, + UNREAL_PROP_KIND_BYTE, + UNREAL_PROP_KIND_INT8, + UNREAL_PROP_KIND_INT16, + UNREAL_PROP_KIND_INT32, + UNREAL_PROP_KIND_INT64, + UNREAL_PROP_KIND_UINT16, + UNREAL_PROP_KIND_UINT32, + UNREAL_PROP_KIND_UINT64, + UNREAL_PROP_KIND_FLOAT, + UNREAL_PROP_KIND_DOUBLE, + UNREAL_PROP_KIND_NAME, + UNREAL_PROP_KIND_STRING, + UNREAL_PROP_KIND_TEXT, + UNREAL_PROP_KIND_OBJECT, + UNREAL_PROP_KIND_CLASS, + UNREAL_PROP_KIND_SOFT_OBJECT, + UNREAL_PROP_KIND_SOFT_CLASS, + UNREAL_PROP_KIND_WEAK_OBJECT, + UNREAL_PROP_KIND_LAZY_OBJECT, + UNREAL_PROP_KIND_INTERFACE, + UNREAL_PROP_KIND_STRUCT, + UNREAL_PROP_KIND_ARRAY, + UNREAL_PROP_KIND_SET, + UNREAL_PROP_KIND_MAP, + UNREAL_PROP_KIND_ENUM, + UNREAL_PROP_KIND_DELEGATE, + UNREAL_PROP_KIND_MULTICAST_DELEGATE, + UNREAL_PROP_KIND_MULTICAST_INLINE_DELEGATE, + UNREAL_PROP_KIND_MULTICAST_SPARSE_DELEGATE, +} unreal_prop_kind_t; + +typedef struct unreal_prop_integer_s unreal_prop_integer_t; +struct unreal_prop_integer_s { + uint64_t value; // cast value to int64_t when is_signed is true + bool is_signed; +}; + +fprop_t * +unreal_ustruct_find_prop(ustruct_t *s, str_t name); + +unreal_prop_kind_t +unreal_fprop_get_kind(fprop_t *prop); +bool +unreal_fprop_struct_is(fprop_t *prop, fname_t struct_name); +bool +unreal_fprop_class_is(fprop_t *prop, fname_t name); +bool +unreal_fprop_class_is_a(fprop_t *prop, fname_t name); +str_t +unreal_fprop_push_type_name(fprop_t *prop, arena_t *arena); + +bool +unreal_fprop_read_bool(fprop_t *prop, const void *value, bool *out); +bool +unreal_fprop_read_integer(fprop_t *prop, const void *value, unreal_prop_integer_t *out); +bool +unreal_fprop_read_real(fprop_t *prop, const void *value, double *out); +bool +unreal_fprop_read_name(fprop_t *prop, const void *value, fname_t *out); + +bool +unreal_fprop_write_bool(fprop_t *prop, void *value, bool input); +bool +unreal_fprop_write_integer(fprop_t *prop, void *value, unreal_prop_integer_t input); +bool +unreal_fprop_write_real(fprop_t *prop, void *value, double input); +bool +unreal_fprop_write_name(fprop_t *prop, void *value, fname_t input); + +uobject_t * +unreal_fprop_get_object(fprop_obj_base_t *prop, const void *value); +uobject_t * +unreal_fprop_get_referenced_object(fprop_t *prop, const void *value); +bool +unreal_fprop_object_is_compatible(fprop_obj_base_t *prop, uobject_t *object); +bool +unreal_fprop_set_object(fprop_obj_base_t *prop, void *value, uobject_t *object); + +uobject_t * +unreal_fweak_object_resolve(fweak_object_ptr_t weak); +str_t +unreal_fscript_delegate_push_summary(const fscript_delegate_t *delegate, arena_t *arena); +/* NOTE: value_size is the readable size of one property element, not its complete fixed-array size */ +str_t +unreal_fprop_push_value_summary(fprop_t *prop, const void *value, int32_t value_size, arena_t *arena); + +static inline void * +unreal_uprop_ptr(fprop_t *prop, void *container) +{ + return (uint8_t *)container + prop->offset_internal; +} + +uint64_t +unreal_fprop_complete_size(fprop_t *prop); +int32_t +unreal_fprop_min_alignment(fprop_t *prop); +void * +unreal_fprop_value_at(fprop_t *prop, void *value, int32_t array_idx); +void * +unreal_fprop_value_in_container(fprop_t *prop, void *container, int32_t array_idx); + +bool +unreal_fprop_initialize_value(fprop_t *prop, void *value); +bool +unreal_fprop_destroy_value(fprop_t *prop, void *value); +bool +unreal_fprop_clear_single_value(fprop_t *prop, void *value); +bool +unreal_fprop_clear_complete_value(fprop_t *prop, void *value); +bool +unreal_fprop_copy_single_value(fprop_t *prop, void *dst, const void *src); +bool +unreal_fprop_copy_complete_value(fprop_t *prop, void *dst, const void *src); + +bool +unreal_fprop_copy_single_value_to_script_vm(fprop_t *prop, void *dst, const void *src); +bool +unreal_fprop_copy_complete_value_to_script_vm(fprop_t *prop, void *dst, const void *src); +bool +unreal_fprop_copy_single_value_from_script_vm(fprop_t *prop, void *dst, const void *src); +bool +unreal_fprop_copy_complete_value_from_script_vm(fprop_t *prop, void *dst, const void *src); +bool +unreal_fprop_single_values_identical(fprop_t *prop, const void *a, const void *b, uint32_t port_flags); +bool +unreal_fprop_complete_values_identical(fprop_t *prop, const void *a, const void *b, uint32_t port_flags); +bool +unreal_fprop_value_hash(fprop_t *prop, const void *value, uint32_t *out_hash); +bool +unreal_fprop_same_type(fprop_t *prop, fprop_t *other); + +void +unreal_fprop_initialize_in_container(fprop_t *prop, void *container); +void +unreal_fprop_destroy_in_container(fprop_t *prop, void *container); + +bool +unreal_ustruct_initialize_struct(ustruct_t *struct_type, void *memory, int32_t array_dim); +bool +unreal_ustruct_destroy_struct(ustruct_t *struct_type, void *memory, int32_t array_dim); + +const wchar_t * +unreal_fprop_import_text_direct(fprop_t *prop, const wchar_t *text, void *value, uobject_t *owner); + +/* NOTE: imports one initialized property element transactionally. text uses engine's ImportText literal syntax */ +bool +unreal_fprop_import_text(fprop_t *prop, void *value, uobject_t *owner, str_t text, arena_t *arena); + +/* Reflected dynamic containers. Indices are Unreal's zero-based sparse/array indices. */ +int32_t +unreal_array_num(const void *array, fprop_array_t *prop); +void * +unreal_array_get(void *array, fprop_array_t *prop, int32_t idx); +int32_t +unreal_array_add(void *array, fprop_array_t *prop, const void *value); +void +unreal_array_insert(void *array, fprop_array_t *prop, int32_t idx, const void *value); +void +unreal_array_remove(void *array, fprop_array_t *prop, int32_t idx); +void +unreal_array_resize(void *array, fprop_array_t *prop, int32_t size); +void +unreal_array_set(void *array, fprop_array_t *prop, int32_t idx, const void *value, bool size_to_fit); +bool +unreal_array_clear(void *array, fprop_array_t *prop); + +int32_t +unreal_set_num(const void *set, fprop_set_t *prop); +int32_t +unreal_set_max_index(const void *set, fprop_set_t *prop); +bool +unreal_set_is_valid_index(const void *set, fprop_set_t *prop, int32_t idx); +const void * +unreal_set_get(const void *set, fprop_set_t *prop, int32_t idx); +int32_t +unreal_set_find_index(const void *set, fprop_set_t *prop, const void *value); +bool +unreal_set_contains(const void *set, fprop_set_t *prop, const void *value); +void +unreal_set_add(void *set, fprop_set_t *prop, const void *value); +bool +unreal_set_remove(void *set, fprop_set_t *prop, const void *value); +bool +unreal_set_clear(void *set, fprop_set_t *prop); + +int32_t +unreal_map_num(const void *map, fprop_map_t *prop); +int32_t +unreal_map_max_index(const void *map, fprop_map_t *prop); +bool +unreal_map_is_valid_index(const void *map, fprop_map_t *prop, int32_t idx); +const void * +unreal_map_get_key(const void *map, fprop_map_t *prop, int32_t idx); +void * +unreal_map_get_value(void *map, fprop_map_t *prop, int32_t idx); +int32_t +unreal_map_find_index(const void *map, fprop_map_t *prop, const void *key); +void * +unreal_map_find_value_ptr(void *map, fprop_map_t *prop, const void *key); +bool +unreal_map_clear(void *map, fprop_map_t *prop); +void +unreal_map_add(void *map, fprop_map_t *prop, const void *key, const void *val); +bool +unreal_map_remove(void *map, fprop_map_t *prop, const void *key); +bool +unreal_map_find(void *map, fprop_map_t *prop, const void *key, void *out_val); + +#endif /* UNREAL_PROP_H */ diff --git a/overdub.vcxproj b/overdub.vcxproj index a971272..807e9d1 100644 --- a/overdub.vcxproj +++ b/overdub.vcxproj @@ -247,6 +247,9 @@ false + + false + false @@ -297,6 +300,7 @@ + diff --git a/src/builtin/details_panel.c b/src/builtin/details_panel.c index 21a7550..9b3b599 100644 --- a/src/builtin/details_panel.c +++ b/src/builtin/details_panel.c @@ -8,6 +8,7 @@ #include "types.h" #include "ui_nuklear.h" #include "unreal.h" +#include "unreal_prop.h" #include "vendor_stb.h" @@ -41,113 +42,8 @@ #define DETAIL_ENUM_COL_TEXT_NAME "NAME" #define DETAIL_ENUM_COL_TEXT_VALUE "VALUE" -typedef struct detail_fvector2d_s detail_fvector2d_t; -struct detail_fvector2d_s { - float x; - float y; -}; - -typedef struct detail_fvector4_s detail_fvector4_t; -struct detail_fvector4_s { - float x; - float y; - float z; - float w; -}; - -typedef struct detail_flinear_color_s detail_flinear_color_t; -struct detail_flinear_color_s { - float r; - float g; - float b; - float a; -}; - -typedef struct detail_fgameplay_tag_s detail_fgameplay_tag_t; -struct detail_fgameplay_tag_s { - fname_t name; -}; - -typedef TARRAY(detail_fgameplay_tag_t) detail_fgameplay_tag_array_t; - -typedef struct detail_fgameplay_tag_container_s detail_fgameplay_tag_container_t; -struct detail_fgameplay_tag_container_s { - detail_fgameplay_tag_array_t tags; - detail_fgameplay_tag_array_t parent_tags; -}; - -typedef struct detail_fint_point_s detail_fint_point_t; -struct detail_fint_point_s { - int32_t x; - int32_t y; -}; - -typedef struct detail_fint_vector_s detail_fint_vector_t; -struct detail_fint_vector_s { - int32_t x; - int32_t y; - int32_t z; -}; - -typedef TARRAY(void) detail_tarray_view_t; - -typedef struct detail_tsparse_view_s detail_tsparse_view_t; -struct detail_tsparse_view_s { - detail_tarray_view_t data; - tbit_array_t alloc_flags; - int32_t first_free_idx; - int32_t num_free_idx; -}; - -typedef struct detail_tset_view_s detail_tset_view_t; -struct detail_tset_view_s { - detail_tsparse_view_t elems; - hash_allocator_t hash; - int32_t hash_size; -}; - -typedef struct detail_fweak_object_ptr_s detail_fweak_object_ptr_t; -struct detail_fweak_object_ptr_s { - int32_t object_idx; - int32_t serial_num; -}; - -typedef struct detail_fguid_s detail_fguid_t; -struct detail_fguid_s { - uint32_t a; - uint32_t b; - uint32_t c; - uint32_t d; -}; - -typedef struct detail_flazy_object_ptr_s detail_flazy_object_ptr_t; -struct detail_flazy_object_ptr_s { - detail_fweak_object_ptr_t weak; - int32_t tag_at_last_test; - detail_fguid_t object_id; -}; - -typedef struct detail_fscript_interface_s detail_fscript_interface_t; -struct detail_fscript_interface_s { - uobject_t *object; - void *iface; -}; - -typedef struct detail_fscript_delegate_s detail_fscript_delegate_t; -struct detail_fscript_delegate_s { - detail_fweak_object_ptr_t object; - fname_t func_name; -}; - -typedef TARRAY(detail_fscript_delegate_t) detail_fscript_delegate_array_t; - -typedef struct detail_fsoft_object_ptr_s detail_fsoft_object_ptr_t; -struct detail_fsoft_object_ptr_s { - detail_fweak_object_ptr_t weak; - int32_t tag_at_last_test; - int32_t pad0; - fsoft_object_path_t path; -}; +typedef fscript_delegate_t detail_fscript_delegate_t; +typedef fmulticast_script_delegate_t detail_fscript_delegate_array_t; static void detail_copy_text(struct nk_context *ctx, str_t text) @@ -350,26 +246,13 @@ detail_prop_push_array_elem(search_tool_t *tool, detail_tab_t *tab, fprop_t *ele static detail_prop_t * detail_prop_push_set_elem(search_tool_t *tool, detail_tab_t *tab, fprop_t *elem, uint32_t elem_idx, uint8_t *elem_addr, int32_t elem_offset, uint32_t depth, bool permanent, bool runtime); static detail_prop_t * -detail_prop_push_map_pair(search_tool_t *tool, detail_tab_t *tab, fprop_map_t *map, uint32_t pair_idx, uint8_t *pair_addr, int32_t pair_offset, uint32_t depth, bool permanent, bool runtime); +detail_prop_push_map_pair( + search_tool_t *tool, detail_tab_t *tab, fprop_map_t *map, uint32_t pair_idx, uint8_t *key_addr, uint8_t *val_addr, int32_t pair_offset, uint32_t depth, bool permanent, bool runtime); static detail_func_t * detail_func_push(search_tool_t *tool, detail_tab_t *tab, record_t *func_record, int32_t index); static detail_enum_t * detail_enum_push(search_tool_t *tool, detail_tab_t *tab, record_t *enum_record); -static inline bool -fprop_struct_is(fprop_t *prop, fname_t name) -{ - ASSERT(prop != NULL); - - fprop_struct_t *sp = (fprop_struct_t *)prop; - if (!sp->script_struct) { - return false; - } - - uobject_t *obj = (uobject_t *)sp->script_struct; - return unreal_fname_equal(obj->name, name, false); -} - detail_prop_t * detail_prop_push_pseudo(search_tool_t *tool, detail_tab_t *tab, fprop_t *prop, str_t name, uint32_t depth, bool permanent, bool runtime) { @@ -417,42 +300,57 @@ detail_prop_expand_complex(search_tool_t *tool, detail_tab_t *tab, detail_prop_t return; } - if (unreal_fprop_class_is(prop, globals.unreal.struct_prop)) { - fprop_struct_t *sp = (fprop_struct_t *)prop; - if (sp->script_struct) { - ustruct_t *st = (ustruct_t *)sp->script_struct; - for (ffield_t *f = st->child_props; f; f = f->next) { - fprop_t *child_prop = (fprop_t *)f; - detail_prop_t *child_node = detail_prop_push(tool, tab, child_prop, false, depth + 1, permanent, runtime); - if (child_node) { - QUEUE_PUSH(node->first_child, node->last_child, child_node); + switch (unreal_fprop_get_kind(prop)) { + case UNREAL_PROP_KIND_STRUCT: { + fprop_struct_t *sp = (fprop_struct_t *)prop; + if (sp->script_struct) { + ustruct_t *st = (ustruct_t *)sp->script_struct; + for (ffield_t *f = st->child_props; f; f = f->next) { + fprop_t *child_prop = (fprop_t *)f; + detail_prop_t *child_node = detail_prop_push(tool, tab, child_prop, false, depth + 1, permanent, runtime); + if (child_node) { + QUEUE_PUSH(node->first_child, node->last_child, child_node); + } } } + break; } - } else if (unreal_fprop_class_is(prop, globals.unreal.array_prop)) { - fprop_array_t *ap = (fprop_array_t *)prop; - detail_prop_t *child_node = detail_prop_push_pseudo(tool, tab, ap->inner, STR_LIT("Inner"), depth + 1, permanent, runtime); - if (child_node) { - QUEUE_PUSH(node->first_child, node->last_child, child_node); - } - } else if (unreal_fprop_class_is(prop, globals.unreal.set_prop)) { - fprop_set_t *sp = (fprop_set_t *)prop; - detail_prop_t *child_node = detail_prop_push_pseudo(tool, tab, sp->elem_prop, STR_LIT("Element"), depth + 1, permanent, runtime); - if (child_node) { - QUEUE_PUSH(node->first_child, node->last_child, child_node); + + case UNREAL_PROP_KIND_ARRAY: { + fprop_array_t *ap = (fprop_array_t *)prop; + detail_prop_t *child_node = detail_prop_push_pseudo(tool, tab, ap->inner, STR_LIT("Inner"), depth + 1, permanent, runtime); + if (child_node) { + QUEUE_PUSH(node->first_child, node->last_child, child_node); + } + break; } - } else if (unreal_fprop_class_is(prop, globals.unreal.map_prop)) { - fprop_map_t *mp = (fprop_map_t *)prop; - detail_prop_t *key_child_node = detail_prop_push_pseudo(tool, tab, mp->key_prop, STR_LIT("Key"), depth + 1, permanent, runtime); - if (key_child_node) { - QUEUE_PUSH(node->first_child, node->last_child, key_child_node); + case UNREAL_PROP_KIND_SET: { + fprop_set_t *sp = (fprop_set_t *)prop; + detail_prop_t *child_node = detail_prop_push_pseudo(tool, tab, sp->elem_prop, STR_LIT("Element"), depth + 1, permanent, runtime); + if (child_node) { + QUEUE_PUSH(node->first_child, node->last_child, child_node); + } + break; } - detail_prop_t *val_child_node = detail_prop_push_pseudo(tool, tab, mp->val_prop, STR_LIT("Value"), depth + 1, permanent, runtime); - if (val_child_node) { - QUEUE_PUSH(node->first_child, node->last_child, val_child_node); + case UNREAL_PROP_KIND_MAP: { + fprop_map_t *mp = (fprop_map_t *)prop; + + detail_prop_t *key_child_node = detail_prop_push_pseudo(tool, tab, mp->key_prop, STR_LIT("Key"), depth + 1, permanent, runtime); + if (key_child_node) { + QUEUE_PUSH(node->first_child, node->last_child, key_child_node); + } + + detail_prop_t *val_child_node = detail_prop_push_pseudo(tool, tab, mp->val_prop, STR_LIT("Value"), depth + 1, permanent, runtime); + if (val_child_node) { + QUEUE_PUSH(node->first_child, node->last_child, val_child_node); + } + break; } + + default: + break; } } @@ -512,6 +410,7 @@ detail_prop_push_array_elem( node->array_dim = elem->array_dim; node->has_value_addr = elem_addr != NULL; node->value_addr = elem_addr; + node->live_slot_idx = elem_idx; node->offset_text = ui_text_span_make(tool->ctx, str_push_fmt(arena, "0x%04X", (uint32_t)node->offset)); node->size_text = ui_text_span_make(tool->ctx, str_push_fmt(arena, "0x%04X", (uint32_t)node->size)); @@ -554,7 +453,7 @@ detail_prop_push_set_elem( detail_prop_t * detail_prop_push_map_pair( - search_tool_t *tool, detail_tab_t *tab, fprop_map_t *map, uint32_t pair_idx, uint8_t *pair_addr, int32_t pair_offset, uint32_t depth, bool permanent, bool runtime) + search_tool_t *tool, detail_tab_t *tab, fprop_map_t *map, uint32_t pair_idx, uint8_t *key_addr, uint8_t *val_addr, int32_t pair_offset, uint32_t depth, bool permanent, bool runtime) { ASSERT(tool != NULL); ASSERT(tool->ctx != NULL); @@ -597,8 +496,8 @@ detail_prop_push_map_pair( pair->type = ui_text_span_make(tool->ctx, pair_type_name); pair->offset = pair_offset; pair->size = map->map_layout.set_layout.size; - pair->has_value_addr = true; - pair->value_addr = pair_addr; + pair->has_value_addr = key_addr != NULL && val_addr != NULL; + pair->value_addr = key_addr; pair->live_slot_idx = pair_idx; pair->children_kind = DETAIL_PROP_CHILDREN_SCHEMA; pair->offset_text = ui_text_span_make(tool->ctx, str_push_fmt(arena, "0x%04X", (uint32_t)pair->offset)); @@ -610,8 +509,8 @@ detail_prop_push_map_pair( key->offset = 0; key->size = map->key_prop->elem_size; key->array_dim = map->key_prop->array_dim; - key->has_value_addr = true; - key->value_addr = pair->value_addr; + key->has_value_addr = key_addr != NULL; + key->value_addr = key_addr; key->offset_text = ui_text_span_make(tool->ctx, str_push_fmt(arena, "0x%04X", (uint32_t)key->offset)); key->size_text = ui_text_span_make(tool->ctx, str_push_fmt(arena, "0x%04X", (uint32_t)key->size)); @@ -624,8 +523,8 @@ detail_prop_push_map_pair( val->offset = map->map_layout.value_offset; val->size = map->val_prop->elem_size; val->array_dim = map->val_prop->array_dim; - val->has_value_addr = true; - val->value_addr = pair->value_addr + val->offset; + val->has_value_addr = val_addr != NULL; + val->value_addr = val_addr; val->offset_text = ui_text_span_make(tool->ctx, str_push_fmt(arena, "0x%04X", (uint32_t)val->offset)); val->size_text = ui_text_span_make(tool->ctx, str_push_fmt(arena, "0x%04X", (uint32_t)val->size)); @@ -1108,287 +1007,6 @@ details_clear_stale(search_tool_t *tool) } } -static int64_t -fprop_read_int_value(fprop_t *prop, void *addr) -{ - if (unreal_fprop_class_is(prop, globals.unreal.byte_prop)) { - return *(uint8_t *)addr; - } - - if (unreal_fprop_class_is(prop, globals.unreal.int8_prop)) { - return *(int8_t *)addr; - } - - if (unreal_fprop_class_is(prop, globals.unreal.int16_prop)) { - return *(int16_t *)addr; - } - - if (unreal_fprop_class_is(prop, globals.unreal.int_prop)) { - return *(int32_t *)addr; - } - - if (unreal_fprop_class_is(prop, globals.unreal.int64_prop)) { - return *(int64_t *)addr; - } - - if (unreal_fprop_class_is(prop, globals.unreal.uint16_prop)) { - return *(uint16_t *)addr; - } - - if (unreal_fprop_class_is(prop, globals.unreal.uint32_prop)) { - return *(uint32_t *)addr; - } - - if (unreal_fprop_class_is(prop, globals.unreal.uint64_prop)) { - return (int64_t)*(uint64_t *)addr; - } - - return 0; -} - -static str_t -detail_enum_value_name(arena_t *arena, uenum_t *uenum, int64_t value) -{ - if (!uenum) { - return STR_NULL; - } - - for (int32_t i = 0; i < uenum->names.num; ++i) { - if (uenum->names.data[i].value == value) { - return unreal_fname_to_str(uenum->names.data[i].key, arena); - } - } - - return STR_NULL; -} - -static str_t -fvector_push_summary(arena_t *arena, void *addr) -{ - ASSERT(addr != NULL); - - float *v = (float *)addr; - return str_push_fmt(arena, "{X=%.3f Y=%.3f Z=%.3f}", v[0], v[1], v[2]); -} - -static str_t -frotator_push_summary(arena_t *arena, void *addr) -{ - ASSERT(addr != NULL); - - float *r = (float *)addr; - return str_push_fmt(arena, "{Pitch=%.3f Yaw=%.3f Roll=%.3f}", r[0], r[1], r[2]); -} - -static str_t -fcolor_push_summary(arena_t *arena, void *addr) -{ - ASSERT(addr != NULL); - - uint8_t *c = (uint8_t *)addr; - - uint8_t b = c[0]; - uint8_t g = c[1]; - uint8_t r = c[2]; - uint8_t a = c[3]; - - return str_push_fmt(arena, "{R=%u G=%u B=%u A=%u}", r, g, b, a); -} - -static str_t -fvector2d_push_summary(arena_t *arena, void *addr) -{ - detail_fvector2d_t *v = (detail_fvector2d_t *)addr; - return str_push_fmt(arena, "{X=%.3f Y=%.3f}", v->x, v->y); -} - -static str_t -fvector4_push_summary(arena_t *arena, void *addr) -{ - detail_fvector4_t *v = (detail_fvector4_t *)addr; - return str_push_fmt(arena, "{X=%.3f Y=%.3f Z=%.3f W=%.3f}", v->x, v->y, v->z, v->w); -} - -static str_t -flinear_color_push_summary(arena_t *arena, void *addr) -{ - detail_flinear_color_t *c = (detail_flinear_color_t *)addr; - return str_push_fmt(arena, "{R=%.3f G=%.3f B=%.3f A=%.3f}", c->r, c->g, c->b, c->a); -} - -static str_t -fquat_push_summary(arena_t *arena, void *addr) -{ - fquat_t *q = (fquat_t *)addr; - return str_push_fmt(arena, "{X=%.3f Y=%.3f Z=%.3f W=%.3f}", q->x, q->y, q->z, q->w); -} - -static str_t -fkey_push_summary(arena_t *arena, void *addr) -{ - fkey_t *key = (fkey_t *)addr; - - if (!key) { - return STR_LIT("None"); - } - - str_t name = unreal_fname_to_str(key->name, arena); - if (str_is_empty(name)) { - return STR_LIT("None"); - } - - return str_push_fmt(arena, "%.*s", STR_ARG(name)); -} - -static str_t -fgameplay_tag_push_summary(arena_t *arena, void *addr) -{ - detail_fgameplay_tag_t *tag = (detail_fgameplay_tag_t *)addr; - - if (!tag) { - return STR_LIT("None"); - } - - str_t name = unreal_fname_to_str(tag->name, arena); - if (str_is_empty(name)) { - return STR_LIT("None"); - } - - return name; -} - -static str_t -fgameplay_tag_container_push_summary(arena_t *arena, void *addr) -{ - detail_fgameplay_tag_container_t *container = (detail_fgameplay_tag_container_t *)addr; - - if (!container) { - return STR_LIT("[]"); - } - - detail_fgameplay_tag_array_t *tags = &container->tags; - if (!tags->data || tags->num <= 0 || tags->max <= 0) { - return STR_LIT("[]"); - } - - int32_t count = MIN_VAL(tags->num, 2); - str_t result = STR_LIT("[]"); - str_list_t list = {0}; - tmp_arena_t tmp = scratch_begin(arena); - { - for (int32_t i = 0; i < count; ++i) { - str_t name = unreal_fname_to_str(tags->data[i].name, tmp.arena); - if (str_is_empty(name)) { - name = STR_LIT("None"); - } - - str_list_push(tmp.arena, &list, name); - } - - if (tags->num > count) { - str_t post = str_push_fmt(tmp.arena, "] +%d", tags->num - count); - result = str_list_join(arena, list, STR_LIT("["), STR_LIT(", "), post); - } else { - result = str_list_join(arena, list, STR_LIT("["), STR_LIT(", "), STR_LIT("]")); - } - } - scratch_end(tmp); - return result; -} - -static str_t -fguid_push_summary(arena_t *arena, void *addr) -{ - fguid_t *g = (fguid_t *)addr; - - return str_push_fmt(arena, "{%08X-%04X-%04X-%04X-%04X%08X}", g->a, (g->b >> 16) & 0xFFFF, g->b & 0xFFFF, (g->c >> 16) & 0xFFFF, g->c & 0xFFFF, g->d); -} - -static str_t -fint_point_push_summary(arena_t *arena, void *addr) -{ - detail_fint_point_t *p = (detail_fint_point_t *)addr; - return str_push_fmt(arena, "{X=%d Y=%d}", p->x, p->y); -} - -static str_t -fint_vector_push_summary(arena_t *arena, void *addr) -{ - detail_fint_vector_t *v = (detail_fint_vector_t *)addr; - return str_push_fmt(arena, "{X=%d Y=%d Z=%d}", v->x, v->y, v->z); -} - -static str_t -fstring_push_quoted(arena_t *arena, fstring_t *s) -{ - ASSERT(arena != NULL); - - if (!s || !s->data || s->len <= 0 || s->len > 4096) { - return STR_LIT("\"\""); - } - - str_t utf8 = str_from_str16(arena, str16_make(s->data, (uint64_t)s->len)); - return str_push_fmt(arena, "\"%.*s\"", STR_ARG(utf8)); -} - -static str_t -fstring_push_plain(arena_t *arena, fstring_t *s) -{ - ASSERT(arena != NULL); - - if (!s || !s->data || s->len <= 0 || s->len > 4096) { - return STR_NULL; - } - - return str_from_str16(arena, str16_make(s->data, (uint64_t)s->len)); -} - -static str_t -ftext_push_summary(arena_t *arena, ftext_t *text) -{ - ASSERT(arena != NULL); - - if (!text || !text->text_data.obj) { - return STR_LIT("null"); - } - - itext_data_t *data = text->text_data.obj; - - str_t result = STR_LIT("\"\""); - tmp_arena_t tmp = scratch_begin(arena); - { - fstring_t *display_string = data->vtable->get_display_string(data); - str_t display = STR_NULL; - - if (display_string) { - display = fstring_push_plain(tmp.arena, display_string); - } - - result = str_push_fmt(arena, "\"%.*s\" Flags=0x%X", STR_ARG(display), (uint32_t)text->flags); - } - scratch_end(tmp); - - return result; -} - -static uobject_t * -detail_weak_object_resolve(detail_fweak_object_ptr_t weak) -{ - if (weak.object_idx < 0 || weak.serial_num <= 0) { - return NULL; - } - - fuobject_item_t *item = unreal_uobject_array_get_item(weak.object_idx); - if (!item || item->serial_num != weak.serial_num) { - return NULL; - } - - if (!unreal_uobject_array_item_is_valid(item)) { - return NULL; - } - - return item->obj; -} static record_t * detail_record_from_uobject(search_tool_t *tool, uobject_t *obj) @@ -1456,12 +1074,12 @@ detail_script_delegate_open_record(search_tool_t *tool, detail_fscript_delegate_ return NULL; } - uobject_t *obj = detail_weak_object_resolve(delegate->object); + uobject_t *obj = unreal_fweak_object_resolve(delegate->object); if (!obj) { return NULL; } - record_t *func_record = detail_record_from_function_name(tool, obj, delegate->func_name); + record_t *func_record = detail_record_from_function_name(tool, obj, delegate->function_name); if (func_record) { return func_record; } @@ -1469,335 +1087,6 @@ detail_script_delegate_open_record(search_tool_t *tool, detail_fscript_delegate_ return detail_record_from_uobject(tool, obj); } -static str_t -weak_object_push_summary(arena_t *arena, detail_fweak_object_ptr_t weak) -{ - ASSERT(arena != NULL); - - if (weak.object_idx < 0 || weak.serial_num <= 0) { - return STR_LIT("null"); - } - - uobject_t *obj = detail_weak_object_resolve(weak); - if (obj) { - return unreal_uobject_push_full_name(obj, arena); - } - - return str_push_fmt(arena, "", weak.object_idx, weak.serial_num); -} - -static str_t -object_ptr_push_summary(arena_t *arena, uobject_t *obj) -{ - ASSERT(arena != NULL); - - if (!obj) { - return STR_LIT("null"); - } - - if (!unreal_uobject_is_valid(obj)) { - return str_push_fmt(arena, "", obj); - } - - return unreal_uobject_push_full_name(obj, arena); -} - -static str_t -soft_object_path_push_summary(arena_t *arena, fsoft_object_path_t *path) -{ - ASSERT(arena != NULL); - - if (!path) { - return STR_LIT("null"); - } - - str_t asset = unreal_fname_to_str(path->asset_path_name, arena); - str_t sub = fstring_push_plain(arena, &path->sub_path_string); - - if (str_is_empty(asset) && str_is_empty(sub)) { - return STR_LIT("null"); - } - - if (str_is_empty(sub)) { - return str_push_fmt(arena, "\"%.*s\"", STR_ARG(asset)); - } - - return str_push_fmt(arena, "\"%.*s:%.*s\"", STR_ARG(asset), STR_ARG(sub)); -} - -static str_t -soft_object_push_summary(arena_t *arena, detail_prop_t *node) -{ - ASSERT(arena != NULL); - ASSERT(node != NULL); - - if (!node->value_addr) { - return STR_NULL; - } - - if (node->size == sizeof(fsoft_object_path_t)) { - return soft_object_path_push_summary(arena, (fsoft_object_path_t *)node->value_addr); - } - - if (node->size >= (int32_t)sizeof(detail_fsoft_object_ptr_t)) { - detail_fsoft_object_ptr_t *ptr = (detail_fsoft_object_ptr_t *)node->value_addr; - uobject_t *obj = detail_weak_object_resolve(ptr->weak); - if (obj) { - return unreal_uobject_push_full_name(obj, arena); - } - - return soft_object_path_push_summary(arena, &ptr->path); - } - - return STR_NULL; -} - -static str_t -lazy_object_push_summary(arena_t *arena, detail_flazy_object_ptr_t *ptr) -{ - ASSERT(arena != NULL); - - if (!ptr) { - return STR_NULL; - } - - uobject_t *obj = detail_weak_object_resolve(ptr->weak); - if (obj) { - return unreal_uobject_push_full_name(obj, arena); - } - - detail_fguid_t *guid = &ptr->object_id; - - if (guid->a == 0 && guid->b == 0 && guid->c == 0 && guid->d == 0) { - return STR_LIT("null"); - } - - return str_push_fmt(arena, "{%08X-%08X-%08X-%08X}", guid->a, guid->b, guid->c, guid->d); -} - -static str_t -interface_push_summary(arena_t *arena, detail_fscript_interface_t *iface) -{ - ASSERT(arena != NULL); - - if (!iface) { - return STR_NULL; - } - - str_t obj = object_ptr_push_summary(arena, iface->object); - return str_push_fmt(arena, "%.*s Interface=%p", STR_ARG(obj), iface->iface); -} - -static str_t -delegate_push_summary(arena_t *arena, detail_fscript_delegate_t *delegate) -{ - ASSERT(arena != NULL); - - if (!delegate) { - return STR_NULL; - } - - str_t func_name = unreal_fname_to_str(delegate->func_name, arena); - str_t obj_name = weak_object_push_summary(arena, delegate->object); - - if (str_is_empty(func_name)) { - return str_push_fmt(arena, "%.*s.", STR_ARG(obj_name)); - } - - return str_push_fmt(arena, "%.*s.%.*s", STR_ARG(obj_name), STR_ARG(func_name)); -} - -static str_t -mcast_delegate_push_summary(arena_t *arena, detail_tarray_view_t *list) -{ - ASSERT(arena != NULL); - - if (!list) { - return STR_NULL; - } - - return str_push_fmt(arena, "Num=%d Max=%d Data=%p", list->num, list->max, list->data); -} - -static str_t -prop_push_hex_summary(arena_t *arena, void *addr, int32_t size) -{ - ASSERT(arena != NULL); - - if (!addr || size <= 0) { - return STR_NULL; - } - - uint8_t *p = (uint8_t *)addr; - - str_t result = STR_NULL; - tmp_arena_t tmp = scratch_begin(arena); - { - str_list_t list = {0}; - - for (int32_t i = 0; i < size; ++i) { - str_list_push(tmp.arena, &list, str_push_fmt(tmp.arena, "%02X", (uint32_t)p[i])); - } - - str_t body = str_list_join(tmp.arena, list, STR_NULL, STR_LIT(" "), STR_NULL); - result = str_push_fmt(arena, "raw bytes (%d): %.*s", size, STR_ARG(body)); - } - scratch_end(tmp); - return result; -} - -static str_t -prop_push_value_summary(search_tool_t *tool, detail_prop_t *node, arena_t *arena) -{ - ASSERT(tool != NULL); - ASSERT(node != NULL); - ASSERT(arena != NULL); - - if (!node) { - return STR_NULL; - } - - ASSERT(node->prop != NULL); - - fprop_t *prop = node->prop; - void *addr = (node->has_value_addr) ? node->value_addr : NULL; - if (!addr) { - return STR_NULL; - } - - str_t result = STR_NULL; - tmp_arena_t tmp = scratch_begin(arena); - { - if (unreal_fprop_class_is(prop, globals.unreal.bool_prop)) { - fprop_bool_t *bp = (fprop_bool_t *)prop; - uint8_t byte = *((uint8_t *)addr + bp->byte_offset); - bool val = (byte & bp->field_mask) != 0; - - result = val ? STR_LIT("true") : STR_LIT("false"); - } else if (unreal_fprop_class_is(prop, globals.unreal.byte_prop)) { - result = str_push_fmt(arena, "%u", (uint32_t)*(uint8_t *)addr); - } else if (unreal_fprop_class_is(prop, globals.unreal.int8_prop)) { - result = str_push_fmt(arena, "%d", (int32_t)*(int8_t *)addr); - } else if (unreal_fprop_class_is(prop, globals.unreal.int16_prop)) { - result = str_push_fmt(arena, "%d", (int32_t)*(int16_t *)addr); - } else if (unreal_fprop_class_is(prop, globals.unreal.int_prop)) { - result = str_push_fmt(arena, "%d", *(int32_t *)addr); - } else if (unreal_fprop_class_is(prop, globals.unreal.int32_prop)) { - result = str_push_fmt(arena, "%d", *(int32_t *)addr); - } else if (unreal_fprop_class_is(prop, globals.unreal.int64_prop)) { - result = str_push_fmt(arena, "%lld", (long long)*(int64_t *)addr); - } else if (unreal_fprop_class_is(prop, globals.unreal.uint16_prop)) { - result = str_push_fmt(arena, "%u", (uint32_t)*(uint16_t *)addr); - } else if (unreal_fprop_class_is(prop, globals.unreal.uint32_prop)) { - result = str_push_fmt(arena, "%u", *(uint32_t *)addr); - } else if (unreal_fprop_class_is(prop, globals.unreal.uint64_prop)) { - result = str_push_fmt(arena, "%llu", (unsigned long long)*(uint64_t *)addr); - } else if (unreal_fprop_class_is(prop, globals.unreal.float_prop)) { - result = str_push_fmt(arena, "%.3f", *(float *)addr); - } else if (unreal_fprop_class_is(prop, globals.unreal.double_prop)) { - result = str_push_fmt(arena, "%.3f", *(double *)addr); - } else if (unreal_fprop_class_is(prop, globals.unreal.name_prop)) { - str_t name = unreal_fname_to_str(*(fname_t *)addr, tmp.arena); - result = str_push_fmt(arena, "\"%.*s\"", STR_ARG(name)); - } else if (unreal_fprop_class_is(prop, globals.unreal.str_prop)) { - result = fstring_push_quoted(arena, (fstring_t *)addr); - } else if (unreal_fprop_class_is(prop, globals.unreal.text_prop)) { - result = ftext_push_summary(arena, (ftext_t *)addr); - } else if (unreal_fprop_class_is(prop, globals.unreal.obj_prop) || unreal_fprop_class_is(prop, globals.unreal.class_prop)) { - result = object_ptr_push_summary(arena, *(uobject_t **)addr); - } else if (unreal_fprop_class_is(prop, globals.unreal.soft_obj_prop) || unreal_fprop_class_is(prop, globals.unreal.soft_class_prop)) { - result = soft_object_push_summary(arena, node); - } else if (unreal_fprop_class_is(prop, globals.unreal.weak_obj_prop)) { - result = weak_object_push_summary(arena, *(detail_fweak_object_ptr_t *)addr); - } else if (unreal_fprop_class_is(prop, globals.unreal.lazy_obj_prop)) { - result = lazy_object_push_summary(arena, (detail_flazy_object_ptr_t *)addr); - } else if (unreal_fprop_class_is(prop, globals.unreal.interface_prop)) { - result = interface_push_summary(arena, (detail_fscript_interface_t *)addr); - } else if (unreal_fprop_class_is(prop, globals.unreal.delegate_prop)) { - result = delegate_push_summary(arena, (detail_fscript_delegate_t *)addr); - } else if (unreal_fprop_class_is(prop, globals.unreal.mcast_delegate_prop)) { - result = mcast_delegate_push_summary(arena, (detail_tarray_view_t *)addr); - } else if (unreal_fprop_class_is(prop, globals.unreal.mcast_inline_delegate_prop)) { - result = mcast_delegate_push_summary(arena, (detail_tarray_view_t *)addr); - } else if (unreal_fprop_class_is(prop, globals.unreal.mcast_sparse_delegate_prop)) { - result = str_push_fmt(arena, "SparseDelegate 0x%02X", (uint32_t)*(uint8_t *)addr); - } else if (unreal_fprop_class_is(prop, globals.unreal.obj_prop) || unreal_fprop_class_is(prop, globals.unreal.class_prop)) { - uobject_t *obj = *(uobject_t **)addr; - if (!obj) { - result = STR_LIT("null"); - } else if (!unreal_uobject_is_valid(obj)) { - result = STR_LIT(""); - } else { - result = unreal_uobject_push_full_name(obj, arena); - } - } else if (unreal_fprop_class_is(prop, globals.unreal.struct_prop)) { - fprop_struct_t *sp = (fprop_struct_t *)prop; - - if (fprop_struct_is(prop, globals.unreal.vector) || fprop_struct_is(prop, globals.unreal.vector_net_quantize) || - fprop_struct_is(prop, globals.unreal.vector_net_quantize10) || fprop_struct_is(prop, globals.unreal.vector_net_quantize100) || - fprop_struct_is(prop, globals.unreal.vector_net_quantize_normal)) { - result = fvector_push_summary(arena, addr); - } else if (fprop_struct_is(prop, globals.unreal.vector2d)) { - result = fvector2d_push_summary(arena, addr); - } else if (fprop_struct_is(prop, globals.unreal.vector4)) { - result = fvector4_push_summary(arena, addr); - } else if (fprop_struct_is(prop, globals.unreal.rotator)) { - result = frotator_push_summary(arena, addr); - } else if (fprop_struct_is(prop, globals.unreal.quat)) { - result = fquat_push_summary(arena, addr); - } else if (fprop_struct_is(prop, globals.unreal.color)) { - result = fcolor_push_summary(arena, addr); - } else if (fprop_struct_is(prop, globals.unreal.linear_color)) { - result = flinear_color_push_summary(arena, addr); - } else if (fprop_struct_is(prop, globals.unreal.key)) { - result = fkey_push_summary(arena, addr); - } else if (fprop_struct_is(prop, globals.unreal.gameplay_tag)) { - result = fgameplay_tag_push_summary(arena, addr); - } else if (fprop_struct_is(prop, globals.unreal.gameplay_tag_container)) { - result = fgameplay_tag_container_push_summary(arena, addr); - } else if (fprop_struct_is(prop, globals.unreal.guid)) { - result = fguid_push_summary(arena, addr); - } else if (fprop_struct_is(prop, globals.unreal.int_point)) { - result = fint_point_push_summary(arena, addr); - } else if (fprop_struct_is(prop, globals.unreal.int_vector)) { - result = fint_vector_push_summary(arena, addr); - } else if (sp && sp->script_struct && sp->script_struct->child_props != NULL) { - result = STR_LIT("{...}"); - } else { - str_t hex = prop_push_hex_summary(arena, addr, node->size); - result = str_push_fmt(arena, " %.*s", STR_ARG(hex)); - } - } else if (unreal_fprop_class_is(prop, globals.unreal.array_prop)) { - detail_tarray_view_t *array = (detail_tarray_view_t *)addr; - result = str_push_fmt(arena, "Num=%d Max=%d Data=%p", array->num, array->max, array->data); - } else if (unreal_fprop_class_is(prop, globals.unreal.set_prop)) { - result = STR_LIT("Num=?"); - } else if (unreal_fprop_class_is(prop, globals.unreal.map_prop)) { - result = STR_LIT("Num=?"); - } else if (unreal_fprop_class_is(prop, globals.unreal.enum_prop)) { - fprop_enum_t *ep = (fprop_enum_t *)prop; - fprop_t *underlying = ep->underlying_prop ? &ep->underlying_prop->base : NULL; - if (!underlying) { - result = STR_LIT(""); - } else { - int64_t value = fprop_read_int_value(underlying, addr); - str_t name = detail_enum_value_name(tmp.arena, ep->uenum, value); - - if (!str_is_empty(name)) { - result = str_push_fmt(arena, "%.*s (%lld)", STR_ARG(name), (long long)value); - } else { - result = str_push_fmt(arena, "%lld", (long long)value); - } - } - } - - if (str_is_empty(result)) { - result = prop_push_hex_summary(arena, addr, node->size); - } - } - scratch_end(tmp); - return result; -} static bool tarray_children_match(detail_prop_t *node, int32_t num) @@ -1813,81 +1102,72 @@ tarray_children_match(detail_prop_t *node, int32_t num) node->live_slot_count == count; } -static inline bool -tset_children_match(detail_prop_t *node, int32_t live_count, int32_t slot_count) -{ - return node && - node->children_kind == DETAIL_PROP_CHILDREN_SET_ELEMS && - node->live_child_count == live_count && - node->live_slot_count == slot_count; -} - -static inline bool -tmap_children_match(detail_prop_t *node, int32_t live_count, int32_t slot_count) -{ - return node && - node->children_kind == DETAIL_PROP_CHILDREN_MAP_PAIRS && - node->live_child_count == live_count && - node->live_slot_count == slot_count; -} - static bool -mcast_delegate_children_match(detail_prop_t *node, int32_t num) +tset_children_match(detail_prop_t *node, const void *set, fprop_set_t *prop, int32_t live_count, int32_t slot_count) { - if (!node) { + if (!node || node->children_kind != DETAIL_PROP_CHILDREN_SET_ELEMS || + node->live_child_count != live_count || node->live_slot_count != slot_count) { return false; } - int32_t count = MIN_VAL(num, DETAIL_MAX_CONTAINER_ELEMS); + detail_prop_t *child = node->first_child; + int32_t emitted = 0; + for (int32_t idx = 0; idx < slot_count && emitted < DETAIL_MAX_CONTAINER_ELEMS; ++idx) { + if (!unreal_set_is_valid_index(set, prop, idx)) { + continue; + } - return node->children_kind == DETAIL_PROP_CHILDREN_MCAST_DELEGATE && - node->live_child_count == num && - node->live_slot_count == count; -} + if (!child || child->live_slot_idx != idx) { + return false; + } -static uint32_t * -bit_array_words(tbit_array_t *bits) -{ - ASSERT(bits != NULL); - if (bits->max_bits <= (int32_t)(COUNTOF(bits->allocator.inline_data) * 32)) { - return bits->allocator.inline_data; + child = child->next; + emitted += 1; } - return (uint32_t *)bits->allocator.secondary_data; + return child == NULL; } static bool -tsparse_is_allocated(detail_tsparse_view_t *sparse, int32_t idx) +tmap_children_match(detail_prop_t *node, const void *map, fprop_map_t *prop, int32_t live_count, int32_t slot_count) { - if (!sparse || idx < 0 || idx >= sparse->alloc_flags.num_bits) { + if (!node || node->children_kind != DETAIL_PROP_CHILDREN_MAP_PAIRS || + node->live_child_count != live_count || node->live_slot_count != slot_count) { return false; } - uint32_t *words = bit_array_words(&sparse->alloc_flags); - if (!words) { - return false; - } + detail_prop_t *child = node->first_child; + int32_t emitted = 0; + for (int32_t idx = 0; idx < slot_count && emitted < DETAIL_MAX_CONTAINER_ELEMS; ++idx) { + if (!unreal_map_is_valid_index(map, prop, idx)) { + continue; + } - uint32_t word = words[idx / 32]; - uint32_t mask = 1U << (idx % 32); - return (word & mask) != 0; + if (!child || child->live_slot_idx != idx) { + return false; + } + + child = child->next; + emitted += 1; + } + return child == NULL; } -static int32_t -tsparse_live_count(detail_tsparse_view_t *sparse) +static bool +mcast_delegate_children_match(detail_prop_t *node, int32_t num) { - if (!sparse) { - return 0; + if (!node) { + return false; } - if (sparse->data.num < 0 || sparse->num_free_idx < 0 || sparse->num_free_idx > sparse->data.num) { - return 0; - } + int32_t count = MIN_VAL(num, DETAIL_MAX_CONTAINER_ELEMS); - return sparse->data.num - sparse->num_free_idx; + return node->children_kind == DETAIL_PROP_CHILDREN_MCAST_DELEGATE && + node->live_child_count == num && + node->live_slot_count == count; } static void -tarray_rebuild_children(search_tool_t *tool, detail_tab_t *tab, detail_prop_t *node, fprop_array_t *array_prop, detail_tarray_view_t *array, int32_t depth) +tarray_rebuild_children(search_tool_t *tool, detail_tab_t *tab, detail_prop_t *node, fprop_array_t *array_prop, void *array, int32_t num, int32_t depth) { ASSERT(tool != NULL); ASSERT(tab != NULL); @@ -1897,13 +1177,13 @@ tarray_rebuild_children(search_tool_t *tool, detail_tab_t *tab, detail_prop_t *n detail_prop_clear_runtime_children(tab, node); - int count = MIN_VAL(array->num, DETAIL_MAX_CONTAINER_ELEMS); + int count = MIN_VAL(num, DETAIL_MAX_CONTAINER_ELEMS); node->children_kind = DETAIL_PROP_CHILDREN_ARRAY_ELEMS; - node->live_child_count = array->num; + node->live_child_count = num; node->live_slot_count = count; - if (!array->data || count <= 0) { + if (count <= 0) { return; } @@ -1914,7 +1194,7 @@ tarray_rebuild_children(search_tool_t *tool, detail_tab_t *tab, detail_prop_t *n for (int i = 0; i < count; ++i) { int32_t elem_offset = i * elem_size; - uint8_t *elem_addr = (uint8_t *)array->data + elem_offset; + uint8_t *elem_addr = (uint8_t *)unreal_array_get(array, array_prop, i); detail_prop_t *elem = detail_prop_push_array_elem(tool, tab, inner, i, elem_addr, elem_offset, depth + 1, false, true); if (elem) { @@ -1925,25 +1205,25 @@ tarray_rebuild_children(search_tool_t *tool, detail_tab_t *tab, detail_prop_t *n static void tset_rebuild_children( - search_tool_t *tool, detail_tab_t *tab, detail_prop_t *node, fprop_set_t *set_prop, detail_tset_view_t *set, int32_t live_count, int32_t slot_count, int32_t depth) + search_tool_t *tool, detail_tab_t *tab, detail_prop_t *node, fprop_set_t *set_prop, void *set, int32_t live_count, int32_t slot_count, int32_t depth) { detail_prop_clear_runtime_children(tab, node); node->children_kind = DETAIL_PROP_CHILDREN_SET_ELEMS; node->live_child_count = live_count; node->live_slot_count = slot_count; - if (!set->elems.data.data || slot_count <= 0 || live_count <= 0) { + if (slot_count <= 0 || live_count <= 0) { return; } fprop_t *set_elem = set_prop->elem_prop; - int32_t elem_size = set_prop->set_layout.size; - ASSERT(elem_size > 0); + int32_t slot_size = set_prop->set_layout.sparse_array_layout.size; + ASSERT(slot_size > 0); int32_t emitted = 0; for (int32_t i = 0; i < slot_count; ++i) { - if (!tsparse_is_allocated(&set->elems, i)) { + if (!unreal_set_is_valid_index(set, set_prop, i)) { continue; } @@ -1951,8 +1231,8 @@ tset_rebuild_children( break; } - int32_t elem_offset = i * elem_size; - uint8_t *elem_addr = (uint8_t *)set->elems.data.data + elem_offset; + int32_t elem_offset = i * slot_size; + uint8_t *elem_addr = (uint8_t *)unreal_set_get(set, set_prop, i); detail_prop_t *elem = detail_prop_push_set_elem(tool, tab, set_elem, i, elem_addr, elem_offset, depth + 1, false, true); if (elem) { @@ -1965,23 +1245,23 @@ tset_rebuild_children( static void tmap_rebuild_children( - search_tool_t *tool, detail_tab_t *tab, detail_prop_t *node, fprop_map_t *map_prop, detail_tset_view_t *set, int32_t live_count, int32_t slot_count, int32_t depth) + search_tool_t *tool, detail_tab_t *tab, detail_prop_t *node, fprop_map_t *map_prop, void *map, int32_t live_count, int32_t slot_count, int32_t depth) { detail_prop_clear_runtime_children(tab, node); node->children_kind = DETAIL_PROP_CHILDREN_MAP_PAIRS; node->live_child_count = live_count; node->live_slot_count = slot_count; - if (!set->elems.data.data || slot_count <= 0 || live_count <= 0) { + if (slot_count <= 0 || live_count <= 0) { return; } - int32_t pair_size = map_prop->map_layout.set_layout.size; - ASSERT(pair_size > 0); + int32_t slot_size = map_prop->map_layout.set_layout.sparse_array_layout.size; + ASSERT(slot_size > 0); int32_t emitted = 0; for (int32_t i = 0; i < slot_count; ++i) { - if (!tsparse_is_allocated(&set->elems, i)) { + if (!unreal_map_is_valid_index(map, map_prop, i)) { continue; } @@ -1989,10 +1269,11 @@ tmap_rebuild_children( break; } - int32_t pair_offset = i * pair_size; - uint8_t *pair_addr = (uint8_t *)set->elems.data.data + pair_offset; + int32_t pair_offset = i * slot_size; + uint8_t *key_addr = (uint8_t *)unreal_map_get_key(map, map_prop, i); + uint8_t *val_addr = (uint8_t *)unreal_map_get_value(map, map_prop, i); - detail_prop_t *pair = detail_prop_push_map_pair(tool, tab, map_prop, i, pair_addr, pair_offset, depth + 1, false, true); + detail_prop_t *pair = detail_prop_push_map_pair(tool, tab, map_prop, i, key_addr, val_addr, pair_offset, depth + 1, false, true); if (pair) { pair->live_slot_idx = i; QUEUE_PUSH(node->first_child, node->last_child, pair); @@ -2048,38 +1329,29 @@ detail_prop_open_record(search_tool_t *tool, detail_prop_t *node) fprop_t *prop = node->prop; void *addr = node->value_addr; - if (unreal_fprop_class_is(prop, globals.unreal.obj_prop) || unreal_fprop_class_is(prop, globals.unreal.class_prop)) { - return detail_record_from_uobject(tool, *(uobject_t **)addr); - } - - if (unreal_fprop_class_is(prop, globals.unreal.weak_obj_prop)) { - detail_fweak_object_ptr_t weak = *(detail_fweak_object_ptr_t *)addr; - return detail_record_from_uobject(tool, detail_weak_object_resolve(weak)); - } - - if (unreal_fprop_class_is(prop, globals.unreal.lazy_obj_prop)) { - detail_flazy_object_ptr_t *ptr = (detail_flazy_object_ptr_t *)addr; - return detail_record_from_uobject(tool, detail_weak_object_resolve(ptr->weak)); - } - - if (unreal_fprop_class_is(prop, globals.unreal.interface_prop)) { - detail_fscript_interface_t *iface = (detail_fscript_interface_t *)addr; - return detail_record_from_uobject(tool, iface->object); - } + switch (unreal_fprop_get_kind(prop)) { + case UNREAL_PROP_KIND_OBJECT: + case UNREAL_PROP_KIND_CLASS: + case UNREAL_PROP_KIND_WEAK_OBJECT: + case UNREAL_PROP_KIND_LAZY_OBJECT: + case UNREAL_PROP_KIND_SOFT_OBJECT: + case UNREAL_PROP_KIND_SOFT_CLASS: + case UNREAL_PROP_KIND_INTERFACE: { + return node->size >= prop->elem_size && prop->elem_size > 0 + ? detail_record_from_uobject(tool, unreal_fprop_get_referenced_object(prop, addr)) + : NULL; + } - if (unreal_fprop_class_is(prop, globals.unreal.delegate_prop)) { - return detail_script_delegate_open_record(tool, (detail_fscript_delegate_t *)addr); - } + case UNREAL_PROP_KIND_DELEGATE: { + return node->size >= (int32_t)sizeof(detail_fscript_delegate_t) + ? detail_script_delegate_open_record(tool, (detail_fscript_delegate_t *)addr) + : NULL; + } - if (unreal_fprop_class_is(prop, globals.unreal.soft_obj_prop) || unreal_fprop_class_is(prop, globals.unreal.soft_class_prop)) { - if (node->size >= (int32_t)sizeof(detail_fsoft_object_ptr_t)) { - detail_fsoft_object_ptr_t *ptr = (detail_fsoft_object_ptr_t *)addr; - return detail_record_from_uobject(tool, detail_weak_object_resolve(ptr->weak)); + default: { + return NULL; } - return NULL; } - - return NULL; } static void @@ -2122,6 +1394,22 @@ detail_prop_refresh_runtime_text(search_tool_t *tool, detail_tab_t *tab, detail_ node->size_text = ui_text_span_make(tool->ctx, str_push_fmt(arena, "0x%04X", (uint32_t)node->size)); } +static void +detail_prop_invalidate_value_tree(detail_prop_t *node) +{ + if (!node) { + return; + } + + node->has_value_addr = false; + node->value_addr = NULL; + node->record_to_open = NULL; + + for (detail_prop_t *child = node->first_child; child; child = child->next) { + detail_prop_invalidate_value_tree(child); + } +} + void detail_prop_fill_value_tarray_children(search_tool_t *tool, detail_tab_t *tab, detail_prop_t *node, fprop_array_t *array_prop, int32_t depth) { @@ -2139,18 +1427,20 @@ detail_prop_fill_value_tarray_children(search_tool_t *tool, detail_tab_t *tab, d ASSERT(array_prop != NULL); ASSERT(array_prop->inner != NULL); - detail_tarray_view_t *array = (detail_tarray_view_t *)node->value_addr; - - int32_t num = array->num; - int32_t max = array->max; - - ASSERT(num >= 0); - ASSERT(max >= 0); - ASSERT(num <= max); + void *array = node->value_addr; + int32_t num = unreal_array_num(array, array_prop); + node->summary = ui_text_span_make(tool->ctx, unreal_fprop_push_value_summary(&array_prop->base, array, node->size, arena)); - node->summary = ui_text_span_make(tool->ctx, str_push_fmt(arena, "Num=%d Max=%d Data=%p", num, max, array->data)); + if (num < 0) { + detail_prop_clear_runtime_children(tab, node); + node->children_kind = DETAIL_PROP_CHILDREN_ARRAY_ELEMS; + node->live_child_count = 0; + node->live_slot_count = 0; + node->maximized = false; + return; + } - if (!array->data || num == 0 || max == 0) { + if (num == 0) { detail_prop_clear_runtime_children(tab, node); node->children_kind = DETAIL_PROP_CHILDREN_ARRAY_ELEMS; node->live_child_count = 0; @@ -2160,7 +1450,7 @@ detail_prop_fill_value_tarray_children(search_tool_t *tool, detail_tab_t *tab, d } if (!tarray_children_match(node, num)) { - tarray_rebuild_children(tool, tab, node, array_prop, array, depth); + tarray_rebuild_children(tool, tab, node, array_prop, array, num, depth); } if (!node->maximized && !tab->force_expand_values) { @@ -2184,8 +1474,15 @@ detail_prop_fill_value_tarray_children(search_tool_t *tool, detail_tab_t *tab, d elem->offset = elem_offset; elem->size = elem_size; - elem->has_value_addr = true; - elem->value_addr = (uint8_t *)array->data + elem_offset; + elem->value_addr = unreal_array_get(array, array_prop, elem_idx); + elem->has_value_addr = elem->value_addr != NULL; + + if (!elem->has_value_addr) { + detail_prop_invalidate_value_tree(elem); + elem->summary = ui_text_span_make(tool->ctx, STR_LIT("")); + elem_idx += 1; + continue; + } detail_prop_refresh_runtime_text(tool, tab, elem, str_push_fmt(tab->value_arena, "[%d]", elem_idx)); detail_prop_fill_value_direct(tool, tab, elem, depth + 1); @@ -2211,19 +1508,21 @@ detail_prop_fill_value_tset_children(search_tool_t *tool, detail_tab_t *tab, det ASSERT(set_prop != NULL); ASSERT(set_prop->elem_prop != NULL); - detail_tset_view_t *set = (detail_tset_view_t *)node->value_addr; - - int live_count = tsparse_live_count(&set->elems); - int slot_count = set->elems.data.num; - - ASSERT(set->elems.data.max >= 0); - ASSERT(slot_count >= 0); - ASSERT(live_count >= 0); - ASSERT(live_count <= slot_count); + void *set = node->value_addr; + int32_t live_count = unreal_set_num(set, set_prop); + int32_t slot_count = unreal_set_max_index(set, set_prop); + node->summary = ui_text_span_make(tool->ctx, unreal_fprop_push_value_summary(&set_prop->base, set, node->size, arena)); - node->summary = ui_text_span_make(tool->ctx, str_push_fmt(arena, "Num=%d Slots=%d Max=%d HashSize=%d", live_count, slot_count, set->elems.data.max, set->hash_size)); + if (live_count < 0 || slot_count < 0) { + detail_prop_clear_runtime_children(tab, node); + node->children_kind = DETAIL_PROP_CHILDREN_SET_ELEMS; + node->live_child_count = 0; + node->live_slot_count = 0; + node->maximized = false; + return; + } - if (!set->elems.data.data || slot_count == 0 || live_count == 0) { + if (slot_count == 0 || live_count == 0) { detail_prop_clear_runtime_children(tab, node); node->children_kind = DETAIL_PROP_CHILDREN_SET_ELEMS; node->live_child_count = 0; @@ -2232,7 +1531,7 @@ detail_prop_fill_value_tset_children(search_tool_t *tool, detail_tab_t *tab, det return; } - if (!tset_children_match(node, live_count, slot_count)) { + if (!tset_children_match(node, set, set_prop, live_count, slot_count)) { tset_rebuild_children(tool, tab, node, set_prop, set, live_count, slot_count, depth); } @@ -2240,8 +1539,10 @@ detail_prop_fill_value_tset_children(search_tool_t *tool, detail_tab_t *tab, det return; } - int elem_size = set_prop->set_layout.size; + int elem_size = set_prop->elem_prop->elem_size; + int slot_size = set_prop->set_layout.sparse_array_layout.size; ASSERT(elem_size > 0); + ASSERT(slot_size > 0); for (detail_prop_t *elem = node->first_child; elem; elem = elem->next) { if (!elem->prop) { @@ -2252,17 +1553,18 @@ detail_prop_fill_value_tset_children(search_tool_t *tool, detail_tab_t *tab, det ASSERT(slot_idx >= 0); ASSERT(slot_idx < slot_count); - if (!tsparse_is_allocated(&set->elems, slot_idx)) { + elem->value_addr = (void *)unreal_set_get(set, set_prop, slot_idx); + elem->has_value_addr = elem->value_addr != NULL; + if (!elem->has_value_addr) { + detail_prop_invalidate_value_tree(elem); elem->summary = ui_text_span_make(tool->ctx, STR_LIT("")); continue; } - int elem_offset = slot_idx * elem_size; + int elem_offset = slot_idx * slot_size; elem->offset = elem_offset; elem->size = elem_size; - elem->has_value_addr = true; - elem->value_addr = (uint8_t *)set->elems.data.data + elem_offset; detail_prop_refresh_runtime_text(tool, tab, elem, str_push_fmt(tab->value_arena, "[%d]", slot_idx)); detail_prop_fill_value_direct(tool, tab, elem, depth + 1); @@ -2285,19 +1587,21 @@ detail_prop_fill_value_tmap_children(search_tool_t *tool, detail_tab_t *tab, det ASSERT(node->value_addr != NULL); ASSERT(map_prop != NULL); - detail_tset_view_t *set = (detail_tset_view_t *)node->value_addr; - - int live_count = tsparse_live_count(&set->elems); - int slot_count = set->elems.data.num; - - ASSERT(set->elems.data.max >= 0); - ASSERT(slot_count >= 0); - ASSERT(live_count >= 0); - ASSERT(live_count <= slot_count); + void *map = node->value_addr; + int32_t live_count = unreal_map_num(map, map_prop); + int32_t slot_count = unreal_map_max_index(map, map_prop); + node->summary = ui_text_span_make(tool->ctx, unreal_fprop_push_value_summary(&map_prop->base, map, node->size, arena)); - node->summary = ui_text_span_make(tool->ctx, str_push_fmt(arena, "Num=%d Slots=%d Max=%d HashSize=%d", live_count, slot_count, set->elems.data.max, set->hash_size)); + if (live_count < 0 || slot_count < 0) { + detail_prop_clear_runtime_children(tab, node); + node->children_kind = DETAIL_PROP_CHILDREN_MAP_PAIRS; + node->live_child_count = 0; + node->live_slot_count = 0; + node->maximized = false; + return; + } - if (!set->elems.data.data || slot_count == 0 || live_count == 0) { + if (slot_count == 0 || live_count == 0) { detail_prop_clear_runtime_children(tab, node); node->children_kind = DETAIL_PROP_CHILDREN_MAP_PAIRS; node->live_child_count = 0; @@ -2306,8 +1610,8 @@ detail_prop_fill_value_tmap_children(search_tool_t *tool, detail_tab_t *tab, det return; } - if (!tmap_children_match(node, live_count, slot_count)) { - tmap_rebuild_children(tool, tab, node, map_prop, set, live_count, slot_count, depth); + if (!tmap_children_match(node, map, map_prop, live_count, slot_count)) { + tmap_rebuild_children(tool, tab, node, map_prop, map, live_count, slot_count, depth); } if (!node->maximized && !tab->force_expand_values) { @@ -2315,7 +1619,9 @@ detail_prop_fill_value_tmap_children(search_tool_t *tool, detail_tab_t *tab, det } int pair_size = map_prop->map_layout.set_layout.size; + int slot_size = map_prop->map_layout.set_layout.sparse_array_layout.size; ASSERT(pair_size > 0); + ASSERT(slot_size > 0); for (detail_prop_t *pair = node->first_child; pair; pair = pair->next) { if (!pair->first_child) { @@ -2326,18 +1632,20 @@ detail_prop_fill_value_tmap_children(search_tool_t *tool, detail_tab_t *tab, det ASSERT(slot_idx >= 0); ASSERT(slot_idx < slot_count); - if (!tsparse_is_allocated(&set->elems, slot_idx)) { + uint8_t *key_addr = (uint8_t *)unreal_map_get_key(map, map_prop, slot_idx); + uint8_t *val_addr = (uint8_t *)unreal_map_get_value(map, map_prop, slot_idx); + if (!key_addr || !val_addr) { + detail_prop_invalidate_value_tree(pair); pair->summary = ui_text_span_make(tool->ctx, STR_LIT("")); continue; } - int pair_offset = slot_idx * pair_size; - uint8_t *pair_addr = (uint8_t *)set->elems.data.data + pair_offset; + int pair_offset = slot_idx * slot_size; pair->offset = pair_offset; pair->size = pair_size; pair->has_value_addr = true; - pair->value_addr = pair_addr; + pair->value_addr = key_addr; pair->summary = ui_text_span_make(tool->ctx, STR_LIT("{...}")); { @@ -2357,7 +1665,7 @@ detail_prop_fill_value_tmap_children(search_tool_t *tool, detail_tab_t *tab, det key->offset = 0; key->size = map_prop->key_prop->elem_size; key->has_value_addr = true; - key->value_addr = pair_addr; + key->value_addr = key_addr; detail_prop_refresh_runtime_text(tool, tab, key, STR_LIT("Key")); detail_prop_fill_value_direct(tool, tab, key, depth + 2); @@ -2368,7 +1676,7 @@ detail_prop_fill_value_tmap_children(search_tool_t *tool, detail_tab_t *tab, det val->offset = map_prop->map_layout.value_offset; val->size = map_prop->val_prop->elem_size; val->has_value_addr = true; - val->value_addr = pair_addr + map_prop->map_layout.value_offset; + val->value_addr = val_addr; detail_prop_refresh_runtime_text(tool, tab, val, STR_LIT("Value")); detail_prop_fill_value_direct(tool, tab, val, depth + 2); @@ -2436,7 +1744,7 @@ detail_prop_fill_value_mcast_delegate_children(search_tool_t *tool, detail_tab_t elem->type = ui_text_span_make(tool->ctx, STR_LIT("DelegateBinding")); elem->offset_text = ui_text_span_make(tool->ctx, str_push_fmt(arena, "0x%04X", (uint32_t)elem->offset)); elem->size_text = ui_text_span_make(tool->ctx, str_push_fmt(arena, "0x%04X", (uint32_t)elem->size)); - elem->summary = ui_text_span_make(tool->ctx, delegate_push_summary(arena, d)); + elem->summary = ui_text_span_make(tool->ctx, unreal_fscript_delegate_push_summary((fscript_delegate_t *)d, arena)); elem->record_to_open = detail_script_delegate_open_record(tool, d); } @@ -2513,7 +1821,7 @@ detail_prop_fill_value_sparse_mcast_delegate_children(search_tool_t *tool, detai elem->type = ui_text_span_make(tool->ctx, STR_LIT("DelegateBinding")); elem->offset_text = ui_text_span_make(tool->ctx, str_push_fmt(arena, "0x%04X", (uint32_t)elem->offset)); elem->size_text = ui_text_span_make(tool->ctx, str_push_fmt(arena, "0x%04X", (uint32_t)elem->size)); - elem->summary = ui_text_span_make(tool->ctx, delegate_push_summary(arena, d)); + elem->summary = ui_text_span_make(tool->ctx, unreal_fscript_delegate_push_summary((fscript_delegate_t *)d, arena)); elem->record_to_open = detail_script_delegate_open_record(tool, d); } } @@ -2532,24 +1840,41 @@ detail_prop_fill_value_direct(search_tool_t *tool, detail_tab_t *tab, detail_pro node->record_to_open = NULL; node->summary = ui_text_span_make(tool->ctx, STR_NULL); - fprop_t *p = node->prop; - - if (unreal_fprop_class_is(p, globals.unreal.array_prop)) { - detail_prop_fill_value_tarray_children(tool, tab, node, (fprop_array_t *)p, depth); - } else if (unreal_fprop_class_is(p, globals.unreal.set_prop)) { - detail_prop_fill_value_tset_children(tool, tab, node, (fprop_set_t *)p, depth); - } else if (unreal_fprop_class_is(p, globals.unreal.map_prop)) { - detail_prop_fill_value_tmap_children(tool, tab, node, (fprop_map_t *)p, depth); - } else if (unreal_fprop_class_is(p, globals.unreal.mcast_delegate_prop) || unreal_fprop_class_is(p, globals.unreal.mcast_inline_delegate_prop)) { - detail_prop_fill_value_mcast_delegate_children(tool, tab, node, depth); - } else if (unreal_fprop_class_is(p, globals.unreal.mcast_sparse_delegate_prop)) { - detail_prop_fill_value_sparse_mcast_delegate_children(tool, tab, node, depth); - } else { - node->summary = ui_text_span_make(tool->ctx, prop_push_value_summary(tool, node, tab->value_arena)); - node->record_to_open = detail_prop_open_record(tool, node); + switch (unreal_fprop_get_kind(node->prop)) { + case UNREAL_PROP_KIND_ARRAY: { + detail_prop_fill_value_tarray_children(tool, tab, node, (fprop_array_t *)node->prop, depth); + break; + } + + case UNREAL_PROP_KIND_SET: { + detail_prop_fill_value_tset_children(tool, tab, node, (fprop_set_t *)node->prop, depth); + break; + } + + case UNREAL_PROP_KIND_MAP: { + detail_prop_fill_value_tmap_children(tool, tab, node, (fprop_map_t *)node->prop, depth); + break; + } + + case UNREAL_PROP_KIND_MULTICAST_DELEGATE: + case UNREAL_PROP_KIND_MULTICAST_INLINE_DELEGATE: { + detail_prop_fill_value_mcast_delegate_children(tool, tab, node, depth); + break; + } + + case UNREAL_PROP_KIND_MULTICAST_SPARSE_DELEGATE: { + detail_prop_fill_value_sparse_mcast_delegate_children(tool, tab, node, depth); + break; + } + + default: { + node->summary = ui_text_span_make(tool->ctx, unreal_fprop_push_value_summary(node->prop, node->value_addr, node->size, tab->value_arena)); + node->record_to_open = detail_prop_open_record(tool, node); - if (node->first_child && (node->maximized || tab->force_expand_values)) { - detail_prop_fill_value_from_base(tool, tab, node->first_child, node->value_addr, depth + 1); + if (node->first_child && (node->maximized || tab->force_expand_values)) { + detail_prop_fill_value_from_base(tool, tab, node->first_child, node->value_addr, depth + 1); + } + break; } } @@ -2577,8 +1902,14 @@ detail_prop_fill_value_from_base(search_tool_t *tool, detail_tab_t *tab, detail_ continue; } - prop->has_value_addr = true; - prop->value_addr = base + prop->offset; + prop->value_addr = unreal_fprop_value_in_container(prop->prop, base, 0); + prop->has_value_addr = prop->value_addr != NULL; + + if (!prop->has_value_addr) { + detail_prop_invalidate_value_tree(prop); + prop->summary = ui_text_span_make(tool->ctx, STR_LIT("")); + continue; + } if (prop->runtime_node) { detail_prop_refresh_runtime_text(tool, tab, prop, unreal_fname_to_str(prop->prop->name, tab->value_arena)); diff --git a/src/builtin/search.c b/src/builtin/search.c index cac947f..4991199 100644 --- a/src/builtin/search.c +++ b/src/builtin/search.c @@ -2,6 +2,7 @@ #include "uobject_search_internal.h" #include "globals.h" +#include "unreal_prop.h" bool uobject_item_matches_record(fuobject_item_t *item, record_t *record) @@ -60,83 +61,77 @@ prop_matches_query(search_tool_t *tool, fprop_t *prop) return true; } - if (unreal_fprop_class_is(prop, globals.unreal.struct_prop)) { - fprop_struct_t *p = (fprop_struct_t *)prop; - - if (query_matches_uobject_name(tool, (uobject_t *)p->script_struct)) { - return true; + switch (unreal_fprop_get_kind(prop)) { + case UNREAL_PROP_KIND_STRUCT: { + fprop_struct_t *p = (fprop_struct_t *)prop; + return query_matches_uobject_name(tool, (uobject_t *)p->script_struct); } - } else if (unreal_fprop_class_is(prop, globals.unreal.array_prop)) { - fprop_array_t *p = (fprop_array_t *)prop; - if (prop_matches_query(tool, p->inner)) { - return true; + case UNREAL_PROP_KIND_ARRAY: { + fprop_array_t *p = (fprop_array_t *)prop; + return prop_matches_query(tool, p->inner); } - } else if (unreal_fprop_class_is(prop, globals.unreal.set_prop)) { - fprop_set_t *p = (fprop_set_t *)prop; - if (prop_matches_query(tool, p->elem_prop)) { - return true; + case UNREAL_PROP_KIND_SET: { + fprop_set_t *p = (fprop_set_t *)prop; + return prop_matches_query(tool, p->elem_prop); } - } else if (unreal_fprop_class_is(prop, globals.unreal.map_prop)) { - fprop_map_t *p = (fprop_map_t *)prop; - if (prop_matches_query(tool, p->key_prop) || prop_matches_query(tool, p->val_prop)) { - return true; + case UNREAL_PROP_KIND_MAP: { + fprop_map_t *p = (fprop_map_t *)prop; + return prop_matches_query(tool, p->key_prop) || prop_matches_query(tool, p->val_prop); } - } else if (unreal_fprop_class_is(prop, globals.unreal.obj_prop) || - unreal_fprop_class_is(prop, globals.unreal.weak_obj_prop) || - unreal_fprop_class_is(prop, globals.unreal.lazy_obj_prop) || - unreal_fprop_class_is(prop, globals.unreal.soft_obj_prop)) { - fprop_obj_base_t *p = (fprop_obj_base_t *)prop; - if (query_matches_uobject_name(tool, (uobject_t *)p->prop_class)) { - return true; + case UNREAL_PROP_KIND_OBJECT: + case UNREAL_PROP_KIND_WEAK_OBJECT: + case UNREAL_PROP_KIND_LAZY_OBJECT: + case UNREAL_PROP_KIND_SOFT_OBJECT: { + fprop_obj_base_t *p = (fprop_obj_base_t *)prop; + return query_matches_uobject_name(tool, (uobject_t *)p->prop_class); } - } else if (unreal_fprop_class_is(prop, globals.unreal.class_prop)) { - fprop_class_t *p = (fprop_class_t *)prop; - if (query_matches_uobject_name(tool, (uobject_t *)p->base.base.prop_class) || query_matches_uobject_name(tool, (uobject_t *)p->meta_class)) { - return true; + case UNREAL_PROP_KIND_CLASS: { + fprop_class_t *p = (fprop_class_t *)prop; + return query_matches_uobject_name(tool, (uobject_t *)p->base.base.prop_class) || + query_matches_uobject_name(tool, (uobject_t *)p->meta_class); } - } else if (unreal_fprop_class_is(prop, globals.unreal.soft_class_prop)) { - fprop_class_soft_t *p = (fprop_class_soft_t *)prop; - if (query_matches_uobject_name(tool, (uobject_t *)p->base.base.prop_class) || query_matches_uobject_name(tool, (uobject_t *)p->meta_class)) { - return true; + case UNREAL_PROP_KIND_SOFT_CLASS: { + fprop_class_soft_t *p = (fprop_class_soft_t *)prop; + return query_matches_uobject_name(tool, (uobject_t *)p->base.base.prop_class) || + query_matches_uobject_name(tool, (uobject_t *)p->meta_class); } - } else if (unreal_fprop_class_is(prop, globals.unreal.interface_prop)) { - fprop_iface_t *p = (fprop_iface_t *)prop; - if (query_matches_uobject_name(tool, (uobject_t *)p->iface_class)) { - return true; + case UNREAL_PROP_KIND_INTERFACE: { + fprop_iface_t *p = (fprop_iface_t *)prop; + return query_matches_uobject_name(tool, (uobject_t *)p->iface_class); } - } else if (unreal_fprop_class_is(prop, globals.unreal.byte_prop)) { - fprop_byte_t *p = (fprop_byte_t *)prop; - if (query_matches_uobject_name(tool, (uobject_t *)p->uenum)) { - return true; + case UNREAL_PROP_KIND_BYTE: { + fprop_byte_t *p = (fprop_byte_t *)prop; + return query_matches_uobject_name(tool, (uobject_t *)p->uenum); } - } else if (unreal_fprop_class_is(prop, globals.unreal.enum_prop)) { - fprop_enum_t *p = (fprop_enum_t *)prop; - if (query_matches_uobject_name(tool, (uobject_t *)p->uenum) || prop_matches_query(tool, (fprop_t *)p->underlying_prop)) { - return true; + case UNREAL_PROP_KIND_ENUM: { + fprop_enum_t *p = (fprop_enum_t *)prop; + return query_matches_uobject_name(tool, (uobject_t *)p->uenum) || + prop_matches_query(tool, (fprop_t *)p->underlying_prop); } - } else if (unreal_fprop_class_is(prop, globals.unreal.delegate_prop)) { - fprop_delegate_t *p = (fprop_delegate_t *)prop; - if (query_matches_uobject_name(tool, (uobject_t *)p->signature_func)) { - return true; + case UNREAL_PROP_KIND_DELEGATE: { + fprop_delegate_t *p = (fprop_delegate_t *)prop; + return query_matches_uobject_name(tool, (uobject_t *)p->signature_func); } - } else if (unreal_fprop_class_is(prop, globals.unreal.mcast_delegate_prop) || - unreal_fprop_class_is(prop, globals.unreal.mcast_inline_delegate_prop) || - unreal_fprop_class_is(prop, globals.unreal.mcast_sparse_delegate_prop)) { - fprop_mcast_delegate_t *p = (fprop_mcast_delegate_t *)prop; - if (query_matches_uobject_name(tool, (uobject_t *)p->signature_func)) { - return true; + case UNREAL_PROP_KIND_MULTICAST_DELEGATE: + case UNREAL_PROP_KIND_MULTICAST_INLINE_DELEGATE: + case UNREAL_PROP_KIND_MULTICAST_SPARSE_DELEGATE: { + fprop_mcast_delegate_t *p = (fprop_mcast_delegate_t *)prop; + return query_matches_uobject_name(tool, (uobject_t *)p->signature_func); } + + default: + break; } return false; diff --git a/src/builtin/ufunction_call.c b/src/builtin/ufunction_call.c index d1a4a18..3e431e0 100644 --- a/src/builtin/ufunction_call.c +++ b/src/builtin/ufunction_call.c @@ -8,6 +8,7 @@ #include "str.h" #include "ui_nuklear.h" #include "unreal.h" +#include "unreal_prop.h" #include "vendor_stb.h" @@ -210,23 +211,32 @@ call_prop_is_supported(fprop_t *prop) return false; } - fname_t supported[] = { - globals.unreal.bool_prop, globals.unreal.byte_prop, globals.unreal.int8_prop, - globals.unreal.int16_prop, globals.unreal.int_prop, globals.unreal.int32_prop, - globals.unreal.int64_prop, globals.unreal.uint16_prop, globals.unreal.uint32_prop, - globals.unreal.uint64_prop, globals.unreal.float_prop, globals.unreal.double_prop, - globals.unreal.name_prop, globals.unreal.str_prop, globals.unreal.text_prop, - globals.unreal.obj_prop, globals.unreal.class_prop, globals.unreal.soft_obj_prop, - globals.unreal.soft_class_prop, globals.unreal.struct_prop, globals.unreal.array_prop, - globals.unreal.enum_prop, - }; - - for (int i = 0; i < COUNTOF(supported); ++i) { - if (unreal_fprop_class_is(prop, supported[i])) { + switch (unreal_fprop_get_kind(prop)) { + case UNREAL_PROP_KIND_BOOL: + case UNREAL_PROP_KIND_BYTE: + case UNREAL_PROP_KIND_INT8: + case UNREAL_PROP_KIND_INT16: + case UNREAL_PROP_KIND_INT32: + case UNREAL_PROP_KIND_INT64: + case UNREAL_PROP_KIND_UINT16: + case UNREAL_PROP_KIND_UINT32: + case UNREAL_PROP_KIND_UINT64: + case UNREAL_PROP_KIND_FLOAT: + case UNREAL_PROP_KIND_DOUBLE: + case UNREAL_PROP_KIND_NAME: + case UNREAL_PROP_KIND_STRING: + case UNREAL_PROP_KIND_TEXT: + case UNREAL_PROP_KIND_OBJECT: + case UNREAL_PROP_KIND_CLASS: + case UNREAL_PROP_KIND_SOFT_OBJECT: + case UNREAL_PROP_KIND_SOFT_CLASS: + case UNREAL_PROP_KIND_STRUCT: + case UNREAL_PROP_KIND_ARRAY: + case UNREAL_PROP_KIND_ENUM: return true; - } + default: + return false; } - return false; } static void @@ -236,25 +246,28 @@ call_value_set_default(call_value_t *node) return; } - fprop_t *prop = node->prop; - if (unreal_fprop_class_is(prop, globals.unreal.bool_prop)) { - str_write_fmt(node->input, sizeof(node->input), "false"); - } else if (unreal_fprop_class_is(prop, globals.unreal.float_prop) || - unreal_fprop_class_is(prop, globals.unreal.double_prop)) { - str_write_fmt(node->input, sizeof(node->input), "0.0"); - } else if (unreal_fprop_class_is(prop, globals.unreal.byte_prop) || - unreal_fprop_class_is(prop, globals.unreal.int8_prop) || - unreal_fprop_class_is(prop, globals.unreal.int16_prop) || - unreal_fprop_class_is(prop, globals.unreal.int_prop) || - unreal_fprop_class_is(prop, globals.unreal.int32_prop) || - unreal_fprop_class_is(prop, globals.unreal.int64_prop) || - unreal_fprop_class_is(prop, globals.unreal.uint16_prop) || - unreal_fprop_class_is(prop, globals.unreal.uint32_prop) || - unreal_fprop_class_is(prop, globals.unreal.uint64_prop) || - unreal_fprop_class_is(prop, globals.unreal.enum_prop)) { - str_write_fmt(node->input, sizeof(node->input), "0"); - } else { - node->input[0] = '\0'; + switch (unreal_fprop_get_kind(node->prop)) { + case UNREAL_PROP_KIND_BOOL: + str_write_fmt(node->input, sizeof(node->input), "false"); + break; + case UNREAL_PROP_KIND_FLOAT: + case UNREAL_PROP_KIND_DOUBLE: + str_write_fmt(node->input, sizeof(node->input), "0.0"); + break; + case UNREAL_PROP_KIND_BYTE: + case UNREAL_PROP_KIND_INT8: + case UNREAL_PROP_KIND_INT16: + case UNREAL_PROP_KIND_INT32: + case UNREAL_PROP_KIND_INT64: + case UNREAL_PROP_KIND_UINT16: + case UNREAL_PROP_KIND_UINT32: + case UNREAL_PROP_KIND_UINT64: + case UNREAL_PROP_KIND_ENUM: + str_write_fmt(node->input, sizeof(node->input), "0"); + break; + default: + node->input[0] = '\0'; + break; } } @@ -665,30 +678,6 @@ call_value_literal(search_tool_t *tool, ufunc_call_dialog_t *dialog, call_value_ return str_push_copy(arena, raw); } -static bool -call_import_literal(fprop_t *prop, void *value, uobject_t *owner, str_t literal, arena_t *arena) -{ - if (!prop || !value || str_is_empty(literal)) { - return false; - } - - str16_t wide = str16_from_str(arena, literal); - if (!wide.data) { - return false; - } - - const wchar_t *end = unreal_fprop_import_text_direct(prop, (const wchar_t *)wide.data, value, owner); - if (!end) { - return false; - } - - while (*end == L' ' || *end == L'\t' || *end == L'\r' || *end == L'\n') { - end += 1; - } - - return *end == L'\0'; -} - static bool call_apply_value(search_tool_t *tool, ufunc_call_dialog_t *dialog, call_value_t *node, uint8_t *value, uobject_t *owner, arena_t *arena) { @@ -738,56 +727,58 @@ call_apply_value(search_tool_t *tool, ufunc_call_dialog_t *dialog, call_value_t return false; } - *(uobject_t **)value = selected; - return true; + return unreal_fprop_set_object((fprop_obj_base_t *)node->prop, value, selected); } str_t literal = call_value_literal(tool, dialog, node, arena); - return call_import_literal(node->prop, value, owner, literal, arena); -} - -static int64_t -call_read_integer(fprop_t *prop, void *value) -{ - if (unreal_fprop_class_is(prop, globals.unreal.byte_prop)) return *(uint8_t *)value; - if (unreal_fprop_class_is(prop, globals.unreal.int8_prop)) return *(int8_t *)value; - if (unreal_fprop_class_is(prop, globals.unreal.int16_prop)) return *(int16_t *)value; - if (unreal_fprop_class_is(prop, globals.unreal.int_prop)) return *(int32_t *)value; - if (unreal_fprop_class_is(prop, globals.unreal.int32_prop)) return *(int32_t *)value; - if (unreal_fprop_class_is(prop, globals.unreal.int64_prop)) return *(int64_t *)value; - if (unreal_fprop_class_is(prop, globals.unreal.uint16_prop)) return *(uint16_t *)value; - if (unreal_fprop_class_is(prop, globals.unreal.uint32_prop)) return *(uint32_t *)value; - if (unreal_fprop_class_is(prop, globals.unreal.uint64_prop)) return (int64_t)*(uint64_t *)value; - - return 0; + return unreal_fprop_import_text(node->prop, value, owner, literal, arena); } static void call_result_format_leaf(call_result_t *result, fprop_t *prop, void *value, arena_t *arena) { - if (unreal_fprop_class_is(prop, globals.unreal.bool_prop)) { - fprop_bool_t *bp = (fprop_bool_t *)prop; - uint8_t byte = *((uint8_t *)value + bp->byte_offset); - str_write_fmt(result->value, sizeof(result->value), "%s", (byte & bp->field_mask) ? "true" : "false"); - } else if (unreal_fprop_class_is(prop, globals.unreal.float_prop)) { - str_write_fmt(result->value, sizeof(result->value), "%.9g", (double)*(float *)value); - } else if (unreal_fprop_class_is(prop, globals.unreal.double_prop)) { - str_write_fmt(result->value, sizeof(result->value), "%.17g", *(double *)value); - } else if (unreal_fprop_class_is(prop, globals.unreal.uint64_prop)) { - str_write_fmt(result->value, sizeof(result->value), "%llu", (unsigned long long)*(uint64_t *)value); - } else if (unreal_fprop_class_is(prop, globals.unreal.byte_prop) || - unreal_fprop_class_is(prop, globals.unreal.int8_prop) || - unreal_fprop_class_is(prop, globals.unreal.int16_prop) || - unreal_fprop_class_is(prop, globals.unreal.int_prop) || - unreal_fprop_class_is(prop, globals.unreal.int32_prop) || - unreal_fprop_class_is(prop, globals.unreal.int64_prop) || - unreal_fprop_class_is(prop, globals.unreal.uint16_prop) || - unreal_fprop_class_is(prop, globals.unreal.uint32_prop)) { - str_write_fmt(result->value, sizeof(result->value), "%lld", (long long)call_read_integer(prop, value)); - } else if (unreal_fprop_class_is(prop, globals.unreal.enum_prop)) { + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + + if (kind == UNREAL_PROP_KIND_BOOL) { + bool boolean = false; + if (unreal_fprop_read_bool(prop, value, &boolean)) { + str_write_fmt(result->value, sizeof(result->value), "%s", boolean ? "true" : "false"); + } + } else if (kind == UNREAL_PROP_KIND_FLOAT) { + double real = 0.0; + if (unreal_fprop_read_real(prop, value, &real)) { + str_write_fmt(result->value, sizeof(result->value), "%.9g", real); + } + } else if (kind == UNREAL_PROP_KIND_DOUBLE) { + double real = 0.0; + if (unreal_fprop_read_real(prop, value, &real)) { + str_write_fmt(result->value, sizeof(result->value), "%.17g", real); + } + } else if (kind == UNREAL_PROP_KIND_BYTE || + kind == UNREAL_PROP_KIND_INT8 || + kind == UNREAL_PROP_KIND_INT16 || + kind == UNREAL_PROP_KIND_INT32 || + kind == UNREAL_PROP_KIND_INT64 || + kind == UNREAL_PROP_KIND_UINT16 || + kind == UNREAL_PROP_KIND_UINT32 || + kind == UNREAL_PROP_KIND_UINT64) { + unreal_prop_integer_t integer = {0}; + if (unreal_fprop_read_integer(prop, value, &integer)) { + if (integer.is_signed) { + str_write_fmt(result->value, sizeof(result->value), "%lld", (long long)(int64_t)integer.value); + } else { + str_write_fmt(result->value, sizeof(result->value), "%llu", (unsigned long long)integer.value); + } + } + } else if (kind == UNREAL_PROP_KIND_ENUM) { fprop_enum_t *enum_prop = (fprop_enum_t *)prop; - int64_t integer = enum_prop->underlying_prop ? call_read_integer(&enum_prop->underlying_prop->base, value) : 0; - str_t name = STR_NULL; + unreal_prop_integer_t integer_value = {0}; + if (!unreal_fprop_read_integer(prop, value, &integer_value)) { + str_write_fmt(result->value, sizeof(result->value), ""); + return; + } + int64_t integer = (int64_t)integer_value.value; + str_t name = STR_NULL; if (enum_prop->uenum) { for (int32_t i = 0; i < enum_prop->uenum->names.num; ++i) { if (enum_prop->uenum->names.data[i].value == integer) { @@ -802,20 +793,24 @@ call_result_format_leaf(call_result_t *result, fprop_t *prop, void *value, arena } else { str_write_fmt(result->value, sizeof(result->value), "%lld", (long long)integer); } - } else if (unreal_fprop_class_is(prop, globals.unreal.name_prop)) { - str_t text = unreal_fname_to_str(*(fname_t *)value, arena); - str_write_fmt(result->value, sizeof(result->value), "%.*s", STR_ARG(text)); - } else if (unreal_fprop_class_is(prop, globals.unreal.str_prop)) { + } else if (kind == UNREAL_PROP_KIND_NAME) { + fname_t name = {0}; + if (unreal_fprop_read_name(prop, value, &name)) { + str_t text = unreal_fname_to_str(name, arena); + str_write_fmt(result->value, sizeof(result->value), "%.*s", STR_ARG(text)); + } + } else if (kind == UNREAL_PROP_KIND_STRING) { str_t text = unreal_fstring_to_str(*(fstring_t *)value, arena); str_write_fmt(result->value, sizeof(result->value), "%.*s", STR_ARG(text)); - } else if (unreal_fprop_class_is(prop, globals.unreal.text_prop)) { + } else if (kind == UNREAL_PROP_KIND_TEXT) { ftext_t *text = (ftext_t *)value; - fstring_t *display = (text->text_data.obj && text->text_data.obj->vtable) ? text->text_data.obj->vtable->get_display_string(text->text_data.obj) : NULL; + fstring_t *display = (text->text_data.obj && text->text_data.obj->vtable && text->text_data.obj->vtable->get_display_string) + ? text->text_data.obj->vtable->get_display_string(text->text_data.obj) + : NULL; str_t display_text = display ? unreal_fstring_to_str(*display, arena) : STR_NULL; str_write_fmt(result->value, sizeof(result->value), "%.*s", STR_ARG(display_text)); - } else if (unreal_fprop_class_is(prop, globals.unreal.obj_prop) || - unreal_fprop_class_is(prop, globals.unreal.class_prop)) { - uobject_t *obj = *(uobject_t **)value; + } else if (kind == UNREAL_PROP_KIND_OBJECT || kind == UNREAL_PROP_KIND_CLASS) { + uobject_t *obj = unreal_fprop_get_object((fprop_obj_base_t *)prop, value); if (!obj) { str_write_fmt(result->value, sizeof(result->value), "None"); } else if (!unreal_uobject_is_valid(obj)) { @@ -826,8 +821,7 @@ call_result_format_leaf(call_result_t *result, fprop_t *prop, void *value, arena str_write_fmt(result->value, sizeof(result->value), "%.*s", STR_ARG(name)); str_write_fmt(result->tooltip, sizeof(result->tooltip), "%.*s", STR_ARG(full_name)); } - } else if (unreal_fprop_class_is(prop, globals.unreal.soft_obj_prop) || - unreal_fprop_class_is(prop, globals.unreal.soft_class_prop)) { + } else if (kind == UNREAL_PROP_KIND_SOFT_OBJECT || kind == UNREAL_PROP_KIND_SOFT_CLASS) { call_fsoft_object_ptr_t *soft = (call_fsoft_object_ptr_t *)value; str_t asset = unreal_fname_to_str(soft->path.asset_path_name, arena); str_t sub = unreal_fstring_to_str(soft->path.sub_path_string, arena); diff --git a/src/mod_host.c b/src/mod_host.c index 8f05e99..6747140 100644 --- a/src/mod_host.c +++ b/src/mod_host.c @@ -7,6 +7,7 @@ #include "scratch.h" #include "sigscan.h" #include "unreal.h" +#include "unreal_prop.h" #include diff --git a/src/unreal.c b/src/unreal.c index 5a73ac5..0d9b06a 100644 --- a/src/unreal.c +++ b/src/unreal.c @@ -1398,537 +1398,6 @@ unreal_process_event_observed(uobject_t *self, ufunc_t *func, void *params) #endif } -static inline str_t -unreal_fprop_class_push_type_name(arena_t *arena, str_t prefix, uclass_t *cls) -{ - str_t cls_name = cls ? unreal_uobject_push_name((uobject_t *)cls, arena) : STR_LIT(""); - return str_push_fmt(arena, "%.*s<%.*s>", STR_ARG(prefix), STR_ARG(cls_name)); -} - -bool -unreal_fprop_class_is(fprop_t *prop, fname_t name) -{ - if (prop && prop->cls) { - return unreal_fname_equal(prop->cls->name, name, false); - } - return false; -} - -bool -unreal_fprop_class_is_a(fprop_t *prop, fname_t name) -{ - for (ffield_class_t *cls = prop ? prop->cls : NULL; cls; cls = cls->super_class) { - if (unreal_fname_equal(cls->name, name, false)) { - return true; - } - } - return false; -} - -str_t -unreal_fprop_push_type_name(fprop_t *prop, arena_t *arena) -{ - if (!prop || !prop->cls || !arena) { - return STR_LIT(""); - } - - struct { - str_t name; - fname_t fname; - } simple_prop_names[] = { - {STR_CLIT("bool"), globals.unreal.bool_prop }, - {STR_CLIT("uint8_t"), globals.unreal.byte_prop }, - {STR_CLIT("int8_t"), globals.unreal.int8_prop }, - {STR_CLIT("int16_t"), globals.unreal.int16_prop }, - {STR_CLIT("int32_t"), globals.unreal.int_prop }, - {STR_CLIT("int32_t"), globals.unreal.int32_prop }, - {STR_CLIT("int64_t"), globals.unreal.int64_prop }, - {STR_CLIT("uint16_t"), globals.unreal.uint16_prop}, - {STR_CLIT("uint32_t"), globals.unreal.uint32_prop}, - {STR_CLIT("uint64_t"), globals.unreal.uint64_prop}, - {STR_CLIT("float"), globals.unreal.float_prop }, - {STR_CLIT("double"), globals.unreal.double_prop}, - {STR_CLIT("FName"), globals.unreal.name_prop }, - {STR_CLIT("FString"), globals.unreal.str_prop }, - {STR_CLIT("FText"), globals.unreal.text_prop }, - }; - - for (int i = 0; i < COUNTOF(simple_prop_names); ++i) { - str_t type_name = simple_prop_names[i].name; - fname_t type_fname = simple_prop_names[i].fname; - - if (unreal_fprop_class_is(prop, type_fname)) { - return type_name; // ok, because it's string literal - } - } - - if (unreal_fprop_class_is(prop, globals.unreal.obj_prop)) { - fprop_obj_base_t *p = (fprop_obj_base_t *)prop; - return unreal_fprop_class_push_type_name(arena, STR_LIT("Object"), p->prop_class); - } - - if (unreal_fprop_class_is(prop, globals.unreal.class_prop)) { - fprop_class_t *p = (fprop_class_t *)prop; - return unreal_fprop_class_push_type_name(arena, STR_LIT("Class"), p->meta_class); - } - - if (unreal_fprop_class_is(prop, globals.unreal.soft_obj_prop)) { - fprop_obj_base_t *p = (fprop_obj_base_t *)prop; - return unreal_fprop_class_push_type_name(arena, STR_LIT("SoftObject"), p->prop_class); - } - - if (unreal_fprop_class_is(prop, globals.unreal.soft_class_prop)) { - fprop_class_soft_t *p = (fprop_class_soft_t *)prop; - return unreal_fprop_class_push_type_name(arena, STR_LIT("SoftClass"), p->meta_class); - } - - if (unreal_fprop_class_is(prop, globals.unreal.weak_obj_prop)) { - fprop_obj_base_t *p = (fprop_obj_base_t *)prop; - return unreal_fprop_class_push_type_name(arena, STR_LIT("WeakObject"), p->prop_class); - } - - if (unreal_fprop_class_is(prop, globals.unreal.lazy_obj_prop)) { - fprop_obj_base_t *p = (fprop_obj_base_t *)prop; - return unreal_fprop_class_push_type_name(arena, STR_LIT("LazyObject"), p->prop_class); - } - - if (unreal_fprop_class_is(prop, globals.unreal.interface_prop)) { - fprop_iface_t *p = (fprop_iface_t *)prop; - return unreal_fprop_class_push_type_name(arena, STR_LIT("Interface"), p->iface_class); - } - - if (unreal_fprop_class_is(prop, globals.unreal.struct_prop)) { - fprop_struct_t *p = (fprop_struct_t *)prop; - - if (!p->script_struct) { - return STR_LIT(""); - } - - return unreal_uobject_push_name((uobject_t *)p->script_struct, arena); - } - - if (unreal_fprop_class_is(prop, globals.unreal.enum_prop)) { - fprop_enum_t *p = (fprop_enum_t *)prop; - str_t enum_name = p->uenum ? unreal_uobject_push_name((uobject_t *)p->uenum, arena) : STR_LIT(""); - - if (p->underlying_prop) { - str_t underlying_type_name = unreal_fprop_push_type_name(&p->underlying_prop->base, arena); - return str_push_fmt(arena, "Enum<%.*s:%.*s>", STR_ARG(enum_name), STR_ARG(underlying_type_name)); - } - return str_push_fmt(arena, "Enum<%.*s>", STR_ARG(enum_name)); - } - - if (unreal_fprop_class_is(prop, globals.unreal.array_prop)) { - fprop_array_t *p = (fprop_array_t *)prop; - str_t inner_type_name = unreal_fprop_push_type_name(p->inner, arena); - return str_push_fmt(arena, "TArray<%.*s>", STR_ARG(inner_type_name)); - } - - if (unreal_fprop_class_is(prop, globals.unreal.set_prop)) { - fprop_set_t *p = (fprop_set_t *)prop; - str_t elem_type_name = unreal_fprop_push_type_name(p->elem_prop, arena); - return str_push_fmt(arena, "TSet<%.*s>", STR_ARG(elem_type_name)); - } - - if (unreal_fprop_class_is(prop, globals.unreal.map_prop)) { - fprop_map_t *p = (fprop_map_t *)prop; - str_t key_type_name = unreal_fprop_push_type_name(p->key_prop, arena); - str_t value_type_name = unreal_fprop_push_type_name(p->val_prop, arena); - return str_push_fmt(arena, "TMap<%.*s, %.*s>", STR_ARG(key_type_name), STR_ARG(value_type_name)); - } - - if (unreal_fprop_class_is(prop, globals.unreal.delegate_prop)) { - fprop_delegate_t *p = (fprop_delegate_t *)prop; - str_t sig = p->signature_func ? unreal_uobject_push_name((uobject_t *)p->signature_func, arena) : STR_LIT(""); - return str_push_fmt(arena, "Delegate<%.*s>", STR_ARG(sig)); - } - - if (unreal_fprop_class_is(prop, globals.unreal.mcast_delegate_prop)) { - fprop_mcast_delegate_t *p = (fprop_mcast_delegate_t *)prop; - str_t sig = p->signature_func ? unreal_uobject_push_name((uobject_t *)p->signature_func, arena) : STR_LIT(""); - return str_push_fmt(arena, "MulticastDelegate<%.*s>", STR_ARG(sig)); - } - - if (unreal_fprop_class_is(prop, globals.unreal.mcast_inline_delegate_prop)) { - fprop_mcast_delegate_t *p = (fprop_mcast_delegate_t *)prop; - str_t sig = p->signature_func ? unreal_uobject_push_name((uobject_t *)p->signature_func, arena) : STR_LIT(""); - return str_push_fmt(arena, "MulticastInlineDelegate<%.*s>", STR_ARG(sig)); - } - - if (unreal_fprop_class_is(prop, globals.unreal.mcast_sparse_delegate_prop)) { - fprop_mcast_delegate_t *p = (fprop_mcast_delegate_t *)prop; - str_t sig = p->signature_func ? unreal_uobject_push_name((uobject_t *)p->signature_func, arena) : STR_LIT(""); - return str_push_fmt(arena, "MulticastSparseDelegate<%.*s>", STR_ARG(sig)); - } - - return unreal_fname_to_str(prop->cls->name, arena); - -} - -static bool -unreal_fprop_has_valid_layout(fprop_t *prop) -{ - return prop && prop->elem_size > 0 && prop->array_dim > 0; -} - -uint64_t -unreal_fprop_complete_size(fprop_t *prop) -{ - if (!unreal_fprop_has_valid_layout(prop)) { - return 0; - } - return (uint64_t)prop->elem_size * (uint64_t)prop->array_dim; -} - -int32_t -unreal_fprop_min_alignment(fprop_t *prop) -{ - if (!unreal_fprop_has_valid_layout(prop) || !prop->vtable || !prop->vtable->get_min_alignment) { - return 0; - } - - int32_t alignment = prop->vtable->get_min_alignment(prop); - return alignment > 0 ? alignment : 0; -} - -void * -unreal_fprop_value_at(fprop_t *prop, void *value, int32_t array_idx) -{ - if (!unreal_fprop_has_valid_layout(prop) || !value || array_idx < 0 || array_idx >= prop->array_dim) { - return NULL; - } - return (uint8_t *)value + (uint64_t)array_idx * (uint64_t)prop->elem_size; -} - -void * -unreal_fprop_value_in_container(fprop_t *prop, void *container, int32_t array_idx) -{ - if (!prop || !container || prop->offset_internal < 0) { - return NULL; - } - return unreal_fprop_value_at(prop, (uint8_t *)container + prop->offset_internal, array_idx); -} - -bool -unreal_fprop_initialize_value(fprop_t *prop, void *value) -{ - uint64_t size = unreal_fprop_complete_size(prop); - if (size == 0 || !value) { - return false; - } - - if (prop->prop_flags & CPF_ZERO_CONSTRUCTOR) { - mem_zero(value, size); - return true; - } - - if (!prop->vtable || !prop->vtable->initialize_value_internal) { - return false; - } - - prop->vtable->initialize_value_internal(prop, value); - return true; -} - -bool -unreal_fprop_destroy_value(fprop_t *prop, void *value) -{ - if (!unreal_fprop_has_valid_layout(prop) || !value) { - return false; - } - - if (prop->prop_flags & CPF_NO_DESTRUCTOR) { - return true; - } - - if (!prop->vtable || !prop->vtable->destroy_value_internal) { - return false; - } - - /* UE 4.27's virtual destroys the complete fixed ArrayDim itself. */ - prop->vtable->destroy_value_internal(prop, value); - return true; -} - -bool -unreal_fprop_clear_single_value(fprop_t *prop, void *value) -{ - if (!unreal_fprop_has_valid_layout(prop) || !value) { - return false; - } - - if ((prop->prop_flags & (CPF_NO_DESTRUCTOR | CPF_ZERO_CONSTRUCTOR)) == - (CPF_NO_DESTRUCTOR | CPF_ZERO_CONSTRUCTOR)) { - mem_zero(value, (uint64_t)prop->elem_size); - return true; - } - - if (!prop->vtable || !prop->vtable->clear_value_internal) { - return false; - } - - prop->vtable->clear_value_internal(prop, value); - return true; -} - -bool -unreal_fprop_clear_complete_value(fprop_t *prop, void *value) -{ - if (!unreal_fprop_has_valid_layout(prop) || !value) { - return false; - } - - for (int32_t i = 0; i < prop->array_dim; ++i) { - void *elem = unreal_fprop_value_at(prop, value, i); - if (!unreal_fprop_clear_single_value(prop, elem)) { - return false; - } - } - return true; -} - -bool -unreal_fprop_copy_single_value(fprop_t *prop, void *dst, const void *src) -{ - if (!unreal_fprop_has_valid_layout(prop) || !dst || !src) { - return false; - } - - if (dst == src) { - return true; - } - - if (prop->prop_flags & CPF_IS_PLAIN_OLD_DATA) { - mem_copy(dst, (void *)src, (uint64_t)prop->elem_size); - return true; - } - - if (!prop->vtable || !prop->vtable->copy_values_internal) { - return false; - } - - prop->vtable->copy_values_internal(prop, dst, src, 1); - return true; -} - -bool -unreal_fprop_copy_complete_value(fprop_t *prop, void *dst, const void *src) -{ - uint64_t size = unreal_fprop_complete_size(prop); - if (size == 0 || !dst || !src) { - return false; - } - - if (dst == src) { - return true; - } - - if (prop->prop_flags & CPF_IS_PLAIN_OLD_DATA) { - mem_copy(dst, (void *)src, size); - return true; - } - - if (!prop->vtable || !prop->vtable->copy_values_internal) { - return false; - } - - prop->vtable->copy_values_internal(prop, dst, src, prop->array_dim); - return true; -} - -bool -unreal_fprop_copy_single_value_to_script_vm(fprop_t *prop, void *dst, const void *src) -{ - if (!unreal_fprop_has_valid_layout(prop) || !dst || !src || - !prop->vtable || !prop->vtable->copy_single_value_to_script_vm) { - return false; - } - - prop->vtable->copy_single_value_to_script_vm(prop, dst, src); - return true; -} - -bool -unreal_fprop_copy_complete_value_to_script_vm(fprop_t *prop, void *dst, const void *src) -{ - if (!unreal_fprop_has_valid_layout(prop) || !dst || !src || - !prop->vtable || !prop->vtable->copy_complete_value_to_script_vm) { - return false; - } - - prop->vtable->copy_complete_value_to_script_vm(prop, dst, src); - return true; -} - -bool -unreal_fprop_copy_single_value_from_script_vm(fprop_t *prop, void *dst, const void *src) -{ - if (!unreal_fprop_has_valid_layout(prop) || !dst || !src || - !prop->vtable || !prop->vtable->copy_single_value_from_script_vm) { - return false; - } - - prop->vtable->copy_single_value_from_script_vm(prop, dst, src); - return true; -} - -bool -unreal_fprop_copy_complete_value_from_script_vm(fprop_t *prop, void *dst, const void *src) -{ - if (!unreal_fprop_has_valid_layout(prop) || !dst || !src || - !prop->vtable || !prop->vtable->copy_complete_value_from_script_vm) { - return false; - } - - prop->vtable->copy_complete_value_from_script_vm(prop, dst, src); - return true; -} - -bool -unreal_fprop_single_values_identical(fprop_t *prop, const void *a, const void *b, uint32_t port_flags) -{ - if (!unreal_fprop_has_valid_layout(prop) || !a || !prop->vtable || !prop->vtable->identical) { - return false; - } - return prop->vtable->identical(prop, a, b, port_flags); -} - -bool -unreal_fprop_complete_values_identical(fprop_t *prop, const void *a, const void *b, uint32_t port_flags) -{ - if (!unreal_fprop_has_valid_layout(prop) || !a || !prop->vtable || !prop->vtable->identical) { - return false; - } - - for (int32_t i = 0; i < prop->array_dim; ++i) { - const void *a_elem = unreal_fprop_value_at(prop, (void *)a, i); - const void *b_elem = b ? unreal_fprop_value_at(prop, (void *)b, i) : NULL; - if (!prop->vtable->identical(prop, a_elem, b_elem, port_flags)) { - return false; - } - } - return true; -} - -bool -unreal_fprop_value_hash(fprop_t *prop, const void *value, uint32_t *out_hash) -{ - if (!unreal_fprop_has_valid_layout(prop) || !value || !out_hash || - !(prop->prop_flags & CPF_HAS_GET_VALUE_TYPE_HASH) || - !prop->vtable || !prop->vtable->get_value_type_hash_internal) { - return false; - } - - *out_hash = prop->vtable->get_value_type_hash_internal(prop, value); - return true; -} - -bool -unreal_fprop_same_type(fprop_t *prop, fprop_t *other) -{ - return prop && other && prop->vtable && prop->vtable->same_type && - prop->vtable->same_type(prop, other); -} - -uobject_t * -unreal_fprop_get_object(fprop_obj_base_t *prop, const void *value) -{ - if (!prop || !value || !prop->vtable) { - return NULL; - } - - return prop->vtable->get_object_prop_value ? prop->vtable->get_object_prop_value(prop, value) : NULL; -} - -bool -unreal_fprop_object_is_compatible(fprop_obj_base_t *prop, uobject_t *object) -{ - if (!prop || (object && (!prop->prop_class || !unreal_uobject_is_a(object, prop->prop_class)))) { - return false; - } - - if (!object) { - return true; - } - - uclass_t *meta_class = NULL; - if (unreal_fprop_class_is((fprop_t *)prop, globals.unreal.class_prop)) { - meta_class = ((fprop_class_t *)prop)->meta_class; - } else if (unreal_fprop_class_is((fprop_t *)prop, globals.unreal.soft_class_prop)) { - meta_class = ((fprop_class_soft_t *)prop)->meta_class; - } - - if (meta_class && !unreal_uclass_is_child_of((uclass_t *)object, meta_class)) { - return false; - } - return true; -} - -bool -unreal_fprop_set_object(fprop_obj_base_t *prop, void *value, uobject_t *object) -{ - if (!prop || !value || !prop->vtable || !unreal_fprop_object_is_compatible(prop, object)) { - return false; - } - - if (!prop->vtable->set_object_prop_value) { - return false; - } - - prop->vtable->set_object_prop_value(prop, value, object); - return true; -} - -void -unreal_fprop_initialize_in_container(fprop_t *prop, void *container) -{ - void *value = unreal_fprop_value_in_container(prop, container, 0); - if (value) { - unreal_fprop_initialize_value(prop, value); - } -} - -void -unreal_fprop_destroy_in_container(fprop_t *prop, void *container) -{ - void *value = unreal_fprop_value_in_container(prop, container, 0); - if (value) { - unreal_fprop_destroy_value(prop, value); - } -} - -bool -unreal_ustruct_initialize_struct(ustruct_t *struct_type, void *memory, int32_t array_dim) -{ - if (!struct_type || !memory || array_dim <= 0 || struct_type->props_size < 0 || - !struct_type->vtable || !struct_type->vtable->init_struct) { - return false; - } - - struct_type->vtable->init_struct(struct_type, memory, array_dim); - return true; -} - -bool -unreal_ustruct_destroy_struct(ustruct_t *struct_type, void *memory, int32_t array_dim) -{ - if (!struct_type || !memory || array_dim <= 0 || struct_type->props_size < 0 || - !struct_type->vtable || !struct_type->vtable->destroy_struct) { - return false; - } - - struct_type->vtable->destroy_struct(struct_type, memory, array_dim); - return true; -} - -const wchar_t * -unreal_fprop_import_text_direct(fprop_t *prop, const wchar_t *text, void *value, uobject_t *owner) -{ - if (!prop || !prop->vtable || !prop->vtable->import_text_internal || !text || !value) { - return NULL; - } - return prop->vtable->import_text_internal(prop, text, value, 0, owner, NULL); -} uobject_t * unreal_spawn_actor(uobject_t *world_ctx_obj, uclass_t *cls) @@ -2237,17 +1706,6 @@ unreal_fframe_step(fframe_t *stack, void *result) } /* ================================================ CLASS INTROSPECTION ============================================= */ -fprop_t * -unreal_ustruct_find_prop(ustruct_t *s, str_t name) -{ - for (fprop_t *p = s->prop_link; p; p = p->prop_link_next) { - if (unreal_fname_match_text(p->name, name, false, true)) { - return p; - } - } - - return NULL; -} ufunc_t * unreal_ustruct_find_func(ustruct_t *s, str_t name) @@ -2375,392 +1833,6 @@ unreal_tset_hash_head(hash_allocator_t *hash, int32_t hash_size, uint32_t key_ha return data[key_hash & (uint32_t)(hash_size - 1)]; } -static bool -unreal_array_prop_is_valid(fprop_array_t *prop) -{ - return prop && unreal_fprop_has_valid_layout(&prop->base) && prop->inner && unreal_fprop_has_valid_layout(prop->inner); -} - -static bool -unreal_array_view_is_valid(const void *array, fprop_array_t *prop) -{ - if (!array || !unreal_array_prop_is_valid(prop) || (prop->array_flags & EAPF_USES_MEM_IMAGE_ALLOCATOR)) { - return false; - } - - const fscript_array_t *script_array = (const fscript_array_t *)array; - return script_array->num >= 0 && script_array->max >= script_array->num && (script_array->num == 0 || script_array->data != NULL); -} - -int32_t -unreal_array_num(const void *array, fprop_array_t *prop) -{ - if (!unreal_array_view_is_valid(array, prop)) { - return -1; - } - return ((const fscript_array_t *)array)->num; -} - -void * -unreal_array_get(void *array, fprop_array_t *prop, int32_t idx) -{ - if (!unreal_array_view_is_valid(array, prop)) { - return NULL; - } - - fscript_array_t *script_array = (fscript_array_t *)array; - if (idx < 0 || idx >= script_array->num) { - return NULL; - } - - return (uint8_t *)script_array->data + (uint64_t)idx * (uint64_t)prop->inner->elem_size; -} - -int32_t -unreal_array_add(void *array, fprop_array_t *prop, const void *value) -{ - if (!array || !unreal_array_prop_is_valid(prop) || !value || !generic_array_add) { - return -1; - } - return generic_array_add(array, prop, value); -} - -void -unreal_array_insert(void *array, fprop_array_t *prop, int32_t idx, const void *value) -{ - if (array && unreal_array_prop_is_valid(prop) && idx >= 0 && value && generic_array_insert) { - generic_array_insert(array, prop, value, idx); - } -} - -void -unreal_array_remove(void *array, fprop_array_t *prop, int32_t idx) -{ - if (array && unreal_array_prop_is_valid(prop) && idx >= 0 && generic_array_remove) { - generic_array_remove(array, prop, idx); - } -} - -void -unreal_array_resize(void *array, fprop_array_t *prop, int32_t size) -{ - if (array && unreal_array_prop_is_valid(prop) && size >= 0 && generic_array_resize) { - generic_array_resize(array, prop, size); - } -} - -void -unreal_array_set(void *array, fprop_array_t *prop, int32_t idx, const void *value, bool size_to_fit) -{ - if (array && unreal_array_prop_is_valid(prop) && idx >= 0 && value && generic_array_set) { - generic_array_set(array, prop, idx, value, size_to_fit); - } -} - -bool -unreal_array_clear(void *array, fprop_array_t *prop) -{ - return array && unreal_array_prop_is_valid(prop) && unreal_fprop_clear_single_value(&prop->base, array); -} - -static bool -unreal_script_set_view_is_valid(const fscript_set_t *set, const fscript_set_layout_t *layout) -{ - if (!set || !layout || layout->size <= 0 || layout->sparse_array_layout.size < layout->size || - layout->sparse_array_layout.alignment <= 0) { - return false; - } - - const fscript_sparse_array_t *sparse = &set->elems; - return sparse->data.num >= 0 && - sparse->data.max >= sparse->data.num && - sparse->num_free_idx >= 0 && - sparse->num_free_idx <= sparse->data.num && - sparse->alloc_flags.num_bits >= sparse->data.num && - sparse->alloc_flags.max_bits >= sparse->alloc_flags.num_bits && - (sparse->data.num == 0 || sparse->data.data != NULL); -} - -static int32_t -unreal_script_set_num(const fscript_set_t *set, const fscript_set_layout_t *layout) -{ - if (!unreal_script_set_view_is_valid(set, layout)) { - return -1; - } - return set->elems.data.num - set->elems.num_free_idx; -} - -static int32_t -unreal_script_set_max_index(const fscript_set_t *set, const fscript_set_layout_t *layout) -{ - if (!unreal_script_set_view_is_valid(set, layout)) { - return -1; - } - return set->elems.data.num; -} - -static bool -unreal_script_set_is_valid_index(const fscript_set_t *set, const fscript_set_layout_t *layout, int32_t idx) -{ - return unreal_script_set_view_is_valid(set, layout) && idx >= 0 && idx < set->elems.data.num && - unreal_tbit_array_is_set((tbit_array_t *)&set->elems.alloc_flags, idx); -} - -static void * -unreal_script_set_get(void *set, const fscript_set_layout_t *layout, int32_t index) -{ - fscript_set_t *script_set = (fscript_set_t *)set; - if (!unreal_script_set_is_valid_index(script_set, layout, index)) { - return NULL; - } - - return (uint8_t *)script_set->elems.data.data + (uint64_t)index * (uint64_t)layout->sparse_array_layout.size; -} - -static bool -unreal_set_prop_is_valid(fprop_set_t *prop) -{ - return prop && unreal_fprop_has_valid_layout(&prop->base) && prop->elem_prop && - unreal_fprop_has_valid_layout(prop->elem_prop) && prop->set_layout.size > 0 && - prop->set_layout.sparse_array_layout.size >= prop->set_layout.size; -} - -int32_t -unreal_set_num(const void *set, fprop_set_t *prop) -{ - if (!unreal_set_prop_is_valid(prop)) { - return -1; - } - return unreal_script_set_num((const fscript_set_t *)set, &prop->set_layout); -} - -int32_t -unreal_set_max_index(const void *set, fprop_set_t *prop) -{ - if (!unreal_set_prop_is_valid(prop)) { - return -1; - } - return unreal_script_set_max_index((const fscript_set_t *)set, &prop->set_layout); -} - -bool -unreal_set_is_valid_index(const void *set, fprop_set_t *prop, int32_t idx) -{ - return unreal_set_prop_is_valid(prop) && unreal_script_set_is_valid_index((const fscript_set_t *)set, &prop->set_layout, idx); -} - -const void * -unreal_set_get(const void *set, fprop_set_t *prop, int32_t idx) -{ - if (!unreal_set_prop_is_valid(prop)) { - return NULL; - } - return unreal_script_set_get((void *)set, &prop->set_layout, idx); -} - -int32_t -unreal_set_find_index(const void *set, fprop_set_t *prop, const void *value) -{ - int32_t max_index = unreal_set_max_index(set, prop); - if (max_index < 0 || !value) { - return TSET_INVALID_ID; - } - - for (int32_t index = 0; index < max_index; ++index) { - const void *elem = unreal_set_get(set, prop, index); - if (elem && unreal_fprop_single_values_identical(prop->elem_prop, elem, value, 0)) { - return index; - } - } - return TSET_INVALID_ID; -} - -bool -unreal_set_contains(const void *set, fprop_set_t *prop, const void *value) -{ - return unreal_set_find_index(set, prop, value) != TSET_INVALID_ID; -} - -void -unreal_set_add(void *set, fprop_set_t *prop, const void *value) -{ - if (!set || !unreal_set_prop_is_valid(prop) || !value || !fscript_set_add_elem) { - return; - } - - fscript_set_helper_t helper = { - .elem_prop = prop->elem_prop, - .set = set, - .layout = prop->set_layout, - }; - fscript_set_add_elem(&helper, value); -} - -bool -unreal_set_remove(void *set, fprop_set_t *prop, const void *value) -{ - if (!set || !unreal_set_prop_is_valid(prop) || !value || !generic_set_remove) { - return false; - } - return generic_set_remove(set, prop, value); -} - -bool -unreal_set_clear(void *set, fprop_set_t *prop) -{ - return set && unreal_set_prop_is_valid(prop) && unreal_fprop_clear_single_value(&prop->base, set); -} - -static bool -unreal_map_prop_is_valid(fprop_map_t *prop) -{ - if (!prop || !unreal_fprop_has_valid_layout(&prop->base) || !prop->key_prop || !prop->val_prop || - !unreal_fprop_has_valid_layout(prop->key_prop) || !unreal_fprop_has_valid_layout(prop->val_prop)) { - return false; - } - - const fscript_map_layout_t *layout = &prop->map_layout; - return layout->set_layout.size > 0 && - layout->set_layout.sparse_array_layout.size >= layout->set_layout.size && - layout->value_offset >= prop->key_prop->elem_size && - (uint64_t)layout->value_offset + (uint64_t)prop->val_prop->elem_size <= (uint64_t)layout->set_layout.size; -} - -static bool -unreal_map_view_prop_is_valid(fprop_map_t *prop) -{ - return unreal_map_prop_is_valid(prop) && !(prop->map_flags & EMPF_USES_MEM_IMAGE_ALLOCATOR); -} - -int32_t -unreal_map_num(const void *map, fprop_map_t *prop) -{ - if (!map || !unreal_map_view_prop_is_valid(prop)) { - return -1; - } - return unreal_script_set_num(&((const fscript_map_t *)map)->pairs, &prop->map_layout.set_layout); -} - -int32_t -unreal_map_max_index(const void *map, fprop_map_t *prop) -{ - if (!map || !unreal_map_view_prop_is_valid(prop)) { - return -1; - } - return unreal_script_set_max_index(&((const fscript_map_t *)map)->pairs, &prop->map_layout.set_layout); -} - -bool -unreal_map_is_valid_index(const void *map, fprop_map_t *prop, int32_t idx) -{ - return unreal_map_view_prop_is_valid(prop) && map && - unreal_script_set_is_valid_index(&((const fscript_map_t *)map)->pairs, &prop->map_layout.set_layout, idx); -} - -const void * -unreal_map_get_key(const void *map, fprop_map_t *prop, int32_t idx) -{ - if (!unreal_map_view_prop_is_valid(prop) || !map) { - return NULL; - } - return unreal_script_set_get(&((fscript_map_t *)map)->pairs, &prop->map_layout.set_layout, idx); -} - -void * -unreal_map_get_value(void *map, fprop_map_t *prop, int32_t idx) -{ - uint8_t *key = (uint8_t *)unreal_map_get_key(map, prop, idx); - return key ? key + prop->map_layout.value_offset : NULL; -} - -int32_t -unreal_map_find_index(const void *map, fprop_map_t *prop, const void *key) -{ - int32_t max_idx = unreal_map_max_index(map, prop); - if (max_idx < 0 || !key) { - return TSET_INVALID_ID; - } - - for (int32_t idx = 0; idx < max_idx; ++idx) { - const void *candidate = unreal_map_get_key(map, prop, idx); - if (candidate && unreal_fprop_single_values_identical(prop->key_prop, candidate, key, 0)) { - return idx; - } - } - return TSET_INVALID_ID; -} - -void * -unreal_map_find_value_ptr(void *map, fprop_map_t *prop, const void *key) -{ - int32_t idx = unreal_map_find_index(map, prop, key); - return idx != TSET_INVALID_ID ? unreal_map_get_value(map, prop, idx) : NULL; -} - -bool -unreal_map_clear(void *map, fprop_map_t *prop) -{ - return map && unreal_map_prop_is_valid(prop) && unreal_fprop_clear_single_value(&prop->base, map); -} - -void -unreal_map_add(void *map, fprop_map_t *prop, const void *key, const void *val) -{ - if (!map || !prop || !prop->key_prop || !prop->val_prop || !key || !val || !fscript_map_add_pair) { - return; - } - - fscript_map_helper_t helper = { - .key_prop = prop->key_prop, - .val_prop = prop->val_prop, - .map = map, - .layout = prop->map_layout, - .flags = prop->map_flags, - }; - - fscript_map_add_ctx_t ctx = { - .helper = &helper, - .key = key, - .value = val, - .key_prop = prop->key_prop, - .val_prop = prop->val_prop, - }; - - fscript_map_add_pair(&helper, &ctx); -} - -bool -unreal_map_remove(void *map, fprop_map_t *prop, const void *key) -{ - if (!map || !prop || !prop->key_prop || !key || !fscript_map_remove_pair) { - return false; - } - - fscript_map_helper_t helper = { - .key_prop = prop->key_prop, - .val_prop = prop->val_prop, - .map = map, - .layout = prop->map_layout, - .flags = prop->map_flags, - }; - - fscript_map_remove_ctx_t ctx = { - .helper = &helper, - .key = key, - .key_prop = prop->key_prop, - }; - - return fscript_map_remove_pair(&helper, &ctx); -} - -bool -unreal_map_find(void *map, fprop_map_t *prop, const void *key, void *out_val) -{ - if (!map || !prop || !key || !generic_map_find) { - return false; - } - return generic_map_find(map, prop, key, out_val); -} /* =================================================== DATA TABLE =================================================== */ diff --git a/src/unreal_prop.c b/src/unreal_prop.c new file mode 100644 index 0000000..510d4c6 --- /dev/null +++ b/src/unreal_prop.c @@ -0,0 +1,1989 @@ +#include "unreal_prop.h" + +#include "globals.h" +#include "scratch.h" +#include "signatures.h" + +typedef struct unreal_prop_vector4_s { + float x; + float y; + float z; + float w; +} unreal_prop_vector4_t; + +typedef struct unreal_prop_linear_color_s { + float r; + float g; + float b; + float a; +} unreal_prop_linear_color_t; + +typedef struct unreal_prop_int_point_s { + int32_t x; + int32_t y; +} unreal_prop_int_point_t; + +typedef struct unreal_prop_int_vector_s { + int32_t x; + int32_t y; + int32_t z; +} unreal_prop_int_vector_t; + +typedef struct unreal_prop_lazy_object_ptr_s { + fweak_object_ptr_t weak; + int32_t tag_at_last_test; + fguid_t object_id; +} unreal_prop_lazy_object_ptr_t; + +typedef struct unreal_prop_soft_object_ptr_s { + fweak_object_ptr_t weak; + int32_t tag_at_last_test; + int32_t pad; + fsoft_object_path_t path; +} unreal_prop_soft_object_ptr_t; + +typedef struct unreal_prop_script_interface_s { + uobject_t *object; + void *interface_ptr; +} unreal_prop_script_interface_t; + +fprop_t * +unreal_ustruct_find_prop(ustruct_t *s, str_t name) +{ + for (fprop_t *p = s->prop_link; p; p = p->prop_link_next) { + if (unreal_fname_match_text(p->name, name, false, true)) { + return p; + } + } + + return NULL; +} + +static inline str_t +unreal_fprop_class_push_type_name(arena_t *arena, str_t prefix, uclass_t *cls) +{ + str_t cls_name = cls ? unreal_uobject_push_name((uobject_t *)cls, arena) : STR_LIT(""); + return str_push_fmt(arena, "%.*s<%.*s>", STR_ARG(prefix), STR_ARG(cls_name)); +} + +unreal_prop_kind_t +unreal_fprop_get_kind(fprop_t *prop) +{ + if (!prop || !prop->cls) { + return UNREAL_PROP_KIND_UNKNOWN; + } + + struct { + fname_t class_name; + unreal_prop_kind_t kind; + } kinds[] = { + {globals.unreal.bool_prop, UNREAL_PROP_KIND_BOOL }, + {globals.unreal.byte_prop, UNREAL_PROP_KIND_BYTE }, + {globals.unreal.int8_prop, UNREAL_PROP_KIND_INT8 }, + {globals.unreal.int16_prop, UNREAL_PROP_KIND_INT16 }, + {globals.unreal.int_prop, UNREAL_PROP_KIND_INT32 }, + {globals.unreal.int32_prop, UNREAL_PROP_KIND_INT32 }, + {globals.unreal.int64_prop, UNREAL_PROP_KIND_INT64 }, + {globals.unreal.uint16_prop, UNREAL_PROP_KIND_UINT16 }, + {globals.unreal.uint32_prop, UNREAL_PROP_KIND_UINT32 }, + {globals.unreal.uint64_prop, UNREAL_PROP_KIND_UINT64 }, + {globals.unreal.float_prop, UNREAL_PROP_KIND_FLOAT }, + {globals.unreal.double_prop, UNREAL_PROP_KIND_DOUBLE }, + {globals.unreal.name_prop, UNREAL_PROP_KIND_NAME }, + {globals.unreal.str_prop, UNREAL_PROP_KIND_STRING }, + {globals.unreal.text_prop, UNREAL_PROP_KIND_TEXT }, + {globals.unreal.obj_prop, UNREAL_PROP_KIND_OBJECT }, + {globals.unreal.class_prop, UNREAL_PROP_KIND_CLASS }, + {globals.unreal.soft_obj_prop, UNREAL_PROP_KIND_SOFT_OBJECT }, + {globals.unreal.soft_class_prop, UNREAL_PROP_KIND_SOFT_CLASS }, + {globals.unreal.weak_obj_prop, UNREAL_PROP_KIND_WEAK_OBJECT }, + {globals.unreal.lazy_obj_prop, UNREAL_PROP_KIND_LAZY_OBJECT }, + {globals.unreal.interface_prop, UNREAL_PROP_KIND_INTERFACE }, + {globals.unreal.struct_prop, UNREAL_PROP_KIND_STRUCT }, + {globals.unreal.array_prop, UNREAL_PROP_KIND_ARRAY }, + {globals.unreal.set_prop, UNREAL_PROP_KIND_SET }, + {globals.unreal.map_prop, UNREAL_PROP_KIND_MAP }, + {globals.unreal.enum_prop, UNREAL_PROP_KIND_ENUM }, + {globals.unreal.delegate_prop, UNREAL_PROP_KIND_DELEGATE }, + {globals.unreal.mcast_delegate_prop, UNREAL_PROP_KIND_MULTICAST_DELEGATE }, + {globals.unreal.mcast_inline_delegate_prop, UNREAL_PROP_KIND_MULTICAST_INLINE_DELEGATE}, + {globals.unreal.mcast_sparse_delegate_prop, UNREAL_PROP_KIND_MULTICAST_SPARSE_DELEGATE}, + }; + + for (int32_t i = 0; i < COUNTOF(kinds); ++i) { + if (unreal_fname_equal(prop->cls->name, kinds[i].class_name, false)) { + return kinds[i].kind; + } + } + return UNREAL_PROP_KIND_UNKNOWN; +} + +bool +unreal_fprop_struct_is(fprop_t *prop, fname_t struct_name) +{ + if (unreal_fprop_get_kind(prop) != UNREAL_PROP_KIND_STRUCT) { + return false; + } + + uscript_struct_t *script_struct = ((fprop_struct_t *)prop)->script_struct; + return script_struct && unreal_fname_equal(script_struct->name, struct_name, false); +} + +bool +unreal_fprop_class_is(fprop_t *prop, fname_t name) +{ + if (prop && prop->cls) { + return unreal_fname_equal(prop->cls->name, name, false); + } + return false; +} + +bool +unreal_fprop_class_is_a(fprop_t *prop, fname_t name) +{ + for (ffield_class_t *cls = prop ? prop->cls : NULL; cls; cls = cls->super_class) { + if (unreal_fname_equal(cls->name, name, false)) { + return true; + } + } + return false; +} + +str_t +unreal_fprop_push_type_name(fprop_t *prop, arena_t *arena) +{ + if (!prop || !prop->cls || !arena) { + return STR_LIT(""); + } + + struct { + str_t name; + fname_t fname; + } simple_prop_names[] = { + {STR_CLIT("bool"), globals.unreal.bool_prop }, + {STR_CLIT("uint8_t"), globals.unreal.byte_prop }, + {STR_CLIT("int8_t"), globals.unreal.int8_prop }, + {STR_CLIT("int16_t"), globals.unreal.int16_prop }, + {STR_CLIT("int32_t"), globals.unreal.int_prop }, + {STR_CLIT("int32_t"), globals.unreal.int32_prop }, + {STR_CLIT("int64_t"), globals.unreal.int64_prop }, + {STR_CLIT("uint16_t"), globals.unreal.uint16_prop}, + {STR_CLIT("uint32_t"), globals.unreal.uint32_prop}, + {STR_CLIT("uint64_t"), globals.unreal.uint64_prop}, + {STR_CLIT("float"), globals.unreal.float_prop }, + {STR_CLIT("double"), globals.unreal.double_prop}, + {STR_CLIT("FName"), globals.unreal.name_prop }, + {STR_CLIT("FString"), globals.unreal.str_prop }, + {STR_CLIT("FText"), globals.unreal.text_prop }, + }; + + for (int i = 0; i < COUNTOF(simple_prop_names); ++i) { + str_t type_name = simple_prop_names[i].name; + fname_t type_fname = simple_prop_names[i].fname; + + if (unreal_fprop_class_is(prop, type_fname)) { + return type_name; // ok, because it's string literal + } + } + + if (unreal_fprop_class_is(prop, globals.unreal.obj_prop)) { + fprop_obj_base_t *p = (fprop_obj_base_t *)prop; + return unreal_fprop_class_push_type_name(arena, STR_LIT("Object"), p->prop_class); + } + + if (unreal_fprop_class_is(prop, globals.unreal.class_prop)) { + fprop_class_t *p = (fprop_class_t *)prop; + return unreal_fprop_class_push_type_name(arena, STR_LIT("Class"), p->meta_class); + } + + if (unreal_fprop_class_is(prop, globals.unreal.soft_obj_prop)) { + fprop_obj_base_t *p = (fprop_obj_base_t *)prop; + return unreal_fprop_class_push_type_name(arena, STR_LIT("SoftObject"), p->prop_class); + } + + if (unreal_fprop_class_is(prop, globals.unreal.soft_class_prop)) { + fprop_class_soft_t *p = (fprop_class_soft_t *)prop; + return unreal_fprop_class_push_type_name(arena, STR_LIT("SoftClass"), p->meta_class); + } + + if (unreal_fprop_class_is(prop, globals.unreal.weak_obj_prop)) { + fprop_obj_base_t *p = (fprop_obj_base_t *)prop; + return unreal_fprop_class_push_type_name(arena, STR_LIT("WeakObject"), p->prop_class); + } + + if (unreal_fprop_class_is(prop, globals.unreal.lazy_obj_prop)) { + fprop_obj_base_t *p = (fprop_obj_base_t *)prop; + return unreal_fprop_class_push_type_name(arena, STR_LIT("LazyObject"), p->prop_class); + } + + if (unreal_fprop_class_is(prop, globals.unreal.interface_prop)) { + fprop_iface_t *p = (fprop_iface_t *)prop; + return unreal_fprop_class_push_type_name(arena, STR_LIT("Interface"), p->iface_class); + } + + if (unreal_fprop_class_is(prop, globals.unreal.struct_prop)) { + fprop_struct_t *p = (fprop_struct_t *)prop; + + if (!p->script_struct) { + return STR_LIT(""); + } + + return unreal_uobject_push_name((uobject_t *)p->script_struct, arena); + } + + if (unreal_fprop_class_is(prop, globals.unreal.enum_prop)) { + fprop_enum_t *p = (fprop_enum_t *)prop; + str_t enum_name = p->uenum ? unreal_uobject_push_name((uobject_t *)p->uenum, arena) : STR_LIT(""); + + if (p->underlying_prop) { + str_t underlying_type_name = unreal_fprop_push_type_name(&p->underlying_prop->base, arena); + return str_push_fmt(arena, "Enum<%.*s:%.*s>", STR_ARG(enum_name), STR_ARG(underlying_type_name)); + } + return str_push_fmt(arena, "Enum<%.*s>", STR_ARG(enum_name)); + } + + if (unreal_fprop_class_is(prop, globals.unreal.array_prop)) { + fprop_array_t *p = (fprop_array_t *)prop; + str_t inner_type_name = unreal_fprop_push_type_name(p->inner, arena); + return str_push_fmt(arena, "TArray<%.*s>", STR_ARG(inner_type_name)); + } + + if (unreal_fprop_class_is(prop, globals.unreal.set_prop)) { + fprop_set_t *p = (fprop_set_t *)prop; + str_t elem_type_name = unreal_fprop_push_type_name(p->elem_prop, arena); + return str_push_fmt(arena, "TSet<%.*s>", STR_ARG(elem_type_name)); + } + + if (unreal_fprop_class_is(prop, globals.unreal.map_prop)) { + fprop_map_t *p = (fprop_map_t *)prop; + str_t key_type_name = unreal_fprop_push_type_name(p->key_prop, arena); + str_t value_type_name = unreal_fprop_push_type_name(p->val_prop, arena); + return str_push_fmt(arena, "TMap<%.*s, %.*s>", STR_ARG(key_type_name), STR_ARG(value_type_name)); + } + + if (unreal_fprop_class_is(prop, globals.unreal.delegate_prop)) { + fprop_delegate_t *p = (fprop_delegate_t *)prop; + str_t sig = p->signature_func ? unreal_uobject_push_name((uobject_t *)p->signature_func, arena) : STR_LIT(""); + return str_push_fmt(arena, "Delegate<%.*s>", STR_ARG(sig)); + } + + if (unreal_fprop_class_is(prop, globals.unreal.mcast_delegate_prop)) { + fprop_mcast_delegate_t *p = (fprop_mcast_delegate_t *)prop; + str_t sig = p->signature_func ? unreal_uobject_push_name((uobject_t *)p->signature_func, arena) : STR_LIT(""); + return str_push_fmt(arena, "MulticastDelegate<%.*s>", STR_ARG(sig)); + } + + if (unreal_fprop_class_is(prop, globals.unreal.mcast_inline_delegate_prop)) { + fprop_mcast_delegate_t *p = (fprop_mcast_delegate_t *)prop; + str_t sig = p->signature_func ? unreal_uobject_push_name((uobject_t *)p->signature_func, arena) : STR_LIT(""); + return str_push_fmt(arena, "MulticastInlineDelegate<%.*s>", STR_ARG(sig)); + } + + if (unreal_fprop_class_is(prop, globals.unreal.mcast_sparse_delegate_prop)) { + fprop_mcast_delegate_t *p = (fprop_mcast_delegate_t *)prop; + str_t sig = p->signature_func ? unreal_uobject_push_name((uobject_t *)p->signature_func, arena) : STR_LIT(""); + return str_push_fmt(arena, "MulticastSparseDelegate<%.*s>", STR_ARG(sig)); + } + + return unreal_fname_to_str(prop->cls->name, arena); +} + +bool +unreal_fprop_read_bool(fprop_t *prop, const void *value, bool *out) +{ + if (unreal_fprop_get_kind(prop) != UNREAL_PROP_KIND_BOOL || !value || !out) { + return false; + } + + fprop_bool_t *bool_prop = (fprop_bool_t *)prop; + if (prop->elem_size <= 0 || bool_prop->field_size == 0 || + bool_prop->byte_offset >= prop->elem_size || bool_prop->byte_offset >= bool_prop->field_size || + bool_prop->field_mask == 0) { + return false; + } + + uint8_t byte = *((const uint8_t *)value + bool_prop->byte_offset); + *out = (byte & bool_prop->field_mask) != 0; + return true; +} + +bool +unreal_fprop_read_integer(fprop_t *prop, const void *value, unreal_prop_integer_t *out) +{ + if (!prop || !value || !out) { + return false; + } + + unreal_prop_integer_t result = {0}; + switch (unreal_fprop_get_kind(prop)) { + case UNREAL_PROP_KIND_BYTE: { + if (prop->elem_size < (int32_t)sizeof(uint8_t)) { + return false; + } + + result.value = *(const uint8_t *)value; + break; + } + + case UNREAL_PROP_KIND_INT8: { + if (prop->elem_size < (int32_t)sizeof(int8_t)) { + return false; + } + + result.value = (uint64_t)*(const int8_t *)value; + result.is_signed = true; + break; + } + + case UNREAL_PROP_KIND_INT16: { + if (prop->elem_size < (int32_t)sizeof(int16_t)) { + return false; + } + + int16_t typed_value = 0; + mem_copy(&typed_value, (void *)value, sizeof(typed_value)); + result.value = (uint64_t)typed_value; + result.is_signed = true; + break; + } + + case UNREAL_PROP_KIND_INT32: { + if (prop->elem_size < (int32_t)sizeof(int32_t)) { + return false; + } + + int32_t typed_value = 0; + mem_copy(&typed_value, (void *)value, sizeof(typed_value)); + + result.value = (uint64_t)typed_value; + result.is_signed = true; + break; + } + + case UNREAL_PROP_KIND_INT64: { + if (prop->elem_size < (int32_t)sizeof(int64_t)) { + return false; + } + + int64_t typed_value = 0; + mem_copy(&typed_value, (void *)value, sizeof(typed_value)); + + result.value = (uint64_t)typed_value; + result.is_signed = true; + break; + } + + case UNREAL_PROP_KIND_UINT16: { + if (prop->elem_size < (int32_t)sizeof(uint16_t)) { + return false; + } + + uint16_t typed_value = 0; + mem_copy(&typed_value, (void *)value, sizeof(typed_value)); + result.value = typed_value; + break; + } + + case UNREAL_PROP_KIND_UINT32: { + if (prop->elem_size < (int32_t)sizeof(uint32_t)) { + return false; + } + + uint32_t typed_value = 0; + mem_copy(&typed_value, (void *)value, sizeof(typed_value)); + result.value = typed_value; + break; + } + + case UNREAL_PROP_KIND_UINT64: { + if (prop->elem_size < (int32_t)sizeof(uint64_t)) { + return false; + } + + uint64_t typed_value = 0; + mem_copy(&typed_value, (void *)value, sizeof(typed_value)); + result.value = typed_value; + break; + } + + case UNREAL_PROP_KIND_ENUM: { + fprop_enum_t *enum_prop = (fprop_enum_t *)prop; + if (!enum_prop->underlying_prop) { + return false; + } + + return unreal_fprop_read_integer(&enum_prop->underlying_prop->base, value, out); + } + + default: { + return false; + } + } + + *out = result; + return true; +} + +bool +unreal_fprop_read_real(fprop_t *prop, const void *value, double *out) +{ + if (!prop || !value || !out) { + return false; + } + + switch (unreal_fprop_get_kind(prop)) { + case UNREAL_PROP_KIND_FLOAT: { + if (prop->elem_size < (int32_t)sizeof(float)) { + return false; + } + + float typed_value = 0.0f; + mem_copy(&typed_value, (void *)value, sizeof(typed_value)); + *out = (double)typed_value; + return true; + } + + case UNREAL_PROP_KIND_DOUBLE: { + if (prop->elem_size < (int32_t)sizeof(double)) { + return false; + } + + double typed_value = 0.0; + mem_copy(&typed_value, (void *)value, sizeof(typed_value)); + *out = typed_value; + return true; + } + + default: { + return false; + } + } +} + +bool +unreal_fprop_read_name(fprop_t *prop, const void *value, fname_t *out) +{ + if (unreal_fprop_get_kind(prop) != UNREAL_PROP_KIND_NAME || !value || !out || + prop->elem_size < (int32_t)sizeof(*out)) { + return false; + } + + mem_copy(out, (void *)value, sizeof(*out)); + return true; +} + +bool +unreal_fprop_write_bool(fprop_t *prop, void *value, bool input) +{ + if (unreal_fprop_get_kind(prop) != UNREAL_PROP_KIND_BOOL || !value) { + return false; + } + + fprop_bool_t *bool_prop = (fprop_bool_t *)prop; + if (prop->elem_size <= 0 || bool_prop->field_size == 0 || + bool_prop->byte_offset >= prop->elem_size || bool_prop->byte_offset >= bool_prop->field_size || + bool_prop->byte_mask == 0 || bool_prop->field_mask == 0) { + return false; + } + + uint8_t *byte = (uint8_t *)value + bool_prop->byte_offset; + *byte = (uint8_t)((*byte & (uint8_t)~bool_prop->field_mask) | (input ? bool_prop->byte_mask : 0)); + return true; +} + +static bool +unreal_prop_integer_as_signed(unreal_prop_integer_t input, int64_t min, int64_t max, int64_t *out) +{ + if (!out) { + return false; + } + + if (!input.is_signed) { + if (input.value > (uint64_t)max) { + return false; + } + *out = (int64_t)input.value; + return true; + } + + int64_t value = (int64_t)input.value; + if (value < min || value > max) { + return false; + } + + *out = value; + return true; +} + +static bool +unreal_prop_integer_as_unsigned(unreal_prop_integer_t input, uint64_t max, uint64_t *out) +{ + if (!out) { + return false; + } + + uint64_t value = input.value; + if (input.is_signed) { + int64_t signed_value = (int64_t)input.value; + if (signed_value < 0) { + return false; + } + value = (uint64_t)signed_value; + } + + if (value > max) { + return false; + } + + *out = value; + return true; +} + +bool +unreal_fprop_write_integer(fprop_t *prop, void *value, unreal_prop_integer_t input) +{ + if (!prop || !value) { + return false; + } + + switch (unreal_fprop_get_kind(prop)) { + case UNREAL_PROP_KIND_BYTE: { + uint64_t converted = 0; + if (prop->elem_size < (int32_t)sizeof(uint8_t) || + !unreal_prop_integer_as_unsigned(input, UINT8_MAX, &converted)) { + return false; + } + + *(uint8_t *)value = (uint8_t)converted; + return true; + } + + case UNREAL_PROP_KIND_INT8: { + int64_t converted = 0; + if (prop->elem_size < (int32_t)sizeof(int8_t) || + !unreal_prop_integer_as_signed(input, INT8_MIN, INT8_MAX, &converted)) { + return false; + } + + *(int8_t *)value = (int8_t)converted; + return true; + } + + case UNREAL_PROP_KIND_INT16: { + int64_t converted = 0; + if (prop->elem_size < (int32_t)sizeof(int16_t) || + !unreal_prop_integer_as_signed(input, INT16_MIN, INT16_MAX, &converted)) { + return false; + } + + int16_t typed_value = (int16_t)converted; + mem_copy(value, &typed_value, sizeof(typed_value)); + return true; + } + + case UNREAL_PROP_KIND_INT32: { + int64_t converted = 0; + if (prop->elem_size < (int32_t)sizeof(int32_t) || + !unreal_prop_integer_as_signed(input, INT32_MIN, INT32_MAX, &converted)) { + return false; + } + + int32_t typed_value = (int32_t)converted; + mem_copy(value, &typed_value, sizeof(typed_value)); + return true; + } + + case UNREAL_PROP_KIND_INT64: { + int64_t converted = 0; + if (prop->elem_size < (int32_t)sizeof(int64_t) || + !unreal_prop_integer_as_signed(input, INT64_MIN, INT64_MAX, &converted)) { + return false; + } + + mem_copy(value, &converted, sizeof(converted)); + return true; + } + + case UNREAL_PROP_KIND_UINT16: { + uint64_t converted = 0; + if (prop->elem_size < (int32_t)sizeof(uint16_t) || + !unreal_prop_integer_as_unsigned(input, UINT16_MAX, &converted)) { + return false; + } + + uint16_t typed_value = (uint16_t)converted; + mem_copy(value, &typed_value, sizeof(typed_value)); + return true; + } + + case UNREAL_PROP_KIND_UINT32: { + uint64_t converted = 0; + if (prop->elem_size < (int32_t)sizeof(uint32_t) || + !unreal_prop_integer_as_unsigned(input, UINT32_MAX, &converted)) { + return false; + } + + uint32_t typed_value = (uint32_t)converted; + mem_copy(value, &typed_value, sizeof(typed_value)); + return true; + } + + case UNREAL_PROP_KIND_UINT64: { + uint64_t converted = 0; + if (prop->elem_size < (int32_t)sizeof(uint64_t) || + !unreal_prop_integer_as_unsigned(input, UINT64_MAX, &converted)) { + return false; + } + + mem_copy(value, &converted, sizeof(converted)); + return true; + } + + case UNREAL_PROP_KIND_ENUM: { + fprop_enum_t *enum_prop = (fprop_enum_t *)prop; + return enum_prop->underlying_prop && unreal_fprop_write_integer(&enum_prop->underlying_prop->base, value, input); + } + + default: { + return false; + } + } +} + +bool +unreal_fprop_write_real(fprop_t *prop, void *value, double input) +{ + if (!prop || !value) { + return false; + } + + switch (unreal_fprop_get_kind(prop)) { + case UNREAL_PROP_KIND_FLOAT: { + if (prop->elem_size < (int32_t)sizeof(float) || + (input == input && (input < -FLT_MAX || input > FLT_MAX))) { + return false; + } + + float typed_value = (float)input; + mem_copy(value, &typed_value, sizeof(typed_value)); + return true; + } + + case UNREAL_PROP_KIND_DOUBLE: { + if (prop->elem_size < (int32_t)sizeof(double)) { + return false; + } + + mem_copy(value, &input, sizeof(input)); + return true; + } + + default: { + return false; + } + } +} + +bool +unreal_fprop_write_name(fprop_t *prop, void *value, fname_t input) +{ + if (unreal_fprop_get_kind(prop) != UNREAL_PROP_KIND_NAME || !value || + prop->elem_size < (int32_t)sizeof(input)) { + return false; + } + + mem_copy(value, &input, sizeof(input)); + return true; +} + +uobject_t * +unreal_fweak_object_resolve(fweak_object_ptr_t weak) +{ + if (weak.object_idx < 0 || weak.object_serial <= 0) { + return NULL; + } + + fuobject_item_t *item = unreal_uobject_array_get_item(weak.object_idx); + if (!item || item->serial_num != weak.object_serial || !unreal_uobject_array_item_is_valid(item)) { + return NULL; + } + + return item->obj; +} + +static str_t +unreal_fstring_push_plain(const fstring_t *string, arena_t *arena) +{ + if (!string || !string->data || string->len <= 0 || string->len > 4096) { + return STR_NULL; + } + return str_from_str16(arena, str16_make(string->data, (uint64_t)string->len)); +} + +static str_t +unreal_fstring_push_quoted(const fstring_t *string, arena_t *arena) +{ + str_t plain = unreal_fstring_push_plain(string, arena); + return str_push_fmt(arena, "\"%.*s\"", STR_ARG(plain)); +} + +static str_t +unreal_uobject_push_value_summary(uobject_t *object, arena_t *arena) +{ + if (!object) { + return STR_LIT("null"); + } + + if (!unreal_uobject_is_valid(object)) { + return str_push_fmt(arena, "", object); + } + + return unreal_uobject_push_full_name(object, arena); +} + +static str_t +unreal_fweak_object_push_summary(fweak_object_ptr_t weak, arena_t *arena) +{ + if (weak.object_idx < 0 || weak.object_serial <= 0) { + return STR_LIT("null"); + } + + uobject_t *object = unreal_fweak_object_resolve(weak); + if (object) { + return unreal_uobject_push_full_name(object, arena); + } + + return str_push_fmt(arena, "", weak.object_idx, weak.object_serial); +} + +str_t +unreal_fscript_delegate_push_summary(const fscript_delegate_t *delegate, arena_t *arena) +{ + if (!delegate || !arena) { + return STR_NULL; + } + + str_t function_name = unreal_fname_to_str(delegate->function_name, arena); + str_t object_name = unreal_fweak_object_push_summary(delegate->object, arena); + if (str_is_empty(function_name)) { + return str_push_fmt(arena, "%.*s.", STR_ARG(object_name)); + } + return str_push_fmt(arena, "%.*s.%.*s", STR_ARG(object_name), STR_ARG(function_name)); +} + +static str_t +unreal_fprop_push_hex_summary(const void *value, int32_t value_size, arena_t *arena) +{ + if (!value || value_size <= 0 || !arena) { + return STR_NULL; + } + + const uint8_t *bytes = (const uint8_t *)value; + str_t result = STR_NULL; + tmp_arena_t tmp = scratch_begin(arena); + { + str_list_t list = {0}; + for (int32_t i = 0; i < value_size; ++i) { + str_list_push(tmp.arena, &list, str_push_fmt(tmp.arena, "%02X", (uint32_t)bytes[i])); + } + + str_t body = str_list_join(tmp.arena, list, STR_NULL, STR_LIT(" "), STR_NULL); + result = str_push_fmt(arena, "raw bytes (%d): %.*s", value_size, STR_ARG(body)); + } + scratch_end(tmp); + return result; +} + +static str_t +unreal_fsoft_object_path_push_summary(const fsoft_object_path_t *path, arena_t *arena) +{ + if (!path) { + return STR_LIT("null"); + } + + str_t asset = unreal_fname_to_str(path->asset_path_name, arena); + str_t sub = unreal_fstring_push_plain(&path->sub_path_string, arena); + if (str_is_empty(asset) && str_is_empty(sub)) { + return STR_LIT("null"); + } + + if (str_is_empty(sub)) { + return str_push_fmt(arena, "\"%.*s\"", STR_ARG(asset)); + } + return str_push_fmt(arena, "\"%.*s:%.*s\"", STR_ARG(asset), STR_ARG(sub)); +} + +static str_t +unreal_fsoft_object_push_summary(const void *value, int32_t value_size, arena_t *arena) +{ + if (value_size == (int32_t)sizeof(fsoft_object_path_t)) { + return unreal_fsoft_object_path_push_summary((const fsoft_object_path_t *)value, arena); + } + + if (value_size >= (int32_t)sizeof(unreal_prop_soft_object_ptr_t)) { + const unreal_prop_soft_object_ptr_t *soft = (const unreal_prop_soft_object_ptr_t *)value; + uobject_t *object = unreal_fweak_object_resolve(soft->weak); + return object ? unreal_uobject_push_full_name(object, arena) : unreal_fsoft_object_path_push_summary(&soft->path, arena); + } + return STR_NULL; +} + +static str_t +unreal_ftext_push_summary(const ftext_t *text, arena_t *arena) +{ + if (!text || !text->text_data.obj) { + return STR_LIT("null"); + } + + itext_data_t *data = text->text_data.obj; + if (!data->vtable || !data->vtable->get_display_string) { + return str_push_fmt(arena, "\"\" Flags=0x%X", (uint32_t)text->flags); + } + + fstring_t *display_string = data->vtable->get_display_string(data); + str_t display = unreal_fstring_push_plain(display_string, arena); + return str_push_fmt(arena, "\"%.*s\" Flags=0x%X", STR_ARG(display), (uint32_t)text->flags); +} + +static str_t +unreal_fprop_push_struct_summary(fprop_t *prop, const void *value, int32_t value_size, arena_t *arena) +{ + if (unreal_fprop_struct_is(prop, globals.unreal.vector) || + unreal_fprop_struct_is(prop, globals.unreal.vector_net_quantize) || + unreal_fprop_struct_is(prop, globals.unreal.vector_net_quantize10) || + unreal_fprop_struct_is(prop, globals.unreal.vector_net_quantize100) || + unreal_fprop_struct_is(prop, globals.unreal.vector_net_quantize_normal)) { + if (value_size >= (int32_t)sizeof(fvector_t)) { + const fvector_t *v = (const fvector_t *)value; + return str_push_fmt(arena, "{X=%.3f Y=%.3f Z=%.3f}", v->x, v->y, v->z); + } + } else if (unreal_fprop_struct_is(prop, globals.unreal.vector2d)) { + if (value_size >= (int32_t)sizeof(fvector2d_t)) { + const fvector2d_t *v = (const fvector2d_t *)value; + return str_push_fmt(arena, "{X=%.3f Y=%.3f}", v->x, v->y); + } + } else if (unreal_fprop_struct_is(prop, globals.unreal.vector4)) { + if (value_size >= (int32_t)sizeof(unreal_prop_vector4_t)) { + const unreal_prop_vector4_t *v = (const unreal_prop_vector4_t *)value; + return str_push_fmt(arena, "{X=%.3f Y=%.3f Z=%.3f W=%.3f}", v->x, v->y, v->z, v->w); + } + } else if (unreal_fprop_struct_is(prop, globals.unreal.rotator)) { + if (value_size >= 3 * (int32_t)sizeof(float)) { + const float *r = (const float *)value; + return str_push_fmt(arena, "{Pitch=%.3f Yaw=%.3f Roll=%.3f}", r[0], r[1], r[2]); + } + } else if (unreal_fprop_struct_is(prop, globals.unreal.quat)) { + if (value_size >= (int32_t)sizeof(fquat_t)) { + const fquat_t *q = (const fquat_t *)value; + return str_push_fmt(arena, "{X=%.3f Y=%.3f Z=%.3f W=%.3f}", q->x, q->y, q->z, q->w); + } + } else if (unreal_fprop_struct_is(prop, globals.unreal.color)) { + if (value_size >= 4) { + const uint8_t *c = (const uint8_t *)value; + return str_push_fmt(arena, "{R=%u G=%u B=%u A=%u}", c[2], c[1], c[0], c[3]); + } + } else if (unreal_fprop_struct_is(prop, globals.unreal.linear_color)) { + if (value_size >= (int32_t)sizeof(unreal_prop_linear_color_t)) { + const unreal_prop_linear_color_t *c = (const unreal_prop_linear_color_t *)value; + return str_push_fmt(arena, "{R=%.3f G=%.3f B=%.3f A=%.3f}", c->r, c->g, c->b, c->a); + } + } else if (unreal_fprop_struct_is(prop, globals.unreal.key)) { + if (value_size >= (int32_t)sizeof(fkey_t)) { + str_t name = unreal_fname_to_str(((const fkey_t *)value)->name, arena); + return str_is_empty(name) ? STR_LIT("None") : name; + } + } else if (unreal_fprop_struct_is(prop, globals.unreal.gameplay_tag)) { + if (value_size >= (int32_t)sizeof(fgameplay_tag_t)) { + str_t name = unreal_fname_to_str(((const fgameplay_tag_t *)value)->tag_name, arena); + return str_is_empty(name) ? STR_LIT("None") : name; + } + } else if (unreal_fprop_struct_is(prop, globals.unreal.gameplay_tag_container)) { + if (value_size >= (int32_t)sizeof(fgameplay_tag_container_t)) { + const fgameplay_tag_container_t *container = (const fgameplay_tag_container_t *)value; + if (!container->gameplay_tags.data || container->gameplay_tags.num <= 0 || container->gameplay_tags.max <= 0) { + return STR_LIT("[]"); + } + + int32_t count = MIN_VAL(container->gameplay_tags.num, 2); + str_t result = STR_LIT("[]"); + tmp_arena_t tmp = scratch_begin(arena); + { + str_list_t list = {0}; + for (int32_t i = 0; i < count; ++i) { + str_t name = unreal_fname_to_str(container->gameplay_tags.data[i].tag_name, tmp.arena); + str_list_push(tmp.arena, &list, str_is_empty(name) ? STR_LIT("None") : name); + } + + str_t suffix = container->gameplay_tags.num > count + ? str_push_fmt(tmp.arena, "] +%d", container->gameplay_tags.num - count) + : STR_LIT("]"); + result = str_list_join(arena, list, STR_LIT("["), STR_LIT(", "), suffix); + } + scratch_end(tmp); + return result; + } + } else if (unreal_fprop_struct_is(prop, globals.unreal.guid)) { + if (value_size >= (int32_t)sizeof(fguid_t)) { + const fguid_t *g = (const fguid_t *)value; + return str_push_fmt(arena, "{%08X-%04X-%04X-%04X-%04X%08X}", + g->a, + (g->b >> 16) & 0xFFFF, g->b & 0xFFFF, + (g->c >> 16) & 0xFFFF, g->c & 0xFFFF, + g->d); + } + } else if (unreal_fprop_struct_is(prop, globals.unreal.int_point)) { + if (value_size >= (int32_t)sizeof(unreal_prop_int_point_t)) { + const unreal_prop_int_point_t *p = (const unreal_prop_int_point_t *)value; + return str_push_fmt(arena, "{X=%d Y=%d}", p->x, p->y); + } + } else if (unreal_fprop_struct_is(prop, globals.unreal.int_vector)) { + if (value_size >= (int32_t)sizeof(unreal_prop_int_vector_t)) { + const unreal_prop_int_vector_t *v = (const unreal_prop_int_vector_t *)value; + return str_push_fmt(arena, "{X=%d Y=%d Z=%d}", v->x, v->y, v->z); + } + } + + fprop_struct_t *struct_prop = (fprop_struct_t *)prop; + if (struct_prop->script_struct && struct_prop->script_struct->child_props) { + return STR_LIT("{...}"); + } + + str_t hex = unreal_fprop_push_hex_summary(value, value_size, arena); + return str_push_fmt(arena, " %.*s", STR_ARG(hex)); +} + +static str_t +unreal_fprop_push_enum_summary(fprop_enum_t *prop, const void *value, arena_t *arena) +{ + if (!prop->underlying_prop) { + return STR_LIT(""); + } + + unreal_prop_integer_t integer = {0}; + if (!unreal_fprop_read_integer(&prop->underlying_prop->base, value, &integer)) { + return STR_NULL; + } + + int64_t signed_value = (int64_t)integer.value; + str_t name = STR_NULL; + if (prop->uenum) { + for (int32_t i = 0; i < prop->uenum->names.num; ++i) { + if (prop->uenum->names.data[i].value == signed_value) { + name = unreal_fname_to_str(prop->uenum->names.data[i].key, arena); + break; + } + } + } + + if (!str_is_empty(name)) { + return str_push_fmt(arena, "%.*s (%lld)", STR_ARG(name), (long long)signed_value); + } + + return integer.is_signed ? str_push_fmt(arena, "%lld", (long long)signed_value) + : str_push_fmt(arena, "%llu", (unsigned long long)integer.value); +} + +str_t +unreal_fprop_push_value_summary(fprop_t *prop, const void *value, int32_t value_size, arena_t *arena) +{ + if (!prop || !value || prop->elem_size <= 0 || value_size < prop->elem_size || !arena) { + return STR_NULL; + } + + switch (unreal_fprop_get_kind(prop)) { + case UNREAL_PROP_KIND_BOOL: { + bool result = false; + return unreal_fprop_read_bool(prop, value, &result) ? (result ? STR_LIT("true") : STR_LIT("false")) : STR_NULL; + } + + case UNREAL_PROP_KIND_BYTE: + case UNREAL_PROP_KIND_INT8: + case UNREAL_PROP_KIND_INT16: + case UNREAL_PROP_KIND_INT32: + case UNREAL_PROP_KIND_INT64: + case UNREAL_PROP_KIND_UINT16: + case UNREAL_PROP_KIND_UINT32: + case UNREAL_PROP_KIND_UINT64: { + unreal_prop_integer_t integer = {0}; + if (!unreal_fprop_read_integer(prop, value, &integer)) { + return STR_NULL; + } + return integer.is_signed ? str_push_fmt(arena, "%lld", (long long)(int64_t)integer.value) + : str_push_fmt(arena, "%llu", (unsigned long long)integer.value); + } + + case UNREAL_PROP_KIND_FLOAT: + case UNREAL_PROP_KIND_DOUBLE: { + double result = 0.0; + return unreal_fprop_read_real(prop, value, &result) ? str_push_fmt(arena, "%.3f", result) : STR_NULL; + } + + case UNREAL_PROP_KIND_NAME: { + fname_t name_value = {0}; + if (value_size < (int32_t)sizeof(name_value) || !unreal_fprop_read_name(prop, value, &name_value)) { + return STR_NULL; + } + str_t name = unreal_fname_to_str(name_value, arena); + return str_push_fmt(arena, "\"%.*s\"", STR_ARG(name)); + } + + case UNREAL_PROP_KIND_STRING: { + return value_size >= (int32_t)sizeof(fstring_t) + ? unreal_fstring_push_quoted((const fstring_t *)value, arena) + : STR_NULL; + } + + case UNREAL_PROP_KIND_TEXT: { + return value_size >= (int32_t)sizeof(ftext_t) + ? unreal_ftext_push_summary((const ftext_t *)value, arena) + : STR_NULL; + } + + case UNREAL_PROP_KIND_OBJECT: + case UNREAL_PROP_KIND_CLASS: { + return value_size >= (int32_t)sizeof(uobject_t *) + ? unreal_uobject_push_value_summary(unreal_fprop_get_object((fprop_obj_base_t *)prop, value), arena) + : STR_NULL; + } + + case UNREAL_PROP_KIND_SOFT_OBJECT: + case UNREAL_PROP_KIND_SOFT_CLASS: { + return unreal_fsoft_object_push_summary(value, value_size, arena); + } + + case UNREAL_PROP_KIND_WEAK_OBJECT: { + return value_size >= (int32_t)sizeof(fweak_object_ptr_t) + ? unreal_fweak_object_push_summary(*(const fweak_object_ptr_t *)value, arena) + : STR_NULL; + } + + case UNREAL_PROP_KIND_LAZY_OBJECT: { + if (value_size < (int32_t)sizeof(unreal_prop_lazy_object_ptr_t)) { + return STR_NULL; + } + + const unreal_prop_lazy_object_ptr_t *lazy = (const unreal_prop_lazy_object_ptr_t *)value; + uobject_t *object = unreal_fweak_object_resolve(lazy->weak); + if (object) { + return unreal_uobject_push_full_name(object, arena); + } + + const fguid_t *guid = &lazy->object_id; + if (guid->a == 0 && guid->b == 0 && guid->c == 0 && guid->d == 0) { + return STR_LIT("null"); + } + return str_push_fmt(arena, "{%08X-%08X-%08X-%08X}", guid->a, guid->b, guid->c, guid->d); + } + + case UNREAL_PROP_KIND_INTERFACE: { + if (value_size < (int32_t)sizeof(unreal_prop_script_interface_t)) { + return STR_NULL; + } + + const unreal_prop_script_interface_t *interface = (const unreal_prop_script_interface_t *)value; + str_t object = unreal_uobject_push_value_summary(interface->object, arena); + return str_push_fmt(arena, "%.*s Interface=%p", STR_ARG(object), interface->interface_ptr); + } + + case UNREAL_PROP_KIND_DELEGATE: { + return value_size >= (int32_t)sizeof(fscript_delegate_t) + ? unreal_fscript_delegate_push_summary((const fscript_delegate_t *)value, arena) + : STR_NULL; + } + + case UNREAL_PROP_KIND_MULTICAST_DELEGATE: + case UNREAL_PROP_KIND_MULTICAST_INLINE_DELEGATE: { + if (value_size < (int32_t)sizeof(fmulticast_script_delegate_t)) { + return STR_NULL; + } + const fmulticast_script_delegate_t *list = (const fmulticast_script_delegate_t *)value; + return str_push_fmt(arena, "Num=%d Max=%d Data=%p", list->num, list->max, list->data); + } + + case UNREAL_PROP_KIND_MULTICAST_SPARSE_DELEGATE: { + return str_push_fmt(arena, "SparseDelegate 0x%02X", (uint32_t)*(const uint8_t *)value); + } + + case UNREAL_PROP_KIND_STRUCT: { + return unreal_fprop_push_struct_summary(prop, value, value_size, arena); + } + + case UNREAL_PROP_KIND_ARRAY: { + int32_t num = unreal_array_num(value, (fprop_array_t *)prop); + if (num < 0) { + return STR_LIT(""); + } + + const fscript_array_t *array = (const fscript_array_t *)value; + return str_push_fmt(arena, "Num=%d Max=%d Data=%p", num, array->max, array->data); + } + + case UNREAL_PROP_KIND_SET: { + int32_t num = unreal_set_num(value, (fprop_set_t *)prop); + int32_t max_index = unreal_set_max_index(value, (fprop_set_t *)prop); + return num >= 0 && max_index >= 0 + ? str_push_fmt(arena, "Num=%d Slots=%d", num, max_index) + : STR_LIT(""); + } + + case UNREAL_PROP_KIND_MAP: { + int32_t num = unreal_map_num(value, (fprop_map_t *)prop); + int32_t max_index = unreal_map_max_index(value, (fprop_map_t *)prop); + return num >= 0 && max_index >= 0 + ? str_push_fmt(arena, "Num=%d Slots=%d", num, max_index) + : STR_LIT(""); + } + + case UNREAL_PROP_KIND_ENUM: { + return unreal_fprop_push_enum_summary((fprop_enum_t *)prop, value, arena); + } + + default: { + return unreal_fprop_push_hex_summary(value, value_size, arena); + } + } +} + +static bool +unreal_fprop_has_valid_layout(fprop_t *prop) +{ + return prop && prop->elem_size > 0 && prop->array_dim > 0; +} + +uint64_t +unreal_fprop_complete_size(fprop_t *prop) +{ + if (!unreal_fprop_has_valid_layout(prop)) { + return 0; + } + return (uint64_t)prop->elem_size * (uint64_t)prop->array_dim; +} + +int32_t +unreal_fprop_min_alignment(fprop_t *prop) +{ + if (!unreal_fprop_has_valid_layout(prop) || !prop->vtable || !prop->vtable->get_min_alignment) { + return 0; + } + + int32_t alignment = prop->vtable->get_min_alignment(prop); + return alignment > 0 ? alignment : 0; +} + +void * +unreal_fprop_value_at(fprop_t *prop, void *value, int32_t array_idx) +{ + if (!unreal_fprop_has_valid_layout(prop) || !value || array_idx < 0 || array_idx >= prop->array_dim) { + return NULL; + } + return (uint8_t *)value + (uint64_t)array_idx * (uint64_t)prop->elem_size; +} + +void * +unreal_fprop_value_in_container(fprop_t *prop, void *container, int32_t array_idx) +{ + if (!prop || !container || prop->offset_internal < 0) { + return NULL; + } + return unreal_fprop_value_at(prop, (uint8_t *)container + prop->offset_internal, array_idx); +} + +bool +unreal_fprop_initialize_value(fprop_t *prop, void *value) +{ + uint64_t size = unreal_fprop_complete_size(prop); + if (size == 0 || !value) { + return false; + } + + if (prop->prop_flags & CPF_ZERO_CONSTRUCTOR) { + mem_zero(value, size); + return true; + } + + if (!prop->vtable || !prop->vtable->initialize_value_internal) { + return false; + } + + prop->vtable->initialize_value_internal(prop, value); + return true; +} + +bool +unreal_fprop_destroy_value(fprop_t *prop, void *value) +{ + if (!unreal_fprop_has_valid_layout(prop) || !value) { + return false; + } + + if (prop->prop_flags & CPF_NO_DESTRUCTOR) { + return true; + } + + if (!prop->vtable || !prop->vtable->destroy_value_internal) { + return false; + } + + prop->vtable->destroy_value_internal(prop, value); + return true; +} + +bool +unreal_fprop_clear_single_value(fprop_t *prop, void *value) +{ + if (!unreal_fprop_has_valid_layout(prop) || !value) { + return false; + } + + if ((prop->prop_flags & (CPF_NO_DESTRUCTOR | CPF_ZERO_CONSTRUCTOR)) == + (CPF_NO_DESTRUCTOR | CPF_ZERO_CONSTRUCTOR)) { + mem_zero(value, (uint64_t)prop->elem_size); + return true; + } + + if (!prop->vtable || !prop->vtable->clear_value_internal) { + return false; + } + + prop->vtable->clear_value_internal(prop, value); + return true; +} + +bool +unreal_fprop_clear_complete_value(fprop_t *prop, void *value) +{ + if (!unreal_fprop_has_valid_layout(prop) || !value) { + return false; + } + + for (int32_t i = 0; i < prop->array_dim; ++i) { + void *elem = unreal_fprop_value_at(prop, value, i); + if (!unreal_fprop_clear_single_value(prop, elem)) { + return false; + } + } + return true; +} + +bool +unreal_fprop_copy_single_value(fprop_t *prop, void *dst, const void *src) +{ + if (!unreal_fprop_has_valid_layout(prop) || !dst || !src) { + return false; + } + + if (dst == src) { + return true; + } + + if (prop->prop_flags & CPF_IS_PLAIN_OLD_DATA) { + mem_copy(dst, (void *)src, (uint64_t)prop->elem_size); + return true; + } + + if (!prop->vtable || !prop->vtable->copy_values_internal) { + return false; + } + + prop->vtable->copy_values_internal(prop, dst, src, 1); + return true; +} + +bool +unreal_fprop_copy_complete_value(fprop_t *prop, void *dst, const void *src) +{ + uint64_t size = unreal_fprop_complete_size(prop); + if (size == 0 || !dst || !src) { + return false; + } + + if (dst == src) { + return true; + } + + if (prop->prop_flags & CPF_IS_PLAIN_OLD_DATA) { + mem_copy(dst, (void *)src, size); + return true; + } + + if (!prop->vtable || !prop->vtable->copy_values_internal) { + return false; + } + + prop->vtable->copy_values_internal(prop, dst, src, prop->array_dim); + return true; +} + +bool +unreal_fprop_copy_single_value_to_script_vm(fprop_t *prop, void *dst, const void *src) +{ + if (!unreal_fprop_has_valid_layout(prop) || !dst || !src || + !prop->vtable || !prop->vtable->copy_single_value_to_script_vm) { + return false; + } + + prop->vtable->copy_single_value_to_script_vm(prop, dst, src); + return true; +} + +bool +unreal_fprop_copy_complete_value_to_script_vm(fprop_t *prop, void *dst, const void *src) +{ + if (!unreal_fprop_has_valid_layout(prop) || !dst || !src || + !prop->vtable || !prop->vtable->copy_complete_value_to_script_vm) { + return false; + } + + prop->vtable->copy_complete_value_to_script_vm(prop, dst, src); + return true; +} + +bool +unreal_fprop_copy_single_value_from_script_vm(fprop_t *prop, void *dst, const void *src) +{ + if (!unreal_fprop_has_valid_layout(prop) || !dst || !src || + !prop->vtable || !prop->vtable->copy_single_value_from_script_vm) { + return false; + } + + prop->vtable->copy_single_value_from_script_vm(prop, dst, src); + return true; +} + +bool +unreal_fprop_copy_complete_value_from_script_vm(fprop_t *prop, void *dst, const void *src) +{ + if (!unreal_fprop_has_valid_layout(prop) || !dst || !src || + !prop->vtable || !prop->vtable->copy_complete_value_from_script_vm) { + return false; + } + + prop->vtable->copy_complete_value_from_script_vm(prop, dst, src); + return true; +} + +bool +unreal_fprop_single_values_identical(fprop_t *prop, const void *a, const void *b, uint32_t port_flags) +{ + if (!unreal_fprop_has_valid_layout(prop) || !a || !prop->vtable || !prop->vtable->identical) { + return false; + } + return prop->vtable->identical(prop, a, b, port_flags); +} + +bool +unreal_fprop_complete_values_identical(fprop_t *prop, const void *a, const void *b, uint32_t port_flags) +{ + if (!unreal_fprop_has_valid_layout(prop) || !a || !prop->vtable || !prop->vtable->identical) { + return false; + } + + for (int32_t i = 0; i < prop->array_dim; ++i) { + const void *a_elem = unreal_fprop_value_at(prop, (void *)a, i); + const void *b_elem = b ? unreal_fprop_value_at(prop, (void *)b, i) : NULL; + if (!prop->vtable->identical(prop, a_elem, b_elem, port_flags)) { + return false; + } + } + return true; +} + +bool +unreal_fprop_value_hash(fprop_t *prop, const void *value, uint32_t *out_hash) +{ + if (!unreal_fprop_has_valid_layout(prop) || !value || !out_hash || + !(prop->prop_flags & CPF_HAS_GET_VALUE_TYPE_HASH) || + !prop->vtable || !prop->vtable->get_value_type_hash_internal) { + return false; + } + + *out_hash = prop->vtable->get_value_type_hash_internal(prop, value); + return true; +} + +bool +unreal_fprop_same_type(fprop_t *prop, fprop_t *other) +{ + return prop && other && prop->vtable && prop->vtable->same_type && prop->vtable->same_type(prop, other); +} + +static bool +unreal_fprop_kind_is_object_reference(unreal_prop_kind_t kind) +{ + return kind == UNREAL_PROP_KIND_OBJECT || kind == UNREAL_PROP_KIND_CLASS || + kind == UNREAL_PROP_KIND_SOFT_OBJECT || kind == UNREAL_PROP_KIND_SOFT_CLASS || + kind == UNREAL_PROP_KIND_WEAK_OBJECT || kind == UNREAL_PROP_KIND_LAZY_OBJECT; +} + +uobject_t * +unreal_fprop_get_object(fprop_obj_base_t *prop, const void *value) +{ + if (!prop || !value || !prop->vtable || !unreal_fprop_kind_is_object_reference(unreal_fprop_get_kind((fprop_t *)prop))) { + return NULL; + } + + return prop->vtable->get_object_prop_value ? prop->vtable->get_object_prop_value(prop, value) : NULL; +} + +uobject_t * +unreal_fprop_get_referenced_object(fprop_t *prop, const void *value) +{ + if (!prop || !value) { + return NULL; + } + + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + switch (kind) { + case UNREAL_PROP_KIND_OBJECT: + case UNREAL_PROP_KIND_CLASS: { + return prop->elem_size >= (int32_t)sizeof(uobject_t *) + ? unreal_fprop_get_object((fprop_obj_base_t *)prop, value) + : NULL; + } + + case UNREAL_PROP_KIND_WEAK_OBJECT: { + return prop->elem_size >= (int32_t)sizeof(fweak_object_ptr_t) + ? unreal_fprop_get_object((fprop_obj_base_t *)prop, value) + : NULL; + } + + case UNREAL_PROP_KIND_LAZY_OBJECT: { + return prop->elem_size >= (int32_t)sizeof(unreal_prop_lazy_object_ptr_t) + ? unreal_fprop_get_object((fprop_obj_base_t *)prop, value) + : NULL; + } + + case UNREAL_PROP_KIND_SOFT_OBJECT: + case UNREAL_PROP_KIND_SOFT_CLASS: { + return prop->elem_size >= (int32_t)sizeof(unreal_prop_soft_object_ptr_t) + ? unreal_fprop_get_object((fprop_obj_base_t *)prop, value) + : NULL; + } + + case UNREAL_PROP_KIND_INTERFACE: { + return prop->elem_size >= (int32_t)sizeof(unreal_prop_script_interface_t) + ? ((const unreal_prop_script_interface_t *)value)->object + : NULL; + } + + default: { + return NULL; + } + } +} + +bool +unreal_fprop_object_is_compatible(fprop_obj_base_t *prop, uobject_t *object) +{ + unreal_prop_kind_t kind = unreal_fprop_get_kind((fprop_t *)prop); + if (!unreal_fprop_kind_is_object_reference(kind) || (object && (!prop->prop_class || !unreal_uobject_is_a(object, prop->prop_class)))) { + return false; + } + + if (!object) { + return true; + } + + uclass_t *meta_class = NULL; + if (kind == UNREAL_PROP_KIND_CLASS) { + meta_class = ((fprop_class_t *)prop)->meta_class; + } else if (kind == UNREAL_PROP_KIND_SOFT_CLASS) { + meta_class = ((fprop_class_soft_t *)prop)->meta_class; + } + + if (meta_class && !unreal_uclass_is_child_of((uclass_t *)object, meta_class)) { + return false; + } + return true; +} + +bool +unreal_fprop_set_object(fprop_obj_base_t *prop, void *value, uobject_t *object) +{ + if (!prop || !value || !prop->vtable || !unreal_fprop_object_is_compatible(prop, object)) { + return false; + } + + if (!prop->vtable->set_object_prop_value) { + return false; + } + + prop->vtable->set_object_prop_value(prop, value, object); + return true; +} + +void +unreal_fprop_initialize_in_container(fprop_t *prop, void *container) +{ + void *value = unreal_fprop_value_in_container(prop, container, 0); + if (value) { + unreal_fprop_initialize_value(prop, value); + } +} + +void +unreal_fprop_destroy_in_container(fprop_t *prop, void *container) +{ + void *value = unreal_fprop_value_in_container(prop, container, 0); + if (value) { + unreal_fprop_destroy_value(prop, value); + } +} + +bool +unreal_ustruct_initialize_struct(ustruct_t *struct_type, void *memory, int32_t array_dim) +{ + if (!struct_type || !memory || array_dim <= 0 || struct_type->props_size < 0 || + !struct_type->vtable || !struct_type->vtable->init_struct) { + return false; + } + + struct_type->vtable->init_struct(struct_type, memory, array_dim); + return true; +} + +bool +unreal_ustruct_destroy_struct(ustruct_t *struct_type, void *memory, int32_t array_dim) +{ + if (!struct_type || !memory || array_dim <= 0 || struct_type->props_size < 0 || + !struct_type->vtable || !struct_type->vtable->destroy_struct) { + return false; + } + + struct_type->vtable->destroy_struct(struct_type, memory, array_dim); + return true; +} + +const wchar_t * +unreal_fprop_import_text_direct(fprop_t *prop, const wchar_t *text, void *value, uobject_t *owner) +{ + if (!prop || !prop->vtable || !prop->vtable->import_text_internal || !text || !value) { + return NULL; + } + return prop->vtable->import_text_internal(prop, text, value, 0, owner, NULL); +} + +bool +unreal_fprop_import_text(fprop_t *prop, void *value, uobject_t *owner, str_t text, arena_t *arena) +{ + uint64_t size = unreal_fprop_complete_size(prop); + int32_t alignment = unreal_fprop_min_alignment(prop); + if (size == 0 || alignment <= 0 || !value || !text.data || !arena) { + return false; + } + + bool result = false; + tmp_arena_t tmp = scratch_begin(arena); + { + str16_t wide = str16_from_str(tmp.arena, text); + void *copy = arena_push_aligned(tmp.arena, size, (uint64_t)alignment); + if (wide.data && copy && unreal_fprop_initialize_value(prop, copy)) { + if (unreal_fprop_copy_single_value(prop, copy, value)) { + const wchar_t *end = unreal_fprop_import_text_direct(prop, (const wchar_t *)wide.data, copy, owner); + if (end) { + while (*end == L' ' || *end == L'\t' || *end == L'\r' || *end == L'\n') { + end += 1; + } + + if (*end == L'\0') { + result = unreal_fprop_copy_single_value(prop, value, copy); + } + } + } + unreal_fprop_destroy_value(prop, copy); + } + } + scratch_end(tmp); + return result; +} + +static bool +unreal_array_prop_is_valid(fprop_array_t *prop) +{ + return prop && unreal_fprop_has_valid_layout(&prop->base) && + prop->base.elem_size >= (int32_t)sizeof(fscript_array_t) && + prop->inner && unreal_fprop_has_valid_layout(prop->inner); +} + +static bool +unreal_array_view_is_valid(const void *array, fprop_array_t *prop) +{ + if (!array || !unreal_array_prop_is_valid(prop) || (prop->array_flags & EAPF_USES_MEM_IMAGE_ALLOCATOR)) { + return false; + } + + const fscript_array_t *script_array = (const fscript_array_t *)array; + return script_array->num >= 0 && script_array->max >= script_array->num && (script_array->num == 0 || script_array->data != NULL); +} + +int32_t +unreal_array_num(const void *array, fprop_array_t *prop) +{ + if (!unreal_array_view_is_valid(array, prop)) { + return -1; + } + return ((const fscript_array_t *)array)->num; +} + +void * +unreal_array_get(void *array, fprop_array_t *prop, int32_t idx) +{ + if (!unreal_array_view_is_valid(array, prop)) { + return NULL; + } + + fscript_array_t *script_array = (fscript_array_t *)array; + if (idx < 0 || idx >= script_array->num) { + return NULL; + } + + return (uint8_t *)script_array->data + (uint64_t)idx * (uint64_t)prop->inner->elem_size; +} + +int32_t +unreal_array_add(void *array, fprop_array_t *prop, const void *value) +{ + if (!array || !unreal_array_prop_is_valid(prop) || !value || !generic_array_add) { + return -1; + } + return generic_array_add(array, prop, value); +} + +void +unreal_array_insert(void *array, fprop_array_t *prop, int32_t idx, const void *value) +{ + if (array && unreal_array_prop_is_valid(prop) && idx >= 0 && value && generic_array_insert) { + generic_array_insert(array, prop, value, idx); + } +} + +void +unreal_array_remove(void *array, fprop_array_t *prop, int32_t idx) +{ + if (array && unreal_array_prop_is_valid(prop) && idx >= 0 && generic_array_remove) { + generic_array_remove(array, prop, idx); + } +} + +void +unreal_array_resize(void *array, fprop_array_t *prop, int32_t size) +{ + if (array && unreal_array_prop_is_valid(prop) && size >= 0 && generic_array_resize) { + generic_array_resize(array, prop, size); + } +} + +void +unreal_array_set(void *array, fprop_array_t *prop, int32_t idx, const void *value, bool size_to_fit) +{ + if (array && unreal_array_prop_is_valid(prop) && idx >= 0 && value && generic_array_set) { + generic_array_set(array, prop, idx, value, size_to_fit); + } +} + +bool +unreal_array_clear(void *array, fprop_array_t *prop) +{ + return array && unreal_array_prop_is_valid(prop) && unreal_fprop_clear_single_value(&prop->base, array); +} + +static bool +unreal_script_set_view_is_valid(const fscript_set_t *set, const fscript_set_layout_t *layout) +{ + if (!set || !layout || layout->size <= 0 || layout->sparse_array_layout.size < layout->size || + layout->sparse_array_layout.alignment <= 0) { + return false; + } + + const fscript_sparse_array_t *sparse = &set->elems; + return sparse->data.num >= 0 && + sparse->data.max >= sparse->data.num && + sparse->num_free_idx >= 0 && + sparse->num_free_idx <= sparse->data.num && + sparse->alloc_flags.num_bits >= sparse->data.num && + sparse->alloc_flags.max_bits >= sparse->alloc_flags.num_bits && + (sparse->data.num == 0 || sparse->data.data != NULL); +} + +static int32_t +unreal_script_set_num(const fscript_set_t *set, const fscript_set_layout_t *layout) +{ + if (!unreal_script_set_view_is_valid(set, layout)) { + return -1; + } + return set->elems.data.num - set->elems.num_free_idx; +} + +static int32_t +unreal_script_set_max_index(const fscript_set_t *set, const fscript_set_layout_t *layout) +{ + if (!unreal_script_set_view_is_valid(set, layout)) { + return -1; + } + return set->elems.data.num; +} + +static bool +unreal_script_set_is_valid_index(const fscript_set_t *set, const fscript_set_layout_t *layout, int32_t idx) +{ + return unreal_script_set_view_is_valid(set, layout) && idx >= 0 && idx < set->elems.data.num && + unreal_tbit_array_is_set((tbit_array_t *)&set->elems.alloc_flags, idx); +} + +static void * +unreal_script_set_get(void *set, const fscript_set_layout_t *layout, int32_t index) +{ + fscript_set_t *script_set = (fscript_set_t *)set; + if (!unreal_script_set_is_valid_index(script_set, layout, index)) { + return NULL; + } + + return (uint8_t *)script_set->elems.data.data + (uint64_t)index * (uint64_t)layout->sparse_array_layout.size; +} + +static bool +unreal_set_prop_is_valid(fprop_set_t *prop) +{ + return prop && unreal_fprop_has_valid_layout(&prop->base) && + prop->base.elem_size >= (int32_t)sizeof(fscript_set_t) && prop->elem_prop && + unreal_fprop_has_valid_layout(prop->elem_prop) && prop->set_layout.size > 0 && + prop->set_layout.sparse_array_layout.size >= prop->set_layout.size; +} + +int32_t +unreal_set_num(const void *set, fprop_set_t *prop) +{ + if (!unreal_set_prop_is_valid(prop)) { + return -1; + } + return unreal_script_set_num((const fscript_set_t *)set, &prop->set_layout); +} + +int32_t +unreal_set_max_index(const void *set, fprop_set_t *prop) +{ + if (!unreal_set_prop_is_valid(prop)) { + return -1; + } + return unreal_script_set_max_index((const fscript_set_t *)set, &prop->set_layout); +} + +bool +unreal_set_is_valid_index(const void *set, fprop_set_t *prop, int32_t idx) +{ + return unreal_set_prop_is_valid(prop) && unreal_script_set_is_valid_index((const fscript_set_t *)set, &prop->set_layout, idx); +} + +const void * +unreal_set_get(const void *set, fprop_set_t *prop, int32_t idx) +{ + if (!unreal_set_prop_is_valid(prop)) { + return NULL; + } + return unreal_script_set_get((void *)set, &prop->set_layout, idx); +} + +int32_t +unreal_set_find_index(const void *set, fprop_set_t *prop, const void *value) +{ + int32_t max_index = unreal_set_max_index(set, prop); + if (max_index < 0 || !value) { + return TSET_INVALID_ID; + } + + for (int32_t index = 0; index < max_index; ++index) { + const void *elem = unreal_set_get(set, prop, index); + if (elem && unreal_fprop_single_values_identical(prop->elem_prop, elem, value, 0)) { + return index; + } + } + return TSET_INVALID_ID; +} + +bool +unreal_set_contains(const void *set, fprop_set_t *prop, const void *value) +{ + return unreal_set_find_index(set, prop, value) != TSET_INVALID_ID; +} + +void +unreal_set_add(void *set, fprop_set_t *prop, const void *value) +{ + if (!set || !unreal_set_prop_is_valid(prop) || !value || !fscript_set_add_elem) { + return; + } + + fscript_set_helper_t helper = { + .elem_prop = prop->elem_prop, + .set = set, + .layout = prop->set_layout, + }; + fscript_set_add_elem(&helper, value); +} + +bool +unreal_set_remove(void *set, fprop_set_t *prop, const void *value) +{ + if (!set || !unreal_set_prop_is_valid(prop) || !value || !generic_set_remove) { + return false; + } + return generic_set_remove(set, prop, value); +} + +bool +unreal_set_clear(void *set, fprop_set_t *prop) +{ + return set && unreal_set_prop_is_valid(prop) && unreal_fprop_clear_single_value(&prop->base, set); +} + +static bool +unreal_map_prop_is_valid(fprop_map_t *prop) +{ + if (!prop || !unreal_fprop_has_valid_layout(&prop->base) || !prop->key_prop || !prop->val_prop || + prop->base.elem_size < (int32_t)sizeof(fscript_map_t) || + !unreal_fprop_has_valid_layout(prop->key_prop) || !unreal_fprop_has_valid_layout(prop->val_prop)) { + return false; + } + + const fscript_map_layout_t *layout = &prop->map_layout; + return layout->set_layout.size > 0 && + layout->set_layout.sparse_array_layout.size >= layout->set_layout.size && + layout->value_offset >= prop->key_prop->elem_size && + (uint64_t)layout->value_offset + (uint64_t)prop->val_prop->elem_size <= (uint64_t)layout->set_layout.size; +} + +static bool +unreal_map_view_prop_is_valid(fprop_map_t *prop) +{ + return unreal_map_prop_is_valid(prop) && !(prop->map_flags & EMPF_USES_MEM_IMAGE_ALLOCATOR); +} + +int32_t +unreal_map_num(const void *map, fprop_map_t *prop) +{ + if (!map || !unreal_map_view_prop_is_valid(prop)) { + return -1; + } + return unreal_script_set_num(&((const fscript_map_t *)map)->pairs, &prop->map_layout.set_layout); +} + +int32_t +unreal_map_max_index(const void *map, fprop_map_t *prop) +{ + if (!map || !unreal_map_view_prop_is_valid(prop)) { + return -1; + } + return unreal_script_set_max_index(&((const fscript_map_t *)map)->pairs, &prop->map_layout.set_layout); +} + +bool +unreal_map_is_valid_index(const void *map, fprop_map_t *prop, int32_t idx) +{ + return unreal_map_view_prop_is_valid(prop) && map && + unreal_script_set_is_valid_index(&((const fscript_map_t *)map)->pairs, &prop->map_layout.set_layout, idx); +} + +const void * +unreal_map_get_key(const void *map, fprop_map_t *prop, int32_t idx) +{ + if (!unreal_map_view_prop_is_valid(prop) || !map) { + return NULL; + } + return unreal_script_set_get(&((fscript_map_t *)map)->pairs, &prop->map_layout.set_layout, idx); +} + +void * +unreal_map_get_value(void *map, fprop_map_t *prop, int32_t idx) +{ + uint8_t *key = (uint8_t *)unreal_map_get_key(map, prop, idx); + return key ? key + prop->map_layout.value_offset : NULL; +} + +int32_t +unreal_map_find_index(const void *map, fprop_map_t *prop, const void *key) +{ + int32_t max_idx = unreal_map_max_index(map, prop); + if (max_idx < 0 || !key) { + return TSET_INVALID_ID; + } + + for (int32_t idx = 0; idx < max_idx; ++idx) { + const void *candidate = unreal_map_get_key(map, prop, idx); + if (candidate && unreal_fprop_single_values_identical(prop->key_prop, candidate, key, 0)) { + return idx; + } + } + return TSET_INVALID_ID; +} + +void * +unreal_map_find_value_ptr(void *map, fprop_map_t *prop, const void *key) +{ + int32_t idx = unreal_map_find_index(map, prop, key); + return idx != TSET_INVALID_ID ? unreal_map_get_value(map, prop, idx) : NULL; +} + +bool +unreal_map_clear(void *map, fprop_map_t *prop) +{ + return map && unreal_map_prop_is_valid(prop) && unreal_fprop_clear_single_value(&prop->base, map); +} + +void +unreal_map_add(void *map, fprop_map_t *prop, const void *key, const void *val) +{ + if (!map || !prop || !prop->key_prop || !prop->val_prop || !key || !val || !fscript_map_add_pair) { + return; + } + + fscript_map_helper_t helper = { + .key_prop = prop->key_prop, + .val_prop = prop->val_prop, + .map = map, + .layout = prop->map_layout, + .flags = prop->map_flags, + }; + + fscript_map_add_ctx_t ctx = { + .helper = &helper, + .key = key, + .value = val, + .key_prop = prop->key_prop, + .val_prop = prop->val_prop, + }; + + fscript_map_add_pair(&helper, &ctx); +} + +bool +unreal_map_remove(void *map, fprop_map_t *prop, const void *key) +{ + if (!map || !prop || !prop->key_prop || !key || !fscript_map_remove_pair) { + return false; + } + + fscript_map_helper_t helper = { + .key_prop = prop->key_prop, + .val_prop = prop->val_prop, + .map = map, + .layout = prop->map_layout, + .flags = prop->map_flags, + }; + + fscript_map_remove_ctx_t ctx = { + .helper = &helper, + .key = key, + .key_prop = prop->key_prop, + }; + + return fscript_map_remove_pair(&helper, &ctx); +} + +bool +unreal_map_find(void *map, fprop_map_t *prop, const void *key, void *out_val) +{ + if (!map || !prop || !key || !generic_map_find) { + return false; + } + return generic_map_find(map, prop, key, out_val); +} From 91f7ccec5569b259f840179a3dcbc6f68ba5d6f5 Mon Sep 17 00:00:00 2001 From: akmubi Date: Fri, 28 Aug 2026 19:07:11 +0500 Subject: [PATCH 3/9] update .gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 17b2866..3a10559 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ .code *.vscode* *.kdev4* +*.code-workspace build tmp @@ -20,4 +21,3 @@ tmp tags cscope.out - From 489f3f212f6c6b743495341147932e17b364c5d4 Mon Sep 17 00:00:00 2001 From: akmubi Date: Sat, 29 Aug 2026 03:32:15 +0500 Subject: [PATCH 4/9] rewrite mod system --- Makefile | 13 +- docs/MOD_DEVELOPMENT.md | 147 +- include/arena.h | 36 +- include/file.h | 32 +- include/ini.h | 14 +- include/input.h | 70 +- include/mod.h | 155 + include/mod_host.h | 159 - include/mod_manager.h | 71 +- include/path.h | 30 +- include/scratch.h | 16 +- include/sigscan.h | 10 +- include/str.h | 163 +- include/types.h | 38 +- include/unreal.h | 193 +- include/unreal_prop.h | 150 +- include/vendor_nuklear.h | 4 + include/version.h | 21 +- mod/Makefile | 37 +- mod/main.c | 16 +- mod/mod.vcxproj | 17 +- mod/mod.vcxproj.filters | 25 +- mod/mod_api.h | 512 - mod/mod_nuklear.c | 30202 ------------------------ mod/mod_nuklear.h | 8001 ------- mod/mod_sdk.c | 2966 --- mod/mod_sdk.h | 1063 - mod/mod_unreal.c | 1395 -- mod/mod_unreal.h | 3115 --- overdub.vcxproj | 17 +- src/builtin/tweaks.c | 24 +- src/builtin/ufunction_call.c | 10 +- src/builtin/ufunction_tracer.c | 10 +- src/builtin/uobject_search.c | 24 +- src/builtin/uobject_search_internal.h | 2 +- src/mod_host.c | 627 +- src/mod_manager.c | 417 +- src/unreal.c | 56 + src/vendor.c | 1 + test/test_ui.c | 116 +- test/test_ui_signatures.c | 10 + 41 files changed, 1497 insertions(+), 48488 deletions(-) create mode 100644 include/mod.h delete mode 100644 include/mod_host.h delete mode 100644 mod/mod_api.h delete mode 100644 mod/mod_nuklear.c delete mode 100644 mod/mod_nuklear.h delete mode 100644 mod/mod_sdk.c delete mode 100644 mod/mod_sdk.h delete mode 100644 mod/mod_unreal.c delete mode 100644 mod/mod_unreal.h create mode 100644 test/test_ui_signatures.c diff --git a/Makefile b/Makefile index b2d0c76..c3263c7 100644 --- a/Makefile +++ b/Makefile @@ -59,6 +59,7 @@ SRCS_TEST_UI := \ src/builtin/ufunction_call.c \ src/builtin/ufunction_tracer.c \ src/builtin/tweaks.c \ + test/test_ui_signatures.c \ test/test_ui_overview.c \ test/test_ui_style_configurator.c @@ -76,15 +77,15 @@ all: debug debug: $(OBJS_DEBUG) | $(BUILD_DIR) @printf "LINK\t$(BUILD_DIR)/overdub.dll\n" - @$(CC) -o $(BUILD_DIR)/overdub.dll $(OBJS_DEBUG) $(LDFLAGS_COMMON) $(LDFLAGS_DEBUG) $(LIBS_DLL) + @$(CC) -o $(BUILD_DIR)/overdub.dll $(OBJS_DEBUG) $(LDFLAGS_COMMON) $(LDFLAGS_DEBUG) -Wl,--out-implib,$(BUILD_DIR)/overdub.lib $(LIBS_DLL) release: $(OBJS_RELEASE) | $(BUILD_DIR) @printf "LINK\t$(BUILD_DIR)/overdub.dll\n" - @$(CC) -o $(BUILD_DIR)/overdub.dll $(OBJS_RELEASE) $(LDFLAGS_COMMON) $(LDFLAGS_RELEASE) $(LIBS_DLL) + @$(CC) -o $(BUILD_DIR)/overdub.dll $(OBJS_RELEASE) $(LDFLAGS_COMMON) $(LDFLAGS_RELEASE) -Wl,--out-implib,$(BUILD_DIR)/overdub.lib $(LIBS_DLL) test_ui: test/test_ui.c $(OBJS_TEST_UI) | $(BUILD_DIR) @printf "LINK\t$(BUILD_DIR)/overdub_test_ui.exe\n" - @$(CC) $(CFLAGS_COMMON) -Wno-missing-braces -g3 -O0 -DBUILD_TEST_UI -o $(BUILD_DIR)/overdub_test_ui.exe test/test_ui.c $(OBJS_TEST_UI) $(LIBS_TEST_UI) + @$(CC) $(CFLAGS_COMMON) -Wno-missing-braces -g3 -O0 -DBUILD_TEST_UI -DOVERDUB_STATIC -o $(BUILD_DIR)/overdub_test_ui.exe test/test_ui.c $(OBJS_TEST_UI) $(LIBS_TEST_UI) @printf "RUN\t$(BUILD_DIR)/overdub_test_ui.exe\n" @wine $(BUILD_DIR)/overdub_test_ui.exe @@ -101,17 +102,17 @@ $(BUILD_DIR) $(OBJ_DIR_DEBUG) $(OBJ_DIR_RELEASE) $(OBJ_DIR_TEST) $(OBJ_DIR_TEST_ $(OBJ_DIR_DEBUG)/%.o: %.c @mkdir -p $(dir $@) @printf "CC\t$@\n" - @$(CC) $(CFLAGS_COMMON) $(CFLAGS_DEBUG) -DBUILD_DEBUG -MMD -MP -c $< -o $@ + @$(CC) $(CFLAGS_COMMON) $(CFLAGS_DEBUG) -DBUILD_DEBUG -DOVERDUB_BUILD_DLL -MMD -MP -c $< -o $@ $(OBJ_DIR_RELEASE)/%.o: %.c @mkdir -p $(dir $@) @printf "CC\t$@\n" - @$(CC) $(CFLAGS_COMMON) $(CFLAGS_RELEASE) -DBUILD_RELEASE -MMD -MP -c $< -o $@ + @$(CC) $(CFLAGS_COMMON) $(CFLAGS_RELEASE) -DBUILD_RELEASE -DOVERDUB_BUILD_DLL -MMD -MP -c $< -o $@ $(OBJ_DIR_TEST_UI)/%.o: %.c @mkdir -p $(dir $@) @printf "CC\t$@\n" - @$(CC) $(CFLAGS_COMMON) -g3 -O0 -DBUILD_TEST_UI -MMD -MP -c $< -o $@ + @$(CC) $(CFLAGS_COMMON) -g3 -O0 -DBUILD_TEST_UI -DOVERDUB_STATIC -MMD -MP -c $< -o $@ $(OBJ_DIR_TEST_LUA)/%.o: %.c @mkdir -p $(dir $@) diff --git a/docs/MOD_DEVELOPMENT.md b/docs/MOD_DEVELOPMENT.md index 77b1e44..c727419 100644 --- a/docs/MOD_DEVELOPMENT.md +++ b/docs/MOD_DEVELOPMENT.md @@ -3,7 +3,7 @@ This guide covers the parts of Unreal Engine and Overdub that are directly useful when making a mod for Hi-Fi RUSH. It assumes basic C/C++ knowledge. Hi-Fi RUSH uses a modified Unreal Engine 4.27 build. Public UE 4.27 source is useful for reference, but always verify addresses, layouts, and behavior against the game build you support. -The public SDK is in [`mod/`](../mod/). A mod should not depend on private loader structures in `src/` or `include/`. +The public SDK headers are in [`include/`](../include/). Include [`mod.h`](../include/mod.h) for the lifecycle ABI and mod-owned resources, and include the other public headers for shared utility, Unreal, and Nuklear APIs. Mods link against the small `build/overdub.lib` import library; the implementations live in `overdub.dll`. ## 1. Choose a Mod Type @@ -166,36 +166,35 @@ Output: mod/build//example.dll ``` -A separate project should compile the matching SDK files from `mod/`. +A mod project should use the matching public headers from `include/` and link `build/overdub.lib`. ## 4. Minimal Native Mod ```c -#include "mod_sdk.h" +#include "mod.h" static bool -example_init(const mod_host_api_t *host, mod_t mod) +example_init(mod_handle_t mod) { - if (!mod_sdk_init(host, mod)) { - return false; - } - - MOD_LOG_INFO("Example mod started"); + MOD_LOG_INFO(mod, "Example mod started"); return true; } static void -example_deinit(mod_t mod) +example_deinit(mod_handle_t mod) { - (void)mod; - MOD_LOG_INFO("Example mod stopped"); + MOD_LOG_INFO(mod, "Example mod stopped"); +} + +MOD_ABI_VERSION_ENTRY() +{ + return MOD_ABI_VERSION; } MOD_ENTRY() { static const mod_api_t api = { .struct_size = sizeof(mod_api_t), - .abi_version = MOD_ABI_VERSION, .init = example_init, .deinit = example_deinit, }; @@ -210,7 +209,6 @@ MOD_ENTRY() ```c struct mod_api_s { uint32_t struct_size; - mod_version_t abi_version; mod_init_fn_t init; mod_deinit_fn_t deinit; mod_tick_fn_t tick; @@ -224,15 +222,9 @@ struct mod_api_s { }; ``` -Always set `struct_size` and `abi_version`. Major and minor ABI versions must match the loader. Patch differences are ignored. A patch release may append optional host functions; SDK wrappers check `struct_size` before using them. +Always export `mod_abi_version()` and set `struct_size`. Major and minor ABI versions must match the loader; patch differences are ignored. `mod_entry()` remains focused on returning the callback table. -If a mod requires an optional capability rather than merely using it when available, reject the host explicitly during `init`. For example: -```c -if (!unreal_map_helpers_available()) { - MOD_LOG_ERROR("this mod requires reflected map helpers"); - return false; -} -``` +Before loading a mod, Overdub checks every symbol it imports from `overdub.dll`. If the mod was linked against a newer API, the error lists the exact missing function names. After loading, Overdub calls `mod_abi_version()` and rejects incompatible callback ABIs before resolving `mod_entry()`. ## 5. Lifecycle and Cleanup @@ -251,7 +243,7 @@ static int g_counter; Reset per-run state in `init`, and clear pointers in `deinit`. -After `deinit`, Overdub removes SDK-managed hooks, UObject listeners, commands, and mod arenas. +After `deinit`, Overdub removes manager-owned hooks, UObject listeners, commands, and mod arenas. The mod must clean up anything Overdub does not own, such as threads, OS handles, external allocations, hooks, patches , etc. @@ -274,7 +266,7 @@ Do not log every frame or every reflected call in normal use. ### Permanent arena ```c -mod_arena_t arena = mod_get_perm(); +mod_arena_handle_t arena = mod_get_perm(mod); ``` Use it for state that lives for one active run of the mod. It is destroyed after `deinit`. @@ -287,18 +279,14 @@ typedef struct { static state_t *g_state; static bool -example_init(const mod_host_api_t *host, mod_t mod) +example_init(mod_handle_t mod) { - if (!mod_sdk_init(host, mod)) { - return false; - } - - g_state = MOD_ARENA_PUSH_ZERO(mod_get_perm(), state_t); + g_state = MOD_ARENA_PUSH_ZERO(mod_get_perm(mod), state_t); return g_state != NULL; } static void -example_deinit(mod_t mod) +example_deinit(mod_handle_t mod) { (void)mod; g_state = NULL; @@ -308,7 +296,7 @@ example_deinit(mod_t mod) ### Dynamic arena ```c -mod_arena_t arena = mod_arena_create(64 * MB, 64 * KB); +mod_arena_handle_t arena = mod_arena_create(mod, 64 * MB, 64 * KB); ``` Use a dynamic arena when a subsystem needs its own reset or destroy point. @@ -316,7 +304,7 @@ Use a dynamic arena when a subsystem needs its own reset or destroy point. ### Scratch arena ```c -tmp_arena_t tmp = mod_scratch_begin(MOD_ARENA_INVALID); +mod_tmp_arena_t tmp = mod_scratch_begin(MOD_ARENA_HANDLE_INVALID); /* temporary allocations */ @@ -325,7 +313,7 @@ mod_scratch_end(tmp); Scratch pointers become invalid at `mod_scratch_end`. Never store them. -Treat `mod_t`, `mod_cfg_t`, and `mod_arena_t` as opaque handles. Do not cast them to pointers or depend on their representation. +Treat `mod_handle_t`, `mod_cfg_handle_t`, and `mod_arena_handle_t` as opaque handles. Do not cast them to pointers or depend on their representation. ## 8. Unreal Runtime Basics @@ -342,7 +330,7 @@ The outer chain is not an inheritance chain. Every actor is a UObject, but many UObjects are not actors. Classes, functions, assets, etc. are also UObjects. -A UObject contains a class, name, outer, flags, and an index in the global UObject array. Overdub exposes the current target layouts through `mod_unreal.h`. +A UObject contains a class, name, outer, flags, and an index in the global UObject array. Overdub exposes the current target layouts through `include/unreal.h`. ### Object lifetime @@ -371,12 +359,10 @@ Function /Script/Engine.Actor.K2_DestroyActor ## 9. Finding UObjects -Include the Unreal helpers and initialize their common cache: +Include the Unreal helpers. Overdub initializes the shared runtime state before starting mods: ```c -#include "mod_unreal.h" - -unreal_cache_objects(); +#include "unreal.h" ``` Find a class by full name: @@ -435,11 +421,11 @@ on_deleted(uobject_t *obj, int32_t idx, void *user) Register them during `init`: ```c -if (!mod_register_uobject_listener(UOBJECT_LISTENER_KIND_CREATE, on_created, NULL)) { +if (!mod_register_uobject_listener(mod, UOBJECT_LISTENER_KIND_CREATE, on_created, NULL)) { return false; } -if (!mod_register_uobject_listener(UOBJECT_LISTENER_KIND_DELETE, on_deleted, NULL)) { +if (!mod_register_uobject_listener(mod, UOBJECT_LISTENER_KIND_DELETE, on_deleted, NULL)) { return false; } ``` @@ -468,18 +454,18 @@ Start with plain numeric values, names, and object pointers. Use the SDK helpers Do not infer offsets from a C declaration. ```c -/* NOTE: error handling is omitted for briefty */ +/* NOTE: error handling is omitted for brevity */ static bool call_set_count(uobject_t *obj, int32_t value) { if (!obj || !unreal_uobject_is_valid(obj)) { - return; + return false; } ufunc_t *func = unreal_ustruct_find_func((ustruct_t *)obj->cls, STR_LIT("SetCount")); fprop_t *count_prop = unreal_ustruct_find_prop((ustruct_t *)func, STR_LIT("Count")); - tmp_arena_t tmp = mod_scratch_begin(MOD_ARENA_INVALID); + mod_tmp_arena_t tmp = mod_scratch_begin(MOD_ARENA_HANDLE_INVALID); { uint8_t *params = MOD_ARENA_PUSH_ARRAY_ZERO(tmp.arena, uint8_t, func->params_size); int32_t *count = (int32_t *)unreal_uprop_ptr(count_prop, params); @@ -500,8 +486,8 @@ This example is only valid when `Count` is really a plain `int32_t`. Complex inp A mod can observe or replace game-thread reflected calls: ```c -bool pe_pre(mod_t mod, uobject_t *obj, ufunc_t *func, void *params); -void pe_post(mod_t mod, uobject_t *obj, ufunc_t *func, void *params, bool consumed); +bool pe_pre(mod_handle_t mod, uobject_t *obj, ufunc_t *func, void *params); +void pe_post(mod_handle_t mod, uobject_t *obj, ufunc_t *func, void *params, bool consumed); ``` Returning `true` from `pe_pre` consumes the call and skips the original `ProcessEvent`. Use this carefully. The original may produce return values, update state, run Blueprint logic, etc. @@ -519,17 +505,13 @@ Never keep the `params` pointer after the callback. Get handles during `init`: ```c -static mod_cfg_t g_enabled_cfg; +static mod_cfg_handle_t g_enabled_cfg; static bool -example_init(const mod_host_api_t *host, mod_t mod) +example_init(mod_handle_t mod) { - if (!mod_sdk_init(host, mod)) { - return false; - } - - g_enabled_cfg = mod_get_cfg_by_id(STR_LIT("feature_enabled")); - return g_enabled_cfg != MOD_CFG_INVALID; + g_enabled_cfg = mod_get_cfg_by_id(mod, STR_LIT("feature_enabled")); + return g_enabled_cfg != MOD_CFG_HANDLE_INVALID; } ``` @@ -549,14 +531,14 @@ Direct input callback: ```c static bool -example_input(mod_t mod, input_event_t *event) +example_input(mod_handle_t mod, input_event_t *event) { (void)mod; if (event->kind == INPUT_EVENT_KEY_DOWN && event->key == INPUT_KEY_F8 && !event->is_repeat) { - MOD_LOG_INFO("F8 pressed"); + MOD_LOG_INFO(mod, "F8 pressed"); return true; } @@ -570,7 +552,7 @@ For a configured keybind, polling from `tick` is often simpler: ```c keybind_t bind = mod_cfg_get_keybind(g_action_key_cfg); -if (mod_keybind_is_pressed(bind)) { +if (keybind_is_pressed(bind)) { /* run once */ } ``` @@ -583,19 +565,18 @@ Register commands during `init`: ```c static void -example_command(mod_t mod, str_t name, str_t args, void *user) +example_command(mod_handle_t mod, str_t name, str_t args, void *user) { - (void)mod; (void)name; (void)user; - MOD_LOG_INFO("args: " STR_FMT, STR_ARG(args)); + MOD_LOG_INFO(mod, "args: " STR_FMT, STR_ARG(args)); } static bool -register_commands(void) +register_commands(mod_handle_t mod) { - return mod_register_cmd(STR_LIT("example.run"), STR_LIT("Runs the example command"), example_command, NULL); + return mod_register_cmd(mod, STR_LIT("example.run"), STR_LIT("Runs the example command"), example_command, NULL); } ``` @@ -603,15 +584,15 @@ Prefix command names to avoid collisions with other mods. ## 17. Custom UI -Include the matching Overdub Nuklear wrapper: +Include Overdub's public Nuklear header: ```c -#include "mod_nuklear.h" +#include "vendor_nuklear.h" ``` ```c static void -example_draw_panel(mod_t mod, struct nk_context *ctx) +example_draw_panel(mod_handle_t mod, struct nk_context *ctx) { (void)mod; @@ -624,7 +605,7 @@ example_draw_panel(mod_t mod, struct nk_context *ctx) } ``` -Overdub uses a modified Nuklear version. Compile against the SDK shipped with the target Overdub version. +Overdub uses a modified Nuklear version. Compile against the public headers shipped with the target Overdub version and call the implementation exported by `overdub.dll`. Nuklear is immediate mode. Rebuild controls every frame, keep persistent UI state in the mod, and never store the context pointer. Do not block or issue D3D12 rendering directly from mod UI callbacks. @@ -662,7 +643,7 @@ Resolve and install it: ```c static bool -install_target_hook(void) +install_target_hook(mod_handle_t mod) { void *target = NULL; @@ -670,19 +651,20 @@ install_target_hook(void) .name = "target", .pattern = "48 89 5C 24 ?? 57 48 83 EC ??", .pp = &target, + .kind = SIG_DIRECT, .op_off = 0, .deref = 0, }; - if (mod_sigscan(&entry) != SIGSCAN_ERR_OK || !target) { + if (mod_sigscan(&entry) != SIG_ERR_OK || !target) { return false; } - if (!mod_hook_create(target, target_hook, (void **)&g_target_real)) { + if (!mod_hook_create(mod, target, target_hook, (void **)&g_target_real)) { return false; } - return mod_hook_enable(target); + return mod_hook_enable(mod, target); } ``` @@ -690,11 +672,11 @@ The pattern above is only an example. A detour must match the real ABI, parameters, return type, and calling thread. It must also handle recursion and shutdown correctly. Call the original when the caller depends on its side effects or return value. -Overdub snapshots the main executable's unpacked executable sections before loading mods, so SDK signature scans are stable if another SDK or direct MinHook detour later changes live code. Scan results are translated by RVA and always point into the live module. +Overdub snapshots the main executable's unpacked executable sections before loading mods, so signature scans are stable if another mod or direct MinHook detour later changes live code. Scan results are translated by RVA and always point into the live module. -SDK hooks on the same target form a chain. The most recently enabled hook runs first, and the `original` pointer returned to each mod is a stable next-call thunk. Disabling or removing a hook rewires the chain without changing another mod's stored pointer. Hooks installed directly with MinHook do not join this chain and can still conflict with it. +Managed hooks on the same target form a chain. The most recently enabled hook runs first, and the `original` pointer returned to each mod is a stable next-call thunk. Disabling or removing a hook rewires the chain without changing another mod's stored pointer. Hooks installed directly with MinHook do not join this chain and can still conflict with it. -Hooks created through the SDK are removed after `deinit`. Manual hooks and patches are the mod's responsibility. +Hooks created through the mod API are removed after `deinit`. Manual hooks and patches are the mod's responsibility. ## 19. Assets and Blueprint Actors @@ -726,10 +708,10 @@ Common asset problems include the wrong cooked target, an incorrect package or g ### Logging ```c -MOD_LOG_DEBUG("value: %d", value); -MOD_LOG_INFO("mod started"); -MOD_LOG_WARN("object not found"); -MOD_LOG_ERROR("failed to install hook"); +MOD_LOG_DEBUG(mod, "value: %d", value); +MOD_LOG_INFO(mod, "mod started"); +MOD_LOG_WARN(mod, "object not found"); +MOD_LOG_ERROR(mod, "failed to install hook"); ``` Log initialization stages and failures with enough context to reproduce them. Avoid hot-path spam. @@ -805,7 +787,6 @@ When reporting a crash, keep: ## 21. Reload-Safe Checklist ### `init` - reset per-run globals -- call `mod_sdk_init` - acquire required config handles - allocate state - resolve required classes and functions @@ -841,10 +822,10 @@ When this guide and the implementation disagree, check the code. | Loader entry and main callbacks | `src/main.c` | | Signatures and core engine hooks | `src/signatures.c` | | Manifest parser and lifecycle | `src/mod_manager.c` | -| Host API | `src/mod_host.c`, `include/mod_host.h` | -| Public mod ABI | `mod/mod_api.h` | -| SDK wrappers | `mod/mod_sdk.h`, `mod/mod_sdk.c` | -| Unreal helpers | `mod/mod_unreal.h`, `mod/mod_unreal.c` | -| Nuklear helpers | `mod/mod_nuklear.h`, `mod/mod_nuklear.c` | +| Exported mod operations | `src/mod_host.c`, `include/mod.h` | +| Public mod ABI | `include/mod.h` | +| Shared utility APIs | `include/`, `src/` | +| Unreal helpers | `include/unreal.h`, `src/unreal.c` | +| Nuklear API | `include/vendor_nuklear.h`, `vendor/` | | D3D12 overlay | `src/nk_d3d12.c` | | Built-in tool examples | `src/builtin/` | diff --git a/include/arena.h b/include/arena.h index d2bc08a..65fb805 100644 --- a/include/arena.h +++ b/include/arena.h @@ -3,6 +3,8 @@ #include "types.h" +MOD_EXTERN_C_BEGIN + #define ARENA_PUSH_ARRAY(ARENA, T, N) (T *)arena_push_aligned((ARENA), (N) * sizeof(T), ALIGNOF(T)) #define ARENA_PUSH_ARRAY_ZERO(ARENA, T, N) (T *)arena_push_zero_aligned((ARENA), (N) * sizeof(T), ALIGNOF(T)) #define ARENA_PUSH(ARENA, T) ARENA_PUSH_ARRAY(ARENA, T, 1) @@ -25,33 +27,33 @@ struct arena_s { uint64_t reserve_size; }; -arena_t +MOD_API arena_t arena_new_static(void *buf, uint64_t size); -arena_t +MOD_API arena_t arena_new_dynamic(uint64_t reserve_size, uint64_t commit_size); -uint64_t +MOD_API uint64_t arena_get_used(arena_t *arena); -uint64_t +MOD_API uint64_t arena_get_reserved(arena_t *arena); -uint64_t +MOD_API uint64_t arena_get_committed(arena_t *arena); -void +MOD_API void arena_set_used(arena_t *arena, uint64_t new_used); -void +MOD_API void arena_reset(arena_t *arena); -void +MOD_API void arena_destroy(arena_t *arena); -void * +MOD_API void * arena_push_aligned(arena_t *a, uint64_t size, uint64_t alignment); -void * +MOD_API void * arena_push_zero_aligned(arena_t *a, uint64_t size, uint64_t alignment); -void +MOD_API void arena_pop_to(arena_t *a, uint64_t new_used); -void +MOD_API void arena_pop(arena_t *a, uint64_t size); typedef struct tmp_arena_s tmp_arena_t; @@ -63,10 +65,10 @@ struct tmp_arena_s { static inline tmp_arena_t tmp_arena_begin(arena_t *a) { - return (tmp_arena_t){ - .arena = a, - .pos = arena_get_used(a), - }; + tmp_arena_t tmp = {0}; + tmp.arena = a; + tmp.pos = arena_get_used(a); + return tmp; } static inline void @@ -75,4 +77,6 @@ tmp_arena_end(tmp_arena_t tmp) arena_set_used(tmp.arena, tmp.pos); } +MOD_EXTERN_C_END + #endif /* ARENA_H */ diff --git a/include/file.h b/include/file.h index 09259a7..26dd241 100644 --- a/include/file.h +++ b/include/file.h @@ -4,6 +4,8 @@ #include "types.h" #include "str.h" +MOD_EXTERN_C_BEGIN + typedef uint8_t dir_entry_kind_t; enum { DIR_ENTRY_FILE, @@ -24,47 +26,49 @@ struct dir_entry_list_s { int count; }; -bool +MOD_API bool file_exists(str_t path); -uint64_t +MOD_API uint64_t file_size(str_t path); -str_t +MOD_API str_t file_read_all(str_t path, arena_t *arena); -bool +MOD_API bool file_write(str_t s, str_t path); -bool +MOD_API bool file_write_lines(str_list_t lines, str_t path); -bool +MOD_API bool file_copy(str_t dst, str_t src); -bool +MOD_API bool file_delete(str_t path); -bool +MOD_API bool dir_exists(str_t path); /* create a directory (does nothing if it already exists) */ -bool +MOD_API bool dir_create(str_t path); /* create a directory and all parent directories */ -bool +MOD_API bool dir_create_recursive(str_t path); /* list the contents of a directory (excludes "." and "..") */ -dir_entry_list_t +MOD_API dir_entry_list_t dir_list(str_t path, arena_t *arena); /* list contents matching a wildcard pattern (e.g. "*.dll") */ -dir_entry_list_t +MOD_API dir_entry_list_t dir_list_filter(str_t path, str_t pattern, arena_t *arena); /* delete a directory (must be empty) */ -bool +MOD_API bool dir_delete(str_t path); /* delete a directory and all its contents recursively */ -bool +MOD_API bool dir_delete_recursive(str_t path); +MOD_EXTERN_C_END + #endif /* FILE_H */ diff --git a/include/ini.h b/include/ini.h index d8ec650..d614b7f 100644 --- a/include/ini.h +++ b/include/ini.h @@ -4,6 +4,8 @@ #include "str.h" #include "arena.h" +MOD_EXTERN_C_BEGIN + typedef struct ini_section_s ini_section_t; struct ini_section_s { ini_section_t *next; @@ -19,17 +21,19 @@ struct ini_section_list_s { int count; }; -bool +MOD_API bool ini_is_line_section(str_t line); -bool +MOD_API bool ini_parse_section_header(str_t line, str_t *out_name, str_t *out_arg); -ini_section_list_t +MOD_API ini_section_list_t ini_parse_sections(arena_t *arena, str_array_t lines); -bool +MOD_API bool ini_parse_kv(str_t line, str_t *out_key, str_t *out_value); -str_array_t +MOD_API str_array_t ini_split_lines(arena_t *arena, str_t text); +MOD_EXTERN_C_END + #endif /* INI_H */ diff --git a/include/input.h b/include/input.h index 6a3f9c5..3bbb693 100644 --- a/include/input.h +++ b/include/input.h @@ -6,6 +6,8 @@ #include "types.h" #include "unreal.h" +MOD_EXTERN_C_BEGIN + typedef uint8_t input_event_kind_t; enum { INPUT_EVENT_KEY_DOWN, @@ -222,7 +224,11 @@ struct input_key_state_s { }; #define KEYBIND_MAX_KEYS (10) -#define KEYBIND_NULL (keybind_t){.keys = {0}, .count = 0} +#ifdef __cplusplus +# define KEYBIND_NULL keybind_t{} +#else +# define KEYBIND_NULL (keybind_t){.keys = {0}, .count = 0} +#endif typedef struct keybind_s keybind_t; struct keybind_s { @@ -230,72 +236,72 @@ struct keybind_s { uint8_t count; }; -void +MOD_API void input_key_map_init(void); -input_key_kind_t +MOD_API input_key_kind_t input_key_from_fname(fname_t key_name); -input_key_kind_t +MOD_API input_key_kind_t input_key_from_str(str_t name); -bool +MOD_API bool input_key_is_down(input_key_kind_t key); -bool +MOD_API bool input_key_is_pressed(input_key_kind_t key); -bool +MOD_API bool input_key_is_released(input_key_kind_t key); -bool +MOD_API bool input_key_is_bindable(input_key_kind_t key); -void +MOD_API void input_key_lost_focus(void); -void +MOD_API void input_key_clear_transient_state(void); -str_t +MOD_API str_t input_key_to_str(input_key_kind_t key); -str_t +MOD_API str_t input_event_kind_to_str(input_event_kind_t kind); -input_event_t +MOD_API input_event_t input_event_from_key_event(input_event_kind_t kind, fkey_event_t *e); -input_event_t +MOD_API input_event_t input_event_from_character_event(fcharacter_event_t *e); -input_event_t +MOD_API input_event_t input_event_from_pointer_event(input_event_kind_t kind, fpointer_event_t *e); -input_event_t +MOD_API input_event_t input_event_from_analog_event(fanalog_input_event_t *e); -input_event_t +MOD_API input_event_t input_event_from_app_activation_event(bool app_activated); -bool +MOD_API bool input_event_is_mouse(input_event_t *ev); -bool +MOD_API bool input_event_is_keyboard(input_event_t *ev); -bool +MOD_API bool input_event_is_gamepad(input_event_t *ev); -keybind_t +MOD_API keybind_t keybind_parse(str_t str, keybind_t default_val); -uint64_t +MOD_API uint64_t keybind_utf8_len(keybind_t bind); -uint64_t +MOD_API uint64_t keybind_utf8_write(keybind_t bind, void *buf, uint64_t cap); -str_t +MOD_API str_t keybind_to_str(keybind_t bind, arena_t *arena); -bool +MOD_API bool keybind_is_valid(keybind_t bind); -bool +MOD_API bool keybind_equal(keybind_t a, keybind_t b); -void +MOD_API void keybind_clear(keybind_t *bind); /* NOTE: used in engine tick */ -bool +MOD_API bool keybind_is_down(keybind_t bind); -bool +MOD_API bool keybind_is_pressed(keybind_t bind); -bool +MOD_API bool keybind_is_released(keybind_t bind); static inline bool @@ -317,7 +323,9 @@ keybind_str_is_released(str_t keybind_str) } /* NOTE: used for input events */ -bool +MOD_API bool keybind_activated_by_event(keybind_t bind, input_event_t *ev); +MOD_EXTERN_C_END + #endif /* INPUT_H */ diff --git a/include/mod.h b/include/mod.h new file mode 100644 index 0000000..cd9d6ba --- /dev/null +++ b/include/mod.h @@ -0,0 +1,155 @@ +#ifndef MOD_H +#define MOD_H + +#include "input.h" +#include "log.h" +#include "sigscan.h" +#include "str.h" +#include "types.h" +#include "unreal.h" +#include "version.h" + +MOD_EXTERN_C_BEGIN + +typedef uint64_t mod_handle_t; +typedef uint64_t mod_cfg_handle_t; +typedef uint64_t mod_arena_handle_t; +typedef version_t mod_version_t; + +#define MOD_HANDLE_INVALID ((mod_handle_t)0) +#define MOD_CFG_HANDLE_INVALID ((mod_cfg_handle_t)0) +#define MOD_ARENA_HANDLE_INVALID ((mod_arena_handle_t)0) + +#define MOD_ABI_VERSION ((mod_version_t)MAKE_VERSION(2, 0, 0)) + +#define MOD_ABI_VERSION_EXPORT "mod_abi_version" +#define MOD_ENTRY_EXPORT "mod_entry" + +#define MOD_ABI_VERSION_ENTRY() MOD_EXTERN_C MOD_EXPORT mod_version_t MOD_CALL mod_abi_version(void) +#define MOD_ENTRY() MOD_EXTERN_C MOD_EXPORT const mod_api_t *MOD_CALL mod_entry(void) + +#define MOD_LOG_ERROR(MOD, ...) mod_log((MOD), LOG_LEVEL_ERROR, __VA_ARGS__) +#define MOD_LOG_WARN(MOD, ...) mod_log((MOD), LOG_LEVEL_WARN, __VA_ARGS__) +#define MOD_LOG_INFO(MOD, ...) mod_log((MOD), LOG_LEVEL_INFO, __VA_ARGS__) +#define MOD_LOG_DEBUG(MOD, ...) mod_log((MOD), LOG_LEVEL_DEBUG, __VA_ARGS__) + +#define MOD_ARENA_PUSH_ARRAY(ARENA, T, N) (T *)mod_arena_push((ARENA), (N) * sizeof(T), ALIGNOF(T)) +#define MOD_ARENA_PUSH_ARRAY_ZERO(ARENA, T, N) (T *)mod_arena_push_zero((ARENA), (N) * sizeof(T), ALIGNOF(T)) +#define MOD_ARENA_PUSH(ARENA, T) MOD_ARENA_PUSH_ARRAY((ARENA), T, 1) +#define MOD_ARENA_PUSH_ZERO(ARENA, T) MOD_ARENA_PUSH_ARRAY_ZERO((ARENA), T, 1) + +typedef struct mod_color_s mod_color_t; +struct mod_color_s { + uint8_t r, g, b, a; +}; + +typedef struct mod_tmp_arena_s mod_tmp_arena_t; +struct mod_tmp_arena_s { + mod_arena_handle_t arena; + uint64_t pos; +}; + +struct nk_context; + +typedef void (MOD_CALL *mod_tick_fn_t) (mod_handle_t mod, float delta); +typedef bool (MOD_CALL *mod_input_fn_t)(mod_handle_t mod, input_event_t *ev); + +typedef bool (MOD_CALL *mod_pe_pre_fn_t) (mod_handle_t mod, uobject_t *obj, ufunc_t *func, void *params); +typedef void (MOD_CALL *mod_pe_post_fn_t)(mod_handle_t mod, uobject_t *obj, ufunc_t *func, void *params, bool consumed); + +typedef bool (MOD_CALL *mod_func_invoke_pre_fn_t) (mod_handle_t mod, ufunc_t *func, uobject_t *obj, fframe_t *stack, void *result); +typedef void (MOD_CALL *mod_func_invoke_post_fn_t)(mod_handle_t mod, ufunc_t *func, uobject_t *obj, fframe_t *stack, void *result, bool consumed); + +typedef void (MOD_CALL *mod_draw_panel_fn_t) (mod_handle_t mod, struct nk_context *ctx); +typedef void (MOD_CALL *mod_draw_config_fn_t)(mod_handle_t mod, struct nk_context *ctx); + +typedef bool (MOD_CALL *mod_init_fn_t) (mod_handle_t mod); +typedef void (MOD_CALL *mod_deinit_fn_t)(mod_handle_t mod); +typedef void (MOD_CALL *mod_cmd_fn_t) (mod_handle_t mod, str_t name, str_t args, void *user); + +typedef struct mod_api_s mod_api_t; +struct mod_api_s { + uint32_t struct_size; + mod_init_fn_t init; + mod_deinit_fn_t deinit; + mod_tick_fn_t tick; + mod_input_fn_t input; + mod_pe_pre_fn_t pe_pre; + mod_pe_post_fn_t pe_post; + mod_func_invoke_pre_fn_t func_invoke_pre; + mod_func_invoke_post_fn_t func_invoke_post; + mod_draw_panel_fn_t draw_panel; + mod_draw_config_fn_t draw_config; +}; + +typedef mod_version_t (MOD_CALL *mod_abi_version_fn_t)(void); +typedef const mod_api_t *(MOD_CALL *mod_entry_fn_t)(void); + +/* Mod identity and mod-owned registrations */ +MOD_API str_t mod_get_mod_dir(mod_handle_t mod); +MOD_API str_t mod_get_config_path(mod_handle_t mod); +MOD_API str_t mod_get_manifest_path(mod_handle_t mod); +MOD_API void mod_log(mod_handle_t mod, log_level_t level, const char *fmt, ...) ATTR_FORMAT(3, 4); +MOD_API void mod_logv(mod_handle_t mod, log_level_t level, const char *fmt, va_list args); +MOD_API mod_cfg_handle_t mod_get_cfg_by_id(mod_handle_t mod, str_t id); +MOD_API bool mod_register_cmd(mod_handle_t mod, str_t name, str_t description, mod_cmd_fn_t fn, void *user); + +/* UI and timing */ +MOD_API struct nk_context *mod_get_nk_ctx(void); +MOD_API void mod_get_viewport_size(unsigned int *width, unsigned int *height); +MOD_API uint64_t mod_get_frame_counter(void); +MOD_API float mod_get_fps(void); + +/* Manifest-backed configuration */ +MOD_API bool mod_cfg_get_bool(mod_cfg_handle_t cfg); +MOD_API int mod_cfg_get_int(mod_cfg_handle_t cfg); +MOD_API float mod_cfg_get_float(mod_cfg_handle_t cfg); +MOD_API int mod_cfg_get_enum(mod_cfg_handle_t cfg); +MOD_API uint64_t mod_cfg_get_string_len(mod_cfg_handle_t cfg); +MOD_API uint64_t mod_cfg_get_string_data(mod_cfg_handle_t cfg, void *buf, uint64_t cap); +MOD_API str_t mod_cfg_push_string(mod_cfg_handle_t cfg, mod_arena_handle_t arena); +MOD_API keybind_t mod_cfg_get_keybind(mod_cfg_handle_t cfg); +MOD_API mod_color_t mod_cfg_get_color(mod_cfg_handle_t cfg); +MOD_API void mod_cfg_set_bool(mod_cfg_handle_t cfg, bool value); +MOD_API void mod_cfg_set_int(mod_cfg_handle_t cfg, int value); +MOD_API void mod_cfg_set_float(mod_cfg_handle_t cfg, float value); +MOD_API void mod_cfg_set_enum(mod_cfg_handle_t cfg, int value); +MOD_API void mod_cfg_set_string(mod_cfg_handle_t cfg, str_t value); +MOD_API void mod_cfg_set_keybind(mod_cfg_handle_t cfg, keybind_t value); +MOD_API void mod_cfg_set_color(mod_cfg_handle_t cfg, mod_color_t value); + +/* Manager-owned arenas */ +MOD_API mod_arena_handle_t mod_get_perm(mod_handle_t mod); +MOD_API mod_arena_handle_t mod_arena_create(mod_handle_t mod, uint64_t reserve_size, uint64_t commit_size); +MOD_API void mod_arena_destroy(mod_handle_t mod, mod_arena_handle_t arena); +MOD_API void *mod_arena_push(mod_arena_handle_t arena, uint64_t size, uint64_t alignment); +MOD_API void *mod_arena_push_zero(mod_arena_handle_t arena, uint64_t size, uint64_t alignment); +MOD_API uint64_t mod_arena_pos(mod_arena_handle_t arena); +MOD_API void mod_arena_reset(mod_arena_handle_t arena); +MOD_API void mod_arena_pop_to(mod_arena_handle_t arena, uint64_t pos); +MOD_API void mod_arena_pop(mod_arena_handle_t arena, uint64_t size); +MOD_API mod_tmp_arena_t mod_scratch_begin(mod_arena_handle_t conflict); +MOD_API void mod_scratch_end(mod_tmp_arena_t tmp); + +/* Manager-owned engine listeners and native hooks */ +MOD_API bool mod_register_uobject_listener(mod_handle_t mod, uobject_listener_kind_t kind, uobject_on_notify_cb_t callback, void *user); +MOD_API void mod_deregister_uobject_listener(mod_handle_t mod, uobject_listener_kind_t kind, uobject_on_notify_cb_t callback, void *user); +MOD_API sigscan_err_t mod_sigscan(sigscan_entry_t *entry); +MOD_API bool mod_hook_create(mod_handle_t mod, void *target, void *detour, void **original); +MOD_API bool mod_hook_enable(mod_handle_t mod, void *target); +MOD_API bool mod_hook_disable(mod_handle_t mod, void *target); +MOD_API bool mod_hook_remove(mod_handle_t mod, void *target); + +/* Exported by each mod DLL */ +MOD_EXTERN_C MOD_EXPORT mod_version_t MOD_CALL mod_abi_version(void); +MOD_EXTERN_C MOD_EXPORT const mod_api_t *MOD_CALL mod_entry(void); + +static inline bool +mod_abi_compatible(mod_version_t host, mod_version_t mod) +{ + return host.major == mod.major && host.minor == mod.minor; +} + +MOD_EXTERN_C_END + +#endif /* MOD_H */ diff --git a/include/mod_host.h b/include/mod_host.h deleted file mode 100644 index a66f721..0000000 --- a/include/mod_host.h +++ /dev/null @@ -1,159 +0,0 @@ -#ifndef MOD_HOST_H -#define MOD_HOST_H - -#include "arena.h" -#include "log.h" -#include "str.h" -#include "types.h" - -#include "sigscan.h" -#include "unreal.h" - -#include "mod_manager.h" - -#define MOD_HOST_ABI_VERSION MAKE_VERSION(1, 1, 0) - -typedef struct host_tmp_arena_s host_tmp_arena_t; -struct host_tmp_arena_s { - mod_arena_handle_t arena; - uint64_t pos; -}; - -typedef struct mod_host_api_s mod_host_api_t; -struct mod_host_api_s { - uint32_t struct_size; - version_t abi_version; - - /* MOD */ - - str_t (MOD_CALL *get_mod_dir) (mod_handle_t h); - str_t (MOD_CALL *get_config_path) (mod_handle_t h); - str_t (MOD_CALL *get_manifest_path) (mod_handle_t h); - void (MOD_CALL *logv) (mod_handle_t h, log_level_t level, const char *fmt, va_list args); - mod_cfg_handle_t (MOD_CALL *get_cfg_by_id) (mod_handle_t h, str_t id); - bool (MOD_CALL *register_cmd) (mod_handle_t h, str_t name, str_t description, mod_cmd_fn_t fn, void *user); - - /* UI */ - struct nk_context *(MOD_CALL *get_nk_ctx) (void); - void (MOD_CALL *get_viewport_size)(unsigned int *vw, unsigned int *vh); - - /* MOD CONFIGURATION */ - - void (MOD_CALL *cfg_get_bool) (mod_cfg_handle_t h, bool *val); - void (MOD_CALL *cfg_get_int) (mod_cfg_handle_t h, int *val); - void (MOD_CALL *cfg_get_float) (mod_cfg_handle_t h, float *val); - void (MOD_CALL *cfg_get_enum) (mod_cfg_handle_t h, int *val); - void (MOD_CALL *cfg_get_string_len) (mod_cfg_handle_t h, uint64_t *len); - void (MOD_CALL *cfg_get_string_data)(mod_cfg_handle_t h, void *buf, uint64_t cap, uint64_t *written); - void (MOD_CALL *cfg_get_keybind) (mod_cfg_handle_t h, keybind_t *val); - void (MOD_CALL *cfg_get_color) (mod_cfg_handle_t h, mod_color_t *val); - void (MOD_CALL *cfg_set_bool) (mod_cfg_handle_t h, bool val); - void (MOD_CALL *cfg_set_int) (mod_cfg_handle_t h, int val); - void (MOD_CALL *cfg_set_float) (mod_cfg_handle_t h, float val); - void (MOD_CALL *cfg_set_enum) (mod_cfg_handle_t h, int val); - void (MOD_CALL *cfg_set_string) (mod_cfg_handle_t h, str_t val); - void (MOD_CALL *cfg_set_keybind) (mod_cfg_handle_t h, keybind_t val); - void (MOD_CALL *cfg_set_color) (mod_cfg_handle_t h, mod_color_t val); - - /* MEMORY ALLOCATION */ - - mod_arena_handle_t (MOD_CALL *get_perm) (mod_handle_t h); - mod_arena_handle_t (MOD_CALL *arena_create) (mod_handle_t h, uint64_t reserve_size, uint64_t commit_size); - void (MOD_CALL *arena_destroy)(mod_handle_t h, mod_arena_handle_t arena_h); - void *(MOD_CALL *arena_push) (mod_arena_handle_t h, uint64_t size, uint64_t alignment); - uint64_t (MOD_CALL *arena_pos) (mod_arena_handle_t h); - void (MOD_CALL *arena_pop_to) (mod_arena_handle_t h, uint64_t pos); - void (MOD_CALL *arena_reset) (mod_arena_handle_t h); - host_tmp_arena_t (MOD_CALL *scratch_begin)(mod_arena_handle_t conflict); - void (MOD_CALL *scratch_end) (host_tmp_arena_t s); - - /* UNREAL ENGINE */ - - fname_pool_t *(MOD_CALL *get_name_pool) (void); - fuobject_array_t *(MOD_CALL *get_object_array) (void); - uworld_t **(MOD_CALL *get_gworld_ptr) (void); - void (MOD_CALL *process_event) (uobject_t *self, ufunc_t *func, void *params); - uclass_t *(MOD_CALL *static_load_class) (uclass_t *base_cls, uobject_t *outer, str_t name, str_t filename, uint32_t load_flags); - bool (MOD_CALL *mount_pak) (str_t file_path, int order); - bool (MOD_CALL *mount_iostore) (str_t file_path, int order); - fname_t (MOD_CALL *fname_from_str) (str_t str, efind_name_t find_type); - uint64_t (MOD_CALL *fname_utf8_len) (fname_t fname); - uint64_t (MOD_CALL *fname_utf8_write) (fname_t fname, void *buf, uint64_t cap); - void *(MOD_CALL *get_mcast_sparse_delegate)(uobject_t *delegate_owner, fname_t delegate_name); - fnative_func_ptr_t (MOD_CALL *get_native) (uint8_t opcode); - - /* INPUT EVENTS / KEYBINDS */ - - input_key_kind_t (MOD_CALL *input_key_from_str) (str_t name); - str_t (MOD_CALL *input_key_to_str) (input_key_kind_t key); - str_t (MOD_CALL *input_event_kind_to_str)(input_event_kind_t kind); - bool (MOD_CALL *keybind_parse) (str_t str, keybind_t *out); - uint64_t (MOD_CALL *keybind_utf8_len) (keybind_t bind); - uint64_t (MOD_CALL *keybind_utf8_write) (keybind_t bind, void *buf, uint64_t cap); - bool (MOD_CALL *keybind_is_down) (keybind_t bind); - bool (MOD_CALL *keybind_is_pressed) (keybind_t bind); - bool (MOD_CALL *keybind_is_released) (keybind_t bind); - - /* UOBJECT CREATE/DELETE LISTENERS */ - - bool (MOD_CALL *register_uobject_listener) (mod_handle_t h, uobject_listener_kind_t kind, uobject_on_notify_cb_t notify_cb, void *user); - void (MOD_CALL *deregister_uobject_listener)(mod_handle_t h, uobject_listener_kind_t kind, uobject_on_notify_cb_t notify_cb, void *user); - - - /* HOOKING / SIGNATURE SCANNING */ - - sigscan_err_t (MOD_CALL *sigscan) (const char *name, const char *pattern, uint8_t op_offset, uint8_t num_deref, uintptr_t first_rvas_to_try[8], void **result); - bool (MOD_CALL *hook_create) (mod_handle_t h, void *target, void *detour, void **original); - bool (MOD_CALL *hook_enable) (mod_handle_t h, void *target); - bool (MOD_CALL *hook_disable)(mod_handle_t h, void *target); - bool (MOD_CALL *hook_remove) (mod_handle_t h, void *target); - - /* UNREAL ENGINE (CONT.) */ - void (MOD_CALL *map_add) (void *map, void *prop, const void *key, const void *val); - bool (MOD_CALL *map_remove) (void *map, void *prop, const void *key); - bool (MOD_CALL *map_find) (void *map, void *prop, const void *key, void *out_val); - uobject_t *(MOD_CALL *static_load_object) (uclass_t *obj_cls, uobject_t *outer, str_t name, str_t filename, uint32_t load_flags, void *sandbox, bool allow_obj_reconcile, void *instancing_ctx); - uobject_t *(MOD_CALL *static_construct_object) (void *params); - bool (MOD_CALL *add_gameplay_tag) (fname_t tag_name); - bool (MOD_CALL *check_gameplay_tag_exists)(fname_t tag_name); - - uint64_t (MOD_CALL *get_frame_counter)(void); - float (MOD_CALL *get_fps)(void); -}; -STATIC_ASSERT(sizeof(mod_host_api_t) == 0x238, "invalid host API size"); - -const mod_host_api_t * -mod_host_api_get(void); - -typedef struct mod_api_s mod_api_t; -struct mod_api_s { - uint32_t struct_size; - version_t abi_version; - mod_init_fn_t init; - mod_deinit_fn_t deinit; - mod_tick_fn_t tick; - mod_input_fn_t input; - mod_pe_pre_fn_t pe_pre; - mod_pe_post_fn_t pe_post; - mod_func_invoke_pre_fn_t func_invoke_pre; - mod_func_invoke_post_fn_t func_invoke_post; - mod_draw_panel_fn_t draw_panel; - mod_draw_config_fn_t draw_config; -}; - -typedef const mod_api_t *(MOD_CALL *mod_entry_fn_t)(void); - -/* - * Host/plugin ABI rule: - * - major must match - * - minor must match - * - patch is ignored for compatibility and may add optional fields at the end of a table - * - struct_size must be checked before accessing optional appended fields - */ -static inline bool -mod_abi_compatible(version_t host, version_t plugin) -{ - return host.major == plugin.major && host.minor == plugin.minor; -} - -#endif /* MOD_HOST_H */ diff --git a/include/mod_manager.h b/include/mod_manager.h index 950cb0b..3a3c4ef 100644 --- a/include/mod_manager.h +++ b/include/mod_manager.h @@ -5,6 +5,7 @@ #include "hook_chain.h" #include "ini.h" #include "input.h" +#include "mod.h" #include "str.h" #include "types.h" #include "unreal.h" @@ -12,33 +13,6 @@ #include "vendor_nuklear.h" -#define MOD_HANDLE_INVALID ((mod_handle_t)0) -#define MOD_CFG_HANDLE_INVALID ((mod_cfg_handle_t)0) -#define MOD_ARENA_HANDLE_INVALID ((mod_arena_handle_t)0) - -typedef uint64_t mod_handle_t; -typedef uint64_t mod_cfg_handle_t; -typedef uint64_t mod_arena_handle_t; - -#define MOD_CALL __cdecl -#define MOD_DLL_ENTRY_EXPORT "mod_entry" - -typedef struct mod_host_api_s mod_host_api_t; - -typedef bool(MOD_CALL *mod_init_fn_t)(const mod_host_api_t *host, mod_handle_t h); -typedef void(MOD_CALL *mod_deinit_fn_t)(mod_handle_t h); - -typedef void(MOD_CALL *mod_tick_fn_t)(mod_handle_t h, float delta); -typedef bool(MOD_CALL *mod_input_fn_t)(mod_handle_t h, input_event_t *ev); - -typedef bool(MOD_CALL *mod_pe_pre_fn_t)(mod_handle_t h, uobject_t *obj, ufunc_t *func, void *params); -typedef void(MOD_CALL *mod_pe_post_fn_t)(mod_handle_t h, uobject_t *obj, ufunc_t *func, void *params, bool consumed); -typedef bool(MOD_CALL *mod_func_invoke_pre_fn_t)(mod_handle_t h, ufunc_t *func, uobject_t *obj, fframe_t *stack, void *result); -typedef void(MOD_CALL *mod_func_invoke_post_fn_t)(mod_handle_t h, ufunc_t *func, uobject_t *obj, fframe_t *stack, void *result, bool consumed); -typedef void(MOD_CALL *mod_draw_panel_fn_t) (mod_handle_t h, struct nk_context *ctx); -typedef void(MOD_CALL *mod_draw_config_fn_t)(mod_handle_t h, struct nk_context *ctx); -typedef void(MOD_CALL *mod_cmd_fn_t)(mod_handle_t h, str_t name, str_t args, void *user); - typedef uint8_t mod_kind_t; enum { MOD_KIND_MOD, @@ -140,11 +114,6 @@ struct mod_blueprint_info_s { keybind_t default_spawn_keybind; }; -typedef struct mod_color_s mod_color_t; -struct mod_color_s { - uint8_t r, g, b, a; -}; - typedef struct mod_option_info_s mod_option_info_t; struct mod_option_info_s { mod_option_type_t type; @@ -460,11 +429,11 @@ mod_get_blueprints_info(mod_manager_t *manager, mod_handle_t h, mod_blueprint_in int mod_get_options_info(mod_manager_t *manager, mod_handle_t h, mod_option_info_t *out, int cap); str_t -mod_get_mod_dir(mod_manager_t *manager, mod_handle_t h); +mod_manager_get_mod_dir(mod_manager_t *manager, mod_handle_t h); str_t -mod_get_config_path(mod_manager_t *manager, mod_handle_t h); +mod_manager_get_config_path(mod_manager_t *manager, mod_handle_t h); str_t -mod_get_manifest_path(mod_manager_t *manager, mod_handle_t h); +mod_manager_get_manifest_path(mod_manager_t *manager, mod_handle_t h); mod_arena_handle_t mod_get_perm_arena(mod_manager_t *manager, mod_handle_t h); @@ -473,7 +442,7 @@ mod_register(mod_manager_t *manager, mod_manifest_t *manifest); mod_handle_t mod_register_builtin(mod_manager_t *manager, mod_manifest_t *manifest, mod_dll_runtime_funcs_t funcs); bool -mod_register_cmd(mod_manager_t *manager, mod_handle_t h, str_t name, str_t description, mod_cmd_fn_t fn, void *user); +mod_manager_register_cmd(mod_manager_t *manager, mod_handle_t h, str_t name, str_t description, mod_cmd_fn_t fn, void *user); bool mod_dll_load(mod_manager_t *manager, mod_handle_t h); @@ -546,37 +515,37 @@ mod_cfg_revert(mod_manager_t *manager, mod_handle_t h); mod_cfg_handle_t mod_cfg_get_by_id(mod_manager_t *manager, mod_handle_t h, str_t id); bool -mod_cfg_get_bool(mod_manager_t *manager, mod_cfg_handle_t h); +mod_manager_cfg_get_bool(mod_manager_t *manager, mod_cfg_handle_t h); int -mod_cfg_get_int(mod_manager_t *manager, mod_cfg_handle_t h); +mod_manager_cfg_get_int(mod_manager_t *manager, mod_cfg_handle_t h); float -mod_cfg_get_float(mod_manager_t *manager, mod_cfg_handle_t h); +mod_manager_cfg_get_float(mod_manager_t *manager, mod_cfg_handle_t h); int -mod_cfg_get_enum(mod_manager_t *manager, mod_cfg_handle_t h); +mod_manager_cfg_get_enum(mod_manager_t *manager, mod_cfg_handle_t h); uint64_t -mod_cfg_get_string_len(mod_manager_t *manager, mod_cfg_handle_t h); +mod_manager_cfg_get_string_len(mod_manager_t *manager, mod_cfg_handle_t h); uint64_t -mod_cfg_get_string_data(mod_manager_t *manager, mod_cfg_handle_t h, void *buf, uint64_t cap); +mod_manager_cfg_get_string_data(mod_manager_t *manager, mod_cfg_handle_t h, void *buf, uint64_t cap); str_t mod_cfg_get_string(mod_manager_t *manager, mod_cfg_handle_t h, arena_t *arena); keybind_t -mod_cfg_get_keybind(mod_manager_t *manager, mod_cfg_handle_t h); +mod_manager_cfg_get_keybind(mod_manager_t *manager, mod_cfg_handle_t h); mod_color_t -mod_cfg_get_color(mod_manager_t *manager, mod_cfg_handle_t h); +mod_manager_cfg_get_color(mod_manager_t *manager, mod_cfg_handle_t h); void -mod_cfg_set_bool(mod_manager_t *manager, mod_cfg_handle_t h, bool val); +mod_manager_cfg_set_bool(mod_manager_t *manager, mod_cfg_handle_t h, bool val); void -mod_cfg_set_int(mod_manager_t *manager, mod_cfg_handle_t h, int val); +mod_manager_cfg_set_int(mod_manager_t *manager, mod_cfg_handle_t h, int val); void -mod_cfg_set_float(mod_manager_t *manager, mod_cfg_handle_t h, float val); +mod_manager_cfg_set_float(mod_manager_t *manager, mod_cfg_handle_t h, float val); void -mod_cfg_set_enum(mod_manager_t *manager, mod_cfg_handle_t h, int val); +mod_manager_cfg_set_enum(mod_manager_t *manager, mod_cfg_handle_t h, int val); void -mod_cfg_set_string(mod_manager_t *manager, mod_cfg_handle_t h, str_t val); +mod_manager_cfg_set_string(mod_manager_t *manager, mod_cfg_handle_t h, str_t val); void -mod_cfg_set_keybind(mod_manager_t *manager, mod_cfg_handle_t h, keybind_t bind); +mod_manager_cfg_set_keybind(mod_manager_t *manager, mod_cfg_handle_t h, keybind_t bind); void -mod_cfg_set_color(mod_manager_t *manager, mod_cfg_handle_t h, mod_color_t color); +mod_manager_cfg_set_color(mod_manager_t *manager, mod_cfg_handle_t h, mod_color_t color); bool mod_cfg_string_set(mod_cfg_string_t *dst, str_t src); diff --git a/include/path.h b/include/path.h index 9a1ed02..613e3b5 100644 --- a/include/path.h +++ b/include/path.h @@ -4,36 +4,40 @@ #include "str.h" #include "arena.h" -str_t +MOD_EXTERN_C_BEGIN + +MOD_API str_t path_base(str_t path); -str_t +MOD_API str_t path_dir(str_t path); -str_t +MOD_API str_t path_get_ext(str_t path); -str_t +MOD_API str_t path_trim_ext(str_t path); -str_t +MOD_API str_t path_replace_slashes_inplace(str_t path, char ch); -bool +MOD_API bool path_equal(str_t a, str_t b); -bool +MOD_API bool path_has_prefix(str_t path, str_t prefix); -bool +MOD_API bool path_make_relative(str_t path, str_t base, str_t *out); -str_t +MOD_API str_t path_push_relative(arena_t *arena, str_t path, str_t base); -bool +MOD_API bool path_is_abs(str_t path); -str_list_t +MOD_API str_list_t path_push_parts(arena_t *arena, str_t path); -str_t +MOD_API str_t path_module_dir(arena_t *perm); -str_t +MOD_API str_t path_join(arena_t *arena, str_t a, str_t b); +MOD_EXTERN_C_END + #endif /* PATH_H */ diff --git a/include/scratch.h b/include/scratch.h index 1d2e0b9..8a45716 100644 --- a/include/scratch.h +++ b/include/scratch.h @@ -4,6 +4,8 @@ #include "types.h" #include "arena.h" +MOD_EXTERN_C_BEGIN + #define SCRATCH_POOL_SIZE (2) typedef struct scratch_s scratch_t; @@ -12,20 +14,22 @@ struct scratch_s { arena_t arenas[SCRATCH_POOL_SIZE]; }; -arena_t * +MOD_API arena_t * scratch_get(arena_t *conflict); -tmp_arena_t +MOD_API tmp_arena_t scratch_begin(arena_t *conflict); -void +MOD_API void scratch_end(tmp_arena_t tmp); -void +MOD_API void scratch_reset(void); -void +MOD_API void scratch_destroy(void); -bool +MOD_API bool scratch_has_conflict(arena_t *conflict); +MOD_EXTERN_C_END + #endif /* SCRATCH_H */ diff --git a/include/sigscan.h b/include/sigscan.h index c55c9c8..1471756 100644 --- a/include/sigscan.h +++ b/include/sigscan.h @@ -4,6 +4,8 @@ #include "arena.h" #include "types.h" +MOD_EXTERN_C_BEGIN + typedef uint8_t sig_kind_t; enum { SIG_DIRECT, // use match address + add @@ -129,13 +131,15 @@ struct sigscan_exec_span_s { uintptr_t rva; }; -int +MOD_API int sigscan_build_exec_spans(sigscan_exec_span_t *spans, int max_spans, void *module_base); -bool +MOD_API bool sigscan_snapshot_exec_spans(sigscan_exec_span_t *spans, int num_spans, arena_t *arena); -sigscan_err_t +MOD_API sigscan_err_t sigscan_scan_entry(sigscan_exec_span_t *spans, int num_spans, void *module_base, sigscan_entry_t *entry); +MOD_EXTERN_C_END + #endif /* SIGSCAN_H */ diff --git a/include/str.h b/include/str.h index 6049b07..e249696 100644 --- a/include/str.h +++ b/include/str.h @@ -4,9 +4,16 @@ #include "arena.h" #include "types.h" +MOD_EXTERN_C_BEGIN + #define STR_CLIT(lit) {.data = (uint8_t *)(ENSURE_STR_LIT(lit)), .len = (sizeof(lit) - 1)} -#define STR_LIT(lit) (str_t) STR_CLIT(ENSURE_STR_LIT(lit)) -#define STR_NULL (str_t){0} +#ifdef __cplusplus +# define STR_LIT(lit) str_t STR_CLIT(lit) +# define STR_NULL str_t{} +#else +# define STR_LIT(lit) (str_t) STR_CLIT(lit) +# define STR_NULL (str_t){0} +#endif #define STR_FMT "%.*s" #define STR_ARG(str) (int)(str).len, (str).data @@ -169,175 +176,177 @@ ascii_equal(uint8_t a, uint8_t b, str_cmp_flags_t flags) } /* length calculation */ -uint64_t +MOD_API uint64_t calc_cstr_len(const char *cstr); -uint64_t +MOD_API uint64_t calc_cstr_len_with_cap(const char *s, uint64_t cap); -uint64_t +MOD_API uint64_t calc_wstr_len(const wchar_t *wstr); -uint64_t +MOD_API uint64_t calc_wstr_len_with_cap(const wchar_t *s, uint64_t cap); /* creation */ -str_t +MOD_API str_t str_make(void *data, uint64_t size); -str_t +MOD_API str_t str_from_cstr(const char *cstr); -str_t +MOD_API str_t str_from_cstr_with_cap(const char *cstr, uint64_t cap); -str16_t +MOD_API str16_t str16_make(uint16_t *data, uint64_t size); -str16_t +MOD_API str16_t str16_from_wstr(const wchar_t *wstr); -str16_t +MOD_API str16_t str16_from_wstr_with_cap(const wchar_t *wstr, uint64_t cap); -str_t +MOD_API str_t str_slice(str_t str, uint64_t start_idx, uint64_t end_idx); /* comparison/search */ -bool +MOD_API bool str_has_prefix(str_t s, str_t prefix, str_cmp_flags_t flags); -bool +MOD_API bool str_has_suffix(str_t s, str_t suffix, str_cmp_flags_t flags); -int +MOD_API int str_compare(str_t a, str_t b, str_cmp_flags_t flags); -bool +MOD_API bool str_equal(str_t a, str_t b, str_cmp_flags_t flags); -bool +MOD_API bool str_equal_icase(str_t a, str_t b); -bool +MOD_API bool str_find(str_t s, str_t sub, str_cmp_flags_t flags, uint64_t *idx); -bool +MOD_API bool str_rfind(str_t s, str_t sub, str_cmp_flags_t flags, uint64_t *idx); -bool +MOD_API bool str_find_any(str_t s, str_t charset, str_cmp_flags_t flags, uint64_t *idx); -bool +MOD_API bool str_rfind_any(str_t s, str_t charset, str_cmp_flags_t flags, uint64_t *idx); -bool +MOD_API bool str_has_char(str_t s, char c, str_cmp_flags_t flags); /* allocation */ -str_t +MOD_API str_t str_push_copy(arena_t *arena, str_t str); -uint64_t +MOD_API uint64_t str_write_vfmt(void *buf, uint64_t cap, const char *fmt, va_list args); -uint64_t +MOD_API uint64_t str_write_fmt(void *buf, uint64_t cap, const char *fmt, ...) ATTR_FORMAT(3, 4); -str_t +MOD_API str_t str_push_vfmt(arena_t *arena, const char *fmt, va_list args); -str_t +MOD_API str_t str_push_fmt(arena_t *arena, const char *fmt, ...) ATTR_FORMAT(2, 3); -str_t +MOD_API str_t str_push_fill_byte(arena_t *arena, uint64_t size, uint8_t byte); -str_t +MOD_API str_t str_push_concat(arena_t *arena, str_t a, str_t b); -str_t +MOD_API str_t str_push_hex(arena_t *arena, void *data, uint64_t size); /* string list/array */ -str_list_t +MOD_API str_list_t str_list_copy(arena_t *arena, str_list_t src); -void +MOD_API void str_list_push_node(str_list_t *list, str_node_t *n); -void +MOD_API void str_list_push_node_front(str_list_t *list, str_node_t *n); -void +MOD_API void str_list_push(arena_t *arena, str_list_t *list, str_t str); -void +MOD_API void str_list_push_copy(arena_t *arena, str_list_t *list, str_t str); -void +MOD_API void str_list_push_fmt(arena_t *arena, str_list_t *list, const char *fmt, ...) ATTR_FORMAT(3, 4); -void +MOD_API void str_list_push_front(arena_t *arena, str_list_t *list, str_t str); -void +MOD_API void str_list_push_front_fmt(arena_t *arena, str_list_t *list, const char *fmt, ...) ATTR_FORMAT(3, 4); -bool +MOD_API bool str_list_contains(str_list_t list, str_t s, str_cmp_flags_t flags); -void +MOD_API void str_list_concat_inplace(str_list_t *dst, str_list_t *src); -str_list_t +MOD_API str_list_t str_split(arena_t *arena, str_t str, uint64_t split_count, str_t *splits); -str_list_t +MOD_API str_list_t str_split_lines(arena_t *arena, str_t str); -str_t +MOD_API str_t str_list_join(arena_t *arena, str_list_t list, str_t pre, str_t sep, str_t post); -str_t +MOD_API str_t str_list_join_lines(arena_t *arena, str_list_t list); -str_array_t +MOD_API str_array_t str_array_make(str_t *items, int count); -str_array_t +MOD_API str_array_t str_array_copy(arena_t *arena, str_array_t a); -str_array_t +MOD_API str_array_t str_array_copy_from_list(arena_t *arena, str_list_t list); -str_array_t +MOD_API str_array_t str_array_from_list(arena_t *arena, str_list_t list); -bool +MOD_API bool str_array_contains(str_array_t array, str_t s, str_cmp_flags_t flags); -bool +MOD_API bool str_array_find(str_array_t array, str_t s, str_cmp_flags_t flags, uint64_t *idx); /* UTF-8 <-> UTF-16 conversions */ -str_t +MOD_API str_t str_from_str16(arena_t *arena, str16_t in); -str16_t +MOD_API str16_t str16_from_str(arena_t *arena, str_t in); -uint64_t +MOD_API uint64_t str16_utf8_len(str16_t in); -uint64_t +MOD_API uint64_t str16_write_utf8(uint8_t *buf, uint64_t max_len, str16_t in); /* C-string conversion */ -char * +MOD_API char * str_push_cstr(arena_t *arena, str_t s); -wchar_t * +MOD_API wchar_t * str16_push_wstr(arena_t *arena, str16_t s); -uint64_t +MOD_API uint64_t str_write_cstr(str_t s, char *buf, uint64_t cap); -uint64_t +MOD_API uint64_t str_write_data(str_t s, char *buf, uint64_t cap); /* mutations */ -str_t +MOD_API str_t str_to_upper(arena_t *arena, str_t str); -str_t +MOD_API str_t str_to_lower(arena_t *arena, str_t str); /* trimming */ -str_t +MOD_API str_t str_trim_leading(str_t str, str_t charset, str_cmp_flags_t flags); -str_t +MOD_API str_t str_trim_trailing(str_t str, str_t charset, str_cmp_flags_t flags); -str_t +MOD_API str_t str_trim(str_t str, str_t charset, str_cmp_flags_t flags); -str_t +MOD_API str_t str_trim_leading_space(str_t str); -str_t +MOD_API str_t str_trim_trailing_space(str_t str); -str_t +MOD_API str_t str_trim_space(str_t str); -str_t +MOD_API str_t str_trim_prefix(str_t str, str_t prefix, str_cmp_flags_t flags); -str_t +MOD_API str_t str_trim_suffix(str_t str, str_t suffix, str_cmp_flags_t flags); -str_t +MOD_API str_t str_trim_comment(str_t str, str_t charset, str_cmp_flags_t flags); /* parsing */ -bool +MOD_API bool str_parse_s64(str_t str, int64_t *value); -bool +MOD_API bool str_parse_int(str_t str, int *value); -bool +MOD_API bool str_parse_u32(str_t str, uint32_t *value); -bool +MOD_API bool str_parse_u16(str_t str, uint16_t *value); -bool +MOD_API bool str_parse_u8(str_t str, uint8_t *value); -bool +MOD_API bool str_parse_float(str_t str, float *value); -bool +MOD_API bool str_parse_bool(str_t s, bool default_val); +MOD_EXTERN_C_END + #endif /* STR_H */ diff --git a/include/types.h b/include/types.h index b5e405c..8d7e089 100644 --- a/include/types.h +++ b/include/types.h @@ -8,6 +8,32 @@ #include #include +/* ----------------------------- public DLL ABI ----------------------------- */ + +#define MOD_CALL __cdecl + +#if defined(OVERDUB_BUILD_DLL) +# define MOD_API __declspec(dllexport) +#elif defined(OVERDUB_STATIC) +# define MOD_API +#else +# define MOD_API __declspec(dllimport) +#endif + +#define MOD_EXPORT __declspec(dllexport) + +#ifdef __cplusplus +# define MOD_EXTERN_C extern "C" +# define MOD_EXTERN_C_BEGIN extern "C" { +# define MOD_EXTERN_C_END } +#else +# define MOD_EXTERN_C +# define MOD_EXTERN_C_BEGIN +# define MOD_EXTERN_C_END +#endif + +MOD_EXTERN_C_BEGIN + /* -------------------------------- compiler -------------------------------- */ #if defined(_MSC_VER) @@ -182,12 +208,12 @@ # define DEBUGBREAK() raise(SIGTRAP) #endif -#if defined BUILD_DEBUG || defined BUILD_TEST_UI -void +MOD_API void my_assert_msg(const char *expr, const char *file, int line, const char *fmt, ...) ATTR_FORMAT(4, 5); -void +MOD_API void my_assert(const char *expr, const char *file, int line); +#if defined BUILD_DEBUG || defined BUILD_TEST_UI # define ASSERT(COND) \ do { \ if (!(COND)) { \ @@ -345,7 +371,7 @@ mem_move(void *dst, void *src, uint64_t size) return dst; } -uint64_t +MOD_API uint64_t time_now_us(void); static inline uint64_t @@ -360,9 +386,11 @@ time_us_to_ms(uint64_t us) return (us + 999) / 1000; } -bool +MOD_API bool float_equal(float a, float b, float min_val, float step); #include "config.h" +MOD_EXTERN_C_END + #endif /* TYPES_H */ diff --git a/include/unreal.h b/include/unreal.h index e9dc963..d7c664e 100644 --- a/include/unreal.h +++ b/include/unreal.h @@ -5,7 +5,13 @@ #include "str.h" #include "types.h" -#define FNAME_NONE (fname_t){0} +MOD_EXTERN_C_BEGIN + +#ifdef __cplusplus +# define FNAME_NONE fname_t{} +#else +# define FNAME_NONE (fname_t){0} +#endif #define FNAME_MAX_BLOCK_BITS 13 #define FNAME_BLOCK_OFFSET_BITS 16 @@ -2064,7 +2070,7 @@ typedef struct foverride_s { typedef struct fsubobject_init_s { struct uobject_s *subobject; - struct uobject_s *template; + struct uobject_s *template_obj; } fsubobject_init_t; typedef TARRAY_INLINE(foverride_t, 8) foverrides_t; @@ -3026,51 +3032,58 @@ STATIC_ASSERT(sizeof(ugameplay_tags_manager_t) /* ===================================================== FNAME ====================================================== */ -bool +MOD_API fname_pool_t * +unreal_get_name_pool(void); +MOD_API fuobject_array_t * +unreal_get_object_array(void); +MOD_API uworld_t * +unreal_get_current_world(void); + +MOD_API bool unreal_fname_equal(fname_t a, fname_t b, bool ignore_num); -uint32_t +MOD_API uint32_t unreal_fname_hash(fname_t name); -bool +MOD_API bool unreal_fname_is_none(fname_t name); -fname_entry_t * +MOD_API fname_entry_t * unreal_fname_entry_get(uint32_t cmp_idx); -uint64_t +MOD_API uint64_t unreal_fname_utf8_len(fname_t name); -uint64_t +MOD_API uint64_t unreal_fname_utf8_write(uint8_t *buf, uint64_t max_len, fname_t name); -str_t +MOD_API str_t unreal_fname_to_str(fname_t fname, arena_t *perm); -fname_t +MOD_API fname_t unreal_fname_from_str(str_t s, efind_name_t find_type); typedef bool (*fname_pool_iter_cb_t)(fname_t name, fname_entry_t *entry, void *user); -void +MOD_API void unreal_fname_pool_iterate(fname_pool_iter_cb_t cb, void *user); -bool +MOD_API bool unreal_fname_entry_match_text(fname_entry_t *entry, str_t text, bool ignore_case, bool exact_match); -bool +MOD_API bool unreal_fname_entry_match_text16(fname_entry_t *entry, str16_t text, bool ignore_case, bool exact_match); -bool +MOD_API bool unreal_fname_match_text(fname_t name, str_t text, bool ignore_case, bool exact_match); -bool +MOD_API bool unreal_fname_match_text16(fname_t name, str16_t text, bool ignore_case, bool exact_match); /* ==================================================== FSTRING ===================================================== */ -fstring_t +MOD_API fstring_t unreal_fstring_view_from_str16(str16_t s); -str16_t +MOD_API str16_t unreal_fstring_view_to_str16(fstring_t fs); -fstring_t +MOD_API fstring_t unreal_fstring_from_str(str_t s, arena_t *perm); -str_t +MOD_API str_t unreal_fstring_to_str(fstring_t fs, arena_t *perm); -uint32_t +MOD_API uint32_t unreal_fstring_hash(fstring_t str); /* =================================================== FIOSTATUS ==================================================== */ -str_t +MOD_API str_t unreal_fio_status_to_str(fio_status_t status, arena_t *perm); /* ==================================================== UOBJECT ===================================================== */ @@ -3160,7 +3173,7 @@ struct unreal_common_s { fname_t int_vector; }; -void +MOD_API void unreal_common_collect(unreal_common_t *common); typedef enum { @@ -3180,164 +3193,172 @@ struct uobject_listener_s { void *user; }; -void +MOD_API void uobject_listener_destroy_cb(fuobject_listener_t *self); -void +MOD_API void uobject_listener_on_notify_cb(fuobject_listener_t *self, const uobject_t *obj, int32_t idx); -void +MOD_API void uobject_listener_on_shutdown_cb(fuobject_listener_t *self); -void +MOD_API void unreal_register_uobject_listener(uobject_listener_kind_t kind, uobject_on_notify_cb_t notify_cb, void *user); -void +MOD_API void unreal_deregister_object_listener(uobject_listener_kind_t kind, uobject_on_notify_cb_t notify_cb, void *user); -void +MOD_API void unreal_uobject_listener_add(uobject_listener_t *listener); -void +MOD_API void unreal_uobject_listener_del(uobject_listener_t *listener); -fuobject_item_t * +MOD_API fuobject_item_t * unreal_uobject_array_get_item(int idx); -bool +MOD_API bool unreal_uobject_array_item_is_valid(fuobject_item_t *item); -uobject_t * +MOD_API uobject_t * unreal_uobject_array_get_obj(int idx); -bool +MOD_API bool unreal_uobject_is_a(uobject_t *obj, uclass_t *cls); -bool +MOD_API bool unreal_uclass_is_child_of(uclass_t *child, uclass_t *parent); -bool +MOD_API bool unreal_uobject_is_default(uobject_t *obj); -bool +MOD_API bool unreal_uobject_is_valid(uobject_t *obj); -uint64_t +MOD_API uint64_t unreal_uobject_get_name_len(uobject_t *obj); -uint64_t +MOD_API uint64_t unreal_uobject_write_name(uobject_t *obj, uint8_t *dst, uint64_t cap); -str_t +MOD_API str_t unreal_uobject_push_name(uobject_t *obj, arena_t *perm); -bool +MOD_API bool unreal_outer_chain_contains(uobject_t *obj, str_t str, bool ignore_case, bool exact_match); -bool +MOD_API bool unreal_super_chain_contains(uclass_t *cls, str_t str, bool ignore_case, bool exact_match); -uint64_t +MOD_API uint64_t unreal_uobject_get_full_name_len(uobject_t *obj); -uint64_t +MOD_API uint64_t unreal_uobject_write_full_name(uobject_t *obj, uint8_t *dst, uint64_t cap); -str_t +MOD_API str_t unreal_uobject_push_full_name(uobject_t *obj, arena_t *perm); -int +MOD_API int unreal_uobject_array_count(void); -int +MOD_API int unreal_uobject_array_capacity(void); -int +MOD_API int unreal_uobject_array_num_chunks(void); -int +MOD_API int unreal_uobject_array_max_chunks(void); -int +MOD_API int unreal_uobject_array_first_gc_index(void); -int +MOD_API int unreal_uobject_array_last_non_gc_index(void); -bool +MOD_API bool unreal_uobject_array_is_open_for_disregard_for_gc(void); -uobject_t * +MOD_API uobject_t * unreal_uobject_find(str_t name, bool ignore_case, bool exact_match); -uclass_t * +MOD_API uclass_t * unreal_uclass_find(str_t name, bool ignore_case, bool exact_match); -uobject_t * +MOD_API uobject_t * unreal_uobject_find_first_of(uclass_t *cls); -uobject_t * +MOD_API uobject_t * unreal_uobject_find_first_of_by_name(uclass_t *cls, str_t name, bool ignore_case, bool exact_match); -uclass_t * +MOD_API uclass_t * unreal_uobject_find_class_by_full_name(str_t full_name); -uobject_t * +MOD_API uobject_t * unreal_uobject_find_by_full_name(uclass_t *cls, str_t full_name); -void +MOD_API void unreal_process_event(uobject_t *self, ufunc_t *func, void *params); /* Calls the virtual ProcessEvent entry so normal Overdub hooks/listeners observe the call. */ -void +MOD_API void unreal_process_event_observed(uobject_t *self, ufunc_t *func, void *params); -uobject_t * +MOD_API uobject_t * unreal_spawn_actor(uobject_t *world_ctx_obj, uclass_t *cls); -void +MOD_API void unreal_despawn_actor(uobject_t *actor); -uobject_t * +MOD_API uobject_t * unreal_static_construct_object(fstatic_construct_obj_params_t *params); -uobject_t * +MOD_API uobject_t * unreal_static_load_object(uclass_t *obj_cls, uobject_t *outer, str_t name, str_t filename, uint32_t load_flags, void *sandbox, bool allow_obj_reconcile, void *instancing_ctx); -uclass_t * +MOD_API uclass_t * unreal_static_load_class(uclass_t *base_cls, uobject_t *outer, str_t name, str_t filename, uint32_t load_flags); -bool +MOD_API bool unreal_pak_is_standalone(str_t file_path); -void +MOD_API void unreal_pak_only_mount_push(void); -void +MOD_API void unreal_pak_only_mount_pop(void); -bool +MOD_API bool unreal_is_pak_only_mount_active(void); -bool +MOD_API bool unreal_mount_pak(str_t file_path, int order); -bool +MOD_API bool unreal_mount_iostore(str_t file_path, int order); -fnative_func_ptr_t +MOD_API fnative_func_ptr_t unreal_get_native(uint8_t opcode); -bool +MOD_API bool unreal_fframe_step(fframe_t *stack, void *result); /* ================================================ CLASS INTROSPECTION ============================================= */ -ufunc_t * +MOD_API ufunc_t * unreal_ustruct_find_func(ustruct_t *s, str_t name); -ufunc_t * +MOD_API ufunc_t * unreal_ustruct_find_func_fname(ustruct_t *s, fname_t name, bool ignore_num); -void * +MOD_API void * unreal_get_mcast_sparse_delegate(uobject_t *s, fname_t name); /* =============================================== CONTAINER UTILITIES ============================================== */ -bool +MOD_API bool unreal_tbit_array_is_set(tbit_array_t *bits, int32_t idx); -int32_t +MOD_API int32_t unreal_tbit_array_find_next_set(tbit_array_t *bits, int32_t start_idx); -int32_t +MOD_API int32_t unreal_tset_hash_head(hash_allocator_t *hash, int32_t hash_size, uint32_t key_hash); /* =================================================== DATA TABLE =================================================== */ -tmap_fname_uint8ptr_t * +MOD_API tmap_fname_uint8ptr_t * unreal_udata_table_get_row_map(udata_table_t *table); -void +MOD_API void unreal_udata_table_add_row(udata_table_t *table, fname_t row_name, const ftable_row_base_t *row_data); -void +MOD_API void unreal_udata_table_remove_row(udata_table_t *table, fname_t row_name); -void +MOD_API void unreal_udata_table_empty(udata_table_t *table); -uint8_t * +MOD_API uint8_t * unreal_udata_table_find_row(udata_table_t *table, fname_t row_name); /* ============================================= GAMEPLAY TAGS MANAGER ============================================== */ -bool +/* Queue a tag for Overdub to add when the engine tag tree is ready. */ +MOD_API bool +unreal_add_gameplay_tag(fname_t tag_name); +MOD_API bool +unreal_check_gameplay_tag_exists(fname_t tag_name); + +MOD_API bool unreal_gameplay_tags_manager_add(fname_t tag_name); -void +MOD_API void unreal_gameplay_tags_manager_broadcast_tree_changed(void); -fgameplay_tag_t +MOD_API fgameplay_tag_t unreal_gameplay_tags_manager_request_tag(fname_t tag_name); +MOD_EXTERN_C_END + #endif /* UE_TYPES_H */ diff --git a/include/unreal_prop.h b/include/unreal_prop.h index 78678d7..83eb7e6 100644 --- a/include/unreal_prop.h +++ b/include/unreal_prop.h @@ -3,6 +3,8 @@ #include "unreal.h" +MOD_EXTERN_C_BEGIN + /* FProperty metadata and lookup. */ typedef enum unreal_prop_kind_e { UNREAL_PROP_KIND_UNKNOWN, @@ -44,53 +46,53 @@ struct unreal_prop_integer_s { bool is_signed; }; -fprop_t * +MOD_API fprop_t * unreal_ustruct_find_prop(ustruct_t *s, str_t name); -unreal_prop_kind_t +MOD_API unreal_prop_kind_t unreal_fprop_get_kind(fprop_t *prop); -bool +MOD_API bool unreal_fprop_struct_is(fprop_t *prop, fname_t struct_name); -bool +MOD_API bool unreal_fprop_class_is(fprop_t *prop, fname_t name); -bool +MOD_API bool unreal_fprop_class_is_a(fprop_t *prop, fname_t name); -str_t +MOD_API str_t unreal_fprop_push_type_name(fprop_t *prop, arena_t *arena); -bool +MOD_API bool unreal_fprop_read_bool(fprop_t *prop, const void *value, bool *out); -bool +MOD_API bool unreal_fprop_read_integer(fprop_t *prop, const void *value, unreal_prop_integer_t *out); -bool +MOD_API bool unreal_fprop_read_real(fprop_t *prop, const void *value, double *out); -bool +MOD_API bool unreal_fprop_read_name(fprop_t *prop, const void *value, fname_t *out); -bool +MOD_API bool unreal_fprop_write_bool(fprop_t *prop, void *value, bool input); -bool +MOD_API bool unreal_fprop_write_integer(fprop_t *prop, void *value, unreal_prop_integer_t input); -bool +MOD_API bool unreal_fprop_write_real(fprop_t *prop, void *value, double input); -bool +MOD_API bool unreal_fprop_write_name(fprop_t *prop, void *value, fname_t input); -uobject_t * +MOD_API uobject_t * unreal_fprop_get_object(fprop_obj_base_t *prop, const void *value); -uobject_t * +MOD_API uobject_t * unreal_fprop_get_referenced_object(fprop_t *prop, const void *value); -bool +MOD_API bool unreal_fprop_object_is_compatible(fprop_obj_base_t *prop, uobject_t *object); -bool +MOD_API bool unreal_fprop_set_object(fprop_obj_base_t *prop, void *value, uobject_t *object); -uobject_t * +MOD_API uobject_t * unreal_fweak_object_resolve(fweak_object_ptr_t weak); -str_t +MOD_API str_t unreal_fscript_delegate_push_summary(const fscript_delegate_t *delegate, arena_t *arena); /* NOTE: value_size is the readable size of one property element, not its complete fixed-array size */ -str_t +MOD_API str_t unreal_fprop_push_value_summary(fprop_t *prop, const void *value, int32_t value_size, arena_t *arena); static inline void * @@ -99,120 +101,122 @@ unreal_uprop_ptr(fprop_t *prop, void *container) return (uint8_t *)container + prop->offset_internal; } -uint64_t +MOD_API uint64_t unreal_fprop_complete_size(fprop_t *prop); -int32_t +MOD_API int32_t unreal_fprop_min_alignment(fprop_t *prop); -void * +MOD_API void * unreal_fprop_value_at(fprop_t *prop, void *value, int32_t array_idx); -void * +MOD_API void * unreal_fprop_value_in_container(fprop_t *prop, void *container, int32_t array_idx); -bool +MOD_API bool unreal_fprop_initialize_value(fprop_t *prop, void *value); -bool +MOD_API bool unreal_fprop_destroy_value(fprop_t *prop, void *value); -bool +MOD_API bool unreal_fprop_clear_single_value(fprop_t *prop, void *value); -bool +MOD_API bool unreal_fprop_clear_complete_value(fprop_t *prop, void *value); -bool +MOD_API bool unreal_fprop_copy_single_value(fprop_t *prop, void *dst, const void *src); -bool +MOD_API bool unreal_fprop_copy_complete_value(fprop_t *prop, void *dst, const void *src); -bool +MOD_API bool unreal_fprop_copy_single_value_to_script_vm(fprop_t *prop, void *dst, const void *src); -bool +MOD_API bool unreal_fprop_copy_complete_value_to_script_vm(fprop_t *prop, void *dst, const void *src); -bool +MOD_API bool unreal_fprop_copy_single_value_from_script_vm(fprop_t *prop, void *dst, const void *src); -bool +MOD_API bool unreal_fprop_copy_complete_value_from_script_vm(fprop_t *prop, void *dst, const void *src); -bool +MOD_API bool unreal_fprop_single_values_identical(fprop_t *prop, const void *a, const void *b, uint32_t port_flags); -bool +MOD_API bool unreal_fprop_complete_values_identical(fprop_t *prop, const void *a, const void *b, uint32_t port_flags); -bool +MOD_API bool unreal_fprop_value_hash(fprop_t *prop, const void *value, uint32_t *out_hash); -bool +MOD_API bool unreal_fprop_same_type(fprop_t *prop, fprop_t *other); -void +MOD_API void unreal_fprop_initialize_in_container(fprop_t *prop, void *container); -void +MOD_API void unreal_fprop_destroy_in_container(fprop_t *prop, void *container); -bool +MOD_API bool unreal_ustruct_initialize_struct(ustruct_t *struct_type, void *memory, int32_t array_dim); -bool +MOD_API bool unreal_ustruct_destroy_struct(ustruct_t *struct_type, void *memory, int32_t array_dim); -const wchar_t * +MOD_API const wchar_t * unreal_fprop_import_text_direct(fprop_t *prop, const wchar_t *text, void *value, uobject_t *owner); /* NOTE: imports one initialized property element transactionally. text uses engine's ImportText literal syntax */ -bool +MOD_API bool unreal_fprop_import_text(fprop_t *prop, void *value, uobject_t *owner, str_t text, arena_t *arena); /* Reflected dynamic containers. Indices are Unreal's zero-based sparse/array indices. */ -int32_t +MOD_API int32_t unreal_array_num(const void *array, fprop_array_t *prop); -void * +MOD_API void * unreal_array_get(void *array, fprop_array_t *prop, int32_t idx); -int32_t +MOD_API int32_t unreal_array_add(void *array, fprop_array_t *prop, const void *value); -void +MOD_API void unreal_array_insert(void *array, fprop_array_t *prop, int32_t idx, const void *value); -void +MOD_API void unreal_array_remove(void *array, fprop_array_t *prop, int32_t idx); -void +MOD_API void unreal_array_resize(void *array, fprop_array_t *prop, int32_t size); -void +MOD_API void unreal_array_set(void *array, fprop_array_t *prop, int32_t idx, const void *value, bool size_to_fit); -bool +MOD_API bool unreal_array_clear(void *array, fprop_array_t *prop); -int32_t +MOD_API int32_t unreal_set_num(const void *set, fprop_set_t *prop); -int32_t +MOD_API int32_t unreal_set_max_index(const void *set, fprop_set_t *prop); -bool +MOD_API bool unreal_set_is_valid_index(const void *set, fprop_set_t *prop, int32_t idx); -const void * +MOD_API const void * unreal_set_get(const void *set, fprop_set_t *prop, int32_t idx); -int32_t +MOD_API int32_t unreal_set_find_index(const void *set, fprop_set_t *prop, const void *value); -bool +MOD_API bool unreal_set_contains(const void *set, fprop_set_t *prop, const void *value); -void +MOD_API void unreal_set_add(void *set, fprop_set_t *prop, const void *value); -bool +MOD_API bool unreal_set_remove(void *set, fprop_set_t *prop, const void *value); -bool +MOD_API bool unreal_set_clear(void *set, fprop_set_t *prop); -int32_t +MOD_API int32_t unreal_map_num(const void *map, fprop_map_t *prop); -int32_t +MOD_API int32_t unreal_map_max_index(const void *map, fprop_map_t *prop); -bool +MOD_API bool unreal_map_is_valid_index(const void *map, fprop_map_t *prop, int32_t idx); -const void * +MOD_API const void * unreal_map_get_key(const void *map, fprop_map_t *prop, int32_t idx); -void * +MOD_API void * unreal_map_get_value(void *map, fprop_map_t *prop, int32_t idx); -int32_t +MOD_API int32_t unreal_map_find_index(const void *map, fprop_map_t *prop, const void *key); -void * +MOD_API void * unreal_map_find_value_ptr(void *map, fprop_map_t *prop, const void *key); -bool +MOD_API bool unreal_map_clear(void *map, fprop_map_t *prop); -void +MOD_API void unreal_map_add(void *map, fprop_map_t *prop, const void *key, const void *val); -bool +MOD_API bool unreal_map_remove(void *map, fprop_map_t *prop, const void *key); -bool +MOD_API bool unreal_map_find(void *map, fprop_map_t *prop, const void *key, void *out_val); +MOD_EXTERN_C_END + #endif /* UNREAL_PROP_H */ diff --git a/include/vendor_nuklear.h b/include/vendor_nuklear.h index b90ecb9..c4770ef 100644 --- a/include/vendor_nuklear.h +++ b/include/vendor_nuklear.h @@ -10,6 +10,10 @@ # pragma GCC diagnostic ignored "-Wunused-parameter" #endif +#ifndef NK_API +# define NK_API MOD_API +#endif + #include "nuklear/include/nuklear.h" #if COMPILER_MSVC diff --git a/include/version.h b/include/version.h index 91db150..abd68cd 100644 --- a/include/version.h +++ b/include/version.h @@ -3,12 +3,21 @@ #include "types.h" -#define MAKE_VERSION(MAJOR, MINOR, PATCH) \ - { \ - .major = MAJOR, \ - .minor = MINOR, \ - .patch = PATCH, \ - } +#ifdef __cplusplus +# define MAKE_VERSION(MAJOR, MINOR, PATCH) \ + version_t{ \ + .major = MAJOR, \ + .minor = MINOR, \ + .patch = PATCH, \ + } +#else +# define MAKE_VERSION(MAJOR, MINOR, PATCH) \ + { \ + .major = MAJOR, \ + .minor = MINOR, \ + .patch = PATCH, \ + } +#endif #define VERSION_ARG(V) (V).major, (V).minor, (V).patch diff --git a/mod/Makefile b/mod/Makefile index 42692b7..f406500 100644 --- a/mod/Makefile +++ b/mod/Makefile @@ -20,22 +20,36 @@ ifeq ($(origin CC), default) endif endif +ifeq ($(origin CXX), default) + ifeq ($(OS),Windows_NT) + CXX := g++ + else + CXX := x86_64-w64-mingw32-g++ + endif +endif + BUILD_DIR := build/$(CONFIG) TARGET := $(BUILD_DIR)/$(MOD_NAME).dll -SRCS := mod_sdk.c mod_unreal.c mod_nuklear.c -OBJS := $(SRCS:%.c=$(BUILD_DIR)/%.o) +SRCS := $(MOD_SRC) +OBJS := $(patsubst %.c,$(BUILD_DIR)/%.o,$(filter %.c,$(SRCS))) \ + $(patsubst %.cpp,$(BUILD_DIR)/%.o,$(filter %.cpp,$(SRCS))) DEPS := $(OBJS:.o=.d) +OVERDUB_LIB := ../build/overdub.lib + COMMON_WARNINGS := -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -COMMON_FLAGS := $(COMMON_WARNINGS) -ffunction-sections -fdata-sections -MMD -MP +COMMON_FLAGS := $(COMMON_WARNINGS) -I../include -I../vendor -ffunction-sections -fdata-sections -MMD -MP -CFLAGS := -std=c11 $(COMMON_FLAGS) +CFLAGS := -std=c11 $(COMMON_FLAGS) +CXXFLAGS := -std=c++20 $(COMMON_FLAGS) ifeq ($(CONFIG),debug) - CFLAGS += -O0 -g3 -DBUILD_DEBUG + CFLAGS += -O0 -g3 -DBUILD_DEBUG + CXXFLAGS += -O0 -g3 -DBUILD_DEBUG else ifeq ($(CONFIG),release) - CFLAGS += -O2 -DNDEBUG -DBUILD_RELEASE + CFLAGS += -O2 -DNDEBUG -DBUILD_RELEASE + CXXFLAGS += -O2 -DNDEBUG -DBUILD_RELEASE else $(error CONFIG must be debug or release) endif @@ -45,21 +59,24 @@ LDFLAGS := -shared -static -static-libgcc -static-libstdc++ \ -Wl,--exclude-all-symbols \ -Wl,--out-implib,$(BUILD_DIR)/lib$(MOD_NAME).a -LDLIBS := -luser32 +LDLIBS := $(OVERDUB_LIB) +LINKER := $(if $(filter %.cpp,$(SRCS)),$(CXX),$(CC)) .PHONY: all clean all: $(TARGET) -$(TARGET): $(OBJS) +$(TARGET): $(OBJS) $(OVERDUB_LIB) @mkdir -p $(@D) - $(CC) $(OBJS) $(LDFLAGS) $(LDLIBS) -o $@ + $(LINKER) $(OBJS) $(LDFLAGS) $(LDLIBS) -o $@ $(BUILD_DIR)/%.o: %.c @mkdir -p $(@D) $(CC) $(CFLAGS) -c $< -o $@ -$(BUILD_DIR)/mod_nuklear.o: CFLAGS += -w +$(BUILD_DIR)/%.o: %.cpp + @mkdir -p $(@D) + $(CXX) $(CXXFLAGS) -c $< -o $@ clean: rm -rf build diff --git a/mod/main.c b/mod/main.c index 5b188f0..6917cf1 100644 --- a/mod/main.c +++ b/mod/main.c @@ -1,21 +1,21 @@ -#include "mod_sdk.h" -#include "mod_unreal.h" +#include "mod.h" static bool -mod_init(const mod_host_api_t *host, mod_t m) +mod_init(mod_handle_t mod) { - mod_sdk_init(host, m); - unreal_cache_objects(); - - MOD_LOG_INFO("Hello from example mod!!!"); + MOD_LOG_INFO(mod, "Hello from example mod!!!"); return true; } +MOD_ABI_VERSION_ENTRY() +{ + return MOD_ABI_VERSION; +} + MOD_ENTRY() { static const mod_api_t api = { .struct_size = sizeof(mod_api_t), - .abi_version = MOD_ABI_VERSION, .init = mod_init, }; diff --git a/mod/mod.vcxproj b/mod/mod.vcxproj index acc0e85..685f145 100644 --- a/mod/mod.vcxproj +++ b/mod/mod.vcxproj @@ -74,12 +74,13 @@ true NotUsing WIN32_LEAN_AND_MEAN;NOMINMAX;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - $(ProjectDir);%(AdditionalIncludeDirectories) + $(ProjectDir)..\include;$(ProjectDir)..\vendor;%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) Windows - user32.lib;%(AdditionalDependencies) + overdub.lib;%(AdditionalDependencies) + $(ProjectDir)..\build;%(AdditionalLibraryDirectories) $(IntDir)$(TargetName).lib true true @@ -121,20 +122,10 @@ - - - - TurnOffAllWarnings - - - - - - TurnOffAllWarnings - + diff --git a/mod/mod.vcxproj.filters b/mod/mod.vcxproj.filters index 43f14fa..60cba7b 100644 --- a/mod/mod.vcxproj.filters +++ b/mod/mod.vcxproj.filters @@ -3,38 +3,17 @@ {2F25DBB8-8650-4DD6-96D1-7C0A40A42FA6} - - {957C32F4-BB0F-481A-9E75-6B0A37224903} - Mod - - SDK - - - SDK - - - SDK - - - SDK - - - SDK - - - SDK - - - SDK + + Mod diff --git a/mod/mod_api.h b/mod/mod_api.h deleted file mode 100644 index e4eccc5..0000000 --- a/mod/mod_api.h +++ /dev/null @@ -1,512 +0,0 @@ -#ifndef MOD_API_H -#define MOD_API_H - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define MOD_CALL __cdecl -#define MOD_EXPORT __declspec(dllexport) - -#ifdef __cplusplus -# define MOD_EXTERN_C extern "C" -#else -# define MOD_EXTERN_C -#endif - -#define MOD_ENTRY_NAME "mod_entry" -#define MOD_ENTRY() \ - MOD_EXTERN_C MOD_EXPORT const mod_api_t * MOD_CALL mod_entry(void) - -/* static assert */ -#if defined(__cplusplus) || (defined _MSC_VER && (_MSC_VER >= 1600)) -# define MOD_STATIC_ASSERT(COND, MSG) static_assert((COND), MSG) -#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) -# define MOD_STATIC_ASSERT(COND, MSG) _Static_assert((COND), MSG) -#endif - -/* ====================================================== INPUT ===================================================== */ - -typedef uint8_t input_event_kind_t; -enum { - INPUT_EVENT_KEY_DOWN, - INPUT_EVENT_KEY_UP, - INPUT_EVENT_KEY_CHAR, - INPUT_EVENT_MOUSE_DOWN, - INPUT_EVENT_MOUSE_UP, - INPUT_EVENT_MOUSE_DBLCLICK, - INPUT_EVENT_MOUSE_MOVE, - INPUT_EVENT_MOUSE_WHEEL, - INPUT_EVENT_ANALOG, - INPUT_EVENT_APP_ACTIVATION, - - INPUT_EVENT_MAX, -}; - -typedef uint8_t input_mod_flags_t; -enum { - INPUT_MOD_SHIFT = (1 << 0), - INPUT_MOD_CTRL = (1 << 1), - INPUT_MOD_ALT = (1 << 2), -}; - -typedef uint16_t input_key_kind_t; -enum { - INPUT_KEY_NONE = 0, - - /* keyboard: letters */ - INPUT_KEY_A, - INPUT_KEY_B, - INPUT_KEY_C, - INPUT_KEY_D, - INPUT_KEY_E, - INPUT_KEY_F, - INPUT_KEY_G, - INPUT_KEY_H, - INPUT_KEY_I, - INPUT_KEY_J, - INPUT_KEY_K, - INPUT_KEY_L, - INPUT_KEY_M, - INPUT_KEY_N, - INPUT_KEY_O, - INPUT_KEY_P, - INPUT_KEY_Q, - INPUT_KEY_R, - INPUT_KEY_S, - INPUT_KEY_T, - INPUT_KEY_U, - INPUT_KEY_V, - INPUT_KEY_W, - INPUT_KEY_X, - INPUT_KEY_Y, - INPUT_KEY_Z, - - /* keyboard: punctuation */ - INPUT_KEY_COMMA, // , or < - INPUT_KEY_PERIOD, // . or > - INPUT_KEY_SLASH, // / or ? - INPUT_KEY_SEMICOLON, // ; or : - INPUT_KEY_APOSTROPHE, // ' or " - INPUT_KEY_LEFT_BRACKET, // [ or { - INPUT_KEY_RIGHT_BRACKET, // ] or } - INPUT_KEY_BACKSLASH, // \ or | - INPUT_KEY_HYPHEN, // - or _ - INPUT_KEY_EQUALS, // = or + - INPUT_KEY_BACKTICK, // ` or ~ - - /* keyboard: digits */ - INPUT_KEY_1, // 1 or ! - INPUT_KEY_2, // 2 or @ - INPUT_KEY_3, // 3 or # - INPUT_KEY_4, // 4 or $ - INPUT_KEY_5, // 5 or % - INPUT_KEY_6, // 6 or ^ - INPUT_KEY_7, // 7 or & - INPUT_KEY_8, // 8 or * - INPUT_KEY_9, // 9 or ( - INPUT_KEY_0, // 0 or ) - - /* keyboard: function */ - INPUT_KEY_F1, - INPUT_KEY_F2, - INPUT_KEY_F3, - INPUT_KEY_F4, - INPUT_KEY_F5, - INPUT_KEY_F6, - INPUT_KEY_F7, - INPUT_KEY_F8, - INPUT_KEY_F9, - INPUT_KEY_F10, - INPUT_KEY_F11, - INPUT_KEY_F12, - - /* keyboard: navigation */ - INPUT_KEY_UP, - INPUT_KEY_DOWN, - INPUT_KEY_LEFT, - INPUT_KEY_RIGHT, - INPUT_KEY_HOME, - INPUT_KEY_END, - INPUT_KEY_PAGE_UP, - INPUT_KEY_PAGE_DOWN, - - /* keyboard: modifiers */ - INPUT_KEY_LEFT_SHIFT, - INPUT_KEY_RIGHT_SHIFT, - INPUT_KEY_LEFT_CTRL, - INPUT_KEY_RIGHT_CTRL, - INPUT_KEY_LEFT_ALT, - INPUT_KEY_RIGHT_ALT, - - /* keyboard: virtual modifiers (either left or right) */ - INPUT_KEY_SHIFT, - INPUT_KEY_CTRL, - INPUT_KEY_ALT, - - /* keyboard: common */ - INPUT_KEY_SPACE, - INPUT_KEY_ENTER, - INPUT_KEY_ESCAPE, - INPUT_KEY_TAB, - INPUT_KEY_BACKSPACE, - INPUT_KEY_CAPS_LOCK, - INPUT_KEY_INSERT, - INPUT_KEY_DELETE, - - /* keyboard: numpad */ - INPUT_KEY_NUM_0, - INPUT_KEY_NUM_1, - INPUT_KEY_NUM_2, - INPUT_KEY_NUM_3, - INPUT_KEY_NUM_4, - INPUT_KEY_NUM_5, - INPUT_KEY_NUM_6, - INPUT_KEY_NUM_7, - INPUT_KEY_NUM_8, - INPUT_KEY_NUM_9, - INPUT_KEY_NUM_MULTIPLY, // * - INPUT_KEY_NUM_ADD, // + - INPUT_KEY_NUM_SUBTRACT, // - - INPUT_KEY_NUM_DECIMAL, // . - INPUT_KEY_NUM_DIVIDE, // / - - /* keyboard: misc */ - INPUT_KEY_PAUSE, - INPUT_KEY_PRINT_SCREEN, - INPUT_KEY_SCROLL_LOCK, - INPUT_KEY_NUM_LOCK, - - /* mouse: buttons */ - INPUT_KEY_MOUSE_LEFT, - INPUT_KEY_MOUSE_RIGHT, - INPUT_KEY_MOUSE_MIDDLE, - INPUT_KEY_MOUSE_THUMB_1, - INPUT_KEY_MOUSE_THUMB_2, - - /* mouse: axes */ - INPUT_KEY_MOUSE_X, - INPUT_KEY_MOUSE_Y, - INPUT_KEY_MOUSE_WHEEL_UP, - INPUT_KEY_MOUSE_WHEEL_DOWN, - - /* gamepad: buttons */ - INPUT_KEY_GAMEPAD_FACE_BOTTOM, // A / cross - INPUT_KEY_GAMEPAD_FACE_RIGHT, // B / circle - INPUT_KEY_GAMEPAD_FACE_LEFT, // X / square - INPUT_KEY_GAMEPAD_FACE_TOP, // Y / triangle - INPUT_KEY_GAMEPAD_LB, - INPUT_KEY_GAMEPAD_RB, - INPUT_KEY_GAMEPAD_LT, - INPUT_KEY_GAMEPAD_RT, - INPUT_KEY_GAMEPAD_L3, - INPUT_KEY_GAMEPAD_R3, - INPUT_KEY_GAMEPAD_SPECIAL_LEFT, // select / share - INPUT_KEY_GAMEPAD_SPECIAL_RIGHT, // start / options - INPUT_KEY_GAMEPAD_DPAD_UP, - INPUT_KEY_GAMEPAD_DPAD_DOWN, - INPUT_KEY_GAMEPAD_DPAD_LEFT, - INPUT_KEY_GAMEPAD_DPAD_RIGHT, - - /* gamepad: axes */ - INPUT_KEY_GAMEPAD_LEFT_X, - INPUT_KEY_GAMEPAD_LEFT_Y, - INPUT_KEY_GAMEPAD_RIGHT_X, - INPUT_KEY_GAMEPAD_RIGHT_Y, - INPUT_KEY_GAMEPAD_LT_AXIS, - INPUT_KEY_GAMEPAD_RT_AXIS, - - INPUT_KEY_MAX, -}; - -typedef struct input_event_s input_event_t; -struct input_event_s { - input_event_kind_t kind; - input_mod_flags_t modifiers; // keyboard modifiers - input_key_kind_t key; // key, button, axis etc. - - uint32_t character; // unicode codepoint (KEY_CHAR only) - bool is_repeat; // KEY_DOWN only - bool app_activated; // APP_ACTIVATION only - uint32_t screen_x, screen_y; // screen position (mouse events) - uint32_t client_x, client_y; // client position (mouse events) - float delta_x, delta_y; // movement delta (MOUSE_MOVE only) - float wheel_delta; // MOUSE_WHEEL only (>0 - up, <0 - down) - float analog_value; // ANALOG only (trigger value range: 0.0 .. 1.0, stick value range: -1.0 .. 1.0) -}; - -#define KEYBIND_MAX_KEYS (10) - -#ifdef __cplusplus -# define KEYBIND_NULL (keybind_t){} -#else -# define KEYBIND_NULL (keybind_t){.keys = {0}, .count = 0} -#endif - -typedef struct keybind_s keybind_t; -struct keybind_s { - input_key_kind_t keys[KEYBIND_MAX_KEYS]; - uint8_t count; -}; - -/* ===================================================== UNREAL ===================================================== */ - -#define UNREAL_CALL __fastcall - -typedef struct fframe_s fframe_t; -typedef struct uobject_s uobject_t; -typedef struct ufunc_s ufunc_t; -typedef struct uclass_s uclass_t; -typedef struct uworld_s uworld_t; -typedef struct fname_pool_s fname_pool_t; -typedef struct fuobject_array_s fuobject_array_t; -typedef struct fname_s fname_t; - -typedef enum { - UOBJECT_LISTENER_KIND_CREATE, - UOBJECT_LISTENER_KIND_DELETE, -} uobject_listener_kind_t; - -typedef int efind_name_t; -enum { - FNAME_FIND, - FNAME_FIND_OR_ADD, - FNAME_REPLACE_NOT_SAFE_FOR_THREADING, -}; - -typedef struct fname_s fname_t; -struct fname_s { - uint32_t cmp_idx; - uint32_t num; -}; -MOD_STATIC_ASSERT(sizeof(fname_t) == 8, "size mismatch"); - -typedef void (UNREAL_CALL *fnative_func_ptr_t) (uobject_t *context, fframe_t *stack, void *result); -typedef void (MOD_CALL *uobject_notify_cb_t)(uobject_t *obj, int32_t idx, void *user); - -/* ===================================================== STRING ===================================================== */ - -/* UTF-8 string */ -typedef struct str_s str_t; -struct str_s { - uint8_t *data; - uint64_t len; -}; - -/* UTF-16 string */ -typedef struct str16_s str16_t; -struct str16_s { - uint16_t *data; - uint64_t len; -}; - -/* ===================================================== SIGSCAN ==================================================== */ - -typedef int sigscan_err_t; -enum { - SIGSCAN_ERR_OK = 0, - SIGSCAN_ERR_INVALID_PATTERN = -1, - SIGSCAN_ERR_TARGET_NOT_READABLE = -2, - SIGSCAN_ERR_NOT_FOUND = -3, -}; - -/* ===================================================== ARENA ====================================================== */ -#define MOD_ARENA_INVALID ((mod_arena_t)0) - -typedef uint64_t mod_arena_t; - -typedef struct tmp_arena_s tmp_arena_t; -struct tmp_arena_s { - mod_arena_t arena; - uint64_t pos; -}; - -/* ====================================================== MOD ======================================================= */ - -#define MOD_INVALID ((mod_t)0) -#define MOD_CFG_INVALID ((mod_cfg_t)0) - -typedef uint64_t mod_t; -typedef uint64_t mod_cfg_t; - -typedef int log_level_t; -enum { - LOG_LEVEL_DEBUG = 0, - LOG_LEVEL_INFO = 1, - LOG_LEVEL_WARN = 2, - LOG_LEVEL_ERROR = 3, -}; - -#define MAKE_VERSION(MAJOR, MINOR, PATCH) \ - { \ - .major = MAJOR, \ - .minor = MINOR, \ - .patch = PATCH, \ - } - -typedef struct mod_version_s mod_version_t; -struct mod_version_s { - uint16_t major; - uint16_t minor; - uint32_t patch; -}; - -typedef struct mod_color_s mod_color_t; -struct mod_color_s { - uint8_t r, g, b, a; -}; - -typedef struct nk_context nk_context_t; - -typedef struct mod_host_api_s mod_host_api_t; - -typedef void (MOD_CALL *mod_tick_fn_t) (mod_t m, float delta); -typedef bool (MOD_CALL *mod_input_fn_t) (mod_t m, input_event_t *ev); - -typedef bool (MOD_CALL *mod_pe_pre_fn_t) (mod_t m, uobject_t *obj, ufunc_t *func, void *params); -typedef void (MOD_CALL *mod_pe_post_fn_t)(mod_t m, uobject_t *obj, ufunc_t *func, void *params, bool consumed); - -typedef bool (MOD_CALL *mod_func_invoke_pre_fn_t) (mod_t m, ufunc_t *func, uobject_t *obj, fframe_t *stack, void *result); -typedef void (MOD_CALL *mod_func_invoke_post_fn_t)(mod_t m, ufunc_t *func, uobject_t *obj, fframe_t *stack, void *result, bool consumed); - -typedef void (MOD_CALL *mod_draw_panel_fn_t) (mod_t m, struct nk_context *ctx); -typedef void (MOD_CALL *mod_draw_config_fn_t)(mod_t m, struct nk_context *ctx); - -typedef bool (MOD_CALL *mod_init_fn_t) (const mod_host_api_t *host, mod_t m); -typedef void (MOD_CALL *mod_deinit_fn_t)(mod_t m); - -typedef void (MOD_CALL *mod_cmd_fn_t)(mod_t m, str_t name, str_t args, void *user); - -#define MOD_ABI_VERSION MAKE_VERSION(1, 1, 0) - -typedef struct mod_api_s mod_api_t; -struct mod_api_s { - uint32_t struct_size; - mod_version_t abi_version; - mod_init_fn_t init; - mod_deinit_fn_t deinit; - mod_tick_fn_t tick; - mod_input_fn_t input; - mod_pe_pre_fn_t pe_pre; - mod_pe_post_fn_t pe_post; - mod_func_invoke_pre_fn_t func_invoke_pre; - mod_func_invoke_post_fn_t func_invoke_post; - mod_draw_panel_fn_t draw_panel; - mod_draw_config_fn_t draw_config; -}; - -typedef const mod_api_t *(MOD_CALL *mod_entry_fn_t)(void); - -struct mod_host_api_s { - uint32_t struct_size; - mod_version_t abi_version; - - /* MOD */ - - str_t (MOD_CALL *get_mod_dir) (mod_t m); - str_t (MOD_CALL *get_config_path) (mod_t m); - str_t (MOD_CALL *get_manifest_path)(mod_t m); - void (MOD_CALL *logv) (mod_t m, log_level_t level, const char *fmt, va_list args); - mod_cfg_t (MOD_CALL *get_cfg_by_id) (mod_t m, str_t id); - bool (MOD_CALL *register_cmd) (mod_t m, str_t name, str_t description, mod_cmd_fn_t fn, void *user); - - /* UI */ - struct nk_context *(MOD_CALL *get_nk_ctx) (void); - void (MOD_CALL *get_viewport_size)(unsigned int *vw, unsigned int *vh); - - /* MOD CONFIGURATION */ - - void (MOD_CALL *cfg_get_bool) (mod_cfg_t h, bool *val); - void (MOD_CALL *cfg_get_int) (mod_cfg_t h, int *val); - void (MOD_CALL *cfg_get_float) (mod_cfg_t h, float *val); - void (MOD_CALL *cfg_get_enum) (mod_cfg_t h, int *val); - void (MOD_CALL *cfg_get_string_len) (mod_cfg_t h, uint64_t *len); - void (MOD_CALL *cfg_get_string_data)(mod_cfg_t h, void *buf, uint64_t cap, uint64_t *written); - void (MOD_CALL *cfg_get_keybind) (mod_cfg_t h, keybind_t *val); - void (MOD_CALL *cfg_get_color) (mod_cfg_t h, mod_color_t *val); - void (MOD_CALL *cfg_set_bool) (mod_cfg_t h, bool val); - void (MOD_CALL *cfg_set_int) (mod_cfg_t h, int val); - void (MOD_CALL *cfg_set_float) (mod_cfg_t h, float val); - void (MOD_CALL *cfg_set_enum) (mod_cfg_t h, int val); - void (MOD_CALL *cfg_set_string) (mod_cfg_t h, str_t val); - void (MOD_CALL *cfg_set_keybind) (mod_cfg_t h, keybind_t val); - void (MOD_CALL *cfg_set_color) (mod_cfg_t h, mod_color_t val); - - /* MEMORY ALLOCATION */ - - mod_arena_t (MOD_CALL *get_perm) (mod_t h); - mod_arena_t (MOD_CALL *arena_create) (mod_t h, uint64_t reserve_size, uint64_t commit_size); - void (MOD_CALL *arena_destroy)(mod_t h, mod_arena_t arena_h); - void *(MOD_CALL *arena_push) (mod_arena_t h, uint64_t size, uint64_t alignment); - uint64_t (MOD_CALL *arena_pos) (mod_arena_t h); - void (MOD_CALL *arena_pop_to) (mod_arena_t h, uint64_t pos); - void (MOD_CALL *arena_reset) (mod_arena_t h); - tmp_arena_t (MOD_CALL *scratch_begin)(mod_arena_t conflict); - void (MOD_CALL *scratch_end) (tmp_arena_t s); - - /* UNREAL ENGINE */ - - fname_pool_t *(MOD_CALL *get_name_pool) (void); - fuobject_array_t *(MOD_CALL *get_object_array) (void); - uworld_t **(MOD_CALL *get_gworld_ptr) (void); - void (MOD_CALL *process_event) (uobject_t *self, ufunc_t *func, void *params); - uclass_t *(MOD_CALL *static_load_class) (uclass_t *base_cls, uobject_t *outer, str_t name, str_t filename, uint32_t load_flags); - bool (MOD_CALL *mount_pak) (str_t file_path, int order); - bool (MOD_CALL *mount_iostore) (str_t file_path, int order); - fname_t (MOD_CALL *fname_from_str) (str_t str, efind_name_t find_type); - uint64_t (MOD_CALL *fname_utf8_len) (fname_t fname); - uint64_t (MOD_CALL *fname_utf8_write) (fname_t fname, void *buf, uint64_t cap); - void *(MOD_CALL *get_mcast_sparse_delegate)(uobject_t *delegate_owner, fname_t delegate_name); - fnative_func_ptr_t (MOD_CALL *get_native) (uint8_t opcode); - - /* INPUT EVENTS / KEYBINDS */ - - input_key_kind_t (MOD_CALL *input_key_from_str) (str_t name); - str_t (MOD_CALL *input_key_to_str) (input_key_kind_t key); - str_t (MOD_CALL *input_event_kind_to_str)(input_event_kind_t kind); - bool (MOD_CALL *keybind_parse) (str_t str, keybind_t *out); - uint64_t (MOD_CALL *keybind_utf8_len) (keybind_t bind); - uint64_t (MOD_CALL *keybind_utf8_write) (keybind_t bind, void *buf, uint64_t cap); - bool (MOD_CALL *keybind_is_down) (keybind_t bind); - bool (MOD_CALL *keybind_is_pressed) (keybind_t bind); - bool (MOD_CALL *keybind_is_released) (keybind_t bind); - - /* UOBJECT CREATE/DELETE LISTENERS */ - - bool (MOD_CALL *register_uobject_listener) (mod_t m, int kind, uobject_notify_cb_t notify_cb, void *user); - void (MOD_CALL *deregister_uobject_listener)(mod_t m, int kind, uobject_notify_cb_t notify_cb, void *user); - - /* HOOKING / SIGNATURE SCANNING */ - - sigscan_err_t (MOD_CALL *sigscan) (const char *name, const char *pattern, uint8_t op_offset, uint8_t num_deref, - uintptr_t first_rvas_to_try[8], void **result); - bool (MOD_CALL *hook_create) (mod_t m, void *target, void *detour, void **original); - bool (MOD_CALL *hook_enable) (mod_t m, void *target); - bool (MOD_CALL *hook_disable)(mod_t m, void *target); - bool (MOD_CALL *hook_remove) (mod_t m, void *target); - - /* UNREAL ENGINE (CONT.) */ - void (MOD_CALL *map_add) (void *map, void *prop, const void *key, const void *val); - bool (MOD_CALL *map_remove) (void *map, void *prop, const void *key); - bool (MOD_CALL *map_find) (void *map, void *prop, const void *key, void *out_val); - uobject_t *(MOD_CALL *static_load_object) (uclass_t *obj_cls, uobject_t *outer, str_t name, str_t filename, uint32_t load_flags, void *sandbox, bool allow_obj_reconcile, void *instancing_ctx); - uobject_t *(MOD_CALL *static_construct_object) (void *params); - bool (MOD_CALL *add_gameplay_tag) (fname_t tag_name); - bool (MOD_CALL *check_gameplay_tag_exists)(fname_t tag_name); - - uint64_t (MOD_CALL *get_frame_counter)(void); - float (MOD_CALL *get_fps)(void); -}; -MOD_STATIC_ASSERT(sizeof(mod_host_api_t) == 0x238, "invalid host API size"); - -#ifdef __cplusplus -} -#endif - -#endif /* MOD_API_H */ - diff --git a/mod/mod_nuklear.c b/mod/mod_nuklear.c deleted file mode 100644 index 5348f4a..0000000 --- a/mod/mod_nuklear.c +++ /dev/null @@ -1,30202 +0,0 @@ -#include "mod_nuklear.h" - -#ifndef NK_PROFILE_SCOPE_BEGIN -# define NK_PROFILE_SCOPE_BEGIN(NAME, SCOPE) -#endif - -#ifndef NK_PROFILE_SCOPE_END -# define NK_PROFILE_SCOPE_END(SCOPE) -#endif - -/* =============================================================== - * - * MATH - * - * ===============================================================*/ -/*/// ### Math -/// Since nuklear is supposed to work on all systems providing floating point -/// math without any dependencies I also had to implement my own math functions -/// for sqrt, sin and cos. Since the actual highly accurate implementations for -/// the standard library functions are quite complex and I do not need high -/// precision for my use cases I use approximations. -/// -/// Sqrt -/// ---- -/// For square root nuklear uses the famous fast inverse square root: -/// https://en.wikipedia.org/wiki/Fast_inverse_square_root with -/// slightly tweaked magic constant. While on today's hardware it is -/// probably not faster it is still fast and accurate enough for -/// nuklear's use cases. IMPORTANT: this requires float format IEEE 754 -/// -/// Sine/Cosine -/// ----------- -/// All constants inside both function are generated Remez's minimax -/// approximations for value range 0...2*PI. The reason why I decided to -/// approximate exactly that range is that nuklear only needs sine and -/// cosine to generate circles which only requires that exact range. -/// In addition I used Remez instead of Taylor for additional precision: -/// www.lolengine.net/blog/2011/12/21/better-function-approximations. -/// -/// The tool I used to generate constants for both sine and cosine -/// (it can actually approximate a lot more functions) can be -/// found here: www.lolengine.net/wiki/oss/lolremez -*/ -#ifdef NK_INV_SQRT_NEEDED -NK_LIB float -nk_inv_sqrt(float n) -{ - float x2; - const float threehalfs = 1.5f; - union { - nk_uint i; - float f; - } conv = {0}; - conv.f = n; - x2 = n * 0.5f; - conv.i = 0x5f375A84 - (conv.i >> 1); - conv.f = conv.f * (threehalfs - (x2 * conv.f * conv.f)); - return conv.f; -} -#endif -#ifdef NK_SIN_NEEDED -NK_LIB float -nk_sin(float x) -{ - NK_STORAGE const float a0 = +1.91059300966915117e-31f; - NK_STORAGE const float a1 = +1.00086760103908896f; - NK_STORAGE const float a2 = -1.21276126894734565e-2f; - NK_STORAGE const float a3 = -1.38078780785773762e-1f; - NK_STORAGE const float a4 = -2.67353392911981221e-2f; - NK_STORAGE const float a5 = +2.08026600266304389e-2f; - NK_STORAGE const float a6 = -3.03996055049204407e-3f; - NK_STORAGE const float a7 = +1.38235642404333740e-4f; - return a0 + x * (a1 + x * (a2 + x * (a3 + x * (a4 + x * (a5 + x * (a6 + x * a7)))))); -} -#endif -#ifdef NK_COS_NEEDED -NK_LIB float -nk_cos(float x) -{ - /* New implementation. Also generated using lolremez. */ - /* Old version significantly deviated from expected results. */ - NK_STORAGE const float a0 = 9.9995999154986614e-1f; - NK_STORAGE const float a1 = 1.2548995793001028e-3f; - NK_STORAGE const float a2 = -5.0648546280678015e-1f; - NK_STORAGE const float a3 = 1.2942246466519995e-2f; - NK_STORAGE const float a4 = 2.8668384702547972e-2f; - NK_STORAGE const float a5 = 7.3726485210586547e-3f; - NK_STORAGE const float a6 = -3.8510875386947414e-3f; - NK_STORAGE const float a7 = 4.7196604604366623e-4f; - NK_STORAGE const float a8 = -1.8776444013090451e-5f; - return a0 + x * (a1 + x * (a2 + x * (a3 + x * (a4 + x * (a5 + x * (a6 + x * (a7 + x * a8))))))); -} -#endif -#ifdef NK_ATAN_NEEDED -NK_LIB float -nk_atan(float x) -{ - /* ./lolremez --progress --float -d 9 -r "0:pi*2" "atan(x)" */ - float u = -1.0989005e-05f; - NK_ASSERT(x >= 0.0f && "TODO support negative floats"); - u = u * x + 0.00034117949f; - u = u * x + -0.0044932296f; - u = u * x + 0.032596264f; - u = u * x + -0.14088021f; - u = u * x + 0.36040401f; - u = u * x + -0.47017866f; - u = u * x + 0.00050198776f; - u = u * x + 1.0077682f; - u = u * x + -0.0004765437f; - return u; -} -#endif -#ifdef NK_ATAN2_NEEDED -NK_LIB float -nk_atan2(float y, float x) -{ - float ax = NK_ABS(x), ay = NK_ABS(y); - /* 0 = +y +x 1 = -y +x - 2 = +y -x 3 = -y -x */ - nk_uint signs = (y < 0) | ((x < 0) << 1); - - float a; - if (y == 0.0 && x == 0.0) { - return 0.0f; - } - a = (ay > ax) ? NK_PI_HALF - NK_ATAN(ax / ay) : NK_ATAN(ay / ax); - - switch (signs) { - case 0: - return a; - case 1: - return -a; - case 2: - return -a + NK_PI; - case 3: - return a - NK_PI; - } - return 0.0f; /* prevents warning */ -} -#endif -NK_LIB nk_uint -nk_round_up_pow2(nk_uint v) -{ - v--; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v++; - return v; -} -#ifdef NK_DTOA_NEEDED -NK_LIB double -nk_pow(double x, int n) -{ - /* check the sign of n */ - double r = 1; - int plus = n >= 0; - n = (plus) ? n : -n; - while (n > 0) { - if ((n & 1) == 1) { - r *= x; - } - n /= 2; - x *= x; - } - return plus ? r : 1.0 / r; -} -#endif -#ifdef NK_DTOA_NEEDED -NK_LIB int -nk_ifloord(double x) -{ - x = (double)((int)x - ((x < 0.0) ? 1 : 0)); - return (int)x; -} -#endif -NK_LIB int -nk_ifloorf(float x) -{ - x = (float)((int)x - ((x < 0.0f) ? 1 : 0)); - return (int)x; -} -NK_LIB int -nk_iceilf(float x) -{ - if (x >= 0) { - int i = (int)x; - return (x > i) ? i + 1 : i; - } else { - int t = (int)x; - float r = x - (float)t; - return (r > 0.0f) ? t + 1 : t; - } -} -#ifdef NK_DTOA_NEEDED -NK_LIB int -nk_log10(double n) -{ - int neg; - int ret; - int exp = 0; - - neg = (n < 0) ? 1 : 0; - ret = (neg) ? (int)-n : (int)n; - while ((ret / 10) > 0) { - ret /= 10; - exp++; - } - if (neg) { - exp = -exp; - } - return exp; -} -#endif -NK_LIB float -nk_roundf(float x) -{ - return (x >= 0.0f) ? (float)nk_ifloorf(x + 0.5f) : (float)nk_iceilf(x - 0.5f); -} -NK_API struct nk_rect -nk_get_null_rect(void) -{ - return nk_null_rect; -} -NK_API struct nk_rect -nk_rect(float x, float y, float w, float h) -{ - struct nk_rect r; - r.x = x; - r.y = y; - r.w = w; - r.h = h; - return r; -} -NK_API struct nk_rect -nk_recti(int x, int y, int w, int h) -{ - struct nk_rect r; - r.x = (float)x; - r.y = (float)y; - r.w = (float)w; - r.h = (float)h; - return r; -} -NK_API struct nk_rect -nk_recta(struct nk_vec2 pos, struct nk_vec2 size) -{ - return nk_rect(pos.x, pos.y, size.x, size.y); -} -NK_API struct nk_rect -nk_rectv(const float *r) -{ - return nk_rect(r[0], r[1], r[2], r[3]); -} -NK_API struct nk_rect -nk_rectiv(const int *r) -{ - return nk_recti(r[0], r[1], r[2], r[3]); -} -NK_API struct nk_vec2 -nk_rect_pos(struct nk_rect r) -{ - struct nk_vec2 ret; - ret.x = r.x; - ret.y = r.y; - return ret; -} -NK_API struct nk_vec2 -nk_rect_size(struct nk_rect r) -{ - struct nk_vec2 ret; - ret.x = r.w; - ret.y = r.h; - return ret; -} -NK_LIB struct nk_rect -nk_shrink_rect(struct nk_rect r, float amount) -{ - struct nk_rect res; - r.w = NK_MAX(r.w, 2 * amount); - r.h = NK_MAX(r.h, 2 * amount); - res.x = r.x + amount; - res.y = r.y + amount; - res.w = r.w - 2 * amount; - res.h = r.h - 2 * amount; - return res; -} -NK_LIB struct nk_rect -nk_pad_rect(struct nk_rect r, struct nk_vec2 pad) -{ - r.w = NK_MAX(r.w, 2 * pad.x); - r.h = NK_MAX(r.h, 2 * pad.y); - r.x += pad.x; - r.y += pad.y; - r.w -= 2 * pad.x; - r.h -= 2 * pad.y; - return r; -} -NK_API struct nk_vec2 -nk_vec2(float x, float y) -{ - struct nk_vec2 ret; - ret.x = x; - ret.y = y; - return ret; -} -NK_API struct nk_vec2 -nk_vec2i(int x, int y) -{ - struct nk_vec2 ret; - ret.x = (float)x; - ret.y = (float)y; - return ret; -} -NK_API struct nk_vec2 -nk_vec2v(const float *v) -{ - return nk_vec2(v[0], v[1]); -} -NK_API struct nk_vec2 -nk_vec2iv(const int *v) -{ - return nk_vec2i(v[0], v[1]); -} -NK_LIB void -nk_unify(struct nk_rect *clip, const struct nk_rect *a, float x0, float y0, float x1, float y1) -{ - NK_ASSERT(a != NULL); - NK_ASSERT(clip != NULL); - clip->x = NK_MAX(a->x, x0); - clip->y = NK_MAX(a->y, y0); - clip->w = NK_MIN(a->x + a->w, x1) - clip->x; - clip->h = NK_MIN(a->y + a->h, y1) - clip->y; - clip->w = NK_MAX(0, clip->w); - clip->h = NK_MAX(0, clip->h); -} - -NK_API void -nk_triangle_from_direction(struct nk_vec2 *result, struct nk_rect r, float pad_x, float pad_y, enum nk_heading direction) -{ - float w_half, h_half; - NK_ASSERT(result != NULL); - - r.w = NK_MAX(2 * pad_x, r.w); - r.h = NK_MAX(2 * pad_y, r.h); - r.w = r.w - 2 * pad_x; - r.h = r.h - 2 * pad_y; - - r.x = r.x + pad_x; - r.y = r.y + pad_y; - - w_half = r.w / 2.0f; - h_half = r.h / 2.0f; - - if (direction == NK_UP) { - result[0] = nk_vec2(r.x + w_half, r.y); - result[1] = nk_vec2(r.x + r.w, r.y + r.h); - result[2] = nk_vec2(r.x, r.y + r.h); - } else if (direction == NK_RIGHT) { - result[0] = nk_vec2(r.x, r.y); - result[1] = nk_vec2(r.x + r.w, r.y + h_half); - result[2] = nk_vec2(r.x, r.y + r.h); - } else if (direction == NK_DOWN) { - result[0] = nk_vec2(r.x, r.y); - result[1] = nk_vec2(r.x + r.w, r.y); - result[2] = nk_vec2(r.x + w_half, r.y + r.h); - } else { - result[0] = nk_vec2(r.x, r.y + h_half); - result[1] = nk_vec2(r.x + r.w, r.y); - result[2] = nk_vec2(r.x + r.w, r.y + r.h); - } -} - -/* =============================================================== - * - * UTIL - * - * ===============================================================*/ -NK_INTERN int -nk_str_match_here(const char *regexp, const char *text); -NK_INTERN int -nk_str_match_star(int c, const char *regexp, const char *text); -NK_LIB nk_bool -nk_is_lower(int c) -{ - return (c >= 'a' && c <= 'z') || (c >= 0xE0 && c <= 0xFF); -} -NK_LIB nk_bool -nk_is_upper(int c) -{ - return (c >= 'A' && c <= 'Z') || (c >= 0xC0 && c <= 0xDF); -} -NK_LIB int -nk_to_upper(int c) -{ - return (c >= 'a' && c <= 'z') ? (c - ('a' - 'A')) : c; -} -NK_LIB int -nk_to_lower(int c) -{ - return (c >= 'A' && c <= 'Z') ? (c - ('a' + 'A')) : c; -} - -#ifdef NK_MEMCPY_NEEDED -NK_LIB void * -nk_memcopy(void *dst0, const void *src0, nk_size length) -{ - nk_ptr t; - char *dst = (char *)dst0; - const char *src = (const char *)src0; - if (length == 0 || dst == src) { - goto done; - } - -# define nk_word int -# define nk_wsize sizeof(nk_word) -# define nk_wmask (nk_wsize - 1) -# define NK_TLOOP(s) \ - if (t) \ - NK_TLOOP1(s) -# define NK_TLOOP1(s) \ - do { \ - s; \ - } while (--t) - - if (dst < src) { - t = (nk_ptr)src; /* only need low bits */ - if ((t | (nk_ptr)dst) & nk_wmask) { - if ((t ^ (nk_ptr)dst) & nk_wmask || length < nk_wsize) { - t = length; - } else { - t = nk_wsize - (t & nk_wmask); - } - length -= t; - NK_TLOOP1(*dst++ = *src++); - } - t = length / nk_wsize; - NK_TLOOP(*(nk_word *)(void *)dst = *(const nk_word *)(const void *)src; src += nk_wsize; dst += nk_wsize); - t = length & nk_wmask; - NK_TLOOP(*dst++ = *src++); - } else { - src += length; - dst += length; - t = (nk_ptr)src; - if ((t | (nk_ptr)dst) & nk_wmask) { - if ((t ^ (nk_ptr)dst) & nk_wmask || length <= nk_wsize) { - t = length; - } else { - t &= nk_wmask; - } - length -= t; - NK_TLOOP1(*--dst = *--src); - } - t = length / nk_wsize; - NK_TLOOP(src -= nk_wsize; dst -= nk_wsize; *(nk_word *)(void *)dst = *(const nk_word *)(const void *)src); - t = length & nk_wmask; - NK_TLOOP(*--dst = *--src); - } -# undef nk_word -# undef nk_wsize -# undef nk_wmask -# undef NK_TLOOP -# undef NK_TLOOP1 -done: - return (dst0); -} -#endif -#ifdef NK_MEMSET_NEEDED -NK_LIB void -nk_memset(void *ptr, int c0, nk_size size) -{ -# define nk_word unsigned -# define nk_wsize sizeof(nk_word) -# define nk_wmask (nk_wsize - 1) - nk_byte *dst = (nk_byte *)ptr; - unsigned c = 0; - nk_size t = 0; - - if ((c = (nk_byte)c0) != 0) { - c = (c << 8) | c; /* at least 16-bits */ - if (sizeof(unsigned int) > 2) { - c = (c << 16) | c; /* at least 32-bits*/ - } - } - - /* too small of a word count */ - dst = (nk_byte *)ptr; - if (size < 3 * nk_wsize) { - while (size--) { - *dst++ = (nk_byte)c0; - } - return; - } - - /* align destination */ - if ((t = NK_PTR_TO_UINT(dst) & nk_wmask) != 0) { - t = nk_wsize - t; - size -= t; - do { - *dst++ = (nk_byte)c0; - } while (--t != 0); - } - - /* fill word */ - t = size / nk_wsize; - do { - *(nk_word *)((void *)dst) = c; - dst += nk_wsize; - } while (--t != 0); - - /* fill trailing bytes */ - t = (size & nk_wmask); - if (t != 0) { - do { - *dst++ = (nk_byte)c0; - } while (--t != 0); - } - -# undef nk_word -# undef nk_wsize -# undef nk_wmask -} -#endif -NK_LIB void -nk_zero(void *ptr, nk_size size) -{ - NK_ASSERT(ptr); - NK_MEMSET(ptr, 0, size); -} -NK_API int -nk_strlen(const char *str) -{ - int siz = 0; - NK_ASSERT(str); - while (str && *str++ != '\0') { - siz++; - } - return siz; -} -NK_API int -nk_strtoi(const char *str, char **endptr) -{ - int neg = 1; - const char *p = str; - int value = 0; - - NK_ASSERT(str); - if (!str) { - return 0; - } - - /* skip whitespace */ - while (*p == ' ') { - p++; - } - if (*p == '-') { - neg = -1; - p++; - } - while (*p && *p >= '0' && *p <= '9') { - value = value * 10 + (int)(*p - '0'); - p++; - } - if (endptr) { - *endptr = (char *)p; - } - return neg * value; -} -#ifdef NK_STRTOD_NEEDED -NK_API double -nk_strtod(const char *str, char **endptr) -{ - double m; - double neg = 1.0; - char *p = (char *)str; - double value = 0; - double number = 0; - - NK_ASSERT(str); - if (!str) { - return 0; - } - - /* skip whitespace */ - while (*p == ' ') { - p++; - } - if (*p == '-') { - neg = -1.0; - p++; - } - - while (*p && *p != '.' && *p != 'e') { - value = value * 10.0 + (double)(*p - '0'); - p++; - } - - if (*p == '.') { - p++; - for (m = 0.1; *p && *p != 'e'; p++) { - value = value + (double)(*p - '0') * m; - m *= 0.1; - } - } - if (*p == 'e') { - int i, pow, div; - p++; - if (*p == '-') { - div = nk_true; - p++; - } else if (*p == '+') { - div = nk_false; - p++; - } else { - div = nk_false; - } - - for (pow = 0; *p; p++) { - pow = pow * 10 + (int)(*p - '0'); - } - - for (m = 1.0, i = 0; i < pow; i++) { - m *= 10.0; - } - - if (div) { - value /= m; - } else { - value *= m; - } - } - number = value * neg; - if (endptr) { - *endptr = (char *)p; - } - return number; -} -#endif -NK_API float -nk_strtof(const char *str, char **endptr) -{ - float float_value; - double double_value; - double_value = NK_STRTOD(str, endptr); - float_value = (float)double_value; - return float_value; -} -NK_API int -nk_stricmp(const char *s1, const char *s2) -{ - nk_int c1, c2, d; - do { - c1 = *s1++; - c2 = *s2++; - d = c1 - c2; - while (d) { - if (c1 <= 'Z' && c1 >= 'A') { - d += ('a' - 'A'); - if (!d) { - break; - } - } - if (c2 <= 'Z' && c2 >= 'A') { - d -= ('a' - 'A'); - if (!d) { - break; - } - } - return ((d >= 0) << 1) - 1; - } - } while (c1); - return 0; -} -NK_API int -nk_stricmpn(const char *s1, const char *s2, int n) -{ - int c1, c2, d; - NK_ASSERT(n >= 0); - do { - c1 = *s1++; - c2 = *s2++; - if (!n--) { - return 0; - } - - d = c1 - c2; - while (d) { - if (c1 <= 'Z' && c1 >= 'A') { - d += ('a' - 'A'); - if (!d) { - break; - } - } - if (c2 <= 'Z' && c2 >= 'A') { - d -= ('a' - 'A'); - if (!d) { - break; - } - } - return ((d >= 0) << 1) - 1; - } - } while (c1); - return 0; -} -NK_INTERN int -nk_str_match_here(const char *regexp, const char *text) -{ - if (regexp[0] == '\0') { - return 1; - } - if (regexp[1] == '*') { - return nk_str_match_star(regexp[0], regexp + 2, text); - } - if (regexp[0] == '$' && regexp[1] == '\0') { - return *text == '\0'; - } - if (*text != '\0' && (regexp[0] == '.' || regexp[0] == *text)) { - return nk_str_match_here(regexp + 1, text + 1); - } - return 0; -} -NK_INTERN int -nk_str_match_star(int c, const char *regexp, const char *text) -{ - do { /* a '* matches zero or more instances */ - if (nk_str_match_here(regexp, text)) { - return 1; - } - } while (*text != '\0' && (*text++ == c || c == '.')); - return 0; -} -NK_API int -nk_strfilter(const char *text, const char *regexp) -{ - /* - c matches any literal character c - . matches any single character - ^ matches the beginning of the input string - $ matches the end of the input string - * matches zero or more occurrences of the previous character*/ - if (regexp[0] == '^') { - return nk_str_match_here(regexp + 1, text); - } - do { /* must look even if string is empty */ - if (nk_str_match_here(regexp, text)) { - return 1; - } - } while (*text++ != '\0'); - return 0; -} -NK_API int -nk_strmatch_fuzzy_text(const char *str, int str_len, const char *pattern, int *out_score) -{ -/* Returns true if each character in pattern is found sequentially within str - * if found then out_score is also set. Score value has no intrinsic meaning. - * Range varies with pattern. Can only compare scores with same search pattern. */ - -/* bonus for adjacent matches */ -#define NK_ADJACENCY_BONUS 5 -/* bonus if match occurs after a separator */ -#define NK_SEPARATOR_BONUS 10 -/* bonus if match is uppercase and prev is lower */ -#define NK_CAMEL_BONUS 10 -/* penalty applied for every letter in str before the first match */ -#define NK_LEADING_LETTER_PENALTY (-3) -/* maximum penalty for leading letters */ -#define NK_MAX_LEADING_LETTER_PENALTY (-9) -/* penalty for every letter that doesn't matter */ -#define NK_UNMATCHED_LETTER_PENALTY (-1) - - /* loop variables */ - int score = 0; - char const *pattern_iter = pattern; - int str_iter = 0; - int prev_matched = nk_false; - int prev_lower = nk_false; - /* true so if first letter match gets separator bonus*/ - int prev_separator = nk_true; - - /* use "best" matched letter if multiple string letters match the pattern */ - char const *best_letter = 0; - int best_letter_score = 0; - - /* loop over strings */ - NK_ASSERT(str); - NK_ASSERT(pattern); - if (!str || !str_len || !pattern) { - return 0; - } - while (str_iter < str_len) { - const char pattern_letter = *pattern_iter; - const char str_letter = str[str_iter]; - - int next_match = *pattern_iter != '\0' && nk_to_lower(pattern_letter) == nk_to_lower(str_letter); - int rematch = best_letter && nk_to_upper(*best_letter) == nk_to_upper(str_letter); - - int advanced = next_match && best_letter; - int pattern_repeat = best_letter && *pattern_iter != '\0'; - pattern_repeat = pattern_repeat && nk_to_lower(*best_letter) == nk_to_lower(pattern_letter); - - if (advanced || pattern_repeat) { - score += best_letter_score; - best_letter = 0; - best_letter_score = 0; - } - - if (next_match || rematch) { - int new_score = 0; - /* Apply penalty for each letter before the first pattern match */ - if (pattern_iter == pattern) { - int count = (int)(&str[str_iter] - str); - int penalty = NK_LEADING_LETTER_PENALTY * count; - if (penalty < NK_MAX_LEADING_LETTER_PENALTY) { - penalty = NK_MAX_LEADING_LETTER_PENALTY; - } - - score += penalty; - } - - /* apply bonus for consecutive bonuses */ - if (prev_matched) { - new_score += NK_ADJACENCY_BONUS; - } - - /* apply bonus for matches after a separator */ - if (prev_separator) { - new_score += NK_SEPARATOR_BONUS; - } - - /* apply bonus across camel case boundaries */ - if (prev_lower && nk_is_upper(str_letter)) { - new_score += NK_CAMEL_BONUS; - } - - /* update pattern iter IFF the next pattern letter was matched */ - if (next_match) { - ++pattern_iter; - } - - /* update best letter in str which may be for a "next" letter or a rematch */ - if (new_score >= best_letter_score) { - /* apply penalty for now skipped letter */ - if (best_letter != 0) { - score += NK_UNMATCHED_LETTER_PENALTY; - } - - best_letter = &str[str_iter]; - best_letter_score = new_score; - } - prev_matched = nk_true; - } else { - score += NK_UNMATCHED_LETTER_PENALTY; - prev_matched = nk_false; - } - - /* separators should be more easily defined */ - prev_lower = nk_is_lower(str_letter) != 0; - prev_separator = str_letter == '_' || str_letter == ' '; - - ++str_iter; - } - - /* apply score for last match */ - if (best_letter) { - score += best_letter_score; - } - - /* did not match full pattern */ - if (*pattern_iter != '\0') { - return nk_false; - } - - if (out_score) { - *out_score = score; - } - return nk_true; -} -NK_API int -nk_strmatch_fuzzy_string(char const *str, char const *pattern, int *out_score) -{ - return nk_strmatch_fuzzy_text(str, nk_strlen(str), pattern, out_score); -} -NK_LIB int -nk_string_float_limit(char *string, int prec) -{ - int dot = 0; - char *c = string; - while (*c) { - if (*c == '.') { - dot = 1; - c++; - continue; - } - if (dot == (prec + 1)) { - *c = 0; - break; - } - if (dot > 0) { - dot++; - } - c++; - } - return (int)(c - string); -} -NK_INTERN void -nk_strrev_ascii(char *s) -{ - int len = nk_strlen(s); - int end = len / 2; - int i = 0; - char t; - for (; i < end; ++i) { - t = s[i]; - s[i] = s[len - 1 - i]; - s[len - 1 - i] = t; - } -} -NK_LIB char * -nk_itoa(char *s, long n) -{ - long i = 0; - if (n == 0) { - s[i++] = '0'; - s[i] = 0; - return s; - } - if (n < 0) { - s[i++] = '-'; - n = -n; - } - while (n > 0) { - s[i++] = (char)('0' + (n % 10)); - n /= 10; - } - s[i] = 0; - if (s[0] == '-') { - ++s; - } - - nk_strrev_ascii(s); - return s; -} -#ifdef NK_DTOA_NEEDED -NK_LIB char * -nk_dtoa(char *s, double n) -{ - int useExp = 0; - int digit = 0, m = 0, m1 = 0; - char *c = s; - int neg = 0; - - NK_ASSERT(s); - if (!s) { - return 0; - } - - if (n == 0.0) { - s[0] = '0'; - s[1] = '\0'; - return s; - } - - neg = (n < 0); - if (neg) { - n = -n; - } - - /* calculate magnitude */ - m = nk_log10(n); - useExp = (m >= 14 || (neg && m >= 9) || m <= -9); - if (neg) { - *(c++) = '-'; - } - - /* set up for scientific notation */ - if (useExp) { - if (m < 0) { - m -= 1; - } - n = n / (double)nk_pow(10.0, m); - m1 = m; - m = 0; - } - if (m < 1.0) { - m = 0; - } - - /* convert the number */ - while (n > NK_FLOAT_PRECISION || m >= 0) { - double weight = nk_pow(10.0, m); - if (weight > 0) { - double t = (double)n / weight; - digit = nk_ifloord(t); - n -= ((double)digit * weight); - *(c++) = (char)('0' + (char)digit); - } - if (m == 0 && n > 0) { - *(c++) = '.'; - } - m--; - } - - if (useExp) { - /* convert the exponent */ - int i, j; - *(c++) = 'e'; - if (m1 > 0) { - *(c++) = '+'; - } else { - *(c++) = '-'; - m1 = -m1; - } - m = 0; - while (m1 > 0) { - *(c++) = (char)('0' + (char)(m1 % 10)); - m1 /= 10; - m++; - } - c -= m; - for (i = 0, j = m - 1; i < j; i++, j--) { - /* swap without temporary */ - c[i] ^= c[j]; - c[j] ^= c[i]; - c[i] ^= c[j]; - } - c += m; - } - *(c) = '\0'; - return s; -} -#endif -#ifdef NK_INCLUDE_STANDARD_VARARGS -# ifndef NK_INCLUDE_STANDARD_IO -NK_INTERN int -nk_vsnprintf(char *buf, int buf_size, const char *fmt, va_list args) -{ - enum nk_arg_type { NK_ARG_TYPE_CHAR, NK_ARG_TYPE_SHORT, NK_ARG_TYPE_DEFAULT, NK_ARG_TYPE_LONG }; - enum nk_arg_flags { NK_ARG_FLAG_LEFT = 0x01, NK_ARG_FLAG_PLUS = 0x02, NK_ARG_FLAG_SPACE = 0x04, NK_ARG_FLAG_NUM = 0x10, NK_ARG_FLAG_ZERO = 0x20 }; - - char number_buffer[NK_MAX_NUMBER_BUFFER]; - enum nk_arg_type arg_type = NK_ARG_TYPE_DEFAULT; - int precision = NK_DEFAULT; - int width = NK_DEFAULT; - nk_flags flag = 0; - - int len = 0; - int result = -1; - const char *iter = fmt; - - NK_ASSERT(buf); - NK_ASSERT(buf_size); - if (!buf || !buf_size || !fmt) { - return 0; - } - for (iter = fmt; *iter && len < buf_size; iter++) { - /* copy all non-format characters */ - while (*iter && (*iter != '%') && (len < buf_size)) { - buf[len++] = *iter++; - } - if (!(*iter) || len >= buf_size) { - break; - } - iter++; - - /* flag arguments */ - while (*iter) { - if (*iter == '-') { - flag |= NK_ARG_FLAG_LEFT; - } else if (*iter == '+') { - flag |= NK_ARG_FLAG_PLUS; - } else if (*iter == ' ') { - flag |= NK_ARG_FLAG_SPACE; - } else if (*iter == '#') { - flag |= NK_ARG_FLAG_NUM; - } else if (*iter == '0') { - flag |= NK_ARG_FLAG_ZERO; - } else { - break; - } - iter++; - } - - /* width argument */ - width = NK_DEFAULT; - if (*iter >= '1' && *iter <= '9') { - char *end; - width = nk_strtoi(iter, &end); - if (end == iter) { - width = -1; - } else { - iter = end; - } - } else if (*iter == '*') { - width = va_arg(args, int); - iter++; - } - - /* precision argument */ - precision = NK_DEFAULT; - if (*iter == '.') { - iter++; - if (*iter == '*') { - precision = va_arg(args, int); - iter++; - } else { - char *end; - precision = nk_strtoi(iter, &end); - if (end == iter) { - precision = -1; - } else { - iter = end; - } - } - } - - /* length modifier */ - if (*iter == 'h') { - if (*(iter + 1) == 'h') { - arg_type = NK_ARG_TYPE_CHAR; - iter++; - } else { - arg_type = NK_ARG_TYPE_SHORT; - } - iter++; - } else if (*iter == 'l') { - arg_type = NK_ARG_TYPE_LONG; - iter++; - } else { - arg_type = NK_ARG_TYPE_DEFAULT; - } - - /* specifier */ - if (*iter == '%') { - NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT); - NK_ASSERT(precision == NK_DEFAULT); - NK_ASSERT(width == NK_DEFAULT); - if (len < buf_size) { - buf[len++] = '%'; - } - } else if (*iter == 's') { - /* string */ - const char *str = va_arg(args, const char *); - NK_ASSERT(str != buf && "buffer and argument are not allowed to overlap!"); - NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT); - NK_ASSERT(precision == NK_DEFAULT); - NK_ASSERT(width == NK_DEFAULT); - if (str == buf) { - return -1; - } - while (str && *str && len < buf_size) { - buf[len++] = *str++; - } - } else if (*iter == 'n') { - /* current length callback */ - signed int *n = va_arg(args, int *); - NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT); - NK_ASSERT(precision == NK_DEFAULT); - NK_ASSERT(width == NK_DEFAULT); - if (n) { - *n = len; - } - } else if (*iter == 'c' || *iter == 'i' || *iter == 'd') { - /* signed integer */ - long value = 0; - const char *num_iter; - int num_len, num_print, padding; - int cur_precision = NK_MAX(precision, 1); - int cur_width = NK_MAX(width, 0); - - /* retrieve correct value type */ - if (arg_type == NK_ARG_TYPE_CHAR) { - value = (signed char)va_arg(args, int); - } else if (arg_type == NK_ARG_TYPE_SHORT) { - value = (signed short)va_arg(args, int); - } else if (arg_type == NK_ARG_TYPE_LONG) { - value = va_arg(args, signed long); - } else if (*iter == 'c') { - value = (unsigned char)va_arg(args, int); - } else { - value = va_arg(args, signed int); - } - - /* convert number to string */ - nk_itoa(number_buffer, value); - num_len = nk_strlen(number_buffer); - padding = NK_MAX(cur_width - NK_MAX(cur_precision, num_len), 0); - if ((flag & NK_ARG_FLAG_PLUS) || (flag & NK_ARG_FLAG_SPACE)) { - padding = NK_MAX(padding - 1, 0); - } - - /* fill left padding up to a total of `width` characters */ - if (!(flag & NK_ARG_FLAG_LEFT)) { - while (padding-- > 0 && (len < buf_size)) { - if ((flag & NK_ARG_FLAG_ZERO) && (precision == NK_DEFAULT)) { - buf[len++] = '0'; - } else { - buf[len++] = ' '; - } - } - } - - /* copy string value representation into buffer */ - if ((flag & NK_ARG_FLAG_PLUS) && value >= 0 && len < buf_size) { - buf[len++] = '+'; - } else if ((flag & NK_ARG_FLAG_SPACE) && value >= 0 && len < buf_size) { - buf[len++] = ' '; - } - - /* fill up to precision number of digits with '0' */ - num_print = NK_MAX(cur_precision, num_len); - while (precision && (num_print > num_len) && (len < buf_size)) { - buf[len++] = '0'; - num_print--; - } - - /* copy string value representation into buffer */ - num_iter = number_buffer; - while (precision && *num_iter && len < buf_size) { - buf[len++] = *num_iter++; - } - - /* fill right padding up to width characters */ - if (flag & NK_ARG_FLAG_LEFT) { - while ((padding-- > 0) && (len < buf_size)) { - buf[len++] = ' '; - } - } - } else if (*iter == 'o' || *iter == 'x' || *iter == 'X' || *iter == 'u') { - /* unsigned integer */ - unsigned long value = 0; - int num_len = 0, num_print, padding = 0; - int cur_precision = NK_MAX(precision, 1); - int cur_width = NK_MAX(width, 0); - unsigned int base = (*iter == 'o') ? 8 : (*iter == 'u') ? 10 : 16; - - /* print oct/hex/dec value */ - const char *upper_output_format = "0123456789ABCDEF"; - const char *lower_output_format = "0123456789abcdef"; - const char *output_format = (*iter == 'x') ? lower_output_format : upper_output_format; - - /* retrieve correct value type */ - if (arg_type == NK_ARG_TYPE_CHAR) { - value = (unsigned char)va_arg(args, int); - } else if (arg_type == NK_ARG_TYPE_SHORT) { - value = (unsigned short)va_arg(args, int); - } else if (arg_type == NK_ARG_TYPE_LONG) { - value = va_arg(args, unsigned long); - } else { - value = va_arg(args, unsigned int); - } - - do { - /* convert decimal number into hex/oct number */ - int digit = output_format[value % base]; - if (num_len < NK_MAX_NUMBER_BUFFER) { - number_buffer[num_len++] = (char)digit; - } - value /= base; - } while (value > 0); - - num_print = NK_MAX(cur_precision, num_len); - padding = NK_MAX(cur_width - NK_MAX(cur_precision, num_len), 0); - if (flag & NK_ARG_FLAG_NUM) { - padding = NK_MAX(padding - 1, 0); - } - - /* fill left padding up to a total of `width` characters */ - if (!(flag & NK_ARG_FLAG_LEFT)) { - while ((padding-- > 0) && (len < buf_size)) { - if ((flag & NK_ARG_FLAG_ZERO) && (precision == NK_DEFAULT)) { - buf[len++] = '0'; - } else { - buf[len++] = ' '; - } - } - } - - /* fill up to precision number of digits */ - if (num_print && (flag & NK_ARG_FLAG_NUM)) { - if ((*iter == 'o') && (len < buf_size)) { - buf[len++] = '0'; - } else if ((*iter == 'x') && ((len + 1) < buf_size)) { - buf[len++] = '0'; - buf[len++] = 'x'; - } else if ((*iter == 'X') && ((len + 1) < buf_size)) { - buf[len++] = '0'; - buf[len++] = 'X'; - } - } - while (precision && (num_print > num_len) && (len < buf_size)) { - buf[len++] = '0'; - num_print--; - } - - /* reverse number direction */ - while (num_len > 0) { - if (precision && (len < buf_size)) { - buf[len++] = number_buffer[num_len - 1]; - } - num_len--; - } - - /* fill right padding up to width characters */ - if (flag & NK_ARG_FLAG_LEFT) { - while ((padding-- > 0) && (len < buf_size)) { - buf[len++] = ' '; - } - } - } else if (*iter == 'f') { - /* floating point */ - const char *num_iter; - int cur_precision = (precision < 0) ? 6 : precision; - int prefix, cur_width = NK_MAX(width, 0); - double value = va_arg(args, double); - int num_len = 0, frac_len = 0, dot = 0; - int padding = 0; - - NK_ASSERT(arg_type == NK_ARG_TYPE_DEFAULT); - NK_DTOA(number_buffer, value); - num_len = nk_strlen(number_buffer); - - /* calculate padding */ - num_iter = number_buffer; - while (*num_iter && *num_iter != '.') { - num_iter++; - } - - prefix = (*num_iter == '.') ? (int)(num_iter - number_buffer) + 1 : 0; - padding = NK_MAX(cur_width - (prefix + NK_MIN(cur_precision, num_len - prefix)), 0); - if ((flag & NK_ARG_FLAG_PLUS) || (flag & NK_ARG_FLAG_SPACE)) { - padding = NK_MAX(padding - 1, 0); - } - - /* fill left padding up to a total of `width` characters */ - if (!(flag & NK_ARG_FLAG_LEFT)) { - while (padding-- > 0 && (len < buf_size)) { - if (flag & NK_ARG_FLAG_ZERO) { - buf[len++] = '0'; - } else { - buf[len++] = ' '; - } - } - } - - /* copy string value representation into buffer */ - num_iter = number_buffer; - if ((flag & NK_ARG_FLAG_PLUS) && (value >= 0) && (len < buf_size)) { - buf[len++] = '+'; - } else if ((flag & NK_ARG_FLAG_SPACE) && (value >= 0) && (len < buf_size)) { - buf[len++] = ' '; - } - while (*num_iter) { - if (dot) { - frac_len++; - } - if (len < buf_size) { - buf[len++] = *num_iter; - } - if (*num_iter == '.') { - dot = 1; - } - if (frac_len >= cur_precision) { - break; - } - num_iter++; - } - - /* fill number up to precision */ - while (frac_len < cur_precision) { - if (!dot && len < buf_size) { - buf[len++] = '.'; - dot = 1; - } - if (len < buf_size) { - buf[len++] = '0'; - } - frac_len++; - } - - /* fill right padding up to width characters */ - if (flag & NK_ARG_FLAG_LEFT) { - while ((padding-- > 0) && (len < buf_size)) { - buf[len++] = ' '; - } - } - } else { - /* Specifier not supported: g,G,e,E,p,z */ - NK_ASSERT(0 && "specifier is not supported!"); - return result; - } - } - buf[(len >= buf_size) ? (buf_size - 1) : len] = 0; - result = (len >= buf_size) ? -1 : len; - return result; -} -# endif -NK_LIB int -nk_strfmt(char *buf, int buf_size, const char *fmt, va_list args) -{ - int result = -1; - NK_ASSERT(buf); - NK_ASSERT(buf_size); - if (!buf || !buf_size || !fmt) { - return 0; - } -# ifdef NK_INCLUDE_STANDARD_IO - result = NK_VSNPRINTF(buf, (nk_size)buf_size, fmt, args); - result = (result >= buf_size) ? -1 : result; - buf[buf_size - 1] = 0; -# else - result = nk_vsnprintf(buf, buf_size, fmt, args); -# endif - return result; -} -#endif -NK_API nk_hash -nk_murmur_hash(const void *key, int len, nk_hash seed) -{ -/* 32-Bit MurmurHash3: https://code.google.com/p/smhasher/wiki/MurmurHash3*/ -#define NK_ROTL(x, r) ((x) << (r) | ((x) >> (32 - r))) - - nk_uint h1 = seed; - nk_uint k1; - const nk_byte *data = (const nk_byte *)key; - const nk_byte *keyptr = data; - nk_byte *k1ptr; - const int bsize = sizeof(k1); - const int nblocks = len / 4; - - const nk_uint c1 = 0xcc9e2d51; - const nk_uint c2 = 0x1b873593; - const nk_byte *tail; - int i; - - /* body */ - if (!key) { - return 0; - } - for (i = 0; i < nblocks; ++i, keyptr += bsize) { - k1ptr = (nk_byte *)&k1; - k1ptr[0] = keyptr[0]; - k1ptr[1] = keyptr[1]; - k1ptr[2] = keyptr[2]; - k1ptr[3] = keyptr[3]; - - k1 *= c1; - k1 = NK_ROTL(k1, 15); - k1 *= c2; - - h1 ^= k1; - h1 = NK_ROTL(h1, 13); - h1 = h1 * 5 + 0xe6546b64; - } - - /* tail */ - tail = (const nk_byte *)(data + nblocks * 4); - k1 = 0; - switch (len & 3) { - case 3: - k1 ^= (nk_uint)(tail[2] << 16); /* fallthrough */ - case 2: - k1 ^= (nk_uint)(tail[1] << 8u); /* fallthrough */ - case 1: - k1 ^= tail[0]; - k1 *= c1; - k1 = NK_ROTL(k1, 15); - k1 *= c2; - h1 ^= k1; - break; - default: - break; - } - - /* finalization */ - h1 ^= (nk_uint)len; - /* fmix32 */ - h1 ^= h1 >> 16; - h1 *= 0x85ebca6b; - h1 ^= h1 >> 13; - h1 *= 0xc2b2ae35; - h1 ^= h1 >> 16; - -#undef NK_ROTL - return h1; -} -#ifdef NK_INCLUDE_STANDARD_IO -NK_LIB char * -nk_file_load(const char *path, nk_size *siz, const struct nk_allocator *alloc) -{ - char *buf; - FILE *fd; - long ret; - - NK_ASSERT(path != NULL); - NK_ASSERT(siz != NULL); - NK_ASSERT(alloc != NULL); - if (!path || !siz || !alloc) { - return 0; - } - - fd = fopen(path, "rb"); - if (!fd) { - return 0; - } - fseek(fd, 0, SEEK_END); - ret = ftell(fd); - if (ret < 0) { - fclose(fd); - return 0; - } - *siz = (nk_size)ret; - fseek(fd, 0, SEEK_SET); - buf = (char *)alloc->alloc(alloc->userdata, 0, *siz); - NK_ASSERT(buf); - if (!buf) { - fclose(fd); - return 0; - } - *siz = (nk_size)fread(buf, 1, *siz, fd); - fclose(fd); - return buf; -} -#endif - -NK_INTERN struct nk_text_shape * -nk_text_shape_build_default(struct nk_context *ctx, const struct nk_user_font *font, float height, const char *text, int len); - -NK_LIB int -nk_text_clamp(struct nk_context *ctx, const struct nk_user_font *font, const char *text, int text_len, float space, int *glyphs, float *text_width, nk_rune *sep_list, int sep_count) -{ - int i = 0; - int glyph_len = 0; - float last_width = 0; - nk_rune unicode = 0; - float width = 0; - int len = 0; - int g = 0; - float s; - - int cluster_idx = 0; - float shape_width = 0.0f; - - struct nk_text_shape *shape; - - int sep_len = 0; - int sep_g = 0; - float sep_width = 0; - sep_count = NK_MAX(sep_count, 0); - shape = nk_text_shape_build_default(ctx, font, ctx->style.font_size, text, text_len); - - glyph_len = nk_utf_decode(text, &unicode, text_len); - while (glyph_len && (width < space) && (len < text_len)) { - len += glyph_len; - while (shape && cluster_idx < shape->num_clusters && shape->clusters[cluster_idx].source_end <= len) { - struct nk_text_cluster *cluster = &shape->clusters[cluster_idx++]; - int glyph_idx; - for (glyph_idx = cluster->glyph_begin; glyph_idx < cluster->glyph_begin + cluster->glyph_count; ++glyph_idx) { - shape_width += shape->glyphs[glyph_idx].advance_x; - } - } - - s = shape_width; - for (i = 0; i < sep_count; ++i) { - if (unicode != sep_list[i]) { - continue; - } - - sep_width = last_width = width; - sep_g = g + 1; - sep_len = len; - break; - } - - if (i == sep_count) { - last_width = sep_width = width; - sep_g = g + 1; - } - - width = s; - glyph_len = nk_utf_decode(&text[len], &unicode, text_len - len); - g += 1; - } - - if (len >= text_len) { - *glyphs = g; - *text_width = last_width; - return len; - } else { - *glyphs = sep_g; - *text_width = sep_width; - return (!sep_len) ? len : sep_len; - } -} - -NK_LIB struct nk_vec2 -nk_text_calculate_text_bounds(struct nk_context *ctx, const struct nk_user_font *font, const char *begin, int byte_len, - float row_height, const char **remaining, struct nk_vec2 *out_offset, int *glyphs, int op) -{ - float line_height = row_height; - struct nk_vec2 text_size = nk_vec2(0, 0); - float line_width = 0.0f; - - int glyph_len = 0; - nk_rune unicode = 0; - int text_len = 0; - int line_begin = 0; - nk_bool stopped_on_newline = nk_false; - - if (!begin || byte_len <= 0 || !font) { - return nk_vec2(0, row_height); - } - - glyph_len = nk_utf_decode(begin, &unicode, byte_len); - if (!glyph_len) { - return text_size; - } - - *glyphs = 0; - while ((text_len < byte_len) && glyph_len) { - if (unicode == '\n') { - line_width = nk_text_width(ctx, font, ctx->style.font_size, begin + line_begin, text_len - line_begin); - text_size.x = NK_MAX(text_size.x, line_width); - text_size.y += line_height; - *glyphs += 1; - if (op == NK_STOP_ON_NEW_LINE) { - stopped_on_newline = nk_true; - break; - } - - text_len += glyph_len; - line_begin = text_len; - glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len - text_len); - continue; - } - - if (unicode == '\r') { - text_len += glyph_len; - *glyphs += 1; - glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len - text_len); - continue; - } - - *glyphs = *glyphs + 1; - text_len += glyph_len; - glyph_len = nk_utf_decode(begin + text_len, &unicode, byte_len - text_len); - } - - line_width = nk_text_width(ctx, font, ctx->style.font_size, begin + line_begin, text_len - line_begin); - if (text_size.x < line_width) { - text_size.x = line_width; - } - - if (!stopped_on_newline && (line_width > 0 || text_size.y == 0.0f)) { - text_size.y += line_height; - } - - if (out_offset) { - *out_offset = nk_vec2(line_width, text_size.y); - } - - if (remaining) { - *remaining = begin + text_len; - } - return text_size; -} - -struct nk_text_geometry_run { - nk_handle texture; - int quad_begin; - int quad_count; -}; - -struct nk_text_geometry_quad { - struct nk_vec2 min; - struct nk_vec2 max; - struct nk_vec2 uv_min; - struct nk_vec2 uv_max; -}; - -struct nk_text_geometry { - struct nk_text_geometry_run *runs; - int num_runs; - struct nk_text_geometry_quad *quads; -}; - -struct nk_text_cache_chunk { - struct nk_text_cache_chunk *prev; - struct nk_text_cache_chunk *next; - struct nk_text_cache_chunk *next_free; - nk_bool free; - nk_size capacity; - nk_byte data[]; -}; - -#define NK_TEXT_CACHE_CHUNK_HEADER_SIZE NK_OFFSETOF(struct nk_text_cache_chunk, data) -NK_STATIC_ASSERT(NK_TEXT_CACHE_CHUNK_HEADER_SIZE == sizeof(struct nk_text_cache_chunk)); -NK_STATIC_ASSERT(!(NK_TEXT_CACHE_CHUNK_HEADER_SIZE % NK_ALIGNOF(struct nk_text_cache_chunk))); - -struct nk_text_cache_entry { - struct nk_text_cache_entry *next_hash; - struct nk_text_cache_entry *lru_prev; - struct nk_text_cache_entry *lru_next; - struct nk_text_cache_chunk *key_chunk; - struct nk_text_cache_chunk *shape_chunk; - struct nk_text_cache_chunk *geometry_chunk; - nk_hash hash; - struct nk_text_shape *shape; - struct nk_text_geometry *geometry; - char *source; - int source_len; - float width; - const struct nk_user_font *font; - float font_height; - enum nk_text_direction direction; - nk_uint script_tag; - char *lang; - int lang_len; - struct nk_text_feature *features; - int num_features; - unsigned int last_used_seq; - nk_bool probation; -}; - -struct nk_text_cache_state { - struct nk_text_cache_entry *buckets[NK_TEXT_CACHE_BUCKET_COUNT]; - struct nk_text_cache_chunk *first_chunk; - struct nk_text_cache_chunk *last_chunk; - struct nk_text_cache_chunk *free_chunks; - struct nk_text_cache_entry *protected_head; - struct nk_text_cache_entry *protected_tail; - struct nk_text_cache_entry *probation_head; - struct nk_text_cache_entry *probation_tail; -}; - -NK_INTERN struct nk_text_cache_state * -nk_text_cache_state(struct nk_context *ctx) -{ - return (struct nk_text_cache_state *)ctx->text_cache_buckets; -} - -NK_INTERN nk_hash -nk_text_request_hash(const struct nk_text_request *request) -{ - int i; - nk_ptr font = NK_PTR_TO_UINT(request->font); - nk_hash hash = nk_murmur_hash(&font, sizeof(font), 0x61E5F08D); - - hash = nk_murmur_hash(&request->font_height, sizeof(request->font_height), hash); - hash = nk_murmur_hash(&request->direction, sizeof(request->direction), hash); - hash = nk_murmur_hash(&request->script_tag, sizeof(request->script_tag), hash); - - if (request->source_len) { - hash = nk_murmur_hash(request->source, request->source_len, hash); - } - - if (request->lang_len) { - hash = nk_murmur_hash(request->lang, request->lang_len, hash); - } - - for (i = 0; i < request->num_features; ++i) { - hash = nk_murmur_hash(&request->features[i], sizeof(request->features[i]), hash); - } - return hash; -} - -NK_INTERN nk_bool -nk_text_memory_equal(const void *a, const void *b, nk_size size) -{ - const nk_byte *left = a; - const nk_byte *right = b; - nk_size i; - for (i = 0; i < size; ++i) { - if (left[i] != right[i]) { - return nk_false; - } - } - return nk_true; -} - -NK_INTERN nk_bool -nk_text_cache_entry_matches(const struct nk_text_cache_entry *entry, const struct nk_text_request *request) -{ - int i; - if (entry->font != request->font || - entry->font_height != request->font_height || - entry->direction != request->direction || - entry->script_tag != request->script_tag || - entry->source_len != request->source_len || - entry->lang_len != request->lang_len || - entry->num_features != request->num_features || - !nk_text_memory_equal(entry->source, request->source, request->source_len) || - !nk_text_memory_equal(entry->lang, request->lang, request->lang_len)) { - return nk_false; - } - - for (i = 0; i < request->num_features; ++i) { - if (entry->features[i].tag != request->features[i].tag || - entry->features[i].value != request->features[i].value) { - return nk_false; - } - } - return nk_true; -} - -NK_INTERN void -nk_text_cache_free_remove(struct nk_text_cache_state *state, struct nk_text_cache_chunk *chunk) -{ - struct nk_text_cache_chunk **link = &state->free_chunks; - while (*link != chunk) { - link = &(*link)->next_free; - } - *link = chunk->next_free; -} - -NK_INTERN void -nk_text_cache_chunk_release(struct nk_context *ctx, struct nk_text_cache_chunk *chunk) -{ - struct nk_text_cache_state *state = nk_text_cache_state(ctx); - - if (!chunk) { - return; - } - - chunk->free = nk_true; - if (chunk->prev && chunk->prev->free) { - struct nk_text_cache_chunk *prev = chunk->prev; - - nk_text_cache_free_remove(state, prev); - - prev->capacity += NK_TEXT_CACHE_CHUNK_HEADER_SIZE + chunk->capacity; - prev->next = chunk->next; - - if (prev->next) { - prev->next->prev = prev; - } else { - state->last_chunk = prev; - } - chunk = prev; - } - - if (chunk->next && chunk->next->free) { - struct nk_text_cache_chunk *next = chunk->next; - - nk_text_cache_free_remove(state, next); - - chunk->capacity += NK_TEXT_CACHE_CHUNK_HEADER_SIZE + next->capacity; - chunk->next = next->next; - - if (chunk->next) { - chunk->next->prev = chunk; - } else { - state->last_chunk = chunk; - } - } - - chunk->next_free = state->free_chunks; - state->free_chunks = chunk; -} - -NK_INTERN void -nk_text_cache_lru_unlink(struct nk_context *ctx, struct nk_text_cache_entry *entry) -{ - struct nk_text_cache_state *state = nk_text_cache_state(ctx); - struct nk_text_cache_entry **head = entry->probation ? &state->probation_head : &state->protected_head; - struct nk_text_cache_entry **tail = entry->probation ? &state->probation_tail : &state->protected_tail; - - if (entry->lru_prev) { - entry->lru_prev->lru_next = entry->lru_next; - } else { - *head = entry->lru_next; - } - - if (entry->lru_next) { - entry->lru_next->lru_prev = entry->lru_prev; - } else { - *tail = entry->lru_prev; - } -} - -NK_INTERN void -nk_text_cache_lru_link_head(struct nk_context *ctx, struct nk_text_cache_entry *entry) -{ - struct nk_text_cache_state *state = nk_text_cache_state(ctx); - struct nk_text_cache_entry **head = entry->probation ? &state->probation_head : &state->protected_head; - struct nk_text_cache_entry **tail = entry->probation ? &state->probation_tail : &state->protected_tail; - - entry->lru_prev = NULL; - entry->lru_next = *head; - - if (entry->lru_next) { - entry->lru_next->lru_prev = entry; - } else { - *tail = entry; - } - *head = entry; -} - -NK_INTERN void -nk_text_cache_lru_touch(struct nk_context *ctx, struct nk_text_cache_entry *entry) -{ - struct nk_text_cache_state *state = nk_text_cache_state(ctx); - struct nk_text_cache_entry *head = entry->probation ? state->probation_head : state->protected_head; - nk_bool promote = entry->probation && entry->last_used_seq != ctx->seq; - - entry->last_used_seq = ctx->seq; - if (!promote && head == entry) { - return; - } - - nk_text_cache_lru_unlink(ctx, entry); - if (promote) { - entry->probation = nk_false; - } - nk_text_cache_lru_link_head(ctx, entry); -} - -NK_INTERN void -nk_text_cache_evict(struct nk_context *ctx, struct nk_text_cache_entry *entry) -{ - struct nk_text_cache_entry **link = &ctx->text_cache_buckets[entry->hash % NK_TEXT_CACHE_BUCKET_COUNT]; - struct nk_text_cache_chunk *key_chunk = entry->key_chunk; - struct nk_text_cache_chunk *shape_chunk = entry->shape_chunk; - struct nk_text_cache_chunk *geometry_chunk = entry->geometry_chunk; - - NK_PROFILE_SCOPE_BEGIN("text.cache_evict", cache_evict); - while (*link != entry) { - link = &(*link)->next_hash; - } - *link = entry->next_hash; - - nk_text_cache_lru_unlink(ctx, entry); - nk_text_cache_chunk_release(ctx, shape_chunk); - nk_text_cache_chunk_release(ctx, geometry_chunk); - nk_text_cache_chunk_release(ctx, key_chunk); - NK_PROFILE_SCOPE_END(cache_evict); -} - -NK_INTERN struct nk_text_cache_chunk * -nk_text_cache_chunk_reuse(struct nk_context *ctx, nk_size capacity) -{ - struct nk_text_cache_state *state = nk_text_cache_state(ctx); - struct nk_text_cache_chunk *best = NULL; - struct nk_text_cache_chunk *chunk; - nk_size remainder; - - for (chunk = state->free_chunks; chunk; chunk = chunk->next_free) { - if (chunk->capacity >= capacity && (!best || chunk->capacity < best->capacity)) { - best = chunk; - } - } - - if (!best) { - return NULL; - } - - nk_text_cache_free_remove(state, best); - remainder = best->capacity - capacity; - if (remainder >= NK_TEXT_CACHE_CHUNK_HEADER_SIZE + 128) { - struct nk_text_cache_chunk *split = (struct nk_text_cache_chunk *)(best->data + capacity); - - split->prev = best; - split->next = best->next; - split->next_free = state->free_chunks; - split->capacity = remainder - NK_TEXT_CACHE_CHUNK_HEADER_SIZE; - split->free = nk_true; - - if (split->next) { - split->next->prev = split; - } else { - state->last_chunk = split; - } - - state->free_chunks = split; - best->next = split; - best->capacity = capacity; - } - - best->next_free = NULL; - best->free = nk_false; - return best; -} - -NK_INTERN struct nk_text_cache_chunk * -nk_text_cache_chunk_alloc(struct nk_context *ctx, nk_size size, struct nk_text_cache_entry *pinned) -{ - struct nk_text_cache_state *state = nk_text_cache_state(ctx); - struct nk_text_cache_chunk *chunk; - struct nk_text_cache_entry *victim; - nk_size capacity; - - if (size > (nk_size)-1 - 7) { - return NULL; - } - capacity = (NK_MAX(size, 128) + 7) & ~(nk_size)7; - - while (1) { - chunk = nk_text_cache_chunk_reuse(ctx, capacity); - if (chunk) { - return chunk; - } - - chunk = nk_buffer_alloc(&ctx->text_cache, NK_BUFFER_FRONT, NK_TEXT_CACHE_CHUNK_HEADER_SIZE + capacity, NK_ALIGNOF(struct nk_text_cache_chunk)); - if (chunk) { - chunk->prev = state->last_chunk; - chunk->next = NULL; - chunk->next_free = NULL; - chunk->capacity = capacity; - chunk->free = nk_false; - - if (state->last_chunk) { - state->last_chunk->next = chunk; - } else { - state->first_chunk = chunk; - } - - state->last_chunk = chunk; - return chunk; - } - - victim = state->probation_tail; - while (victim && (victim == pinned || victim->last_used_seq == ctx->seq)) { - victim = victim->lru_prev; - } - - if (!victim) { - victim = state->protected_tail; - while (victim && (victim == pinned || victim->last_used_seq == ctx->seq)) { - victim = victim->lru_prev; - } - } - - if (!victim) { - return NULL; - } - nk_text_cache_evict(ctx, victim); - } -} - -NK_INTERN struct nk_text_cache_entry * -nk_text_cache_find(struct nk_context *ctx, const struct nk_text_request *request, nk_hash hash) -{ - struct nk_text_cache_entry *entry = ctx->text_cache_buckets ? ctx->text_cache_buckets[hash % NK_TEXT_CACHE_BUCKET_COUNT] : NULL; - for (; entry; entry = entry->next_hash) { - if (entry->hash == hash && nk_text_cache_entry_matches(entry, request)) { - nk_text_cache_lru_touch(ctx, entry); - return entry; - } - } - return NULL; -} - -NK_INTERN struct nk_text_cache_entry * -nk_text_cache_alloc(struct nk_context *ctx, const struct nk_text_request *request, nk_hash hash) -{ - struct nk_text_cache_entry *entry; - struct nk_text_cache_chunk *chunk; - nk_size features_size = sizeof(struct nk_text_feature) * request->num_features; - nk_size entry_size = sizeof(*entry) + features_size + request->lang_len + request->source_len; - - chunk = nk_text_cache_chunk_alloc(ctx, entry_size, NULL); - if (!chunk) { - return NULL; - } - - entry = (struct nk_text_cache_entry *)chunk->data; - NK_MEMSET(entry, 0, sizeof(*entry)); - - entry->key_chunk = chunk; - entry->hash = hash; - entry->source = nk_ptr_add(char, entry, sizeof(*entry) + features_size + request->lang_len); - entry->source_len = request->source_len; - entry->font = request->font; - entry->font_height = request->font_height; - entry->direction = request->direction; - entry->script_tag = request->script_tag; - entry->features = nk_ptr_add(struct nk_text_feature, entry, sizeof(*entry)); - entry->num_features = request->num_features; - entry->lang = nk_ptr_add(char, entry->features, features_size); - entry->lang_len = request->lang_len; - - if (features_size) { - NK_MEMCPY(entry->features, request->features, features_size); - } - - if (request->lang_len) { - NK_MEMCPY(entry->lang, request->lang, request->lang_len); - } - - if (request->source_len) { - NK_MEMCPY(entry->source, request->source, request->source_len); - } - return entry; -} - -NK_INTERN void -nk_text_cache_link(struct nk_context *ctx, struct nk_text_cache_entry *entry) -{ - nk_hash bucket = entry->hash % NK_TEXT_CACHE_BUCKET_COUNT; - - entry->next_hash = ctx->text_cache_buckets[bucket]; - ctx->text_cache_buckets[bucket] = entry; - entry->last_used_seq = ctx->seq; - entry->probation = nk_true; - nk_text_cache_lru_link_head(ctx, entry); -} - -NK_INTERN struct nk_text_geometry * -nk_text_geometry_build(struct nk_context *ctx, struct nk_text_cache_entry *entry, const struct nk_text_shape *shape, float font_height) -{ - struct nk_text_cache_chunk *chunk; - struct nk_text_geometry *geometry; - struct nk_vec2 pen = nk_vec2(0.0f, 0.0f); - nk_size runs_size = sizeof(*geometry->runs) * shape->num_runs; - nk_size quads_size = sizeof(*geometry->quads) * shape->num_glyphs; - nk_size size = sizeof(*geometry) + runs_size + quads_size; - int run_idx; - - chunk = nk_text_cache_chunk_alloc(ctx, size, entry); - if (!chunk) { - return NULL; - } - - geometry = (struct nk_text_geometry *)chunk->data; - geometry->runs = nk_ptr_add(struct nk_text_geometry_run, geometry, sizeof(*geometry)); - geometry->num_runs = shape->num_runs; - geometry->quads = nk_ptr_add(struct nk_text_geometry_quad, geometry->runs, runs_size); - - for (run_idx = 0; run_idx < shape->num_runs; ++run_idx) { - const struct nk_text_run *run = &shape->runs[run_idx]; - int glyph_idx; - - geometry->runs[run_idx].texture = run->font->texture; - geometry->runs[run_idx].quad_begin = run->glyph_begin; - geometry->runs[run_idx].quad_count = run->glyph_count; - - for (glyph_idx = run->glyph_begin; glyph_idx < run->glyph_begin + run->glyph_count; ++glyph_idx) { - const struct nk_text_glyph *glyph = &shape->glyphs[glyph_idx]; - struct nk_text_geometry_quad *quad = &geometry->quads[glyph_idx]; - struct nk_user_font_glyph font_glyph; - float x; - float y; - - run->font->query_glyph(run->font->userdata, font_height, &font_glyph, glyph->id); - x = pen.x + glyph->offset_x + font_glyph.offset.x; - y = pen.y + shape->baseline + glyph->offset_y + font_glyph.offset.y; - - quad->min = nk_vec2(x, y); - quad->max = nk_vec2(x + font_glyph.width, y + font_glyph.height); - quad->uv_min = font_glyph.uv[0]; - quad->uv_max = font_glyph.uv[1]; - - pen.x += glyph->advance_x; - pen.y += glyph->advance_y; - } - } - - entry->geometry_chunk = chunk; - entry->geometry = geometry; - return geometry; -} - -NK_API void -nk_text_chunk_list_init(struct nk_text_chunk_list *list, nk_size item_size) -{ - NK_ASSERT(list); - NK_MEMSET(list, 0, sizeof(*list)); - list->item_size = item_size; -} - -NK_API nk_bool -nk_text_chunk_list_push(struct nk_text_chunk_list *list, struct nk_buffer *buffer, const void *item) -{ - struct nk_text_chunk *chunk; - - NK_ASSERT(list); - NK_ASSERT(buffer); - NK_ASSERT(item); - NK_ASSERT(list->item_size); - NK_ASSERT(list->item_size <= NK_TEXT_CHUNK_DATA_SIZE); - - chunk = list->last; - if (!chunk || chunk->used + list->item_size > NK_TEXT_CHUNK_DATA_SIZE) { - chunk = nk_buffer_alloc(buffer, NK_BUFFER_FRONT, sizeof(*chunk), NK_ALIGNOF(struct nk_text_chunk)); - if (!chunk) { - return nk_false; - } - - chunk->next = NULL; - chunk->used = 0; - if (list->last) { - list->last->next = chunk; - } else { - list->first = chunk; - } - list->last = chunk; - } - - NK_MEMCPY(chunk->data + chunk->used, item, list->item_size); - chunk->used += list->item_size; - list->count++; - return nk_true; -} - -NK_API void * -nk_text_chunk_list_flatten(const struct nk_text_chunk_list *list, struct nk_buffer *buffer, nk_size alignment) -{ - const struct nk_text_chunk *chunk; - nk_byte *result; - nk_byte *destination; - - NK_ASSERT(list); - NK_ASSERT(buffer); - if (!list->count) { - return NULL; - } - - result = nk_buffer_alloc(buffer, NK_BUFFER_FRONT, list->count * list->item_size, alignment); - if (!result) { - return NULL; - } - - destination = result; - for (chunk = list->first; chunk; chunk = chunk->next) { - NK_MEMCPY(destination, chunk->data, chunk->used); - destination += chunk->used; - } - return result; -} - -NK_API nk_bool -nk_text_memory_init_fixed(struct nk_context *ctx, nk_size cache_size) -{ - void *memory; - - NK_ASSERT(ctx); - NK_ASSERT(cache_size); - NK_ASSERT(!ctx->text_memory_initialized); - NK_ASSERT(ctx->memory.type == NK_BUFFER_FIXED); - NK_ASSERT(!ctx->memory.allocated); - NK_ASSERT(cache_size < ctx->memory.size); - if (cache_size >= ctx->memory.size) { - return nk_false; - } - - ctx->memory.memory.size -= cache_size; - ctx->memory.size -= cache_size; - memory = nk_ptr_add(void, ctx->memory.memory.ptr, ctx->memory.size); - nk_buffer_init_fixed(&ctx->text_cache, memory, cache_size); - ctx->text_memory_initialized = nk_true; - nk_text_memory_clear(ctx); - return nk_true; -} - -NK_API void -nk_text_memory_clear(struct nk_context *ctx) -{ - struct nk_text_cache_state *state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->text_memory_initialized); - nk_buffer_clear(&ctx->text_cache); - - state = nk_buffer_alloc(&ctx->text_cache, NK_BUFFER_FRONT, sizeof(*state), NK_ALIGNOF(struct nk_text_cache_state)); - if (state) { - NK_MEMSET(state, 0, sizeof(*state)); - ctx->text_cache_buckets = state->buckets; - } else { - ctx->text_cache_buckets = NULL; - } -} - -NK_API void -nk_text_backend_set(struct nk_context *ctx, const struct nk_text_backend *backend) -{ - NK_ASSERT(ctx); - NK_ASSERT(backend); - NK_ASSERT(ctx->text_memory_initialized); - nk_text_memory_clear(ctx); - ctx->text_backend = *backend; -} - -NK_INTERN struct nk_text_shape * -nk_text_shape_build_temporary(struct nk_context *ctx, const struct nk_text_request *request) -{ - struct nk_text_shape *shape; - - if (!ctx->text_backend.temporary) { - return NULL; - } - - nk_buffer_clear(ctx->text_backend.temporary); - NK_PROFILE_SCOPE_BEGIN("text.shape_backend_temporary", shape_backend_temporary); - { - shape = ctx->text_backend.build(ctx->text_backend.userdata, ctx->text_backend.temporary, request); - } - NK_PROFILE_SCOPE_END(shape_backend_temporary); - return shape; -} - -NK_INTERN void * -nk_text_shape_array_copy(struct nk_buffer *buffer, const void *source, nk_size size, nk_size alignment) -{ - void *result = NULL; - if (size) { - result = nk_buffer_alloc(buffer, NK_BUFFER_FRONT, size, alignment); - NK_MEMCPY(result, source, size); - } - return result; -} - -NK_INTERN struct nk_text_shape * -nk_text_shape_cache(struct nk_context *ctx, - struct nk_text_cache_entry *entry, - const struct nk_text_shape *source) -{ - struct nk_text_cache_chunk *chunk; - struct nk_text_shape *shape; - struct nk_buffer buffer; - nk_size size; - - size = sizeof(*shape) + 64; - size += sizeof(*shape->boundaries) * source->num_boundaries; - size += sizeof(*shape->clusters) * source->num_clusters; - size += sizeof(*shape->runs) * source->num_runs; - size += sizeof(*shape->glyphs) * source->num_glyphs; - - chunk = nk_text_cache_chunk_alloc(ctx, size, entry); - if (!chunk) { - return NULL; - } - - nk_buffer_init_fixed(&buffer, chunk->data, chunk->capacity); - shape = nk_buffer_alloc(&buffer, NK_BUFFER_FRONT, sizeof(*shape), NK_ALIGNOF(struct nk_text_shape)); - *shape = *source; - shape->source = entry->source; - shape->boundaries = NULL; - shape->clusters = NULL; - shape->runs = NULL; - shape->glyphs = NULL; - - shape->boundaries = nk_text_shape_array_copy(&buffer, source->boundaries, sizeof(*shape->boundaries) * source->num_boundaries, NK_ALIGNOF(struct nk_text_boundary)); - shape->clusters = nk_text_shape_array_copy(&buffer, source->clusters, sizeof(*shape->clusters) * source->num_clusters, NK_ALIGNOF(struct nk_text_cluster)); - shape->runs = nk_text_shape_array_copy(&buffer, source->runs, sizeof(*shape->runs) * source->num_runs, NK_ALIGNOF(struct nk_text_run)); - shape->glyphs = nk_text_shape_array_copy(&buffer, source->glyphs, sizeof(*shape->glyphs) * source->num_glyphs, NK_ALIGNOF(struct nk_text_glyph)); - - entry->shape_chunk = chunk; - entry->shape = shape; - return shape; -} - -NK_API struct nk_text_shape * -nk_text_shape_build(struct nk_context *ctx, const struct nk_text_request *request) -{ - struct nk_text_cache_entry *entry; - struct nk_text_shape *shape; - nk_hash hash; - - NK_ASSERT(ctx); - NK_ASSERT(request); - NK_ASSERT(ctx->text_memory_initialized); - NK_ASSERT(ctx->text_backend.build); - - NK_PROFILE_SCOPE_BEGIN("text.shape_cache_lookup", shape_cache_lookup); - { - hash = nk_text_request_hash(request); - entry = nk_text_cache_find(ctx, request, hash); - } - NK_PROFILE_SCOPE_END(shape_cache_lookup); - - if (entry && entry->shape) { - return entry->shape; - } - - shape = nk_text_shape_build_temporary(ctx, request); - if (!shape) { - return NULL; - } - - if (!entry && ctx->text_cache_buckets) { - entry = nk_text_cache_alloc(ctx, request, hash); - if (entry) { - entry->width = shape->advance.x; - nk_text_cache_link(ctx, entry); - } - } - - if (!entry) { - return shape; - } - - { - struct nk_text_shape *cached = nk_text_shape_cache(ctx, entry, shape); - if (cached) { - entry->width = cached->advance.x; - return cached; - } - } - return shape; -} - -NK_INTERN struct nk_text_shape * -nk_text_shape_build_default(struct nk_context *ctx, const struct nk_user_font *font, float height, const char *text, int len) -{ - struct nk_text_request request = {0}; - if (!len) { - return NULL; - } - request.source = text; - request.source_len = len; - request.font = font; - request.font_height = height; - return nk_text_shape_build(ctx, &request); -} - -NK_API float -nk_text_shape_width(const struct nk_text_shape *shape, int source_begin, int source_end) -{ - float width = 0.0f; - int i; - - if (source_begin == 0 && source_end == shape->source_len) { - return shape->advance.x; - } - - for (i = 0; i < shape->num_glyphs; ++i) { - const struct nk_text_glyph *glyph = &shape->glyphs[i]; - const struct nk_text_cluster *cluster = &shape->clusters[glyph->cluster_idx]; - if (cluster->source_begin >= source_begin && cluster->source_end <= source_end) { - width += glyph->advance_x; - } - } - return width; -} - -NK_API int -nk_text_shape_boundary_previous(const struct nk_text_shape *shape, int source_offset, nk_flags flags) -{ - int i; - for (i = shape->num_boundaries - 1; i >= 0; --i) { - if (shape->boundaries[i].source_offset < source_offset && (shape->boundaries[i].flags & flags)) { - return shape->boundaries[i].source_offset; - } - } - return 0; -} - -NK_API int -nk_text_shape_boundary_next(const struct nk_text_shape *shape, int source_offset, nk_flags flags) -{ - int i; - for (i = 0; i < shape->num_boundaries; ++i) { - if (shape->boundaries[i].source_offset > source_offset && (shape->boundaries[i].flags & flags)) { - return shape->boundaries[i].source_offset; - } - } - return shape->source_len; -} - -NK_INTERN nk_bool -nk_text_shape_cluster_glyph_bounds(const struct nk_text_shape *shape, int cluster_idx, - float *left, float *right, enum nk_text_direction *direction) -{ - float pen = 0.0f; - int run_idx; - nk_bool found = nk_false; - - for (run_idx = 0; run_idx < shape->num_runs; ++run_idx) { - struct nk_text_run *run = &shape->runs[run_idx]; - int glyph_idx; - - for (glyph_idx = run->glyph_begin; glyph_idx < run->glyph_begin + run->glyph_count; ++glyph_idx) { - struct nk_text_glyph *glyph = &shape->glyphs[glyph_idx]; - float next = pen + glyph->advance_x; - - if (glyph->cluster_idx == cluster_idx) { - if (!found) { - *left = NK_MIN(pen, next); - *right = NK_MAX(pen, next); - found = nk_true; - } else { - *left = NK_MIN(*left, NK_MIN(pen, next)); - *right = NK_MAX(*right, NK_MAX(pen, next)); - } - *direction = run->direction; - } - pen = next; - } - } - return found; -} - -NK_INTERN nk_bool -nk_text_shape_cluster_bounds(const struct nk_text_shape *shape, int cluster_idx, float *left, float *right, enum nk_text_direction *direction) -{ - int owner = cluster_idx; - int group_end; - int group_count; - int group_offset; - float group_left; - float group_right; - float width; - - while (owner > 0 && !shape->clusters[owner].glyph_count) { - owner -= 1; - } - if (!shape->clusters[owner].glyph_count || - !nk_text_shape_cluster_glyph_bounds(shape, owner, &group_left, &group_right, direction)) { - return nk_false; - } - - group_end = owner + 1; - while (group_end < shape->num_clusters && !shape->clusters[group_end].glyph_count) { - group_end += 1; - } - if (cluster_idx >= group_end) { - return nk_false; - } - - group_count = group_end - owner; - group_offset = cluster_idx - owner; - width = (group_right - group_left) / group_count; - if (*direction == NK_TEXT_DIRECTION_RTL) { - *left = group_right - width * (group_offset + 1); - *right = group_right - width * group_offset; - } else { - *left = group_left + width * group_offset; - *right = *left + width; - } - return nk_true; -} - -NK_INTERN struct nk_text_cursor -nk_text_shape_cluster_edge(const struct nk_text_shape *shape, int cluster_idx, enum nk_text_affinity affinity) -{ - struct nk_text_cluster *cluster = &shape->clusters[cluster_idx]; - struct nk_text_cursor cursor; - enum nk_text_direction direction; - float left; - float right; - - cursor.source_offset = affinity == NK_TEXT_AFFINITY_LEADING ? cluster->source_begin : cluster->source_end; - cursor.affinity = affinity; - if (nk_text_shape_cluster_bounds(shape, cluster_idx, &left, &right, &direction)) { - if (direction == NK_TEXT_DIRECTION_RTL) { - cursor.x = affinity == NK_TEXT_AFFINITY_LEADING ? right : left; - } else { - cursor.x = affinity == NK_TEXT_AFFINITY_LEADING ? left : right; - } - return cursor; - } - - if (affinity == NK_TEXT_AFFINITY_LEADING) { - int previous; - for (previous = cluster_idx - 1; previous >= 0; --previous) { - if (shape->clusters[previous].glyph_count) { - cursor.x = nk_text_shape_cluster_edge(shape, previous, NK_TEXT_AFFINITY_TRAILING).x; - return cursor; - } - } - } else { - int next; - for (next = cluster_idx + 1; next < shape->num_clusters; ++next) { - if (shape->clusters[next].glyph_count) { - cursor.x = nk_text_shape_cluster_edge(shape, next, NK_TEXT_AFFINITY_LEADING).x; - return cursor; - } - } - } - cursor.x = affinity == NK_TEXT_AFFINITY_LEADING ? 0.0f : shape->advance.x; - return cursor; -} - -NK_API struct nk_text_cursor -nk_text_shape_cursor_at(const struct nk_text_shape *shape, int source_offset, enum nk_text_affinity affinity) -{ - struct nk_text_cursor cursor; - int cluster_idx; - - cursor.source_offset = NK_CLAMP(0, source_offset, shape->source_len); - cursor.affinity = affinity; - cursor.x = source_offset <= 0 ? 0.0f : shape->advance.x; - - if (affinity == NK_TEXT_AFFINITY_LEADING) { - for (cluster_idx = 0; cluster_idx < shape->num_clusters; ++cluster_idx) { - if (shape->clusters[cluster_idx].source_begin == cursor.source_offset) { - return nk_text_shape_cluster_edge(shape, cluster_idx, affinity); - } - } - } else { - for (cluster_idx = shape->num_clusters - 1; cluster_idx >= 0; --cluster_idx) { - if (shape->clusters[cluster_idx].source_end == cursor.source_offset) { - return nk_text_shape_cluster_edge(shape, cluster_idx, affinity); - } - } - } - return cursor; -} - -NK_API struct nk_text_cursor -nk_text_shape_hit_test(const struct nk_text_shape *shape, float x) -{ - struct nk_text_cursor first = nk_text_shape_cursor_at(shape, 0, NK_TEXT_AFFINITY_LEADING); - struct nk_text_cursor last = nk_text_shape_cursor_at(shape, shape->source_len, NK_TEXT_AFFINITY_TRAILING); - float pen = 0.0f; - int run_idx; - - if (x <= 0.0f) { - return first.x <= last.x ? first : last; - } - - if (x >= shape->advance.x) { - return first.x >= last.x ? first : last; - } - - for (run_idx = 0; run_idx < shape->num_runs; ++run_idx) { - struct nk_text_run *run = &shape->runs[run_idx]; - int glyph_idx = run->glyph_begin; - - while (glyph_idx < run->glyph_begin + run->glyph_count) { - struct nk_text_glyph *glyph = &shape->glyphs[glyph_idx]; - int cluster_idx = glyph->cluster_idx; - float begin = pen; - - do { - pen += shape->glyphs[glyph_idx].advance_x; - glyph_idx += 1; - } while (glyph_idx < run->glyph_begin + run->glyph_count && shape->glyphs[glyph_idx].cluster_idx == cluster_idx); - - if (x < (begin + pen) * 0.5f) { - return nk_text_shape_cluster_edge(shape, cluster_idx, run->direction == NK_TEXT_DIRECTION_RTL ? NK_TEXT_AFFINITY_TRAILING : NK_TEXT_AFFINITY_LEADING); - } - - if (x <= pen) { - return nk_text_shape_cluster_edge(shape, cluster_idx, run->direction == NK_TEXT_DIRECTION_RTL ? NK_TEXT_AFFINITY_LEADING : NK_TEXT_AFFINITY_TRAILING); - } - } - } - return last; -} - -NK_API struct nk_text_cursor -nk_text_shape_cursor_move(const struct nk_text_shape *shape, struct nk_text_cursor cursor, int direction) -{ - struct nk_text_cursor current = nk_text_shape_cursor_at(shape, cursor.source_offset, cursor.affinity); - struct nk_text_cursor best = current; - int cluster_idx; - - for (cluster_idx = 0; cluster_idx < shape->num_clusters; ++cluster_idx) { - struct nk_text_cursor leading = nk_text_shape_cluster_edge(shape, cluster_idx, NK_TEXT_AFFINITY_LEADING); - struct nk_text_cursor trailing = nk_text_shape_cluster_edge(shape, cluster_idx, NK_TEXT_AFFINITY_TRAILING); - struct nk_text_cursor edges[] = {leading, trailing}; - int edge_idx; - - for (edge_idx = 0; edge_idx < 2; ++edge_idx) { - struct nk_text_cursor edge = edges[edge_idx]; - if (direction < 0 && edge.x < current.x && (best.x == current.x || edge.x > best.x)) { - best = edge; - } - - if (direction > 0 && edge.x > current.x && (best.x == current.x || edge.x < best.x)) { - best = edge; - } - } - } - return best; -} - -NK_API void -nk_text_selection_iterator_begin(struct nk_text_selection_iterator *iterator, const struct nk_text_shape *shape, int source_begin, int source_end) -{ - NK_MEMSET(iterator, 0, sizeof(*iterator)); - iterator->shape = shape; - iterator->source_begin = NK_CLAMP(0, source_begin, shape->source_len); - iterator->source_end = NK_CLAMP(iterator->source_begin, source_end, shape->source_len); - iterator->glyph_idx = shape->num_runs ? shape->runs[0].glyph_begin : 0; -} - -NK_API nk_bool -nk_text_selection_iterator_next(struct nk_text_selection_iterator *iterator, struct nk_text_selection_span *span) -{ - const struct nk_text_shape *shape = iterator->shape; - nk_bool inside = nk_false; - - if (iterator->has_pending) { - span->x = iterator->pending_x; - span->width = iterator->pending_width; - iterator->has_pending = nk_false; - inside = nk_true; - } - - while (iterator->run_idx < shape->num_runs) { - struct nk_text_run *run = &shape->runs[iterator->run_idx]; - - while (iterator->glyph_idx < run->glyph_begin + run->glyph_count) { - int cluster_idx = shape->glyphs[iterator->glyph_idx].cluster_idx; - int group_end = cluster_idx + 1; - int selected_begin = 0; - int selected_end = 0; - int group_count = 0; - float group_left = iterator->pen_x; - float group_right = 0; - float selected_left = 0; - float selected_right = 0; - - do { - iterator->pen_x += shape->glyphs[iterator->glyph_idx].advance_x; - iterator->glyph_idx += 1; - } while (iterator->glyph_idx < run->glyph_begin + run->glyph_count && shape->glyphs[iterator->glyph_idx].cluster_idx == cluster_idx); - group_right = iterator->pen_x; - - while (group_end < shape->num_clusters && !shape->clusters[group_end].glyph_count) { - group_end += 1; - } - - selected_begin = cluster_idx; - while (selected_begin < group_end && shape->clusters[selected_begin].source_end <= iterator->source_begin) { - selected_begin += 1; - } - - selected_end = selected_begin; - while (selected_end < group_end && shape->clusters[selected_end].source_begin < iterator->source_end) { - selected_end += 1; - } - - if (selected_begin == selected_end) { - if (inside) { - return nk_true; - } - continue; - } - - group_count = group_end - cluster_idx; - if (run->direction == NK_TEXT_DIRECTION_RTL) { - selected_left = group_right - (group_right - group_left) * (selected_end - cluster_idx) / group_count; - selected_right = group_right - (group_right - group_left) * (selected_begin - cluster_idx) / group_count; - } else { - selected_left = group_left + (group_right - group_left) * (selected_begin - cluster_idx) / group_count; - selected_right = group_left + (group_right - group_left) * (selected_end - cluster_idx) / group_count; - } - - if (!inside) { - span->x = selected_left; - span->width = selected_right - selected_left; - inside = nk_true; - } else if (selected_left == span->x + span->width) { - span->width = selected_right - span->x; - } else { - iterator->pending_x = selected_left; - iterator->pending_width = selected_right - selected_left; - iterator->has_pending = nk_true; - return nk_true; - } - } - - iterator->run_idx += 1; - if (iterator->run_idx < shape->num_runs) { - iterator->glyph_idx = shape->runs[iterator->run_idx].glyph_begin; - } - } - - if (inside) { - return nk_true; - } - return nk_false; -} - -NK_API void -nk_text_wrap_iterator_begin(struct nk_text_wrap_iterator *iterator, const struct nk_text_shape *shape, float max_width) -{ - NK_ASSERT(iterator); - NK_MEMSET(iterator, 0, sizeof(*iterator)); - iterator->shape = shape; - iterator->max_width = NK_MAX(0.0f, max_width); -} - -NK_INTERN float -nk_text_cluster_width(const struct nk_text_shape *shape, int cluster_idx) -{ - struct nk_text_cluster *cluster = &shape->clusters[cluster_idx]; - float width = 0.0f; - int glyph_idx; - - for (glyph_idx = cluster->glyph_begin; glyph_idx < cluster->glyph_begin + cluster->glyph_count; ++glyph_idx) { - width += shape->glyphs[glyph_idx].advance_x; - } - return width; -} - -NK_INTERN nk_flags -nk_text_boundary_flags_at(const struct nk_text_shape *shape, int *boundary_idx, int source_offset) -{ - nk_flags flags = 0; - - while (*boundary_idx < shape->num_boundaries && shape->boundaries[*boundary_idx].source_offset <= source_offset) { - struct nk_text_boundary *boundary = &shape->boundaries[*boundary_idx]; - if (boundary->source_offset == source_offset) { - flags |= boundary->flags; - } - *boundary_idx += 1; - } - return flags; -} - -NK_INTERN nk_bool -nk_text_wrap_line_set(struct nk_text_wrap_iterator *iterator, struct nk_text_wrap_line *line, - int source_end, float width, nk_flags flags, int cluster_idx, int boundary_idx) -{ - line->source_begin = iterator->source_offset; - line->source_end = source_end; - line->width = width; - line->break_flags = flags; - iterator->source_offset = source_end; - iterator->cluster_idx = cluster_idx; - iterator->boundary_idx = boundary_idx; - return nk_true; -} - -NK_API nk_bool -nk_text_wrap_iterator_next(struct nk_text_wrap_iterator *iterator, struct nk_text_wrap_line *line) -{ - const struct nk_text_shape *shape; - int line_cluster_begin; - int cluster_idx; - int boundary_idx; - int soft_source_end = 0; - int soft_cluster_idx = 0; - int soft_boundary_idx = 0; - float soft_width = 0.0f; - float width = 0.0f; - - NK_ASSERT(iterator); - NK_ASSERT(line); - shape = iterator->shape; - if (!shape || iterator->source_offset >= shape->source_len) { - return nk_false; - } - - line_cluster_begin = iterator->cluster_idx; - cluster_idx = iterator->cluster_idx; - boundary_idx = iterator->boundary_idx; - while (boundary_idx < shape->num_boundaries && shape->boundaries[boundary_idx].source_offset <= iterator->source_offset) { - boundary_idx += 1; - } - - while (cluster_idx < shape->num_clusters) { - const struct nk_text_cluster *cluster = &shape->clusters[cluster_idx]; - float next_width = width + nk_text_cluster_width(shape, cluster_idx); - nk_flags flags; - - if (next_width > iterator->max_width && cluster_idx > line_cluster_begin) { - if (soft_source_end > iterator->source_offset) { - return nk_text_wrap_line_set(iterator, line, soft_source_end, soft_width, NK_TEXT_BOUNDARY_LINE_SOFT, soft_cluster_idx, soft_boundary_idx); - } - return nk_text_wrap_line_set(iterator, line, cluster->source_begin, width, NK_TEXT_BOUNDARY_GRAPHEME, cluster_idx, boundary_idx); - } - - width = next_width; - flags = nk_text_boundary_flags_at(shape, &boundary_idx, cluster->source_end); - cluster_idx += 1; - - if (flags & NK_TEXT_BOUNDARY_LINE_HARD) { - return nk_text_wrap_line_set(iterator, line, cluster->source_end, width, flags, cluster_idx, boundary_idx); - } - - if (flags & NK_TEXT_BOUNDARY_LINE_SOFT) { - soft_source_end = cluster->source_end; - soft_cluster_idx = cluster_idx; - soft_boundary_idx = boundary_idx; - soft_width = width; - } - - if (width > iterator->max_width && cluster_idx == line_cluster_begin + 1) { - return nk_text_wrap_line_set(iterator, line, cluster->source_end, width, NK_TEXT_BOUNDARY_GRAPHEME, cluster_idx, boundary_idx); - } - } - - return nk_text_wrap_line_set(iterator, line, shape->source_len, width, 0, shape->num_clusters, shape->num_boundaries); -} - -NK_API float -nk_text_width(struct nk_context *ctx, const struct nk_user_font *font, float height, const char *text, int len) -{ - struct nk_text_request request; - struct nk_text_cache_entry *entry; - struct nk_text_shape *shape; - nk_hash hash; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->text_memory_initialized); - NK_ASSERT(ctx->text_backend.build); - if (!len) { - return 0.0f; - } - - NK_MEMSET(&request, 0, sizeof(request)); - request.source = text; - request.source_len = len; - request.font = font; - request.font_height = height; - - NK_PROFILE_SCOPE_BEGIN("text.measure_cache_lookup", measure_cache_lookup); - { - hash = nk_text_request_hash(&request); - entry = nk_text_cache_find(ctx, &request, hash); - } - NK_PROFILE_SCOPE_END(measure_cache_lookup); - - if (entry) { - return entry->width; - } - - if (!ctx->text_backend.temporary) { - shape = nk_text_shape_build(ctx, &request); - return shape ? shape->advance.x : 0.0f; - } - - nk_buffer_clear(ctx->text_backend.temporary); - - NK_PROFILE_SCOPE_BEGIN("text.measure_backend", measure_backend); - { - shape = ctx->text_backend.build(ctx->text_backend.userdata, ctx->text_backend.temporary, &request); - } - NK_PROFILE_SCOPE_END(measure_backend); - - if (!shape) { - return 0.0f; - } - - if (ctx->text_cache_buckets) { - entry = nk_text_cache_alloc(ctx, &request, hash); - if (entry) { - entry->width = shape->advance.x; - nk_text_cache_link(ctx, entry); - } - } - return shape->advance.x; -} - -/* ============================================================== - * - * COLOR - * - * ===============================================================*/ -NK_INTERN int -nk_parse_hex(const char *p, int length) -{ - int i = 0; - int len = 0; - while (len < length) { - i <<= 4; - if (p[len] >= 'a' && p[len] <= 'f') { - i += ((p[len] - 'a') + 10); - } else if (p[len] >= 'A' && p[len] <= 'F') { - i += ((p[len] - 'A') + 10); - } else { - i += (p[len] - '0'); - } - len++; - } - return i; -} -NK_API struct nk_color -nk_rgb_factor(struct nk_color col, float factor) -{ - if (factor == 1.0f) { - return col; - } - col.r = (nk_byte)(col.r * factor); - col.g = (nk_byte)(col.g * factor); - col.b = (nk_byte)(col.b * factor); - return col; -} -NK_API struct nk_color -nk_rgba(int r, int g, int b, int a) -{ - struct nk_color ret; - ret.r = (nk_byte)NK_CLAMP(0, r, 255); - ret.g = (nk_byte)NK_CLAMP(0, g, 255); - ret.b = (nk_byte)NK_CLAMP(0, b, 255); - ret.a = (nk_byte)NK_CLAMP(0, a, 255); - return ret; -} -NK_API struct nk_color -nk_rgb_hex(const char *rgb) -{ - struct nk_color col; - const char *c = rgb; - if (*c == '#') { - c++; - } - col.r = (nk_byte)nk_parse_hex(c, 2); - col.g = (nk_byte)nk_parse_hex(c + 2, 2); - col.b = (nk_byte)nk_parse_hex(c + 4, 2); - col.a = 255; - return col; -} -NK_API struct nk_color -nk_rgba_hex(const char *rgb) -{ - struct nk_color col; - const char *c = rgb; - if (*c == '#') { - c++; - } - col.r = (nk_byte)nk_parse_hex(c, 2); - col.g = (nk_byte)nk_parse_hex(c + 2, 2); - col.b = (nk_byte)nk_parse_hex(c + 4, 2); - col.a = (nk_byte)nk_parse_hex(c + 6, 2); - return col; -} -NK_API void -nk_color_hex_rgba(char *output, struct nk_color col) -{ -#define NK_TO_HEX(i) ((i) <= 9 ? '0' + (i) : 'A' - 10 + (i)) - output[0] = (char)NK_TO_HEX((col.r & 0xF0) >> 4); - output[1] = (char)NK_TO_HEX((col.r & 0x0F)); - output[2] = (char)NK_TO_HEX((col.g & 0xF0) >> 4); - output[3] = (char)NK_TO_HEX((col.g & 0x0F)); - output[4] = (char)NK_TO_HEX((col.b & 0xF0) >> 4); - output[5] = (char)NK_TO_HEX((col.b & 0x0F)); - output[6] = (char)NK_TO_HEX((col.a & 0xF0) >> 4); - output[7] = (char)NK_TO_HEX((col.a & 0x0F)); - output[8] = '\0'; -#undef NK_TO_HEX -} -NK_API void -nk_color_hex_rgb(char *output, struct nk_color col) -{ -#define NK_TO_HEX(i) ((i) <= 9 ? '0' + (i) : 'A' - 10 + (i)) - output[0] = (char)NK_TO_HEX((col.r & 0xF0) >> 4); - output[1] = (char)NK_TO_HEX((col.r & 0x0F)); - output[2] = (char)NK_TO_HEX((col.g & 0xF0) >> 4); - output[3] = (char)NK_TO_HEX((col.g & 0x0F)); - output[4] = (char)NK_TO_HEX((col.b & 0xF0) >> 4); - output[5] = (char)NK_TO_HEX((col.b & 0x0F)); - output[6] = '\0'; -#undef NK_TO_HEX -} -NK_API struct nk_color -nk_rgba_iv(const int *c) -{ - return nk_rgba(c[0], c[1], c[2], c[3]); -} -NK_API struct nk_color -nk_rgba_bv(const nk_byte *c) -{ - return nk_rgba(c[0], c[1], c[2], c[3]); -} -NK_API struct nk_color -nk_rgb(int r, int g, int b) -{ - struct nk_color ret; - ret.r = (nk_byte)NK_CLAMP(0, r, 255); - ret.g = (nk_byte)NK_CLAMP(0, g, 255); - ret.b = (nk_byte)NK_CLAMP(0, b, 255); - ret.a = (nk_byte)255; - return ret; -} -NK_API struct nk_color -nk_rgb_iv(const int *c) -{ - return nk_rgb(c[0], c[1], c[2]); -} -NK_API struct nk_color -nk_rgb_bv(const nk_byte *c) -{ - return nk_rgb(c[0], c[1], c[2]); -} -NK_API struct nk_color -nk_rgba_u32(nk_uint in) -{ - struct nk_color ret; - ret.r = (in & 0xFF); - ret.g = ((in >> 8) & 0xFF); - ret.b = ((in >> 16) & 0xFF); - ret.a = (nk_byte)((in >> 24) & 0xFF); - return ret; -} -NK_API struct nk_color -nk_rgba_f(float r, float g, float b, float a) -{ - struct nk_color ret; - ret.r = (nk_byte)(NK_SATURATE(r) * 255.0f); - ret.g = (nk_byte)(NK_SATURATE(g) * 255.0f); - ret.b = (nk_byte)(NK_SATURATE(b) * 255.0f); - ret.a = (nk_byte)(NK_SATURATE(a) * 255.0f); - return ret; -} -NK_API struct nk_color -nk_rgba_fv(const float *c) -{ - return nk_rgba_f(c[0], c[1], c[2], c[3]); -} -NK_API struct nk_color -nk_rgba_cf(struct nk_colorf c) -{ - return nk_rgba_f(c.r, c.g, c.b, c.a); -} -NK_API struct nk_color -nk_rgb_f(float r, float g, float b) -{ - struct nk_color ret; - ret.r = (nk_byte)(NK_SATURATE(r) * 255.0f); - ret.g = (nk_byte)(NK_SATURATE(g) * 255.0f); - ret.b = (nk_byte)(NK_SATURATE(b) * 255.0f); - ret.a = 255; - return ret; -} -NK_API struct nk_color -nk_rgb_fv(const float *c) -{ - return nk_rgb_f(c[0], c[1], c[2]); -} -NK_API struct nk_color -nk_rgb_cf(struct nk_colorf c) -{ - return nk_rgb_f(c.r, c.g, c.b); -} -NK_API struct nk_color -nk_hsv(int h, int s, int v) -{ - return nk_hsva(h, s, v, 255); -} -NK_API struct nk_color -nk_hsv_iv(const int *c) -{ - return nk_hsv(c[0], c[1], c[2]); -} -NK_API struct nk_color -nk_hsv_bv(const nk_byte *c) -{ - return nk_hsv(c[0], c[1], c[2]); -} -NK_API struct nk_color -nk_hsv_f(float h, float s, float v) -{ - return nk_hsva_f(h, s, v, 1.0f); -} -NK_API struct nk_color -nk_hsv_fv(const float *c) -{ - return nk_hsv_f(c[0], c[1], c[2]); -} -NK_API struct nk_color -nk_hsva(int h, int s, int v, int a) -{ - float hf = ((float)NK_CLAMP(0, h, 255)) / 255.0f; - float sf = ((float)NK_CLAMP(0, s, 255)) / 255.0f; - float vf = ((float)NK_CLAMP(0, v, 255)) / 255.0f; - float af = ((float)NK_CLAMP(0, a, 255)) / 255.0f; - return nk_hsva_f(hf, sf, vf, af); -} -NK_API struct nk_color -nk_hsva_iv(const int *c) -{ - return nk_hsva(c[0], c[1], c[2], c[3]); -} -NK_API struct nk_color -nk_hsva_bv(const nk_byte *c) -{ - return nk_hsva(c[0], c[1], c[2], c[3]); -} -NK_API struct nk_colorf -nk_hsva_colorf(float h, float s, float v, float a) -{ - int i; - float p, q, t, f; - struct nk_colorf out = {0, 0, 0, 0}; - if (s <= 0.0f) { - out.r = v; - out.g = v; - out.b = v; - out.a = a; - return out; - } - h = h / (60.0f / 360.0f); - i = (int)h; - f = h - (float)i; - p = v * (1.0f - s); - q = v * (1.0f - (s * f)); - t = v * (1.0f - s * (1.0f - f)); - - switch (i) { - case 0: - default: - out.r = v; - out.g = t; - out.b = p; - break; - case 1: - out.r = q; - out.g = v; - out.b = p; - break; - case 2: - out.r = p; - out.g = v; - out.b = t; - break; - case 3: - out.r = p; - out.g = q; - out.b = v; - break; - case 4: - out.r = t; - out.g = p; - out.b = v; - break; - case 5: - out.r = v; - out.g = p; - out.b = q; - break; - } - out.a = a; - return out; -} -NK_API struct nk_colorf -nk_hsva_colorfv(const float *c) -{ - return nk_hsva_colorf(c[0], c[1], c[2], c[3]); -} -NK_API struct nk_color -nk_hsva_f(float h, float s, float v, float a) -{ - struct nk_colorf c = nk_hsva_colorf(h, s, v, a); - return nk_rgba_f(c.r, c.g, c.b, c.a); -} -NK_API struct nk_color -nk_hsva_fv(const float *c) -{ - return nk_hsva_f(c[0], c[1], c[2], c[3]); -} -NK_API nk_uint -nk_color_u32(struct nk_color in) -{ - nk_uint out = (nk_uint)in.r; - out |= ((nk_uint)in.g << 8); - out |= ((nk_uint)in.b << 16); - out |= ((nk_uint)in.a << 24); - return out; -} -NK_API void -nk_color_f(float *r, float *g, float *b, float *a, struct nk_color in) -{ - NK_STORAGE const float s = 1.0f / 255.0f; - *r = (float)in.r * s; - *g = (float)in.g * s; - *b = (float)in.b * s; - *a = (float)in.a * s; -} -NK_API void -nk_color_fv(float *c, struct nk_color in) -{ - nk_color_f(&c[0], &c[1], &c[2], &c[3], in); -} -NK_API struct nk_colorf -nk_color_cf(struct nk_color in) -{ - struct nk_colorf o; - nk_color_f(&o.r, &o.g, &o.b, &o.a, in); - return o; -} -NK_API void -nk_color_d(double *r, double *g, double *b, double *a, struct nk_color in) -{ - NK_STORAGE const double s = 1.0 / 255.0; - *r = (double)in.r * s; - *g = (double)in.g * s; - *b = (double)in.b * s; - *a = (double)in.a * s; -} -NK_API void -nk_color_dv(double *c, struct nk_color in) -{ - nk_color_d(&c[0], &c[1], &c[2], &c[3], in); -} -NK_API void -nk_color_hsv_f(float *out_h, float *out_s, float *out_v, struct nk_color in) -{ - float a; - nk_color_hsva_f(out_h, out_s, out_v, &a, in); -} -NK_API void -nk_color_hsv_fv(float *out, struct nk_color in) -{ - float a; - nk_color_hsva_f(&out[0], &out[1], &out[2], &a, in); -} -NK_API void -nk_colorf_hsva_f(float *out_h, float *out_s, float *out_v, float *out_a, struct nk_colorf in) -{ - float chroma; - float K = 0.0f; - if (in.g < in.b) { - const float t = in.g; - in.g = in.b; - in.b = t; - K = -1.f; - } - if (in.r < in.g) { - const float t = in.r; - in.r = in.g; - in.g = t; - K = -2.f / 6.0f - K; - } - chroma = in.r - ((in.g < in.b) ? in.g : in.b); - *out_h = NK_ABS(K + (in.g - in.b) / (6.0f * chroma + 1e-20f)); - *out_s = chroma / (in.r + 1e-20f); - *out_v = in.r; - *out_a = in.a; -} -NK_API void -nk_colorf_hsva_fv(float *hsva, struct nk_colorf in) -{ - nk_colorf_hsva_f(&hsva[0], &hsva[1], &hsva[2], &hsva[3], in); -} -NK_API void -nk_color_hsva_f(float *out_h, float *out_s, float *out_v, float *out_a, struct nk_color in) -{ - struct nk_colorf col; - nk_color_f(&col.r, &col.g, &col.b, &col.a, in); - nk_colorf_hsva_f(out_h, out_s, out_v, out_a, col); -} -NK_API void -nk_color_hsva_fv(float *out, struct nk_color in) -{ - nk_color_hsva_f(&out[0], &out[1], &out[2], &out[3], in); -} -NK_API void -nk_color_hsva_i(int *out_h, int *out_s, int *out_v, int *out_a, struct nk_color in) -{ - float h, s, v, a; - nk_color_hsva_f(&h, &s, &v, &a, in); - *out_h = (nk_byte)(h * 255.0f); - *out_s = (nk_byte)(s * 255.0f); - *out_v = (nk_byte)(v * 255.0f); - *out_a = (nk_byte)(a * 255.0f); -} -NK_API void -nk_color_hsva_iv(int *out, struct nk_color in) -{ - nk_color_hsva_i(&out[0], &out[1], &out[2], &out[3], in); -} -NK_API void -nk_color_hsva_bv(nk_byte *out, struct nk_color in) -{ - int tmp[4]; - nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in); - out[0] = (nk_byte)tmp[0]; - out[1] = (nk_byte)tmp[1]; - out[2] = (nk_byte)tmp[2]; - out[3] = (nk_byte)tmp[3]; -} -NK_API void -nk_color_hsva_b(nk_byte *h, nk_byte *s, nk_byte *v, nk_byte *a, struct nk_color in) -{ - int tmp[4]; - nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in); - *h = (nk_byte)tmp[0]; - *s = (nk_byte)tmp[1]; - *v = (nk_byte)tmp[2]; - *a = (nk_byte)tmp[3]; -} -NK_API void -nk_color_hsv_i(int *out_h, int *out_s, int *out_v, struct nk_color in) -{ - int a; - nk_color_hsva_i(out_h, out_s, out_v, &a, in); -} -NK_API void -nk_color_hsv_b(nk_byte *out_h, nk_byte *out_s, nk_byte *out_v, struct nk_color in) -{ - int tmp[4]; - nk_color_hsva_i(&tmp[0], &tmp[1], &tmp[2], &tmp[3], in); - *out_h = (nk_byte)tmp[0]; - *out_s = (nk_byte)tmp[1]; - *out_v = (nk_byte)tmp[2]; -} -NK_API void -nk_color_hsv_iv(int *out, struct nk_color in) -{ - nk_color_hsv_i(&out[0], &out[1], &out[2], in); -} -NK_API void -nk_color_hsv_bv(nk_byte *out, struct nk_color in) -{ - int tmp[4]; - nk_color_hsv_i(&tmp[0], &tmp[1], &tmp[2], in); - out[0] = (nk_byte)tmp[0]; - out[1] = (nk_byte)tmp[1]; - out[2] = (nk_byte)tmp[2]; -} - -/* =============================================================== - * - * UTF-8 - * - * ===============================================================*/ -NK_GLOBAL const nk_byte nk_utfbyte[NK_UTF_SIZE + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0}; -NK_GLOBAL const nk_byte nk_utfmask[NK_UTF_SIZE + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; -NK_GLOBAL const nk_uint nk_utfmin[NK_UTF_SIZE + 1] = {0, 0, 0x80, 0x800, 0x10000}; -NK_GLOBAL const nk_uint nk_utfmax[NK_UTF_SIZE + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; - -NK_INTERN int -nk_utf_validate(nk_rune *u, int i) -{ - NK_ASSERT(u != NULL); - if (!u) { - return 0; - } - if (!NK_BETWEEN(*u, nk_utfmin[i], nk_utfmax[i]) || NK_BETWEEN(*u, 0xD800, 0xDFFF)) { - *u = NK_UTF_INVALID; - } - for (i = 1; *u > nk_utfmax[i]; ++i) - ; - return i; -} -NK_INTERN nk_rune -nk_utf_decode_byte(char c, int *i) -{ - NK_ASSERT(i != NULL); - if (!i) { - return 0; - } - for (*i = 0; *i < (int)NK_LEN(nk_utfmask); ++(*i)) { - if (((nk_byte)c & nk_utfmask[*i]) == nk_utfbyte[*i]) { - return (nk_byte)(c & ~nk_utfmask[*i]); - } - } - return 0; -} -NK_API int -nk_utf_decode(const char *c, nk_rune *u, int clen) -{ - int i, j, len, type = 0; - nk_rune udecoded; - - NK_ASSERT(c != NULL); - NK_ASSERT(u != NULL); - - if (!c || !u) { - return 0; - } - if (!clen) { - return 0; - } - *u = NK_UTF_INVALID; - - udecoded = nk_utf_decode_byte(c[0], &len); - if (!NK_BETWEEN(len, 1, NK_UTF_SIZE + 1)) { /* +1 because NK_BETWEEN uses strict upper bound ((a) <= (x) && (x) < (b)) */ - return 1; - } - - for (i = 1, j = 1; i < clen && j < len; ++i, ++j) { - udecoded = (udecoded << 6) | nk_utf_decode_byte(c[i], &type); - if (type != 0) { - return j; - } - } - if (j < len) { - return 0; - } - *u = udecoded; - nk_utf_validate(u, len); - return len; -} -NK_INTERN char -nk_utf_encode_byte(nk_rune u, int i) -{ - return (char)((nk_utfbyte[i]) | ((nk_byte)u & ~nk_utfmask[i])); -} -NK_API int -nk_utf_encode(nk_rune u, char *c, int clen) -{ - int len, i; - len = nk_utf_validate(&u, 0); - if (clen < len || !len || len > NK_UTF_SIZE) { - return 0; - } - - for (i = len - 1; i != 0; --i) { - c[i] = nk_utf_encode_byte(u, 0); - u >>= 6; - } - c[0] = nk_utf_encode_byte(u, len); - return len; -} -NK_API int -nk_utf_len(const char *str, int len) -{ - const char *text; - int glyphs = 0; - int text_len; - int glyph_len; - int src_len = 0; - nk_rune unicode; - - NK_ASSERT(str); - if (!str || !len) { - return 0; - } - - text = str; - text_len = len; - glyph_len = nk_utf_decode(text, &unicode, text_len); - while (glyph_len && src_len < len) { - glyphs++; - src_len = src_len + glyph_len; - glyph_len = nk_utf_decode(text + src_len, &unicode, text_len - src_len); - } - return glyphs; -} -NK_API const char * -nk_utf_at(const char *buffer, int length, int index, nk_rune *unicode, int *len) -{ - int i = 0; - int src_len = 0; - int glyph_len = 0; - const char *text; - int text_len; - - NK_ASSERT(buffer); - NK_ASSERT(unicode); - NK_ASSERT(len); - - if (!buffer || !unicode || !len) { - return 0; - } - if (index < 0) { - *unicode = NK_UTF_INVALID; - *len = 0; - return 0; - } - - text = buffer; - text_len = length; - glyph_len = nk_utf_decode(text, unicode, text_len); - while (glyph_len) { - if (i == index) { - *len = glyph_len; - break; - } - - i++; - src_len = src_len + glyph_len; - glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len); - } - if (i != index) { - return 0; - } - return buffer + src_len; -} - -/* ============================================================== - * - * BUFFER - * - * ===============================================================*/ -#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR -NK_LIB void * -nk_malloc(nk_handle unused, void *old, nk_size size) -{ - NK_UNUSED(unused); - NK_UNUSED(old); - return malloc(size); -} -NK_LIB void -nk_mfree(nk_handle unused, void *ptr) -{ - NK_UNUSED(unused); - free(ptr); -} -NK_API void -nk_buffer_init_default(struct nk_buffer *buffer) -{ - struct nk_allocator alloc; - alloc.userdata.ptr = 0; - alloc.alloc = nk_malloc; - alloc.free = nk_mfree; - nk_buffer_init(buffer, &alloc, NK_BUFFER_DEFAULT_INITIAL_SIZE); -} -#endif - -NK_API void -nk_buffer_init(struct nk_buffer *b, const struct nk_allocator *a, nk_size initial_size) -{ - NK_ASSERT(b); - NK_ASSERT(a); - NK_ASSERT(initial_size); - if (!b || !a || !initial_size) { - return; - } - - nk_zero(b, sizeof(*b)); - b->type = NK_BUFFER_DYNAMIC; - b->memory.ptr = a->alloc(a->userdata, 0, initial_size); - b->memory.size = initial_size; - b->size = initial_size; - b->grow_factor = 2.0f; - b->pool = *a; -} -NK_API void -nk_buffer_init_fixed(struct nk_buffer *b, void *m, nk_size size) -{ - NK_ASSERT(b); - NK_ASSERT(m); - NK_ASSERT(size); - if (!b || !m || !size) { - return; - } - - nk_zero(b, sizeof(*b)); - b->type = NK_BUFFER_FIXED; - b->memory.ptr = m; - b->memory.size = size; - b->size = size; -} -NK_LIB void * -nk_buffer_align(void *unaligned, nk_size align, nk_size *alignment, enum nk_buffer_allocation_type type) -{ - void *memory = 0; - switch (type) { - default: - case NK_BUFFER_MAX: - case NK_BUFFER_FRONT: - if (align) { - memory = NK_ALIGN_PTR(unaligned, align); - *alignment = (nk_size)((nk_byte *)memory - (nk_byte *)unaligned); - } else { - memory = unaligned; - *alignment = 0; - } - break; - case NK_BUFFER_BACK: - if (align) { - memory = NK_ALIGN_PTR_BACK(unaligned, align); - *alignment = (nk_size)((nk_byte *)unaligned - (nk_byte *)memory); - } else { - memory = unaligned; - *alignment = 0; - } - break; - } - return memory; -} -NK_LIB void * -nk_buffer_realloc(struct nk_buffer *b, nk_size capacity, nk_size *size) -{ - void *temp; - nk_size buffer_size; - - NK_ASSERT(b); - NK_ASSERT(size); - if (!b || !size || !b->pool.alloc || !b->pool.free) { - return 0; - } - - buffer_size = b->memory.size; - temp = b->pool.alloc(b->pool.userdata, b->memory.ptr, capacity); - NK_ASSERT(temp); - if (!temp) { - return 0; - } - - *size = capacity; - if (temp != b->memory.ptr) { - NK_MEMCPY(temp, b->memory.ptr, buffer_size); - b->pool.free(b->pool.userdata, b->memory.ptr); - } - - if (b->size == buffer_size) { - /* no back buffer so just set correct size */ - b->size = capacity; - return temp; - } else { - /* copy back buffer to the end of the new buffer */ - void *dst, *src; - nk_size back_size; - back_size = buffer_size - b->size; - dst = nk_ptr_add(void, temp, capacity - back_size); - src = nk_ptr_add(void, temp, b->size); - NK_MEMCPY(dst, src, back_size); - b->size = capacity - back_size; - } - return temp; -} -NK_LIB void * -nk_buffer_alloc(struct nk_buffer *b, enum nk_buffer_allocation_type type, nk_size size, nk_size align) -{ - int full; - nk_size alignment; - void *unaligned; - void *memory; - - NK_ASSERT(b); - NK_ASSERT(size); - if (!b || !size) { - return 0; - } - b->needed += size; - - /* calculate total size with needed alignment + size */ - if (type == NK_BUFFER_FRONT) { - unaligned = nk_ptr_add(void, b->memory.ptr, b->allocated); - } else { - unaligned = nk_ptr_add(void, b->memory.ptr, b->size - size); - } - memory = nk_buffer_align(unaligned, align, &alignment, type); - - /* check if buffer has enough memory*/ - if (type == NK_BUFFER_FRONT) { - full = ((b->allocated + size + alignment) > b->size); - } else { - full = ((b->size - NK_MIN(b->size, (size + alignment))) <= b->allocated); - } - - if (full) { - nk_size capacity; - if (b->type != NK_BUFFER_DYNAMIC) { - return 0; - } - NK_ASSERT(b->pool.alloc && b->pool.free); - if (b->type != NK_BUFFER_DYNAMIC || !b->pool.alloc || !b->pool.free) { - return 0; - } - - /* buffer is full so allocate bigger buffer if dynamic */ - capacity = (nk_size)((float)b->memory.size * b->grow_factor); - capacity = NK_MAX(capacity, nk_round_up_pow2((nk_uint)(b->allocated + size))); - b->memory.ptr = nk_buffer_realloc(b, capacity, &b->memory.size); - if (!b->memory.ptr) { - return 0; - } - - /* align newly allocated pointer */ - if (type == NK_BUFFER_FRONT) { - unaligned = nk_ptr_add(void, b->memory.ptr, b->allocated); - } else { - unaligned = nk_ptr_add(void, b->memory.ptr, b->size - size); - } - memory = nk_buffer_align(unaligned, align, &alignment, type); - } - if (type == NK_BUFFER_FRONT) { - b->allocated += size + alignment; - } else { - b->size -= (size + alignment); - } - b->needed += alignment; - b->calls++; - return memory; -} -NK_API void -nk_buffer_push(struct nk_buffer *b, enum nk_buffer_allocation_type type, const void *memory, nk_size size, nk_size align) -{ - void *mem = nk_buffer_alloc(b, type, size, align); - if (!mem) { - return; - } - NK_MEMCPY(mem, memory, size); -} -NK_API void -nk_buffer_mark(struct nk_buffer *buffer, enum nk_buffer_allocation_type type) -{ - NK_ASSERT(buffer); - if (!buffer) { - return; - } - buffer->marker[type].active = nk_true; - if (type == NK_BUFFER_BACK) { - buffer->marker[type].offset = buffer->size; - } else { - buffer->marker[type].offset = buffer->allocated; - } -} -NK_API void -nk_buffer_reset(struct nk_buffer *buffer, enum nk_buffer_allocation_type type) -{ - NK_ASSERT(buffer); - if (!buffer) { - return; - } - if (type == NK_BUFFER_BACK) { - /* reset back buffer either back to marker or empty */ - buffer->needed -= (buffer->memory.size - buffer->marker[type].offset); - if (buffer->marker[type].active) { - buffer->size = buffer->marker[type].offset; - } else { - buffer->size = buffer->memory.size; - } - buffer->marker[type].active = nk_false; - } else { - /* reset front buffer either back to back marker or empty */ - buffer->needed -= (buffer->allocated - buffer->marker[type].offset); - if (buffer->marker[type].active) { - buffer->allocated = buffer->marker[type].offset; - } else { - buffer->allocated = 0; - } - buffer->marker[type].active = nk_false; - } -} -NK_API void -nk_buffer_clear(struct nk_buffer *b) -{ - NK_ASSERT(b); - if (!b) { - return; - } - b->allocated = 0; - b->size = b->memory.size; - b->calls = 0; - b->needed = 0; -} -NK_API void -nk_buffer_free(struct nk_buffer *b) -{ - NK_ASSERT(b); - if (!b || !b->memory.ptr) { - return; - } - if (b->type == NK_BUFFER_FIXED) { - return; - } - if (!b->pool.free) { - return; - } - NK_ASSERT(b->pool.free); - b->pool.free(b->pool.userdata, b->memory.ptr); -} -NK_API void -nk_buffer_info(struct nk_memory_status *s, const struct nk_buffer *b) -{ - NK_ASSERT(b); - NK_ASSERT(s); - if (!s || !b) { - return; - } - s->allocated = b->allocated; - s->size = b->memory.size; - s->needed = b->needed; - s->memory = b->memory.ptr; - s->calls = b->calls; -} -NK_API void * -nk_buffer_memory(struct nk_buffer *buffer) -{ - NK_ASSERT(buffer); - if (!buffer) { - return 0; - } - return buffer->memory.ptr; -} -NK_API const void * -nk_buffer_memory_const(const struct nk_buffer *buffer) -{ - NK_ASSERT(buffer); - if (!buffer) { - return 0; - } - return buffer->memory.ptr; -} -NK_API nk_size -nk_buffer_total(const struct nk_buffer *buffer) -{ - NK_ASSERT(buffer); - if (!buffer) { - return 0; - } - return buffer->memory.size; -} - -/* =============================================================== - * - * STRING - * - * ===============================================================*/ -#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR -NK_API void -nk_str_init_default(struct nk_str *str) -{ - struct nk_allocator alloc; - alloc.userdata.ptr = 0; - alloc.alloc = nk_malloc; - alloc.free = nk_mfree; - nk_buffer_init(&str->buffer, &alloc, 32); - str->len = 0; -} -#endif - -NK_API void -nk_str_init(struct nk_str *str, const struct nk_allocator *alloc, nk_size size) -{ - nk_buffer_init(&str->buffer, alloc, size); - str->len = 0; -} -NK_API void -nk_str_init_fixed(struct nk_str *str, void *memory, nk_size size) -{ - nk_buffer_init_fixed(&str->buffer, memory, size); - str->len = 0; -} -NK_API int -nk_str_append_text_char(struct nk_str *s, const char *str, int len) -{ - char *mem; - NK_ASSERT(s); - NK_ASSERT(str); - if (!s || !str || !len) { - return 0; - } - mem = (char *)nk_buffer_alloc(&s->buffer, NK_BUFFER_FRONT, (nk_size)len * sizeof(char), 0); - if (!mem) { - return 0; - } - NK_MEMCPY(mem, str, (nk_size)len * sizeof(char)); - s->len += nk_utf_len(str, len); - return len; -} -NK_API int -nk_str_append_str_char(struct nk_str *s, const char *str) -{ - return nk_str_append_text_char(s, str, nk_strlen(str)); -} -NK_API int -nk_str_append_text_utf8(struct nk_str *str, const char *text, int len) -{ - int i = 0; - int byte_len = 0; - nk_rune unicode; - if (!str || !text || !len) { - return 0; - } - for (i = 0; i < len; ++i) { - byte_len += nk_utf_decode(text + byte_len, &unicode, 4); - } - nk_str_append_text_char(str, text, byte_len); - return len; -} -NK_API int -nk_str_append_str_utf8(struct nk_str *str, const char *text) -{ - int byte_len = 0; - int num_runes = 0; - int glyph_len = 0; - nk_rune unicode; - if (!str || !text) { - return 0; - } - - glyph_len = byte_len = nk_utf_decode(text + byte_len, &unicode, 4); - while (unicode != '\0' && glyph_len) { - glyph_len = nk_utf_decode(text + byte_len, &unicode, 4); - byte_len += glyph_len; - num_runes++; - } - nk_str_append_text_char(str, text, byte_len); - return num_runes; -} -NK_API int -nk_str_append_text_runes(struct nk_str *str, const nk_rune *text, int len) -{ - int i = 0; - int byte_len = 0; - nk_glyph glyph; - - NK_ASSERT(str); - if (!str || !text || !len) { - return 0; - } - for (i = 0; i < len; ++i) { - byte_len = nk_utf_encode(text[i], glyph, NK_UTF_SIZE); - if (!byte_len) { - break; - } - nk_str_append_text_char(str, glyph, byte_len); - } - return len; -} -NK_API int -nk_str_append_str_runes(struct nk_str *str, const nk_rune *runes) -{ - int i = 0; - nk_glyph glyph; - int byte_len; - NK_ASSERT(str); - if (!str || !runes) { - return 0; - } - while (runes[i] != '\0') { - byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE); - nk_str_append_text_char(str, glyph, byte_len); - i++; - } - return i; -} -NK_API int -nk_str_insert_at_char(struct nk_str *s, int pos, const char *str, int len) -{ - int i; - void *mem; - char *src; - char *dst; - - int copylen; - NK_ASSERT(s); - NK_ASSERT(str); - NK_ASSERT(len >= 0); - if (!s || !str || !len || (nk_size)pos > s->buffer.allocated) { - return 0; - } - if ((s->buffer.allocated + (nk_size)len >= s->buffer.memory.size) && (s->buffer.type == NK_BUFFER_FIXED)) { - return 0; - } - - copylen = (int)s->buffer.allocated - pos; - if (!copylen) { - nk_str_append_text_char(s, str, len); - return 1; - } - mem = nk_buffer_alloc(&s->buffer, NK_BUFFER_FRONT, (nk_size)len * sizeof(char), 0); - if (!mem) { - return 0; - } - - /* memmove */ - NK_ASSERT(((int)pos + (int)len + ((int)copylen - 1)) >= 0); - NK_ASSERT(((int)pos + ((int)copylen - 1)) >= 0); - dst = nk_ptr_add(char, s->buffer.memory.ptr, pos + len + (copylen - 1)); - src = nk_ptr_add(char, s->buffer.memory.ptr, pos + (copylen - 1)); - for (i = 0; i < copylen; ++i) { - *dst-- = *src--; - } - mem = nk_ptr_add(void, s->buffer.memory.ptr, pos); - NK_MEMCPY(mem, str, (nk_size)len * sizeof(char)); - s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated); - return 1; -} -NK_API int -nk_str_insert_at_rune(struct nk_str *str, int pos, const char *cstr, int len) -{ - int glyph_len; - nk_rune unicode; - const char *begin; - const char *buffer; - - NK_ASSERT(str); - NK_ASSERT(cstr); - NK_ASSERT(len); - if (!str || !cstr || !len) { - return 0; - } - begin = nk_str_at_rune(str, pos, &unicode, &glyph_len); - if (!str->len) { - return nk_str_append_text_char(str, cstr, len); - } - buffer = nk_str_get_const(str); - if (!begin) { - return 0; - } - return nk_str_insert_at_char(str, (int)(begin - buffer), cstr, len); -} -NK_API int -nk_str_insert_text_char(struct nk_str *str, int pos, const char *text, int len) -{ - return nk_str_insert_at_rune(str, pos, text, len) ? len : 0; -} -NK_API int -nk_str_insert_str_char(struct nk_str *str, int pos, const char *text) -{ - return nk_str_insert_text_char(str, pos, text, nk_strlen(text)); -} -NK_API int -nk_str_insert_text_utf8(struct nk_str *str, int pos, const char *text, int len) -{ - int i = 0; - int byte_len = 0; - nk_rune unicode; - - NK_ASSERT(str); - NK_ASSERT(text); - if (!str || !text || !len) { - return 0; - } - for (i = 0; i < len; ++i) { - byte_len += nk_utf_decode(text + byte_len, &unicode, 4); - } - nk_str_insert_at_rune(str, pos, text, byte_len); - return len; -} -NK_API int -nk_str_insert_str_utf8(struct nk_str *str, int pos, const char *text) -{ - int byte_len = 0; - int num_runes = 0; - int glyph_len = 0; - nk_rune unicode; - if (!str || !text) { - return 0; - } - - glyph_len = byte_len = nk_utf_decode(text + byte_len, &unicode, 4); - while (unicode != '\0' && glyph_len) { - glyph_len = nk_utf_decode(text + byte_len, &unicode, 4); - byte_len += glyph_len; - num_runes++; - } - nk_str_insert_at_rune(str, pos, text, byte_len); - return num_runes; -} -NK_API int -nk_str_insert_text_runes(struct nk_str *str, int pos, const nk_rune *runes, int len) -{ - int i = 0; - int byte_len = 0; - nk_glyph glyph; - - NK_ASSERT(str); - if (!str || !runes || !len) { - return 0; - } - for (i = 0; i < len; ++i) { - byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE); - if (!byte_len) { - break; - } - nk_str_insert_at_rune(str, pos + i, glyph, byte_len); - } - return len; -} -NK_API int -nk_str_insert_str_runes(struct nk_str *str, int pos, const nk_rune *runes) -{ - int i = 0; - nk_glyph glyph; - int byte_len; - NK_ASSERT(str); - if (!str || !runes) { - return 0; - } - while (runes[i] != '\0') { - byte_len = nk_utf_encode(runes[i], glyph, NK_UTF_SIZE); - nk_str_insert_at_rune(str, pos + i, glyph, byte_len); - i++; - } - return i; -} -NK_API void -nk_str_remove_chars(struct nk_str *s, int len) -{ - NK_ASSERT(s); - NK_ASSERT(len >= 0); - if (!s || len < 0 || (nk_size)len > s->buffer.allocated) { - return; - } - NK_ASSERT(((int)s->buffer.allocated - (int)len) >= 0); - s->buffer.allocated -= (nk_size)len; - s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated); -} -NK_API void -nk_str_remove_runes(struct nk_str *str, int len) -{ - int index; - const char *begin; - const char *end; - nk_rune unicode; - - NK_ASSERT(str); - NK_ASSERT(len >= 0); - if (!str || len < 0) { - return; - } - if (len >= str->len) { - str->len = 0; - return; - } - - index = str->len - len; - begin = nk_str_at_rune(str, index, &unicode, &len); - end = (const char *)str->buffer.memory.ptr + str->buffer.allocated; - nk_str_remove_chars(str, (int)(end - begin) + 1); -} -NK_API void -nk_str_delete_chars(struct nk_str *s, int pos, int len) -{ - NK_ASSERT(s); - if (!s || !len || (nk_size)pos > s->buffer.allocated || (nk_size)(pos + len) > s->buffer.allocated) { - return; - } - - if ((nk_size)(pos + len) < s->buffer.allocated) { - /* memmove */ - char *dst = nk_ptr_add(char, s->buffer.memory.ptr, pos); - char *src = nk_ptr_add(char, s->buffer.memory.ptr, pos + len); - NK_MEMCPY(dst, src, s->buffer.allocated - (nk_size)(pos + len)); - NK_ASSERT(((int)s->buffer.allocated - (int)len) >= 0); - s->buffer.allocated -= (nk_size)len; - } else { - nk_str_remove_chars(s, len); - } - s->len = nk_utf_len((char *)s->buffer.memory.ptr, (int)s->buffer.allocated); -} -NK_API void -nk_str_delete_runes(struct nk_str *s, int pos, int len) -{ - char *temp; - nk_rune unicode; - char *begin; - char *end; - int unused; - - NK_ASSERT(s); - NK_ASSERT(s->len >= pos + len); - if (s->len < pos + len) { - len = NK_CLAMP(0, (s->len - pos), s->len); - } - if (!len) { - return; - } - - temp = (char *)s->buffer.memory.ptr; - begin = nk_str_at_rune(s, pos, &unicode, &unused); - if (!begin) { - return; - } - s->buffer.memory.ptr = begin; - end = nk_str_at_rune(s, len, &unicode, &unused); - s->buffer.memory.ptr = temp; - if (!end) { - return; - } - nk_str_delete_chars(s, (int)(begin - temp), (int)(end - begin)); -} -NK_API char * -nk_str_at_char(struct nk_str *s, int pos) -{ - NK_ASSERT(s); - if (!s || pos > (int)s->buffer.allocated) { - return 0; - } - return nk_ptr_add(char, s->buffer.memory.ptr, pos); -} -NK_API char * -nk_str_at_rune(struct nk_str *str, int pos, nk_rune *unicode, int *len) -{ - int i = 0; - int src_len = 0; - int glyph_len = 0; - char *text; - int text_len; - - NK_ASSERT(str); - NK_ASSERT(unicode); - NK_ASSERT(len); - - if (!str || !unicode || !len) { - return 0; - } - if (pos < 0) { - *unicode = 0; - *len = 0; - return 0; - } - - text = (char *)str->buffer.memory.ptr; - text_len = (int)str->buffer.allocated; - glyph_len = nk_utf_decode(text, unicode, text_len); - while (glyph_len) { - if (i == pos) { - *len = glyph_len; - break; - } - - i++; - src_len = src_len + glyph_len; - glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len); - } - if (i != pos) { - return 0; - } - return text + src_len; -} -NK_API const char * -nk_str_at_char_const(const struct nk_str *s, int pos) -{ - NK_ASSERT(s); - if (!s || pos > (int)s->buffer.allocated) { - return 0; - } - return nk_ptr_add(char, s->buffer.memory.ptr, pos); -} -NK_API const char * -nk_str_at_const(const struct nk_str *str, int pos, nk_rune *unicode, int *len) -{ - int i = 0; - int src_len = 0; - int glyph_len = 0; - char *text; - int text_len; - - NK_ASSERT(str); - NK_ASSERT(unicode); - NK_ASSERT(len); - - if (!str || !unicode || !len) { - return 0; - } - if (pos < 0) { - *unicode = 0; - *len = 0; - return 0; - } - - text = (char *)str->buffer.memory.ptr; - text_len = (int)str->buffer.allocated; - glyph_len = nk_utf_decode(text, unicode, text_len); - while (glyph_len) { - if (i == pos) { - *len = glyph_len; - break; - } - - i++; - src_len = src_len + glyph_len; - glyph_len = nk_utf_decode(text + src_len, unicode, text_len - src_len); - } - if (i != pos) { - return 0; - } - return text + src_len; -} -NK_API nk_rune -nk_str_rune_at(const struct nk_str *str, int pos) -{ - int len; - nk_rune unicode = 0; - nk_str_at_const(str, pos, &unicode, &len); - return unicode; -} -NK_API char * -nk_str_get(struct nk_str *s) -{ - NK_ASSERT(s); - if (!s || !s->len || !s->buffer.allocated) { - return 0; - } - return (char *)s->buffer.memory.ptr; -} -NK_API const char * -nk_str_get_const(const struct nk_str *s) -{ - NK_ASSERT(s); - if (!s || !s->len || !s->buffer.allocated) { - return 0; - } - return (const char *)s->buffer.memory.ptr; -} -NK_API int -nk_str_len(const struct nk_str *s) -{ - NK_ASSERT(s); - if (!s || !s->len || !s->buffer.allocated) { - return 0; - } - return s->len; -} -NK_API int -nk_str_len_char(const struct nk_str *s) -{ - NK_ASSERT(s); - if (!s || !s->len || !s->buffer.allocated) { - return 0; - } - return (int)s->buffer.allocated; -} -NK_API void -nk_str_clear(struct nk_str *str) -{ - NK_ASSERT(str); - nk_buffer_clear(&str->buffer); - str->len = 0; -} -NK_API void -nk_str_free(struct nk_str *str) -{ - NK_ASSERT(str); - nk_buffer_free(&str->buffer); - str->len = 0; -} - -/* ============================================================== - * - * DRAW - * - * ===============================================================*/ -NK_LIB void -nk_command_buffer_init(struct nk_command_buffer *cb, struct nk_buffer *b, enum nk_command_clipping clip) -{ - NK_ASSERT(cb); - NK_ASSERT(b); - if (!cb || !b) { - return; - } - cb->base = b; - cb->context = NULL; - cb->use_clipping = (int)clip; - cb->begin = b->allocated; - cb->end = b->allocated; - cb->last = b->allocated; -} -NK_LIB void -nk_command_buffer_reset(struct nk_command_buffer *b) -{ - NK_ASSERT(b); - if (!b) { - return; - } - b->begin = 0; - b->end = 0; - b->last = 0; - b->clip = nk_null_rect; -#ifdef NK_INCLUDE_COMMAND_USERDATA - b->userdata.ptr = 0; -#endif -} -NK_LIB void * -nk_command_buffer_push(struct nk_command_buffer *b, enum nk_command_type t, nk_size size) -{ - NK_STORAGE const nk_size align = NK_ALIGNOF(struct nk_command); - struct nk_command *cmd; - nk_size alignment; - void *unaligned; - void *memory; - - NK_ASSERT(b); - NK_ASSERT(b->base); - if (!b) { - return 0; - } - cmd = (struct nk_command *)nk_buffer_alloc(b->base, NK_BUFFER_FRONT, size, align); - if (!cmd) { - return 0; - } - - /* make sure the offset to the next command is aligned */ - b->last = (nk_size)((nk_byte *)cmd - (nk_byte *)b->base->memory.ptr); - unaligned = (nk_byte *)cmd + size; - memory = NK_ALIGN_PTR(unaligned, align); - alignment = (nk_size)((nk_byte *)memory - (nk_byte *)unaligned); -#ifdef NK_ZERO_COMMAND_MEMORY - NK_MEMSET(cmd, 0, size + alignment); -#endif - - cmd->type = t; - cmd->next = b->base->allocated + alignment; -#ifdef NK_INCLUDE_COMMAND_USERDATA - cmd->userdata = b->userdata; -#endif - b->end = cmd->next; - return cmd; -} -NK_API void -nk_push_scissor(struct nk_command_buffer *b, struct nk_rect r) -{ - struct nk_command_scissor *cmd; - NK_ASSERT(b); - if (!b) { - return; - } - - b->clip.x = r.x; - b->clip.y = r.y; - b->clip.w = r.w; - b->clip.h = r.h; - cmd = (struct nk_command_scissor *)nk_command_buffer_push(b, NK_COMMAND_SCISSOR, sizeof(*cmd)); - - if (!cmd) { - return; - } - cmd->x = (short)r.x; - cmd->y = (short)r.y; - cmd->w = (unsigned short)NK_MAX(0, r.w); - cmd->h = (unsigned short)NK_MAX(0, r.h); -} -NK_API void -nk_stroke_line(struct nk_command_buffer *b, float x0, float y0, float x1, float y1, float line_thickness, struct nk_color c) -{ - struct nk_command_line *cmd; - NK_ASSERT(b); - if (!b || line_thickness <= 0) { - return; - } - cmd = (struct nk_command_line *)nk_command_buffer_push(b, NK_COMMAND_LINE, sizeof(*cmd)); - if (!cmd) { - return; - } - cmd->line_thickness = (unsigned short)line_thickness; - cmd->begin.x = (short)x0; - cmd->begin.y = (short)y0; - cmd->end.x = (short)x1; - cmd->end.y = (short)y1; - cmd->color = c; -} -NK_API void -nk_stroke_curve( - struct nk_command_buffer *b, float ax, float ay, float ctrl0x, float ctrl0y, float ctrl1x, float ctrl1y, float bx, float by, float line_thickness, struct nk_color col) -{ - struct nk_command_curve *cmd; - NK_ASSERT(b); - if (!b || col.a == 0 || line_thickness <= 0) { - return; - } - - cmd = (struct nk_command_curve *)nk_command_buffer_push(b, NK_COMMAND_CURVE, sizeof(*cmd)); - if (!cmd) { - return; - } - cmd->line_thickness = (unsigned short)line_thickness; - cmd->begin.x = (short)ax; - cmd->begin.y = (short)ay; - cmd->ctrl[0].x = (short)ctrl0x; - cmd->ctrl[0].y = (short)ctrl0y; - cmd->ctrl[1].x = (short)ctrl1x; - cmd->ctrl[1].y = (short)ctrl1y; - cmd->end.x = (short)bx; - cmd->end.y = (short)by; - cmd->color = col; -} -NK_API void -nk_stroke_rect(struct nk_command_buffer *b, struct nk_rect rect, float rounding, float line_thickness, struct nk_color c) -{ - struct nk_command_rect *cmd; - NK_ASSERT(b); - if (!b || c.a == 0 || rect.w == 0 || rect.h == 0 || line_thickness <= 0) { - return; - } - if (b->use_clipping) { - const struct nk_rect *clip = &b->clip; - if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h, clip->x, clip->y, clip->w, clip->h)) { - return; - } - } - cmd = (struct nk_command_rect *)nk_command_buffer_push(b, NK_COMMAND_RECT, sizeof(*cmd)); - if (!cmd) { - return; - } - cmd->rounding = (unsigned short)rounding; - cmd->line_thickness = (unsigned short)line_thickness; - cmd->x = (short)rect.x; - cmd->y = (short)rect.y; - cmd->w = (unsigned short)NK_MAX(0, rect.w); - cmd->h = (unsigned short)NK_MAX(0, rect.h); - cmd->color = c; -} -NK_API void -nk_fill_rect(struct nk_command_buffer *b, struct nk_rect rect, float rounding, struct nk_color c) -{ - struct nk_command_rect_filled *cmd; - NK_ASSERT(b); - if (!b || c.a == 0 || rect.w == 0 || rect.h == 0) { - return; - } - if (b->use_clipping) { - const struct nk_rect *clip = &b->clip; - if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h, clip->x, clip->y, clip->w, clip->h)) { - return; - } - } - - cmd = (struct nk_command_rect_filled *)nk_command_buffer_push(b, NK_COMMAND_RECT_FILLED, sizeof(*cmd)); - if (!cmd) { - return; - } - cmd->rounding = (unsigned short)rounding; - cmd->x = (short)rect.x; - cmd->y = (short)rect.y; - cmd->w = (unsigned short)NK_MAX(0, rect.w); - cmd->h = (unsigned short)NK_MAX(0, rect.h); - cmd->color = c; -} -NK_API void -nk_fill_rect_multi_color(struct nk_command_buffer *b, struct nk_rect rect, struct nk_color left, struct nk_color top, struct nk_color right, struct nk_color bottom) -{ - struct nk_command_rect_multi_color *cmd; - NK_ASSERT(b); - if (!b || rect.w == 0 || rect.h == 0) { - return; - } - if (b->use_clipping) { - const struct nk_rect *clip = &b->clip; - if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h, clip->x, clip->y, clip->w, clip->h)) { - return; - } - } - - cmd = (struct nk_command_rect_multi_color *)nk_command_buffer_push(b, NK_COMMAND_RECT_MULTI_COLOR, sizeof(*cmd)); - if (!cmd) { - return; - } - cmd->x = (short)rect.x; - cmd->y = (short)rect.y; - cmd->w = (unsigned short)NK_MAX(0, rect.w); - cmd->h = (unsigned short)NK_MAX(0, rect.h); - cmd->left = left; - cmd->top = top; - cmd->right = right; - cmd->bottom = bottom; -} -NK_API void -nk_stroke_circle(struct nk_command_buffer *b, struct nk_rect r, float line_thickness, struct nk_color c) -{ - struct nk_command_circle *cmd; - if (!b || r.w == 0 || r.h == 0 || line_thickness <= 0) { - return; - } - if (b->use_clipping) { - const struct nk_rect *clip = &b->clip; - if (!NK_INTERSECT(r.x, r.y, r.w, r.h, clip->x, clip->y, clip->w, clip->h)) { - return; - } - } - - cmd = (struct nk_command_circle *)nk_command_buffer_push(b, NK_COMMAND_CIRCLE, sizeof(*cmd)); - if (!cmd) { - return; - } - cmd->line_thickness = (unsigned short)line_thickness; - cmd->x = (short)r.x; - cmd->y = (short)r.y; - cmd->w = (unsigned short)NK_MAX(r.w, 0); - cmd->h = (unsigned short)NK_MAX(r.h, 0); - cmd->color = c; -} -NK_API void -nk_fill_circle(struct nk_command_buffer *b, struct nk_rect r, struct nk_color c) -{ - struct nk_command_circle_filled *cmd; - NK_ASSERT(b); - if (!b || c.a == 0 || r.w == 0 || r.h == 0) { - return; - } - if (b->use_clipping) { - const struct nk_rect *clip = &b->clip; - if (!NK_INTERSECT(r.x, r.y, r.w, r.h, clip->x, clip->y, clip->w, clip->h)) { - return; - } - } - - cmd = (struct nk_command_circle_filled *)nk_command_buffer_push(b, NK_COMMAND_CIRCLE_FILLED, sizeof(*cmd)); - if (!cmd) { - return; - } - cmd->x = (short)r.x; - cmd->y = (short)r.y; - cmd->w = (unsigned short)NK_MAX(r.w, 0); - cmd->h = (unsigned short)NK_MAX(r.h, 0); - cmd->color = c; -} -NK_API void -nk_stroke_arc(struct nk_command_buffer *b, float cx, float cy, float radius, float a_min, float a_max, float line_thickness, struct nk_color c) -{ - struct nk_command_arc *cmd; - if (!b || c.a == 0 || line_thickness <= 0) { - return; - } - cmd = (struct nk_command_arc *)nk_command_buffer_push(b, NK_COMMAND_ARC, sizeof(*cmd)); - if (!cmd) { - return; - } - cmd->line_thickness = (unsigned short)line_thickness; - cmd->cx = (short)cx; - cmd->cy = (short)cy; - cmd->r = (unsigned short)radius; - cmd->a[0] = a_min; - cmd->a[1] = a_max; - cmd->color = c; -} -NK_API void -nk_fill_arc(struct nk_command_buffer *b, float cx, float cy, float radius, float a_min, float a_max, struct nk_color c) -{ - struct nk_command_arc_filled *cmd; - NK_ASSERT(b); - if (!b || c.a == 0) { - return; - } - cmd = (struct nk_command_arc_filled *)nk_command_buffer_push(b, NK_COMMAND_ARC_FILLED, sizeof(*cmd)); - if (!cmd) { - return; - } - cmd->cx = (short)cx; - cmd->cy = (short)cy; - cmd->r = (unsigned short)radius; - cmd->a[0] = a_min; - cmd->a[1] = a_max; - cmd->color = c; -} -NK_API void -nk_stroke_triangle(struct nk_command_buffer *b, float x0, float y0, float x1, float y1, float x2, float y2, float line_thickness, struct nk_color c) -{ - struct nk_command_triangle *cmd; - NK_ASSERT(b); - if (!b || c.a == 0 || line_thickness <= 0) { - return; - } - if (b->use_clipping) { - const struct nk_rect *clip = &b->clip; - if (!NK_INBOX(x0, y0, clip->x, clip->y, clip->w, clip->h) && !NK_INBOX(x1, y1, clip->x, clip->y, clip->w, clip->h) && !NK_INBOX(x2, y2, clip->x, clip->y, clip->w, clip->h)) { - return; - } - } - - cmd = (struct nk_command_triangle *)nk_command_buffer_push(b, NK_COMMAND_TRIANGLE, sizeof(*cmd)); - if (!cmd) { - return; - } - cmd->line_thickness = (unsigned short)line_thickness; - cmd->a.x = (short)x0; - cmd->a.y = (short)y0; - cmd->b.x = (short)x1; - cmd->b.y = (short)y1; - cmd->c.x = (short)x2; - cmd->c.y = (short)y2; - cmd->color = c; -} -NK_API void -nk_fill_triangle(struct nk_command_buffer *b, float x0, float y0, float x1, float y1, float x2, float y2, struct nk_color c) -{ - struct nk_command_triangle_filled *cmd; - NK_ASSERT(b); - if (!b || c.a == 0) { - return; - } - if (!b) { - return; - } - if (b->use_clipping) { - const struct nk_rect *clip = &b->clip; - if (!NK_INBOX(x0, y0, clip->x, clip->y, clip->w, clip->h) && !NK_INBOX(x1, y1, clip->x, clip->y, clip->w, clip->h) && !NK_INBOX(x2, y2, clip->x, clip->y, clip->w, clip->h)) { - return; - } - } - - cmd = (struct nk_command_triangle_filled *)nk_command_buffer_push(b, NK_COMMAND_TRIANGLE_FILLED, sizeof(*cmd)); - if (!cmd) { - return; - } - cmd->a.x = (short)x0; - cmd->a.y = (short)y0; - cmd->b.x = (short)x1; - cmd->b.y = (short)y1; - cmd->c.x = (short)x2; - cmd->c.y = (short)y2; - cmd->color = c; -} -NK_API void -nk_stroke_polygon(struct nk_command_buffer *b, const float *points, int point_count, float line_thickness, struct nk_color col) -{ - int i; - nk_size size = 0; - struct nk_command_polygon *cmd; - - NK_ASSERT(b); - if (!b || col.a == 0 || line_thickness <= 0) { - return; - } - size = sizeof(*cmd) + sizeof(short) * 2 * (nk_size)point_count; - cmd = (struct nk_command_polygon *)nk_command_buffer_push(b, NK_COMMAND_POLYGON, size); - if (!cmd) { - return; - } - cmd->color = col; - cmd->line_thickness = (unsigned short)line_thickness; - cmd->point_count = (unsigned short)point_count; - for (i = 0; i < point_count; ++i) { - cmd->points[i].x = (short)points[i * 2]; - cmd->points[i].y = (short)points[i * 2 + 1]; - } -} -NK_API void -nk_fill_polygon(struct nk_command_buffer *b, const float *points, int point_count, struct nk_color col) -{ - int i; - nk_size size = 0; - struct nk_command_polygon_filled *cmd; - - NK_ASSERT(b); - if (!b || col.a == 0) { - return; - } - size = sizeof(*cmd) + sizeof(short) * 2 * (nk_size)point_count; - cmd = (struct nk_command_polygon_filled *)nk_command_buffer_push(b, NK_COMMAND_POLYGON_FILLED, size); - if (!cmd) { - return; - } - cmd->color = col; - cmd->point_count = (unsigned short)point_count; - for (i = 0; i < point_count; ++i) { - cmd->points[i].x = (short)points[i * 2 + 0]; - cmd->points[i].y = (short)points[i * 2 + 1]; - } -} -NK_API void -nk_stroke_polyline(struct nk_command_buffer *b, const float *points, int point_count, float line_thickness, struct nk_color col) -{ - int i; - nk_size size = 0; - struct nk_command_polyline *cmd; - - NK_ASSERT(b); - if (!b || col.a == 0 || line_thickness <= 0) { - return; - } - size = sizeof(*cmd) + sizeof(short) * 2 * (nk_size)point_count; - cmd = (struct nk_command_polyline *)nk_command_buffer_push(b, NK_COMMAND_POLYLINE, size); - if (!cmd) { - return; - } - cmd->color = col; - cmd->point_count = (unsigned short)point_count; - cmd->line_thickness = (unsigned short)line_thickness; - for (i = 0; i < point_count; ++i) { - cmd->points[i].x = (short)points[i * 2]; - cmd->points[i].y = (short)points[i * 2 + 1]; - } -} -NK_API void -nk_draw_image(struct nk_command_buffer *b, struct nk_rect r, const struct nk_image *img, struct nk_color col) -{ - struct nk_command_image *cmd; - NK_ASSERT(b); - if (!b) { - return; - } - if (b->use_clipping) { - const struct nk_rect *c = &b->clip; - if (c->w == 0 || c->h == 0 || !NK_INTERSECT(r.x, r.y, r.w, r.h, c->x, c->y, c->w, c->h)) { - return; - } - } - - cmd = (struct nk_command_image *)nk_command_buffer_push(b, NK_COMMAND_IMAGE, sizeof(*cmd)); - if (!cmd) { - return; - } - cmd->x = (short)r.x; - cmd->y = (short)r.y; - cmd->w = (unsigned short)NK_MAX(0, r.w); - cmd->h = (unsigned short)NK_MAX(0, r.h); - cmd->img = *img; - cmd->col = col; -} -NK_API void -nk_draw_nine_slice(struct nk_command_buffer *b, struct nk_rect r, const struct nk_nine_slice *slc, struct nk_color col) -{ - struct nk_image img; - const struct nk_image *slcimg = (const struct nk_image *)slc; - nk_ushort rgnX, rgnY, rgnW, rgnH; - rgnX = slcimg->region[0]; - rgnY = slcimg->region[1]; - rgnW = slcimg->region[2]; - rgnH = slcimg->region[3]; - - /* top-left */ - img.handle = slcimg->handle; - img.w = slcimg->w; - img.h = slcimg->h; - img.region[0] = rgnX; - img.region[1] = rgnY; - img.region[2] = slc->l; - img.region[3] = slc->t; - - nk_draw_image(b, nk_rect(r.x, r.y, (float)slc->l, (float)slc->t), &img, col); - -#define IMG_RGN(x, y, w, h) \ - img.region[0] = (nk_ushort)(x); \ - img.region[1] = (nk_ushort)(y); \ - img.region[2] = (nk_ushort)(w); \ - img.region[3] = (nk_ushort)(h); - - /* top-center */ - IMG_RGN(rgnX + slc->l, rgnY, rgnW - slc->l - slc->r, slc->t); - nk_draw_image(b, nk_rect(r.x + (float)slc->l, r.y, (float)(r.w - slc->l - slc->r), (float)slc->t), &img, col); - - /* top-right */ - IMG_RGN(rgnX + rgnW - slc->r, rgnY, slc->r, slc->t); - nk_draw_image(b, nk_rect(r.x + r.w - (float)slc->r, r.y, (float)slc->r, (float)slc->t), &img, col); - - /* center-left */ - IMG_RGN(rgnX, rgnY + slc->t, slc->l, rgnH - slc->t - slc->b); - nk_draw_image(b, nk_rect(r.x, r.y + (float)slc->t, (float)slc->l, (float)(r.h - slc->t - slc->b)), &img, col); - - /* center */ - IMG_RGN(rgnX + slc->l, rgnY + slc->t, rgnW - slc->l - slc->r, rgnH - slc->t - slc->b); - nk_draw_image(b, nk_rect(r.x + (float)slc->l, r.y + (float)slc->t, (float)(r.w - slc->l - slc->r), (float)(r.h - slc->t - slc->b)), &img, col); - - /* center-right */ - IMG_RGN(rgnX + rgnW - slc->r, rgnY + slc->t, slc->r, rgnH - slc->t - slc->b); - nk_draw_image(b, nk_rect(r.x + r.w - (float)slc->r, r.y + (float)slc->t, (float)slc->r, (float)(r.h - slc->t - slc->b)), &img, col); - - /* bottom-left */ - IMG_RGN(rgnX, rgnY + rgnH - slc->b, slc->l, slc->b); - nk_draw_image(b, nk_rect(r.x, r.y + r.h - (float)slc->b, (float)slc->l, (float)slc->b), &img, col); - - /* bottom-center */ - IMG_RGN(rgnX + slc->l, rgnY + rgnH - slc->b, rgnW - slc->l - slc->r, slc->b); - nk_draw_image(b, nk_rect(r.x + (float)slc->l, r.y + r.h - (float)slc->b, (float)(r.w - slc->l - slc->r), (float)slc->b), &img, col); - - /* bottom-right */ - IMG_RGN(rgnX + rgnW - slc->r, rgnY + rgnH - slc->b, slc->r, slc->b); - nk_draw_image(b, nk_rect(r.x + r.w - (float)slc->r, r.y + r.h - (float)slc->b, (float)slc->r, (float)slc->b), &img, col); - -#undef IMG_RGN -} -NK_API void -nk_push_custom(struct nk_command_buffer *b, struct nk_rect r, nk_command_custom_callback cb, nk_handle usr) -{ - struct nk_command_custom *cmd; - NK_ASSERT(b); - if (!b) { - return; - } - if (b->use_clipping) { - const struct nk_rect *c = &b->clip; - if (c->w == 0 || c->h == 0 || !NK_INTERSECT(r.x, r.y, r.w, r.h, c->x, c->y, c->w, c->h)) { - return; - } - } - - cmd = (struct nk_command_custom *)nk_command_buffer_push(b, NK_COMMAND_CUSTOM, sizeof(*cmd)); - if (!cmd) { - return; - } - cmd->x = (short)r.x; - cmd->y = (short)r.y; - cmd->w = (unsigned short)NK_MAX(0, r.w); - cmd->h = (unsigned short)NK_MAX(0, r.h); - cmd->callback_data = usr; - cmd->callback = cb; -} -NK_INTERN void -nk_push_draw_text(struct nk_command_buffer *b, struct nk_rect r, const char *string, int length, - const struct nk_user_font *font, float height, struct nk_color bg, struct nk_color fg) -{ - struct nk_command_text *cmd; - - if (!length) { - return; - } - cmd = (struct nk_command_text *)nk_command_buffer_push(b, NK_COMMAND_TEXT, sizeof(*cmd) + (nk_size)(length + 1)); - if (!cmd) { - return; - } - cmd->x = (short)r.x; - cmd->y = (short)r.y; - cmd->w = (unsigned short)r.w; - cmd->h = (unsigned short)r.h; - cmd->background = bg; - cmd->foreground = fg; - cmd->font = font; - cmd->length = length; - cmd->height = height; - NK_MEMCPY(cmd->string, string, (nk_size)length); - cmd->string[length] = '\0'; -} - -NK_API void -nk_draw_text(struct nk_command_buffer *b, struct nk_rect r, const char *string, int length, - const struct nk_user_font *font, struct nk_color bg, struct nk_color fg) -{ - struct nk_text_shape *shape; - float text_width; - - NK_ASSERT(b); - NK_ASSERT(font); - if (!b || !string || !length || (bg.a == 0 && fg.a == 0)) { - return; - } - - if (b->use_clipping) { - struct nk_rect *c = &b->clip; - if (c->w == 0 || c->h == 0 || !NK_INTERSECT(r.x, r.y, r.w, r.h, c->x, c->y, c->w, c->h)) { - return; - } - } - - shape = nk_text_shape_build_default(b->context, font, b->context->style.font_size, string, length); - text_width = shape ? shape->advance.x : 0.0f; - if (text_width > r.w) { - int glyphs = 0; - float width = text_width; - length = nk_text_clamp(b->context, font, string, length, r.w, &glyphs, &width, 0, 0); - } - - nk_push_draw_text(b, r, string, length, font, b->context->style.font_size, bg, fg); -} - -/* =============================================================== - * - * VERTEX - * - * ===============================================================*/ -#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT -NK_API void -nk_draw_list_init(struct nk_draw_list *list) -{ - nk_size i = 0; - NK_ASSERT(list); - if (!list) { - return; - } - nk_zero(list, sizeof(*list)); - for (i = 0; i < NK_LEN(list->circle_vtx); ++i) { - const int size = NK_LEN(list->circle_vtx); - const float a = ((float)i / (float)size) * 2 * NK_PI; - list->circle_vtx[i].x = (float)NK_COS(a); - list->circle_vtx[i].y = (float)NK_SIN(a); - } -} -NK_API void -nk_draw_list_setup(struct nk_draw_list *canvas, - const struct nk_convert_config *config, - struct nk_buffer *cmds, - struct nk_buffer *vertices, - struct nk_buffer *elements, - enum nk_anti_aliasing line_aa, - enum nk_anti_aliasing shape_aa) -{ - NK_ASSERT(canvas); - NK_ASSERT(config); - NK_ASSERT(cmds); - NK_ASSERT(vertices); - NK_ASSERT(elements); - if (!canvas || !config || !cmds || !vertices || !elements) { - return; - } - - canvas->buffer = cmds; - canvas->config = *config; - canvas->elements = elements; - canvas->vertices = vertices; - canvas->line_AA = line_aa; - canvas->shape_AA = shape_aa; - canvas->clip_rect = nk_null_rect; - - canvas->cmd_offset = 0; - canvas->element_count = 0; - canvas->vertex_count = 0; - canvas->cmd_offset = 0; - canvas->cmd_count = 0; - canvas->path_count = 0; -} -NK_API const struct nk_draw_command * -nk__draw_list_begin(const struct nk_draw_list *canvas, const struct nk_buffer *buffer) -{ - nk_byte *memory; - nk_size offset; - const struct nk_draw_command *cmd; - - NK_ASSERT(buffer); - if (!buffer || !buffer->size || !canvas->cmd_count) { - return 0; - } - - memory = (nk_byte *)buffer->memory.ptr; - offset = buffer->memory.size - canvas->cmd_offset; - cmd = nk_ptr_add(const struct nk_draw_command, memory, offset); - return cmd; -} -NK_API const struct nk_draw_command * -nk__draw_list_end(const struct nk_draw_list *canvas, const struct nk_buffer *buffer) -{ - nk_size size; - nk_size offset; - nk_byte *memory; - const struct nk_draw_command *end; - - NK_ASSERT(buffer); - NK_ASSERT(canvas); - if (!buffer || !canvas) { - return 0; - } - - memory = (nk_byte *)buffer->memory.ptr; - size = buffer->memory.size; - offset = size - canvas->cmd_offset; - end = nk_ptr_add(const struct nk_draw_command, memory, offset); - end -= (canvas->cmd_count - 1); - return end; -} -NK_API const struct nk_draw_command * -nk__draw_list_next(const struct nk_draw_command *cmd, const struct nk_buffer *buffer, const struct nk_draw_list *canvas) -{ - const struct nk_draw_command *end; - NK_ASSERT(buffer); - NK_ASSERT(canvas); - if (!cmd || !buffer || !canvas) { - return 0; - } - - end = nk__draw_list_end(canvas, buffer); - if (cmd <= end) { - return 0; - } - return (cmd - 1); -} -NK_INTERN struct nk_vec2 * -nk_draw_list_alloc_path(struct nk_draw_list *list, int count) -{ - struct nk_vec2 *points; - NK_STORAGE const nk_size point_align = NK_ALIGNOF(struct nk_vec2); - NK_STORAGE const nk_size point_size = sizeof(struct nk_vec2); - points = (struct nk_vec2 *)nk_buffer_alloc(list->buffer, NK_BUFFER_FRONT, point_size * (nk_size)count, point_align); - - if (!points) { - return 0; - } - if (!list->path_offset) { - void *memory = nk_buffer_memory(list->buffer); - list->path_offset = (unsigned int)((nk_byte *)points - (nk_byte *)memory); - } - list->path_count += (unsigned int)count; - return points; -} -NK_INTERN struct nk_vec2 -nk_draw_list_path_last(struct nk_draw_list *list) -{ - void *memory; - struct nk_vec2 *point; - NK_ASSERT(list->path_count); - memory = nk_buffer_memory(list->buffer); - point = nk_ptr_add(struct nk_vec2, memory, list->path_offset); - point += (list->path_count - 1); - return *point; -} -NK_INTERN struct nk_draw_command * -nk_draw_list_push_command(struct nk_draw_list *list, struct nk_rect clip, nk_handle texture) -{ - NK_STORAGE const nk_size cmd_align = NK_ALIGNOF(struct nk_draw_command); - NK_STORAGE const nk_size cmd_size = sizeof(struct nk_draw_command); - struct nk_draw_command *cmd; - - NK_ASSERT(list); - cmd = (struct nk_draw_command *)nk_buffer_alloc(list->buffer, NK_BUFFER_BACK, cmd_size, cmd_align); - - if (!cmd) { - return 0; - } - if (!list->cmd_count) { - nk_byte *memory = (nk_byte *)nk_buffer_memory(list->buffer); - nk_size total = nk_buffer_total(list->buffer); - memory = nk_ptr_add(nk_byte, memory, total); - list->cmd_offset = (nk_size)(memory - (nk_byte *)cmd); - } - - cmd->elem_count = 0; - cmd->clip_rect = clip; - cmd->texture = texture; -# ifdef NK_INCLUDE_COMMAND_USERDATA - cmd->userdata = list->userdata; -# endif - - list->cmd_count++; - list->clip_rect = clip; - return cmd; -} -NK_INTERN struct nk_draw_command * -nk_draw_list_command_last(struct nk_draw_list *list) -{ - void *memory; - nk_size size; - struct nk_draw_command *cmd; - NK_ASSERT(list->cmd_count); - - memory = nk_buffer_memory(list->buffer); - size = nk_buffer_total(list->buffer); - cmd = nk_ptr_add(struct nk_draw_command, memory, size - list->cmd_offset); - return (cmd - (list->cmd_count - 1)); -} -NK_INTERN void -nk_draw_list_add_clip(struct nk_draw_list *list, struct nk_rect rect) -{ - NK_ASSERT(list); - if (!list) { - return; - } - if (!list->cmd_count) { - nk_draw_list_push_command(list, rect, list->config.tex_null.texture); - } else { - struct nk_draw_command *prev = nk_draw_list_command_last(list); - if (prev->elem_count == 0) { - prev->clip_rect = rect; - } - nk_draw_list_push_command(list, rect, prev->texture); - } -} -NK_INTERN void -nk_draw_list_push_image(struct nk_draw_list *list, nk_handle texture) -{ - NK_ASSERT(list); - if (!list) { - return; - } - if (!list->cmd_count) { - nk_draw_list_push_command(list, nk_null_rect, texture); - } else { - struct nk_draw_command *prev = nk_draw_list_command_last(list); - if (prev->elem_count == 0) { - prev->texture = texture; -# ifdef NK_INCLUDE_COMMAND_USERDATA - prev->userdata = list->userdata; -# endif - } else if (prev->texture.id != texture.id -# ifdef NK_INCLUDE_COMMAND_USERDATA - || prev->userdata.id != list->userdata.id -# endif - ) { - nk_draw_list_push_command(list, prev->clip_rect, texture); - } - } -} -# ifdef NK_INCLUDE_COMMAND_USERDATA -NK_API void -nk_draw_list_push_userdata(struct nk_draw_list *list, nk_handle userdata) -{ - list->userdata = userdata; -} -# endif -NK_INTERN void * -nk_draw_list_alloc_vertices(struct nk_draw_list *list, nk_size count) -{ - void *vtx; - NK_ASSERT(list); - if (!list) { - return 0; - } - vtx = nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT, list->config.vertex_size * count, list->config.vertex_alignment); - if (!vtx) { - return 0; - } - list->vertex_count += (unsigned int)count; - - /* This assert triggers because your are drawing a lot of stuff and nuklear - * defined `nk_draw_index` as `nk_ushort` to safe space be default. - * - * So you reached the maximum number of indices or rather vertexes. - * To solve this issue please change typedef `nk_draw_index` to `nk_uint` - * and don't forget to specify the new element size in your drawing - * backend (OpenGL, DirectX, ...). For example in OpenGL for `glDrawElements` - * instead of specifying `GL_UNSIGNED_SHORT` you have to define `GL_UNSIGNED_INT`. - * Sorry for the inconvenience. */ - if (sizeof(nk_draw_index) == 2) { - NK_ASSERT((list->vertex_count < NK_USHORT_MAX && "To many vertices for 16-bit vertex indices. Please read comment above on how to solve this problem")); - } - return vtx; -} -NK_INTERN nk_draw_index * -nk_draw_list_alloc_elements(struct nk_draw_list *list, nk_size count) -{ - nk_draw_index *ids; - struct nk_draw_command *cmd; - NK_STORAGE const nk_size elem_align = NK_ALIGNOF(nk_draw_index); - NK_STORAGE const nk_size elem_size = sizeof(nk_draw_index); - NK_ASSERT(list); - if (!list) { - return 0; - } - - ids = (nk_draw_index *)nk_buffer_alloc(list->elements, NK_BUFFER_FRONT, elem_size * count, elem_align); - if (!ids) { - return 0; - } - cmd = nk_draw_list_command_last(list); - list->element_count += (unsigned int)count; - cmd->elem_count += (unsigned int)count; - return ids; -} -NK_INTERN int -nk_draw_vertex_layout_element_is_end_of_layout(const struct nk_draw_vertex_layout_element *element) -{ - return (element->attribute == NK_VERTEX_ATTRIBUTE_COUNT || element->format == NK_FORMAT_COUNT); -} -NK_INTERN void -nk_draw_vertex_color(void *attr, const float *vals, enum nk_draw_vertex_layout_format format) -{ - /* if this triggers you tried to provide a value format for a color */ - float val[4]; - NK_ASSERT(format >= NK_FORMAT_COLOR_BEGIN); - NK_ASSERT(format <= NK_FORMAT_COLOR_END); - if (format < NK_FORMAT_COLOR_BEGIN || format > NK_FORMAT_COLOR_END) { - return; - } - - val[0] = NK_SATURATE(vals[0]); - val[1] = NK_SATURATE(vals[1]); - val[2] = NK_SATURATE(vals[2]); - val[3] = NK_SATURATE(vals[3]); - - switch (format) { - default: - NK_ASSERT(0 && "Invalid vertex layout color format"); - break; - case NK_FORMAT_R8G8B8A8: - case NK_FORMAT_R8G8B8: { - struct nk_color col = nk_rgba_fv(val); - NK_MEMCPY(attr, &col.r, sizeof(col)); - } break; - case NK_FORMAT_B8G8R8A8: { - struct nk_color col = nk_rgba_fv(val); - struct nk_color bgra = nk_rgba(col.b, col.g, col.r, col.a); - NK_MEMCPY(attr, &bgra, sizeof(bgra)); - } break; - case NK_FORMAT_R16G15B16: { - nk_ushort col[3]; - col[0] = (nk_ushort)(val[0] * (float)NK_USHORT_MAX); - col[1] = (nk_ushort)(val[1] * (float)NK_USHORT_MAX); - col[2] = (nk_ushort)(val[2] * (float)NK_USHORT_MAX); - NK_MEMCPY(attr, col, sizeof(col)); - } break; - case NK_FORMAT_R16G15B16A16: { - nk_ushort col[4]; - col[0] = (nk_ushort)(val[0] * (float)NK_USHORT_MAX); - col[1] = (nk_ushort)(val[1] * (float)NK_USHORT_MAX); - col[2] = (nk_ushort)(val[2] * (float)NK_USHORT_MAX); - col[3] = (nk_ushort)(val[3] * (float)NK_USHORT_MAX); - NK_MEMCPY(attr, col, sizeof(col)); - } break; - case NK_FORMAT_R32G32B32: { - nk_uint col[3]; - col[0] = (nk_uint)(val[0] * (float)NK_UINT_MAX); - col[1] = (nk_uint)(val[1] * (float)NK_UINT_MAX); - col[2] = (nk_uint)(val[2] * (float)NK_UINT_MAX); - NK_MEMCPY(attr, col, sizeof(col)); - } break; - case NK_FORMAT_R32G32B32A32: { - nk_uint col[4]; - col[0] = (nk_uint)(val[0] * (float)NK_UINT_MAX); - col[1] = (nk_uint)(val[1] * (float)NK_UINT_MAX); - col[2] = (nk_uint)(val[2] * (float)NK_UINT_MAX); - col[3] = (nk_uint)(val[3] * (float)NK_UINT_MAX); - NK_MEMCPY(attr, col, sizeof(col)); - } break; - case NK_FORMAT_R32G32B32A32_FLOAT: - NK_MEMCPY(attr, val, sizeof(float) * 4); - break; - case NK_FORMAT_R32G32B32A32_DOUBLE: { - double col[4]; - col[0] = (double)val[0]; - col[1] = (double)val[1]; - col[2] = (double)val[2]; - col[3] = (double)val[3]; - NK_MEMCPY(attr, col, sizeof(col)); - } break; - case NK_FORMAT_RGB32: - case NK_FORMAT_RGBA32: { - struct nk_color col = nk_rgba_fv(val); - nk_uint color = nk_color_u32(col); - NK_MEMCPY(attr, &color, sizeof(color)); - } break; - } -} -NK_INTERN void -nk_draw_vertex_element(void *dst, const float *values, int value_count, enum nk_draw_vertex_layout_format format) -{ - int value_index; - void *attribute = dst; - /* if this triggers you tried to provide a color format for a value */ - NK_ASSERT(format < NK_FORMAT_COLOR_BEGIN); - if (format >= NK_FORMAT_COLOR_BEGIN && format <= NK_FORMAT_COLOR_END) { - return; - } - for (value_index = 0; value_index < value_count; ++value_index) { - switch (format) { - default: - NK_ASSERT(0 && "invalid vertex layout format"); - break; - case NK_FORMAT_SCHAR: { - char value = (char)NK_CLAMP((float)NK_SCHAR_MIN, values[value_index], (float)NK_SCHAR_MAX); - NK_MEMCPY(attribute, &value, sizeof(value)); - attribute = (void *)((char *)attribute + sizeof(char)); - } break; - case NK_FORMAT_SSHORT: { - nk_short value = (nk_short)NK_CLAMP((float)NK_SSHORT_MIN, values[value_index], (float)NK_SSHORT_MAX); - NK_MEMCPY(attribute, &value, sizeof(value)); - attribute = (void *)((char *)attribute + sizeof(value)); - } break; - case NK_FORMAT_SINT: { - nk_int value = (nk_int)NK_CLAMP((float)NK_SINT_MIN, values[value_index], (float)NK_SINT_MAX); - NK_MEMCPY(attribute, &value, sizeof(value)); - attribute = (void *)((char *)attribute + sizeof(nk_int)); - } break; - case NK_FORMAT_UCHAR: { - unsigned char value = (unsigned char)NK_CLAMP((float)NK_UCHAR_MIN, values[value_index], (float)NK_UCHAR_MAX); - NK_MEMCPY(attribute, &value, sizeof(value)); - attribute = (void *)((char *)attribute + sizeof(unsigned char)); - } break; - case NK_FORMAT_USHORT: { - nk_ushort value = (nk_ushort)NK_CLAMP((float)NK_USHORT_MIN, values[value_index], (float)NK_USHORT_MAX); - NK_MEMCPY(attribute, &value, sizeof(value)); - attribute = (void *)((char *)attribute + sizeof(value)); - } break; - case NK_FORMAT_UINT: { - nk_uint value = (nk_uint)NK_CLAMP((float)NK_UINT_MIN, values[value_index], (float)NK_UINT_MAX); - NK_MEMCPY(attribute, &value, sizeof(value)); - attribute = (void *)((char *)attribute + sizeof(nk_uint)); - } break; - case NK_FORMAT_FLOAT: - NK_MEMCPY(attribute, &values[value_index], sizeof(values[value_index])); - attribute = (void *)((char *)attribute + sizeof(float)); - break; - case NK_FORMAT_DOUBLE: { - double value = (double)values[value_index]; - NK_MEMCPY(attribute, &value, sizeof(value)); - attribute = (void *)((char *)attribute + sizeof(double)); - } break; - } - } -} -NK_INTERN void * -nk_draw_vertex(void *dst, const struct nk_convert_config *config, struct nk_vec2 pos, struct nk_vec2 uv, struct nk_colorf color) -{ - void *result = (void *)((char *)dst + config->vertex_size); - const struct nk_draw_vertex_layout_element *elem_iter = config->vertex_layout; - while (!nk_draw_vertex_layout_element_is_end_of_layout(elem_iter)) { - void *address = (void *)((char *)dst + elem_iter->offset); - switch (elem_iter->attribute) { - case NK_VERTEX_ATTRIBUTE_COUNT: - default: - NK_ASSERT(0 && "wrong element attribute"); - break; - case NK_VERTEX_POSITION: - nk_draw_vertex_element(address, &pos.x, 2, elem_iter->format); - break; - case NK_VERTEX_TEXCOORD: - nk_draw_vertex_element(address, &uv.x, 2, elem_iter->format); - break; - case NK_VERTEX_COLOR: - nk_draw_vertex_color(address, &color.r, elem_iter->format); - break; - } - elem_iter++; - } - return result; -} -NK_API void -nk_draw_list_stroke_poly_line(struct nk_draw_list *list, - const struct nk_vec2 *points, - const unsigned int points_count, - struct nk_color color, - enum nk_draw_list_stroke closed, - float thickness, - enum nk_anti_aliasing aliasing) -{ - nk_size count; - int thick_line; - struct nk_colorf col; - struct nk_colorf col_trans; - NK_ASSERT(list); - if (!list || points_count < 2) { - return; - } - - color.a = (nk_byte)((float)color.a * list->config.global_alpha); - count = points_count; - if (!closed) { - count = points_count - 1; - } - thick_line = thickness > 1.0f; - -# ifdef NK_INCLUDE_COMMAND_USERDATA - nk_draw_list_push_userdata(list, list->userdata); -# endif - - color.a = (nk_byte)((float)color.a * list->config.global_alpha); - nk_color_fv(&col.r, color); - col_trans = col; - col_trans.a = 0; - - if (aliasing == NK_ANTI_ALIASING_ON) { - /* ANTI-ALIASED STROKE */ - const float AA_SIZE = 1.0f; - NK_STORAGE const nk_size pnt_align = NK_ALIGNOF(struct nk_vec2); - NK_STORAGE const nk_size pnt_size = sizeof(struct nk_vec2); - - /* allocate vertices and elements */ - nk_size i1 = 0; - nk_size vertex_offset; - nk_size index = list->vertex_count; - - const nk_size idx_count = (thick_line) ? (count * 18) : (count * 12); - const nk_size vtx_count = (thick_line) ? (points_count * 4) : (points_count * 3); - - void *vtx = nk_draw_list_alloc_vertices(list, vtx_count); - nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count); - - nk_size size; - struct nk_vec2 *normals, *temp; - if (!vtx || !ids) { - return; - } - - /* temporary allocate normals + points */ - vertex_offset = (nk_size)((nk_byte *)vtx - (nk_byte *)list->vertices->memory.ptr); - nk_buffer_mark(list->vertices, NK_BUFFER_FRONT); - size = pnt_size * ((thick_line) ? 5 : 3) * points_count; - normals = (struct nk_vec2 *)nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT, size, pnt_align); - if (!normals) { - return; - } - temp = normals + points_count; - - /* make sure vertex pointer is still correct */ - vtx = (void *)((nk_byte *)list->vertices->memory.ptr + vertex_offset); - - /* calculate normals */ - for (i1 = 0; i1 < count; ++i1) { - const nk_size i2 = ((i1 + 1) == points_count) ? 0 : (i1 + 1); - struct nk_vec2 diff = nk_vec2_sub(points[i2], points[i1]); - float len; - - /* vec2 inverted length */ - len = nk_vec2_len_sqr(diff); - if (len != 0.0f) { - len = NK_INV_SQRT(len); - } else { - len = 1.0f; - } - - diff = nk_vec2_muls(diff, len); - normals[i1].x = diff.y; - normals[i1].y = -diff.x; - } - - if (!closed) { - normals[points_count - 1] = normals[points_count - 2]; - } - - if (!thick_line) { - nk_size idx1, i; - if (!closed) { - struct nk_vec2 d; - temp[0] = nk_vec2_add(points[0], nk_vec2_muls(normals[0], AA_SIZE)); - temp[1] = nk_vec2_sub(points[0], nk_vec2_muls(normals[0], AA_SIZE)); - d = nk_vec2_muls(normals[points_count - 1], AA_SIZE); - temp[(points_count - 1) * 2 + 0] = nk_vec2_add(points[points_count - 1], d); - temp[(points_count - 1) * 2 + 1] = nk_vec2_sub(points[points_count - 1], d); - } - - /* fill elements */ - idx1 = index; - for (i1 = 0; i1 < count; i1++) { - struct nk_vec2 dm; - float dmr2; - nk_size i2 = ((i1 + 1) == points_count) ? 0 : (i1 + 1); - nk_size idx2 = ((i1 + 1) == points_count) ? index : (idx1 + 3); - - /* average normals */ - dm = nk_vec2_muls(nk_vec2_add(normals[i1], normals[i2]), 0.5f); - dmr2 = dm.x * dm.x + dm.y * dm.y; - if (dmr2 > 0.000001f) { - float scale = 1.0f / dmr2; - scale = NK_MIN(100.0f, scale); - dm = nk_vec2_muls(dm, scale); - } - - dm = nk_vec2_muls(dm, AA_SIZE); - temp[i2 * 2 + 0] = nk_vec2_add(points[i2], dm); - temp[i2 * 2 + 1] = nk_vec2_sub(points[i2], dm); - - ids[0] = (nk_draw_index)(idx2 + 0); - ids[1] = (nk_draw_index)(idx1 + 0); - ids[2] = (nk_draw_index)(idx1 + 2); - ids[3] = (nk_draw_index)(idx1 + 2); - ids[4] = (nk_draw_index)(idx2 + 2); - ids[5] = (nk_draw_index)(idx2 + 0); - ids[6] = (nk_draw_index)(idx2 + 1); - ids[7] = (nk_draw_index)(idx1 + 1); - ids[8] = (nk_draw_index)(idx1 + 0); - ids[9] = (nk_draw_index)(idx1 + 0); - ids[10] = (nk_draw_index)(idx2 + 0); - ids[11] = (nk_draw_index)(idx2 + 1); - ids += 12; - idx1 = idx2; - } - - /* fill vertices */ - for (i = 0; i < points_count; ++i) { - const struct nk_vec2 uv = list->config.tex_null.uv; - vtx = nk_draw_vertex(vtx, &list->config, points[i], uv, col); - vtx = nk_draw_vertex(vtx, &list->config, temp[i * 2 + 0], uv, col_trans); - vtx = nk_draw_vertex(vtx, &list->config, temp[i * 2 + 1], uv, col_trans); - } - } else { - nk_size idx1, i; - const float half_inner_thickness = (thickness - AA_SIZE) * 0.5f; - if (!closed) { - struct nk_vec2 d1 = nk_vec2_muls(normals[0], half_inner_thickness + AA_SIZE); - struct nk_vec2 d2 = nk_vec2_muls(normals[0], half_inner_thickness); - - temp[0] = nk_vec2_add(points[0], d1); - temp[1] = nk_vec2_add(points[0], d2); - temp[2] = nk_vec2_sub(points[0], d2); - temp[3] = nk_vec2_sub(points[0], d1); - - d1 = nk_vec2_muls(normals[points_count - 1], half_inner_thickness + AA_SIZE); - d2 = nk_vec2_muls(normals[points_count - 1], half_inner_thickness); - - temp[(points_count - 1) * 4 + 0] = nk_vec2_add(points[points_count - 1], d1); - temp[(points_count - 1) * 4 + 1] = nk_vec2_add(points[points_count - 1], d2); - temp[(points_count - 1) * 4 + 2] = nk_vec2_sub(points[points_count - 1], d2); - temp[(points_count - 1) * 4 + 3] = nk_vec2_sub(points[points_count - 1], d1); - } - - /* add all elements */ - idx1 = index; - for (i1 = 0; i1 < count; ++i1) { - struct nk_vec2 dm_out, dm_in; - const nk_size i2 = ((i1 + 1) == points_count) ? 0 : (i1 + 1); - nk_size idx2 = ((i1 + 1) == points_count) ? index : (idx1 + 4); - - /* average normals */ - struct nk_vec2 dm = nk_vec2_muls(nk_vec2_add(normals[i1], normals[i2]), 0.5f); - float dmr2 = dm.x * dm.x + dm.y * dm.y; - if (dmr2 > 0.000001f) { - float scale = 1.0f / dmr2; - scale = NK_MIN(100.0f, scale); - dm = nk_vec2_muls(dm, scale); - } - - dm_out = nk_vec2_muls(dm, ((half_inner_thickness) + AA_SIZE)); - dm_in = nk_vec2_muls(dm, half_inner_thickness); - temp[i2 * 4 + 0] = nk_vec2_add(points[i2], dm_out); - temp[i2 * 4 + 1] = nk_vec2_add(points[i2], dm_in); - temp[i2 * 4 + 2] = nk_vec2_sub(points[i2], dm_in); - temp[i2 * 4 + 3] = nk_vec2_sub(points[i2], dm_out); - - /* add indexes */ - ids[0] = (nk_draw_index)(idx2 + 1); - ids[1] = (nk_draw_index)(idx1 + 1); - ids[2] = (nk_draw_index)(idx1 + 2); - ids[3] = (nk_draw_index)(idx1 + 2); - ids[4] = (nk_draw_index)(idx2 + 2); - ids[5] = (nk_draw_index)(idx2 + 1); - ids[6] = (nk_draw_index)(idx2 + 1); - ids[7] = (nk_draw_index)(idx1 + 1); - ids[8] = (nk_draw_index)(idx1 + 0); - ids[9] = (nk_draw_index)(idx1 + 0); - ids[10] = (nk_draw_index)(idx2 + 0); - ids[11] = (nk_draw_index)(idx2 + 1); - ids[12] = (nk_draw_index)(idx2 + 2); - ids[13] = (nk_draw_index)(idx1 + 2); - ids[14] = (nk_draw_index)(idx1 + 3); - ids[15] = (nk_draw_index)(idx1 + 3); - ids[16] = (nk_draw_index)(idx2 + 3); - ids[17] = (nk_draw_index)(idx2 + 2); - ids += 18; - idx1 = idx2; - } - - /* add vertices */ - for (i = 0; i < points_count; ++i) { - const struct nk_vec2 uv = list->config.tex_null.uv; - vtx = nk_draw_vertex(vtx, &list->config, temp[i * 4 + 0], uv, col_trans); - vtx = nk_draw_vertex(vtx, &list->config, temp[i * 4 + 1], uv, col); - vtx = nk_draw_vertex(vtx, &list->config, temp[i * 4 + 2], uv, col); - vtx = nk_draw_vertex(vtx, &list->config, temp[i * 4 + 3], uv, col_trans); - } - } - /* free temporary normals + points */ - nk_buffer_reset(list->vertices, NK_BUFFER_FRONT); - } else { - /* NON ANTI-ALIASED STROKE */ - nk_size i1 = 0; - nk_size idx = list->vertex_count; - const nk_size idx_count = count * 6; - const nk_size vtx_count = count * 4; - void *vtx = nk_draw_list_alloc_vertices(list, vtx_count); - nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count); - if (!vtx || !ids) { - return; - } - - for (i1 = 0; i1 < count; ++i1) { - float dx, dy; - const struct nk_vec2 uv = list->config.tex_null.uv; - const nk_size i2 = ((i1 + 1) == points_count) ? 0 : i1 + 1; - const struct nk_vec2 p1 = points[i1]; - const struct nk_vec2 p2 = points[i2]; - struct nk_vec2 diff = nk_vec2_sub(p2, p1); - float len; - - /* vec2 inverted length */ - len = nk_vec2_len_sqr(diff); - if (len != 0.0f) { - len = NK_INV_SQRT(len); - } else { - len = 1.0f; - } - diff = nk_vec2_muls(diff, len); - - /* add vertices */ - dx = diff.x * (thickness * 0.5f); - dy = diff.y * (thickness * 0.5f); - - vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p1.x + dy, p1.y - dx), uv, col); - vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p2.x + dy, p2.y - dx), uv, col); - vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p2.x - dy, p2.y + dx), uv, col); - vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(p1.x - dy, p1.y + dx), uv, col); - - ids[0] = (nk_draw_index)(idx + 0); - ids[1] = (nk_draw_index)(idx + 1); - ids[2] = (nk_draw_index)(idx + 2); - ids[3] = (nk_draw_index)(idx + 0); - ids[4] = (nk_draw_index)(idx + 2); - ids[5] = (nk_draw_index)(idx + 3); - - ids += 6; - idx += 4; - } - } -} -NK_API void -nk_draw_list_fill_poly_convex(struct nk_draw_list *list, const struct nk_vec2 *points, const unsigned int points_count, struct nk_color color, enum nk_anti_aliasing aliasing) -{ - struct nk_colorf col; - struct nk_colorf col_trans; - - NK_STORAGE const nk_size pnt_align = NK_ALIGNOF(struct nk_vec2); - NK_STORAGE const nk_size pnt_size = sizeof(struct nk_vec2); - NK_ASSERT(list); - if (!list || points_count < 3) { - return; - } - -# ifdef NK_INCLUDE_COMMAND_USERDATA - nk_draw_list_push_userdata(list, list->userdata); -# endif - - color.a = (nk_byte)((float)color.a * list->config.global_alpha); - nk_color_fv(&col.r, color); - col_trans = col; - col_trans.a = 0; - - if (aliasing == NK_ANTI_ALIASING_ON) { - nk_size i = 0; - nk_size i0 = 0; - nk_size i1 = 0; - - const float AA_SIZE = 1.0f; - nk_size vertex_offset = 0; - nk_size index = list->vertex_count; - - const nk_size idx_count = (points_count - 2) * 3 + points_count * 6; - const nk_size vtx_count = (points_count * 2); - - void *vtx = nk_draw_list_alloc_vertices(list, vtx_count); - nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count); - - nk_size size = 0; - struct nk_vec2 *normals = 0; - unsigned int vtx_inner_idx = (unsigned int)(index + 0); - unsigned int vtx_outer_idx = (unsigned int)(index + 1); - if (!vtx || !ids) { - return; - } - - /* temporary allocate normals */ - vertex_offset = (nk_size)((nk_byte *)vtx - (nk_byte *)list->vertices->memory.ptr); - nk_buffer_mark(list->vertices, NK_BUFFER_FRONT); - size = pnt_size * points_count; - normals = (struct nk_vec2 *)nk_buffer_alloc(list->vertices, NK_BUFFER_FRONT, size, pnt_align); - if (!normals) { - return; - } - vtx = (void *)((nk_byte *)list->vertices->memory.ptr + vertex_offset); - - /* add elements */ - for (i = 2; i < points_count; i++) { - ids[0] = (nk_draw_index)(vtx_inner_idx); - ids[1] = (nk_draw_index)(vtx_inner_idx + ((i - 1) << 1)); - ids[2] = (nk_draw_index)(vtx_inner_idx + (i << 1)); - ids += 3; - } - - /* compute normals */ - for (i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++) { - struct nk_vec2 p0 = points[i0]; - struct nk_vec2 p1 = points[i1]; - struct nk_vec2 diff = nk_vec2_sub(p1, p0); - - /* vec2 inverted length */ - float len = nk_vec2_len_sqr(diff); - if (len != 0.0f) { - len = NK_INV_SQRT(len); - } else { - len = 1.0f; - } - diff = nk_vec2_muls(diff, len); - - normals[i0].x = diff.y; - normals[i0].y = -diff.x; - } - - /* add vertices + indexes */ - for (i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++) { - const struct nk_vec2 uv = list->config.tex_null.uv; - struct nk_vec2 n0 = normals[i0]; - struct nk_vec2 n1 = normals[i1]; - struct nk_vec2 dm = nk_vec2_muls(nk_vec2_add(n0, n1), 0.5f); - float dmr2 = dm.x * dm.x + dm.y * dm.y; - if (dmr2 > 0.000001f) { - float scale = 1.0f / dmr2; - scale = NK_MIN(scale, 100.0f); - dm = nk_vec2_muls(dm, scale); - } - dm = nk_vec2_muls(dm, AA_SIZE * 0.5f); - - /* add vertices */ - vtx = nk_draw_vertex(vtx, &list->config, nk_vec2_sub(points[i1], dm), uv, col); - vtx = nk_draw_vertex(vtx, &list->config, nk_vec2_add(points[i1], dm), uv, col_trans); - - /* add indexes */ - ids[0] = (nk_draw_index)(vtx_inner_idx + (i1 << 1)); - ids[1] = (nk_draw_index)(vtx_inner_idx + (i0 << 1)); - ids[2] = (nk_draw_index)(vtx_outer_idx + (i0 << 1)); - ids[3] = (nk_draw_index)(vtx_outer_idx + (i0 << 1)); - ids[4] = (nk_draw_index)(vtx_outer_idx + (i1 << 1)); - ids[5] = (nk_draw_index)(vtx_inner_idx + (i1 << 1)); - ids += 6; - } - /* free temporary normals + points */ - nk_buffer_reset(list->vertices, NK_BUFFER_FRONT); - } else { - nk_size i = 0; - nk_size index = list->vertex_count; - const nk_size idx_count = (points_count - 2) * 3; - const nk_size vtx_count = points_count; - void *vtx = nk_draw_list_alloc_vertices(list, vtx_count); - nk_draw_index *ids = nk_draw_list_alloc_elements(list, idx_count); - - if (!vtx || !ids) { - return; - } - for (i = 0; i < vtx_count; ++i) { - vtx = nk_draw_vertex(vtx, &list->config, points[i], list->config.tex_null.uv, col); - } - for (i = 2; i < points_count; ++i) { - ids[0] = (nk_draw_index)index; - ids[1] = (nk_draw_index)(index + i - 1); - ids[2] = (nk_draw_index)(index + i); - ids += 3; - } - } -} -NK_API void -nk_draw_list_path_clear(struct nk_draw_list *list) -{ - NK_ASSERT(list); - if (!list) { - return; - } - nk_buffer_reset(list->buffer, NK_BUFFER_FRONT); - list->path_count = 0; - list->path_offset = 0; -} -NK_API void -nk_draw_list_path_line_to(struct nk_draw_list *list, struct nk_vec2 pos) -{ - struct nk_vec2 *points = 0; - struct nk_draw_command *cmd = 0; - NK_ASSERT(list); - if (!list) { - return; - } - if (!list->cmd_count) { - nk_draw_list_add_clip(list, nk_null_rect); - } - - cmd = nk_draw_list_command_last(list); - if (cmd && cmd->texture.ptr != list->config.tex_null.texture.ptr) { - nk_draw_list_push_image(list, list->config.tex_null.texture); - } - - points = nk_draw_list_alloc_path(list, 1); - if (!points) { - return; - } - points[0] = pos; -} -NK_API void -nk_draw_list_path_arc_to_fast(struct nk_draw_list *list, struct nk_vec2 center, float radius, int a_min, int a_max) -{ - int a = 0; - NK_ASSERT(list); - if (!list) { - return; - } - if (a_min <= a_max) { - for (a = a_min; a <= a_max; a++) { - const struct nk_vec2 c = list->circle_vtx[(nk_size)a % NK_LEN(list->circle_vtx)]; - const float x = center.x + c.x * radius; - const float y = center.y + c.y * radius; - nk_draw_list_path_line_to(list, nk_vec2(x, y)); - } - } -} -NK_API void -nk_draw_list_path_arc_to(struct nk_draw_list *list, struct nk_vec2 center, float radius, float a_min, float a_max, unsigned int segments) -{ - unsigned int i = 0; - NK_ASSERT(list); - if (!list) { - return; - } - if (radius == 0.0f) { - return; - } - - /* This algorithm for arc drawing relies on these two trigonometric identities[1]: - sin(a + b) = sin(a) * cos(b) + cos(a) * sin(b) - cos(a + b) = cos(a) * cos(b) - sin(a) * sin(b) - - Two coordinates (x, y) of a point on a circle centered on - the origin can be written in polar form as: - x = r * cos(a) - y = r * sin(a) - where r is the radius of the circle, - a is the angle between (x, y) and the origin. - - This allows us to rotate the coordinates around the - origin by an angle b using the following transformation: - x' = r * cos(a + b) = x * cos(b) - y * sin(b) - y' = r * sin(a + b) = y * cos(b) + x * sin(b) - - [1] https://en.wikipedia.org/wiki/List_of_trigonometric_identities#Angle_sum_and_difference_identities - */ - { - const float d_angle = (a_max - a_min) / (float)segments; - const float sin_d = (float)NK_SIN(d_angle); - const float cos_d = (float)NK_COS(d_angle); - - float cx = (float)NK_COS(a_min) * radius; - float cy = (float)NK_SIN(a_min) * radius; - for (i = 0; i <= segments; ++i) { - float new_cx, new_cy; - const float x = center.x + cx; - const float y = center.y + cy; - nk_draw_list_path_line_to(list, nk_vec2(x, y)); - - new_cx = cx * cos_d - cy * sin_d; - new_cy = cy * cos_d + cx * sin_d; - cx = new_cx; - cy = new_cy; - } - } -} -NK_API void -nk_draw_list_path_rect_to(struct nk_draw_list *list, struct nk_vec2 a, struct nk_vec2 b, float rounding) -{ - float r; - NK_ASSERT(list); - if (!list) { - return; - } - r = rounding; - r = NK_MIN(r, ((b.x - a.x) < 0) ? -(b.x - a.x) : (b.x - a.x)); - r = NK_MIN(r, ((b.y - a.y) < 0) ? -(b.y - a.y) : (b.y - a.y)); - - if (r == 0.0f) { - nk_draw_list_path_line_to(list, a); - nk_draw_list_path_line_to(list, nk_vec2(b.x, a.y)); - nk_draw_list_path_line_to(list, b); - nk_draw_list_path_line_to(list, nk_vec2(a.x, b.y)); - } else { - nk_draw_list_path_arc_to_fast(list, nk_vec2(a.x + r, a.y + r), r, 6, 9); - nk_draw_list_path_arc_to_fast(list, nk_vec2(b.x - r, a.y + r), r, 9, 12); - nk_draw_list_path_arc_to_fast(list, nk_vec2(b.x - r, b.y - r), r, 0, 3); - nk_draw_list_path_arc_to_fast(list, nk_vec2(a.x + r, b.y - r), r, 3, 6); - } -} -NK_API void -nk_draw_list_path_curve_to(struct nk_draw_list *list, struct nk_vec2 p2, struct nk_vec2 p3, struct nk_vec2 p4, unsigned int num_segments) -{ - float t_step; - unsigned int i_step; - struct nk_vec2 p1; - - NK_ASSERT(list); - NK_ASSERT(list->path_count); - if (!list || !list->path_count) { - return; - } - num_segments = NK_MAX(num_segments, 1); - - p1 = nk_draw_list_path_last(list); - t_step = 1.0f / (float)num_segments; - for (i_step = 1; i_step <= num_segments; ++i_step) { - float t = t_step * (float)i_step; - float u = 1.0f - t; - float w1 = u * u * u; - float w2 = 3 * u * u * t; - float w3 = 3 * u * t * t; - float w4 = t * t * t; - float x = w1 * p1.x + w2 * p2.x + w3 * p3.x + w4 * p4.x; - float y = w1 * p1.y + w2 * p2.y + w3 * p3.y + w4 * p4.y; - nk_draw_list_path_line_to(list, nk_vec2(x, y)); - } -} -NK_API void -nk_draw_list_path_fill(struct nk_draw_list *list, struct nk_color color) -{ - struct nk_vec2 *points; - NK_ASSERT(list); - if (!list) { - return; - } - points = (struct nk_vec2 *)nk_buffer_memory(list->buffer); - nk_draw_list_fill_poly_convex(list, points, list->path_count, color, list->config.shape_AA); - nk_draw_list_path_clear(list); -} -NK_API void -nk_draw_list_path_stroke(struct nk_draw_list *list, struct nk_color color, enum nk_draw_list_stroke closed, float thickness) -{ - struct nk_vec2 *points; - NK_ASSERT(list); - if (!list) { - return; - } - points = (struct nk_vec2 *)nk_buffer_memory(list->buffer); - nk_draw_list_stroke_poly_line(list, points, list->path_count, color, closed, thickness, list->config.line_AA); - nk_draw_list_path_clear(list); -} -NK_API void -nk_draw_list_stroke_line(struct nk_draw_list *list, struct nk_vec2 a, struct nk_vec2 b, struct nk_color col, float thickness) -{ - NK_ASSERT(list); - if (!list || !col.a) { - return; - } - if (list->line_AA == NK_ANTI_ALIASING_ON) { - nk_draw_list_path_line_to(list, a); - nk_draw_list_path_line_to(list, b); - } else { - nk_draw_list_path_line_to(list, nk_vec2_sub(a, nk_vec2(0.5f, 0.5f))); - nk_draw_list_path_line_to(list, nk_vec2_sub(b, nk_vec2(0.5f, 0.5f))); - } - nk_draw_list_path_stroke(list, col, NK_STROKE_OPEN, thickness); -} -NK_API void -nk_draw_list_fill_rect(struct nk_draw_list *list, struct nk_rect rect, struct nk_color col, float rounding) -{ - NK_ASSERT(list); - if (!list || !col.a) { - return; - } - - if (list->line_AA == NK_ANTI_ALIASING_ON) { - nk_draw_list_path_rect_to(list, nk_vec2(rect.x, rect.y), nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding); - } else { - nk_draw_list_path_rect_to(list, nk_vec2(rect.x - 0.5f, rect.y - 0.5f), nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding); - } - nk_draw_list_path_fill(list, col); -} -NK_API void -nk_draw_list_stroke_rect(struct nk_draw_list *list, struct nk_rect rect, struct nk_color col, float rounding, float thickness) -{ - NK_ASSERT(list); - if (!list || !col.a) { - return; - } - if (list->line_AA == NK_ANTI_ALIASING_ON) { - nk_draw_list_path_rect_to(list, nk_vec2(rect.x, rect.y), nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding); - } else { - nk_draw_list_path_rect_to(list, nk_vec2(rect.x - 0.5f, rect.y - 0.5f), nk_vec2(rect.x + rect.w, rect.y + rect.h), rounding); - } - nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness); -} -NK_API void -nk_draw_list_fill_rect_multi_color(struct nk_draw_list *list, struct nk_rect rect, struct nk_color left, struct nk_color top, struct nk_color right, struct nk_color bottom) -{ - void *vtx; - struct nk_colorf col_left, col_top; - struct nk_colorf col_right, col_bottom; - nk_draw_index *idx; - nk_draw_index index; - - nk_color_fv(&col_left.r, left); - nk_color_fv(&col_right.r, right); - nk_color_fv(&col_top.r, top); - nk_color_fv(&col_bottom.r, bottom); - - NK_ASSERT(list); - if (!list) { - return; - } - - nk_draw_list_push_image(list, list->config.tex_null.texture); - index = (nk_draw_index)list->vertex_count; - vtx = nk_draw_list_alloc_vertices(list, 4); - idx = nk_draw_list_alloc_elements(list, 6); - if (!vtx || !idx) { - return; - } - - idx[0] = (nk_draw_index)(index + 0); - idx[1] = (nk_draw_index)(index + 1); - idx[2] = (nk_draw_index)(index + 2); - idx[3] = (nk_draw_index)(index + 0); - idx[4] = (nk_draw_index)(index + 2); - idx[5] = (nk_draw_index)(index + 3); - - vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x, rect.y), list->config.tex_null.uv, col_left); - vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x + rect.w, rect.y), list->config.tex_null.uv, col_top); - vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x + rect.w, rect.y + rect.h), list->config.tex_null.uv, col_right); - vtx = nk_draw_vertex(vtx, &list->config, nk_vec2(rect.x, rect.y + rect.h), list->config.tex_null.uv, col_bottom); -} -NK_API void -nk_draw_list_fill_triangle(struct nk_draw_list *list, struct nk_vec2 a, struct nk_vec2 b, struct nk_vec2 c, struct nk_color col) -{ - NK_ASSERT(list); - if (!list || !col.a) { - return; - } - nk_draw_list_path_line_to(list, a); - nk_draw_list_path_line_to(list, b); - nk_draw_list_path_line_to(list, c); - nk_draw_list_path_fill(list, col); -} -NK_API void -nk_draw_list_stroke_triangle(struct nk_draw_list *list, struct nk_vec2 a, struct nk_vec2 b, struct nk_vec2 c, struct nk_color col, float thickness) -{ - NK_ASSERT(list); - if (!list || !col.a) { - return; - } - nk_draw_list_path_line_to(list, a); - nk_draw_list_path_line_to(list, b); - nk_draw_list_path_line_to(list, c); - nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness); -} -NK_API void -nk_draw_list_fill_circle(struct nk_draw_list *list, struct nk_vec2 center, float radius, struct nk_color col, unsigned int segs) -{ - float a_max; - NK_ASSERT(list); - if (!list || !col.a) { - return; - } - a_max = NK_PI * 2.0f * ((float)segs - 1.0f) / (float)segs; - nk_draw_list_path_arc_to(list, center, radius, 0.0f, a_max, segs); - nk_draw_list_path_fill(list, col); -} -NK_API void -nk_draw_list_stroke_circle(struct nk_draw_list *list, struct nk_vec2 center, float radius, struct nk_color col, unsigned int segs, float thickness) -{ - float a_max; - NK_ASSERT(list); - if (!list || !col.a) { - return; - } - a_max = NK_PI * 2.0f * ((float)segs - 1.0f) / (float)segs; - nk_draw_list_path_arc_to(list, center, radius, 0.0f, a_max, segs); - nk_draw_list_path_stroke(list, col, NK_STROKE_CLOSED, thickness); -} -NK_API void -nk_draw_list_stroke_curve( - struct nk_draw_list *list, struct nk_vec2 p0, struct nk_vec2 cp0, struct nk_vec2 cp1, struct nk_vec2 p1, struct nk_color col, unsigned int segments, float thickness) -{ - NK_ASSERT(list); - if (!list || !col.a) { - return; - } - nk_draw_list_path_line_to(list, p0); - nk_draw_list_path_curve_to(list, cp0, cp1, p1, segments); - nk_draw_list_path_stroke(list, col, NK_STROKE_OPEN, thickness); -} -NK_INTERN void -nk_draw_list_push_rect_uv(struct nk_draw_list *list, struct nk_vec2 a, struct nk_vec2 c, struct nk_vec2 uva, struct nk_vec2 uvc, struct nk_color color) -{ - void *vtx; - struct nk_vec2 uvb; - struct nk_vec2 uvd; - struct nk_vec2 b; - struct nk_vec2 d; - - struct nk_colorf col; - nk_draw_index *idx; - nk_draw_index index; - NK_ASSERT(list); - if (!list) { - return; - } - - nk_color_fv(&col.r, color); - uvb = nk_vec2(uvc.x, uva.y); - uvd = nk_vec2(uva.x, uvc.y); - b = nk_vec2(c.x, a.y); - d = nk_vec2(a.x, c.y); - - index = (nk_draw_index)list->vertex_count; - vtx = nk_draw_list_alloc_vertices(list, 4); - idx = nk_draw_list_alloc_elements(list, 6); - if (!vtx || !idx) { - return; - } - - idx[0] = (nk_draw_index)(index + 0); - idx[1] = (nk_draw_index)(index + 1); - idx[2] = (nk_draw_index)(index + 2); - idx[3] = (nk_draw_index)(index + 0); - idx[4] = (nk_draw_index)(index + 2); - idx[5] = (nk_draw_index)(index + 3); - - vtx = nk_draw_vertex(vtx, &list->config, a, uva, col); - vtx = nk_draw_vertex(vtx, &list->config, b, uvb, col); - vtx = nk_draw_vertex(vtx, &list->config, c, uvc, col); - vtx = nk_draw_vertex(vtx, &list->config, d, uvd, col); -} -NK_API void -nk_draw_list_add_image(struct nk_draw_list *list, struct nk_image texture, struct nk_rect rect, struct nk_color color) -{ - NK_ASSERT(list); - if (!list) { - return; - } - /* push new command with given texture */ - nk_draw_list_push_image(list, texture.handle); - if (nk_image_is_subimage(&texture)) { - /* add region inside of the texture */ - struct nk_vec2 uv[2]; - uv[0].x = (float)texture.region[0] / (float)texture.w; - uv[0].y = (float)texture.region[1] / (float)texture.h; - uv[1].x = (float)(texture.region[0] + texture.region[2]) / (float)texture.w; - uv[1].y = (float)(texture.region[1] + texture.region[3]) / (float)texture.h; - nk_draw_list_push_rect_uv(list, nk_vec2(rect.x, rect.y), nk_vec2(rect.x + rect.w, rect.y + rect.h), uv[0], uv[1], color); - } else { - nk_draw_list_push_rect_uv(list, nk_vec2(rect.x, rect.y), nk_vec2(rect.x + rect.w, rect.y + rect.h), nk_vec2(0.0f, 0.0f), nk_vec2(1.0f, 1.0f), color); - } -} - -struct nk_text_vertex_writer { - nk_size pos_offset; - nk_size uv_offset; - nk_size color_offset; - nk_bool direct; -}; - -NK_INTERN struct nk_text_vertex_writer -nk_text_vertex_writer_make(const struct nk_convert_config *config) -{ - nk_bool has_pos = nk_false; - nk_bool has_uv = nk_false; - nk_bool has_color = nk_false; - - struct nk_text_vertex_writer writer; - const struct nk_draw_vertex_layout_element *element = NULL; - - NK_MEMSET(&writer, 0, sizeof(writer)); - - for (element = config->vertex_layout; !nk_draw_vertex_layout_element_is_end_of_layout(element); ++element) { - if (element->attribute == NK_VERTEX_POSITION && element->format == NK_FORMAT_FLOAT) { - writer.pos_offset = element->offset; - has_pos = nk_true; - } else if (element->attribute == NK_VERTEX_TEXCOORD && element->format == NK_FORMAT_FLOAT) { - writer.uv_offset = element->offset; - has_uv = nk_true; - } else if (element->attribute == NK_VERTEX_COLOR && element->format == NK_FORMAT_R8G8B8A8) { - writer.color_offset = element->offset; - has_color = nk_true; - } - } - - writer.direct = has_pos && has_uv && has_color; - return writer; -} - -NK_INTERN void * -nk_text_vertex_write(void *vertices, const struct nk_convert_config *config, const struct nk_text_vertex_writer *writer, - struct nk_vec2 pos, struct nk_vec2 uv, struct nk_color color, struct nk_colorf colorf) -{ - if (!writer->direct) { - return nk_draw_vertex(vertices, config, pos, uv, colorf); - } - - NK_MEMCPY(nk_ptr_add(nk_byte, vertices, writer->pos_offset), &pos, sizeof(pos)); - NK_MEMCPY(nk_ptr_add(nk_byte, vertices, writer->uv_offset), &uv, sizeof(uv)); - NK_MEMCPY(nk_ptr_add(nk_byte, vertices, writer->color_offset), &color, sizeof(color)); - return nk_ptr_add(void, vertices, config->vertex_size); -} - -NK_INTERN void -nk_draw_list_add_text_geometry(struct nk_draw_list *list, const struct nk_text_geometry *geometry, struct nk_rect rect, struct nk_color fg) -{ - struct nk_text_vertex_writer writer = nk_text_vertex_writer_make(&list->config); - struct nk_colorf colorf; - int run_idx; - - if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h, list->clip_rect.x, list->clip_rect.y, list->clip_rect.w, list->clip_rect.h)) { - return; - } - - fg.a = (nk_byte)((float)fg.a * list->config.global_alpha); - nk_color_fv(&colorf.r, fg); - - for (run_idx = 0; run_idx < geometry->num_runs; ++run_idx) { - struct nk_text_geometry_run *run = &geometry->runs[run_idx]; - nk_draw_index *indices; - nk_draw_index index; - void *vertices; - int quad_idx; - - nk_draw_list_push_image(list, run->texture); - index = (nk_draw_index)list->vertex_count; - vertices = nk_draw_list_alloc_vertices(list, (nk_size)run->quad_count * 4); - indices = nk_draw_list_alloc_elements(list, (nk_size)run->quad_count * 6); - if (!vertices || !indices) { - return; - } - - for (quad_idx = run->quad_begin; quad_idx < run->quad_begin + run->quad_count; ++quad_idx) { - struct nk_text_geometry_quad *quad = &geometry->quads[quad_idx]; - - struct nk_vec2 a = nk_vec2(rect.x + quad->min.x, rect.y + quad->min.y); - struct nk_vec2 b = nk_vec2(rect.x + quad->max.x, rect.y + quad->min.y); - struct nk_vec2 c = nk_vec2(rect.x + quad->max.x, rect.y + quad->max.y); - struct nk_vec2 d = nk_vec2(rect.x + quad->min.x, rect.y + quad->max.y); - struct nk_vec2 uvb = nk_vec2(quad->uv_max.x, quad->uv_min.y); - struct nk_vec2 uvd = nk_vec2(quad->uv_min.x, quad->uv_max.y); - - indices[0] = (nk_draw_index)(index + 0); - indices[1] = (nk_draw_index)(index + 1); - indices[2] = (nk_draw_index)(index + 2); - indices[3] = (nk_draw_index)(index + 0); - indices[4] = (nk_draw_index)(index + 2); - indices[5] = (nk_draw_index)(index + 3); - - vertices = nk_text_vertex_write(vertices, &list->config, &writer, a, quad->uv_min, fg, colorf); - vertices = nk_text_vertex_write(vertices, &list->config, &writer, b, uvb, fg, colorf); - vertices = nk_text_vertex_write(vertices, &list->config, &writer, c, quad->uv_max, fg, colorf); - vertices = nk_text_vertex_write(vertices, &list->config, &writer, d, uvd, fg, colorf); - - indices += 6; - index += 4; - } - } -} - -NK_API void -nk_draw_list_add_text_shape(struct nk_draw_list *list, const struct nk_text_shape *shape, struct nk_rect rect, float font_height, struct nk_color fg) -{ - struct nk_colorf color; - struct nk_vec2 pen = nk_vec2(rect.x, rect.y); - int run_index; - - NK_ASSERT(list); - NK_ASSERT(shape); - if (!NK_INTERSECT(rect.x, rect.y, rect.w, rect.h, list->clip_rect.x, list->clip_rect.y, list->clip_rect.w, list->clip_rect.h)) { - return; - } - - fg.a = (nk_byte)((float)fg.a * list->config.global_alpha); - nk_color_fv(&color.r, fg); - for (run_index = 0; run_index < shape->num_runs; ++run_index) { - struct nk_text_run *run = &shape->runs[run_index]; - nk_draw_index index; - nk_draw_index *indices; - void *vertices; - int glyph_idx; - - nk_draw_list_push_image(list, run->font->texture); - index = (nk_draw_index)list->vertex_count; - vertices = nk_draw_list_alloc_vertices(list, (nk_size)run->glyph_count * 4); - indices = nk_draw_list_alloc_elements(list, (nk_size)run->glyph_count * 6); - if (!vertices || !indices) { - return; - } - - for (glyph_idx = run->glyph_begin; glyph_idx < run->glyph_begin + run->glyph_count; ++glyph_idx) { - struct nk_text_glyph *glyph = &shape->glyphs[glyph_idx]; - - struct nk_user_font_glyph g; - struct nk_vec2 a; - struct nk_vec2 b; - struct nk_vec2 c; - struct nk_vec2 d; - struct nk_vec2 uvb; - struct nk_vec2 uvd; - float x; - float y; - - NK_PROFILE_SCOPE_BEGIN("text.glyph_query", glyph_query); - { - run->font->query_glyph(run->font->userdata, font_height, &g, glyph->id); - } - NK_PROFILE_SCOPE_END(glyph_query); - - x = pen.x + glyph->offset_x + g.offset.x; - y = pen.y + shape->baseline + glyph->offset_y + g.offset.y; - - a = nk_vec2(x, y); - b = nk_vec2(x + g.width, y); - c = nk_vec2(x + g.width, y + g.height); - d = nk_vec2(x, y + g.height); - uvb = nk_vec2(g.uv[1].x, g.uv[0].y); - uvd = nk_vec2(g.uv[0].x, g.uv[1].y); - - indices[0] = (nk_draw_index)(index + 0); - indices[1] = (nk_draw_index)(index + 1); - indices[2] = (nk_draw_index)(index + 2); - indices[3] = (nk_draw_index)(index + 0); - indices[4] = (nk_draw_index)(index + 2); - indices[5] = (nk_draw_index)(index + 3); - - vertices = nk_draw_vertex(vertices, &list->config, a, g.uv[0], color); - vertices = nk_draw_vertex(vertices, &list->config, b, uvb, color); - vertices = nk_draw_vertex(vertices, &list->config, c, g.uv[1], color); - vertices = nk_draw_vertex(vertices, &list->config, d, uvd, color); - - indices += 6; - index += 4; - - pen.x += glyph->advance_x; - pen.y += glyph->advance_y; - } - } -} -NK_API nk_flags -nk_convert(struct nk_context *ctx, struct nk_buffer *cmds, struct nk_buffer *vertices, struct nk_buffer *elements, const struct nk_convert_config *config) -{ - nk_flags res = NK_CONVERT_SUCCESS; - const struct nk_command *cmd; - NK_ASSERT(ctx); - NK_ASSERT(cmds); - NK_ASSERT(vertices); - NK_ASSERT(elements); - NK_ASSERT(config); - NK_ASSERT(config->vertex_layout); - NK_ASSERT(config->vertex_size); - if (!ctx || !cmds || !vertices || !elements || !config || !config->vertex_layout) { - return NK_CONVERT_INVALID_PARAM; - } - - nk_draw_list_setup(&ctx->draw_list, config, cmds, vertices, elements, config->line_AA, config->shape_AA); - nk_foreach(cmd, ctx) - { -# ifdef NK_INCLUDE_COMMAND_USERDATA - ctx->draw_list.userdata = cmd->userdata; -# endif - switch (cmd->type) { - case NK_COMMAND_NOP: - break; - case NK_COMMAND_SCISSOR: { - const struct nk_command_scissor *s = (const struct nk_command_scissor *)cmd; - nk_draw_list_add_clip(&ctx->draw_list, nk_rect(s->x, s->y, s->w, s->h)); - } break; - case NK_COMMAND_LINE: { - const struct nk_command_line *l = (const struct nk_command_line *)cmd; - nk_draw_list_stroke_line(&ctx->draw_list, nk_vec2(l->begin.x, l->begin.y), nk_vec2(l->end.x, l->end.y), l->color, l->line_thickness); - } break; - case NK_COMMAND_CURVE: { - const struct nk_command_curve *q = (const struct nk_command_curve *)cmd; - nk_draw_list_stroke_curve(&ctx->draw_list, - nk_vec2(q->begin.x, q->begin.y), - nk_vec2(q->ctrl[0].x, q->ctrl[0].y), - nk_vec2(q->ctrl[1].x, q->ctrl[1].y), - nk_vec2(q->end.x, q->end.y), - q->color, - config->curve_segment_count, - q->line_thickness); - } break; - case NK_COMMAND_RECT: { - const struct nk_command_rect *r = (const struct nk_command_rect *)cmd; - nk_draw_list_stroke_rect(&ctx->draw_list, nk_rect(r->x, r->y, r->w, r->h), r->color, (float)r->rounding, r->line_thickness); - } break; - case NK_COMMAND_RECT_FILLED: { - const struct nk_command_rect_filled *r = (const struct nk_command_rect_filled *)cmd; - nk_draw_list_fill_rect(&ctx->draw_list, nk_rect(r->x, r->y, r->w, r->h), r->color, (float)r->rounding); - } break; - case NK_COMMAND_RECT_MULTI_COLOR: { - const struct nk_command_rect_multi_color *r = (const struct nk_command_rect_multi_color *)cmd; - nk_draw_list_fill_rect_multi_color(&ctx->draw_list, nk_rect(r->x, r->y, r->w, r->h), r->left, r->top, r->right, r->bottom); - } break; - case NK_COMMAND_CIRCLE: { - const struct nk_command_circle *c = (const struct nk_command_circle *)cmd; - nk_draw_list_stroke_circle( - &ctx->draw_list, nk_vec2((float)c->x + (float)c->w / 2, (float)c->y + (float)c->h / 2), (float)c->w / 2, c->color, config->circle_segment_count, c->line_thickness); - } break; - case NK_COMMAND_CIRCLE_FILLED: { - const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd; - nk_draw_list_fill_circle(&ctx->draw_list, nk_vec2((float)c->x + (float)c->w / 2, (float)c->y + (float)c->h / 2), (float)c->w / 2, c->color, config->circle_segment_count); - } break; - case NK_COMMAND_ARC: { - const struct nk_command_arc *c = (const struct nk_command_arc *)cmd; - nk_draw_list_path_line_to(&ctx->draw_list, nk_vec2(c->cx, c->cy)); - nk_draw_list_path_arc_to(&ctx->draw_list, nk_vec2(c->cx, c->cy), c->r, c->a[0], c->a[1], config->arc_segment_count); - nk_draw_list_path_stroke(&ctx->draw_list, c->color, NK_STROKE_CLOSED, c->line_thickness); - } break; - case NK_COMMAND_ARC_FILLED: { - const struct nk_command_arc_filled *c = (const struct nk_command_arc_filled *)cmd; - nk_draw_list_path_line_to(&ctx->draw_list, nk_vec2(c->cx, c->cy)); - nk_draw_list_path_arc_to(&ctx->draw_list, nk_vec2(c->cx, c->cy), c->r, c->a[0], c->a[1], config->arc_segment_count); - nk_draw_list_path_fill(&ctx->draw_list, c->color); - } break; - case NK_COMMAND_TRIANGLE: { - const struct nk_command_triangle *t = (const struct nk_command_triangle *)cmd; - nk_draw_list_stroke_triangle(&ctx->draw_list, nk_vec2(t->a.x, t->a.y), nk_vec2(t->b.x, t->b.y), nk_vec2(t->c.x, t->c.y), t->color, t->line_thickness); - } break; - case NK_COMMAND_TRIANGLE_FILLED: { - const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled *)cmd; - nk_draw_list_fill_triangle(&ctx->draw_list, nk_vec2(t->a.x, t->a.y), nk_vec2(t->b.x, t->b.y), nk_vec2(t->c.x, t->c.y), t->color); - } break; - case NK_COMMAND_POLYGON: { - int i; - const struct nk_command_polygon *p = (const struct nk_command_polygon *)cmd; - for (i = 0; i < p->point_count; ++i) { - struct nk_vec2 pnt = nk_vec2((float)p->points[i].x, (float)p->points[i].y); - nk_draw_list_path_line_to(&ctx->draw_list, pnt); - } - nk_draw_list_path_stroke(&ctx->draw_list, p->color, NK_STROKE_CLOSED, p->line_thickness); - } break; - case NK_COMMAND_POLYGON_FILLED: { - int i; - const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled *)cmd; - for (i = 0; i < p->point_count; ++i) { - struct nk_vec2 pnt = nk_vec2((float)p->points[i].x, (float)p->points[i].y); - nk_draw_list_path_line_to(&ctx->draw_list, pnt); - } - nk_draw_list_path_fill(&ctx->draw_list, p->color); - } break; - case NK_COMMAND_POLYLINE: { - int i; - const struct nk_command_polyline *p = (const struct nk_command_polyline *)cmd; - for (i = 0; i < p->point_count; ++i) { - struct nk_vec2 pnt = nk_vec2((float)p->points[i].x, (float)p->points[i].y); - nk_draw_list_path_line_to(&ctx->draw_list, pnt); - } - nk_draw_list_path_stroke(&ctx->draw_list, p->color, NK_STROKE_OPEN, p->line_thickness); - } break; - case NK_COMMAND_TEXT: { - const struct nk_command_text *t = (const struct nk_command_text *)cmd; - struct nk_text_request request = {0}; - struct nk_text_cache_entry *entry; - struct nk_text_geometry *geometry; - struct nk_text_shape *shape = NULL; - nk_hash hash; - - request.source = t->string; - request.source_len = t->length; - request.font = t->font; - request.font_height = t->height; - - NK_PROFILE_SCOPE_BEGIN("text.geometry_cache_lookup", geometry_cache_lookup); - { - hash = nk_text_request_hash(&request); - entry = nk_text_cache_find(ctx, &request, hash); - geometry = entry ? entry->geometry : NULL; - } - NK_PROFILE_SCOPE_END(geometry_cache_lookup); - - if (!geometry) { - NK_PROFILE_SCOPE_BEGIN("text.geometry_prepare", geometry_prepare); - { - shape = nk_text_shape_build(ctx, &request); - entry = nk_text_cache_find(ctx, &request, hash); - - if (shape && entry) { - NK_PROFILE_SCOPE_BEGIN("text.geometry_build", geometry_build); - { - geometry = nk_text_geometry_build(ctx, entry, shape, t->height); - } - NK_PROFILE_SCOPE_END(geometry_build); - } - } - NK_PROFILE_SCOPE_END(geometry_prepare); - } - - if (geometry) { - NK_PROFILE_SCOPE_BEGIN("text.geometry_cached", geometry_cached); - { - nk_draw_list_add_text_geometry(&ctx->draw_list, geometry, nk_rect(t->x, t->y, t->w, t->h), t->foreground); - } - NK_PROFILE_SCOPE_END(geometry_cached); - } else if (shape) { - NK_PROFILE_SCOPE_BEGIN("text.geometry_uncached", geometry_uncached); - { - nk_draw_list_add_text_shape(&ctx->draw_list, shape, nk_rect(t->x, t->y, t->w, t->h), t->height, t->foreground); - } - NK_PROFILE_SCOPE_END(geometry_uncached); - } - } break; - case NK_COMMAND_IMAGE: { - const struct nk_command_image *i = (const struct nk_command_image *)cmd; - nk_draw_list_add_image(&ctx->draw_list, i->img, nk_rect(i->x, i->y, i->w, i->h), i->col); - } break; - case NK_COMMAND_CUSTOM: { - const struct nk_command_custom *c = (const struct nk_command_custom *)cmd; - c->callback(&ctx->draw_list, c->x, c->y, c->w, c->h, c->callback_data); - } break; - default: - break; - } - } - res |= (cmds->needed > cmds->allocated + (cmds->memory.size - cmds->size)) ? NK_CONVERT_COMMAND_BUFFER_FULL : 0; - res |= (vertices->needed > vertices->allocated) ? NK_CONVERT_VERTEX_BUFFER_FULL : 0; - res |= (elements->needed > elements->allocated) ? NK_CONVERT_ELEMENT_BUFFER_FULL : 0; - return res; -} -NK_API const struct nk_draw_command * -nk__draw_begin(const struct nk_context *ctx, const struct nk_buffer *buffer) -{ - return nk__draw_list_begin(&ctx->draw_list, buffer); -} -NK_API const struct nk_draw_command * -nk__draw_end(const struct nk_context *ctx, const struct nk_buffer *buffer) -{ - return nk__draw_list_end(&ctx->draw_list, buffer); -} -NK_API const struct nk_draw_command * -nk__draw_next(const struct nk_draw_command *cmd, const struct nk_buffer *buffer, const struct nk_context *ctx) -{ - return nk__draw_list_next(cmd, buffer, &ctx->draw_list); -} -#endif - -/* stb_rect_pack.h - v1.01 - public domain - rectangle packing */ -/* Sean Barrett 2014 */ -/* */ -/* Useful for e.g. packing rectangular textures into an atlas. */ -/* Does not do rotation. */ -/* */ -/* Before #including, */ -/* */ -/* #define STB_RECT_PACK_IMPLEMENTATION */ -/* */ -/* in the file that you want to have the implementation. */ -/* */ -/* Not necessarily the awesomest packing method, but better than */ -/* the totally naive one in stb_truetype (which is primarily what */ -/* this is meant to replace). */ -/* */ -/* Has only had a few tests run, may have issues. */ -/* */ -/* More docs to come. */ -/* */ -/* No memory allocations; uses qsort() and assert() from stdlib. */ -/* Can override those by defining STBRP_SORT and STBRP_ASSERT. */ -/* */ -/* This library currently uses the Skyline Bottom-Left algorithm. */ -/* */ -/* Please note: better rectangle packers are welcome! Please */ -/* implement them to the same API, but with a different init */ -/* function. */ -/* */ -/* Credits */ -/* */ -/* Library */ -/* Sean Barrett */ -/* Minor features */ -/* Martins Mozeiko */ -/* github:IntellectualKitty */ -/* */ -/* Bugfixes / warning fixes */ -/* Jeremy Jaussaud */ -/* Fabian Giesen */ -/* */ -/* Version history: */ -/* */ -/* 1.01 (2021-07-11) always use large rect mode, expose STBRP__MAXVAL in public section */ -/* 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles */ -/* 0.99 (2019-02-07) warning fixes */ -/* 0.11 (2017-03-03) return packing success/fail result */ -/* 0.10 (2016-10-25) remove cast-away-const to avoid warnings */ -/* 0.09 (2016-08-27) fix compiler warnings */ -/* 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0) */ -/* 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0) */ -/* 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort */ -/* 0.05: added STBRP_ASSERT to allow replacing assert */ -/* 0.04: fixed minor bug in STBRP_LARGE_RECTS support */ -/* 0.01: initial release */ -/* */ -/* LICENSE */ -/* */ -/* See end of file for license information. */ - -/* //////////////////////////////////////////////////////////////////////////// */ -/* */ -/* INCLUDE SECTION */ -/* */ - -#ifndef STB_INCLUDE_STB_RECT_PACK_H -# define STB_INCLUDE_STB_RECT_PACK_H - -# define STB_RECT_PACK_VERSION 1 - -# ifdef STBRP_STATIC -# define STBRP_DEF static -# else -# define STBRP_DEF extern -# endif - -# ifdef __cplusplus -extern "C" { -# endif - -typedef struct stbrp_context stbrp_context; -typedef struct stbrp_node stbrp_node; -typedef struct stbrp_rect stbrp_rect; - -typedef int stbrp_coord; - -# define STBRP__MAXVAL 0x7fffffff -/* Mostly for internal use, but this is the maximum supported coordinate value. */ - -STBRP_DEF int -stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects); -/* Assign packed locations to rectangles. The rectangles are of type */ -/* 'stbrp_rect' defined below, stored in the array 'rects', and there */ -/* are 'num_rects' many of them. */ -/* */ -/* Rectangles which are successfully packed have the 'was_packed' flag */ -/* set to a non-zero value and 'x' and 'y' store the minimum location */ -/* on each axis (i.e. bottom-left in cartesian coordinates, top-left */ -/* if you imagine y increasing downwards). Rectangles which do not fit */ -/* have the 'was_packed' flag set to 0. */ -/* */ -/* You should not try to access the 'rects' array from another thread */ -/* while this function is running, as the function temporarily reorders */ -/* the array while it executes. */ -/* */ -/* To pack into another rectangle, you need to call stbrp_init_target */ -/* again. To continue packing into the same rectangle, you can call */ -/* this function again. Calling this multiple times with multiple rect */ -/* arrays will probably produce worse packing results than calling it */ -/* a single time with the full rectangle array, but the option is */ -/* available. */ -/* */ -/* The function returns 1 if all of the rectangles were successfully */ -/* packed and 0 otherwise. */ - -struct stbrp_rect { - /* reserved for your use: */ - int id; - - /* input: */ - stbrp_coord w, h; - - /* output: */ - stbrp_coord x, y; - int was_packed; /* non-zero if valid packing */ - -}; /* 16 bytes, nominally */ - -STBRP_DEF void -stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes); -/* Initialize a rectangle packer to: */ -/* pack a rectangle that is 'width' by 'height' in dimensions */ -/* using temporary storage provided by the array 'nodes', which is 'num_nodes' long */ -/* */ -/* You must call this function every time you start packing into a new target. */ -/* */ -/* There is no "shutdown" function. The 'nodes' memory must stay valid for */ -/* the following stbrp_pack_rects() call (or calls), but can be freed after */ -/* the call (or calls) finish. */ -/* */ -/* Note: to guarantee best results, either: */ -/* 1. make sure 'num_nodes' >= 'width' */ -/* or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1' */ -/* */ -/* If you don't do either of the above things, widths will be quantized to multiples */ -/* of small integers to guarantee the algorithm doesn't run out of temporary storage. */ -/* */ -/* If you do #2, then the non-quantized algorithm will be used, but the algorithm */ -/* may run out of temporary storage and be unable to pack some rectangles. */ - -STBRP_DEF void -stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem); -/* Optionally call this function after init but before doing any packing to */ -/* change the handling of the out-of-temp-memory scenario, described above. */ -/* If you call init again, this will be reset to the default (false). */ - -STBRP_DEF void -stbrp_setup_heuristic(stbrp_context *context, int heuristic); -/* Optionally select which packing heuristic the library should use. Different */ -/* heuristics will produce better/worse results for different data sets. */ -/* If you call init again, this will be reset to the default. */ - -enum { STBRP_HEURISTIC_Skyline_default = 0, STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default, STBRP_HEURISTIC_Skyline_BF_sortHeight }; - -/* //////////////////////////////////////////////////////////////////////////// */ -/* */ -/* the details of the following structures don't matter to you, but they must */ -/* be visible so you can handle the memory allocations for them */ - -struct stbrp_node { - stbrp_coord x, y; - stbrp_node *next; -}; - -struct stbrp_context { - int width; - int height; - int align; - int init_mode; - int heuristic; - int num_nodes; - stbrp_node *active_head; - stbrp_node *free_head; - stbrp_node extra[2]; /* we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2' */ -}; - -# ifdef __cplusplus -} -# endif - -#endif - -/* //////////////////////////////////////////////////////////////////////////// */ -/* */ -/* IMPLEMENTATION SECTION */ -/* */ - -#ifdef STB_RECT_PACK_IMPLEMENTATION -# ifndef STBRP_SORT -# include -# define STBRP_SORT qsort -# endif - -# ifndef STBRP_ASSERT -# include -# define STBRP_ASSERT assert -# endif - -# ifdef _MSC_VER -# define STBRP__NOTUSED(v) (void)(v) -# define STBRP__CDECL __cdecl -# else -# define STBRP__NOTUSED(v) (void)sizeof(v) -# define STBRP__CDECL -# endif - -enum { STBRP__INIT_skyline = 1 }; - -STBRP_DEF void -stbrp_setup_heuristic(stbrp_context *context, int heuristic) -{ - switch (context->init_mode) { - case STBRP__INIT_skyline: - STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight); - context->heuristic = heuristic; - break; - default: - STBRP_ASSERT(0); - } -} - -STBRP_DEF void -stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem) -{ - if (allow_out_of_mem) { - /* if it's ok to run out of memory, then don't bother aligning them; */ - /* this gives better packing, but may fail due to OOM (even though */ - /* the rectangles easily fit). @TODO a smarter approach would be to only */ - /* quantize once we've hit OOM, then we could get rid of this parameter. */ - context->align = 1; - } else { - /* if it's not ok to run out of memory, then quantize the widths */ - /* so that num_nodes is always enough nodes. */ - /* */ - /* I.e. num_nodes * align >= width */ - /* align >= width / num_nodes */ - /* align = ceil(width/num_nodes) */ - - context->align = (context->width + context->num_nodes - 1) / context->num_nodes; - } -} - -STBRP_DEF void -stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes) -{ - int i; - - for (i = 0; i < num_nodes - 1; ++i) { - nodes[i].next = &nodes[i + 1]; - } - nodes[i].next = NULL; - context->init_mode = STBRP__INIT_skyline; - context->heuristic = STBRP_HEURISTIC_Skyline_default; - context->free_head = &nodes[0]; - context->active_head = &context->extra[0]; - context->width = width; - context->height = height; - context->num_nodes = num_nodes; - stbrp_setup_allow_out_of_mem(context, 0); - - /* node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly) */ - context->extra[0].x = 0; - context->extra[0].y = 0; - context->extra[0].next = &context->extra[1]; - context->extra[1].x = (stbrp_coord)width; - context->extra[1].y = (1 << 30); - context->extra[1].next = NULL; -} - -/* find minimum y position if it starts at x1 */ -static int -stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste) -{ - stbrp_node *node = first; - int x1 = x0 + width; - int min_y, visited_width, waste_area; - - (void)(c); - - STBRP_ASSERT(first->x <= x0); - -# if 0 - /* skip in case we're past the node */ - while (node->next->x <= x0) - ++node; -# else - STBRP_ASSERT(node->next->x > x0); /* we ended up handling this in the caller for efficiency */ -# endif - - STBRP_ASSERT(node->x <= x0); - - min_y = 0; - waste_area = 0; - visited_width = 0; - while (node->x < x1) { - if (node->y > min_y) { - /* raise min_y higher. */ - /* we've accounted for all waste up to min_y, */ - /* but we'll now add more waste for everything we've visited */ - waste_area += visited_width * (node->y - min_y); - min_y = node->y; - /* the first time through, visited_width might be reduced */ - if (node->x < x0) { - visited_width += node->next->x - x0; - } else { - visited_width += node->next->x - node->x; - } - } else { - /* add waste area */ - int under_width = node->next->x - node->x; - if (under_width + visited_width > width) { - under_width = width - visited_width; - } - waste_area += under_width * (min_y - node->y); - visited_width += under_width; - } - node = node->next; - } - - *pwaste = waste_area; - return min_y; -} - -typedef struct { - int x, y; - stbrp_node **prev_link; -} stbrp__findresult; - -static stbrp__findresult -stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height) -{ - int best_waste = (1 << 30), best_x, best_y = (1 << 30); - stbrp__findresult fr; - stbrp_node **prev, *node, *tail, **best = NULL; - - /* align to multiple of c->align */ - width = (width + c->align - 1); - width -= width % c->align; - STBRP_ASSERT(width % c->align == 0); - - /* if it can't possibly fit, bail immediately */ - if (width > c->width || height > c->height) { - fr.prev_link = NULL; - fr.x = fr.y = 0; - return fr; - } - - node = c->active_head; - prev = &c->active_head; - while (node->x + width <= c->width) { - int y, waste; - y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste); - if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { /* actually just want to test BL */ - /* bottom left */ - if (y < best_y) { - best_y = y; - best = prev; - } - } else { - /* best-fit */ - if (y + height <= c->height) { - /* can only use it if it first vertically */ - if (y < best_y || (y == best_y && waste < best_waste)) { - best_y = y; - best_waste = waste; - best = prev; - } - } - } - prev = &node->next; - node = node->next; - } - - best_x = (best == NULL) ? 0 : (*best)->x; - - /* if doing best-fit (BF), we also have to try aligning right edge to each node position */ - /* */ - /* e.g, if fitting */ - /* */ - /* ____________________ */ - /* |____________________| */ - /* */ - /* into */ - /* */ - /* | | */ - /* | ____________| */ - /* |____________| */ - /* */ - /* then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned */ - /* */ - /* This makes BF take about 2x the time */ - - if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) { - tail = c->active_head; - node = c->active_head; - prev = &c->active_head; - /* find first node that's admissible */ - while (tail->x < width) { - tail = tail->next; - } - while (tail) { - int xpos = tail->x - width; - int y, waste; - STBRP_ASSERT(xpos >= 0); - /* find the left position that matches this */ - while (node->next->x <= xpos) { - prev = &node->next; - node = node->next; - } - STBRP_ASSERT(node->next->x > xpos && node->x <= xpos); - y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste); - if (y + height <= c->height) { - if (y <= best_y) { - if (y < best_y || waste < best_waste || (waste == best_waste && xpos < best_x)) { - best_x = xpos; - STBRP_ASSERT(y <= best_y); - best_y = y; - best_waste = waste; - best = prev; - } - } - } - tail = tail->next; - } - } - - fr.prev_link = best; - fr.x = best_x; - fr.y = best_y; - return fr; -} - -static stbrp__findresult -stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height) -{ - /* find best position according to heuristic */ - stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height); - stbrp_node *node, *cur; - - /* bail if: */ - /* 1. it failed */ - /* 2. the best node doesn't fit (we don't always check this) */ - /* 3. we're out of memory */ - if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) { - res.prev_link = NULL; - return res; - } - - /* on success, create new node */ - node = context->free_head; - node->x = (stbrp_coord)res.x; - node->y = (stbrp_coord)(res.y + height); - - context->free_head = node->next; - - /* insert the new node into the right starting point, and */ - /* let 'cur' point to the remaining nodes needing to be */ - /* stitched back in */ - - cur = *res.prev_link; - if (cur->x < res.x) { - /* preserve the existing one, so start testing with the next one */ - stbrp_node *next = cur->next; - cur->next = node; - cur = next; - } else { - *res.prev_link = node; - } - - /* from here, traverse cur and free the nodes, until we get to one */ - /* that shouldn't be freed */ - while (cur->next && cur->next->x <= res.x + width) { - stbrp_node *next = cur->next; - /* move the current node to the free list */ - cur->next = context->free_head; - context->free_head = cur; - cur = next; - } - - /* stitch the list back in */ - node->next = cur; - - if (cur->x < res.x + width) { - cur->x = (stbrp_coord)(res.x + width); - } - -# ifdef _DEBUG - cur = context->active_head; - while (cur->x < context->width) { - STBRP_ASSERT(cur->x < cur->next->x); - cur = cur->next; - } - STBRP_ASSERT(cur->next == NULL); - - { - int count = 0; - cur = context->active_head; - while (cur) { - cur = cur->next; - ++count; - } - cur = context->free_head; - while (cur) { - cur = cur->next; - ++count; - } - STBRP_ASSERT(count == context->num_nodes + 2); - } -# endif - - return res; -} - -static int STBRP__CDECL -rect_height_compare(const void *a, const void *b) -{ - const stbrp_rect *p = (const stbrp_rect *)a; - const stbrp_rect *q = (const stbrp_rect *)b; - if (p->h > q->h) { - return -1; - } - if (p->h < q->h) { - return 1; - } - return (p->w > q->w) ? -1 : (p->w < q->w); -} - -static int STBRP__CDECL -rect_original_order(const void *a, const void *b) -{ - const stbrp_rect *p = (const stbrp_rect *)a; - const stbrp_rect *q = (const stbrp_rect *)b; - return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed); -} - -STBRP_DEF int -stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects) -{ - int i, all_rects_packed = 1; - - /* we use the 'was_packed' field internally to allow sorting/unsorting */ - for (i = 0; i < num_rects; ++i) { - rects[i].was_packed = i; - } - - /* sort according to heuristic */ - STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare); - - for (i = 0; i < num_rects; ++i) { - if (rects[i].w == 0 || rects[i].h == 0) { - rects[i].x = rects[i].y = 0; /* empty rect needs no space */ - } else { - stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h); - if (fr.prev_link) { - rects[i].x = (stbrp_coord)fr.x; - rects[i].y = (stbrp_coord)fr.y; - } else { - rects[i].x = rects[i].y = STBRP__MAXVAL; - } - } - } - - /* unsort */ - STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order); - - /* set was_packed flags and all_rects_packed status */ - for (i = 0; i < num_rects; ++i) { - rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL); - if (!rects[i].was_packed) { - all_rects_packed = 0; - } - } - - /* return the all_rects_packed status */ - return all_rects_packed; -} -#endif - -/* ------------------------------------------------------------------------------- -This software is available under 2 licenses -- choose whichever you prefer. ------------------------------------------------------------------------------- -ALTERNATIVE A - MIT License -Copyright (c) 2017 Sean Barrett -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. ------------------------------------------------------------------------------- -ALTERNATIVE B - Public Domain (www.unlicense.org) -This is free and unencumbered software released into the public domain. -Anyone is free to copy, modify, publish, use, compile, sell, or distribute this -software, either in source code form or as a compiled binary, for any purpose, -commercial or non-commercial, and by any means. -In jurisdictions that recognize copyright laws, the author or authors of this -software dedicate any and all copyright interest in the software to the public -domain. We make this dedication for the benefit of the public at large and to -the detriment of our heirs and successors. We intend this dedication to be an -overt act of relinquishment in perpetuity of all present and future rights to -this software under copyright law. -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 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. ------------------------------------------------------------------------------- -*/ - -/* stb_truetype.h - v1.26 - public domain */ -/* authored from 2009-2021 by Sean Barrett / RAD Game Tools */ -/* */ -/* ======================================================================= */ -/* */ -/* NO SECURITY GUARANTEE -- DO NOT USE THIS ON UNTRUSTED FONT FILES */ -/* */ -/* This library does no range checking of the offsets found in the file, */ -/* meaning an attacker can use it to read arbitrary memory. */ -/* */ -/* ======================================================================= */ -/* */ -/* This library processes TrueType files: */ -/* parse files */ -/* extract glyph metrics */ -/* extract glyph shapes */ -/* render glyphs to one-channel bitmaps with antialiasing (box filter) */ -/* render glyphs to one-channel SDF bitmaps (signed-distance field/function) */ -/* */ -/* Todo: */ -/* non-MS cmaps */ -/* crashproof on bad data */ -/* hinting? (no longer patented) */ -/* cleartype-style AA? */ -/* optimize: use simple memory allocator for intermediates */ -/* optimize: build edge-list directly from curves */ -/* optimize: rasterize directly from curves? */ -/* */ -/* ADDITIONAL CONTRIBUTORS */ -/* */ -/* Mikko Mononen: compound shape support, more cmap formats */ -/* Tor Andersson: kerning, subpixel rendering */ -/* Dougall Johnson: OpenType / Type 2 font handling */ -/* Daniel Ribeiro Maciel: basic GPOS-based kerning */ -/* */ -/* Misc other: */ -/* Ryan Gordon */ -/* Simon Glass */ -/* github:IntellectualKitty */ -/* Imanol Celaya */ -/* Daniel Ribeiro Maciel */ -/* */ -/* Bug/warning reports/fixes: */ -/* "Zer" on mollyrocket Fabian "ryg" Giesen github:NiLuJe */ -/* Cass Everitt Martins Mozeiko github:aloucks */ -/* stoiko (Haemimont Games) Cap Petschulat github:oyvindjam */ -/* Brian Hook Omar Cornut github:vassvik */ -/* Walter van Niftrik Ryan Griege */ -/* David Gow Peter LaValle */ -/* David Given Sergey Popov */ -/* Ivan-Assen Ivanov Giumo X. Clanjor */ -/* Anthony Pesch Higor Euripedes */ -/* Johan Duparc Thomas Fields */ -/* Hou Qiming Derek Vinyard */ -/* Rob Loach Cort Stratton */ -/* Kenney Phillis Jr. Brian Costabile */ -/* Ken Voskuil (kaesve) */ -/* */ -/* VERSION HISTORY */ -/* */ -/* 1.26 (2021-08-28) fix broken rasterizer */ -/* 1.25 (2021-07-11) many fixes */ -/* 1.24 (2020-02-05) fix warning */ -/* 1.23 (2020-02-02) query SVG data for glyphs; query whole kerning table (but only kern not GPOS) */ -/* 1.22 (2019-08-11) minimize missing-glyph duplication; fix kerning if both 'GPOS' and 'kern' are defined */ -/* 1.21 (2019-02-25) fix warning */ -/* 1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics() */ -/* 1.19 (2018-02-11) GPOS kerning, STBTT_fmod */ -/* 1.18 (2018-01-29) add missing function */ -/* 1.17 (2017-07-23) make more arguments const; doc fix */ -/* 1.16 (2017-07-12) SDF support */ -/* 1.15 (2017-03-03) make more arguments const */ -/* 1.14 (2017-01-16) num-fonts-in-TTC function */ -/* 1.13 (2017-01-02) support OpenType fonts, certain Apple fonts */ -/* 1.12 (2016-10-25) suppress warnings about casting away const with -Wcast-qual */ -/* 1.11 (2016-04-02) fix unused-variable warning */ -/* 1.10 (2016-04-02) user-defined fabs(); rare memory leak; remove duplicate typedef */ -/* 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use allocation userdata properly */ -/* 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges */ -/* 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints; */ -/* variant PackFontRanges to pack and render in separate phases; */ -/* fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?); */ -/* fixed an assert() bug in the new rasterizer */ -/* replace assert() with STBTT_assert() in new rasterizer */ -/* */ -/* Full history can be found at the end of this file. */ -/* */ -/* LICENSE */ -/* */ -/* See end of file for license information. */ -/* */ -/* USAGE */ -/* */ -/* Include this file in whatever places need to refer to it. In ONE C/C++ */ -/* file, write: */ -/* #define STB_TRUETYPE_IMPLEMENTATION */ -/* before the #include of this file. This expands out the actual */ -/* implementation into that C/C++ file. */ -/* */ -/* To make the implementation private to the file that generates the implementation, */ -/* #define STBTT_STATIC */ -/* */ -/* Simple 3D API (don't ship this, but it's fine for tools and quick start) */ -/* stbtt_BakeFontBitmap() -- bake a font to a bitmap for use as texture */ -/* stbtt_GetBakedQuad() -- compute quad to draw for a given char */ -/* */ -/* Improved 3D API (more shippable): */ -/* #include "stb_rect_pack.h" -- optional, but you really want it */ -/* stbtt_PackBegin() */ -/* stbtt_PackSetOversampling() -- for improved quality on small fonts */ -/* stbtt_PackFontRanges() -- pack and renders */ -/* stbtt_PackEnd() */ -/* stbtt_GetPackedQuad() */ -/* */ -/* "Load" a font file from a memory buffer (you have to keep the buffer loaded) */ -/* stbtt_InitFont() */ -/* stbtt_GetFontOffsetForIndex() -- indexing for TTC font collections */ -/* stbtt_GetNumberOfFonts() -- number of fonts for TTC font collections */ -/* */ -/* Render a unicode codepoint to a bitmap */ -/* stbtt_GetCodepointBitmap() -- allocates and returns a bitmap */ -/* stbtt_MakeCodepointBitmap() -- renders into bitmap you provide */ -/* stbtt_GetCodepointBitmapBox() -- how big the bitmap must be */ -/* */ -/* Character advance/positioning */ -/* stbtt_GetCodepointHMetrics() */ -/* stbtt_GetFontVMetrics() */ -/* stbtt_GetFontVMetricsOS2() */ -/* stbtt_GetCodepointKernAdvance() */ -/* */ -/* Starting with version 1.06, the rasterizer was replaced with a new, */ -/* faster and generally-more-precise rasterizer. The new rasterizer more */ -/* accurately measures pixel coverage for anti-aliasing, except in the case */ -/* where multiple shapes overlap, in which case it overestimates the AA pixel */ -/* coverage. Thus, anti-aliasing of intersecting shapes may look wrong. If */ -/* this turns out to be a problem, you can re-enable the old rasterizer with */ -/* #define STBTT_RASTERIZER_VERSION 1 */ -/* which will incur about a 15% speed hit. */ -/* */ -/* ADDITIONAL DOCUMENTATION */ -/* */ -/* Immediately after this block comment are a series of sample programs. */ -/* */ -/* After the sample programs is the "header file" section. This section */ -/* includes documentation for each API function. */ -/* */ -/* Some important concepts to understand to use this library: */ -/* */ -/* Codepoint */ -/* Characters are defined by unicode codepoints, e.g. 65 is */ -/* uppercase A, 231 is lowercase c with a cedilla, 0x7e30 is */ -/* the hiragana for "ma". */ -/* */ -/* Glyph */ -/* A visual character shape (every codepoint is rendered as */ -/* some glyph) */ -/* */ -/* Glyph index */ -/* A font-specific integer ID representing a glyph */ -/* */ -/* Baseline */ -/* Glyph shapes are defined relative to a baseline, which is the */ -/* bottom of uppercase characters. Characters extend both above */ -/* and below the baseline. */ -/* */ -/* Current Point */ -/* As you draw text to the screen, you keep track of a "current point" */ -/* which is the origin of each character. The current point's vertical */ -/* position is the baseline. Even "baked fonts" use this model. */ -/* */ -/* Vertical Font Metrics */ -/* The vertical qualities of the font, used to vertically position */ -/* and space the characters. See docs for stbtt_GetFontVMetrics. */ -/* */ -/* Font Size in Pixels or Points */ -/* The preferred interface for specifying font sizes in stb_truetype */ -/* is to specify how tall the font's vertical extent should be in pixels. */ -/* If that sounds good enough, skip the next paragraph. */ -/* */ -/* Most font APIs instead use "points", which are a common typographic */ -/* measurement for describing font size, defined as 72 points per inch. */ -/* stb_truetype provides a point API for compatibility. However, true */ -/* "per inch" conventions don't make much sense on computer displays */ -/* since different monitors have different number of pixels per */ -/* inch. For example, Windows traditionally uses a convention that */ -/* there are 96 pixels per inch, thus making 'inch' measurements have */ -/* nothing to do with inches, and thus effectively defining a point to */ -/* be 1.333 pixels. Additionally, the TrueType font data provides */ -/* an explicit scale factor to scale a given font's glyphs to points, */ -/* but the author has observed that this scale factor is often wrong */ -/* for non-commercial fonts, thus making fonts scaled in points */ -/* according to the TrueType spec incoherently sized in practice. */ -/* */ -/* DETAILED USAGE: */ -/* */ -/* Scale: */ -/* Select how high you want the font to be, in points or pixels. */ -/* Call ScaleForPixelHeight or ScaleForMappingEmToPixels to compute */ -/* a scale factor SF that will be used by all other functions. */ -/* */ -/* Baseline: */ -/* You need to select a y-coordinate that is the baseline of where */ -/* your text will appear. Call GetFontBoundingBox to get the baseline-relative */ -/* bounding box for all characters. SF*-y0 will be the distance in pixels */ -/* that the worst-case character could extend above the baseline, so if */ -/* you want the top edge of characters to appear at the top of the */ -/* screen where y=0, then you would set the baseline to SF*-y0. */ -/* */ -/* Current point: */ -/* Set the current point where the first character will appear. The */ -/* first character could extend left of the current point; this is font */ -/* dependent. You can either choose a current point that is the leftmost */ -/* point and hope, or add some padding, or check the bounding box or */ -/* left-side-bearing of the first character to be displayed and set */ -/* the current point based on that. */ -/* */ -/* Displaying a character: */ -/* Compute the bounding box of the character. It will contain signed values */ -/* relative to . I.e. if it returns x0,y0,x1,y1, */ -/* then the character should be displayed in the rectangle from */ -/* to = 32 && *text < 128) { - stbtt_aligned_quad q; - stbtt_GetBakedQuad(cdata, 512,512, *text-32, &x,&y,&q,1);/* 1=opengl & d3d10+,0=d3d9 */ - glTexCoord2f(q.s0,q.t0); glVertex2f(q.x0,q.y0); - glTexCoord2f(q.s1,q.t0); glVertex2f(q.x1,q.y0); - glTexCoord2f(q.s1,q.t1); glVertex2f(q.x1,q.y1); - glTexCoord2f(q.s0,q.t1); glVertex2f(q.x0,q.y1); - } - ++text; - } - glEnd(); -} -#endif -/* */ -/* */ -/* //////////////////////////////////////////////////////////////////////////// */ -/* */ -/* Complete program (this compiles): get a single bitmap, print as ASCII art */ -/* */ -#if 0 -# include -# define STB_TRUETYPE_IMPLEMENTATION /* force following include to generate implementation */ -# include "stb_truetype.h" - -char ttf_buffer[1<<25]; - -int main(int argc, char **argv) -{ - stbtt_fontinfo font; - unsigned char *bitmap; - int w,h,i,j,c = (argc > 1 ? atoi(argv[1]) : 'a'), s = (argc > 2 ? atoi(argv[2]) : 20); - - fread(ttf_buffer, 1, 1<<25, fopen(argc > 3 ? argv[3] : "c:/windows/fonts/arialbd.ttf", "rb")); - - stbtt_InitFont(&font, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0)); - bitmap = stbtt_GetCodepointBitmap(&font, 0,stbtt_ScaleForPixelHeight(&font, s), c, &w, &h, 0,0); - - for (j=0; j < h; ++j) { - for (i=0; i < w; ++i) - putchar(" .:ioVM@"[bitmap[j*w+i]>>5]); - putchar('\n'); - } - return 0; -} -#endif -/* */ -/* Output: */ -/* */ -/* .ii. */ -/* @@@@@@. */ -/* V@Mio@@o */ -/* :i. V@V */ -/* :oM@@M */ -/* :@@@MM@M */ -/* @@o o@M */ -/* :@@. M@M */ -/* @@@o@@@@ */ -/* :M@@V:@@. */ -/* */ -/* //////////////////////////////////////////////////////////////////////////// */ -/* */ -/* Complete program: print "Hello World!" banner, with bugs */ -/* */ -#if 0 -char buffer[24<<20]; -unsigned char screen[20][79]; - -int main(int arg, char **argv) -{ - stbtt_fontinfo font; - int i,j,ascent,baseline,ch=0; - float scale, xpos=2; /* leave a little padding in case the character extends left */ - char *text = "Heljo World!"; /* intentionally misspelled to show 'lj' brokenness */ - - fread(buffer, 1, 1000000, fopen("c:/windows/fonts/arialbd.ttf", "rb")); - stbtt_InitFont(&font, buffer, 0); - - scale = stbtt_ScaleForPixelHeight(&font, 15); - stbtt_GetFontVMetrics(&font, &ascent,0,0); - baseline = (int) (ascent*scale); - - while (text[ch]) { - int advance,lsb,x0,y0,x1,y1; - float x_shift = xpos - (float) floor(xpos); - stbtt_GetCodepointHMetrics(&font, text[ch], &advance, &lsb); - stbtt_GetCodepointBitmapBoxSubpixel(&font, text[ch], scale,scale,x_shift,0, &x0,&y0,&x1,&y1); - stbtt_MakeCodepointBitmapSubpixel(&font, &screen[baseline + y0][(int) xpos + x0], x1-x0,y1-y0, 79, scale,scale,x_shift,0, text[ch]); - /* note that this stomps the old data, so where character boxes overlap (e.g. 'lj') it's wrong */ - /* because this API is really for baking character bitmaps into textures. if you want to render */ - /* a sequence of characters, you really need to render each bitmap to a temp buffer, then */ - /* "alpha blend" that into the working buffer */ - xpos += (advance * scale); - if (text[ch+1]) - xpos += scale*stbtt_GetCodepointKernAdvance(&font, text[ch],text[ch+1]); - ++ch; - } - - for (j=0; j < 20; ++j) { - for (i=0; i < 78; ++i) - putchar(" .:ioVM@"[screen[j][i]>>5]); - putchar('\n'); - } - - return 0; -} -#endif - -/* //////////////////////////////////////////////////////////////////////////// */ -/* //////////////////////////////////////////////////////////////////////////// */ -/* // */ -/* // INTEGRATION WITH YOUR CODEBASE */ -/* // */ -/* // The following sections allow you to supply alternate definitions */ -/* // of C library functions used by stb_truetype, e.g. if you don't */ -/* // link with the C runtime library. */ - -#ifdef STB_TRUETYPE_IMPLEMENTATION -/* #define your own (u)stbtt_int8/16/32 before including to override this */ -# ifndef stbtt_uint8 -typedef unsigned char stbtt_uint8; -typedef signed char stbtt_int8; -typedef unsigned short stbtt_uint16; -typedef signed short stbtt_int16; -typedef unsigned int stbtt_uint32; -typedef signed int stbtt_int32; -# endif - -typedef char stbtt__check_size32[sizeof(stbtt_int32) == 4 ? 1 : -1]; -typedef char stbtt__check_size16[sizeof(stbtt_int16) == 2 ? 1 : -1]; - -/* e.g. #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h */ -# ifndef STBTT_ifloor -# include -# define STBTT_ifloor(x) ((int)floor(x)) -# define STBTT_iceil(x) ((int)ceil(x)) -# endif - -# ifndef STBTT_sqrt -# include -# define STBTT_sqrt(x) sqrt(x) -# define STBTT_pow(x, y) pow(x, y) -# endif - -# ifndef STBTT_fmod -# include -# define STBTT_fmod(x, y) fmod(x, y) -# endif - -# ifndef STBTT_cos -# include -# define STBTT_cos(x) cos(x) -# define STBTT_acos(x) acos(x) -# endif - -# ifndef STBTT_fabs -# include -# define STBTT_fabs(x) fabs(x) -# endif - -/* #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h */ -# ifndef STBTT_malloc -# include -# define STBTT_malloc(x, u) ((void)(u), malloc(x)) -# define STBTT_free(x, u) ((void)(u), free(x)) -# endif - -# ifndef STBTT_assert -# include -# define STBTT_assert(x) assert(x) -# endif - -# ifndef STBTT_strlen -# include -# define STBTT_strlen(x) strlen(x) -# endif - -# ifndef STBTT_memcpy -# include -# define STBTT_memcpy memcpy -# define STBTT_memset memset -# endif -#endif - -/* ///////////////////////////////////////////////////////////////////////////// */ -/* ///////////////////////////////////////////////////////////////////////////// */ -/* // */ -/* // INTERFACE */ -/* // */ -/* // */ - -#ifndef __STB_INCLUDE_STB_TRUETYPE_H__ -# define __STB_INCLUDE_STB_TRUETYPE_H__ - -# ifdef STBTT_STATIC -# define STBTT_DEF static -# else -# define STBTT_DEF extern -# endif - -# ifdef __cplusplus -extern "C" { -# endif - -/* private structure */ -typedef struct { - unsigned char *data; - int cursor; - int size; -} stbtt__buf; - -/* //////////////////////////////////////////////////////////////////////////// */ -/* */ -/* TEXTURE BAKING API */ -/* */ -/* If you use this API, you only have to call two functions ever. */ -/* */ - -typedef struct { - unsigned short x0, y0, x1, y1; /* coordinates of bbox in bitmap */ - float xoff, yoff, xadvance; -} stbtt_bakedchar; - -STBTT_DEF int -stbtt_BakeFontBitmap(const unsigned char *data, - int offset, /* font location (use offset=0 for plain .ttf) */ - float pixel_height, /* height of font in pixels */ - unsigned char *pixels, - int pw, - int ph, /* bitmap to be filled in */ - int first_char, - int num_chars, /* characters to bake */ - stbtt_bakedchar *chardata); /* you allocate this, it's num_chars long */ -/* if return is positive, the first unused row of the bitmap */ -/* if return is negative, returns the negative of the number of characters that fit */ -/* if return is 0, no characters fit and no rows were used */ -/* This uses a very crappy packing. */ - -typedef struct { - float x0, y0, s0, t0; /* top-left */ - float x1, y1, s1, t1; /* bottom-right */ -} stbtt_aligned_quad; - -STBTT_DEF void -stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, - int pw, - int ph, /* same data as above */ - int char_index, /* character to display */ - float *xpos, - float *ypos, /* pointers to current position in screen pixel space */ - stbtt_aligned_quad *q, /* output: quad to draw */ - int opengl_fillrule); /* true if opengl fill rule; false if DX9 or earlier */ -/* Call GetBakedQuad with char_index = 'character - first_char', and it */ -/* creates the quad you need to draw and advances the current position. */ -/* */ -/* The coordinate system used assumes y increases downwards. */ -/* */ -/* Characters will extend both above and below the current position; */ -/* see discussion of "BASELINE" above. */ -/* */ -/* It's inefficient; you might want to c&p it and optimize it. */ - -STBTT_DEF void -stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap); -/* Query the font vertical metrics without having to create a font first. */ - -/* //////////////////////////////////////////////////////////////////////////// */ -/* */ -/* NEW TEXTURE BAKING API */ -/* */ -/* This provides options for packing multiple fonts into one atlas, not */ -/* perfectly but better than nothing. */ - -typedef struct { - unsigned short x0, y0, x1, y1; /* coordinates of bbox in bitmap */ - float xoff, yoff, xadvance; - float xoff2, yoff2; -} stbtt_packedchar; - -typedef struct stbtt_pack_context stbtt_pack_context; -typedef struct stbtt_fontinfo stbtt_fontinfo; -# ifndef STB_RECT_PACK_VERSION -typedef struct stbrp_rect stbrp_rect; -# endif - -STBTT_DEF int -stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context); -/* Initializes a packing context stored in the passed-in stbtt_pack_context. */ -/* Future calls using this context will pack characters into the bitmap passed */ -/* in here: a 1-channel bitmap that is width * height. stride_in_bytes is */ -/* the distance from one row to the next (or 0 to mean they are packed tightly */ -/* together). "padding" is the amount of padding to leave between each */ -/* character (normally you want '1' for bitmaps you'll use as textures with */ -/* bilinear filtering). */ -/* */ -/* Returns 0 on failure, 1 on success. */ - -STBTT_DEF void -stbtt_PackEnd(stbtt_pack_context *spc); -/* Cleans up the packing context and frees all memory. */ - -# define STBTT_POINT_SIZE(x) (-(x)) - -STBTT_DEF int -stbtt_PackFontRange(stbtt_pack_context *spc, - const unsigned char *fontdata, - int font_index, - float font_size, - int first_unicode_char_in_range, - int num_chars_in_range, - stbtt_packedchar *chardata_for_range); -/* Creates character bitmaps from the font_index'th font found in fontdata (use */ -/* font_index=0 if you don't know what that is). It creates num_chars_in_range */ -/* bitmaps for characters with unicode values starting at first_unicode_char_in_range */ -/* and increasing. Data for how to render them is stored in chardata_for_range; */ -/* pass these to stbtt_GetPackedQuad to get back renderable quads. */ -/* */ -/* font_size is the full height of the character from ascender to descender, */ -/* as computed by stbtt_ScaleForPixelHeight. To use a point size as computed */ -/* by stbtt_ScaleForMappingEmToPixels, wrap the point size in STBTT_POINT_SIZE() */ -/* and pass that result as 'font_size': */ -/* ..., 20 , ... // font max minus min y is 20 pixels tall */ -/* ..., STBTT_POINT_SIZE(20), ... // 'M' is 20 pixels tall */ - -typedef struct { - float font_size; - int first_unicode_codepoint_in_range; /* if non-zero, then the chars are continuous, and this is the first codepoint */ - int *array_of_unicode_codepoints; /* if non-zero, then this is an array of unicode codepoints */ - int num_chars; - stbtt_packedchar *chardata_for_range; /* output */ - unsigned char h_oversample, v_oversample; /* don't set these, they're used internally */ -} stbtt_pack_range; - -STBTT_DEF int -stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges); -/* Creates character bitmaps from multiple ranges of characters stored in */ -/* ranges. This will usually create a better-packed bitmap than multiple */ -/* calls to stbtt_PackFontRange. Note that you can call this multiple */ -/* times within a single PackBegin/PackEnd. */ - -STBTT_DEF void -stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample); -/* Oversampling a font increases the quality by allowing higher-quality subpixel */ -/* positioning, and is especially valuable at smaller text sizes. */ -/* */ -/* This function sets the amount of oversampling for all following calls to */ -/* stbtt_PackFontRange(s) or stbtt_PackFontRangesGatherRects for a given */ -/* pack context. The default (no oversampling) is achieved by h_oversample=1 */ -/* and v_oversample=1. The total number of pixels required is */ -/* h_oversample*v_oversample larger than the default; for example, 2x2 */ -/* oversampling requires 4x the storage of 1x1. For best results, render */ -/* oversampled textures with bilinear filtering. Look at the readme in */ -/* stb/tests/oversample for information about oversampled fonts */ -/* */ -/* To use with PackFontRangesGather etc., you must set it before calls */ -/* call to PackFontRangesGatherRects. */ - -STBTT_DEF void -stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip); -/* If skip != 0, this tells stb_truetype to skip any codepoints for which */ -/* there is no corresponding glyph. If skip=0, which is the default, then */ -/* codepoints without a glyph recived the font's "missing character" glyph, */ -/* typically an empty box by convention. */ - -STBTT_DEF void -stbtt_GetPackedQuad(const stbtt_packedchar *chardata, - int pw, - int ph, /* same data as above */ - int char_index, /* character to display */ - float *xpos, - float *ypos, /* pointers to current position in screen pixel space */ - stbtt_aligned_quad *q, /* output: quad to draw */ - int align_to_integer); - -STBTT_DEF int -stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); -STBTT_DEF void -stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects); -STBTT_DEF int -stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); -/* Calling these functions in sequence is roughly equivalent to calling */ -/* stbtt_PackFontRanges(). If you more control over the packing of multiple */ -/* fonts, or if you want to pack custom data into a font texture, take a look */ -/* at the source to of stbtt_PackFontRanges() and create a custom version */ -/* using these functions, e.g. call GatherRects multiple times, */ -/* building up a single array of rects, then call PackRects once, */ -/* then call RenderIntoRects repeatedly. This may result in a */ -/* better packing than calling PackFontRanges multiple times */ -/* (or it may not). */ - -/* this is an opaque structure that you shouldn't mess with which holds */ -/* all the context needed from PackBegin to PackEnd. */ -struct stbtt_pack_context { - void *user_allocator_context; - void *pack_info; - int width; - int height; - int stride_in_bytes; - int padding; - int skip_missing; - unsigned int h_oversample, v_oversample; - unsigned char *pixels; - void *nodes; -}; - -/* //////////////////////////////////////////////////////////////////////////// */ -/* */ -/* FONT LOADING */ -/* */ -/* */ - -STBTT_DEF int -stbtt_GetNumberOfFonts(const unsigned char *data); -/* This function will determine the number of fonts in a font file. TrueType */ -/* collection (.ttc) files may contain multiple fonts, while TrueType font */ -/* (.ttf) files only contain one font. The number of fonts can be used for */ -/* indexing with the previous function where the index is between zero and one */ -/* less than the total fonts. If an error occurs, -1 is returned. */ - -STBTT_DEF int -stbtt_GetFontOffsetForIndex(const unsigned char *data, int index); -/* Each .ttf/.ttc file may have more than one font. Each font has a sequential */ -/* index number starting from 0. Call this function to get the font offset for */ -/* a given index; it returns -1 if the index is out of range. A regular .ttf */ -/* file will only define one font and it always be at offset 0, so it will */ -/* return '0' for index 0, and -1 for all other indices. */ - -/* The following structure is defined publicly so you can declare one on */ -/* the stack or as a global or etc, but you should treat it as opaque. */ -struct stbtt_fontinfo { - void *userdata; - unsigned char *data; /* pointer to .ttf file */ - int fontstart; /* offset of start of font */ - - int numGlyphs; /* number of glyphs, needed for range checking */ - - int loca, head, glyf, hhea, hmtx, kern, gpos, svg; /* table locations as offset from start of .ttf */ - int index_map; /* a cmap mapping for our chosen character encoding */ - int indexToLocFormat; /* format needed to map from glyph index to glyph */ - - stbtt__buf cff; /* cff font data */ - stbtt__buf charstrings; /* the charstring index */ - stbtt__buf gsubrs; /* global charstring subroutines index */ - stbtt__buf subrs; /* private charstring subroutines index */ - stbtt__buf fontdicts; /* array of font dicts */ - stbtt__buf fdselect; /* map from glyph to fontdict */ -}; - -STBTT_DEF int -stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset); -/* Given an offset into the file that defines a font, this function builds */ -/* the necessary cached info for the rest of the system. You must allocate */ -/* the stbtt_fontinfo yourself, and stbtt_InitFont will fill it out. You don't */ -/* need to do anything special to free it, because the contents are pure */ -/* value data with no additional data structures. Returns 0 on failure. */ - -/* //////////////////////////////////////////////////////////////////////////// */ -/* */ -/* CHARACTER TO GLYPH-INDEX CONVERSIOn */ - -STBTT_DEF int -stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint); -/* If you're going to perform multiple operations on the same character */ -/* and you want a speed-up, call this function with the character you're */ -/* going to process, then use glyph-based functions instead of the */ -/* codepoint-based functions. */ -/* Returns 0 if the character codepoint is not defined in the font. */ - -/* //////////////////////////////////////////////////////////////////////////// */ -/* */ -/* CHARACTER PROPERTIES */ -/* */ - -STBTT_DEF float -stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float pixels); -/* computes a scale factor to produce a font whose "height" is 'pixels' tall. */ -/* Height is measured as the distance from the highest ascender to the lowest */ -/* descender; in other words, it's equivalent to calling stbtt_GetFontVMetrics */ -/* and computing: */ -/* scale = pixels / (ascent - descent) */ -/* so if you prefer to measure height by the ascent only, use a similar calculation. */ - -STBTT_DEF float -stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels); -/* computes a scale factor to produce a font whose EM size is mapped to */ -/* 'pixels' tall. This is probably what traditional APIs compute, but */ -/* I'm not positive. */ - -STBTT_DEF void -stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap); -/* ascent is the coordinate above the baseline the font extends; descent */ -/* is the coordinate below the baseline the font extends (i.e. it is typically negative) */ -/* lineGap is the spacing between one row's descent and the next row's ascent... */ -/* so you should advance the vertical position by "*ascent - *descent + *lineGap" */ -/* these are expressed in unscaled coordinates, so you must multiply by */ -/* the scale factor for a given size */ - -STBTT_DEF int -stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap); -/* analogous to GetFontVMetrics, but returns the "typographic" values from the OS/2 */ -/* table (specific to MS/Windows TTF files). */ -/* */ -/* Returns 1 on success (table present), 0 on failure. */ - -STBTT_DEF void -stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1); -/* the bounding box around all possible characters */ - -STBTT_DEF void -stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing); -/* leftSideBearing is the offset from the current horizontal position to the left edge of the character */ -/* advanceWidth is the offset from the current horizontal position to the next horizontal position */ -/* these are expressed in unscaled coordinates */ - -STBTT_DEF int -stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2); -/* an additional amount to add to the 'advance' value between ch1 and ch2 */ - -STBTT_DEF int -stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1); -/* Gets the bounding box of the visible part of the glyph, in unscaled coordinates */ - -STBTT_DEF void -stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing); -STBTT_DEF int -stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2); -STBTT_DEF int -stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1); -/* as above, but takes one or more glyph indices for greater efficiency */ - -typedef struct stbtt_kerningentry { - int glyph1; /* use stbtt_FindGlyphIndex */ - int glyph2; - int advance; -} stbtt_kerningentry; - -STBTT_DEF int -stbtt_GetKerningTableLength(const stbtt_fontinfo *info); -STBTT_DEF int -stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningentry *table, int table_length); -/* Retrieves a complete list of all of the kerning pairs provided by the font */ -/* stbtt_GetKerningTable never writes more than table_length entries and returns how many entries it did write. */ -/* The table will be sorted by (a.glyph1 == b.glyph1)?(a.glyph2 < b.glyph2):(a.glyph1 < b.glyph1) */ - -/* //////////////////////////////////////////////////////////////////////////// */ -/* */ -/* GLYPH SHAPES (you probably don't need these, but they have to go before */ -/* the bitmaps for C declaration-order reasons) */ -/* */ - -# ifndef STBTT_vmove /* you can predefine these to use different values (but why?) */ -enum { STBTT_vmove = 1, STBTT_vline, STBTT_vcurve, STBTT_vcubic }; -# endif - -# ifndef stbtt_vertex /* you can predefine this to use different values */ - /* (we share this with other code at RAD) */ -# define stbtt_vertex_type short /* can't use stbtt_int16 because that's not visible in the header file */ -typedef struct { - stbtt_vertex_type x, y, cx, cy, cx1, cy1; - unsigned char type, padding; -} stbtt_vertex; -# endif - -STBTT_DEF int -stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index); -/* returns non-zero if nothing is drawn for this glyph */ - -STBTT_DEF int -stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices); -STBTT_DEF int -stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices); -/* returns # of vertices and fills *vertices with the pointer to them */ -/* these are expressed in "unscaled" coordinates */ -/* */ -/* The shape is a series of contours. Each one starts with */ -/* a STBTT_moveto, then consists of a series of mixed */ -/* STBTT_lineto and STBTT_curveto segments. A lineto */ -/* draws a line from previous endpoint to its x,y; a curveto */ -/* draws a quadratic bezier from previous endpoint to */ -/* its x,y, using cx,cy as the bezier control point. */ - -STBTT_DEF void -stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices); -/* frees the data allocated above */ - -STBTT_DEF unsigned char * -stbtt_FindSVGDoc(const stbtt_fontinfo *info, int gl); -STBTT_DEF int -stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg); -STBTT_DEF int -stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg); -/* fills svg with the character's SVG data. */ -/* returns data size or 0 if SVG not found. */ - -/* //////////////////////////////////////////////////////////////////////////// */ -/* */ -/* BITMAP RENDERING */ -/* */ - -STBTT_DEF void -stbtt_FreeBitmap(unsigned char *bitmap, void *userdata); -/* frees the bitmap allocated below */ - -STBTT_DEF unsigned char * -stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff); -/* allocates a large-enough single-channel 8bpp bitmap and renders the */ -/* specified character/glyph at the specified scale into it, with */ -/* antialiasing. 0 is no coverage (transparent), 255 is fully covered (opaque). */ -/* *width & *height are filled out with the width & height of the bitmap, */ -/* which is stored left-to-right, top-to-bottom. */ -/* */ -/* xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap */ - -STBTT_DEF unsigned char * -stbtt_GetCodepointBitmapSubpixel( - const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff); -/* the same as stbtt_GetCodepoitnBitmap, but you can specify a subpixel */ -/* shift for the character */ - -STBTT_DEF void -stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint); -/* the same as stbtt_GetCodepointBitmap, but you pass in storage for the bitmap */ -/* in the form of 'output', with row spacing of 'out_stride' bytes. the bitmap */ -/* is clipped to out_w/out_h bytes. Call stbtt_GetCodepointBitmapBox to get the */ -/* width and height and positioning info for it first. */ - -STBTT_DEF void -stbtt_MakeCodepointBitmapSubpixel( - const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint); -/* same as stbtt_MakeCodepointBitmap, but you can specify a subpixel */ -/* shift for the character */ - -STBTT_DEF void -stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo *info, - unsigned char *output, - int out_w, - int out_h, - int out_stride, - float scale_x, - float scale_y, - float shift_x, - float shift_y, - int oversample_x, - int oversample_y, - float *sub_x, - float *sub_y, - int codepoint); -/* same as stbtt_MakeCodepointBitmapSubpixel, but prefiltering */ -/* is performed (see stbtt_PackSetOversampling) */ - -STBTT_DEF void -stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); -/* get the bbox of the bitmap centered around the glyph origin; so the */ -/* bitmap width is ix1-ix0, height is iy1-iy0, and location to place */ -/* the bitmap top left is (leftSideBearing*scale,iy0). */ -/* (Note that the bitmap uses y-increases-down, but the shape uses */ -/* y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.) */ - -STBTT_DEF void -stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); -/* same as stbtt_GetCodepointBitmapBox, but you can specify a subpixel */ -/* shift for the character */ - -/* the following functions are equivalent to the above functions, but operate */ -/* on glyph indices instead of Unicode codepoints (for efficiency) */ -STBTT_DEF unsigned char * -stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff); -STBTT_DEF unsigned char * -stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff); -STBTT_DEF void -stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph); -STBTT_DEF void -stbtt_MakeGlyphBitmapSubpixel( - const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph); -STBTT_DEF void -stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info, - unsigned char *output, - int out_w, - int out_h, - int out_stride, - float scale_x, - float scale_y, - float shift_x, - float shift_y, - int oversample_x, - int oversample_y, - float *sub_x, - float *sub_y, - int glyph); -STBTT_DEF void -stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); -STBTT_DEF void -stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); - -/* @TODO: don't expose this structure */ -typedef struct { - int w, h, stride; - unsigned char *pixels; -} stbtt__bitmap; - -/* rasterize a shape with quadratic beziers into a bitmap */ -STBTT_DEF void -stbtt_Rasterize(stbtt__bitmap *result, /* 1-channel bitmap to draw into */ - float flatness_in_pixels, /* allowable error of curve in pixels */ - stbtt_vertex *vertices, /* array of vertices defining shape */ - int num_verts, /* number of vertices in above array */ - float scale_x, - float scale_y, /* scale applied to input vertices */ - float shift_x, - float shift_y, /* translation applied to input vertices */ - int x_off, - int y_off, /* another translation applied to input */ - int invert, /* if non-zero, vertically flip shape */ - void *userdata); /* context for to STBTT_MALLOC */ - -/* //////////////////////////////////////////////////////////////////////////// */ -/* */ -/* Signed Distance Function (or Field) rendering */ - -STBTT_DEF void -stbtt_FreeSDF(unsigned char *bitmap, void *userdata); -/* frees the SDF bitmap allocated below */ - -STBTT_DEF unsigned char * -stbtt_GetGlyphSDF( - const stbtt_fontinfo *info, float scale, int glyph, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff); -STBTT_DEF unsigned char * -stbtt_GetCodepointSDF( - const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff); -/* These functions compute a discretized SDF field for a single character, suitable for storing */ -/* in a single-channel texture, sampling with bilinear filtering, and testing against */ -/* larger than some threshold to produce scalable fonts. */ -/* info -- the font */ -/* scale -- controls the size of the resulting SDF bitmap, same as it would be creating a regular - * bitmap */ -/* glyph/codepoint -- the character to generate the SDF for */ -/* padding -- extra "pixels" around the character which are filled with the distance to the character - * (not 0), */ -/* which allows effects like bit outlines */ -/* onedge_value -- value 0-255 to test the SDF against to reconstruct the character (i.e. the isocontour - * of the character) */ -/* pixel_dist_scale -- what value the SDF should increase by when moving one SDF "pixel" away from the edge - * (on the 0..255 scale) */ -/* if positive, > onedge_value is inside; if negative, < onedge_value is inside */ -/* width,height -- output height & width of the SDF bitmap (including padding) */ -/* xoff,yoff -- output origin of the character */ -/* return value -- a 2D array of bytes 0..255, width*height in size */ -/* */ -/* pixel_dist_scale & onedge_value are a scale & bias that allows you to make */ -/* optimal use of the limited 0..255 for your application, trading off precision */ -/* and special effects. SDF values outside the range 0..255 are clamped to 0..255. */ -/* */ -/* Example: */ -/* scale = stbtt_ScaleForPixelHeight(22) */ -/* padding = 5 */ -/* onedge_value = 180 */ -/* pixel_dist_scale = 180/5.0 = 36.0 */ -/* */ -/* This will create an SDF bitmap in which the character is about 22 pixels */ -/* high but the whole bitmap is about 22+5+5=32 pixels high. To produce a filled */ -/* shape, sample the SDF at each pixel and fill the pixel if the SDF value */ -/* is greater than or equal to 180/255. (You'll actually want to antialias, */ -/* which is beyond the scope of this example.) Additionally, you can compute */ -/* offset outlines (e.g. to stroke the character border inside & outside, */ -/* or only outside). For example, to fill outside the character up to 3 SDF */ -/* pixels, you would compare against (180-36.0*3)/255 = 72/255. The above */ -/* choice of variables maps a range from 5 pixels outside the shape to */ -/* 2 pixels inside the shape to 0..255; this is intended primarily for apply */ -/* outside effects only (the interior range is needed to allow proper */ -/* antialiasing of the font at *smaller* sizes) */ -/* */ -/* The function computes the SDF analytically at each SDF pixel, not by e.g. */ -/* building a higher-res bitmap and approximating it. In theory the quality */ -/* should be as high as possible for an SDF of this size & representation, but */ -/* unclear if this is true in practice (perhaps building a higher-res bitmap */ -/* and computing from that can allow drop-out prevention). */ -/* */ -/* The algorithm has not been optimized at all, so expect it to be slow */ -/* if computing lots of characters or very large sizes. */ - -/* //////////////////////////////////////////////////////////////////////////// */ -/* */ -/* Finding the right font... */ -/* */ -/* You should really just solve this offline, keep your own tables */ -/* of what font is what, and don't try to get it out of the .ttf file. */ -/* That's because getting it out of the .ttf file is really hard, because */ -/* the names in the file can appear in many possible encodings, in many */ -/* possible languages, and e.g. if you need a case-insensitive comparison, */ -/* the details of that depend on the encoding & language in a complex way */ -/* (actually underspecified in truetype, but also gigantic). */ -/* */ -/* But you can use the provided functions in two possible ways: */ -/* stbtt_FindMatchingFont() will use *case-sensitive* comparisons on */ -/* unicode-encoded names to try to find the font you want; */ -/* you can run this before calling stbtt_InitFont() */ -/* */ -/* stbtt_GetFontNameString() lets you get any of the various strings */ -/* from the file yourself and do your own comparisons on them. */ -/* You have to have called stbtt_InitFont() first. */ - -STBTT_DEF int -stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags); -/* returns the offset (not index) of the font that matches, or -1 if none */ -/* if you use STBTT_MACSTYLE_DONTCARE, use a font name like "Arial Bold". */ -/* if you use any other flag, use a font name like "Arial"; this checks */ -/* the 'macStyle' header field; i don't know if fonts set this consistently */ -# define STBTT_MACSTYLE_DONTCARE 0 -# define STBTT_MACSTYLE_BOLD 1 -# define STBTT_MACSTYLE_ITALIC 2 -# define STBTT_MACSTYLE_UNDERSCORE 4 -# define STBTT_MACSTYLE_NONE 8 /* <= not same as 0, this makes us check the bitfield is 0 */ - -STBTT_DEF int -stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2); -/* returns 1/0 whether the first string interpreted as utf8 is identical to */ -/* the second string interpreted as big-endian utf16... useful for strings from next func */ - -STBTT_DEF const char * -stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID); -/* returns the string (which may be big-endian double byte, e.g. for unicode) */ -/* and puts the length in bytes in *length. */ -/* */ -/* some of the values for the IDs are below; for more see the truetype spec: */ -/* http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html */ -/* http://www.microsoft.com/typography/otspec/name.htm */ - -enum { /* platformID */ - STBTT_PLATFORM_ID_UNICODE = 0, - STBTT_PLATFORM_ID_MAC = 1, - STBTT_PLATFORM_ID_ISO = 2, - STBTT_PLATFORM_ID_MICROSOFT = 3 -}; - -enum { /* encodingID for STBTT_PLATFORM_ID_UNICODE */ - STBTT_UNICODE_EID_UNICODE_1_0 = 0, - STBTT_UNICODE_EID_UNICODE_1_1 = 1, - STBTT_UNICODE_EID_ISO_10646 = 2, - STBTT_UNICODE_EID_UNICODE_2_0_BMP = 3, - STBTT_UNICODE_EID_UNICODE_2_0_FULL = 4 -}; - -enum { /* encodingID for STBTT_PLATFORM_ID_MICROSOFT */ - STBTT_MS_EID_SYMBOL = 0, - STBTT_MS_EID_UNICODE_BMP = 1, - STBTT_MS_EID_SHIFTJIS = 2, - STBTT_MS_EID_UNICODE_FULL = 10 -}; - -enum { /* encodingID for STBTT_PLATFORM_ID_MAC; same as Script Manager codes */ - STBTT_MAC_EID_ROMAN = 0, - STBTT_MAC_EID_ARABIC = 4, - STBTT_MAC_EID_JAPANESE = 1, - STBTT_MAC_EID_HEBREW = 5, - STBTT_MAC_EID_CHINESE_TRAD = 2, - STBTT_MAC_EID_GREEK = 6, - STBTT_MAC_EID_KOREAN = 3, - STBTT_MAC_EID_RUSSIAN = 7 -}; - -enum { /* languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID... */ - /* problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs */ - STBTT_MS_LANG_ENGLISH = 0x0409, - STBTT_MS_LANG_ITALIAN = 0x0410, - STBTT_MS_LANG_CHINESE = 0x0804, - STBTT_MS_LANG_JAPANESE = 0x0411, - STBTT_MS_LANG_DUTCH = 0x0413, - STBTT_MS_LANG_KOREAN = 0x0412, - STBTT_MS_LANG_FRENCH = 0x040c, - STBTT_MS_LANG_RUSSIAN = 0x0419, - STBTT_MS_LANG_GERMAN = 0x0407, - STBTT_MS_LANG_SPANISH = 0x0409, - STBTT_MS_LANG_HEBREW = 0x040d, - STBTT_MS_LANG_SWEDISH = 0x041D -}; - -enum { /* languageID for STBTT_PLATFORM_ID_MAC */ - STBTT_MAC_LANG_ENGLISH = 0, - STBTT_MAC_LANG_JAPANESE = 11, - STBTT_MAC_LANG_ARABIC = 12, - STBTT_MAC_LANG_KOREAN = 23, - STBTT_MAC_LANG_DUTCH = 4, - STBTT_MAC_LANG_RUSSIAN = 32, - STBTT_MAC_LANG_FRENCH = 1, - STBTT_MAC_LANG_SPANISH = 6, - STBTT_MAC_LANG_GERMAN = 2, - STBTT_MAC_LANG_SWEDISH = 5, - STBTT_MAC_LANG_HEBREW = 10, - STBTT_MAC_LANG_CHINESE_SIMPLIFIED = 33, - STBTT_MAC_LANG_ITALIAN = 3, - STBTT_MAC_LANG_CHINESE_TRAD = 19 -}; - -# ifdef __cplusplus -} -# endif - -#endif /* __STB_INCLUDE_STB_TRUETYPE_H__ */ - -/* ///////////////////////////////////////////////////////////////////////////// */ -/* ///////////////////////////////////////////////////////////////////////////// */ -/* // */ -/* // IMPLEMENTATION */ -/* // */ -/* // */ - -#ifdef STB_TRUETYPE_IMPLEMENTATION - -# ifndef STBTT_MAX_OVERSAMPLE -# define STBTT_MAX_OVERSAMPLE 8 -# endif - -# if STBTT_MAX_OVERSAMPLE > 255 -# error "STBTT_MAX_OVERSAMPLE cannot be > 255" -# endif - -typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE - 1)) == 0 ? 1 : -1]; - -# ifndef STBTT_RASTERIZER_VERSION -# define STBTT_RASTERIZER_VERSION 2 -# endif - -# ifdef _MSC_VER -# define STBTT__NOTUSED(v) (void)(v) -# else -# define STBTT__NOTUSED(v) (void)sizeof(v) -# endif - -/* //////////////////////////////////////////////////////////////////////// */ -/* */ -/* stbtt__buf helpers to parse data from file */ -/* */ - -static stbtt_uint8 -stbtt__buf_get8(stbtt__buf *b) -{ - if (b->cursor >= b->size) { - return 0; - } - return b->data[b->cursor++]; -} - -static stbtt_uint8 -stbtt__buf_peek8(stbtt__buf *b) -{ - if (b->cursor >= b->size) { - return 0; - } - return b->data[b->cursor]; -} - -static void -stbtt__buf_seek(stbtt__buf *b, int o) -{ - STBTT_assert(!(o > b->size || o < 0)); - b->cursor = (o > b->size || o < 0) ? b->size : o; -} - -static void -stbtt__buf_skip(stbtt__buf *b, int o) -{ - stbtt__buf_seek(b, b->cursor + o); -} - -static stbtt_uint32 -stbtt__buf_get(stbtt__buf *b, int n) -{ - stbtt_uint32 v = 0; - int i; - STBTT_assert(n >= 1 && n <= 4); - for (i = 0; i < n; i++) { - v = (v << 8) | stbtt__buf_get8(b); - } - return v; -} - -static stbtt__buf -stbtt__new_buf(const void *p, size_t size) -{ - stbtt__buf r; - STBTT_assert(size < 0x40000000); - r.data = (stbtt_uint8 *)p; - r.size = (int)size; - r.cursor = 0; - return r; -} - -# define stbtt__buf_get16(b) stbtt__buf_get((b), 2) -# define stbtt__buf_get32(b) stbtt__buf_get((b), 4) - -static stbtt__buf -stbtt__buf_range(const stbtt__buf *b, int o, int s) -{ - stbtt__buf r = stbtt__new_buf(NULL, 0); - if (o < 0 || s < 0 || o > b->size || s > b->size - o) { - return r; - } - r.data = b->data + o; - r.size = s; - return r; -} - -static stbtt__buf -stbtt__cff_get_index(stbtt__buf *b) -{ - int count, start, offsize; - start = b->cursor; - count = stbtt__buf_get16(b); - if (count) { - offsize = stbtt__buf_get8(b); - STBTT_assert(offsize >= 1 && offsize <= 4); - stbtt__buf_skip(b, offsize * count); - stbtt__buf_skip(b, stbtt__buf_get(b, offsize) - 1); - } - return stbtt__buf_range(b, start, b->cursor - start); -} - -static stbtt_uint32 -stbtt__cff_int(stbtt__buf *b) -{ - int b0 = stbtt__buf_get8(b); - if (b0 >= 32 && b0 <= 246) { - return b0 - 139; - } else if (b0 >= 247 && b0 <= 250) { - return (b0 - 247) * 256 + stbtt__buf_get8(b) + 108; - } else if (b0 >= 251 && b0 <= 254) { - return -(b0 - 251) * 256 - stbtt__buf_get8(b) - 108; - } else if (b0 == 28) { - return stbtt__buf_get16(b); - } else if (b0 == 29) { - return stbtt__buf_get32(b); - } - STBTT_assert(0); - return 0; -} - -static void -stbtt__cff_skip_operand(stbtt__buf *b) -{ - int v, b0 = stbtt__buf_peek8(b); - STBTT_assert(b0 >= 28); - if (b0 == 30) { - stbtt__buf_skip(b, 1); - while (b->cursor < b->size) { - v = stbtt__buf_get8(b); - if ((v & 0xF) == 0xF || (v >> 4) == 0xF) { - break; - } - } - } else { - stbtt__cff_int(b); - } -} - -static stbtt__buf -stbtt__dict_get(stbtt__buf *b, int key) -{ - stbtt__buf_seek(b, 0); - while (b->cursor < b->size) { - int start = b->cursor, end, op; - while (stbtt__buf_peek8(b) >= 28) { - stbtt__cff_skip_operand(b); - } - end = b->cursor; - op = stbtt__buf_get8(b); - if (op == 12) { - op = stbtt__buf_get8(b) | 0x100; - } - if (op == key) { - return stbtt__buf_range(b, start, end - start); - } - } - return stbtt__buf_range(b, 0, 0); -} - -static void -stbtt__dict_get_ints(stbtt__buf *b, int key, int outcount, stbtt_uint32 *out) -{ - int i; - stbtt__buf operands = stbtt__dict_get(b, key); - for (i = 0; i < outcount && operands.cursor < operands.size; i++) { - out[i] = stbtt__cff_int(&operands); - } -} - -static int -stbtt__cff_index_count(stbtt__buf *b) -{ - stbtt__buf_seek(b, 0); - return stbtt__buf_get16(b); -} - -static stbtt__buf -stbtt__cff_index_get(stbtt__buf b, int i) -{ - int count, offsize, start, end; - stbtt__buf_seek(&b, 0); - count = stbtt__buf_get16(&b); - offsize = stbtt__buf_get8(&b); - STBTT_assert(i >= 0 && i < count); - STBTT_assert(offsize >= 1 && offsize <= 4); - stbtt__buf_skip(&b, i * offsize); - start = stbtt__buf_get(&b, offsize); - end = stbtt__buf_get(&b, offsize); - return stbtt__buf_range(&b, 2 + (count + 1) * offsize + start, end - start); -} - -/* //////////////////////////////////////////////////////////////////////// */ -/* */ -/* accessors to parse data from file */ -/* */ - -/* on platforms that don't allow misaligned reads, if we want to allow */ -/* truetype fonts that aren't padded to alignment, define ALLOW_UNALIGNED_TRUETYPE */ - -# define ttBYTE(p) (*(stbtt_uint8 *)(p)) -# define ttCHAR(p) (*(stbtt_int8 *)(p)) -# define ttFixed(p) ttLONG(p) - -static stbtt_uint16 -ttUSHORT(stbtt_uint8 *p) -{ - return p[0] * 256 + p[1]; -} -static stbtt_int16 -ttSHORT(stbtt_uint8 *p) -{ - return p[0] * 256 + p[1]; -} -static stbtt_uint32 -ttULONG(stbtt_uint8 *p) -{ - return (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3]; -} -static stbtt_int32 -ttLONG(stbtt_uint8 *p) -{ - return (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3]; -} - -# define stbtt_tag4(p, c0, c1, c2, c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3)) -# define stbtt_tag(p, str) stbtt_tag4(p, str[0], str[1], str[2], str[3]) - -static int -stbtt__isfont(stbtt_uint8 *font) -{ - /* check the version number */ - if (stbtt_tag4(font, '1', 0, 0, 0)) { - return 1; /* TrueType 1 */ - } - if (stbtt_tag(font, "typ1")) { - return 1; /* TrueType with type 1 font -- we don't support this! */ - } - if (stbtt_tag(font, "OTTO")) { - return 1; /* OpenType with CFF */ - } - if (stbtt_tag4(font, 0, 1, 0, 0)) { - return 1; /* OpenType 1.0 */ - } - if (stbtt_tag(font, "true")) { - return 1; /* Apple specification for TrueType fonts */ - } - return 0; -} - -/* @OPTIMIZE: binary search */ -static stbtt_uint32 -stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart, const char *tag) -{ - stbtt_int32 num_tables = ttUSHORT(data + fontstart + 4); - stbtt_uint32 tabledir = fontstart + 12; - stbtt_int32 i; - for (i = 0; i < num_tables; ++i) { - stbtt_uint32 loc = tabledir + 16 * i; - if (stbtt_tag(data + loc + 0, tag)) { - return ttULONG(data + loc + 8); - } - } - return 0; -} - -static int -stbtt_GetFontOffsetForIndex_internal(unsigned char *font_collection, int index) -{ - /* if it's just a font, there's only one valid index */ - if (stbtt__isfont(font_collection)) { - return index == 0 ? 0 : -1; - } - - /* check if it's a TTC */ - if (stbtt_tag(font_collection, "ttcf")) { - /* version 1? */ - if (ttULONG(font_collection + 4) == 0x00010000 || ttULONG(font_collection + 4) == 0x00020000) { - stbtt_int32 n = ttLONG(font_collection + 8); - if (index >= n) { - return -1; - } - return ttULONG(font_collection + 12 + index * 4); - } - } - return -1; -} - -static int -stbtt_GetNumberOfFonts_internal(unsigned char *font_collection) -{ - /* if it's just a font, there's only one valid font */ - if (stbtt__isfont(font_collection)) { - return 1; - } - - /* check if it's a TTC */ - if (stbtt_tag(font_collection, "ttcf")) { - /* version 1? */ - if (ttULONG(font_collection + 4) == 0x00010000 || ttULONG(font_collection + 4) == 0x00020000) { - return ttLONG(font_collection + 8); - } - } - return 0; -} - -static stbtt__buf -stbtt__get_subrs(stbtt__buf cff, stbtt__buf fontdict) -{ - stbtt_uint32 subrsoff = 0, private_loc[2] = {0, 0}; - stbtt__buf pdict; - stbtt__dict_get_ints(&fontdict, 18, 2, private_loc); - if (!private_loc[1] || !private_loc[0]) { - return stbtt__new_buf(NULL, 0); - } - pdict = stbtt__buf_range(&cff, private_loc[1], private_loc[0]); - stbtt__dict_get_ints(&pdict, 19, 1, &subrsoff); - if (!subrsoff) { - return stbtt__new_buf(NULL, 0); - } - stbtt__buf_seek(&cff, private_loc[1] + subrsoff); - return stbtt__cff_get_index(&cff); -} - -/* since most people won't use this, find this table the first time it's needed */ -static int -stbtt__get_svg(stbtt_fontinfo *info) -{ - stbtt_uint32 t; - if (info->svg < 0) { - t = stbtt__find_table(info->data, info->fontstart, "SVG "); - if (t) { - stbtt_uint32 offset = ttULONG(info->data + t + 2); - info->svg = t + offset; - } else { - info->svg = 0; - } - } - return info->svg; -} - -static int -stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, int fontstart) -{ - stbtt_uint32 cmap, t; - stbtt_int32 i, numTables; - - info->data = data; - info->fontstart = fontstart; - info->cff = stbtt__new_buf(NULL, 0); - - cmap = stbtt__find_table(data, fontstart, "cmap"); /* required */ - info->loca = stbtt__find_table(data, fontstart, "loca"); /* required */ - info->head = stbtt__find_table(data, fontstart, "head"); /* required */ - info->glyf = stbtt__find_table(data, fontstart, "glyf"); /* required */ - info->hhea = stbtt__find_table(data, fontstart, "hhea"); /* required */ - info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); /* required */ - info->kern = stbtt__find_table(data, fontstart, "kern"); /* not required */ - info->gpos = stbtt__find_table(data, fontstart, "GPOS"); /* not required */ - - if (!cmap || !info->head || !info->hhea || !info->hmtx) { - return 0; - } - if (info->glyf) { - /* required for truetype */ - if (!info->loca) { - return 0; - } - } else { - /* initialization for CFF / Type2 fonts (OTF) */ - stbtt__buf b, topdict, topdictidx; - stbtt_uint32 cstype = 2, charstrings = 0, fdarrayoff = 0, fdselectoff = 0; - stbtt_uint32 cff; - - cff = stbtt__find_table(data, fontstart, "CFF "); - if (!cff) { - return 0; - } - - info->fontdicts = stbtt__new_buf(NULL, 0); - info->fdselect = stbtt__new_buf(NULL, 0); - - /* @TODO this should use size from table (not 512MB) */ - info->cff = stbtt__new_buf(data + cff, 512 * 1024 * 1024); - b = info->cff; - - /* read the header */ - stbtt__buf_skip(&b, 2); - stbtt__buf_seek(&b, stbtt__buf_get8(&b)); /* hdrsize */ - - /* @TODO the name INDEX could list multiple fonts, */ - /* but we just use the first one. */ - stbtt__cff_get_index(&b); /* name INDEX */ - topdictidx = stbtt__cff_get_index(&b); - topdict = stbtt__cff_index_get(topdictidx, 0); - stbtt__cff_get_index(&b); /* string INDEX */ - info->gsubrs = stbtt__cff_get_index(&b); - - stbtt__dict_get_ints(&topdict, 17, 1, &charstrings); - stbtt__dict_get_ints(&topdict, 0x100 | 6, 1, &cstype); - stbtt__dict_get_ints(&topdict, 0x100 | 36, 1, &fdarrayoff); - stbtt__dict_get_ints(&topdict, 0x100 | 37, 1, &fdselectoff); - info->subrs = stbtt__get_subrs(b, topdict); - - /* we only support Type 2 charstrings */ - if (cstype != 2) { - return 0; - } - if (charstrings == 0) { - return 0; - } - - if (fdarrayoff) { - /* looks like a CID font */ - if (!fdselectoff) { - return 0; - } - stbtt__buf_seek(&b, fdarrayoff); - info->fontdicts = stbtt__cff_get_index(&b); - info->fdselect = stbtt__buf_range(&b, fdselectoff, b.size - fdselectoff); - } - - stbtt__buf_seek(&b, charstrings); - info->charstrings = stbtt__cff_get_index(&b); - } - - t = stbtt__find_table(data, fontstart, "maxp"); - if (t) { - info->numGlyphs = ttUSHORT(data + t + 4); - } else { - info->numGlyphs = 0xffff; - } - - info->svg = -1; - - /* find a cmap encoding table we understand *now* to avoid searching */ - /* later. (todo: could make this installable) */ - /* the same regardless of glyph. */ - numTables = ttUSHORT(data + cmap + 2); - info->index_map = 0; - for (i = 0; i < numTables; ++i) { - stbtt_uint32 encoding_record = cmap + 4 + 8 * i; - /* find an encoding we understand: */ - switch (ttUSHORT(data + encoding_record)) { - case STBTT_PLATFORM_ID_MICROSOFT: - switch (ttUSHORT(data + encoding_record + 2)) { - case STBTT_MS_EID_UNICODE_BMP: - case STBTT_MS_EID_UNICODE_FULL: - /* MS/Unicode */ - info->index_map = cmap + ttULONG(data + encoding_record + 4); - break; - } - break; - case STBTT_PLATFORM_ID_UNICODE: - /* Mac/iOS has these */ - /* all the encodingIDs are unicode, so we don't bother to check it */ - info->index_map = cmap + ttULONG(data + encoding_record + 4); - break; - } - } - if (info->index_map == 0) { - return 0; - } - - info->indexToLocFormat = ttUSHORT(data + info->head + 50); - return 1; -} - -STBTT_DEF int -stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint) -{ - stbtt_uint8 *data = info->data; - stbtt_uint32 index_map = info->index_map; - - stbtt_uint16 format = ttUSHORT(data + index_map + 0); - if (format == 0) { /* apple byte encoding */ - stbtt_int32 bytes = ttUSHORT(data + index_map + 2); - if (unicode_codepoint < bytes - 6) { - return ttBYTE(data + index_map + 6 + unicode_codepoint); - } - return 0; - } else if (format == 6) { - stbtt_uint32 first = ttUSHORT(data + index_map + 6); - stbtt_uint32 count = ttUSHORT(data + index_map + 8); - if ((stbtt_uint32)unicode_codepoint >= first && (stbtt_uint32)unicode_codepoint < first + count) { - return ttUSHORT(data + index_map + 10 + (unicode_codepoint - first) * 2); - } - return 0; - } else if (format == 2) { - STBTT_assert(0); /* @TODO: high-byte mapping for japanese/chinese/korean */ - return 0; - } else if (format == 4) { /* standard mapping for windows fonts: binary search collection of ranges */ - stbtt_uint16 segcount = ttUSHORT(data + index_map + 6) >> 1; - stbtt_uint16 searchRange = ttUSHORT(data + index_map + 8) >> 1; - stbtt_uint16 entrySelector = ttUSHORT(data + index_map + 10); - stbtt_uint16 rangeShift = ttUSHORT(data + index_map + 12) >> 1; - - /* do a binary search of the segments */ - stbtt_uint32 endCount = index_map + 14; - stbtt_uint32 search = endCount; - - if (unicode_codepoint > 0xffff) { - return 0; - } - - /* they lie from endCount .. endCount + segCount */ - /* but searchRange is the nearest power of two, so... */ - if (unicode_codepoint >= ttUSHORT(data + search + rangeShift * 2)) { - search += rangeShift * 2; - } - - /* now decrement to bias correctly to find smallest */ - search -= 2; - while (entrySelector) { - stbtt_uint16 end; - searchRange >>= 1; - end = ttUSHORT(data + search + searchRange * 2); - if (unicode_codepoint > end) { - search += searchRange * 2; - } - --entrySelector; - } - search += 2; - - { - stbtt_uint16 offset, start, last; - stbtt_uint16 item = (stbtt_uint16)((search - endCount) >> 1); - - start = ttUSHORT(data + index_map + 14 + segcount * 2 + 2 + 2 * item); - last = ttUSHORT(data + endCount + 2 * item); - if (unicode_codepoint < start || unicode_codepoint > last) { - return 0; - } - - offset = ttUSHORT(data + index_map + 14 + segcount * 6 + 2 + 2 * item); - if (offset == 0) { - return (stbtt_uint16)(unicode_codepoint + ttSHORT(data + index_map + 14 + segcount * 4 + 2 + 2 * item)); - } - - return ttUSHORT(data + offset + (unicode_codepoint - start) * 2 + index_map + 14 + segcount * 6 + 2 + 2 * item); - } - } else if (format == 12 || format == 13) { - stbtt_uint32 ngroups = ttULONG(data + index_map + 12); - stbtt_int32 low, high; - low = 0; - high = (stbtt_int32)ngroups; - /* Binary search the right group. */ - while (low < high) { - stbtt_int32 mid = low + ((high - low) >> 1); /* rounds down, so low <= mid < high */ - stbtt_uint32 start_char = ttULONG(data + index_map + 16 + mid * 12); - stbtt_uint32 end_char = ttULONG(data + index_map + 16 + mid * 12 + 4); - if ((stbtt_uint32)unicode_codepoint < start_char) { - high = mid; - } else if ((stbtt_uint32)unicode_codepoint > end_char) { - low = mid + 1; - } else { - stbtt_uint32 start_glyph = ttULONG(data + index_map + 16 + mid * 12 + 8); - if (format == 12) { - return start_glyph + unicode_codepoint - start_char; - } else { /* format == 13 */ - return start_glyph; - } - } - } - return 0; /* not found */ - } - /* @TODO */ - STBTT_assert(0); - return 0; -} - -STBTT_DEF int -stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices) -{ - return stbtt_GetGlyphShape(info, stbtt_FindGlyphIndex(info, unicode_codepoint), vertices); -} - -static void -stbtt_setvertex(stbtt_vertex *v, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy) -{ - v->type = type; - v->x = (stbtt_int16)x; - v->y = (stbtt_int16)y; - v->cx = (stbtt_int16)cx; - v->cy = (stbtt_int16)cy; -} - -static int -stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int glyph_index) -{ - int g1, g2; - - STBTT_assert(!info->cff.size); - - if (glyph_index >= info->numGlyphs) { - return -1; /* glyph index out of range */ - } - if (info->indexToLocFormat >= 2) { - return -1; /* unknown index->glyph map format */ - } - - if (info->indexToLocFormat == 0) { - g1 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2) * 2; - g2 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2; - } else { - g1 = info->glyf + ttULONG(info->data + info->loca + glyph_index * 4); - g2 = info->glyf + ttULONG(info->data + info->loca + glyph_index * 4 + 4); - } - - return g1 == g2 ? -1 : g1; /* if length is 0, return -1 */ -} - -static int -stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1); - -STBTT_DEF int -stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) -{ - if (info->cff.size) { - stbtt__GetGlyphInfoT2(info, glyph_index, x0, y0, x1, y1); - } else { - int g = stbtt__GetGlyfOffset(info, glyph_index); - if (g < 0) { - return 0; - } - - if (x0) { - *x0 = ttSHORT(info->data + g + 2); - } - if (y0) { - *y0 = ttSHORT(info->data + g + 4); - } - if (x1) { - *x1 = ttSHORT(info->data + g + 6); - } - if (y1) { - *y1 = ttSHORT(info->data + g + 8); - } - } - return 1; -} - -STBTT_DEF int -stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1) -{ - return stbtt_GetGlyphBox(info, stbtt_FindGlyphIndex(info, codepoint), x0, y0, x1, y1); -} - -STBTT_DEF int -stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index) -{ - stbtt_int16 numberOfContours; - int g; - if (info->cff.size) { - return stbtt__GetGlyphInfoT2(info, glyph_index, NULL, NULL, NULL, NULL) == 0; - } - g = stbtt__GetGlyfOffset(info, glyph_index); - if (g < 0) { - return 1; - } - numberOfContours = ttSHORT(info->data + g); - return numberOfContours == 0; -} - -static int -stbtt__close_shape( - stbtt_vertex *vertices, int num_vertices, int was_off, int start_off, stbtt_int32 sx, stbtt_int32 sy, stbtt_int32 scx, stbtt_int32 scy, stbtt_int32 cx, stbtt_int32 cy) -{ - if (start_off) { - if (was_off) { - stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx + scx) >> 1, (cy + scy) >> 1, cx, cy); - } - stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx, sy, scx, scy); - } else { - if (was_off) { - stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx, sy, cx, cy); - } else { - stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, sx, sy, 0, 0); - } - } - return num_vertices; -} - -static int -stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) -{ - stbtt_int16 numberOfContours; - stbtt_uint8 *endPtsOfContours; - stbtt_uint8 *data = info->data; - stbtt_vertex *vertices = 0; - int num_vertices = 0; - int g = stbtt__GetGlyfOffset(info, glyph_index); - - *pvertices = NULL; - - if (g < 0) { - return 0; - } - - numberOfContours = ttSHORT(data + g); - - if (numberOfContours > 0) { - stbtt_uint8 flags = 0, flagcount; - stbtt_int32 ins, i, j = 0, m, n, next_move, was_off = 0, off, start_off = 0; - stbtt_int32 x, y, cx, cy, sx, sy, scx, scy; - stbtt_uint8 *points; - endPtsOfContours = (data + g + 10); - ins = ttUSHORT(data + g + 10 + numberOfContours * 2); - points = data + g + 10 + numberOfContours * 2 + 2 + ins; - - n = 1 + ttUSHORT(endPtsOfContours + numberOfContours * 2 - 2); - - m = n + 2 * numberOfContours; /* a loose bound on how many vertices we might need */ - vertices = (stbtt_vertex *)STBTT_malloc(m * sizeof(vertices[0]), info->userdata); - if (vertices == 0) { - return 0; - } - - next_move = 0; - flagcount = 0; - - /* in first pass, we load uninterpreted data into the allocated array */ - /* above, shifted to the end of the array so we won't overwrite it when */ - /* we create our final data starting from the front */ - - off = m - n; /* starting offset for uninterpreted data, regardless of how m ends up being calculated */ - - /* first load flags */ - - for (i = 0; i < n; ++i) { - if (flagcount == 0) { - flags = *points++; - if (flags & 8) { - flagcount = *points++; - } - } else { - --flagcount; - } - vertices[off + i].type = flags; - } - - /* now load x coordinates */ - x = 0; - for (i = 0; i < n; ++i) { - flags = vertices[off + i].type; - if (flags & 2) { - stbtt_int16 dx = *points++; - x += (flags & 16) ? dx : -dx; /* ??? */ - } else { - if (!(flags & 16)) { - x = x + (stbtt_int16)(points[0] * 256 + points[1]); - points += 2; - } - } - vertices[off + i].x = (stbtt_int16)x; - } - - /* now load y coordinates */ - y = 0; - for (i = 0; i < n; ++i) { - flags = vertices[off + i].type; - if (flags & 4) { - stbtt_int16 dy = *points++; - y += (flags & 32) ? dy : -dy; /* ??? */ - } else { - if (!(flags & 32)) { - y = y + (stbtt_int16)(points[0] * 256 + points[1]); - points += 2; - } - } - vertices[off + i].y = (stbtt_int16)y; - } - - /* now convert them to our format */ - num_vertices = 0; - sx = sy = cx = cy = scx = scy = 0; - for (i = 0; i < n; ++i) { - flags = vertices[off + i].type; - x = (stbtt_int16)vertices[off + i].x; - y = (stbtt_int16)vertices[off + i].y; - - if (next_move == i) { - if (i != 0) { - num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx, sy, scx, scy, cx, cy); - } - - /* now start the new one */ - start_off = !(flags & 1); - if (start_off) { - /* if we start off with an off-curve point, then when we need to find a point on the curve */ - /* where we can start, and we need to save some state for when we wraparound. */ - scx = x; - scy = y; - if (!(vertices[off + i + 1].type & 1)) { - /* next point is also a curve point, so interpolate an on-point curve */ - sx = (x + (stbtt_int32)vertices[off + i + 1].x) >> 1; - sy = (y + (stbtt_int32)vertices[off + i + 1].y) >> 1; - } else { - /* otherwise just use the next point as our start point */ - sx = (stbtt_int32)vertices[off + i + 1].x; - sy = (stbtt_int32)vertices[off + i + 1].y; - ++i; /* we're using point i+1 as the starting point, so skip it */ - } - } else { - sx = x; - sy = y; - } - stbtt_setvertex(&vertices[num_vertices++], STBTT_vmove, sx, sy, 0, 0); - was_off = 0; - next_move = 1 + ttUSHORT(endPtsOfContours + j * 2); - ++j; - } else { - if (!(flags & 1)) { /* if it's a curve */ - if (was_off) { /* two off-curve control points in a row means interpolate an on-curve midpoint */ - stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx + x) >> 1, (cy + y) >> 1, cx, cy); - } - cx = x; - cy = y; - was_off = 1; - } else { - if (was_off) { - stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, x, y, cx, cy); - } else { - stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, x, y, 0, 0); - } - was_off = 0; - } - } - } - num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx, sy, scx, scy, cx, cy); - } else if (numberOfContours < 0) { - /* Compound shapes. */ - int more = 1; - stbtt_uint8 *comp = data + g + 10; - num_vertices = 0; - vertices = 0; - while (more) { - stbtt_uint16 flags, gidx; - int comp_num_verts = 0, i; - stbtt_vertex *comp_verts = 0, *tmp = 0; - float mtx[6] = {1, 0, 0, 1, 0, 0}, m, n; - - flags = ttSHORT(comp); - comp += 2; - gidx = ttSHORT(comp); - comp += 2; - - if (flags & 2) { /* XY values */ - if (flags & 1) { /* shorts */ - mtx[4] = ttSHORT(comp); - comp += 2; - mtx[5] = ttSHORT(comp); - comp += 2; - } else { - mtx[4] = ttCHAR(comp); - comp += 1; - mtx[5] = ttCHAR(comp); - comp += 1; - } - } else { - /* @TODO handle matching point */ - STBTT_assert(0); - } - if (flags & (1 << 3)) { /* WE_HAVE_A_SCALE */ - mtx[0] = mtx[3] = ttSHORT(comp) / 16384.0f; - comp += 2; - mtx[1] = mtx[2] = 0; - } else if (flags & (1 << 6)) { /* WE_HAVE_AN_X_AND_YSCALE */ - mtx[0] = ttSHORT(comp) / 16384.0f; - comp += 2; - mtx[1] = mtx[2] = 0; - mtx[3] = ttSHORT(comp) / 16384.0f; - comp += 2; - } else if (flags & (1 << 7)) { /* WE_HAVE_A_TWO_BY_TWO */ - mtx[0] = ttSHORT(comp) / 16384.0f; - comp += 2; - mtx[1] = ttSHORT(comp) / 16384.0f; - comp += 2; - mtx[2] = ttSHORT(comp) / 16384.0f; - comp += 2; - mtx[3] = ttSHORT(comp) / 16384.0f; - comp += 2; - } - - /* Find transformation scales. */ - m = (float)STBTT_sqrt(mtx[0] * mtx[0] + mtx[1] * mtx[1]); - n = (float)STBTT_sqrt(mtx[2] * mtx[2] + mtx[3] * mtx[3]); - - /* Get indexed glyph. */ - comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts); - if (comp_num_verts > 0) { - /* Transform vertices. */ - for (i = 0; i < comp_num_verts; ++i) { - stbtt_vertex *v = &comp_verts[i]; - stbtt_vertex_type x, y; - x = v->x; - y = v->y; - v->x = (stbtt_vertex_type)(m * (mtx[0] * x + mtx[2] * y + mtx[4])); - v->y = (stbtt_vertex_type)(n * (mtx[1] * x + mtx[3] * y + mtx[5])); - x = v->cx; - y = v->cy; - v->cx = (stbtt_vertex_type)(m * (mtx[0] * x + mtx[2] * y + mtx[4])); - v->cy = (stbtt_vertex_type)(n * (mtx[1] * x + mtx[3] * y + mtx[5])); - } - /* Append vertices. */ - tmp = (stbtt_vertex *)STBTT_malloc((num_vertices + comp_num_verts) * sizeof(stbtt_vertex), info->userdata); - if (!tmp) { - if (vertices) { - STBTT_free(vertices, info->userdata); - } - if (comp_verts) { - STBTT_free(comp_verts, info->userdata); - } - return 0; - } - if (num_vertices > 0 && vertices) { - STBTT_memcpy(tmp, vertices, num_vertices * sizeof(stbtt_vertex)); - } - STBTT_memcpy(tmp + num_vertices, comp_verts, comp_num_verts * sizeof(stbtt_vertex)); - if (vertices) { - STBTT_free(vertices, info->userdata); - } - vertices = tmp; - STBTT_free(comp_verts, info->userdata); - num_vertices += comp_num_verts; - } - /* More components ? */ - more = flags & (1 << 5); - } - } else { - /* numberOfCounters == 0, do nothing */ - } - - *pvertices = vertices; - return num_vertices; -} - -typedef struct { - int bounds; - int started; - float first_x, first_y; - float x, y; - stbtt_int32 min_x, max_x, min_y, max_y; - - stbtt_vertex *pvertices; - int num_vertices; -} stbtt__csctx; - -# define STBTT__CSCTX_INIT(bounds) {bounds, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, 0} - -static void -stbtt__track_vertex(stbtt__csctx *c, stbtt_int32 x, stbtt_int32 y) -{ - if (x > c->max_x || !c->started) { - c->max_x = x; - } - if (y > c->max_y || !c->started) { - c->max_y = y; - } - if (x < c->min_x || !c->started) { - c->min_x = x; - } - if (y < c->min_y || !c->started) { - c->min_y = y; - } - c->started = 1; -} - -static void -stbtt__csctx_v(stbtt__csctx *c, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy, stbtt_int32 cx1, stbtt_int32 cy1) -{ - if (c->bounds) { - stbtt__track_vertex(c, x, y); - if (type == STBTT_vcubic) { - stbtt__track_vertex(c, cx, cy); - stbtt__track_vertex(c, cx1, cy1); - } - } else { - stbtt_setvertex(&c->pvertices[c->num_vertices], type, x, y, cx, cy); - c->pvertices[c->num_vertices].cx1 = (stbtt_int16)cx1; - c->pvertices[c->num_vertices].cy1 = (stbtt_int16)cy1; - } - c->num_vertices++; -} - -static void -stbtt__csctx_close_shape(stbtt__csctx *ctx) -{ - if (ctx->first_x != ctx->x || ctx->first_y != ctx->y) { - stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->first_x, (int)ctx->first_y, 0, 0, 0, 0); - } -} - -static void -stbtt__csctx_rmove_to(stbtt__csctx *ctx, float dx, float dy) -{ - stbtt__csctx_close_shape(ctx); - ctx->first_x = ctx->x = ctx->x + dx; - ctx->first_y = ctx->y = ctx->y + dy; - stbtt__csctx_v(ctx, STBTT_vmove, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0); -} - -static void -stbtt__csctx_rline_to(stbtt__csctx *ctx, float dx, float dy) -{ - ctx->x += dx; - ctx->y += dy; - stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0); -} - -static void -stbtt__csctx_rccurve_to(stbtt__csctx *ctx, float dx1, float dy1, float dx2, float dy2, float dx3, float dy3) -{ - float cx1 = ctx->x + dx1; - float cy1 = ctx->y + dy1; - float cx2 = cx1 + dx2; - float cy2 = cy1 + dy2; - ctx->x = cx2 + dx3; - ctx->y = cy2 + dy3; - stbtt__csctx_v(ctx, STBTT_vcubic, (int)ctx->x, (int)ctx->y, (int)cx1, (int)cy1, (int)cx2, (int)cy2); -} - -static stbtt__buf -stbtt__get_subr(stbtt__buf idx, int n) -{ - int count = stbtt__cff_index_count(&idx); - int bias = 107; - if (count >= 33900) { - bias = 32768; - } else if (count >= 1240) { - bias = 1131; - } - n += bias; - if (n < 0 || n >= count) { - return stbtt__new_buf(NULL, 0); - } - return stbtt__cff_index_get(idx, n); -} - -static stbtt__buf -stbtt__cid_get_glyph_subrs(const stbtt_fontinfo *info, int glyph_index) -{ - stbtt__buf fdselect = info->fdselect; - int nranges, start, end, v, fmt, fdselector = -1, i; - - stbtt__buf_seek(&fdselect, 0); - fmt = stbtt__buf_get8(&fdselect); - if (fmt == 0) { - /* untested */ - stbtt__buf_skip(&fdselect, glyph_index); - fdselector = stbtt__buf_get8(&fdselect); - } else if (fmt == 3) { - nranges = stbtt__buf_get16(&fdselect); - start = stbtt__buf_get16(&fdselect); - for (i = 0; i < nranges; i++) { - v = stbtt__buf_get8(&fdselect); - end = stbtt__buf_get16(&fdselect); - if (glyph_index >= start && glyph_index < end) { - fdselector = v; - break; - } - start = end; - } - } - if (fdselector == -1) { - stbtt__new_buf(NULL, 0); - } - return stbtt__get_subrs(info->cff, stbtt__cff_index_get(info->fontdicts, fdselector)); -} - -static int -stbtt__run_charstring(const stbtt_fontinfo *info, int glyph_index, stbtt__csctx *c) -{ - int in_header = 1, maskbits = 0, subr_stack_height = 0, sp = 0, v, i, b0; - int has_subrs = 0, clear_stack; - float s[48]; - stbtt__buf subr_stack[10], subrs = info->subrs, b; - float f; - -# define STBTT__CSERR(s) (0) - - /* this currently ignores the initial width value, which isn't needed if we have hmtx */ - b = stbtt__cff_index_get(info->charstrings, glyph_index); - while (b.cursor < b.size) { - i = 0; - clear_stack = 1; - b0 = stbtt__buf_get8(&b); - switch (b0) { - /* @TODO implement hinting */ - case 0x13: /* hintmask */ - case 0x14: /* cntrmask */ - if (in_header) { - maskbits += (sp / 2); /* implicit "vstem" */ - } - in_header = 0; - stbtt__buf_skip(&b, (maskbits + 7) / 8); - break; - - case 0x01: /* hstem */ - case 0x03: /* vstem */ - case 0x12: /* hstemhm */ - case 0x17: /* vstemhm */ - maskbits += (sp / 2); - break; - - case 0x15: /* rmoveto */ - in_header = 0; - if (sp < 2) { - return STBTT__CSERR("rmoveto stack"); - } - stbtt__csctx_rmove_to(c, s[sp - 2], s[sp - 1]); - break; - case 0x04: /* vmoveto */ - in_header = 0; - if (sp < 1) { - return STBTT__CSERR("vmoveto stack"); - } - stbtt__csctx_rmove_to(c, 0, s[sp - 1]); - break; - case 0x16: /* hmoveto */ - in_header = 0; - if (sp < 1) { - return STBTT__CSERR("hmoveto stack"); - } - stbtt__csctx_rmove_to(c, s[sp - 1], 0); - break; - - case 0x05: /* rlineto */ - if (sp < 2) { - return STBTT__CSERR("rlineto stack"); - } - for (; i + 1 < sp; i += 2) { - stbtt__csctx_rline_to(c, s[i], s[i + 1]); - } - break; - - /* hlineto/vlineto and vhcurveto/hvcurveto alternate horizontal and vertical */ - /* starting from a different place. */ - - case 0x07: /* vlineto */ - if (sp < 1) { - return STBTT__CSERR("vlineto stack"); - } - goto vlineto; - case 0x06: /* hlineto */ - if (sp < 1) { - return STBTT__CSERR("hlineto stack"); - } - for (;;) { - if (i >= sp) { - break; - } - stbtt__csctx_rline_to(c, s[i], 0); - i++; - vlineto: - if (i >= sp) { - break; - } - stbtt__csctx_rline_to(c, 0, s[i]); - i++; - } - break; - - case 0x1F: /* hvcurveto */ - if (sp < 4) { - return STBTT__CSERR("hvcurveto stack"); - } - goto hvcurveto; - case 0x1E: /* vhcurveto */ - if (sp < 4) { - return STBTT__CSERR("vhcurveto stack"); - } - for (;;) { - if (i + 3 >= sp) { - break; - } - stbtt__csctx_rccurve_to(c, 0, s[i], s[i + 1], s[i + 2], s[i + 3], (sp - i == 5) ? s[i + 4] : 0.0f); - i += 4; - hvcurveto: - if (i + 3 >= sp) { - break; - } - stbtt__csctx_rccurve_to(c, s[i], 0, s[i + 1], s[i + 2], (sp - i == 5) ? s[i + 4] : 0.0f, s[i + 3]); - i += 4; - } - break; - - case 0x08: /* rrcurveto */ - if (sp < 6) { - return STBTT__CSERR("rcurveline stack"); - } - for (; i + 5 < sp; i += 6) { - stbtt__csctx_rccurve_to(c, s[i], s[i + 1], s[i + 2], s[i + 3], s[i + 4], s[i + 5]); - } - break; - - case 0x18: /* rcurveline */ - if (sp < 8) { - return STBTT__CSERR("rcurveline stack"); - } - for (; i + 5 < sp - 2; i += 6) { - stbtt__csctx_rccurve_to(c, s[i], s[i + 1], s[i + 2], s[i + 3], s[i + 4], s[i + 5]); - } - if (i + 1 >= sp) { - return STBTT__CSERR("rcurveline stack"); - } - stbtt__csctx_rline_to(c, s[i], s[i + 1]); - break; - - case 0x19: /* rlinecurve */ - if (sp < 8) { - return STBTT__CSERR("rlinecurve stack"); - } - for (; i + 1 < sp - 6; i += 2) { - stbtt__csctx_rline_to(c, s[i], s[i + 1]); - } - if (i + 5 >= sp) { - return STBTT__CSERR("rlinecurve stack"); - } - stbtt__csctx_rccurve_to(c, s[i], s[i + 1], s[i + 2], s[i + 3], s[i + 4], s[i + 5]); - break; - - case 0x1A: /* vvcurveto */ - case 0x1B: /* hhcurveto */ - if (sp < 4) { - return STBTT__CSERR("(vv|hh)curveto stack"); - } - f = 0.0; - if (sp & 1) { - f = s[i]; - i++; - } - for (; i + 3 < sp; i += 4) { - if (b0 == 0x1B) { - stbtt__csctx_rccurve_to(c, s[i], f, s[i + 1], s[i + 2], s[i + 3], 0.0); - } else { - stbtt__csctx_rccurve_to(c, f, s[i], s[i + 1], s[i + 2], 0.0, s[i + 3]); - } - f = 0.0; - } - break; - - case 0x0A: /* callsubr */ - if (!has_subrs) { - if (info->fdselect.size) { - subrs = stbtt__cid_get_glyph_subrs(info, glyph_index); - } - has_subrs = 1; - } - /* FALLTHROUGH */ - case 0x1D: /* callgsubr */ - if (sp < 1) { - return STBTT__CSERR("call(g|)subr stack"); - } - v = (int)s[--sp]; - if (subr_stack_height >= 10) { - return STBTT__CSERR("recursion limit"); - } - subr_stack[subr_stack_height++] = b; - b = stbtt__get_subr(b0 == 0x0A ? subrs : info->gsubrs, v); - if (b.size == 0) { - return STBTT__CSERR("subr not found"); - } - b.cursor = 0; - clear_stack = 0; - break; - - case 0x0B: /* return */ - if (subr_stack_height <= 0) { - return STBTT__CSERR("return outside subr"); - } - b = subr_stack[--subr_stack_height]; - clear_stack = 0; - break; - - case 0x0E: /* endchar */ - stbtt__csctx_close_shape(c); - return 1; - - case 0x0C: { /* two-byte escape */ - float dx1, dx2, dx3, dx4, dx5, dx6, dy1, dy2, dy3, dy4, dy5, dy6; - float dx, dy; - int b1 = stbtt__buf_get8(&b); - switch (b1) { - /* @TODO These "flex" implementations ignore the flex-depth and resolution, */ - /* and always draw beziers. */ - case 0x22: /* hflex */ - if (sp < 7) { - return STBTT__CSERR("hflex stack"); - } - dx1 = s[0]; - dx2 = s[1]; - dy2 = s[2]; - dx3 = s[3]; - dx4 = s[4]; - dx5 = s[5]; - dx6 = s[6]; - stbtt__csctx_rccurve_to(c, dx1, 0, dx2, dy2, dx3, 0); - stbtt__csctx_rccurve_to(c, dx4, 0, dx5, -dy2, dx6, 0); - break; - - case 0x23: /* flex */ - if (sp < 13) { - return STBTT__CSERR("flex stack"); - } - dx1 = s[0]; - dy1 = s[1]; - dx2 = s[2]; - dy2 = s[3]; - dx3 = s[4]; - dy3 = s[5]; - dx4 = s[6]; - dy4 = s[7]; - dx5 = s[8]; - dy5 = s[9]; - dx6 = s[10]; - dy6 = s[11]; - /* fd is s[12] */ - stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3); - stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6); - break; - - case 0x24: /* hflex1 */ - if (sp < 9) { - return STBTT__CSERR("hflex1 stack"); - } - dx1 = s[0]; - dy1 = s[1]; - dx2 = s[2]; - dy2 = s[3]; - dx3 = s[4]; - dx4 = s[5]; - dx5 = s[6]; - dy5 = s[7]; - dx6 = s[8]; - stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, 0); - stbtt__csctx_rccurve_to(c, dx4, 0, dx5, dy5, dx6, -(dy1 + dy2 + dy5)); - break; - - case 0x25: /* flex1 */ - if (sp < 11) { - return STBTT__CSERR("flex1 stack"); - } - dx1 = s[0]; - dy1 = s[1]; - dx2 = s[2]; - dy2 = s[3]; - dx3 = s[4]; - dy3 = s[5]; - dx4 = s[6]; - dy4 = s[7]; - dx5 = s[8]; - dy5 = s[9]; - dx6 = dy6 = s[10]; - dx = dx1 + dx2 + dx3 + dx4 + dx5; - dy = dy1 + dy2 + dy3 + dy4 + dy5; - if (STBTT_fabs(dx) > STBTT_fabs(dy)) { - dy6 = -dy; - } else { - dx6 = -dx; - } - stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3); - stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6); - break; - - default: - return STBTT__CSERR("unimplemented"); - } - } break; - - default: - if (b0 != 255 && b0 != 28 && b0 < 32) { - return STBTT__CSERR("reserved operator"); - } - - /* push immediate */ - if (b0 == 255) { - f = (float)(stbtt_int32)stbtt__buf_get32(&b) / 0x10000; - } else { - stbtt__buf_skip(&b, -1); - f = (float)(stbtt_int16)stbtt__cff_int(&b); - } - if (sp >= 48) { - return STBTT__CSERR("push stack overflow"); - } - s[sp++] = f; - clear_stack = 0; - break; - } - if (clear_stack) { - sp = 0; - } - } - return STBTT__CSERR("no endchar"); - -# undef STBTT__CSERR -} - -static int -stbtt__GetGlyphShapeT2(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) -{ - /* runs the charstring twice, once to count and once to output (to avoid realloc) */ - stbtt__csctx count_ctx = STBTT__CSCTX_INIT(1); - stbtt__csctx output_ctx = STBTT__CSCTX_INIT(0); - if (stbtt__run_charstring(info, glyph_index, &count_ctx)) { - *pvertices = (stbtt_vertex *)STBTT_malloc(count_ctx.num_vertices * sizeof(stbtt_vertex), info->userdata); - output_ctx.pvertices = *pvertices; - if (stbtt__run_charstring(info, glyph_index, &output_ctx)) { - STBTT_assert(output_ctx.num_vertices == count_ctx.num_vertices); - return output_ctx.num_vertices; - } - } - *pvertices = NULL; - return 0; -} - -static int -stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) -{ - stbtt__csctx c = STBTT__CSCTX_INIT(1); - int r = stbtt__run_charstring(info, glyph_index, &c); - if (x0) { - *x0 = r ? c.min_x : 0; - } - if (y0) { - *y0 = r ? c.min_y : 0; - } - if (x1) { - *x1 = r ? c.max_x : 0; - } - if (y1) { - *y1 = r ? c.max_y : 0; - } - return r ? c.num_vertices : 0; -} - -STBTT_DEF int -stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) -{ - if (!info->cff.size) { - return stbtt__GetGlyphShapeTT(info, glyph_index, pvertices); - } else { - return stbtt__GetGlyphShapeT2(info, glyph_index, pvertices); - } -} - -STBTT_DEF void -stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing) -{ - stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data + info->hhea + 34); - if (glyph_index < numOfLongHorMetrics) { - if (advanceWidth) { - *advanceWidth = ttSHORT(info->data + info->hmtx + 4 * glyph_index); - } - if (leftSideBearing) { - *leftSideBearing = ttSHORT(info->data + info->hmtx + 4 * glyph_index + 2); - } - } else { - if (advanceWidth) { - *advanceWidth = ttSHORT(info->data + info->hmtx + 4 * (numOfLongHorMetrics - 1)); - } - if (leftSideBearing) { - *leftSideBearing = ttSHORT(info->data + info->hmtx + 4 * numOfLongHorMetrics + 2 * (glyph_index - numOfLongHorMetrics)); - } - } -} - -STBTT_DEF int -stbtt_GetKerningTableLength(const stbtt_fontinfo *info) -{ - stbtt_uint8 *data = info->data + info->kern; - - /* we only look at the first table. it must be 'horizontal' and format 0. */ - if (!info->kern) { - return 0; - } - if (ttUSHORT(data + 2) < 1) { /* number of tables, need at least 1 */ - return 0; - } - if (ttUSHORT(data + 8) != 1) { /* horizontal flag must be set in format */ - return 0; - } - - return ttUSHORT(data + 10); -} - -STBTT_DEF int -stbtt_GetKerningTable(const stbtt_fontinfo *info, stbtt_kerningentry *table, int table_length) -{ - stbtt_uint8 *data = info->data + info->kern; - int k, length; - - /* we only look at the first table. it must be 'horizontal' and format 0. */ - if (!info->kern) { - return 0; - } - if (ttUSHORT(data + 2) < 1) { /* number of tables, need at least 1 */ - return 0; - } - if (ttUSHORT(data + 8) != 1) { /* horizontal flag must be set in format */ - return 0; - } - - length = ttUSHORT(data + 10); - if (table_length < length) { - length = table_length; - } - - for (k = 0; k < length; k++) { - table[k].glyph1 = ttUSHORT(data + 18 + (k * 6)); - table[k].glyph2 = ttUSHORT(data + 20 + (k * 6)); - table[k].advance = ttSHORT(data + 22 + (k * 6)); - } - - return length; -} - -static int -stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) -{ - stbtt_uint8 *data = info->data + info->kern; - stbtt_uint32 needle, straw; - int l, r, m; - - /* we only look at the first table. it must be 'horizontal' and format 0. */ - if (!info->kern) { - return 0; - } - if (ttUSHORT(data + 2) < 1) { /* number of tables, need at least 1 */ - return 0; - } - if (ttUSHORT(data + 8) != 1) { /* horizontal flag must be set in format */ - return 0; - } - - l = 0; - r = ttUSHORT(data + 10) - 1; - needle = glyph1 << 16 | glyph2; - while (l <= r) { - m = (l + r) >> 1; - straw = ttULONG(data + 18 + (m * 6)); /* note: unaligned read */ - if (needle < straw) { - r = m - 1; - } else if (needle > straw) { - l = m + 1; - } else { - return ttSHORT(data + 22 + (m * 6)); - } - } - return 0; -} - -static stbtt_int32 -stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyph) -{ - stbtt_uint16 coverageFormat = ttUSHORT(coverageTable); - switch (coverageFormat) { - case 1: { - stbtt_uint16 glyphCount = ttUSHORT(coverageTable + 2); - - /* Binary search. */ - stbtt_int32 l = 0, r = glyphCount - 1, m; - int straw, needle = glyph; - while (l <= r) { - stbtt_uint8 *glyphArray = coverageTable + 4; - stbtt_uint16 glyphID; - m = (l + r) >> 1; - glyphID = ttUSHORT(glyphArray + 2 * m); - straw = glyphID; - if (needle < straw) { - r = m - 1; - } else if (needle > straw) { - l = m + 1; - } else { - return m; - } - } - break; - } - - case 2: { - stbtt_uint16 rangeCount = ttUSHORT(coverageTable + 2); - stbtt_uint8 *rangeArray = coverageTable + 4; - - /* Binary search. */ - stbtt_int32 l = 0, r = rangeCount - 1, m; - int strawStart, strawEnd, needle = glyph; - while (l <= r) { - stbtt_uint8 *rangeRecord; - m = (l + r) >> 1; - rangeRecord = rangeArray + 6 * m; - strawStart = ttUSHORT(rangeRecord); - strawEnd = ttUSHORT(rangeRecord + 2); - if (needle < strawStart) { - r = m - 1; - } else if (needle > strawEnd) { - l = m + 1; - } else { - stbtt_uint16 startCoverageIndex = ttUSHORT(rangeRecord + 4); - return startCoverageIndex + glyph - strawStart; - } - } - break; - } - - default: - return -1; /* unsupported */ - } - - return -1; -} - -static stbtt_int32 -stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph) -{ - stbtt_uint16 classDefFormat = ttUSHORT(classDefTable); - switch (classDefFormat) { - case 1: { - stbtt_uint16 startGlyphID = ttUSHORT(classDefTable + 2); - stbtt_uint16 glyphCount = ttUSHORT(classDefTable + 4); - stbtt_uint8 *classDef1ValueArray = classDefTable + 6; - - if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount) { - return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID)); - } - break; - } - - case 2: { - stbtt_uint16 classRangeCount = ttUSHORT(classDefTable + 2); - stbtt_uint8 *classRangeRecords = classDefTable + 4; - - /* Binary search. */ - stbtt_int32 l = 0, r = classRangeCount - 1, m; - int strawStart, strawEnd, needle = glyph; - while (l <= r) { - stbtt_uint8 *classRangeRecord; - m = (l + r) >> 1; - classRangeRecord = classRangeRecords + 6 * m; - strawStart = ttUSHORT(classRangeRecord); - strawEnd = ttUSHORT(classRangeRecord + 2); - if (needle < strawStart) { - r = m - 1; - } else if (needle > strawEnd) { - l = m + 1; - } else { - return (stbtt_int32)ttUSHORT(classRangeRecord + 4); - } - } - break; - } - - default: - return -1; /* Unsupported definition type, return an error. */ - } - - /* "All glyphs not assigned to a class fall into class 0". (OpenType spec) */ - return 0; -} - -/* Define to STBTT_assert(x) if you want to break on unimplemented formats. */ -# define STBTT_GPOS_TODO_assert(x) - -static stbtt_int32 -stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) -{ - stbtt_uint16 lookupListOffset; - stbtt_uint8 *lookupList; - stbtt_uint16 lookupCount; - stbtt_uint8 *data; - stbtt_int32 i, sti; - - if (!info->gpos) { - return 0; - } - - data = info->data + info->gpos; - - if (ttUSHORT(data + 0) != 1) { - return 0; /* Major version 1 */ - } - if (ttUSHORT(data + 2) != 0) { - return 0; /* Minor version 0 */ - } - - lookupListOffset = ttUSHORT(data + 8); - lookupList = data + lookupListOffset; - lookupCount = ttUSHORT(lookupList); - - for (i = 0; i < lookupCount; ++i) { - stbtt_uint16 lookupOffset = ttUSHORT(lookupList + 2 + 2 * i); - stbtt_uint8 *lookupTable = lookupList + lookupOffset; - - stbtt_uint16 lookupType = ttUSHORT(lookupTable); - stbtt_uint16 subTableCount = ttUSHORT(lookupTable + 4); - stbtt_uint8 *subTableOffsets = lookupTable + 6; - if (lookupType != 2) { /* Pair Adjustment Positioning Subtable */ - continue; - } - - for (sti = 0; sti < subTableCount; sti++) { - stbtt_uint16 subtableOffset = ttUSHORT(subTableOffsets + 2 * sti); - stbtt_uint8 *table = lookupTable + subtableOffset; - stbtt_uint16 posFormat = ttUSHORT(table); - stbtt_uint16 coverageOffset = ttUSHORT(table + 2); - stbtt_int32 coverageIndex = stbtt__GetCoverageIndex(table + coverageOffset, glyph1); - if (coverageIndex == -1) { - continue; - } - - switch (posFormat) { - case 1: { - stbtt_int32 l, r, m; - int straw, needle; - stbtt_uint16 valueFormat1 = ttUSHORT(table + 4); - stbtt_uint16 valueFormat2 = ttUSHORT(table + 6); - if (valueFormat1 == 4 && valueFormat2 == 0) { /* Support more formats? */ - stbtt_int32 valueRecordPairSizeInBytes = 2; - stbtt_uint16 pairSetCount = ttUSHORT(table + 8); - stbtt_uint16 pairPosOffset = ttUSHORT(table + 10 + 2 * coverageIndex); - stbtt_uint8 *pairValueTable = table + pairPosOffset; - stbtt_uint16 pairValueCount = ttUSHORT(pairValueTable); - stbtt_uint8 *pairValueArray = pairValueTable + 2; - - if (coverageIndex >= pairSetCount) { - return 0; - } - - needle = glyph2; - r = pairValueCount - 1; - l = 0; - - /* Binary search. */ - while (l <= r) { - stbtt_uint16 secondGlyph; - stbtt_uint8 *pairValue; - m = (l + r) >> 1; - pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m; - secondGlyph = ttUSHORT(pairValue); - straw = secondGlyph; - if (needle < straw) { - r = m - 1; - } else if (needle > straw) { - l = m + 1; - } else { - stbtt_int16 xAdvance = ttSHORT(pairValue + 2); - return xAdvance; - } - } - } else { - return 0; - } - break; - } - - case 2: { - stbtt_uint16 valueFormat1 = ttUSHORT(table + 4); - stbtt_uint16 valueFormat2 = ttUSHORT(table + 6); - if (valueFormat1 == 4 && valueFormat2 == 0) { /* Support more formats? */ - stbtt_uint16 classDef1Offset = ttUSHORT(table + 8); - stbtt_uint16 classDef2Offset = ttUSHORT(table + 10); - int glyph1class = stbtt__GetGlyphClass(table + classDef1Offset, glyph1); - int glyph2class = stbtt__GetGlyphClass(table + classDef2Offset, glyph2); - - stbtt_uint16 class1Count = ttUSHORT(table + 12); - stbtt_uint16 class2Count = ttUSHORT(table + 14); - stbtt_uint8 *class1Records, *class2Records; - stbtt_int16 xAdvance; - - if (glyph1class < 0 || glyph1class >= class1Count) { - return 0; /* malformed */ - } - if (glyph2class < 0 || glyph2class >= class2Count) { - return 0; /* malformed */ - } - - class1Records = table + 16; - class2Records = class1Records + 2 * (glyph1class * class2Count); - xAdvance = ttSHORT(class2Records + 2 * glyph2class); - return xAdvance; - } else { - return 0; - } - break; - } - - default: - return 0; /* Unsupported position format */ - } - } - } - - return 0; -} - -STBTT_DEF int -stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int g1, int g2) -{ - int xAdvance = 0; - - if (info->gpos) { - xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2); - } else if (info->kern) { - xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2); - } - - return xAdvance; -} - -STBTT_DEF int -stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2) -{ - if (!info->kern && !info->gpos) { /* if no kerning table, don't waste time looking up both codepoint->glyphs */ - return 0; - } - return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info, ch1), stbtt_FindGlyphIndex(info, ch2)); -} - -STBTT_DEF void -stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing) -{ - stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info, codepoint), advanceWidth, leftSideBearing); -} - -STBTT_DEF void -stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap) -{ - if (ascent) { - *ascent = ttSHORT(info->data + info->hhea + 4); - } - if (descent) { - *descent = ttSHORT(info->data + info->hhea + 6); - } - if (lineGap) { - *lineGap = ttSHORT(info->data + info->hhea + 8); - } -} - -STBTT_DEF int -stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap) -{ - int tab = stbtt__find_table(info->data, info->fontstart, "OS/2"); - if (!tab) { - return 0; - } - if (typoAscent) { - *typoAscent = ttSHORT(info->data + tab + 68); - } - if (typoDescent) { - *typoDescent = ttSHORT(info->data + tab + 70); - } - if (typoLineGap) { - *typoLineGap = ttSHORT(info->data + tab + 72); - } - return 1; -} - -STBTT_DEF void -stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1) -{ - *x0 = ttSHORT(info->data + info->head + 36); - *y0 = ttSHORT(info->data + info->head + 38); - *x1 = ttSHORT(info->data + info->head + 40); - *y1 = ttSHORT(info->data + info->head + 42); -} - -STBTT_DEF float -stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float height) -{ - int fheight = ttSHORT(info->data + info->hhea + 4) - ttSHORT(info->data + info->hhea + 6); - return (float)height / fheight; -} - -STBTT_DEF float -stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels) -{ - int unitsPerEm = ttUSHORT(info->data + info->head + 18); - return pixels / unitsPerEm; -} - -STBTT_DEF void -stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v) -{ - STBTT_free(v, info->userdata); -} - -STBTT_DEF stbtt_uint8 * -stbtt_FindSVGDoc(const stbtt_fontinfo *info, int gl) -{ - int i; - stbtt_uint8 *data = info->data; - stbtt_uint8 *svg_doc_list = data + stbtt__get_svg((stbtt_fontinfo *)info); - - int numEntries = ttUSHORT(svg_doc_list); - stbtt_uint8 *svg_docs = svg_doc_list + 2; - - for (i = 0; i < numEntries; i++) { - stbtt_uint8 *svg_doc = svg_docs + (12 * i); - if ((gl >= ttUSHORT(svg_doc)) && (gl <= ttUSHORT(svg_doc + 2))) { - return svg_doc; - } - } - return 0; -} - -STBTT_DEF int -stbtt_GetGlyphSVG(const stbtt_fontinfo *info, int gl, const char **svg) -{ - stbtt_uint8 *data = info->data; - stbtt_uint8 *svg_doc; - - if (info->svg == 0) { - return 0; - } - - svg_doc = stbtt_FindSVGDoc(info, gl); - if (svg_doc != NULL) { - *svg = (char *)data + info->svg + ttULONG(svg_doc + 4); - return ttULONG(svg_doc + 8); - } else { - return 0; - } -} - -STBTT_DEF int -stbtt_GetCodepointSVG(const stbtt_fontinfo *info, int unicode_codepoint, const char **svg) -{ - return stbtt_GetGlyphSVG(info, stbtt_FindGlyphIndex(info, unicode_codepoint), svg); -} - -/* //////////////////////////////////////////////////////////////////////////// */ -/* */ -/* antialiasing software rasterizer */ -/* */ - -STBTT_DEF void -stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) -{ - int x0 = 0, y0 = 0, x1, y1; /* =0 suppresses compiler warning */ - if (!stbtt_GetGlyphBox(font, glyph, &x0, &y0, &x1, &y1)) { - /* e.g. space character */ - if (ix0) { - *ix0 = 0; - } - if (iy0) { - *iy0 = 0; - } - if (ix1) { - *ix1 = 0; - } - if (iy1) { - *iy1 = 0; - } - } else { - /* move to integral bboxes (treating pixels as little squares, what pixels get touched)? */ - if (ix0) { - *ix0 = STBTT_ifloor(x0 * scale_x + shift_x); - } - if (iy0) { - *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y); - } - if (ix1) { - *ix1 = STBTT_iceil(x1 * scale_x + shift_x); - } - if (iy1) { - *iy1 = STBTT_iceil(-y0 * scale_y + shift_y); - } - } -} - -STBTT_DEF void -stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1) -{ - stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y, 0.0f, 0.0f, ix0, iy0, ix1, iy1); -} - -STBTT_DEF void -stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) -{ - stbtt_GetGlyphBitmapBoxSubpixel(font, stbtt_FindGlyphIndex(font, codepoint), scale_x, scale_y, shift_x, shift_y, ix0, iy0, ix1, iy1); -} - -STBTT_DEF void -stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1) -{ - stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y, 0.0f, 0.0f, ix0, iy0, ix1, iy1); -} - -/* //////////////////////////////////////////////////////////////////////////// */ -/* */ -/* Rasterizer */ - -typedef struct stbtt__hheap_chunk { - struct stbtt__hheap_chunk *next; -} stbtt__hheap_chunk; - -typedef struct stbtt__hheap { - struct stbtt__hheap_chunk *head; - void *first_free; - int num_remaining_in_head_chunk; -} stbtt__hheap; - -static void * -stbtt__hheap_alloc(stbtt__hheap *hh, size_t size, void *userdata) -{ - if (hh->first_free) { - void *p = hh->first_free; - hh->first_free = *(void **)p; - return p; - } else { - if (hh->num_remaining_in_head_chunk == 0) { - int count = (size < 32 ? 2000 : size < 128 ? 800 : 100); - stbtt__hheap_chunk *c = (stbtt__hheap_chunk *)STBTT_malloc(sizeof(stbtt__hheap_chunk) + size * count, userdata); - if (c == NULL) { - return NULL; - } - c->next = hh->head; - hh->head = c; - hh->num_remaining_in_head_chunk = count; - } - --hh->num_remaining_in_head_chunk; - return (char *)(hh->head) + sizeof(stbtt__hheap_chunk) + size * hh->num_remaining_in_head_chunk; - } -} - -static void -stbtt__hheap_free(stbtt__hheap *hh, void *p) -{ - *(void **)p = hh->first_free; - hh->first_free = p; -} - -static void -stbtt__hheap_cleanup(stbtt__hheap *hh, void *userdata) -{ - stbtt__hheap_chunk *c = hh->head; - while (c) { - stbtt__hheap_chunk *n = c->next; - STBTT_free(c, userdata); - c = n; - } -} - -typedef struct stbtt__edge { - float x0, y0, x1, y1; - int invert; -} stbtt__edge; - -typedef struct stbtt__active_edge { - struct stbtt__active_edge *next; -# if STBTT_RASTERIZER_VERSION == 1 - int x, dx; - float ey; - int direction; -# elif STBTT_RASTERIZER_VERSION == 2 - float fx, fdx, fdy; - float direction; - float sy; - float ey; -# else -# error "Unrecognized value of STBTT_RASTERIZER_VERSION" -# endif -} stbtt__active_edge; - -# if STBTT_RASTERIZER_VERSION == 1 -# define STBTT_FIXSHIFT 10 -# define STBTT_FIX (1 << STBTT_FIXSHIFT) -# define STBTT_FIXMASK (STBTT_FIX - 1) - -static stbtt__active_edge * -stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata) -{ - stbtt__active_edge *z = (stbtt__active_edge *)stbtt__hheap_alloc(hh, sizeof(*z), userdata); - float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); - STBTT_assert(z != NULL); - if (!z) { - return z; - } - - /* round dx down to avoid overshooting */ - if (dxdy < 0) { - z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy); - } else { - z->dx = STBTT_ifloor(STBTT_FIX * dxdy); - } - - z->x = STBTT_ifloor(STBTT_FIX * e->x0 + z->dx * (start_point - e->y0)); /* use z->dx so when we offset later it's by the same amount */ - z->x -= off_x * STBTT_FIX; - - z->ey = e->y1; - z->next = 0; - z->direction = e->invert ? 1 : -1; - return z; -} -# elif STBTT_RASTERIZER_VERSION == 2 -static stbtt__active_edge * -stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata) -{ - stbtt__active_edge *z = (stbtt__active_edge *)stbtt__hheap_alloc(hh, sizeof(*z), userdata); - float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); - STBTT_assert(z != NULL); - /* STBTT_assert(e->y0 <= start_point); */ - if (!z) { - return z; - } - z->fdx = dxdy; - z->fdy = dxdy != 0.0f ? (1.0f / dxdy) : 0.0f; - z->fx = e->x0 + dxdy * (start_point - e->y0); - z->fx -= off_x; - z->direction = e->invert ? 1.0f : -1.0f; - z->sy = e->y0; - z->ey = e->y1; - z->next = 0; - return z; -} -# else -# error "Unrecognized value of STBTT_RASTERIZER_VERSION" -# endif - -# if STBTT_RASTERIZER_VERSION == 1 -/* note: this routine clips fills that extend off the edges... ideally this */ -/* wouldn't happen, but it could happen if the truetype glyph bounding boxes */ -/* are wrong, or if the user supplies a too-small bitmap */ -static void -stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__active_edge *e, int max_weight) -{ - /* non-zero winding fill */ - int x0 = 0, w = 0; - - while (e) { - if (w == 0) { - /* if we're currently at zero, we need to record the edge start point */ - x0 = e->x; - w += e->direction; - } else { - int x1 = e->x; - w += e->direction; - /* if we went to zero, we need to draw */ - if (w == 0) { - int i = x0 >> STBTT_FIXSHIFT; - int j = x1 >> STBTT_FIXSHIFT; - - if (i < len && j >= 0) { - if (i == j) { - /* x0,x1 are the same pixel, so compute combined coverage */ - scanline[i] = scanline[i] + (stbtt_uint8)((x1 - x0) * max_weight >> STBTT_FIXSHIFT); - } else { - if (i >= 0) { /* add antialiasing for x0 */ - scanline[i] = scanline[i] + (stbtt_uint8)(((STBTT_FIX - (x0 & STBTT_FIXMASK)) * max_weight) >> STBTT_FIXSHIFT); - } else { - i = -1; /* clip */ - } - - if (j < len) { /* add antialiasing for x1 */ - scanline[j] = scanline[j] + (stbtt_uint8)(((x1 & STBTT_FIXMASK) * max_weight) >> STBTT_FIXSHIFT); - } else { - j = len; /* clip */ - } - - for (++i; i < j; ++i) { /* fill pixels between x0 and x1 */ - scanline[i] = scanline[i] + (stbtt_uint8)max_weight; - } - } - } - } - } - - e = e->next; - } -} - -static void -stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata) -{ - stbtt__hheap hh = {0, 0, 0}; - stbtt__active_edge *active = NULL; - int y, j = 0; - int max_weight = (255 / vsubsample); /* weight per vertical scanline */ - int s; /* vertical subsample index */ - unsigned char scanline_data[512], *scanline; - - if (result->w > 512) { - scanline = (unsigned char *)STBTT_malloc(result->w, userdata); - } else { - scanline = scanline_data; - } - - y = off_y * vsubsample; - e[n].y0 = (off_y + result->h) * (float)vsubsample + 1; - - while (j < result->h) { - STBTT_memset(scanline, 0, result->w); - for (s = 0; s < vsubsample; ++s) { - /* find center of pixel for this scanline */ - float scan_y = y + 0.5f; - stbtt__active_edge **step = &active; - - /* update all active edges; */ - /* remove all active edges that terminate before the center of this scanline */ - while (*step) { - stbtt__active_edge *z = *step; - if (z->ey <= scan_y) { - *step = z->next; /* delete from list */ - STBTT_assert(z->direction); - z->direction = 0; - stbtt__hheap_free(&hh, z); - } else { - z->x += z->dx; /* advance to position for current scanline */ - step = &((*step)->next); /* advance through list */ - } - } - - /* resort the list if needed */ - for (;;) { - int changed = 0; - step = &active; - while (*step && (*step)->next) { - if ((*step)->x > (*step)->next->x) { - stbtt__active_edge *t = *step; - stbtt__active_edge *q = t->next; - - t->next = q->next; - q->next = t; - *step = q; - changed = 1; - } - step = &(*step)->next; - } - if (!changed) { - break; - } - } - - /* insert all edges that start before the center of this scanline -- omit ones that also end on this scanline */ - while (e->y0 <= scan_y) { - if (e->y1 > scan_y) { - stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y, userdata); - if (z != NULL) { - /* find insertion point */ - if (active == NULL) { - active = z; - } else if (z->x < active->x) { - /* insert at front */ - z->next = active; - active = z; - } else { - /* find thing to insert AFTER */ - stbtt__active_edge *p = active; - while (p->next && p->next->x < z->x) { - p = p->next; - } - /* at this point, p->next->x is NOT < z->x */ - z->next = p->next; - p->next = z; - } - } - } - ++e; - } - - /* now process all active edges in XOR fashion */ - if (active) { - stbtt__fill_active_edges(scanline, result->w, active, max_weight); - } - - ++y; - } - STBTT_memcpy(result->pixels + j * result->stride, scanline, result->w); - ++j; - } - - stbtt__hheap_cleanup(&hh, userdata); - - if (scanline != scanline_data) { - STBTT_free(scanline, userdata); - } -} - -# elif STBTT_RASTERIZER_VERSION == 2 - -/* the edge passed in here does not cross the vertical line at x or the vertical line at x+1 */ -/* (i.e. it has already been clipped to those) */ -static void -stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edge *e, float x0, float y0, float x1, float y1) -{ - if (y0 == y1) { - return; - } - STBTT_assert(y0 < y1); - STBTT_assert(e->sy <= e->ey); - if (y0 > e->ey) { - return; - } - if (y1 < e->sy) { - return; - } - if (y0 < e->sy) { - x0 += (x1 - x0) * (e->sy - y0) / (y1 - y0); - y0 = e->sy; - } - if (y1 > e->ey) { - x1 += (x1 - x0) * (e->ey - y1) / (y1 - y0); - y1 = e->ey; - } - - if (x0 == x) { - STBTT_assert(x1 <= x + 1); - } else if (x0 == x + 1) { - STBTT_assert(x1 >= x); - } else if (x0 <= x) { - STBTT_assert(x1 <= x); - } else if (x0 >= x + 1) { - STBTT_assert(x1 >= x + 1); - } else { - STBTT_assert(x1 >= x && x1 <= x + 1); - } - - if (x0 <= x && x1 <= x) { - scanline[x] += e->direction * (y1 - y0); - } else if (x0 >= x + 1 && x1 >= x + 1) - ; - else { - STBTT_assert(x0 >= x && x0 <= x + 1 && x1 >= x && x1 <= x + 1); - scanline[x] += e->direction * (y1 - y0) * (1 - ((x0 - x) + (x1 - x)) / 2); /* coverage = 1 - average x position */ - } -} - -static float -stbtt__sized_trapezoid_area(float height, float top_width, float bottom_width) -{ - STBTT_assert(top_width >= 0); - STBTT_assert(bottom_width >= 0); - return (top_width + bottom_width) / 2.0f * height; -} - -static float -stbtt__position_trapezoid_area(float height, float tx0, float tx1, float bx0, float bx1) -{ - return stbtt__sized_trapezoid_area(height, tx1 - tx0, bx1 - bx0); -} - -static float -stbtt__sized_triangle_area(float height, float width) -{ - return height * width / 2; -} - -static void -stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, int len, stbtt__active_edge *e, float y_top) -{ - float y_bottom = y_top + 1; - - while (e) { - /* brute force every pixel */ - - /* compute intersection points with top & bottom */ - STBTT_assert(e->ey >= y_top); - - if (e->fdx == 0) { - float x0 = e->fx; - if (x0 < len) { - if (x0 >= 0) { - stbtt__handle_clipped_edge(scanline, (int)x0, e, x0, y_top, x0, y_bottom); - stbtt__handle_clipped_edge(scanline_fill - 1, (int)x0 + 1, e, x0, y_top, x0, y_bottom); - } else { - stbtt__handle_clipped_edge(scanline_fill - 1, 0, e, x0, y_top, x0, y_bottom); - } - } - } else { - float x0 = e->fx; - float dx = e->fdx; - float xb = x0 + dx; - float x_top, x_bottom; - float sy0, sy1; - float dy = e->fdy; - STBTT_assert(e->sy <= y_bottom && e->ey >= y_top); - - /* compute endpoints of line segment clipped to this scanline (if the */ - /* line segment starts on this scanline. x0 is the intersection of the */ - /* line with y_top, but that may be off the line segment. */ - if (e->sy > y_top) { - x_top = x0 + dx * (e->sy - y_top); - sy0 = e->sy; - } else { - x_top = x0; - sy0 = y_top; - } - if (e->ey < y_bottom) { - x_bottom = x0 + dx * (e->ey - y_top); - sy1 = e->ey; - } else { - x_bottom = xb; - sy1 = y_bottom; - } - - if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) { - /* from here on, we don't have to range check x values */ - - if ((int)x_top == (int)x_bottom) { - float height; - /* simple case, only spans one pixel */ - int x = (int)x_top; - height = (sy1 - sy0) * e->direction; - STBTT_assert(x >= 0 && x < len); - scanline[x] += stbtt__position_trapezoid_area(height, x_top, x + 1.0f, x_bottom, x + 1.0f); - scanline_fill[x] += height; /* everything right of this pixel is filled */ - } else { - int x, x1, x2; - float y_crossing, y_final, step, sign, area; - /* covers 2+ pixels */ - if (x_top > x_bottom) { - /* flip scanline vertically; signed area is the same */ - float t; - sy0 = y_bottom - (sy0 - y_top); - sy1 = y_bottom - (sy1 - y_top); - t = sy0, sy0 = sy1, sy1 = t; - t = x_bottom, x_bottom = x_top, x_top = t; - dx = -dx; - dy = -dy; - t = x0, x0 = xb, xb = t; - } - STBTT_assert(dy >= 0); - STBTT_assert(dx >= 0); - - x1 = (int)x_top; - x2 = (int)x_bottom; - /* compute intersection with y axis at x1+1 */ - y_crossing = y_top + dy * (x1 + 1 - x0); - - /* compute intersection with y axis at x2 */ - y_final = y_top + dy * (x2 - x0); - - /* x1 x_top x2 x_bottom */ - /* y_top +------|-----+------------+------------+--------|---+------------+ */ - /* | | | | | | */ - /* | | | | | | */ - /* sy0 | Txxxxx|............|............|............|............| */ - /* y_crossing | *xxxxx.......|............|............|............| */ - /* | | xxxxx..|............|............|............| */ - /* | | /- xx*xxxx........|............|............| */ - /* | | dy < | xxxxxx..|............|............| */ - /* y_final | | \- | xx*xxx.........|............| */ - /* sy1 | | | | xxxxxB...|............| */ - /* | | | | | | */ - /* | | | | | | */ - /* y_bottom +------------+------------+------------+------------+------------+ */ - /* */ - /* goal is to measure the area covered by '.' in each pixel */ - - /* if x2 is right at the right edge of x1, y_crossing can blow up, github #1057 */ - /* @TODO: maybe test against sy1 rather than y_bottom? */ - if (y_crossing > y_bottom) { - y_crossing = y_bottom; - } - - sign = e->direction; - - /* area of the rectangle covered from sy0..y_crossing */ - area = sign * (y_crossing - sy0); - - /* area of the triangle (x_top,sy0), (x1+1,sy0), (x1+1,y_crossing) */ - scanline[x1] += stbtt__sized_triangle_area(area, x1 + 1 - x_top); - - /* check if final y_crossing is blown up; no test case for this */ - if (y_final > y_bottom) { - y_final = y_bottom; - dy = (y_final - y_crossing) / (x2 - (x1 + 1)); /* if denom=0, y_final = y_crossing, so y_final <= y_bottom */ - } - - /* in second pixel, area covered by line segment found in first pixel */ - /* is always a rectangle 1 wide * the height of that line segment; this */ - /* is exactly what the variable 'area' stores. it also gets a contribution */ - /* from the line segment within it. the THIRD pixel will get the first */ - /* pixel's rectangle contribution, the second pixel's rectangle contribution, */ - /* and its own contribution. the 'own contribution' is the same in every pixel except */ - /* the leftmost and rightmost, a trapezoid that slides down in each pixel. */ - /* the second pixel's contribution to the third pixel will be the */ - /* rectangle 1 wide times the height change in the second pixel, which is dy. */ - - step = sign * dy * 1; /* dy is dy/dx, change in y for every 1 change in x, */ - /* which multiplied by 1-pixel-width is how much pixel area changes for each step in x */ - /* so the area advances by 'step' every time */ - - for (x = x1 + 1; x < x2; ++x) { - scanline[x] += area + step / 2; /* area of trapezoid is 1*step/2 */ - area += step; - } - STBTT_assert(STBTT_fabs(area) <= 1.01f); /* accumulated error from area += step unless we round step down */ - STBTT_assert(sy1 > y_final - 0.01f); - - /* area covered in the last pixel is the rectangle from all the pixels to the left, */ - /* plus the trapezoid filled by the line segment in this pixel all the way to the right edge */ - scanline[x2] += area + sign * stbtt__position_trapezoid_area(sy1 - y_final, (float)x2, x2 + 1.0f, x_bottom, x2 + 1.0f); - - /* the rest of the line is filled based on the total height of the line segment in this pixel */ - scanline_fill[x2] += sign * (sy1 - sy0); - } - } else { - /* if edge goes outside of box we're drawing, we require */ - /* clipping logic. since this does not match the intended use */ - /* of this library, we use a different, very slow brute */ - /* force implementation */ - /* note though that this does happen some of the time because */ - /* x_top and x_bottom can be extrapolated at the top & bottom of */ - /* the shape and actually lie outside the bounding box */ - int x; - for (x = 0; x < len; ++x) { - /* cases: */ - /* */ - /* there can be up to two intersections with the pixel. any intersection */ - /* with left or right edges can be handled by splitting into two (or three) */ - /* regions. intersections with top & bottom do not necessitate case-wise logic. */ - /* */ - /* the old way of doing this found the intersections with the left & right edges, */ - /* then used some simple logic to produce up to three segments in sorted order */ - /* from top-to-bottom. however, this had a problem: if an x edge was epsilon */ - /* across the x border, then the corresponding y position might not be distinct */ - /* from the other y segment, and it might ignored as an empty segment. to avoid */ - /* that, we need to explicitly produce segments based on x positions. */ - - /* rename variables to clearly-defined pairs */ - float y0 = y_top; - float x1 = (float)(x); - float x2 = (float)(x + 1); - float x3 = xb; - float y3 = y_bottom; - - /* x = e->x + e->dx * (y-y_top) */ - /* (y-y_top) = (x - e->x) / e->dx */ - /* y = (x - e->x) / e->dx + y_top */ - float y1 = (x - x0) / dx + y_top; - float y2 = (x + 1 - x0) / dx + y_top; - - if (x0 < x1 && x3 > x2) { /* three segments descending down-right */ - stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x1, y1); - stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x2, y2); - stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x3, y3); - } else if (x3 < x1 && x0 > x2) { /* three segments descending down-left */ - stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x2, y2); - stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x1, y1); - stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x3, y3); - } else if (x0 < x1 && x3 > x1) { /* two segments across x, down-right */ - stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x1, y1); - stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x3, y3); - } else if (x3 < x1 && x0 > x1) { /* two segments across x, down-left */ - stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x1, y1); - stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x3, y3); - } else if (x0 < x2 && x3 > x2) { /* two segments across x+1, down-right */ - stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x2, y2); - stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x3, y3); - } else if (x3 < x2 && x0 > x2) { /* two segments across x+1, down-left */ - stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x2, y2); - stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x3, y3); - } else { /* one segment */ - stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x3, y3); - } - } - } - } - e = e->next; - } -} - -/* directly AA rasterize edges w/o supersampling */ -static void -stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata) -{ - stbtt__hheap hh = {0, 0, 0}; - stbtt__active_edge *active = NULL; - int y, j = 0, i; - float scanline_data[129], *scanline, *scanline2; - - STBTT__NOTUSED(vsubsample); - - if (result->w > 64) { - scanline = (float *)STBTT_malloc((result->w * 2 + 1) * sizeof(float), userdata); - } else { - scanline = scanline_data; - } - - scanline2 = scanline + result->w; - - y = off_y; - e[n].y0 = (float)(off_y + result->h) + 1; - - while (j < result->h) { - /* find center of pixel for this scanline */ - float scan_y_top = y + 0.0f; - float scan_y_bottom = y + 1.0f; - stbtt__active_edge **step = &active; - - STBTT_memset(scanline, 0, result->w * sizeof(scanline[0])); - STBTT_memset(scanline2, 0, (result->w + 1) * sizeof(scanline[0])); - - /* update all active edges; */ - /* remove all active edges that terminate before the top of this scanline */ - while (*step) { - stbtt__active_edge *z = *step; - if (z->ey <= scan_y_top) { - *step = z->next; /* delete from list */ - STBTT_assert(z->direction); - z->direction = 0; - stbtt__hheap_free(&hh, z); - } else { - step = &((*step)->next); /* advance through list */ - } - } - - /* insert all edges that start before the bottom of this scanline */ - while (e->y0 <= scan_y_bottom) { - if (e->y0 != e->y1) { - stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata); - if (z != NULL) { - if (j == 0 && off_y != 0) { - if (z->ey < scan_y_top) { - /* this can happen due to subpixel positioning and some kind of fp rounding error i think */ - z->ey = scan_y_top; - } - } - STBTT_assert(z->ey >= scan_y_top); /* if we get really unlucky a tiny bit of an edge can be out of bounds */ - /* insert at front */ - z->next = active; - active = z; - } - } - ++e; - } - - /* now process all active edges */ - if (active) { - stbtt__fill_active_edges_new(scanline, scanline2 + 1, result->w, active, scan_y_top); - } - - { - float sum = 0; - for (i = 0; i < result->w; ++i) { - float k; - int m; - sum += scanline2[i]; - k = scanline[i] + sum; - k = (float)STBTT_fabs(k) * 255 + 0.5f; - m = (int)k; - if (m > 255) { - m = 255; - } - result->pixels[j * result->stride + i] = (unsigned char)m; - } - } - /* advance all the edges */ - step = &active; - while (*step) { - stbtt__active_edge *z = *step; - z->fx += z->fdx; /* advance to position for current scanline */ - step = &((*step)->next); /* advance through list */ - } - - ++y; - ++j; - } - - stbtt__hheap_cleanup(&hh, userdata); - - if (scanline != scanline_data) { - STBTT_free(scanline, userdata); - } -} -# else -# error "Unrecognized value of STBTT_RASTERIZER_VERSION" -# endif - -# define STBTT__COMPARE(a, b) ((a)->y0 < (b)->y0) - -static void -stbtt__sort_edges_ins_sort(stbtt__edge *p, int n) -{ - int i, j; - for (i = 1; i < n; ++i) { - stbtt__edge t = p[i], *a = &t; - j = i; - while (j > 0) { - stbtt__edge *b = &p[j - 1]; - int c = STBTT__COMPARE(a, b); - if (!c) { - break; - } - p[j] = p[j - 1]; - --j; - } - if (i != j) { - p[j] = t; - } - } -} - -static void -stbtt__sort_edges_quicksort(stbtt__edge *p, int n) -{ - /* threshold for transitioning to insertion sort */ - while (n > 12) { - stbtt__edge t; - int c01, c12, c, m, i, j; - - /* compute median of three */ - m = n >> 1; - c01 = STBTT__COMPARE(&p[0], &p[m]); - c12 = STBTT__COMPARE(&p[m], &p[n - 1]); - /* if 0 >= mid >= end, or 0 < mid < end, then use mid */ - if (c01 != c12) { - /* otherwise, we'll need to swap something else to middle */ - int z; - c = STBTT__COMPARE(&p[0], &p[n - 1]); - /* 0>mid && midn => n; 0 0 */ - /* 0n: 0>n => 0; 0 n */ - z = (c == c12) ? 0 : n - 1; - t = p[z]; - p[z] = p[m]; - p[m] = t; - } - /* now p[m] is the median-of-three */ - /* swap it to the beginning so it won't move around */ - t = p[0]; - p[0] = p[m]; - p[m] = t; - - /* partition loop */ - i = 1; - j = n - 1; - for (;;) { - /* handling of equality is crucial here */ - /* for sentinels & efficiency with duplicates */ - for (;; ++i) { - if (!STBTT__COMPARE(&p[i], &p[0])) { - break; - } - } - for (;; --j) { - if (!STBTT__COMPARE(&p[0], &p[j])) { - break; - } - } - /* make sure we haven't crossed */ - if (i >= j) { - break; - } - t = p[i]; - p[i] = p[j]; - p[j] = t; - - ++i; - --j; - } - /* recurse on smaller side, iterate on larger */ - if (j < (n - i)) { - stbtt__sort_edges_quicksort(p, j); - p = p + i; - n = n - i; - } else { - stbtt__sort_edges_quicksort(p + i, n - i); - n = j; - } - } -} - -static void -stbtt__sort_edges(stbtt__edge *p, int n) -{ - stbtt__sort_edges_quicksort(p, n); - stbtt__sort_edges_ins_sort(p, n); -} - -typedef struct { - float x, y; -} stbtt__point; - -static void -stbtt__rasterize( - stbtt__bitmap *result, stbtt__point *pts, int *wcount, int windings, float scale_x, float scale_y, float shift_x, float shift_y, int off_x, int off_y, int invert, void *userdata) -{ - float y_scale_inv = invert ? -scale_y : scale_y; - stbtt__edge *e; - int n, i, j, k, m; -# if STBTT_RASTERIZER_VERSION == 1 - int vsubsample = result->h < 8 ? 15 : 5; -# elif STBTT_RASTERIZER_VERSION == 2 - int vsubsample = 1; -# else -# error "Unrecognized value of STBTT_RASTERIZER_VERSION" -# endif - /* vsubsample should divide 255 evenly; otherwise we won't reach full opacity */ - - /* now we have to blow out the windings into explicit edge lists */ - n = 0; - for (i = 0; i < windings; ++i) { - n += wcount[i]; - } - - e = (stbtt__edge *)STBTT_malloc(sizeof(*e) * (n + 1), userdata); /* add an extra one as a sentinel */ - if (e == 0) { - return; - } - n = 0; - - m = 0; - for (i = 0; i < windings; ++i) { - stbtt__point *p = pts + m; - m += wcount[i]; - j = wcount[i] - 1; - for (k = 0; k < wcount[i]; j = k++) { - int a = k, b = j; - /* skip the edge if horizontal */ - if (p[j].y == p[k].y) { - continue; - } - /* add edge from j to k to the list */ - e[n].invert = 0; - if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) { - e[n].invert = 1; - a = j, b = k; - } - e[n].x0 = p[a].x * scale_x + shift_x; - e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample; - e[n].x1 = p[b].x * scale_x + shift_x; - e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample; - ++n; - } - } - - /* now sort the edges by their highest point (should snap to integer, and then by x) */ - /* STBTT_sort(e, n, sizeof(e[0]), stbtt__edge_compare); */ - stbtt__sort_edges(e, n); - - /* now, traverse the scanlines and find the intersections on each scanline, use xor winding rule */ - stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata); - - STBTT_free(e, userdata); -} - -static void -stbtt__add_point(stbtt__point *points, int n, float x, float y) -{ - if (!points) { - return; /* during first pass, it's unallocated */ - } - points[n].x = x; - points[n].y = y; -} - -/* tessellate until threshold p is happy... @TODO warped to compensate for non-linear stretching */ -static int -stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n) -{ - /* midpoint */ - float mx = (x0 + 2 * x1 + x2) / 4; - float my = (y0 + 2 * y1 + y2) / 4; - /* versus directly drawn line */ - float dx = (x0 + x2) / 2 - mx; - float dy = (y0 + y2) / 2 - my; - if (n > 16) { /* 65536 segments on one curve better be enough! */ - return 1; - } - if (dx * dx + dy * dy > objspace_flatness_squared) { /* half-pixel error allowed... need to be smaller if AA */ - stbtt__tesselate_curve(points, num_points, x0, y0, (x0 + x1) / 2.0f, (y0 + y1) / 2.0f, mx, my, objspace_flatness_squared, n + 1); - stbtt__tesselate_curve(points, num_points, mx, my, (x1 + x2) / 2.0f, (y1 + y2) / 2.0f, x2, y2, objspace_flatness_squared, n + 1); - } else { - stbtt__add_point(points, *num_points, x2, y2); - *num_points = *num_points + 1; - } - return 1; -} - -static void -stbtt__tesselate_cubic( - stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float objspace_flatness_squared, int n) -{ - /* @TODO this "flatness" calculation is just made-up nonsense that seems to work well enough */ - float dx0 = x1 - x0; - float dy0 = y1 - y0; - float dx1 = x2 - x1; - float dy1 = y2 - y1; - float dx2 = x3 - x2; - float dy2 = y3 - y2; - float dx = x3 - x0; - float dy = y3 - y0; - float longlen = (float)(STBTT_sqrt(dx0 * dx0 + dy0 * dy0) + STBTT_sqrt(dx1 * dx1 + dy1 * dy1) + STBTT_sqrt(dx2 * dx2 + dy2 * dy2)); - float shortlen = (float)STBTT_sqrt(dx * dx + dy * dy); - float flatness_squared = longlen * longlen - shortlen * shortlen; - - if (n > 16) { /* 65536 segments on one curve better be enough! */ - return; - } - - if (flatness_squared > objspace_flatness_squared) { - float x01 = (x0 + x1) / 2; - float y01 = (y0 + y1) / 2; - float x12 = (x1 + x2) / 2; - float y12 = (y1 + y2) / 2; - float x23 = (x2 + x3) / 2; - float y23 = (y2 + y3) / 2; - - float xa = (x01 + x12) / 2; - float ya = (y01 + y12) / 2; - float xb = (x12 + x23) / 2; - float yb = (y12 + y23) / 2; - - float mx = (xa + xb) / 2; - float my = (ya + yb) / 2; - - stbtt__tesselate_cubic(points, num_points, x0, y0, x01, y01, xa, ya, mx, my, objspace_flatness_squared, n + 1); - stbtt__tesselate_cubic(points, num_points, mx, my, xb, yb, x23, y23, x3, y3, objspace_flatness_squared, n + 1); - } else { - stbtt__add_point(points, *num_points, x3, y3); - *num_points = *num_points + 1; - } -} - -/* returns number of contours */ -static stbtt__point * -stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata) -{ - stbtt__point *points = 0; - int num_points = 0; - - float objspace_flatness_squared = objspace_flatness * objspace_flatness; - int i, n = 0, start = 0, pass; - - /* count how many "moves" there are to get the contour count */ - for (i = 0; i < num_verts; ++i) { - if (vertices[i].type == STBTT_vmove) { - ++n; - } - } - - *num_contours = n; - if (n == 0) { - return 0; - } - - *contour_lengths = (int *)STBTT_malloc(sizeof(**contour_lengths) * n, userdata); - - if (*contour_lengths == 0) { - *num_contours = 0; - return 0; - } - - /* make two passes through the points so we don't need to realloc */ - for (pass = 0; pass < 2; ++pass) { - float x = 0, y = 0; - if (pass == 1) { - points = (stbtt__point *)STBTT_malloc(num_points * sizeof(points[0]), userdata); - if (points == NULL) { - goto error; - } - } - num_points = 0; - n = -1; - for (i = 0; i < num_verts; ++i) { - switch (vertices[i].type) { - case STBTT_vmove: - /* start the next contour */ - if (n >= 0) { - (*contour_lengths)[n] = num_points - start; - } - ++n; - start = num_points; - - x = vertices[i].x, y = vertices[i].y; - stbtt__add_point(points, num_points++, x, y); - break; - case STBTT_vline: - x = vertices[i].x, y = vertices[i].y; - stbtt__add_point(points, num_points++, x, y); - break; - case STBTT_vcurve: - stbtt__tesselate_curve(points, &num_points, x, y, vertices[i].cx, vertices[i].cy, vertices[i].x, vertices[i].y, objspace_flatness_squared, 0); - x = vertices[i].x, y = vertices[i].y; - break; - case STBTT_vcubic: - stbtt__tesselate_cubic( - points, &num_points, x, y, vertices[i].cx, vertices[i].cy, vertices[i].cx1, vertices[i].cy1, vertices[i].x, vertices[i].y, objspace_flatness_squared, 0); - x = vertices[i].x, y = vertices[i].y; - break; - } - } - (*contour_lengths)[n] = num_points - start; - } - - return points; -error: - STBTT_free(points, userdata); - STBTT_free(*contour_lengths, userdata); - *contour_lengths = 0; - *num_contours = 0; - return NULL; -} - -STBTT_DEF void -stbtt_Rasterize(stbtt__bitmap *result, - float flatness_in_pixels, - stbtt_vertex *vertices, - int num_verts, - float scale_x, - float scale_y, - float shift_x, - float shift_y, - int x_off, - int y_off, - int invert, - void *userdata) -{ - float scale = scale_x > scale_y ? scale_y : scale_x; - int winding_count = 0; - int *winding_lengths = NULL; - stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata); - if (windings) { - stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata); - STBTT_free(winding_lengths, userdata); - STBTT_free(windings, userdata); - } -} - -STBTT_DEF void -stbtt_FreeBitmap(unsigned char *bitmap, void *userdata) -{ - STBTT_free(bitmap, userdata); -} - -STBTT_DEF unsigned char * -stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff) -{ - int ix0, iy0, ix1, iy1; - stbtt__bitmap gbm; - stbtt_vertex *vertices; - int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); - - if (scale_x == 0) { - scale_x = scale_y; - } - if (scale_y == 0) { - if (scale_x == 0) { - STBTT_free(vertices, info->userdata); - return NULL; - } - scale_y = scale_x; - } - - stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0, &iy0, &ix1, &iy1); - - /* now we get the size */ - gbm.w = (ix1 - ix0); - gbm.h = (iy1 - iy0); - gbm.pixels = NULL; /* in case we error */ - - if (width) { - *width = gbm.w; - } - if (height) { - *height = gbm.h; - } - if (xoff) { - *xoff = ix0; - } - if (yoff) { - *yoff = iy0; - } - - if (gbm.w && gbm.h) { - gbm.pixels = (unsigned char *)STBTT_malloc(gbm.w * gbm.h, info->userdata); - if (gbm.pixels) { - gbm.stride = gbm.w; - - stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata); - } - } - STBTT_free(vertices, info->userdata); - return gbm.pixels; -} - -STBTT_DEF unsigned char * -stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff) -{ - return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, glyph, width, height, xoff, yoff); -} - -STBTT_DEF void -stbtt_MakeGlyphBitmapSubpixel( - const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph) -{ - int ix0, iy0; - stbtt_vertex *vertices; - int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); - stbtt__bitmap gbm; - - stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0, &iy0, 0, 0); - gbm.pixels = output; - gbm.w = out_w; - gbm.h = out_h; - gbm.stride = out_stride; - - if (gbm.w && gbm.h) { - stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata); - } - - STBTT_free(vertices, info->userdata); -} - -STBTT_DEF void -stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph) -{ - stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f, 0.0f, glyph); -} - -STBTT_DEF unsigned char * -stbtt_GetCodepointBitmapSubpixel( - const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff) -{ - return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info, codepoint), width, height, xoff, yoff); -} - -STBTT_DEF void -stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo *info, - unsigned char *output, - int out_w, - int out_h, - int out_stride, - float scale_x, - float scale_y, - float shift_x, - float shift_y, - int oversample_x, - int oversample_y, - float *sub_x, - float *sub_y, - int codepoint) -{ - stbtt_MakeGlyphBitmapSubpixelPrefilter( - info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, oversample_x, oversample_y, sub_x, sub_y, stbtt_FindGlyphIndex(info, codepoint)); -} - -STBTT_DEF void -stbtt_MakeCodepointBitmapSubpixel( - const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint) -{ - stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info, codepoint)); -} - -STBTT_DEF unsigned char * -stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff) -{ - return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, codepoint, width, height, xoff, yoff); -} - -STBTT_DEF void -stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint) -{ - stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f, 0.0f, codepoint); -} - -/* //////////////////////////////////////////////////////////////////////////// */ -/* */ -/* bitmap baking */ -/* */ -/* This is SUPER-CRAPPY packing to keep source code small */ - -static int -stbtt_BakeFontBitmap_internal(unsigned char *data, - int offset, /* font location (use offset=0 for plain .ttf) */ - float pixel_height, /* height of font in pixels */ - unsigned char *pixels, - int pw, - int ph, /* bitmap to be filled in */ - int first_char, - int num_chars, /* characters to bake */ - stbtt_bakedchar *chardata) -{ - float scale; - int x, y, bottom_y, i; - stbtt_fontinfo f; - f.userdata = NULL; - if (!stbtt_InitFont(&f, data, offset)) { - return -1; - } - STBTT_memset(pixels, 0, pw * ph); /* background of 0 around pixels */ - x = y = 1; - bottom_y = 1; - - scale = stbtt_ScaleForPixelHeight(&f, pixel_height); - - for (i = 0; i < num_chars; ++i) { - int advance, lsb, x0, y0, x1, y1, gw, gh; - int g = stbtt_FindGlyphIndex(&f, first_char + i); - stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb); - stbtt_GetGlyphBitmapBox(&f, g, scale, scale, &x0, &y0, &x1, &y1); - gw = x1 - x0; - gh = y1 - y0; - if (x + gw + 1 >= pw) { - y = bottom_y, x = 1; /* advance to next row */ - } - if (y + gh + 1 >= ph) { /* check if it fits vertically AFTER potentially moving to next row */ - return -i; - } - STBTT_assert(x + gw < pw); - STBTT_assert(y + gh < ph); - stbtt_MakeGlyphBitmap(&f, pixels + x + y * pw, gw, gh, pw, scale, scale, g); - chardata[i].x0 = (stbtt_int16)x; - chardata[i].y0 = (stbtt_int16)y; - chardata[i].x1 = (stbtt_int16)(x + gw); - chardata[i].y1 = (stbtt_int16)(y + gh); - chardata[i].xadvance = scale * advance; - chardata[i].xoff = (float)x0; - chardata[i].yoff = (float)y0; - x = x + gw + 1; - if (y + gh + 1 > bottom_y) { - bottom_y = y + gh + 1; - } - } - return bottom_y; -} - -STBTT_DEF void -stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule) -{ - float d3d_bias = opengl_fillrule ? 0 : -0.5f; - float ipw = 1.0f / pw, iph = 1.0f / ph; - const stbtt_bakedchar *b = chardata + char_index; - int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5f); - int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5f); - - q->x0 = round_x + d3d_bias; - q->y0 = round_y + d3d_bias; - q->x1 = round_x + b->x1 - b->x0 + d3d_bias; - q->y1 = round_y + b->y1 - b->y0 + d3d_bias; - - q->s0 = b->x0 * ipw; - q->t0 = b->y0 * iph; - q->s1 = b->x1 * ipw; - q->t1 = b->y1 * iph; - - *xpos += b->xadvance; -} - -/* //////////////////////////////////////////////////////////////////////////// */ -/* */ -/* rectangle packing replacement routines if you don't have stb_rect_pack.h */ -/* */ - -# ifndef STB_RECT_PACK_VERSION - -typedef int stbrp_coord; - -/* ////////////////////////////////////////////////////////////////////////////////// */ -/* // */ -/* // */ -/* COMPILER WARNING ?!?!? // */ -/* // */ -/* // */ -/* if you get a compile warning due to these symbols being defined more than // */ -/* once, move #include "stb_rect_pack.h" before #include "stb_truetype.h" // */ -/* // */ -/* ////////////////////////////////////////////////////////////////////////////////// */ - -typedef struct { - int width, height; - int x, y, bottom_y; -} stbrp_context; - -typedef struct { - unsigned char x; -} stbrp_node; - -struct stbrp_rect { - stbrp_coord x, y; - int id, w, h, was_packed; -}; - -static void -stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_node *nodes, int num_nodes) -{ - con->width = pw; - con->height = ph; - con->x = 0; - con->y = 0; - con->bottom_y = 0; - STBTT__NOTUSED(nodes); - STBTT__NOTUSED(num_nodes); -} - -static void -stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects) -{ - int i; - for (i = 0; i < num_rects; ++i) { - if (con->x + rects[i].w > con->width) { - con->x = 0; - con->y = con->bottom_y; - } - if (con->y + rects[i].h > con->height) { - break; - } - rects[i].x = con->x; - rects[i].y = con->y; - rects[i].was_packed = 1; - con->x += rects[i].w; - if (con->y + rects[i].h > con->bottom_y) { - con->bottom_y = con->y + rects[i].h; - } - } - for (; i < num_rects; ++i) { - rects[i].was_packed = 0; - } -} -# endif - -/* //////////////////////////////////////////////////////////////////////////// */ -/* */ -/* bitmap baking */ -/* */ -/* This is SUPER-AWESOME (tm Ryan Gordon) packing using stb_rect_pack.h. If */ -/* stb_rect_pack.h isn't available, it uses the BakeFontBitmap strategy. */ - -STBTT_DEF int -stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int pw, int ph, int stride_in_bytes, int padding, void *alloc_context) -{ - stbrp_context *context = (stbrp_context *)STBTT_malloc(sizeof(*context), alloc_context); - int num_nodes = pw - padding; - stbrp_node *nodes = (stbrp_node *)STBTT_malloc(sizeof(*nodes) * num_nodes, alloc_context); - - if (context == NULL || nodes == NULL) { - if (context != NULL) { - STBTT_free(context, alloc_context); - } - if (nodes != NULL) { - STBTT_free(nodes, alloc_context); - } - return 0; - } - - spc->user_allocator_context = alloc_context; - spc->width = pw; - spc->height = ph; - spc->pixels = pixels; - spc->pack_info = context; - spc->nodes = nodes; - spc->padding = padding; - spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw; - spc->h_oversample = 1; - spc->v_oversample = 1; - spc->skip_missing = 0; - - stbrp_init_target(context, pw - padding, ph - padding, nodes, num_nodes); - - if (pixels) { - STBTT_memset(pixels, 0, pw * ph); /* background of 0 around pixels */ - } - - return 1; -} - -STBTT_DEF void -stbtt_PackEnd(stbtt_pack_context *spc) -{ - STBTT_free(spc->nodes, spc->user_allocator_context); - STBTT_free(spc->pack_info, spc->user_allocator_context); -} - -STBTT_DEF void -stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample) -{ - STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE); - STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE); - if (h_oversample <= STBTT_MAX_OVERSAMPLE) { - spc->h_oversample = h_oversample; - } - if (v_oversample <= STBTT_MAX_OVERSAMPLE) { - spc->v_oversample = v_oversample; - } -} - -STBTT_DEF void -stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip) -{ - spc->skip_missing = skip; -} - -# define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE - 1) - -static void -stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) -{ - unsigned char buffer[STBTT_MAX_OVERSAMPLE]; - int safe_w = w - kernel_width; - int j; - STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); /* suppress bogus warning from VS2013 -analyze */ - for (j = 0; j < h; ++j) { - int i; - unsigned int total; - STBTT_memset(buffer, 0, kernel_width); - - total = 0; - - /* make kernel_width a constant in common cases so compiler can optimize out the divide */ - switch (kernel_width) { - case 2: - for (i = 0; i <= safe_w; ++i) { - total += pixels[i] - buffer[i & STBTT__OVER_MASK]; - buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i]; - pixels[i] = (unsigned char)(total / 2); - } - break; - case 3: - for (i = 0; i <= safe_w; ++i) { - total += pixels[i] - buffer[i & STBTT__OVER_MASK]; - buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i]; - pixels[i] = (unsigned char)(total / 3); - } - break; - case 4: - for (i = 0; i <= safe_w; ++i) { - total += pixels[i] - buffer[i & STBTT__OVER_MASK]; - buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i]; - pixels[i] = (unsigned char)(total / 4); - } - break; - case 5: - for (i = 0; i <= safe_w; ++i) { - total += pixels[i] - buffer[i & STBTT__OVER_MASK]; - buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i]; - pixels[i] = (unsigned char)(total / 5); - } - break; - default: - for (i = 0; i <= safe_w; ++i) { - total += pixels[i] - buffer[i & STBTT__OVER_MASK]; - buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i]; - pixels[i] = (unsigned char)(total / kernel_width); - } - break; - } - - for (; i < w; ++i) { - STBTT_assert(pixels[i] == 0); - total -= buffer[i & STBTT__OVER_MASK]; - pixels[i] = (unsigned char)(total / kernel_width); - } - - pixels += stride_in_bytes; - } -} - -static void -stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) -{ - unsigned char buffer[STBTT_MAX_OVERSAMPLE]; - int safe_h = h - kernel_width; - int j; - STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); /* suppress bogus warning from VS2013 -analyze */ - for (j = 0; j < w; ++j) { - int i; - unsigned int total; - STBTT_memset(buffer, 0, kernel_width); - - total = 0; - - /* make kernel_width a constant in common cases so compiler can optimize out the divide */ - switch (kernel_width) { - case 2: - for (i = 0; i <= safe_h; ++i) { - total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; - buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes]; - pixels[i * stride_in_bytes] = (unsigned char)(total / 2); - } - break; - case 3: - for (i = 0; i <= safe_h; ++i) { - total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; - buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes]; - pixels[i * stride_in_bytes] = (unsigned char)(total / 3); - } - break; - case 4: - for (i = 0; i <= safe_h; ++i) { - total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; - buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes]; - pixels[i * stride_in_bytes] = (unsigned char)(total / 4); - } - break; - case 5: - for (i = 0; i <= safe_h; ++i) { - total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; - buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes]; - pixels[i * stride_in_bytes] = (unsigned char)(total / 5); - } - break; - default: - for (i = 0; i <= safe_h; ++i) { - total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; - buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes]; - pixels[i * stride_in_bytes] = (unsigned char)(total / kernel_width); - } - break; - } - - for (; i < h; ++i) { - STBTT_assert(pixels[i * stride_in_bytes] == 0); - total -= buffer[i & STBTT__OVER_MASK]; - pixels[i * stride_in_bytes] = (unsigned char)(total / kernel_width); - } - - pixels += 1; - } -} - -static float -stbtt__oversample_shift(int oversample) -{ - if (!oversample) { - return 0.0f; - } - - /* The prefilter is a box filter of width "oversample", */ - /* which shifts phase by (oversample - 1)/2 pixels in */ - /* oversampled space. We want to shift in the opposite */ - /* direction to counter this. */ - return (float)-(oversample - 1) / (2.0f * (float)oversample); -} - -/* rects array must be big enough to accommodate all characters in the given ranges */ -STBTT_DEF int -stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) -{ - int i, j, k; - int missing_glyph_added = 0; - - k = 0; - for (i = 0; i < num_ranges; ++i) { - float fh = ranges[i].font_size; - float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh); - ranges[i].h_oversample = (unsigned char)spc->h_oversample; - ranges[i].v_oversample = (unsigned char)spc->v_oversample; - for (j = 0; j < ranges[i].num_chars; ++j) { - int x0, y0, x1, y1; - int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; - int glyph = stbtt_FindGlyphIndex(info, codepoint); - if (glyph == 0 && (spc->skip_missing || missing_glyph_added)) { - rects[k].w = rects[k].h = 0; - } else { - stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale * spc->h_oversample, scale * spc->v_oversample, 0, 0, &x0, &y0, &x1, &y1); - rects[k].w = (stbrp_coord)(x1 - x0 + spc->padding + spc->h_oversample - 1); - rects[k].h = (stbrp_coord)(y1 - y0 + spc->padding + spc->v_oversample - 1); - if (glyph == 0) { - missing_glyph_added = 1; - } - } - ++k; - } - } - - return k; -} - -STBTT_DEF void -stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info, - unsigned char *output, - int out_w, - int out_h, - int out_stride, - float scale_x, - float scale_y, - float shift_x, - float shift_y, - int prefilter_x, - int prefilter_y, - float *sub_x, - float *sub_y, - int glyph) -{ - stbtt_MakeGlyphBitmapSubpixel(info, output, out_w - (prefilter_x - 1), out_h - (prefilter_y - 1), out_stride, scale_x, scale_y, shift_x, shift_y, glyph); - - if (prefilter_x > 1) { - stbtt__h_prefilter(output, out_w, out_h, out_stride, prefilter_x); - } - - if (prefilter_y > 1) { - stbtt__v_prefilter(output, out_w, out_h, out_stride, prefilter_y); - } - - *sub_x = stbtt__oversample_shift(prefilter_x); - *sub_y = stbtt__oversample_shift(prefilter_y); -} - -/* rects array must be big enough to accommodate all characters in the given ranges */ -STBTT_DEF int -stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) -{ - int i, j, k, missing_glyph = -1, return_value = 1; - - /* save current values */ - int old_h_over = spc->h_oversample; - int old_v_over = spc->v_oversample; - - k = 0; - for (i = 0; i < num_ranges; ++i) { - float fh = ranges[i].font_size; - float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh); - float recip_h, recip_v, sub_x, sub_y; - spc->h_oversample = ranges[i].h_oversample; - spc->v_oversample = ranges[i].v_oversample; - recip_h = 1.0f / spc->h_oversample; - recip_v = 1.0f / spc->v_oversample; - sub_x = stbtt__oversample_shift(spc->h_oversample); - sub_y = stbtt__oversample_shift(spc->v_oversample); - for (j = 0; j < ranges[i].num_chars; ++j) { - stbrp_rect *r = &rects[k]; - if (r->was_packed && r->w != 0 && r->h != 0) { - stbtt_packedchar *bc = &ranges[i].chardata_for_range[j]; - int advance, lsb, x0, y0, x1, y1; - int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; - int glyph = stbtt_FindGlyphIndex(info, codepoint); - stbrp_coord pad = (stbrp_coord)spc->padding; - - /* pad on left and top */ - r->x += pad; - r->y += pad; - r->w -= pad; - r->h -= pad; - stbtt_GetGlyphHMetrics(info, glyph, &advance, &lsb); - stbtt_GetGlyphBitmapBox(info, glyph, scale * spc->h_oversample, scale * spc->v_oversample, &x0, &y0, &x1, &y1); - stbtt_MakeGlyphBitmapSubpixel(info, - spc->pixels + r->x + r->y * spc->stride_in_bytes, - r->w - spc->h_oversample + 1, - r->h - spc->v_oversample + 1, - spc->stride_in_bytes, - scale * spc->h_oversample, - scale * spc->v_oversample, - 0, - 0, - glyph); - - if (spc->h_oversample > 1) { - stbtt__h_prefilter(spc->pixels + r->x + r->y * spc->stride_in_bytes, r->w, r->h, spc->stride_in_bytes, spc->h_oversample); - } - - if (spc->v_oversample > 1) { - stbtt__v_prefilter(spc->pixels + r->x + r->y * spc->stride_in_bytes, r->w, r->h, spc->stride_in_bytes, spc->v_oversample); - } - - bc->x0 = (stbtt_int16)r->x; - bc->y0 = (stbtt_int16)r->y; - bc->x1 = (stbtt_int16)(r->x + r->w); - bc->y1 = (stbtt_int16)(r->y + r->h); - bc->xadvance = scale * advance; - bc->xoff = (float)x0 * recip_h + sub_x; - bc->yoff = (float)y0 * recip_v + sub_y; - bc->xoff2 = (x0 + r->w) * recip_h + sub_x; - bc->yoff2 = (y0 + r->h) * recip_v + sub_y; - - if (glyph == 0) { - missing_glyph = j; - } - } else if (spc->skip_missing) { - return_value = 0; - } else if (r->was_packed && r->w == 0 && r->h == 0 && missing_glyph >= 0) { - ranges[i].chardata_for_range[j] = ranges[i].chardata_for_range[missing_glyph]; - } else { - return_value = 0; /* if any fail, report failure */ - } - - ++k; - } - } - - /* restore original values */ - spc->h_oversample = old_h_over; - spc->v_oversample = old_v_over; - - return return_value; -} - -STBTT_DEF void -stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects) -{ - stbrp_pack_rects((stbrp_context *)spc->pack_info, rects, num_rects); -} - -STBTT_DEF int -stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges) -{ - stbtt_fontinfo info; - int i, j, n, return_value = 1; - /* stbrp_context *context = (stbrp_context *) spc->pack_info; */ - stbrp_rect *rects; - - /* flag all characters as NOT packed */ - for (i = 0; i < num_ranges; ++i) { - for (j = 0; j < ranges[i].num_chars; ++j) { - ranges[i].chardata_for_range[j].x0 = ranges[i].chardata_for_range[j].y0 = ranges[i].chardata_for_range[j].x1 = ranges[i].chardata_for_range[j].y1 = 0; - } - } - - n = 0; - for (i = 0; i < num_ranges; ++i) { - n += ranges[i].num_chars; - } - - rects = (stbrp_rect *)STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context); - if (rects == NULL) { - return 0; - } - - info.userdata = spc->user_allocator_context; - stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, font_index)); - - n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects); - - stbtt_PackFontRangesPackRects(spc, rects, n); - - return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects); - - STBTT_free(rects, spc->user_allocator_context); - return return_value; -} - -STBTT_DEF int -stbtt_PackFontRange(stbtt_pack_context *spc, - const unsigned char *fontdata, - int font_index, - float font_size, - int first_unicode_codepoint_in_range, - int num_chars_in_range, - stbtt_packedchar *chardata_for_range) -{ - stbtt_pack_range range; - range.first_unicode_codepoint_in_range = first_unicode_codepoint_in_range; - range.array_of_unicode_codepoints = NULL; - range.num_chars = num_chars_in_range; - range.chardata_for_range = chardata_for_range; - range.font_size = font_size; - return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1); -} - -STBTT_DEF void -stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap) -{ - int i_ascent, i_descent, i_lineGap; - float scale; - stbtt_fontinfo info; - stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, index)); - scale = size > 0 ? stbtt_ScaleForPixelHeight(&info, size) : stbtt_ScaleForMappingEmToPixels(&info, -size); - stbtt_GetFontVMetrics(&info, &i_ascent, &i_descent, &i_lineGap); - *ascent = (float)i_ascent * scale; - *descent = (float)i_descent * scale; - *lineGap = (float)i_lineGap * scale; -} - -STBTT_DEF void -stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer) -{ - float ipw = 1.0f / pw, iph = 1.0f / ph; - const stbtt_packedchar *b = chardata + char_index; - - if (align_to_integer) { - float x = (float)STBTT_ifloor((*xpos + b->xoff) + 0.5f); - float y = (float)STBTT_ifloor((*ypos + b->yoff) + 0.5f); - q->x0 = x; - q->y0 = y; - q->x1 = x + b->xoff2 - b->xoff; - q->y1 = y + b->yoff2 - b->yoff; - } else { - q->x0 = *xpos + b->xoff; - q->y0 = *ypos + b->yoff; - q->x1 = *xpos + b->xoff2; - q->y1 = *ypos + b->yoff2; - } - - q->s0 = b->x0 * ipw; - q->t0 = b->y0 * iph; - q->s1 = b->x1 * ipw; - q->t1 = b->y1 * iph; - - *xpos += b->xadvance; -} - -/* //////////////////////////////////////////////////////////////////////////// */ -/* */ -/* sdf computation */ -/* */ - -# define STBTT_min(a, b) ((a) < (b) ? (a) : (b)) -# define STBTT_max(a, b) ((a) < (b) ? (b) : (a)) - -static int -stbtt__ray_intersect_bezier(float orig[2], float ray[2], float q0[2], float q1[2], float q2[2], float hits[2][2]) -{ - float q0perp = q0[1] * ray[0] - q0[0] * ray[1]; - float q1perp = q1[1] * ray[0] - q1[0] * ray[1]; - float q2perp = q2[1] * ray[0] - q2[0] * ray[1]; - float roperp = orig[1] * ray[0] - orig[0] * ray[1]; - - float a = q0perp - 2 * q1perp + q2perp; - float b = q1perp - q0perp; - float c = q0perp - roperp; - - float s0 = 0., s1 = 0.; - int num_s = 0; - - if (a != 0.0) { - float discr = b * b - a * c; - if (discr > 0.0) { - float rcpna = -1 / a; - float d = (float)STBTT_sqrt(discr); - s0 = (b + d) * rcpna; - s1 = (b - d) * rcpna; - if (s0 >= 0.0 && s0 <= 1.0) { - num_s = 1; - } - if (d > 0.0 && s1 >= 0.0 && s1 <= 1.0) { - if (num_s == 0) { - s0 = s1; - } - ++num_s; - } - } - } else { - /* 2*b*s + c = 0 */ - /* s = -c / (2*b) */ - s0 = c / (-2 * b); - if (s0 >= 0.0 && s0 <= 1.0) { - num_s = 1; - } - } - - if (num_s == 0) { - return 0; - } else { - float rcp_len2 = 1 / (ray[0] * ray[0] + ray[1] * ray[1]); - float rayn_x = ray[0] * rcp_len2, rayn_y = ray[1] * rcp_len2; - - float q0d = q0[0] * rayn_x + q0[1] * rayn_y; - float q1d = q1[0] * rayn_x + q1[1] * rayn_y; - float q2d = q2[0] * rayn_x + q2[1] * rayn_y; - float rod = orig[0] * rayn_x + orig[1] * rayn_y; - - float q10d = q1d - q0d; - float q20d = q2d - q0d; - float q0rd = q0d - rod; - - hits[0][0] = q0rd + s0 * (2.0f - 2.0f * s0) * q10d + s0 * s0 * q20d; - hits[0][1] = a * s0 + b; - - if (num_s > 1) { - hits[1][0] = q0rd + s1 * (2.0f - 2.0f * s1) * q10d + s1 * s1 * q20d; - hits[1][1] = a * s1 + b; - return 2; - } else { - return 1; - } - } -} - -static int -stbtt__equal(float *a, float *b) -{ - return (a[0] == b[0] && a[1] == b[1]); -} - -static int -stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex *verts) -{ - int i; - float orig[2], ray[2] = {1, 0}; - float y_frac; - int winding = 0; - - /* make sure y never passes through a vertex of the shape */ - y_frac = (float)STBTT_fmod(y, 1.0f); - if (y_frac < 0.01f) { - y += 0.01f; - } else if (y_frac > 0.99f) { - y -= 0.01f; - } - - orig[0] = x; - orig[1] = y; - - /* test a ray from (-infinity,y) to (x,y) */ - for (i = 0; i < nverts; ++i) { - if (verts[i].type == STBTT_vline) { - int x0 = (int)verts[i - 1].x, y0 = (int)verts[i - 1].y; - int x1 = (int)verts[i].x, y1 = (int)verts[i].y; - if (y > STBTT_min(y0, y1) && y < STBTT_max(y0, y1) && x > STBTT_min(x0, x1)) { - float x_inter = (y - y0) / (y1 - y0) * (x1 - x0) + x0; - if (x_inter < x) { - winding += (y0 < y1) ? 1 : -1; - } - } - } - if (verts[i].type == STBTT_vcurve) { - int x0 = (int)verts[i - 1].x, y0 = (int)verts[i - 1].y; - int x1 = (int)verts[i].cx, y1 = (int)verts[i].cy; - int x2 = (int)verts[i].x, y2 = (int)verts[i].y; - int ax = STBTT_min(x0, STBTT_min(x1, x2)), ay = STBTT_min(y0, STBTT_min(y1, y2)); - int by = STBTT_max(y0, STBTT_max(y1, y2)); - if (y > ay && y < by && x > ax) { - float q0[2], q1[2], q2[2]; - float hits[2][2]; - q0[0] = (float)x0; - q0[1] = (float)y0; - q1[0] = (float)x1; - q1[1] = (float)y1; - q2[0] = (float)x2; - q2[1] = (float)y2; - if (stbtt__equal(q0, q1) || stbtt__equal(q1, q2)) { - x0 = (int)verts[i - 1].x; - y0 = (int)verts[i - 1].y; - x1 = (int)verts[i].x; - y1 = (int)verts[i].y; - if (y > STBTT_min(y0, y1) && y < STBTT_max(y0, y1) && x > STBTT_min(x0, x1)) { - float x_inter = (y - y0) / (y1 - y0) * (x1 - x0) + x0; - if (x_inter < x) { - winding += (y0 < y1) ? 1 : -1; - } - } - } else { - int num_hits = stbtt__ray_intersect_bezier(orig, ray, q0, q1, q2, hits); - if (num_hits >= 1) { - if (hits[0][0] < 0) { - winding += (hits[0][1] < 0 ? -1 : 1); - } - } - if (num_hits >= 2) { - if (hits[1][0] < 0) { - winding += (hits[1][1] < 0 ? -1 : 1); - } - } - } - } - } - } - return winding; -} - -static float -stbtt__cuberoot(float x) -{ - if (x < 0) { - return -(float)STBTT_pow(-x, 1.0f / 3.0f); - } else { - return (float)STBTT_pow(x, 1.0f / 3.0f); - } -} - -/* x^3 + a*x^2 + b*x + c = 0 */ -static int -stbtt__solve_cubic(float a, float b, float c, float *r) -{ - float s = -a / 3; - float p = b - a * a / 3; - float q = a * (2 * a * a - 9 * b) / 27 + c; - float p3 = p * p * p; - float d = q * q + 4 * p3 / 27; - if (d >= 0) { - float z = (float)STBTT_sqrt(d); - float u = (-q + z) / 2; - float v = (-q - z) / 2; - u = stbtt__cuberoot(u); - v = stbtt__cuberoot(v); - r[0] = s + u + v; - return 1; - } else { - float u = (float)STBTT_sqrt(-p / 3); - float v = (float)STBTT_acos(-STBTT_sqrt(-27 / p3) * q / 2) / 3; /* p3 must be negative, since d is negative */ - float m = (float)STBTT_cos(v); - float n = (float)STBTT_cos(v - 3.141592 / 2) * 1.732050808f; - r[0] = s + u * 2 * m; - r[1] = s - u * (m + n); - r[2] = s - u * (m - n); - - /* STBTT_assert( STBTT_fabs(((r[0]+a)*r[0]+b)*r[0]+c) < 0.05f); // these asserts may not be safe at all scales, - * though they're in bezier t parameter units so maybe? */ - /* STBTT_assert( STBTT_fabs(((r[1]+a)*r[1]+b)*r[1]+c) < 0.05f); */ - /* STBTT_assert( STBTT_fabs(((r[2]+a)*r[2]+b)*r[2]+c) < 0.05f); */ - return 3; - } -} - -STBTT_DEF unsigned char * -stbtt_GetGlyphSDF( - const stbtt_fontinfo *info, float scale, int glyph, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff) -{ - float scale_x = scale, scale_y = scale; - int ix0, iy0, ix1, iy1; - int w, h; - unsigned char *data; - - if (scale == 0) { - return NULL; - } - - stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f, 0.0f, &ix0, &iy0, &ix1, &iy1); - - /* if empty, return NULL */ - if (ix0 == ix1 || iy0 == iy1) { - return NULL; - } - - ix0 -= padding; - iy0 -= padding; - ix1 += padding; - iy1 += padding; - - w = (ix1 - ix0); - h = (iy1 - iy0); - - if (width) { - *width = w; - } - if (height) { - *height = h; - } - if (xoff) { - *xoff = ix0; - } - if (yoff) { - *yoff = iy0; - } - - /* invert for y-downwards bitmaps */ - scale_y = -scale_y; - - { - int x, y, i, j; - float *precompute; - stbtt_vertex *verts; - int num_verts = stbtt_GetGlyphShape(info, glyph, &verts); - data = (unsigned char *)STBTT_malloc(w * h, info->userdata); - precompute = (float *)STBTT_malloc(num_verts * sizeof(float), info->userdata); - - for (i = 0, j = num_verts - 1; i < num_verts; j = i++) { - if (verts[i].type == STBTT_vline) { - float x0 = verts[i].x * scale_x, y0 = verts[i].y * scale_y; - float x1 = verts[j].x * scale_x, y1 = verts[j].y * scale_y; - float dist = (float)STBTT_sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)); - precompute[i] = (dist == 0) ? 0.0f : 1.0f / dist; - } else if (verts[i].type == STBTT_vcurve) { - float x2 = verts[j].x * scale_x, y2 = verts[j].y * scale_y; - float x1 = verts[i].cx * scale_x, y1 = verts[i].cy * scale_y; - float x0 = verts[i].x * scale_x, y0 = verts[i].y * scale_y; - float bx = x0 - 2 * x1 + x2, by = y0 - 2 * y1 + y2; - float len2 = bx * bx + by * by; - if (len2 != 0.0f) { - precompute[i] = 1.0f / (bx * bx + by * by); - } else { - precompute[i] = 0.0f; - } - } else { - precompute[i] = 0.0f; - } - } - - for (y = iy0; y < iy1; ++y) { - for (x = ix0; x < ix1; ++x) { - float val; - float min_dist = 999999.0f; - float sx = (float)x + 0.5f; - float sy = (float)y + 0.5f; - float x_gspace = (sx / scale_x); - float y_gspace = (sy / scale_y); - - int winding = stbtt__compute_crossings_x(x_gspace, y_gspace, num_verts, verts); /* @OPTIMIZE: this could just be a rasterization, but needs to be line - vs. non-tesselated curves so a new path */ - - for (i = 0; i < num_verts; ++i) { - float x0 = verts[i].x * scale_x, y0 = verts[i].y * scale_y; - - if (verts[i].type == STBTT_vline && precompute[i] != 0.0f) { - float x1 = verts[i - 1].x * scale_x, y1 = verts[i - 1].y * scale_y; - - float dist, dist2 = (x0 - sx) * (x0 - sx) + (y0 - sy) * (y0 - sy); - if (dist2 < min_dist * min_dist) { - min_dist = (float)STBTT_sqrt(dist2); - } - - /* coarse culling against bbox */ - /* if (sx > STBTT_min(x0,x1)-min_dist && sx < STBTT_max(x0,x1)+min_dist && */ - /* sy > STBTT_min(y0,y1)-min_dist && sy < STBTT_max(y0,y1)+min_dist) */ - dist = (float)STBTT_fabs((x1 - x0) * (y0 - sy) - (y1 - y0) * (x0 - sx)) * precompute[i]; - STBTT_assert(i != 0); - if (dist < min_dist) { - /* check position along line */ - /* x' = x0 + t*(x1-x0), y' = y0 + t*(y1-y0) */ - /* minimize (x'-sx)*(x'-sx)+(y'-sy)*(y'-sy) */ - float dx = x1 - x0, dy = y1 - y0; - float px = x0 - sx, py = y0 - sy; - /* minimize (px+t*dx)^2 + (py+t*dy)^2 = px*px + 2*px*dx*t + t^2*dx*dx + py*py + 2*py*dy*t + t^2*dy*dy */ - /* derivative: 2*px*dx + 2*py*dy + (2*dx*dx+2*dy*dy)*t, set to 0 and solve */ - float t = -(px * dx + py * dy) / (dx * dx + dy * dy); - if (t >= 0.0f && t <= 1.0f) { - min_dist = dist; - } - } - } else if (verts[i].type == STBTT_vcurve) { - float x2 = verts[i - 1].x * scale_x, y2 = verts[i - 1].y * scale_y; - float x1 = verts[i].cx * scale_x, y1 = verts[i].cy * scale_y; - float box_x0 = STBTT_min(STBTT_min(x0, x1), x2); - float box_y0 = STBTT_min(STBTT_min(y0, y1), y2); - float box_x1 = STBTT_max(STBTT_max(x0, x1), x2); - float box_y1 = STBTT_max(STBTT_max(y0, y1), y2); - /* coarse culling against bbox to avoid computing cubic unnecessarily */ - if (sx > box_x0 - min_dist && sx < box_x1 + min_dist && sy > box_y0 - min_dist && sy < box_y1 + min_dist) { - int num = 0; - float ax = x1 - x0, ay = y1 - y0; - float bx = x0 - 2 * x1 + x2, by = y0 - 2 * y1 + y2; - float mx = x0 - sx, my = y0 - sy; - float res[3] = {0.f, 0.f, 0.f}; - float px, py, t, it, dist2; - float a_inv = precompute[i]; - if (a_inv == 0.0) { /* if a_inv is 0, it's 2nd degree so use quadratic formula */ - float a = 3 * (ax * bx + ay * by); - float b = 2 * (ax * ax + ay * ay) + (mx * bx + my * by); - float c = mx * ax + my * ay; - if (a == 0.0) { /* if a is 0, it's linear */ - if (b != 0.0) { - res[num++] = -c / b; - } - } else { - float discriminant = b * b - 4 * a * c; - if (discriminant < 0) { - num = 0; - } else { - float root = (float)STBTT_sqrt(discriminant); - res[0] = (-b - root) / (2 * a); - res[1] = (-b + root) / (2 * a); - num = 2; /* don't bother distinguishing 1-solution case, as code below will still work */ - } - } - } else { - float b = 3 * (ax * bx + ay * by) * a_inv; /* could precompute this as it doesn't depend on sample point */ - float c = (2 * (ax * ax + ay * ay) + (mx * bx + my * by)) * a_inv; - float d = (mx * ax + my * ay) * a_inv; - num = stbtt__solve_cubic(b, c, d, res); - } - dist2 = (x0 - sx) * (x0 - sx) + (y0 - sy) * (y0 - sy); - if (dist2 < min_dist * min_dist) { - min_dist = (float)STBTT_sqrt(dist2); - } - - if (num >= 1 && res[0] >= 0.0f && res[0] <= 1.0f) { - t = res[0], it = 1.0f - t; - px = it * it * x0 + 2 * t * it * x1 + t * t * x2; - py = it * it * y0 + 2 * t * it * y1 + t * t * y2; - dist2 = (px - sx) * (px - sx) + (py - sy) * (py - sy); - if (dist2 < min_dist * min_dist) { - min_dist = (float)STBTT_sqrt(dist2); - } - } - if (num >= 2 && res[1] >= 0.0f && res[1] <= 1.0f) { - t = res[1], it = 1.0f - t; - px = it * it * x0 + 2 * t * it * x1 + t * t * x2; - py = it * it * y0 + 2 * t * it * y1 + t * t * y2; - dist2 = (px - sx) * (px - sx) + (py - sy) * (py - sy); - if (dist2 < min_dist * min_dist) { - min_dist = (float)STBTT_sqrt(dist2); - } - } - if (num >= 3 && res[2] >= 0.0f && res[2] <= 1.0f) { - t = res[2], it = 1.0f - t; - px = it * it * x0 + 2 * t * it * x1 + t * t * x2; - py = it * it * y0 + 2 * t * it * y1 + t * t * y2; - dist2 = (px - sx) * (px - sx) + (py - sy) * (py - sy); - if (dist2 < min_dist * min_dist) { - min_dist = (float)STBTT_sqrt(dist2); - } - } - } - } - } - if (winding == 0) { - min_dist = -min_dist; /* if outside the shape, value is negative */ - } - val = onedge_value + pixel_dist_scale * min_dist; - if (val < 0) { - val = 0; - } else if (val > 255) { - val = 255; - } - data[(y - iy0) * w + (x - ix0)] = (unsigned char)val; - } - } - STBTT_free(precompute, info->userdata); - STBTT_free(verts, info->userdata); - } - return data; -} - -STBTT_DEF unsigned char * -stbtt_GetCodepointSDF( - const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff) -{ - return stbtt_GetGlyphSDF(info, scale, stbtt_FindGlyphIndex(info, codepoint), padding, onedge_value, pixel_dist_scale, width, height, xoff, yoff); -} - -STBTT_DEF void -stbtt_FreeSDF(unsigned char *bitmap, void *userdata) -{ - STBTT_free(bitmap, userdata); -} - -/* //////////////////////////////////////////////////////////////////////////// */ -/* */ -/* font name matching -- recommended not to use this */ -/* */ - -/* check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string */ -static stbtt_int32 -stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, stbtt_int32 len1, stbtt_uint8 *s2, stbtt_int32 len2) -{ - stbtt_int32 i = 0; - - /* convert utf16 to utf8 and compare the results while converting */ - while (len2) { - stbtt_uint16 ch = s2[0] * 256 + s2[1]; - if (ch < 0x80) { - if (i >= len1) { - return -1; - } - if (s1[i++] != ch) { - return -1; - } - } else if (ch < 0x800) { - if (i + 1 >= len1) { - return -1; - } - if (s1[i++] != 0xc0 + (ch >> 6)) { - return -1; - } - if (s1[i++] != 0x80 + (ch & 0x3f)) { - return -1; - } - } else if (ch >= 0xd800 && ch < 0xdc00) { - stbtt_uint32 c; - stbtt_uint16 ch2 = s2[2] * 256 + s2[3]; - if (i + 3 >= len1) { - return -1; - } - c = ((ch - 0xd800) << 10) + (ch2 - 0xdc00) + 0x10000; - if (s1[i++] != 0xf0 + (c >> 18)) { - return -1; - } - if (s1[i++] != 0x80 + ((c >> 12) & 0x3f)) { - return -1; - } - if (s1[i++] != 0x80 + ((c >> 6) & 0x3f)) { - return -1; - } - if (s1[i++] != 0x80 + ((c) & 0x3f)) { - return -1; - } - s2 += 2; /* plus another 2 below */ - len2 -= 2; - } else if (ch >= 0xdc00 && ch < 0xe000) { - return -1; - } else { - if (i + 2 >= len1) { - return -1; - } - if (s1[i++] != 0xe0 + (ch >> 12)) { - return -1; - } - if (s1[i++] != 0x80 + ((ch >> 6) & 0x3f)) { - return -1; - } - if (s1[i++] != 0x80 + ((ch) & 0x3f)) { - return -1; - } - } - s2 += 2; - len2 -= 2; - } - return i; -} - -static int -stbtt_CompareUTF8toUTF16_bigendian_internal(char *s1, int len1, char *s2, int len2) -{ - return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8 *)s1, len1, (stbtt_uint8 *)s2, len2); -} - -/* returns results in whatever encoding you request... but note that 2-byte encodings */ -/* will be BIG-ENDIAN... use stbtt_CompareUTF8toUTF16_bigendian() to compare */ -STBTT_DEF const char * -stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID) -{ - stbtt_int32 i, count, stringOffset; - stbtt_uint8 *fc = font->data; - stbtt_uint32 offset = font->fontstart; - stbtt_uint32 nm = stbtt__find_table(fc, offset, "name"); - if (!nm) { - return NULL; - } - - count = ttUSHORT(fc + nm + 2); - stringOffset = nm + ttUSHORT(fc + nm + 4); - for (i = 0; i < count; ++i) { - stbtt_uint32 loc = nm + 6 + 12 * i; - if (platformID == ttUSHORT(fc + loc + 0) && encodingID == ttUSHORT(fc + loc + 2) && languageID == ttUSHORT(fc + loc + 4) && nameID == ttUSHORT(fc + loc + 6)) { - *length = ttUSHORT(fc + loc + 8); - return (const char *)(fc + stringOffset + ttUSHORT(fc + loc + 10)); - } - } - return NULL; -} - -static int -stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, stbtt_int32 nlen, stbtt_int32 target_id, stbtt_int32 next_id) -{ - stbtt_int32 i; - stbtt_int32 count = ttUSHORT(fc + nm + 2); - stbtt_int32 stringOffset = nm + ttUSHORT(fc + nm + 4); - - for (i = 0; i < count; ++i) { - stbtt_uint32 loc = nm + 6 + 12 * i; - stbtt_int32 id = ttUSHORT(fc + loc + 6); - if (id == target_id) { - /* find the encoding */ - stbtt_int32 platform = ttUSHORT(fc + loc + 0), encoding = ttUSHORT(fc + loc + 2), language = ttUSHORT(fc + loc + 4); - - /* is this a Unicode encoding? */ - if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) { - stbtt_int32 slen = ttUSHORT(fc + loc + 8); - stbtt_int32 off = ttUSHORT(fc + loc + 10); - - /* check if there's a prefix match */ - stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc + stringOffset + off, slen); - if (matchlen >= 0) { - /* check for target_id+1 immediately following, with same encoding & language */ - if (i + 1 < count && ttUSHORT(fc + loc + 12 + 6) == next_id && ttUSHORT(fc + loc + 12) == platform && ttUSHORT(fc + loc + 12 + 2) == encoding && - ttUSHORT(fc + loc + 12 + 4) == language) { - slen = ttUSHORT(fc + loc + 12 + 8); - off = ttUSHORT(fc + loc + 12 + 10); - if (slen == 0) { - if (matchlen == nlen) { - return 1; - } - } else if (matchlen < nlen && name[matchlen] == ' ') { - ++matchlen; - if (stbtt_CompareUTF8toUTF16_bigendian_internal((char *)(name + matchlen), nlen - matchlen, (char *)(fc + stringOffset + off), slen)) { - return 1; - } - } - } else { - /* if nothing immediately following */ - if (matchlen == nlen) { - return 1; - } - } - } - } - - /* @TODO handle other encodings */ - } - } - return 0; -} - -static int -stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *name, stbtt_int32 flags) -{ - stbtt_int32 nlen = (stbtt_int32)STBTT_strlen((char *)name); - stbtt_uint32 nm, hd; - if (!stbtt__isfont(fc + offset)) { - return 0; - } - - /* check italics/bold/underline flags in macStyle... */ - if (flags) { - hd = stbtt__find_table(fc, offset, "head"); - if ((ttUSHORT(fc + hd + 44) & 7) != (flags & 7)) { - return 0; - } - } - - nm = stbtt__find_table(fc, offset, "name"); - if (!nm) { - return 0; - } - - if (flags) { - /* if we checked the macStyle flags, then just check the family and ignore the subfamily */ - if (stbtt__matchpair(fc, nm, name, nlen, 16, -1)) { - return 1; - } - if (stbtt__matchpair(fc, nm, name, nlen, 1, -1)) { - return 1; - } - if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) { - return 1; - } - } else { - if (stbtt__matchpair(fc, nm, name, nlen, 16, 17)) { - return 1; - } - if (stbtt__matchpair(fc, nm, name, nlen, 1, 2)) { - return 1; - } - if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) { - return 1; - } - } - - return 0; -} - -static int -stbtt_FindMatchingFont_internal(unsigned char *font_collection, char *name_utf8, stbtt_int32 flags) -{ - stbtt_int32 i; - for (i = 0;; ++i) { - stbtt_int32 off = stbtt_GetFontOffsetForIndex(font_collection, i); - if (off < 0) { - return off; - } - if (stbtt__matches((stbtt_uint8 *)font_collection, off, (stbtt_uint8 *)name_utf8, flags)) { - return off; - } - } -} - -# if defined(__GNUC__) || defined(__clang__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wcast-qual" -# endif - -STBTT_DEF int -stbtt_BakeFontBitmap(const unsigned char *data, int offset, float pixel_height, unsigned char *pixels, int pw, int ph, int first_char, int num_chars, stbtt_bakedchar *chardata) -{ - return stbtt_BakeFontBitmap_internal((unsigned char *)data, offset, pixel_height, pixels, pw, ph, first_char, num_chars, chardata); -} - -STBTT_DEF int -stbtt_GetFontOffsetForIndex(const unsigned char *data, int index) -{ - return stbtt_GetFontOffsetForIndex_internal((unsigned char *)data, index); -} - -STBTT_DEF int -stbtt_GetNumberOfFonts(const unsigned char *data) -{ - return stbtt_GetNumberOfFonts_internal((unsigned char *)data); -} - -STBTT_DEF int -stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset) -{ - return stbtt_InitFont_internal(info, (unsigned char *)data, offset); -} - -STBTT_DEF int -stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags) -{ - return stbtt_FindMatchingFont_internal((unsigned char *)fontdata, (char *)name, flags); -} - -STBTT_DEF int -stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2) -{ - return stbtt_CompareUTF8toUTF16_bigendian_internal((char *)s1, len1, (char *)s2, len2); -} - -# if defined(__GNUC__) || defined(__clang__) -# pragma GCC diagnostic pop -# endif - -#endif /* STB_TRUETYPE_IMPLEMENTATION */ - -/* FULL VERSION HISTORY */ -/* */ -/* 1.25 (2021-07-11) many fixes */ -/* 1.24 (2020-02-05) fix warning */ -/* 1.23 (2020-02-02) query SVG data for glyphs; query whole kerning table (but only kern not GPOS) */ -/* 1.22 (2019-08-11) minimize missing-glyph duplication; fix kerning if both 'GPOS' and 'kern' are defined */ -/* 1.21 (2019-02-25) fix warning */ -/* 1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics() */ -/* 1.19 (2018-02-11) OpenType GPOS kerning (horizontal only), STBTT_fmod */ -/* 1.18 (2018-01-29) add missing function */ -/* 1.17 (2017-07-23) make more arguments const; doc fix */ -/* 1.16 (2017-07-12) SDF support */ -/* 1.15 (2017-03-03) make more arguments const */ -/* 1.14 (2017-01-16) num-fonts-in-TTC function */ -/* 1.13 (2017-01-02) support OpenType fonts, certain Apple fonts */ -/* 1.12 (2016-10-25) suppress warnings about casting away const with -Wcast-qual */ -/* 1.11 (2016-04-02) fix unused-variable warning */ -/* 1.10 (2016-04-02) allow user-defined fabs() replacement */ -/* fix memory leak if fontsize=0.0 */ -/* fix warning from duplicate typedef */ -/* 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use alloc userdata for PackFontRanges */ -/* 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges */ -/* 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints; */ -/* allow PackFontRanges to pack and render in separate phases; */ -/* fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?); */ -/* fixed an assert() bug in the new rasterizer */ -/* replace assert() with STBTT_assert() in new rasterizer */ -/* 1.06 (2015-07-14) performance improvements (~35% faster on x86 and x64 on test machine) */ -/* also more precise AA rasterizer, except if shapes overlap */ -/* remove need for STBTT_sort */ -/* 1.05 (2015-04-15) fix misplaced definitions for STBTT_STATIC */ -/* 1.04 (2015-04-15) typo in example */ -/* 1.03 (2015-04-12) STBTT_STATIC, fix memory leak in new packing, various fixes */ -/* 1.02 (2014-12-10) fix various warnings & compile issues w/ stb_rect_pack, C++ */ -/* 1.01 (2014-12-08) fix subpixel position when oversampling to exactly match */ -/* non-oversampled; STBTT_POINT_SIZE for packed case only */ -/* 1.00 (2014-12-06) add new PackBegin etc. API, w/ support for oversampling */ -/* 0.99 (2014-09-18) fix multiple bugs with subpixel rendering (ryg) */ -/* 0.9 (2014-08-07) support certain mac/iOS fonts without an MS platformID */ -/* 0.8b (2014-07-07) fix a warning */ -/* 0.8 (2014-05-25) fix a few more warnings */ -/* 0.7 (2013-09-25) bugfix: subpixel glyph bug fixed in 0.5 had come back */ -/* 0.6c (2012-07-24) improve documentation */ -/* 0.6b (2012-07-20) fix a few more warnings */ -/* 0.6 (2012-07-17) fix warnings; added stbtt_ScaleForMappingEmToPixels, */ -/* stbtt_GetFontBoundingBox, stbtt_IsGlyphEmpty */ -/* 0.5 (2011-12-09) bugfixes: */ -/* subpixel glyph renderer computed wrong bounding box */ -/* first vertex of shape can be off-curve (FreeSans) */ -/* 0.4b (2011-12-03) fixed an error in the font baking example */ -/* 0.4 (2011-12-01) kerning, subpixel rendering (tor) */ -/* bugfixes for: */ -/* codepoint-to-glyph conversion using table fmt=12 */ -/* codepoint-to-glyph conversion using table fmt=4 */ -/* stbtt_GetBakedQuad with non-square texture (Zer) */ -/* updated Hello World! sample to use kerning and subpixel */ -/* fixed some warnings */ -/* 0.3 (2009-06-24) cmap fmt=12, compound shapes (MM) */ -/* userdata, malloc-from-userdata, non-zero fill (stb) */ -/* 0.2 (2009-03-11) Fix unsigned/signed char warnings */ -/* 0.1 (2009-03-09) First public release */ -/* */ - -/* ------------------------------------------------------------------------------- -This software is available under 2 licenses -- choose whichever you prefer. ------------------------------------------------------------------------------- -ALTERNATIVE A - MIT License -Copyright (c) 2017 Sean Barrett -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. ------------------------------------------------------------------------------- -ALTERNATIVE B - Public Domain (www.unlicense.org) -This is free and unencumbered software released into the public domain. -Anyone is free to copy, modify, publish, use, compile, sell, or distribute this -software, either in source code form or as a compiled binary, for any purpose, -commercial or non-commercial, and by any means. -In jurisdictions that recognize copyright laws, the author or authors of this -software dedicate any and all copyright interest in the software to the public -domain. We make this dedication for the benefit of the public at large and to -the detriment of our heirs and successors. We intend this dedication to be an -overt act of relinquishment in perpetuity of all present and future rights to -this software under copyright law. -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 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. ------------------------------------------------------------------------------- -*/ - -#ifdef NK_INCLUDE_FONT_BAKING -/* ------------------------------------------------------------- - * - * RECT PACK - * - * --------------------------------------------------------------*/ - -/* - * ============================================================== - * - * TRUETYPE - * - * =============================================================== - */ -# define STBTT_MAX_OVERSAMPLE 8 - -/* ------------------------------------------------------------- - * - * FONT BAKING - * - * --------------------------------------------------------------*/ -struct nk_font_bake_data { - struct stbtt_fontinfo info; - struct stbrp_rect *rects; - stbtt_pack_range *ranges; - nk_rune range_count; -}; - -struct nk_font_baker { - struct nk_allocator alloc; - struct stbtt_pack_context spc; - struct nk_font_bake_data *build; - stbtt_packedchar *packed_chars; - struct stbrp_rect *rects; - stbtt_pack_range *ranges; -}; - -NK_GLOBAL const nk_size nk_rect_align = NK_ALIGNOF(struct stbrp_rect); -NK_GLOBAL const nk_size nk_range_align = NK_ALIGNOF(stbtt_pack_range); -NK_GLOBAL const nk_size nk_char_align = NK_ALIGNOF(stbtt_packedchar); -NK_GLOBAL const nk_size nk_build_align = NK_ALIGNOF(struct nk_font_bake_data); -NK_GLOBAL const nk_size nk_baker_align = NK_ALIGNOF(struct nk_font_baker); - -NK_INTERN int -nk_range_count(const nk_rune *range) -{ - const nk_rune *iter = range; - NK_ASSERT(range); - if (!range) { - return 0; - } - while (*(iter++) != 0) - ; - return (iter == range) ? 0 : (int)((iter - range) / 2); -} -NK_INTERN int -nk_range_glyph_count(const nk_rune *range, int count) -{ - int i = 0; - int total_glyphs = 0; - for (i = 0; i < count; ++i) { - int diff; - nk_rune f = range[(i * 2) + 0]; - nk_rune t = range[(i * 2) + 1]; - NK_ASSERT(t >= f); - diff = (int)((t - f) + 1); - total_glyphs += diff; - } - return total_glyphs; -} -NK_API const nk_rune * -nk_font_default_glyph_ranges(void) -{ - NK_STORAGE const nk_rune ranges[] = {0x0020, 0x00FF, 0}; - return ranges; -} -NK_API const nk_rune * -nk_font_chinese_glyph_ranges(void) -{ - NK_STORAGE const nk_rune ranges[] = {0x0020, 0x00FF, 0x3000, 0x30FF, 0x31F0, 0x31FF, 0xFF00, 0xFFEF, 0x4E00, 0x9FAF, 0}; - return ranges; -} -NK_API const nk_rune * -nk_font_cyrillic_glyph_ranges(void) -{ - NK_STORAGE const nk_rune ranges[] = {0x0020, 0x00FF, 0x0400, 0x052F, 0x2DE0, 0x2DFF, 0xA640, 0xA69F, 0}; - return ranges; -} -NK_API const nk_rune * -nk_font_korean_glyph_ranges(void) -{ - NK_STORAGE const nk_rune ranges[] = {0x0020, 0x00FF, 0x3131, 0x3163, 0xAC00, 0xD79D, 0}; - return ranges; -} -NK_INTERN void -nk_font_baker_memory(nk_size *temp, int *glyph_count, struct nk_font_config *config_list, int count) -{ - int range_count = 0; - int total_range_count = 0; - struct nk_font_config *iter, *i; - - NK_ASSERT(config_list); - NK_ASSERT(glyph_count); - if (!config_list) { - *temp = 0; - *glyph_count = 0; - return; - } - *glyph_count = 0; - for (iter = config_list; iter; iter = iter->next) { - i = iter; - do { - if (!i->range) { - iter->range = nk_font_default_glyph_ranges(); - } - range_count = nk_range_count(i->range); - total_range_count += range_count; - *glyph_count += nk_range_glyph_count(i->range, range_count); - } while ((i = i->n) != iter); - } - *temp = (nk_size)*glyph_count * sizeof(struct stbrp_rect); - *temp += (nk_size)total_range_count * sizeof(stbtt_pack_range); - *temp += (nk_size)*glyph_count * sizeof(stbtt_packedchar); - *temp += (nk_size)count * sizeof(struct nk_font_bake_data); - *temp += sizeof(struct nk_font_baker); - *temp += nk_rect_align + nk_range_align + nk_char_align; - *temp += nk_build_align + nk_baker_align; -} -NK_INTERN struct nk_font_baker * -nk_font_baker(void *memory, int glyph_count, int count, const struct nk_allocator *alloc) -{ - struct nk_font_baker *baker; - if (!memory) { - return 0; - } - /* setup baker inside a memory block */ - baker = (struct nk_font_baker *)NK_ALIGN_PTR(memory, nk_baker_align); - baker->build = (struct nk_font_bake_data *)NK_ALIGN_PTR((baker + 1), nk_build_align); - baker->packed_chars = (stbtt_packedchar *)NK_ALIGN_PTR((baker->build + count), nk_char_align); - baker->rects = (struct stbrp_rect *)NK_ALIGN_PTR((baker->packed_chars + glyph_count), nk_rect_align); - baker->ranges = (stbtt_pack_range *)NK_ALIGN_PTR((baker->rects + glyph_count), nk_range_align); - baker->alloc = *alloc; - return baker; -} -NK_INTERN int -nk_font_bake_pack(struct nk_font_baker *baker, - nk_size *image_memory, - int *width, - int *height, - struct nk_recti *custom, - const struct nk_font_config *config_list, - int count, - const struct nk_allocator *alloc) -{ - NK_STORAGE const nk_size max_height = 1024 * 32; - const struct nk_font_config *config_iter, *it; - int total_glyph_count = 0; - int total_range_count = 0; - int range_count = 0; - int i = 0; - - NK_ASSERT(image_memory); - NK_ASSERT(width); - NK_ASSERT(height); - NK_ASSERT(config_list); - NK_ASSERT(count); - NK_ASSERT(alloc); - - if (!image_memory || !width || !height || !config_list || !count) { - return nk_false; - } - for (config_iter = config_list; config_iter; config_iter = config_iter->next) { - it = config_iter; - do { - range_count = nk_range_count(it->range); - total_range_count += range_count; - total_glyph_count += nk_range_glyph_count(it->range, range_count); - } while ((it = it->n) != config_iter); - } - /* setup font baker from temporary memory */ - for (config_iter = config_list; config_iter; config_iter = config_iter->next) { - it = config_iter; - do { - struct stbtt_fontinfo *font_info = &baker->build[i++].info; - font_info->userdata = (void *)alloc; - - if (!stbtt_InitFont(font_info, (const unsigned char *)it->ttf_blob, stbtt_GetFontOffsetForIndex((const unsigned char *)it->ttf_blob, 0))) { - return nk_false; - } - } while ((it = it->n) != config_iter); - } - *height = 0; - *width = (total_glyph_count > 1000) ? 1024 : 512; - stbtt_PackBegin(&baker->spc, 0, (int)*width, (int)max_height, 0, 1, (void *)alloc); - { - int input_i = 0; - int range_n = 0; - int rect_n = 0; - int char_n = 0; - - if (custom) { - /* pack custom user data first so it will be in the upper left corner*/ - struct stbrp_rect custom_space; - nk_zero(&custom_space, sizeof(custom_space)); - custom_space.w = (stbrp_coord)(custom->w); - custom_space.h = (stbrp_coord)(custom->h); - - stbtt_PackSetOversampling(&baker->spc, 1, 1); - stbrp_pack_rects((struct stbrp_context *)baker->spc.pack_info, &custom_space, 1); - *height = NK_MAX(*height, (int)(custom_space.y + custom_space.h)); - - custom->x = (short)custom_space.x; - custom->y = (short)custom_space.y; - custom->w = (short)custom_space.w; - custom->h = (short)custom_space.h; - } - - /* first font pass: pack all glyphs */ - for (input_i = 0, config_iter = config_list; input_i < count && config_iter; config_iter = config_iter->next) { - it = config_iter; - do { - int n = 0; - int glyph_count; - const nk_rune *in_range; - const struct nk_font_config *cfg = it; - struct nk_font_bake_data *tmp = &baker->build[input_i++]; - - /* count glyphs + ranges in current font */ - glyph_count = 0; - range_count = 0; - for (in_range = cfg->range; in_range[0] && in_range[1]; in_range += 2) { - glyph_count += (int)(in_range[1] - in_range[0]) + 1; - range_count++; - } - - /* setup ranges */ - tmp->ranges = baker->ranges + range_n; - tmp->range_count = (nk_rune)range_count; - range_n += range_count; - for (i = 0; i < range_count; ++i) { - in_range = &cfg->range[i * 2]; - tmp->ranges[i].font_size = cfg->size; - tmp->ranges[i].first_unicode_codepoint_in_range = (int)in_range[0]; - tmp->ranges[i].num_chars = (int)(in_range[1] - in_range[0]) + 1; - tmp->ranges[i].chardata_for_range = baker->packed_chars + char_n; - char_n += tmp->ranges[i].num_chars; - } - - /* pack */ - tmp->rects = baker->rects + rect_n; - rect_n += glyph_count; - stbtt_PackSetOversampling(&baker->spc, cfg->oversample_h, cfg->oversample_v); - n = stbtt_PackFontRangesGatherRects(&baker->spc, &tmp->info, tmp->ranges, (int)tmp->range_count, tmp->rects); - stbrp_pack_rects((struct stbrp_context *)baker->spc.pack_info, tmp->rects, (int)n); - - /* texture height */ - for (i = 0; i < n; ++i) { - if (tmp->rects[i].was_packed) { - *height = NK_MAX(*height, tmp->rects[i].y + tmp->rects[i].h); - } - } - } while ((it = it->n) != config_iter); - } - NK_ASSERT(rect_n == total_glyph_count); - NK_ASSERT(char_n == total_glyph_count); - NK_ASSERT(range_n == total_range_count); - } - *height = (int)nk_round_up_pow2((nk_uint)*height); - *image_memory = (nk_size)(*width) * (nk_size)(*height); - return nk_true; -} -NK_INTERN void -nk_font_bake( - struct nk_font_baker *baker, void *image_memory, int width, int height, struct nk_font_glyph *glyphs, int glyphs_count, const struct nk_font_config *config_list, int font_count) -{ - int input_i = 0; - nk_rune glyph_n = 0; - const struct nk_font_config *config_iter; - const struct nk_font_config *it; - - NK_ASSERT(image_memory); - NK_ASSERT(width); - NK_ASSERT(height); - NK_ASSERT(config_list); - NK_ASSERT(baker); - NK_ASSERT(font_count); - NK_ASSERT(glyphs_count); - if (!image_memory || !width || !height || !config_list || !font_count || !glyphs || !glyphs_count) { - return; - } - - /* second font pass: render glyphs */ - nk_zero(image_memory, (nk_size)((nk_size)width * (nk_size)height)); - baker->spc.pixels = (unsigned char *)image_memory; - baker->spc.height = (int)height; - for (input_i = 0, config_iter = config_list; input_i < font_count && config_iter; config_iter = config_iter->next) { - it = config_iter; - do { - const struct nk_font_config *cfg = it; - struct nk_font_bake_data *tmp = &baker->build[input_i++]; - stbtt_PackSetOversampling(&baker->spc, cfg->oversample_h, cfg->oversample_v); - stbtt_PackFontRangesRenderIntoRects(&baker->spc, &tmp->info, tmp->ranges, (int)tmp->range_count, tmp->rects); - } while ((it = it->n) != config_iter); - } - stbtt_PackEnd(&baker->spc); - - /* third pass: setup font and glyphs */ - for (input_i = 0, config_iter = config_list; input_i < font_count && config_iter; config_iter = config_iter->next) { - it = config_iter; - do { - nk_size i = 0; - int char_idx = 0; - nk_rune glyph_count = 0; - const struct nk_font_config *cfg = it; - struct nk_font_bake_data *tmp = &baker->build[input_i++]; - struct nk_baked_font *dst_font = cfg->font; - - float font_scale = cfg->size > 0 ? stbtt_ScaleForPixelHeight(&tmp->info, cfg->size) : stbtt_ScaleForMappingEmToPixels(&tmp->info, -cfg->size); - int unscaled_ascent, unscaled_descent, unscaled_line_gap; - stbtt_GetFontVMetrics(&tmp->info, &unscaled_ascent, &unscaled_descent, &unscaled_line_gap); - - /* fill baked font */ - if (!cfg->merge_mode) { - dst_font->ranges = cfg->range; - dst_font->height = NK_ABS(cfg->size); - dst_font->ascent = ((float)unscaled_ascent * font_scale); - dst_font->descent = ((float)unscaled_descent * font_scale); - dst_font->glyph_offset = glyph_n; - /* - Need to zero this, or it will carry over from a previous - bake, and cause a segfault when accessing glyphs[]. - */ - dst_font->glyph_count = 0; - } - - /* fill own baked font glyph array */ - for (i = 0; i < tmp->range_count; ++i) { - stbtt_pack_range *range = &tmp->ranges[i]; - for (char_idx = 0; char_idx < range->num_chars; char_idx++) { - nk_rune codepoint = 0; - float dummy_x = 0, dummy_y = 0; - stbtt_aligned_quad q; - struct nk_font_glyph *glyph; - - /* query glyph bounds from stb_truetype */ - const stbtt_packedchar *pc = &range->chardata_for_range[char_idx]; - codepoint = (nk_rune)(range->first_unicode_codepoint_in_range + char_idx); - stbtt_GetPackedQuad(range->chardata_for_range, (int)width, (int)height, char_idx, &dummy_x, &dummy_y, &q, 0); - - /* fill own glyph type with data */ - glyph = &glyphs[dst_font->glyph_offset + dst_font->glyph_count + (unsigned int)glyph_count]; - glyph->codepoint = codepoint; - glyph->id = stbtt_FindGlyphIndex(&tmp->info, codepoint); - glyph->x0 = q.x0; - glyph->y0 = q.y0; - glyph->x1 = q.x1; - glyph->y1 = q.y1; - glyph->w = glyph->x1 - glyph->x0 + 0.5f; - glyph->h = glyph->y1 - glyph->y0; - - if (cfg->coord_type == NK_COORD_PIXEL) { - glyph->u0 = q.s0 * (float)width; - glyph->v0 = q.t0 * (float)height; - glyph->u1 = q.s1 * (float)width; - glyph->v1 = q.t1 * (float)height; - } else { - glyph->u0 = q.s0; - glyph->v0 = q.t0; - glyph->u1 = q.s1; - glyph->v1 = q.t1; - } - glyph->xadvance = (pc->xadvance + cfg->spacing.x); - if (cfg->pixel_snap) { - glyph->xadvance = (float)(int)(glyph->xadvance + 0.5f); - } - glyph_count++; - } - } - dst_font->glyph_count += glyph_count; - glyph_n += glyph_count; - } while ((it = it->n) != config_iter); - } -} -NK_INTERN void -nk_font_bake_custom_data( - void *img_memory, int img_width, int img_height, struct nk_recti img_dst, const char *texture_data_mask, int tex_width, int tex_height, char white, char black) -{ - nk_byte *pixels; - int y = 0; - int x = 0; - int n = 0; - - NK_ASSERT(img_memory); - NK_ASSERT(img_width); - NK_ASSERT(img_height); - NK_ASSERT(texture_data_mask); - NK_UNUSED(tex_height); - if (!img_memory || !img_width || !img_height || !texture_data_mask) { - return; - } - - pixels = (nk_byte *)img_memory; - for (y = 0, n = 0; y < tex_height; ++y) { - for (x = 0; x < tex_width; ++x, ++n) { - const int off0 = ((img_dst.x + x) + (img_dst.y + y) * img_width); - const int off1 = off0 + 1 + tex_width; - pixels[off0] = (texture_data_mask[n] == white) ? 0xFF : 0x00; - pixels[off1] = (texture_data_mask[n] == black) ? 0xFF : 0x00; - } - } -} -NK_INTERN void -nk_font_bake_convert(void *out_memory, int img_width, int img_height, const void *in_memory) -{ - int n = 0; - nk_rune *dst; - const nk_byte *src; - - NK_ASSERT(out_memory); - NK_ASSERT(in_memory); - NK_ASSERT(img_width); - NK_ASSERT(img_height); - if (!out_memory || !in_memory || !img_height || !img_width) { - return; - } - - dst = (nk_rune *)out_memory; - src = (const nk_byte *)in_memory; - for (n = (int)(img_width * img_height); n > 0; n--) { - *dst++ = ((nk_rune)(*src++) << 24) | 0x00FFFFFF; - } -} - -/* ------------------------------------------------------------- - * - * FONT - * - * --------------------------------------------------------------*/ -NK_INTERN void -nk_font_init(struct nk_font *font, - float pixel_height, - struct nk_font_glyph *glyphs, - const struct nk_baked_font *baked_font, - nk_handle atlas) -{ - NK_ASSERT(font); - NK_ASSERT(glyphs); - NK_ASSERT(baked_font); - if (!font || !glyphs || !baked_font) { - return; - } - - font->info = *baked_font; - font->glyphs = &glyphs[baked_font->glyph_offset]; - font->texture = atlas; - font->handle.height = pixel_height; - font->handle.userdata.ptr = font; -# ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT - font->handle.texture = font->texture; -# endif -} - -/* --------------------------------------------------------------------------- - * - * DEFAULT FONT - * - * ProggyClean.ttf - * Copyright (c) 2004, 2005 Tristan Grimmer - * MIT license https://github.com/bluescan/proggyfonts/blob/master/LICENSE - * Download and more information at https://github.com/bluescan/proggyfonts - *-----------------------------------------------------------------------------*/ -# ifdef __clang__ -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Woverlength-strings" -# elif defined(__GNUC__) || defined(__GNUG__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Woverlength-strings" -# endif - -# ifdef NK_INCLUDE_DEFAULT_FONT - -NK_GLOBAL const char nk_proggy_clean_ttf_compressed_data_base85[11980 + 1] = - "7])#######hV0qs'/###[),##/l:$#Q6>##5[n42>c-TH`->>#/" - "e>11NNV=Bv(*:.F?uu#(gRU.o0XGH`$vhLG1hxt9?W`#,5LsCp#-i>.r$<$6pD>Lb';9Crc6tgXmKVeU2cD4Eo3R/" - "2*>]b(MC;$jPfY.;h^`IWM9Qo#t'X#(v#Y9w0#1D$CIf;W'#pWUPXOuxXuU(H9M(1=Ke$$'5F%)]0^#0X@U.a$FBjVQTSDgEKnIS7EM9>ZY9w0#L;>>#Mx&4Mvt//" - "L[MkA#W@lK.N'[0#7RL_&#w+F%HtG9M#XL`N&.,GM4Pg;--VsM.M0rJfLH2eTM`*oJMHRC`N" - "kfimM2J,W-jXS:)r0wK#@Fge$U>`w'N7G#$#fB#$E^$#:9:hk+eOe--6x)F7*E%?76%^GMHePW-Z5l'&GiF#$956:rS?dA#fiK:)Yr+`�j@'DbG&#^" - "$PG.Ll+DNa&VZ>1i%h1S9u5o@YaaW$e+bROPOpxTO7Stwi1::iB1q)C_=dV26J;2,]7op$]uQr@_V7$q^%lQwtuHY]=DX,n3L#0PHDO4f9>dC@O>HBuKPpP*E,N+b3L#" - "lpR/MrTEH.IAQk.a>D[.e;mc." - "x]Ip.PH^'/aqUO/$1WxLoW0[iLAw=4h(9.`G" - "CRUxHPeR`5Mjol(dUWxZa(>STrPkrJiWx`5U7F#.g*jrohGg`cg:lSTvEY/" - "EV_7H4Q9[Z%cnv;JQYZ5q.l7Zeas:HOIZOB?Ggv:[7MI2k).'2($5FNP&EQ(,)" - "U]W]+fh18.vsai00);D3@4ku5P?DP8aJt+;qUM]=+b'8@;mViBKx0DE[-auGl8:PJ&Dj+M6OC]O^((##]`0i)drT;-7X`=-H3[igUnPG-NZlo.#k@h#=" - "Ork$m>a>$-?Tm$UV(?#P6YY#" - "'/###xe7q.73rI3*pP/$1>s9)W,JrM7SN]'/4C#v$U`0#V.[0>xQsH$fEmPMgY2u7Kh(G%siIfLSoS+MK2eTM$=5,M8p`A.;_R%#u[K#$x4AG8.kK/" - "HSB==-'Ie/QTtG?-.*^N-4B/ZM" - "_3YlQC7(p7q)&](`6_c)$/*JL(L-^(]$wIM`dPtOdGA,U3:w2M-0+WomX2u7lqM2iEumMTcsF?-aT=Z-97UEnXglEn1K-bnEO`gu" - "Ft(c%=;Am_Qs@jLooI&NX;]0#j4#F14;gl8-GQpgwhrq8'=l_f-b49'UOqkLu7-##oDY2L(te+Mch&gLYtJ,MEtJfLh'x'M=$CS-ZZ%P]8bZ>#S?YY#%" - "Q&q'3^Fw&?D)UDNrocM3A76/" - "/oL?#h7gl85[qW/" - "NDOk%16ij;+:1a'iNIdb-ou8.P*w,v5#EI$TWS>Pot-R*H'-SEpA:g)f+O$%%`kA#G=8RMmG1&O`>to8bC]T&$,n.LoO>29sp3dt-52U%VM#q7'DHpg+" - "#Z9%H[Ket`e;)f#Km8&+DC$I46>#Kr]]u-[=99tts1.qb#" - "q72g1WJO81q+eN'03'eM>&1XxY-caEnO" - "j%2n8)),?ILR5^.Ibn<-X-Mq7[a82Lq:F&#ce+S9wsCK*x`569E8ew'He]h:sI[2LM$[guka3ZRd6:t%IG:;$%YiJ:Nq=?eAw;/" - ":nnDq0(CYcMpG)qLN4$##&J-XTt,%OVU4)S1+R-#dg0/" - "Nn?Ku1^0f$B*P:Rowwm-`0PKjYDDM'3]d39VZHEl4,.j']Pk-M.h^&:0FACm$maq-&sgw0t7/6(^xtk%" - "LuH88Fj-ekm>GA#_>568x6(OFRl-IZp`&b,_P'$MhLbxfc$mj`,O;&%W2m`Zh:/" - ")Uetw:aJ%]K9h:TcF]u_-Sj9,VK3M.*'&0D[Ca]J9gp8,kAW]" - "%(?A%R$f<->Zts'^kn=-^@c4%-pY6qI%J%1IGxfLU9CP8cbPlXv);C=b),<2mOvP8up,UVf3839acAWAW-W?#ao/" - "^#%KYo8fRULNd2.>%m]UK:n%r$'sw]J;5pAoO_#2mO3n,'=H5(et" - "Hg*`+RLgv>=4U8guD$I%D:W>-r5V*%j*W:Kvej.Lp$'?;++O'>()jLR-^u68PHm8ZFWe+ej8h:9r6L*0//c&iH&R8pRbA#Kjm%upV1g:" - "a_#Ur7FuA#(tRh#.Y5K+@?3<-8m0$PEn;J:rh6?I6uG<-`wMU'ircp0LaE_OtlMb&1#6T.#FDKu#1Lw%u%+GM+X'e?YLfjM[VO0MbuFp7;>Q&#WIo)0@" - "F%q7c#4XAXN-U&VBpqB>0ie&jhZ[?iLR@@_AvA-iQC(=ksRZRVp7`.=+NpBC%rh&3]R:8XDmE5^V8O(x<-+k?'(^](H.aREZSi,#1:[IXaZFOm<-ui#qUq2$##Ri;u75OK#(RtaW-K-F`S+cF]uN`-" - "KMQ%rP/Xri.LRcB##=YL3BgM/3M" - "D?@f&1'BW-)Ju#bmmWCMkk&#TR`C,5d>g)F;t,4:@_l8G/" - "5h4vUd%&%950:VXD'QdWoY-F$BtUwmfe$YqL'8(PWX(" - "P?^@Po3$##`MSs?DWBZ/S>+4%>fX,VWv/w'KD`LP5IbH;rTV>n3cEK8U#bX]l-/" - "V+^lj3;vlMb&[5YQ8#pekX9JP3XUC72L,,?+Ni&co7ApnO*5NK,((W-i:$,kp'UDAO(G0Sq7MVjJs" - "bIu)'Z,*[>br5fX^:FPAWr-m2KgLQ_nN6'8uTGT5g)uLv:873UpTLgH+#FgpH'_o1780Ph8KmxQJ8#H72L4@768@Tm&Q" - "h4CB/5OvmA&,Q&QbUoi$a_%3M01H)4x7I^&KQVgtFnV+;[Pc>[m4k//" - ",]1?#`VY[Jr*3&&slRfLiVZJ:]?=K3Sw=[$=uRB?3xk48@aege0jT6'N#(q%.O=?2S]u*(m<-" - "V8J'(1)G][68hW$5'q[GC&5j`TE?m'esFGNRM)j,ffZ?-qx8;->g4t*:CIP/[Qap7/" - "9'#(1sao7w-.qNUdkJ)tCF&#B^;xGvn2r9FEPFFFcL@.iFNkTve$m%#QvQS8U@)2Z+3K:AKM5i" - "sZ88+dKQ)W6>J%CL`.d*(B`-n8D9oK-XV1q['-5k'cAZ69e;D_?$ZPP&s^+7])$*$#@QYi9,5P r+$%CE=68>K8r0=dSC%%(@p7" - ".m7jilQ02'0-VWAgTlGW'b)Tq7VT9q^*^$$.:&N@@" - "$&)WHtPm*5_rO0&e%K&#-30j(E4#'Zb.o/(Tpm$>K'f@[PvFl,hfINTNU6u'0pao7%XUp9]5.>%h`8_=VYbxuel.NTSsJfLacFu3B'lQSu/" - "m6-Oqem8T+oE--$0a/k]uj9EwsG>%veR*" - "hv^BFpQj:K'#SJ,sB-'#](j.Lg92rTw-*n%@/;39rrJF,l#qV%OrtBeC6/" - ",;qB3ebNW[?,Hqj2L.1NP&GjUR=1D8QaS3Up&@*9wP?+lo7b?@%'k4`p0Z$22%K3+iCZj?XJN4Nm&+YF]u" - "@-W$U%VEQ/,,>>#)D#%8cY#YZ?=,`Wdxu/ae&#" - "w6)R89tI#6@s'(6Bf7a&?S=^ZI_kS&ai`&=tE72L_D,;^R)7[$so8lKN%5/$(vdfq7+ebA#" - "u1p]ovUKW&Y%q]'>$1@-[xfn$7ZTp7mM,G,Ko7a&Gu%G[RMxJs[0MM%wci.LFDK)(%:_i2B5CsR8&9Z&#=mPEnm0f`<&c)QL5uJ#%u%lJj+D-r;BoFDoS97h5g)E#o:&S4weDF,9^Hoe`h*L+_a*" - "NrLW-1pG_&2UdB8" - "6e%B/:=>)N4xeW.*wft-;$'58-ESqr#U`'6AQ]m&6/" - "`Z>#S?YY#Vc;r7U2&326d=w&H####?TZ`*4?&.MK?LP8Vxg>$[QXc%QJv92.(Db*B)gb*BM9dM*hJMAo*c&#" - "b0v=Pjer]$gG&JXDf->'StvU7505l9$AFvgYRI^&<^b68?j#q9QX4SM'RO#&sL1IM.rJfLUAj221]d##DW=m83u5;'bYx,*Sl0hL(W;;$doB&O/" - "TQ:(Z^xBdLjLV#*8U_72Lh+2Q8Cj0i:6hp&$C/:p(HK>T8Y[gHQ4`4)'$Ab(Nof%V'8hL&#SfD07&6D@M.*J:;$-rv29'M]8qMv-tLp,'886iaC=Hb*YJoKJ,(j%K=H`K.v9HggqBIiZu'QvBT.#=)0ukruV&.)3=(^1`o*" - "Pj4<-#MJ+gLq9-##@HuZPN0]u:h7.T..G:;$/" - "Usj(T7`Q8tT72LnYl<-qx8;-HV7Q-&Xdx%1a,hC=0u+HlsV>nuIQL-5" - "_>@kXQtMacfD.m-VAb8;IReM3$wf0''hra*so568'Ip&vRs849'MRYSp%:t:h5qSgwpEr$B>Q,;s(C#$)`svQuF$##-D,##,g68@2[T;.XSdN9Qe)" - "rpt._K-#5wF)sP'##p#C0c%-Gb%" - "hd+<-j'Ai*x&&HMkT]C'OSl##5RG[JXaHN;d'uA#x._U;.`PU@(Z3dt4r152@:v,'R.Sj'w#0<-;kPI)FfJ&#AYJ&#//" - ")>-k=m=*XnK$>=)72L]0I%>.G690a:$##<,);?;72#?x9+d;" - "^V'9;jY@;)br#q^YQpx:X#Te$Z^'=-=bGhLf:D6&bNwZ9-ZD#n^9HhLMr5G;']d&6'wYmTFmLq9wI>P(9mI[>kC-" - "ekLC/R&CH+s'B;K-M6$EB%is00:" - "+A4[7xks.LrNk0&E)wILYF@2L'0Nb$+pv<(2.768/" - "FrY&h$^3i&@+G%JT'<-,v`3;_)I9M^AE]CN?Cl2AZg+%4iTpT3$" - "U4O]GKx'm9)b@p7YsvK3w^YR-" - "CdQ*:Ir<($u&)#(&?L9Rg3H)4fiEp^iI9O8KnTj,]H?D*r7'M;PwZ9K0E^k&-cpI;.p/6_vwoFMV<->#%Xi.LxVnrU(4&8/" - "P+:hLSKj$#U%]49t'I:rgMi'FL@a:0Y-uA[39',(vbma*" - "hU%<-SRF`Tt:542R_VV$p@[p8DV[A,?1839FWdFTi1O*H&#(AL8[_P%.M>v^-))qOT*F5Cq0`Ye%+$B6i:7@0IX<" - "N+T+0MlMBPQ*Vj>SsDiWP,##P`%/L-" - "S(qw%sf/@%#B6;/" - "U7K]uZbi^Oc^2n%t<)'mEVE''n`WnJra$^TKvX5B>;_aSEK',(hwa0:i4G?.Bci.(X[?b*($,=-n<.Q%`(X=?+@Am*Js0&=3bh8K]mL<" - "LoNs'6,'85`" - "0?t/'_U59@]ddF<#LdF69=Lb,OcZV/);TTm8VI;?%OtJ<(b4mq7M6:u?KRdFl*:xP?Yb.5)%w_I?7uk5JC+FS(m#i'k.'a0i)9<7b'fs'59hq$*5Uhv##pi^8+hIEBF`nvo`;'l0.^S1<-" - "wUK2/Coh58KKhLj" - "M=SO*rfO`+qC`W-On.=AJ56>>i2@2LH6A:&5q`?9I3@@'04&p2/" - "LVa*T-4<-i3;M9UvZd+N7>b*eIwg:CC)c<>nO&#$(>.Z-I&J(Q0Hd5Q%7Co-b`-cP)hI;*_F]u`Rb[.j8_Q/<&>uu+VsH$sM9TA%?)(vmJ80),P7E>)tjD%2L=-t#fK[%`v=Q8WlA2);Sa" - ">gXm8YB`1d@K#n]76-a$U,mF%Ul:#/'xoFM9QX-$.QN'>" - "[%$Z$uF6pA6Ki2O5:8w*vP1<-1`[G,)-m#>0`P&#eb#.3i)rtB61(o'$?X3B2Qft^ae_5tKL9MUe9b*sLEQ95C&`=G?@Mj=wh*'3E>=-<)Gt*Iw)'QG:`@I" - "wOf7&]1i'S01B+Ev/Nac#9S;=;YQpg_6U`*kVY39xK,[/" - "6Aj7:'1Bm-_1EYfa1+o&o4hp7KN_Q(OlIo@S%;jVdn0'1h19w,WQhLI)3S#f$2(eb,jr*b;3Vw]*7NH%$c4Vs,eD9>XW8?N]o+(*pgC%/" - "72LV-uW%iewS8W6m2rtCpo'RS1R84=@paTKt)>=%&1[)*vp'u+x,VrwN;&]kuO9JDbg=pO$J*.jVe;u'm0dr9l,<*wMK*Oe=" - "g8lV_KEBFkO'oU]^=[-792#ok,)" - "i]lR8qQ2oA8wcRCZ^7w/Njh;?.stX?Q1>S1q4Bn$)K1<-rGdO'$Wr.Lc.CG)$/*JL4tNR/" - ",SVO3,aUw'DJN:)Ss;wGn9A32ijw%FL+Z0Fn.U9;reSq)bmI32U==5ALuG&#Vf1398/pVo" - "1*c-(aY168o<`JsSbk-,1N;$>0:OUas(3:8Z972LSfF8eb=c-;>SPw7.6hn3m`9^Xkn(r.qS[0;T%&Qc=+STRxX'q1BNk3&*eu2;&8q$&x>Q#Q7^Tf+" - "6<(d%ZVmj2bDi%.3L2n+4W'$P" - "iDDG)g,r%+?,$@?uou5tSe2aN_AQU*'IAO" - "URQ##V^Fv-XFbGM7Fl(N<3DhLGF%q.1rC$#:T__&Pi68%0xi_&[qFJ(77j_&JWoF.V735&T,[R*:xFR*K5>>#`bW-?4Ne_&6Ne_&6Ne_&n`kr-#" - "GJcM6X;uM6X;uM(.a..^2TkL%oR(#" - ";u.T%fAr%4tJ8&><1=GHZ_+m9/#H1F^R#SC#*N=BA9(D?v[UiFY>>^8p,KKF.W]L29uLkLlu/" - "+4T" - "w$)F./^n3+rlo+DB;5sIYGNk+i1t-69Jg--0pao7Sm#K)pdHW&;LuDNH@H>#/" - "X-TI(;P>#,Gc>#0Su>#4`1?#8lC?#xL$#B.`$#F:r$#JF.%#NR@%#R_R%#Vke%#Zww%#_-4^Rh%Sflr-k'MS.o?.5/sWel/wpEM0%3'/" - "1)K^f1-d>G21&v(35>V`39V7A4=onx4" - "A1OY5EI0;6Ibgr6M$HS7Q<)58C5w,;WoA*#[%T*#`1g*#d=#+#hI5+#lUG+#pbY+#tnl+#x$),#&1;,#*=M,#.I`,#2Ur,#6b.-#;w[H#iQtA#m^0B#" - "qjBB#uvTB##-hB#'9$C#+E6C#" - "/QHC#3^ZC#7jmC#;v)D#?,)4kMYD4lVu`4m`:&5niUA5@(A5BA1]PBB:xlBCC=2CDLXMCEUtiCf&0g2'tN?" - "PGT4CPGT4CPGT4CPGT4CPGT4CPGT4CPGT4CP" - "GT4CPGT4CPGT4CPGT4CPGT4CPGT4CP-qekC`.9kEg^+F$kwViFJTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&" - "5KTB&5KTB&5o,^<-28ZI'O?;xp" - "O?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xp;7q-#lLYI:xvD=#"; - -# endif /* NK_INCLUDE_DEFAULT_FONT */ - -# define NK_CURSOR_DATA_W 90 -# define NK_CURSOR_DATA_H 27 -NK_GLOBAL const char nk_custom_cursor_data[NK_CURSOR_DATA_W * NK_CURSOR_DATA_H + 1] = { - "..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX" - "..- -X.....X- X.X - X.X -X.....X - X.....X" - "--- -XXX.XXX- X...X - X...X -X....X - X....X" - "X - X.X - X.....X - X.....X -X...X - X...X" - "XX - X.X -X.......X- X.......X -X..X.X - X.X..X" - "X.X - X.X -XXXX.XXXX- XXXX.XXXX -X.X X.X - X.X X.X" - "X..X - X.X - X.X - X.X -XX X.X - X.X XX" - "X...X - X.X - X.X - XX X.X XX - X.X - X.X " - "X....X - X.X - X.X - X.X X.X X.X - X.X - X.X " - "X.....X - X.X - X.X - X..X X.X X..X - X.X - X.X " - "X......X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X XX-XX X.X " - "X.......X - X.X - X.X -X.....................X- X.X X.X-X.X X.X " - "X........X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X..X-X..X.X " - "X.........X -XXX.XXX- X.X - X..X X.X X..X - X...X-X...X " - "X..........X-X.....X- X.X - X.X X.X X.X - X....X-X....X " - "X......XXXXX-XXXXXXX- X.X - XX X.X XX - X.....X-X.....X " - "X...X..X --------- X.X - X.X - XXXXXXX-XXXXXXX " - "X..X X..X - -XXXX.XXXX- XXXX.XXXX ------------------------------------" - "X.X X..X - -X.......X- X.......X - XX XX - " - "XX X..X - - X.....X - X.....X - X.X X.X - " - " X..X - X...X - X...X - X..X X..X - " - " XX - X.X - X.X - X...XXXXXXXXXXXXX...X - " - "------------ - X - X -X.....................X- " - " ----------------------------------- X...XXXXXXXXXXXXX...X - " - " - X..X X..X - " - " - X.X X.X - " - " - XX XX - "}; - -# ifdef __clang__ -# pragma clang diagnostic pop -# elif defined(__GNUC__) || defined(__GNUG__) -# pragma GCC diagnostic pop -# endif - -NK_GLOBAL unsigned char *nk__barrier; -NK_GLOBAL unsigned char *nk__barrier2; -NK_GLOBAL unsigned char *nk__barrier3; -NK_GLOBAL unsigned char *nk__barrier4; -NK_GLOBAL unsigned char *nk__dout; - -NK_INTERN unsigned int -nk_decompress_length(unsigned char *input) -{ - return (unsigned int)((input[8] << 24) + (input[9] << 16) + (input[10] << 8) + input[11]); -} -NK_INTERN void -nk__match(unsigned char *data, unsigned int length) -{ - /* INVERSE of memmove... write each byte before copying the next...*/ - NK_ASSERT(nk__dout + length <= nk__barrier); - if (nk__dout + length > nk__barrier) { - nk__dout += length; - return; - } - if (data < nk__barrier4) { - nk__dout = nk__barrier + 1; - return; - } - while (length--) { - *nk__dout++ = *data++; - } -} -NK_INTERN void -nk__lit(unsigned char *data, unsigned int length) -{ - NK_ASSERT(nk__dout + length <= nk__barrier); - if (nk__dout + length > nk__barrier) { - nk__dout += length; - return; - } - if (data < nk__barrier2) { - nk__dout = nk__barrier + 1; - return; - } - NK_MEMCPY(nk__dout, data, (nk_size)length); - nk__dout += length; -} -NK_INTERN unsigned char * -nk_decompress_token(unsigned char *i) -{ -# define nk__in2(x) ((i[x] << 8) + i[(x) + 1]) -# define nk__in3(x) ((i[x] << 16) + nk__in2((x) + 1)) -# define nk__in4(x) ((i[x] << 24) + nk__in3((x) + 1)) - - if (*i >= 0x20) { /* use fewer if's for cases that expand small */ - if (*i >= 0x80) { - nk__match(nk__dout - i[1] - 1, (unsigned int)i[0] - 0x80 + 1), i += 2; - } else if (*i >= 0x40) { - nk__match(nk__dout - (nk__in2(0) - 0x4000 + 1), (unsigned int)i[2] + 1), i += 3; - } else { /* *i >= 0x20 */ - nk__lit(i + 1, (unsigned int)i[0] - 0x20 + 1), i += 1 + (i[0] - 0x20 + 1); - } - } else { /* more ifs for cases that expand large, since overhead is amortized */ - if (*i >= 0x18) { - nk__match(nk__dout - (unsigned int)(nk__in3(0) - 0x180000 + 1), (unsigned int)i[3] + 1), i += 4; - } else if (*i >= 0x10) { - nk__match(nk__dout - (unsigned int)(nk__in3(0) - 0x100000 + 1), (unsigned int)nk__in2(3) + 1), i += 5; - } else if (*i >= 0x08) { - nk__lit(i + 2, (unsigned int)nk__in2(0) - 0x0800 + 1), i += 2 + (nk__in2(0) - 0x0800 + 1); - } else if (*i == 0x07) { - nk__lit(i + 3, (unsigned int)nk__in2(1) + 1), i += 3 + (nk__in2(1) + 1); - } else if (*i == 0x06) { - nk__match(nk__dout - (unsigned int)(nk__in3(1) + 1), i[4] + 1u), i += 5; - } else if (*i == 0x04) { - nk__match(nk__dout - (unsigned int)(nk__in3(1) + 1), (unsigned int)nk__in2(4) + 1u), i += 6; - } - } - return i; -} -NK_INTERN unsigned int -nk_adler32(unsigned int adler32, unsigned char *buffer, unsigned int buflen) -{ - const unsigned long ADLER_MOD = 65521; - unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16; - unsigned long blocklen, i; - - blocklen = buflen % 5552; - while (buflen) { - for (i = 0; i + 7 < blocklen; i += 8) { - s1 += buffer[0]; - s2 += s1; - s1 += buffer[1]; - s2 += s1; - s1 += buffer[2]; - s2 += s1; - s1 += buffer[3]; - s2 += s1; - s1 += buffer[4]; - s2 += s1; - s1 += buffer[5]; - s2 += s1; - s1 += buffer[6]; - s2 += s1; - s1 += buffer[7]; - s2 += s1; - buffer += 8; - } - for (; i < blocklen; ++i) { - s1 += *buffer++; - s2 += s1; - } - - s1 %= ADLER_MOD; - s2 %= ADLER_MOD; - buflen -= (unsigned int)blocklen; - blocklen = 5552; - } - return (unsigned int)(s2 << 16) + (unsigned int)s1; -} -NK_INTERN unsigned int -nk_decompress(unsigned char *output, unsigned char *i, unsigned int length) -{ - unsigned int olen; - if (nk__in4(0) != 0x57bC0000) { - return 0; - } - if (nk__in4(4) != 0) { - return 0; /* error! stream is > 4GB */ - } - olen = nk_decompress_length(i); - nk__barrier2 = i; - nk__barrier3 = i + length; - nk__barrier = output + olen; - nk__barrier4 = output; - i += 16; - - nk__dout = output; - for (;;) { - unsigned char *old_i = i; - i = nk_decompress_token(i); - if (i == old_i) { - if (*i == 0x05 && i[1] == 0xfa) { - NK_ASSERT(nk__dout == output + olen); - if (nk__dout != output + olen) { - return 0; - } - if (nk_adler32(1, output, olen) != (unsigned int)nk__in4(2)) { - return 0; - } - return olen; - } else { - NK_ASSERT(0); /* NOTREACHED */ - return 0; - } - } - NK_ASSERT(nk__dout <= output + olen); - if (nk__dout > output + olen) { - return 0; - } - } -} -NK_INTERN unsigned int -nk_decode_85_byte(char c) -{ - return (unsigned int)((c >= '\\') ? c - 36 : c - 35); -} -NK_INTERN void -nk_decode_85(unsigned char *dst, const unsigned char *src) -{ - while (*src) { - unsigned int tmp = - nk_decode_85_byte((char)src[0]) + - 85 * (nk_decode_85_byte((char)src[1]) + 85 * (nk_decode_85_byte((char)src[2]) + 85 * (nk_decode_85_byte((char)src[3]) + 85 * nk_decode_85_byte((char)src[4])))); - - /* we can't assume little-endianess. */ - dst[0] = (unsigned char)((tmp >> 0) & 0xFF); - dst[1] = (unsigned char)((tmp >> 8) & 0xFF); - dst[2] = (unsigned char)((tmp >> 16) & 0xFF); - dst[3] = (unsigned char)((tmp >> 24) & 0xFF); - - src += 5; - dst += 4; - } -} - -/* ------------------------------------------------------------- - * - * FONT ATLAS - * - * --------------------------------------------------------------*/ -NK_API struct nk_font_config -nk_font_config(float pixel_height) -{ - struct nk_font_config cfg; - nk_zero_struct(cfg); - cfg.ttf_blob = 0; - cfg.ttf_size = 0; - cfg.ttf_data_owned_by_atlas = 0; - cfg.size = pixel_height; - cfg.oversample_h = 3; - cfg.oversample_v = 1; - cfg.pixel_snap = 0; - cfg.coord_type = NK_COORD_UV; - cfg.spacing = nk_vec2(0, 0); - cfg.range = nk_font_default_glyph_ranges(); - cfg.merge_mode = 0; - cfg.font = 0; - cfg.n = 0; - return cfg; -} -# ifdef NK_INCLUDE_DEFAULT_ALLOCATOR -NK_API void -nk_font_atlas_init_default(struct nk_font_atlas *atlas) -{ - NK_ASSERT(atlas); - if (!atlas) { - return; - } - nk_zero_struct(*atlas); - atlas->temporary.userdata.ptr = 0; - atlas->temporary.alloc = nk_malloc; - atlas->temporary.free = nk_mfree; - atlas->permanent.userdata.ptr = 0; - atlas->permanent.alloc = nk_malloc; - atlas->permanent.free = nk_mfree; -} -# endif -NK_API void -nk_font_atlas_init(struct nk_font_atlas *atlas, const struct nk_allocator *alloc) -{ - NK_ASSERT(atlas); - NK_ASSERT(alloc); - if (!atlas || !alloc) { - return; - } - nk_zero_struct(*atlas); - atlas->permanent = *alloc; - atlas->temporary = *alloc; -} -NK_API void -nk_font_atlas_init_custom(struct nk_font_atlas *atlas, const struct nk_allocator *permanent, const struct nk_allocator *temporary) -{ - NK_ASSERT(atlas); - NK_ASSERT(permanent); - NK_ASSERT(temporary); - if (!atlas || !permanent || !temporary) { - return; - } - nk_zero_struct(*atlas); - atlas->permanent = *permanent; - atlas->temporary = *temporary; -} -NK_API void -nk_font_atlas_begin(struct nk_font_atlas *atlas) -{ - NK_ASSERT(atlas); - NK_ASSERT(atlas->temporary.alloc && atlas->temporary.free); - NK_ASSERT(atlas->permanent.alloc && atlas->permanent.free); - if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free || !atlas->temporary.alloc || !atlas->temporary.free) { - return; - } - if (atlas->glyphs) { - atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs); - atlas->glyphs = 0; - } - if (atlas->pixel) { - atlas->permanent.free(atlas->permanent.userdata, atlas->pixel); - atlas->pixel = 0; - } -} -NK_API struct nk_font * -nk_font_atlas_add(struct nk_font_atlas *atlas, const struct nk_font_config *config) -{ - struct nk_font *font = 0; - struct nk_font_config *cfg; - - NK_ASSERT(atlas); - NK_ASSERT(atlas->permanent.alloc); - NK_ASSERT(atlas->permanent.free); - NK_ASSERT(atlas->temporary.alloc); - NK_ASSERT(atlas->temporary.free); - - NK_ASSERT(config); - NK_ASSERT(config->ttf_blob); - NK_ASSERT(config->ttf_size); - NK_ASSERT(config->size != 0.0f); - - if (!atlas || !config || !config->ttf_blob || !config->ttf_size || config->size == 0.0f || !atlas->permanent.alloc || !atlas->permanent.free || !atlas->temporary.alloc || - !atlas->temporary.free) { - return 0; - } - - /* allocate font config */ - cfg = (struct nk_font_config *)atlas->permanent.alloc(atlas->permanent.userdata, 0, sizeof(struct nk_font_config)); - NK_MEMCPY(cfg, config, sizeof(*config)); - cfg->n = cfg; - cfg->p = cfg; - - if (!config->merge_mode) { - /* insert font config into list */ - if (!atlas->config) { - atlas->config = cfg; - cfg->next = 0; - } else { - struct nk_font_config *i = atlas->config; - while (i->next) { - i = i->next; - } - i->next = cfg; - cfg->next = 0; - } - /* allocate new font */ - font = (struct nk_font *)atlas->permanent.alloc(atlas->permanent.userdata, 0, sizeof(struct nk_font)); - NK_ASSERT(font); - nk_zero(font, sizeof(*font)); - if (!font) { - return 0; - } - font->config = cfg; - - /* insert font into list */ - if (!atlas->fonts) { - atlas->fonts = font; - font->next = 0; - } else { - struct nk_font *i = atlas->fonts; - while (i->next) { - i = i->next; - } - i->next = font; - font->next = 0; - } - cfg->font = &font->info; - } else { - /* extend previously added font */ - struct nk_font *f = 0; - struct nk_font_config *c = 0; - NK_ASSERT(atlas->font_num); - f = atlas->fonts; - c = f->config; - cfg->font = &f->info; - - cfg->n = c; - cfg->p = c->p; - c->p->n = cfg; - c->p = cfg; - } - /* create own copy of .TTF font blob */ - if (!config->ttf_data_owned_by_atlas) { - cfg->ttf_blob = atlas->permanent.alloc(atlas->permanent.userdata, 0, cfg->ttf_size); - NK_ASSERT(cfg->ttf_blob); - if (!cfg->ttf_blob) { - atlas->font_num++; - return 0; - } - NK_MEMCPY(cfg->ttf_blob, config->ttf_blob, cfg->ttf_size); - cfg->ttf_data_owned_by_atlas = 1; - } - atlas->font_num++; - return font; -} -NK_API struct nk_font * -nk_font_atlas_add_from_memory(struct nk_font_atlas *atlas, void *memory, nk_size size, float height, const struct nk_font_config *config) -{ - struct nk_font_config cfg; - NK_ASSERT(memory); - NK_ASSERT(size); - - NK_ASSERT(atlas); - NK_ASSERT(atlas->temporary.alloc); - NK_ASSERT(atlas->temporary.free); - NK_ASSERT(atlas->permanent.alloc); - NK_ASSERT(atlas->permanent.free); - if (!atlas || !atlas->temporary.alloc || !atlas->temporary.free || !memory || !size || !atlas->permanent.alloc || !atlas->permanent.free) { - return 0; - } - - cfg = (config) ? *config : nk_font_config(height); - cfg.ttf_blob = memory; - cfg.ttf_size = size; - cfg.size = height; - cfg.ttf_data_owned_by_atlas = 0; - return nk_font_atlas_add(atlas, &cfg); -} -# ifdef NK_INCLUDE_STANDARD_IO -NK_API struct nk_font * -nk_font_atlas_add_from_file(struct nk_font_atlas *atlas, const char *file_path, float height, const struct nk_font_config *config) -{ - nk_size size; - char *memory; - struct nk_font_config cfg; - - NK_ASSERT(atlas); - NK_ASSERT(atlas->temporary.alloc); - NK_ASSERT(atlas->temporary.free); - NK_ASSERT(atlas->permanent.alloc); - NK_ASSERT(atlas->permanent.free); - - if (!atlas || !file_path) { - return 0; - } - memory = nk_file_load(file_path, &size, &atlas->permanent); - if (!memory) { - return 0; - } - - cfg = (config) ? *config : nk_font_config(height); - cfg.ttf_blob = memory; - cfg.ttf_size = size; - cfg.size = height; - cfg.ttf_data_owned_by_atlas = 1; - return nk_font_atlas_add(atlas, &cfg); -} -# endif -NK_API struct nk_font * -nk_font_atlas_add_compressed(struct nk_font_atlas *atlas, void *compressed_data, nk_size compressed_size, float height, const struct nk_font_config *config) -{ - unsigned int decompressed_size; - void *decompressed_data; - struct nk_font_config cfg; - - NK_ASSERT(atlas); - NK_ASSERT(atlas->temporary.alloc); - NK_ASSERT(atlas->temporary.free); - NK_ASSERT(atlas->permanent.alloc); - NK_ASSERT(atlas->permanent.free); - - NK_ASSERT(compressed_data); - NK_ASSERT(compressed_size); - if (!atlas || !compressed_data || !atlas->temporary.alloc || !atlas->temporary.free || !atlas->permanent.alloc || !atlas->permanent.free) { - return 0; - } - - decompressed_size = nk_decompress_length((unsigned char *)compressed_data); - decompressed_data = atlas->permanent.alloc(atlas->permanent.userdata, 0, decompressed_size); - NK_ASSERT(decompressed_data); - if (!decompressed_data) { - return 0; - } - nk_decompress((unsigned char *)decompressed_data, (unsigned char *)compressed_data, (unsigned int)compressed_size); - - cfg = (config) ? *config : nk_font_config(height); - cfg.ttf_blob = decompressed_data; - cfg.ttf_size = decompressed_size; - cfg.size = height; - cfg.ttf_data_owned_by_atlas = 1; - return nk_font_atlas_add(atlas, &cfg); -} -NK_API struct nk_font * -nk_font_atlas_add_compressed_base85(struct nk_font_atlas *atlas, const char *data_base85, float height, const struct nk_font_config *config) -{ - int compressed_size; - void *compressed_data; - struct nk_font *font; - - NK_ASSERT(atlas); - NK_ASSERT(atlas->temporary.alloc); - NK_ASSERT(atlas->temporary.free); - NK_ASSERT(atlas->permanent.alloc); - NK_ASSERT(atlas->permanent.free); - - NK_ASSERT(data_base85); - if (!atlas || !data_base85 || !atlas->temporary.alloc || !atlas->temporary.free || !atlas->permanent.alloc || !atlas->permanent.free) { - return 0; - } - - compressed_size = (((int)nk_strlen(data_base85) + 4) / 5) * 4; - compressed_data = atlas->temporary.alloc(atlas->temporary.userdata, 0, (nk_size)compressed_size); - NK_ASSERT(compressed_data); - if (!compressed_data) { - return 0; - } - nk_decode_85((unsigned char *)compressed_data, (const unsigned char *)data_base85); - font = nk_font_atlas_add_compressed(atlas, compressed_data, (nk_size)compressed_size, height, config); - atlas->temporary.free(atlas->temporary.userdata, compressed_data); - return font; -} - -# ifdef NK_INCLUDE_DEFAULT_FONT -NK_API struct nk_font * -nk_font_atlas_add_default(struct nk_font_atlas *atlas, float pixel_height, const struct nk_font_config *config) -{ - NK_ASSERT(atlas); - NK_ASSERT(atlas->temporary.alloc); - NK_ASSERT(atlas->temporary.free); - NK_ASSERT(atlas->permanent.alloc); - NK_ASSERT(atlas->permanent.free); - return nk_font_atlas_add_compressed_base85(atlas, nk_proggy_clean_ttf_compressed_data_base85, pixel_height, config); -} -# endif -NK_API const void * -nk_font_atlas_bake(struct nk_font_atlas *atlas, int *width, int *height, enum nk_font_atlas_format fmt) -{ - int i = 0; - void *tmp = 0; - nk_size tmp_size, img_size; - struct nk_font *font_iter; - struct nk_font_baker *baker; - - NK_ASSERT(atlas); - NK_ASSERT(atlas->temporary.alloc); - NK_ASSERT(atlas->temporary.free); - NK_ASSERT(atlas->permanent.alloc); - NK_ASSERT(atlas->permanent.free); - - NK_ASSERT(width); - NK_ASSERT(height); - if (!atlas || !width || !height || !atlas->temporary.alloc || !atlas->temporary.free || !atlas->permanent.alloc || !atlas->permanent.free) { - return 0; - } - -# ifdef NK_INCLUDE_DEFAULT_FONT - /* no font added so just use default font */ - if (!atlas->font_num) { - atlas->default_font = nk_font_atlas_add_default(atlas, 13.0f, 0); - } -# endif - NK_ASSERT(atlas->font_num); - if (!atlas->font_num) { - return 0; - } - - /* allocate temporary baker memory required for the baking process */ - nk_font_baker_memory(&tmp_size, &atlas->glyph_count, atlas->config, atlas->font_num); - tmp = atlas->temporary.alloc(atlas->temporary.userdata, 0, tmp_size); - NK_ASSERT(tmp); - if (!tmp) { - goto failed; - } - NK_MEMSET(tmp, 0, tmp_size); - - /* allocate glyph memory for all fonts */ - baker = nk_font_baker(tmp, atlas->glyph_count, atlas->font_num, &atlas->temporary); - atlas->glyphs = (struct nk_font_glyph *)atlas->permanent.alloc(atlas->permanent.userdata, 0, sizeof(struct nk_font_glyph) * (nk_size)atlas->glyph_count); - NK_ASSERT(atlas->glyphs); - if (!atlas->glyphs) { - goto failed; - } - - /* pack all glyphs into a tight fit space */ - atlas->custom.w = (NK_CURSOR_DATA_W * 2) + 1; - atlas->custom.h = NK_CURSOR_DATA_H + 1; - if (!nk_font_bake_pack(baker, &img_size, width, height, &atlas->custom, atlas->config, atlas->font_num, &atlas->temporary)) { - goto failed; - } - - /* allocate memory for the baked image font atlas */ - atlas->pixel = atlas->temporary.alloc(atlas->temporary.userdata, 0, img_size); - NK_ASSERT(atlas->pixel); - if (!atlas->pixel) { - goto failed; - } - - /* bake glyphs and custom white pixel into image */ - nk_font_bake(baker, atlas->pixel, *width, *height, atlas->glyphs, atlas->glyph_count, atlas->config, atlas->font_num); - nk_font_bake_custom_data(atlas->pixel, *width, *height, atlas->custom, nk_custom_cursor_data, NK_CURSOR_DATA_W, NK_CURSOR_DATA_H, '.', 'X'); - - if (fmt == NK_FONT_ATLAS_RGBA32) { - /* convert alpha8 image into rgba32 image */ - void *img_rgba = atlas->temporary.alloc(atlas->temporary.userdata, 0, (nk_size)(*width * *height * 4)); - NK_ASSERT(img_rgba); - if (!img_rgba) { - goto failed; - } - nk_font_bake_convert(img_rgba, *width, *height, atlas->pixel); - atlas->temporary.free(atlas->temporary.userdata, atlas->pixel); - atlas->pixel = img_rgba; - } - atlas->tex_width = *width; - atlas->tex_height = *height; - - /* initialize each font */ - for (font_iter = atlas->fonts; font_iter; font_iter = font_iter->next) { - struct nk_font *font = font_iter; - struct nk_font_config *config = font->config; - nk_font_init(font, NK_ABS(config->size), atlas->glyphs, config->font, nk_handle_ptr(0)); - } - - /* initialize each cursor */ - { - NK_STORAGE const struct nk_vec2 nk_cursor_data[NK_CURSOR_COUNT][3] = { - /* Pos Size Offset */ - { { 0, 3}, {12, 19}, { 0, 0}}, - { {13, 0}, { 7, 16}, { 4, 8}}, - { {31, 0}, {23, 23}, {11, 11}}, - { {21, 0}, { 9, 23}, { 5, 11}}, - { {55, 18}, {23, 9}, {11, 5}}, - { {73, 0}, {17, 17}, { 9, 9}}, - { {55, 0}, {17, 17}, { 9, 9}}, - }; - - for (i = 0; i < NK_CURSOR_COUNT; ++i) { - struct nk_cursor *cursor = &atlas->cursors[i]; - cursor->img.w = (unsigned short)*width; - cursor->img.h = (unsigned short)*height; - cursor->img.region[0] = (unsigned short)(atlas->custom.x + nk_cursor_data[i][0].x); - cursor->img.region[1] = (unsigned short)(atlas->custom.y + nk_cursor_data[i][0].y); - cursor->img.region[2] = (unsigned short)nk_cursor_data[i][1].x; - cursor->img.region[3] = (unsigned short)nk_cursor_data[i][1].y; - cursor->size = nk_cursor_data[i][1]; - cursor->offset = nk_cursor_data[i][2]; - } - } - /* free temporary memory */ - atlas->temporary.free(atlas->temporary.userdata, tmp); - return atlas->pixel; - -failed: - /* error so cleanup all memory */ - if (tmp) { - atlas->temporary.free(atlas->temporary.userdata, tmp); - } - if (atlas->glyphs) { - atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs); - atlas->glyphs = 0; - } - if (atlas->pixel) { - atlas->temporary.free(atlas->temporary.userdata, atlas->pixel); - atlas->pixel = 0; - } - return 0; -} -NK_API void -nk_font_atlas_end(struct nk_font_atlas *atlas, nk_handle texture, struct nk_draw_null_texture *tex_null) -{ - int i = 0; - struct nk_font *font_iter; - NK_ASSERT(atlas); - if (!atlas) { - if (!tex_null) { - return; - } - tex_null->texture = texture; - tex_null->uv = nk_vec2(0.5f, 0.5f); - } - if (tex_null) { - tex_null->texture = texture; - tex_null->uv.x = (atlas->custom.x + 0.5f) / (float)atlas->tex_width; - tex_null->uv.y = (atlas->custom.y + 0.5f) / (float)atlas->tex_height; - } - for (font_iter = atlas->fonts; font_iter; font_iter = font_iter->next) { - font_iter->texture = texture; -# ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT - font_iter->handle.texture = texture; -# endif - } - for (i = 0; i < NK_CURSOR_COUNT; ++i) { - atlas->cursors[i].img.handle = texture; - } - - atlas->temporary.free(atlas->temporary.userdata, atlas->pixel); - atlas->pixel = 0; - atlas->tex_width = 0; - atlas->tex_height = 0; - atlas->custom.x = 0; - atlas->custom.y = 0; - atlas->custom.w = 0; - atlas->custom.h = 0; -} -NK_API void -nk_font_atlas_cleanup(struct nk_font_atlas *atlas) -{ - NK_ASSERT(atlas); - NK_ASSERT(atlas->temporary.alloc); - NK_ASSERT(atlas->temporary.free); - NK_ASSERT(atlas->permanent.alloc); - NK_ASSERT(atlas->permanent.free); - if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free) { - return; - } - if (atlas->config) { - struct nk_font_config *iter; - for (iter = atlas->config; iter; iter = iter->next) { - struct nk_font_config *i; - for (i = iter->n; i != iter; i = i->n) { - atlas->permanent.free(atlas->permanent.userdata, i->ttf_blob); - i->ttf_blob = 0; - } - atlas->permanent.free(atlas->permanent.userdata, iter->ttf_blob); - iter->ttf_blob = 0; - } - } -} -NK_API void -nk_font_atlas_clear(struct nk_font_atlas *atlas) -{ - NK_ASSERT(atlas); - NK_ASSERT(atlas->temporary.alloc); - NK_ASSERT(atlas->temporary.free); - NK_ASSERT(atlas->permanent.alloc); - NK_ASSERT(atlas->permanent.free); - if (!atlas || !atlas->permanent.alloc || !atlas->permanent.free) { - return; - } - - if (atlas->config) { - struct nk_font_config *iter, *next; - for (iter = atlas->config; iter; iter = next) { - struct nk_font_config *i, *n; - for (i = iter->n; i != iter; i = n) { - n = i->n; - if (i->ttf_blob) { - atlas->permanent.free(atlas->permanent.userdata, i->ttf_blob); - } - atlas->permanent.free(atlas->permanent.userdata, i); - } - next = iter->next; - if (i->ttf_blob) { - atlas->permanent.free(atlas->permanent.userdata, iter->ttf_blob); - } - atlas->permanent.free(atlas->permanent.userdata, iter); - } - atlas->config = 0; - } - if (atlas->fonts) { - struct nk_font *iter, *next; - for (iter = atlas->fonts; iter; iter = next) { - next = iter->next; - atlas->permanent.free(atlas->permanent.userdata, iter); - } - atlas->fonts = 0; - } - if (atlas->glyphs) { - atlas->permanent.free(atlas->permanent.userdata, atlas->glyphs); - } - nk_zero_struct(*atlas); -} -#endif - -/* =============================================================== - * - * INPUT - * - * ===============================================================*/ -NK_API void -nk_input_begin(struct nk_context *ctx) -{ - int i; - struct nk_input *in; - NK_ASSERT(ctx); - if (!ctx) { - return; - } - in = &ctx->input; - for (i = 0; i < NK_BUTTON_MAX; ++i) { - in->mouse.buttons[i].clicked = 0; - } - - in->keyboard.text_len = 0; - in->mouse.scroll_delta = nk_vec2(0, 0); - in->mouse.prev.x = in->mouse.pos.x; - in->mouse.prev.y = in->mouse.pos.y; - in->mouse.delta.x = 0; - in->mouse.delta.y = 0; - for (i = 0; i < NK_KEY_MAX; i++) { - in->keyboard.keys[i].clicked = 0; - } -} -NK_API void -nk_input_end(struct nk_context *ctx) -{ - struct nk_input *in; - NK_ASSERT(ctx); - if (!ctx) { - return; - } - in = &ctx->input; - if (in->mouse.grab) { - in->mouse.grab = 0; - } - if (in->mouse.ungrab) { - in->mouse.grabbed = 0; - in->mouse.ungrab = 0; - in->mouse.grab = 0; - } -} -NK_API void -nk_input_motion(struct nk_context *ctx, int x, int y) -{ - struct nk_input *in; - NK_ASSERT(ctx); - if (!ctx) { - return; - } - in = &ctx->input; - in->mouse.pos.x = (float)x; - in->mouse.pos.y = (float)y; - in->mouse.delta.x = in->mouse.pos.x - in->mouse.prev.x; - in->mouse.delta.y = in->mouse.pos.y - in->mouse.prev.y; -} -NK_API void -nk_input_key(struct nk_context *ctx, enum nk_keys key, nk_bool down) -{ - struct nk_input *in; - NK_ASSERT(ctx); - if (!ctx) { - return; - } - in = &ctx->input; -#ifdef NK_KEYSTATE_BASED_INPUT - if (in->keyboard.keys[key].down != down) { - in->keyboard.keys[key].clicked++; - } -#else - in->keyboard.keys[key].clicked++; -#endif - in->keyboard.keys[key].down = down; -} -NK_API void -nk_input_button(struct nk_context *ctx, enum nk_buttons id, int x, int y, nk_bool down) -{ - struct nk_mouse_button *btn; - struct nk_input *in; - NK_ASSERT(ctx); - if (!ctx) { - return; - } - in = &ctx->input; - if (in->mouse.buttons[id].down == down) { - return; - } - - btn = &in->mouse.buttons[id]; - btn->clicked_pos.x = (float)x; - btn->clicked_pos.y = (float)y; - btn->down = down; - btn->clicked++; - - /* Fix Click-Drag for touch events. */ - in->mouse.delta.x = 0; - in->mouse.delta.y = 0; -#ifdef NK_BUTTON_TRIGGER_ON_RELEASE - if (down == 1 && id == NK_BUTTON_LEFT) { - in->mouse.down_pos.x = btn->clicked_pos.x; - in->mouse.down_pos.y = btn->clicked_pos.y; - } -#endif -} -NK_API void -nk_input_scroll(struct nk_context *ctx, struct nk_vec2 val) -{ - NK_ASSERT(ctx); - if (!ctx) { - return; - } - ctx->input.mouse.scroll_delta.x += val.x; - ctx->input.mouse.scroll_delta.y += val.y; -} -NK_API void -nk_input_glyph(struct nk_context *ctx, const nk_glyph glyph) -{ - int len = 0; - nk_rune unicode; - struct nk_input *in; - - NK_ASSERT(ctx); - if (!ctx) { - return; - } - in = &ctx->input; - - len = nk_utf_decode(glyph, &unicode, NK_UTF_SIZE); - if (len && ((in->keyboard.text_len + len) < NK_INPUT_MAX)) { - nk_utf_encode(unicode, &in->keyboard.text[in->keyboard.text_len], NK_INPUT_MAX - in->keyboard.text_len); - in->keyboard.text_len += len; - } -} -NK_API void -nk_input_char(struct nk_context *ctx, char c) -{ - nk_glyph glyph = {0}; - NK_ASSERT(ctx); - if (!ctx) { - return; - } - glyph[0] = c; - nk_input_glyph(ctx, glyph); -} -NK_API void -nk_input_unicode(struct nk_context *ctx, nk_rune unicode) -{ - nk_glyph rune; - NK_ASSERT(ctx); - if (!ctx) { - return; - } - nk_utf_encode(unicode, rune, NK_UTF_SIZE); - nk_input_glyph(ctx, rune); -} -NK_API nk_bool -nk_input_has_mouse_click(const struct nk_input *i, enum nk_buttons id) -{ - const struct nk_mouse_button *btn; - if (!i) { - return nk_false; - } - btn = &i->mouse.buttons[id]; - return (btn->clicked && btn->down == nk_false) ? nk_true : nk_false; -} -NK_API nk_bool -nk_input_has_mouse_click_in_rect(const struct nk_input *i, enum nk_buttons id, struct nk_rect b) -{ - const struct nk_mouse_button *btn; - if (!i) { - return nk_false; - } - btn = &i->mouse.buttons[id]; - if (!NK_INBOX(btn->clicked_pos.x, btn->clicked_pos.y, b.x, b.y, b.w, b.h)) { - return nk_false; - } - return nk_true; -} -NK_API nk_bool -nk_input_has_mouse_click_in_button_rect(const struct nk_input *i, enum nk_buttons id, struct nk_rect b) -{ - const struct nk_mouse_button *btn; - if (!i) { - return nk_false; - } - btn = &i->mouse.buttons[id]; -#ifdef NK_BUTTON_TRIGGER_ON_RELEASE - if (!NK_INBOX(btn->clicked_pos.x, btn->clicked_pos.y, b.x, b.y, b.w, b.h) || !NK_INBOX(i->mouse.down_pos.x, i->mouse.down_pos.y, b.x, b.y, b.w, b.h)) -#else - if (!NK_INBOX(btn->clicked_pos.x, btn->clicked_pos.y, b.x, b.y, b.w, b.h)) -#endif - return nk_false; - return nk_true; -} -NK_API nk_bool -nk_input_has_mouse_click_down_in_rect(const struct nk_input *i, enum nk_buttons id, struct nk_rect b, nk_bool down) -{ - const struct nk_mouse_button *btn; - if (!i) { - return nk_false; - } - btn = &i->mouse.buttons[id]; - return nk_input_has_mouse_click_in_rect(i, id, b) && (btn->down == down); -} -NK_API nk_bool -nk_input_is_mouse_click_in_rect(const struct nk_input *i, enum nk_buttons id, struct nk_rect b) -{ - const struct nk_mouse_button *btn; - if (!i) { - return nk_false; - } - btn = &i->mouse.buttons[id]; - return (nk_input_has_mouse_click_down_in_rect(i, id, b, nk_false) && btn->clicked) ? nk_true : nk_false; -} -NK_API nk_bool -nk_input_is_mouse_click_down_in_rect(const struct nk_input *i, enum nk_buttons id, struct nk_rect b, nk_bool down) -{ - const struct nk_mouse_button *btn; - if (!i) { - return nk_false; - } - btn = &i->mouse.buttons[id]; - return (nk_input_has_mouse_click_down_in_rect(i, id, b, down) && btn->clicked) ? nk_true : nk_false; -} -NK_API nk_bool -nk_input_any_mouse_click_in_rect(const struct nk_input *in, struct nk_rect b) -{ - int i, down = 0; - for (i = 0; i < NK_BUTTON_MAX; ++i) { - down = down || nk_input_is_mouse_click_in_rect(in, (enum nk_buttons)i, b); - } - return down; -} -NK_API nk_bool -nk_input_is_mouse_hovering_rect(const struct nk_input *i, struct nk_rect rect) -{ - if (!i) { - return nk_false; - } - return NK_INBOX(i->mouse.pos.x, i->mouse.pos.y, rect.x, rect.y, rect.w, rect.h); -} -NK_API nk_bool -nk_input_is_mouse_prev_hovering_rect(const struct nk_input *i, struct nk_rect rect) -{ - if (!i) { - return nk_false; - } - return NK_INBOX(i->mouse.prev.x, i->mouse.prev.y, rect.x, rect.y, rect.w, rect.h); -} -NK_API nk_bool -nk_input_mouse_clicked(const struct nk_input *i, enum nk_buttons id, struct nk_rect rect) -{ - if (!i) { - return nk_false; - } - if (!nk_input_is_mouse_hovering_rect(i, rect)) { - return nk_false; - } - return nk_input_is_mouse_click_in_rect(i, id, rect); -} -NK_API nk_bool -nk_input_is_mouse_down(const struct nk_input *i, enum nk_buttons id) -{ - if (!i) { - return nk_false; - } - return i->mouse.buttons[id].down; -} -NK_API nk_bool -nk_input_is_mouse_pressed(const struct nk_input *i, enum nk_buttons id) -{ - const struct nk_mouse_button *b; - if (!i) { - return nk_false; - } - b = &i->mouse.buttons[id]; - if (b->down && b->clicked) { - return nk_true; - } - return nk_false; -} -NK_API nk_bool -nk_input_is_mouse_released(const struct nk_input *i, enum nk_buttons id) -{ - if (!i) { - return nk_false; - } - return (!i->mouse.buttons[id].down && i->mouse.buttons[id].clicked); -} -NK_API nk_bool -nk_input_is_mouse_moved(const struct nk_input *i) -{ - if (!i) { - return nk_false; - } - return i->mouse.delta.x != 0 || i->mouse.delta.y != 0; -} -NK_API nk_bool -nk_input_is_key_pressed(const struct nk_input *i, enum nk_keys key) -{ - const struct nk_key *k; - if (!i) { - return nk_false; - } - k = &i->keyboard.keys[key]; - if ((k->down && k->clicked) || (!k->down && k->clicked >= 2)) { - return nk_true; - } - return nk_false; -} -NK_API nk_bool -nk_input_is_key_released(const struct nk_input *i, enum nk_keys key) -{ - const struct nk_key *k; - if (!i) { - return nk_false; - } - k = &i->keyboard.keys[key]; - if ((!k->down && k->clicked) || (k->down && k->clicked >= 2)) { - return nk_true; - } - return nk_false; -} -NK_API nk_bool -nk_input_is_key_down(const struct nk_input *i, enum nk_keys key) -{ - const struct nk_key *k; - if (!i) { - return nk_false; - } - k = &i->keyboard.keys[key]; - if (k->down) { - return nk_true; - } - return nk_false; -} - -/* =============================================================== - * - * STYLE - * - * ===============================================================*/ -NK_API void -nk_style_default(struct nk_context *ctx) -{ - nk_style_from_table(ctx, 0); -} -#define NK_COLOR_MAP(NK_COLOR) \ - NK_COLOR(NK_COLOR_TEXT, 175, 175, 175, 255) \ - NK_COLOR(NK_COLOR_WINDOW, 45, 45, 45, 255) \ - NK_COLOR(NK_COLOR_HEADER, 40, 40, 40, 255) \ - NK_COLOR(NK_COLOR_BORDER, 65, 65, 65, 255) \ - NK_COLOR(NK_COLOR_BUTTON, 50, 50, 50, 255) \ - NK_COLOR(NK_COLOR_BUTTON_HOVER, 40, 40, 40, 255) \ - NK_COLOR(NK_COLOR_BUTTON_ACTIVE, 35, 35, 35, 255) \ - NK_COLOR(NK_COLOR_TOGGLE, 100, 100, 100, 255) \ - NK_COLOR(NK_COLOR_TOGGLE_HOVER, 120, 120, 120, 255) \ - NK_COLOR(NK_COLOR_TOGGLE_CURSOR, 45, 45, 45, 255) \ - NK_COLOR(NK_COLOR_SELECT, 45, 45, 45, 255) \ - NK_COLOR(NK_COLOR_SELECT_ACTIVE, 35, 35, 35, 255) \ - NK_COLOR(NK_COLOR_SLIDER, 38, 38, 38, 255) \ - NK_COLOR(NK_COLOR_SLIDER_CURSOR, 100, 100, 100, 255) \ - NK_COLOR(NK_COLOR_SLIDER_CURSOR_HOVER, 120, 120, 120, 255) \ - NK_COLOR(NK_COLOR_SLIDER_CURSOR_ACTIVE, 150, 150, 150, 255) \ - NK_COLOR(NK_COLOR_PROPERTY, 38, 38, 38, 255) \ - NK_COLOR(NK_COLOR_EDIT, 38, 38, 38, 255) \ - NK_COLOR(NK_COLOR_EDIT_CURSOR, 175, 175, 175, 255) \ - NK_COLOR(NK_COLOR_COMBO, 45, 45, 45, 255) \ - NK_COLOR(NK_COLOR_CHART, 120, 120, 120, 255) \ - NK_COLOR(NK_COLOR_CHART_COLOR, 45, 45, 45, 255) \ - NK_COLOR(NK_COLOR_CHART_COLOR_HIGHLIGHT, 255, 0, 0, 255) \ - NK_COLOR(NK_COLOR_SCROLLBAR, 40, 40, 40, 255) \ - NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR, 100, 100, 100, 255) \ - NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR_HOVER, 120, 120, 120, 255) \ - NK_COLOR(NK_COLOR_SCROLLBAR_CURSOR_ACTIVE, 150, 150, 150, 255) \ - NK_COLOR(NK_COLOR_TAB_HEADER, 40, 40, 40, 255) \ - NK_COLOR(NK_COLOR_KNOB, 38, 38, 38, 255) \ - NK_COLOR(NK_COLOR_KNOB_CURSOR, 100, 100, 100, 255) \ - NK_COLOR(NK_COLOR_KNOB_CURSOR_HOVER, 120, 120, 120, 255) \ - NK_COLOR(NK_COLOR_KNOB_CURSOR_ACTIVE, 150, 150, 150, 255) - -const struct nk_color nk_default_color_style[NK_COLOR_COUNT] = { -#define NK_COLOR(a, b, c, d, e) {b, c, d, e}, - NK_COLOR_MAP(NK_COLOR) -#undef NK_COLOR -}; -const char *nk_color_names[NK_COLOR_COUNT] = { -#define NK_COLOR(a, b, c, d, e) #a, - NK_COLOR_MAP(NK_COLOR) -#undef NK_COLOR -}; - -NK_API const char * -nk_style_get_color_by_name(enum nk_style_colors c) -{ - return nk_color_names[c]; -} -NK_API struct nk_style_item -nk_style_item_color(struct nk_color col) -{ - struct nk_style_item i; - i.type = NK_STYLE_ITEM_COLOR; - i.data.color = col; - return i; -} -NK_API struct nk_style_item -nk_style_item_image(struct nk_image img) -{ - struct nk_style_item i; - i.type = NK_STYLE_ITEM_IMAGE; - i.data.image = img; - return i; -} -NK_API struct nk_style_item -nk_style_item_nine_slice(struct nk_nine_slice slice) -{ - struct nk_style_item i; - i.type = NK_STYLE_ITEM_NINE_SLICE; - i.data.slice = slice; - return i; -} -NK_API struct nk_style_item -nk_style_item_hide(void) -{ - struct nk_style_item i; - i.type = NK_STYLE_ITEM_COLOR; - i.data.color = nk_rgba(0, 0, 0, 0); - return i; -} -NK_API void -nk_style_from_table(struct nk_context *ctx, const struct nk_color *table) -{ - struct nk_style *style; - struct nk_style_text *text; - struct nk_style_button *button; - struct nk_style_toggle *toggle; - struct nk_style_selectable *select; - struct nk_style_slider *slider; - struct nk_style_knob *knob; - struct nk_style_progress *prog; - struct nk_style_scrollbar *scroll; - struct nk_style_edit *edit; - struct nk_style_property *property; - struct nk_style_combo *combo; - struct nk_style_chart *chart; - struct nk_style_tab *tab; - struct nk_style_window *win; - - NK_ASSERT(ctx); - if (!ctx) { - return; - } - style = &ctx->style; - table = (!table) ? nk_default_color_style : table; - - /* default text */ - text = &style->text; - text->color = table[NK_COLOR_TEXT]; - text->padding = nk_vec2(0, 0); - text->color_factor = 1.0f; - text->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - - /* default button */ - button = &style->button; - nk_zero_struct(*button); - button->normal = nk_style_item_color(table[NK_COLOR_BUTTON]); - button->hover = nk_style_item_color(table[NK_COLOR_BUTTON_HOVER]); - button->active = nk_style_item_color(table[NK_COLOR_BUTTON_ACTIVE]); - button->border_color = table[NK_COLOR_BORDER]; - button->text_background = table[NK_COLOR_BUTTON]; - button->text_normal = table[NK_COLOR_TEXT]; - button->text_hover = table[NK_COLOR_TEXT]; - button->text_active = table[NK_COLOR_TEXT]; - button->padding = nk_vec2(2.0f, 2.0f); - button->image_padding = nk_vec2(0.0f, 0.0f); - button->touch_padding = nk_vec2(0.0f, 0.0f); - button->userdata = nk_handle_ptr(0); - button->text_alignment = NK_TEXT_CENTERED; - button->border = 1.0f; - button->rounding = 4.0f; - button->color_factor_text = 1.0f; - button->color_factor_background = 1.0f; - button->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - button->draw_begin = 0; - button->draw_end = 0; - - /* contextual button */ - button = &style->contextual_button; - nk_zero_struct(*button); - button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]); - button->hover = nk_style_item_color(table[NK_COLOR_BUTTON_HOVER]); - button->active = nk_style_item_color(table[NK_COLOR_BUTTON_ACTIVE]); - button->border_color = table[NK_COLOR_WINDOW]; - button->text_background = table[NK_COLOR_WINDOW]; - button->text_normal = table[NK_COLOR_TEXT]; - button->text_hover = table[NK_COLOR_TEXT]; - button->text_active = table[NK_COLOR_TEXT]; - button->padding = nk_vec2(2.0f, 2.0f); - button->touch_padding = nk_vec2(0.0f, 0.0f); - button->userdata = nk_handle_ptr(0); - button->text_alignment = NK_TEXT_CENTERED; - button->border = 0.0f; - button->rounding = 0.0f; - button->color_factor_text = 1.0f; - button->color_factor_background = 1.0f; - button->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - button->draw_begin = 0; - button->draw_end = 0; - - /* menu button */ - button = &style->menu_button; - nk_zero_struct(*button); - button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]); - button->hover = nk_style_item_color(table[NK_COLOR_WINDOW]); - button->active = nk_style_item_color(table[NK_COLOR_WINDOW]); - button->border_color = table[NK_COLOR_WINDOW]; - button->text_background = table[NK_COLOR_WINDOW]; - button->text_normal = table[NK_COLOR_TEXT]; - button->text_hover = table[NK_COLOR_TEXT]; - button->text_active = table[NK_COLOR_TEXT]; - button->padding = nk_vec2(2.0f, 2.0f); - button->touch_padding = nk_vec2(0.0f, 0.0f); - button->userdata = nk_handle_ptr(0); - button->text_alignment = NK_TEXT_CENTERED; - button->border = 0.0f; - button->rounding = 1.0f; - button->color_factor_text = 1.0f; - button->color_factor_background = 1.0f; - button->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - button->draw_begin = 0; - button->draw_end = 0; - - /* checkbox toggle */ - toggle = &style->checkbox; - nk_zero_struct(*toggle); - toggle->normal = nk_style_item_color(table[NK_COLOR_TOGGLE]); - toggle->hover = nk_style_item_color(table[NK_COLOR_TOGGLE_HOVER]); - toggle->active = nk_style_item_color(table[NK_COLOR_TOGGLE_HOVER]); - toggle->cursor_normal = nk_style_item_color(table[NK_COLOR_TOGGLE_CURSOR]); - toggle->cursor_hover = nk_style_item_color(table[NK_COLOR_TOGGLE_CURSOR]); - toggle->userdata = nk_handle_ptr(0); - toggle->text_background = table[NK_COLOR_WINDOW]; - toggle->text_normal = table[NK_COLOR_TEXT]; - toggle->text_hover = table[NK_COLOR_TEXT]; - toggle->text_active = table[NK_COLOR_TEXT]; - toggle->padding = nk_vec2(2.0f, 2.0f); - toggle->touch_padding = nk_vec2(0, 0); - toggle->border_color = nk_rgba(0, 0, 0, 0); - toggle->border = 0.0f; - toggle->spacing = 4; - toggle->color_factor = 1.0f; - toggle->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - - /* option toggle */ - toggle = &style->option; - nk_zero_struct(*toggle); - toggle->normal = nk_style_item_color(table[NK_COLOR_TOGGLE]); - toggle->hover = nk_style_item_color(table[NK_COLOR_TOGGLE_HOVER]); - toggle->active = nk_style_item_color(table[NK_COLOR_TOGGLE_HOVER]); - toggle->cursor_normal = nk_style_item_color(table[NK_COLOR_TOGGLE_CURSOR]); - toggle->cursor_hover = nk_style_item_color(table[NK_COLOR_TOGGLE_CURSOR]); - toggle->userdata = nk_handle_ptr(0); - toggle->text_background = table[NK_COLOR_WINDOW]; - toggle->text_normal = table[NK_COLOR_TEXT]; - toggle->text_hover = table[NK_COLOR_TEXT]; - toggle->text_active = table[NK_COLOR_TEXT]; - toggle->padding = nk_vec2(3.0f, 3.0f); - toggle->touch_padding = nk_vec2(0, 0); - toggle->border_color = nk_rgba(0, 0, 0, 0); - toggle->border = 0.0f; - toggle->spacing = 4; - toggle->color_factor = 1.0f; - toggle->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - - /* selectable */ - select = &style->selectable; - nk_zero_struct(*select); - select->normal = nk_style_item_color(table[NK_COLOR_SELECT]); - select->hover = nk_style_item_color(table[NK_COLOR_SELECT]); - select->pressed = nk_style_item_color(table[NK_COLOR_SELECT]); - select->normal_active = nk_style_item_color(table[NK_COLOR_SELECT_ACTIVE]); - select->hover_active = nk_style_item_color(table[NK_COLOR_SELECT_ACTIVE]); - select->pressed_active = nk_style_item_color(table[NK_COLOR_SELECT_ACTIVE]); - select->text_normal = table[NK_COLOR_TEXT]; - select->text_hover = table[NK_COLOR_TEXT]; - select->text_pressed = table[NK_COLOR_TEXT]; - select->text_normal_active = table[NK_COLOR_TEXT]; - select->text_hover_active = table[NK_COLOR_TEXT]; - select->text_pressed_active = table[NK_COLOR_TEXT]; - select->padding = nk_vec2(2.0f, 2.0f); - select->image_padding = nk_vec2(2.0f, 2.0f); - select->touch_padding = nk_vec2(0, 0); - select->userdata = nk_handle_ptr(0); - select->rounding = 0.0f; - select->color_factor = 1.0f; - select->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - select->draw_begin = 0; - select->draw_end = 0; - - /* slider */ - slider = &style->slider; - nk_zero_struct(*slider); - slider->normal = nk_style_item_hide(); - slider->hover = nk_style_item_hide(); - slider->active = nk_style_item_hide(); - slider->bar_normal = table[NK_COLOR_SLIDER]; - slider->bar_hover = table[NK_COLOR_SLIDER]; - slider->bar_active = table[NK_COLOR_SLIDER]; - slider->bar_filled = table[NK_COLOR_SLIDER_CURSOR]; - slider->cursor_normal = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR]); - slider->cursor_hover = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR_HOVER]); - slider->cursor_active = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR_ACTIVE]); - slider->inc_symbol = NK_SYMBOL_TRIANGLE_RIGHT; - slider->dec_symbol = NK_SYMBOL_TRIANGLE_LEFT; - slider->cursor_size = nk_vec2(16, 16); - slider->padding = nk_vec2(2, 2); - slider->spacing = nk_vec2(2, 2); - slider->userdata = nk_handle_ptr(0); - slider->show_buttons = nk_false; - slider->bar_height = 8; - slider->rounding = 0; - slider->color_factor = 1.0f; - slider->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - slider->draw_begin = 0; - slider->draw_end = 0; - - /* slider buttons */ - button = &style->slider.inc_button; - button->normal = nk_style_item_color(nk_rgb(40, 40, 40)); - button->hover = nk_style_item_color(nk_rgb(42, 42, 42)); - button->active = nk_style_item_color(nk_rgb(44, 44, 44)); - button->border_color = nk_rgb(65, 65, 65); - button->text_background = nk_rgb(40, 40, 40); - button->text_normal = nk_rgb(175, 175, 175); - button->text_hover = nk_rgb(175, 175, 175); - button->text_active = nk_rgb(175, 175, 175); - button->padding = nk_vec2(8.0f, 8.0f); - button->touch_padding = nk_vec2(0.0f, 0.0f); - button->userdata = nk_handle_ptr(0); - button->text_alignment = NK_TEXT_CENTERED; - button->border = 1.0f; - button->rounding = 0.0f; - button->color_factor_text = 1.0f; - button->color_factor_background = 1.0f; - button->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - button->draw_begin = 0; - button->draw_end = 0; - style->slider.dec_button = style->slider.inc_button; - - /* knob */ - knob = &style->knob; - nk_zero_struct(*knob); - knob->normal = nk_style_item_hide(); - knob->hover = nk_style_item_hide(); - knob->active = nk_style_item_hide(); - knob->knob_normal = table[NK_COLOR_KNOB]; - knob->knob_hover = table[NK_COLOR_KNOB]; - knob->knob_active = table[NK_COLOR_KNOB]; - knob->cursor_normal = table[NK_COLOR_KNOB_CURSOR]; - knob->cursor_hover = table[NK_COLOR_KNOB_CURSOR_HOVER]; - knob->cursor_active = table[NK_COLOR_KNOB_CURSOR_ACTIVE]; - - knob->knob_border_color = table[NK_COLOR_BORDER]; - knob->knob_border = 1.0f; - - knob->padding = nk_vec2(2, 2); - knob->spacing = nk_vec2(2, 2); - knob->cursor_width = 2; - knob->color_factor = 1.0f; - knob->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - - knob->userdata = nk_handle_ptr(0); - knob->draw_begin = 0; - knob->draw_end = 0; - - /* progressbar */ - prog = &style->progress; - nk_zero_struct(*prog); - prog->normal = nk_style_item_color(table[NK_COLOR_SLIDER]); - prog->hover = nk_style_item_color(table[NK_COLOR_SLIDER]); - prog->active = nk_style_item_color(table[NK_COLOR_SLIDER]); - prog->cursor_normal = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR]); - prog->cursor_hover = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR_HOVER]); - prog->cursor_active = nk_style_item_color(table[NK_COLOR_SLIDER_CURSOR_ACTIVE]); - prog->border_color = nk_rgba(0, 0, 0, 0); - prog->cursor_border_color = nk_rgba(0, 0, 0, 0); - prog->userdata = nk_handle_ptr(0); - prog->padding = nk_vec2(4, 4); - prog->rounding = 0; - prog->border = 0; - prog->cursor_rounding = 0; - prog->cursor_border = 0; - prog->color_factor = 1.0f; - prog->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - prog->draw_begin = 0; - prog->draw_end = 0; - - /* scrollbars */ - scroll = &style->scrollh; - nk_zero_struct(*scroll); - scroll->normal = nk_style_item_color(table[NK_COLOR_SCROLLBAR]); - scroll->hover = nk_style_item_color(table[NK_COLOR_SCROLLBAR]); - scroll->active = nk_style_item_color(table[NK_COLOR_SCROLLBAR]); - scroll->cursor_normal = nk_style_item_color(table[NK_COLOR_SCROLLBAR_CURSOR]); - scroll->cursor_hover = nk_style_item_color(table[NK_COLOR_SCROLLBAR_CURSOR_HOVER]); - scroll->cursor_active = nk_style_item_color(table[NK_COLOR_SCROLLBAR_CURSOR_ACTIVE]); - scroll->dec_symbol = NK_SYMBOL_CIRCLE_SOLID; - scroll->inc_symbol = NK_SYMBOL_CIRCLE_SOLID; - scroll->userdata = nk_handle_ptr(0); - scroll->border_color = table[NK_COLOR_SCROLLBAR]; - scroll->cursor_border_color = table[NK_COLOR_SCROLLBAR]; - scroll->padding = nk_vec2(0, 0); - scroll->show_buttons = nk_false; - scroll->border = 0; - scroll->rounding = 0; - scroll->border_cursor = 0; - scroll->rounding_cursor = 0; - scroll->cursor_min_size = 10.0f; - scroll->color_factor = 1.0f; - scroll->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - scroll->draw_begin = 0; - scroll->draw_end = 0; - style->scrollv = style->scrollh; - - /* scrollbars buttons */ - button = &style->scrollh.inc_button; - button->normal = nk_style_item_color(nk_rgb(40, 40, 40)); - button->hover = nk_style_item_color(nk_rgb(42, 42, 42)); - button->active = nk_style_item_color(nk_rgb(44, 44, 44)); - button->border_color = nk_rgb(65, 65, 65); - button->text_background = nk_rgb(40, 40, 40); - button->text_normal = nk_rgb(175, 175, 175); - button->text_hover = nk_rgb(175, 175, 175); - button->text_active = nk_rgb(175, 175, 175); - button->padding = nk_vec2(4.0f, 4.0f); - button->touch_padding = nk_vec2(0.0f, 0.0f); - button->userdata = nk_handle_ptr(0); - button->text_alignment = NK_TEXT_CENTERED; - button->border = 1.0f; - button->rounding = 0.0f; - button->color_factor_text = 1.0f; - button->color_factor_background = 1.0f; - button->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - button->draw_begin = 0; - button->draw_end = 0; - style->scrollh.dec_button = style->scrollh.inc_button; - style->scrollv.inc_button = style->scrollh.inc_button; - style->scrollv.dec_button = style->scrollh.inc_button; - - /* edit */ - edit = &style->edit; - nk_zero_struct(*edit); - edit->normal = nk_style_item_color(table[NK_COLOR_EDIT]); - edit->hover = nk_style_item_color(table[NK_COLOR_EDIT]); - edit->active = nk_style_item_color(table[NK_COLOR_EDIT]); - edit->cursor_normal = table[NK_COLOR_TEXT]; - edit->cursor_hover = table[NK_COLOR_TEXT]; - edit->cursor_text_normal = table[NK_COLOR_EDIT]; - edit->cursor_text_hover = table[NK_COLOR_EDIT]; - edit->border_color = table[NK_COLOR_BORDER]; - edit->text_normal = table[NK_COLOR_TEXT]; - edit->text_hover = table[NK_COLOR_TEXT]; - edit->text_active = table[NK_COLOR_TEXT]; - edit->selected_normal = table[NK_COLOR_TEXT]; - edit->selected_hover = table[NK_COLOR_TEXT]; - edit->selected_text_normal = table[NK_COLOR_EDIT]; - edit->selected_text_hover = table[NK_COLOR_EDIT]; - edit->scrollbar_size = nk_vec2(10, 10); - edit->scrollbar = style->scrollv; - edit->padding = nk_vec2(4, 4); - edit->row_padding = 2; - edit->cursor_size = 4; - edit->border = 1; - edit->rounding = 0; - edit->color_factor = 1.0f; - edit->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - - /* property */ - property = &style->property; - nk_zero_struct(*property); - property->normal = nk_style_item_color(table[NK_COLOR_PROPERTY]); - property->hover = nk_style_item_color(table[NK_COLOR_PROPERTY]); - property->active = nk_style_item_color(table[NK_COLOR_PROPERTY]); - property->border_color = table[NK_COLOR_BORDER]; - property->label_normal = table[NK_COLOR_TEXT]; - property->label_hover = table[NK_COLOR_TEXT]; - property->label_active = table[NK_COLOR_TEXT]; - property->sym_left = NK_SYMBOL_TRIANGLE_LEFT; - property->sym_right = NK_SYMBOL_TRIANGLE_RIGHT; - property->userdata = nk_handle_ptr(0); - property->padding = nk_vec2(4, 4); - property->border = 1; - property->rounding = 10; - property->draw_begin = 0; - property->draw_end = 0; - property->color_factor = 1.0f; - property->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - - /* property buttons */ - button = &style->property.dec_button; - nk_zero_struct(*button); - button->normal = nk_style_item_color(table[NK_COLOR_PROPERTY]); - button->hover = nk_style_item_color(table[NK_COLOR_PROPERTY]); - button->active = nk_style_item_color(table[NK_COLOR_PROPERTY]); - button->border_color = nk_rgba(0, 0, 0, 0); - button->text_background = table[NK_COLOR_PROPERTY]; - button->text_normal = table[NK_COLOR_TEXT]; - button->text_hover = table[NK_COLOR_TEXT]; - button->text_active = table[NK_COLOR_TEXT]; - button->padding = nk_vec2(0.0f, 0.0f); - button->touch_padding = nk_vec2(0.0f, 0.0f); - button->userdata = nk_handle_ptr(0); - button->text_alignment = NK_TEXT_CENTERED; - button->border = 0.0f; - button->rounding = 0.0f; - button->color_factor_text = 1.0f; - button->color_factor_background = 1.0f; - button->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - button->draw_begin = 0; - button->draw_end = 0; - style->property.inc_button = style->property.dec_button; - - /* property edit */ - edit = &style->property.edit; - nk_zero_struct(*edit); - edit->normal = nk_style_item_color(table[NK_COLOR_PROPERTY]); - edit->hover = nk_style_item_color(table[NK_COLOR_PROPERTY]); - edit->active = nk_style_item_color(table[NK_COLOR_PROPERTY]); - edit->border_color = nk_rgba(0, 0, 0, 0); - edit->cursor_normal = table[NK_COLOR_TEXT]; - edit->cursor_hover = table[NK_COLOR_TEXT]; - edit->cursor_text_normal = table[NK_COLOR_EDIT]; - edit->cursor_text_hover = table[NK_COLOR_EDIT]; - edit->text_normal = table[NK_COLOR_TEXT]; - edit->text_hover = table[NK_COLOR_TEXT]; - edit->text_active = table[NK_COLOR_TEXT]; - edit->selected_normal = table[NK_COLOR_TEXT]; - edit->selected_hover = table[NK_COLOR_TEXT]; - edit->selected_text_normal = table[NK_COLOR_EDIT]; - edit->selected_text_hover = table[NK_COLOR_EDIT]; - edit->padding = nk_vec2(0, 0); - edit->cursor_size = 8; - edit->border = 0; - edit->rounding = 0; - edit->color_factor = 1.0f; - edit->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - - /* chart */ - chart = &style->chart; - nk_zero_struct(*chart); - chart->background = nk_style_item_color(table[NK_COLOR_CHART]); - chart->border_color = table[NK_COLOR_BORDER]; - chart->selected_color = table[NK_COLOR_CHART_COLOR_HIGHLIGHT]; - chart->color = table[NK_COLOR_CHART_COLOR]; - chart->padding = nk_vec2(4, 4); - chart->border = 0; - chart->rounding = 0; - chart->color_factor = 1.0f; - chart->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - chart->show_markers = nk_true; - - /* combo */ - combo = &style->combo; - combo->normal = nk_style_item_color(table[NK_COLOR_COMBO]); - combo->hover = nk_style_item_color(table[NK_COLOR_COMBO]); - combo->active = nk_style_item_color(table[NK_COLOR_COMBO]); - combo->border_color = table[NK_COLOR_BORDER]; - combo->label_normal = table[NK_COLOR_TEXT]; - combo->label_hover = table[NK_COLOR_TEXT]; - combo->label_active = table[NK_COLOR_TEXT]; - combo->sym_normal = NK_SYMBOL_TRIANGLE_DOWN; - combo->sym_hover = NK_SYMBOL_TRIANGLE_DOWN; - combo->sym_active = NK_SYMBOL_TRIANGLE_DOWN; - combo->content_padding = nk_vec2(4, 4); - combo->button_padding = nk_vec2(0, 4); - combo->spacing = nk_vec2(4, 0); - combo->border = 1; - combo->rounding = 0; - combo->color_factor = 1.0f; - combo->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - - /* combo button */ - button = &style->combo.button; - nk_zero_struct(*button); - button->normal = nk_style_item_color(table[NK_COLOR_COMBO]); - button->hover = nk_style_item_color(table[NK_COLOR_COMBO]); - button->active = nk_style_item_color(table[NK_COLOR_COMBO]); - button->border_color = nk_rgba(0, 0, 0, 0); - button->text_background = table[NK_COLOR_COMBO]; - button->text_normal = table[NK_COLOR_TEXT]; - button->text_hover = table[NK_COLOR_TEXT]; - button->text_active = table[NK_COLOR_TEXT]; - button->padding = nk_vec2(2.0f, 2.0f); - button->touch_padding = nk_vec2(0.0f, 0.0f); - button->userdata = nk_handle_ptr(0); - button->text_alignment = NK_TEXT_CENTERED; - button->border = 0.0f; - button->rounding = 0.0f; - button->color_factor_text = 1.0f; - button->color_factor_background = 1.0f; - button->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - button->draw_begin = 0; - button->draw_end = 0; - - /* tab */ - tab = &style->tab; - tab->background = nk_style_item_color(table[NK_COLOR_TAB_HEADER]); - tab->border_color = table[NK_COLOR_BORDER]; - tab->text = table[NK_COLOR_TEXT]; - tab->sym_minimize = NK_SYMBOL_TRIANGLE_RIGHT; - tab->sym_maximize = NK_SYMBOL_TRIANGLE_DOWN; - tab->padding = nk_vec2(4, 4); - tab->spacing = nk_vec2(4, 4); - tab->indent = 10.0f; - tab->border = 1; - tab->rounding = 0; - tab->color_factor = 1.0f; - tab->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - - /* tab button */ - button = &style->tab.tab_minimize_button; - nk_zero_struct(*button); - button->normal = nk_style_item_color(table[NK_COLOR_TAB_HEADER]); - button->hover = nk_style_item_color(table[NK_COLOR_TAB_HEADER]); - button->active = nk_style_item_color(table[NK_COLOR_TAB_HEADER]); - button->border_color = nk_rgba(0, 0, 0, 0); - button->text_background = table[NK_COLOR_TAB_HEADER]; - button->text_normal = table[NK_COLOR_TEXT]; - button->text_hover = table[NK_COLOR_TEXT]; - button->text_active = table[NK_COLOR_TEXT]; - button->padding = nk_vec2(2.0f, 2.0f); - button->touch_padding = nk_vec2(0.0f, 0.0f); - button->userdata = nk_handle_ptr(0); - button->text_alignment = NK_TEXT_CENTERED; - button->border = 0.0f; - button->rounding = 0.0f; - button->color_factor_text = 1.0f; - button->color_factor_background = 1.0f; - button->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - button->draw_begin = 0; - button->draw_end = 0; - style->tab.tab_maximize_button = *button; - - /* node button */ - button = &style->tab.node_minimize_button; - nk_zero_struct(*button); - button->normal = nk_style_item_color(table[NK_COLOR_WINDOW]); - button->hover = nk_style_item_color(table[NK_COLOR_WINDOW]); - button->active = nk_style_item_color(table[NK_COLOR_WINDOW]); - button->border_color = nk_rgba(0, 0, 0, 0); - button->text_background = table[NK_COLOR_TAB_HEADER]; - button->text_normal = table[NK_COLOR_TEXT]; - button->text_hover = table[NK_COLOR_TEXT]; - button->text_active = table[NK_COLOR_TEXT]; - button->padding = nk_vec2(2.0f, 2.0f); - button->touch_padding = nk_vec2(0.0f, 0.0f); - button->userdata = nk_handle_ptr(0); - button->text_alignment = NK_TEXT_CENTERED; - button->border = 0.0f; - button->rounding = 0.0f; - button->color_factor_text = 1.0f; - button->color_factor_background = 1.0f; - button->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - button->draw_begin = 0; - button->draw_end = 0; - style->tab.node_maximize_button = *button; - - /* window header */ - win = &style->window; - win->header.align = NK_HEADER_RIGHT; - win->header.close_symbol = NK_SYMBOL_X; - win->header.minimize_symbol = NK_SYMBOL_MINUS; - win->header.maximize_symbol = NK_SYMBOL_PLUS; - win->header.normal = nk_style_item_color(table[NK_COLOR_HEADER]); - win->header.hover = nk_style_item_color(table[NK_COLOR_HEADER]); - win->header.active = nk_style_item_color(table[NK_COLOR_HEADER]); - win->header.label_normal = table[NK_COLOR_TEXT]; - win->header.label_hover = table[NK_COLOR_TEXT]; - win->header.label_active = table[NK_COLOR_TEXT]; - win->header.label_padding = nk_vec2(4, 4); - win->header.padding = nk_vec2(4, 4); - win->header.spacing = nk_vec2(0, 0); - - /* window header close button */ - button = &style->window.header.close_button; - nk_zero_struct(*button); - button->normal = nk_style_item_color(table[NK_COLOR_HEADER]); - button->hover = nk_style_item_color(table[NK_COLOR_HEADER]); - button->active = nk_style_item_color(table[NK_COLOR_HEADER]); - button->border_color = nk_rgba(0, 0, 0, 0); - button->text_background = table[NK_COLOR_HEADER]; - button->text_normal = table[NK_COLOR_TEXT]; - button->text_hover = table[NK_COLOR_TEXT]; - button->text_active = table[NK_COLOR_TEXT]; - button->padding = nk_vec2(0.0f, 0.0f); - button->touch_padding = nk_vec2(0.0f, 0.0f); - button->userdata = nk_handle_ptr(0); - button->text_alignment = NK_TEXT_CENTERED; - button->border = 0.0f; - button->rounding = 0.0f; - button->color_factor_text = 1.0f; - button->color_factor_background = 1.0f; - button->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - button->draw_begin = 0; - button->draw_end = 0; - - /* window header minimize button */ - button = &style->window.header.minimize_button; - nk_zero_struct(*button); - button->normal = nk_style_item_color(table[NK_COLOR_HEADER]); - button->hover = nk_style_item_color(table[NK_COLOR_HEADER]); - button->active = nk_style_item_color(table[NK_COLOR_HEADER]); - button->border_color = nk_rgba(0, 0, 0, 0); - button->text_background = table[NK_COLOR_HEADER]; - button->text_normal = table[NK_COLOR_TEXT]; - button->text_hover = table[NK_COLOR_TEXT]; - button->text_active = table[NK_COLOR_TEXT]; - button->padding = nk_vec2(0.0f, 0.0f); - button->touch_padding = nk_vec2(0.0f, 0.0f); - button->userdata = nk_handle_ptr(0); - button->text_alignment = NK_TEXT_CENTERED; - button->border = 0.0f; - button->rounding = 0.0f; - button->color_factor_text = 1.0f; - button->color_factor_background = 1.0f; - button->disabled_factor = NK_WIDGET_DISABLED_FACTOR; - button->draw_begin = 0; - button->draw_end = 0; - - /* window */ - win->background = table[NK_COLOR_WINDOW]; - win->fixed_background = nk_style_item_color(table[NK_COLOR_WINDOW]); - win->border_color = table[NK_COLOR_BORDER]; - win->popup_border_color = table[NK_COLOR_BORDER]; - win->combo_border_color = table[NK_COLOR_BORDER]; - win->contextual_border_color = table[NK_COLOR_BORDER]; - win->menu_border_color = table[NK_COLOR_BORDER]; - win->group_border_color = table[NK_COLOR_BORDER]; - win->tooltip_border_color = table[NK_COLOR_BORDER]; - win->scaler = nk_style_item_color(table[NK_COLOR_TEXT]); - - win->rounding = 0.0f; - win->spacing = nk_vec2(4, 4); - win->scrollbar_size = nk_vec2(10, 10); - win->min_size = nk_vec2(64, 64); - - win->combo_border = 1.0f; - win->contextual_border = 1.0f; - win->menu_border = 1.0f; - win->group_border = 1.0f; - win->tooltip_border = 1.0f; - win->popup_border = 1.0f; - win->border = 2.0f; - win->min_row_height_padding = 8; - - win->padding = nk_vec2(4, 4); - win->group_padding = nk_vec2(4, 4); - win->popup_padding = nk_vec2(4, 4); - win->combo_padding = nk_vec2(4, 4); - win->contextual_padding = nk_vec2(4, 4); - win->menu_padding = nk_vec2(4, 4); - win->tooltip_padding = nk_vec2(4, 4); - - /* default tooltip just down and to the right of the cursor - * so it doesn't cover the text - * - * TODO might be worth consolidating tooltip styling - * into its own style structure, though it is a - * type of window...*/ - win->tooltip_origin = NK_TOP_LEFT; - win->tooltip_offset = nk_vec2(12, 12); -} -NK_API void -nk_style_set_font(struct nk_context *ctx, const struct nk_user_font *font) -{ - struct nk_style *style; - NK_ASSERT(ctx); - - if (!ctx) { - return; - } - style = &ctx->style; - style->font = font; - style->font_size = font ? font->height : 0.0f; - ctx->stacks.fonts.head = 0; - if (ctx->current) { - nk_layout_reset_min_row_height(ctx); - } -} -NK_API void -nk_style_set_font_size(struct nk_context *ctx, float size) -{ - NK_ASSERT(ctx); - NK_ASSERT(size > 0.0f); - ctx->style.font_size = size; - if (ctx->current) { - nk_layout_reset_min_row_height(ctx); - } -} -NK_API nk_bool -nk_style_push_font(struct nk_context *ctx, const struct nk_user_font *font) -{ - struct nk_config_stack_user_font *font_stack; - struct nk_config_stack_user_font_element *element; - - NK_ASSERT(ctx); - if (!ctx) { - return 0; - } - - font_stack = &ctx->stacks.fonts; - NK_ASSERT(font_stack->head < (int)NK_LEN(font_stack->elements)); - if (font_stack->head >= (int)NK_LEN(font_stack->elements)) { - return 0; - } - - element = &font_stack->elements[font_stack->head++]; - element->address = &ctx->style.font; - element->old_value = ctx->style.font; - ctx->style.font = font; - if (ctx->current) { - nk_layout_reset_min_row_height(ctx); - } - return 1; -} -NK_API nk_bool -nk_style_pop_font(struct nk_context *ctx) -{ - struct nk_config_stack_user_font *font_stack; - struct nk_config_stack_user_font_element *element; - - NK_ASSERT(ctx); - if (!ctx) { - return 0; - } - - font_stack = &ctx->stacks.fonts; - NK_ASSERT(font_stack->head > 0); - if (font_stack->head < 1) { - return 0; - } - - element = &font_stack->elements[--font_stack->head]; - *element->address = element->old_value; - if (ctx->current) { - nk_layout_reset_min_row_height(ctx); - } - return 1; -} -#define NK_STYLE_PUSH_IMPLEMENATION(prefix, type, stack) \ - nk_style_push_##type(struct nk_context *ctx, prefix##_##type *address, prefix##_##type value) \ - { \ - struct nk_config_stack_##type *type_stack; \ - struct nk_config_stack_##type##_element *element; \ - NK_ASSERT(ctx); \ - if (!ctx) \ - return 0; \ - type_stack = &ctx->stacks.stack; \ - NK_ASSERT(type_stack->head < (int)NK_LEN(type_stack->elements)); \ - if (type_stack->head >= (int)NK_LEN(type_stack->elements)) \ - return 0; \ - element = &type_stack->elements[type_stack->head++]; \ - element->address = address; \ - element->old_value = *address; \ - *address = value; \ - return 1; \ - } -#define NK_STYLE_POP_IMPLEMENATION(type, stack) \ - nk_style_pop_##type(struct nk_context *ctx) \ - { \ - struct nk_config_stack_##type *type_stack; \ - struct nk_config_stack_##type##_element *element; \ - NK_ASSERT(ctx); \ - if (!ctx) \ - return 0; \ - type_stack = &ctx->stacks.stack; \ - NK_ASSERT(type_stack->head > 0); \ - if (type_stack->head < 1) \ - return 0; \ - element = &type_stack->elements[--type_stack->head]; \ - *element->address = element->old_value; \ - return 1; \ - } -NK_API nk_bool NK_STYLE_PUSH_IMPLEMENATION(struct nk, style_item, style_items) -NK_API nk_bool -NK_STYLE_PUSH_IMPLEMENATION(nk, float, floats) -NK_API nk_bool NK_STYLE_PUSH_IMPLEMENATION(struct nk, vec2, vectors) -NK_API nk_bool -NK_STYLE_PUSH_IMPLEMENATION(nk, flags, flags) -NK_API nk_bool NK_STYLE_PUSH_IMPLEMENATION(struct nk, color, colors) - -NK_API nk_bool -NK_STYLE_POP_IMPLEMENATION(style_item, style_items) -NK_API nk_bool -NK_STYLE_POP_IMPLEMENATION(float, floats) -NK_API nk_bool -NK_STYLE_POP_IMPLEMENATION(vec2, vectors) -NK_API nk_bool -NK_STYLE_POP_IMPLEMENATION(flags, flags) -NK_API nk_bool -NK_STYLE_POP_IMPLEMENATION(color, colors) - -NK_API nk_bool -nk_style_push_font_size(struct nk_context *ctx, float size) -{ - nk_bool result; - NK_ASSERT(size > 0.0f); - result = nk_style_push_float(ctx, &ctx->style.font_size, size); - if (result && ctx->current) { - nk_layout_reset_min_row_height(ctx); - } - return result; -} - -NK_API nk_bool -nk_style_pop_font_size(struct nk_context *ctx) -{ - nk_bool result = nk_style_pop_float(ctx); - if (result && ctx->current) { - nk_layout_reset_min_row_height(ctx); - } - return result; -} - -NK_API nk_bool -nk_style_set_cursor(struct nk_context *ctx, enum nk_style_cursor c) -{ - struct nk_style *style; - NK_ASSERT(ctx); - if (!ctx) { - return 0; - } - style = &ctx->style; - if (style->cursors[c]) { - style->cursor_active = style->cursors[c]; - return 1; - } - return 0; -} -NK_API void -nk_style_show_cursor(struct nk_context *ctx) -{ - ctx->style.cursor_visible = nk_true; -} -NK_API void -nk_style_hide_cursor(struct nk_context *ctx) -{ - ctx->style.cursor_visible = nk_false; -} -NK_API void -nk_style_load_cursor(struct nk_context *ctx, enum nk_style_cursor cursor, const struct nk_cursor *c) -{ - struct nk_style *style; - NK_ASSERT(ctx); - if (!ctx) { - return; - } - style = &ctx->style; - style->cursors[cursor] = c; -} -NK_API void -nk_style_load_all_cursors(struct nk_context *ctx, const struct nk_cursor *cursors) -{ - int i = 0; - struct nk_style *style; - NK_ASSERT(ctx); - if (!ctx) { - return; - } - style = &ctx->style; - for (i = 0; i < NK_CURSOR_COUNT; ++i) { - style->cursors[i] = &cursors[i]; - } - style->cursor_visible = nk_true; -} - -/* ============================================================== - * - * CONTEXT - * - * ===============================================================*/ -NK_INTERN void -nk_setup(struct nk_context *ctx, const struct nk_user_font *font) -{ - NK_ASSERT(ctx); - if (!ctx) { - return; - } - nk_zero_struct(*ctx); - nk_style_default(ctx); - ctx->seq = 1; - if (font) { - ctx->style.font = font; - ctx->style.font_size = font->height; - } -#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT - nk_draw_list_init(&ctx->draw_list); -#endif -} -#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR -NK_API nk_bool -nk_init_default(struct nk_context *ctx, const struct nk_user_font *font) -{ - struct nk_allocator alloc; - alloc.userdata.ptr = 0; - alloc.alloc = nk_malloc; - alloc.free = nk_mfree; - return nk_init(ctx, &alloc, font); -} -#endif -NK_API nk_bool -nk_init_fixed(struct nk_context *ctx, void *memory, nk_size size, const struct nk_user_font *font) -{ - NK_ASSERT(memory); - if (!memory) { - return 0; - } - nk_setup(ctx, font); - nk_buffer_init_fixed(&ctx->memory, memory, size); - ctx->use_pool = nk_false; - return 1; -} -NK_API nk_bool -nk_init_custom(struct nk_context *ctx, struct nk_buffer *cmds, struct nk_buffer *pool, const struct nk_user_font *font) -{ - NK_ASSERT(cmds); - NK_ASSERT(pool); - if (!cmds || !pool) { - return 0; - } - - nk_setup(ctx, font); - ctx->memory = *cmds; - if (pool->type == NK_BUFFER_FIXED) { - /* take memory from buffer and alloc fixed pool */ - nk_pool_init_fixed(&ctx->pool, pool->memory.ptr, pool->memory.size); - } else { - /* create dynamic pool from buffer allocator */ - struct nk_allocator *alloc = &pool->pool; - nk_pool_init(&ctx->pool, alloc, NK_POOL_DEFAULT_CAPACITY); - } - ctx->use_pool = nk_true; - return 1; -} -NK_API nk_bool -nk_init(struct nk_context *ctx, const struct nk_allocator *alloc, const struct nk_user_font *font) -{ - NK_ASSERT(alloc); - if (!alloc) { - return 0; - } - nk_setup(ctx, font); - nk_buffer_init(&ctx->memory, alloc, NK_DEFAULT_COMMAND_BUFFER_SIZE); - nk_pool_init(&ctx->pool, alloc, NK_POOL_DEFAULT_CAPACITY); - ctx->use_pool = nk_true; - return 1; -} -#ifdef NK_INCLUDE_COMMAND_USERDATA -NK_API void -nk_set_user_data(struct nk_context *ctx, nk_handle handle) -{ - if (!ctx) { - return; - } - ctx->userdata = handle; - if (ctx->current) { - ctx->current->buffer.userdata = handle; - } -} -#endif -NK_API void -nk_free(struct nk_context *ctx) -{ - NK_ASSERT(ctx); - if (!ctx) { - return; - } - nk_buffer_free(&ctx->memory); - if (ctx->use_pool) { - nk_pool_free(&ctx->pool); - } - - nk_zero(&ctx->input, sizeof(ctx->input)); - nk_zero(&ctx->style, sizeof(ctx->style)); - nk_zero(&ctx->memory, sizeof(ctx->memory)); - - ctx->seq = 0; - ctx->build = 0; - ctx->begin = 0; - ctx->end = 0; - ctx->active = 0; - ctx->current = 0; - ctx->freelist = 0; - ctx->count = 0; -} -NK_API void -nk_clear(struct nk_context *ctx) -{ - struct nk_window *iter; - struct nk_window *next; - NK_ASSERT(ctx); - - if (!ctx) { - return; - } - if (ctx->use_pool) { - nk_buffer_clear(&ctx->memory); - } else { - nk_buffer_reset(&ctx->memory, NK_BUFFER_FRONT); - } - - ctx->build = 0; - ctx->memory.calls = 0; - ctx->last_widget_state = 0; - ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_ARROW]; - NK_MEMSET(&ctx->overlay, 0, sizeof(ctx->overlay)); - - /* garbage collector */ - iter = ctx->begin; - while (iter) { - /* make sure valid minimized windows do not get removed */ - if ((iter->flags & NK_WINDOW_MINIMIZED) && !(iter->flags & NK_WINDOW_CLOSED) && iter->seq == ctx->seq) { - iter = iter->next; - continue; - } - /* remove hotness from hidden or closed windows*/ - if (((iter->flags & NK_WINDOW_HIDDEN) || (iter->flags & NK_WINDOW_CLOSED)) && iter == ctx->active) { - ctx->active = iter->prev; - ctx->end = iter->prev; - if (!ctx->end) { - ctx->begin = 0; - } - if (ctx->active) { - ctx->active->flags &= ~(unsigned)NK_WINDOW_ROM; - } - } - /* free unused popup windows */ - if (iter->popup.win && iter->popup.win->seq != ctx->seq) { - nk_free_window(ctx, iter->popup.win); - iter->popup.win = 0; - } - /* remove unused window state tables */ - { - struct nk_table *n, *it = iter->tables; - while (it) { - n = it->next; - if (it->seq != ctx->seq) { - nk_remove_table(iter, it); - nk_zero(it, sizeof(union nk_page_data)); - nk_free_table(ctx, it); - if (it == iter->tables) { - iter->tables = n; - } - } - it = n; - } - } - /* window itself is not used anymore so free */ - if (iter->seq != ctx->seq || iter->flags & NK_WINDOW_CLOSED) { - next = iter->next; - nk_remove_window(ctx, iter); - nk_free_window(ctx, iter); - iter = next; - } else { - iter = iter->next; - } - } - ctx->seq++; -} -NK_LIB void -nk_start_buffer(struct nk_context *ctx, struct nk_command_buffer *buffer) -{ - NK_ASSERT(ctx); - NK_ASSERT(buffer); - if (!ctx || !buffer) { - return; - } - buffer->context = ctx; - buffer->begin = ctx->memory.allocated; - buffer->end = buffer->begin; - buffer->last = buffer->begin; - buffer->clip = nk_null_rect; -} -NK_LIB void -nk_start(struct nk_context *ctx, struct nk_window *win) -{ - NK_ASSERT(ctx); - NK_ASSERT(win); - nk_start_buffer(ctx, &win->buffer); -} -NK_LIB void -nk_start_popup(struct nk_context *ctx, struct nk_window *win) -{ - struct nk_popup_buffer *buf; - NK_ASSERT(ctx); - NK_ASSERT(win); - if (!ctx || !win) { - return; - } - - /* save buffer fill state for popup */ - buf = &win->popup.buf; - buf->begin = win->buffer.end; - buf->end = win->buffer.end; - buf->parent = win->buffer.last; - buf->last = buf->begin; - buf->active = nk_true; -} -NK_LIB void -nk_finish_popup(struct nk_context *ctx, struct nk_window *win) -{ - struct nk_popup_buffer *buf; - NK_ASSERT(ctx); - NK_ASSERT(win); - if (!ctx || !win) { - return; - } - - buf = &win->popup.buf; - buf->last = win->buffer.last; - buf->end = win->buffer.end; -} -NK_LIB void -nk_finish_buffer(struct nk_context *ctx, struct nk_command_buffer *buffer) -{ - NK_ASSERT(ctx); - NK_ASSERT(buffer); - if (!ctx || !buffer) { - return; - } - buffer->end = ctx->memory.allocated; -} -NK_LIB void -nk_finish(struct nk_context *ctx, struct nk_window *win) -{ - struct nk_popup_buffer *buf; - struct nk_command *parent_last; - void *memory; - - NK_ASSERT(ctx); - NK_ASSERT(win); - if (!ctx || !win) { - return; - } - nk_finish_buffer(ctx, &win->buffer); - if (!win->popup.buf.active) { - return; - } - - buf = &win->popup.buf; - memory = ctx->memory.memory.ptr; - parent_last = nk_ptr_add(struct nk_command, memory, buf->parent); - parent_last->next = buf->end; -} -NK_LIB void -nk_build(struct nk_context *ctx) -{ - struct nk_window *it = 0; - struct nk_command *cmd = 0; - nk_byte *buffer = 0; - - /* draw cursor overlay */ - if (!ctx->style.cursor_active) { - ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_ARROW]; - } - if (ctx->style.cursor_active && !ctx->input.mouse.grabbed && ctx->style.cursor_visible) { - struct nk_rect mouse_bounds; - const struct nk_cursor *cursor = ctx->style.cursor_active; - nk_command_buffer_init(&ctx->overlay, &ctx->memory, NK_CLIPPING_OFF); - nk_start_buffer(ctx, &ctx->overlay); - - mouse_bounds.x = ctx->input.mouse.pos.x - cursor->offset.x; - mouse_bounds.y = ctx->input.mouse.pos.y - cursor->offset.y; - mouse_bounds.w = cursor->size.x; - mouse_bounds.h = cursor->size.y; - - nk_draw_image(&ctx->overlay, mouse_bounds, &cursor->img, nk_white); - nk_finish_buffer(ctx, &ctx->overlay); - } - /* build one big draw command list out of all window buffers */ - it = ctx->begin; - buffer = (nk_byte *)ctx->memory.memory.ptr; - while (it != 0) { - struct nk_window *next = it->next; - if (it->buffer.last == it->buffer.begin || (it->flags & NK_WINDOW_HIDDEN) || it->seq != ctx->seq) { - goto cont; - } - - cmd = nk_ptr_add(struct nk_command, buffer, it->buffer.last); - while (next && ((next->buffer.last == next->buffer.begin) || (next->flags & NK_WINDOW_HIDDEN) || next->seq != ctx->seq)) { - next = next->next; /* skip empty command buffers */ - } - - if (next) { - cmd->next = next->buffer.begin; - } - cont: - it = next; - } - /* append all popup draw commands into lists */ - it = ctx->begin; - while (it != 0) { - struct nk_window *next = it->next; - struct nk_popup_buffer *buf; - if (!it->popup.buf.active) { - goto skip; - } - - buf = &it->popup.buf; - cmd->next = buf->begin; - cmd = nk_ptr_add(struct nk_command, buffer, buf->last); - buf->active = nk_false; - skip: - it = next; - } - if (cmd) { - /* append overlay commands */ - if (ctx->overlay.end != ctx->overlay.begin) { - cmd->next = ctx->overlay.begin; - } else { - cmd->next = ctx->memory.allocated; - } - } -} -NK_API const struct nk_command * -nk__begin(struct nk_context *ctx) -{ - struct nk_window *iter; - nk_byte *buffer; - NK_ASSERT(ctx); - if (!ctx) { - return 0; - } - if (!ctx->count) { - return 0; - } - - buffer = (nk_byte *)ctx->memory.memory.ptr; - if (!ctx->build) { - nk_build(ctx); - ctx->build = nk_true; - } - iter = ctx->begin; - while (iter && ((iter->buffer.begin == iter->buffer.end) || (iter->flags & NK_WINDOW_HIDDEN) || iter->seq != ctx->seq)) { - iter = iter->next; - } - if (!iter) { - return 0; - } - return nk_ptr_add_const(struct nk_command, buffer, iter->buffer.begin); -} - -NK_API const struct nk_command * -nk__next(struct nk_context *ctx, const struct nk_command *cmd) -{ - nk_byte *buffer; - const struct nk_command *next; - NK_ASSERT(ctx); - if (!ctx || !cmd || !ctx->count) { - return 0; - } - if (cmd->next >= ctx->memory.allocated) { - return 0; - } - buffer = (nk_byte *)ctx->memory.memory.ptr; - next = nk_ptr_add_const(struct nk_command, buffer, cmd->next); - return next; -} - -/* =============================================================== - * - * POOL - * - * ===============================================================*/ -NK_LIB void -nk_pool_init(struct nk_pool *pool, const struct nk_allocator *alloc, unsigned int capacity) -{ - NK_ASSERT(capacity >= 1); - nk_zero(pool, sizeof(*pool)); - pool->alloc = *alloc; - pool->capacity = capacity; - pool->type = NK_BUFFER_DYNAMIC; - pool->pages = 0; -} -NK_LIB void -nk_pool_free(struct nk_pool *pool) -{ - struct nk_page *iter; - if (!pool) { - return; - } - iter = pool->pages; - if (pool->type == NK_BUFFER_FIXED) { - return; - } - while (iter) { - struct nk_page *next = iter->next; - pool->alloc.free(pool->alloc.userdata, iter); - iter = next; - } -} -NK_LIB void -nk_pool_init_fixed(struct nk_pool *pool, void *memory, nk_size size) -{ - nk_zero(pool, sizeof(*pool)); - NK_ASSERT(size >= sizeof(struct nk_page)); - if (size < sizeof(struct nk_page)) { - return; - } - /* first nk_page_element is embedded in nk_page, additional elements follow in adjacent space */ - pool->capacity = (unsigned)(1 + (size - sizeof(struct nk_page)) / sizeof(struct nk_page_element)); - pool->pages = (struct nk_page *)memory; - pool->type = NK_BUFFER_FIXED; - pool->size = size; -} -NK_LIB struct nk_page_element * -nk_pool_alloc(struct nk_pool *pool) -{ - if (!pool->pages || pool->pages->size >= pool->capacity) { - /* allocate new page */ - struct nk_page *page; - if (pool->type == NK_BUFFER_FIXED) { - NK_ASSERT(pool->pages); - if (!pool->pages) { - return 0; - } - NK_ASSERT(pool->pages->size < pool->capacity); - return 0; - } else { - nk_size size = sizeof(struct nk_page); - size += (pool->capacity - 1) * sizeof(struct nk_page_element); - page = (struct nk_page *)pool->alloc.alloc(pool->alloc.userdata, 0, size); - page->next = pool->pages; - pool->pages = page; - page->size = 0; - } - } - return &pool->pages->win[pool->pages->size++]; -} - -/* =============================================================== - * - * PAGE ELEMENT - * - * ===============================================================*/ -NK_LIB struct nk_page_element * -nk_create_page_element(struct nk_context *ctx) -{ - struct nk_page_element *elem; - if (ctx->freelist) { - /* unlink page element from free list */ - elem = ctx->freelist; - ctx->freelist = elem->next; - } else if (ctx->use_pool) { - /* allocate page element from memory pool */ - elem = nk_pool_alloc(&ctx->pool); - NK_ASSERT(elem); - if (!elem) { - return 0; - } - } else { - /* allocate new page element from back of fixed size memory buffer */ - NK_STORAGE const nk_size size = sizeof(struct nk_page_element); - NK_STORAGE const nk_size align = NK_ALIGNOF(struct nk_page_element); - elem = (struct nk_page_element *)nk_buffer_alloc(&ctx->memory, NK_BUFFER_BACK, size, align); - NK_ASSERT(elem); - if (!elem) { - return 0; - } - } - nk_zero_struct(*elem); - elem->next = 0; - elem->prev = 0; - return elem; -} -NK_LIB void -nk_link_page_element_into_freelist(struct nk_context *ctx, struct nk_page_element *elem) -{ - /* link table into freelist */ - if (!ctx->freelist) { - ctx->freelist = elem; - } else { - elem->next = ctx->freelist; - ctx->freelist = elem; - } -} -NK_LIB void -nk_free_page_element(struct nk_context *ctx, struct nk_page_element *elem) -{ - /* we have a pool so just add to free list */ - if (ctx->use_pool) { - nk_link_page_element_into_freelist(ctx, elem); - return; - } - /* if possible remove last element from back of fixed memory buffer */ - { - void *elem_end = (void *)(elem + 1); - void *buffer_end = (nk_byte *)ctx->memory.memory.ptr + ctx->memory.size; - if (elem_end == buffer_end) { - ctx->memory.size -= sizeof(struct nk_page_element); - } else { - nk_link_page_element_into_freelist(ctx, elem); - } - } -} - -/* =============================================================== - * - * TABLE - * - * ===============================================================*/ -NK_LIB struct nk_table * -nk_create_table(struct nk_context *ctx) -{ - struct nk_page_element *elem; - elem = nk_create_page_element(ctx); - if (!elem) { - return 0; - } - return &elem->data.tbl; -} -NK_LIB void -nk_free_table(struct nk_context *ctx, struct nk_table *tbl) -{ - union nk_page_data *pd = NK_CONTAINER_OF(tbl, union nk_page_data, tbl); - struct nk_page_element *pe = NK_CONTAINER_OF(pd, struct nk_page_element, data); - nk_free_page_element(ctx, pe); -} -NK_LIB void -nk_push_table(struct nk_window *win, struct nk_table *tbl) -{ - if (!win->tables) { - win->tables = tbl; - tbl->next = 0; - tbl->prev = 0; - tbl->size = 0; - win->table_count = 1; - return; - } - win->tables->prev = tbl; - tbl->next = win->tables; - tbl->prev = 0; - tbl->size = 0; - win->tables = tbl; - win->table_count++; -} -NK_LIB void -nk_remove_table(struct nk_window *win, struct nk_table *tbl) -{ - if (win->tables == tbl) { - win->tables = tbl->next; - } - if (tbl->next) { - tbl->next->prev = tbl->prev; - } - if (tbl->prev) { - tbl->prev->next = tbl->next; - } - tbl->next = 0; - tbl->prev = 0; -} -NK_LIB nk_uint * -nk_add_value(struct nk_context *ctx, struct nk_window *win, nk_hash name, nk_uint value) -{ - NK_ASSERT(ctx); - NK_ASSERT(win); - if (!win || !ctx) { - return 0; - } - if (!win->tables || win->tables->size >= NK_VALUE_PAGE_CAPACITY) { - struct nk_table *tbl = nk_create_table(ctx); - NK_ASSERT(tbl); - if (!tbl) { - return 0; - } - nk_push_table(win, tbl); - } - win->tables->seq = win->seq; - win->tables->keys[win->tables->size] = name; - win->tables->values[win->tables->size] = value; - return &win->tables->values[win->tables->size++]; -} -NK_LIB nk_uint * -nk_find_value(const struct nk_window *win, nk_hash name) -{ - struct nk_table *iter = win->tables; - while (iter) { - unsigned int i = 0; - unsigned int size = iter->size; - for (i = 0; i < size; ++i) { - if (iter->keys[i] == name) { - iter->seq = win->seq; - return &iter->values[i]; - } - } - size = NK_VALUE_PAGE_CAPACITY; - iter = iter->next; - } - return 0; -} - -enum nk_text_selection_storage_field { - NK_TEXT_SELECTION_STORAGE_ANCHOR, - NK_TEXT_SELECTION_STORAGE_CURSOR, - NK_TEXT_SELECTION_STORAGE_FLAGS, - NK_TEXT_SELECTION_STORAGE_ANCHOR_WIDGET, - NK_TEXT_SELECTION_STORAGE_CURSOR_WIDGET, - NK_TEXT_SELECTION_STORAGE_INDEX, - NK_TEXT_SELECTION_STORAGE_WIDGET_COUNT, - NK_TEXT_SELECTION_STORAGE_FRAME, - NK_TEXT_SELECTION_STORAGE_COUNT -}; - -NK_LIB struct nk_window * -nk_text_selection_storage_window(struct nk_window *win) -{ - while (win->parent) { - win = win->parent; - } - return win; -} - -NK_LIB nk_hash -nk_text_selection_storage_key(nk_hash scope, int field) -{ - return nk_murmur_hash(&scope, sizeof(scope), (nk_hash)(0x74584310u + field)); -} - -NK_LIB void -nk_text_selection_panel_load(struct nk_context *ctx, struct nk_panel *panel) -{ - struct nk_window *win = NULL; - nk_uint *value[NK_TEXT_SELECTION_STORAGE_COUNT]; - nk_uint flags; - int i; - - win = nk_text_selection_storage_window(ctx->current); - panel->text_selection_loaded = nk_true; - for (i = 0; i < NK_TEXT_SELECTION_STORAGE_COUNT; ++i) { - value[i] = nk_find_value(win, nk_text_selection_storage_key(panel->text_selection_scope, i)); - if (!value[i]) { - return; - } - } - - flags = *value[NK_TEXT_SELECTION_STORAGE_FLAGS]; - panel->text_selection.selection.anchor = (int)*value[NK_TEXT_SELECTION_STORAGE_ANCHOR]; - panel->text_selection.selection.cursor = (int)*value[NK_TEXT_SELECTION_STORAGE_CURSOR]; - panel->text_selection.selection.active = (unsigned char)(flags & 0xffu); - panel->text_selection.selection.dragging = (unsigned char)((flags >> 8) & 0xffu); - panel->text_selection.selection.affinity = (unsigned char)((flags >> 16) & 0xffu); - panel->text_selection.selection.anchor_affinity = (unsigned char)((flags >> 24) & 0xffu); - panel->text_selection.anchor_widget = *value[NK_TEXT_SELECTION_STORAGE_ANCHOR_WIDGET]; - panel->text_selection.cursor_widget = *value[NK_TEXT_SELECTION_STORAGE_CURSOR_WIDGET]; - panel->text_selection.widget_index = *value[NK_TEXT_SELECTION_STORAGE_INDEX]; - panel->text_selection.widget_count = *value[NK_TEXT_SELECTION_STORAGE_WIDGET_COUNT]; - panel->text_selection.frame = *value[NK_TEXT_SELECTION_STORAGE_FRAME]; -} - -NK_LIB void -nk_text_selection_panel_save(struct nk_context *ctx, struct nk_panel *panel) -{ - struct nk_window *win = nk_text_selection_storage_window(ctx->current); - nk_uint value[NK_TEXT_SELECTION_STORAGE_COUNT]; - int i; - nk_uint flags; - - flags = (nk_uint)(panel->text_selection.selection.active << 0) | - (nk_uint)(panel->text_selection.selection.dragging << 8) | - (nk_uint)(panel->text_selection.selection.affinity << 16) | - (nk_uint)(panel->text_selection.selection.anchor_affinity << 24); - - value[NK_TEXT_SELECTION_STORAGE_ANCHOR] = (nk_uint)panel->text_selection.selection.anchor; - value[NK_TEXT_SELECTION_STORAGE_CURSOR] = (nk_uint)panel->text_selection.selection.cursor; - value[NK_TEXT_SELECTION_STORAGE_FLAGS] = flags; - value[NK_TEXT_SELECTION_STORAGE_ANCHOR_WIDGET] = panel->text_selection.anchor_widget; - value[NK_TEXT_SELECTION_STORAGE_CURSOR_WIDGET] = panel->text_selection.cursor_widget; - value[NK_TEXT_SELECTION_STORAGE_INDEX] = panel->text_selection.widget_index; - value[NK_TEXT_SELECTION_STORAGE_WIDGET_COUNT] = panel->text_selection.widget_count; - value[NK_TEXT_SELECTION_STORAGE_FRAME] = panel->text_selection.frame; - - for (i = 0; i < NK_TEXT_SELECTION_STORAGE_COUNT; ++i) { - nk_hash key = nk_text_selection_storage_key(panel->text_selection_scope, i); - nk_uint *entry = nk_find_value(win, key); - if (!entry) { - entry = nk_add_value(ctx, win, key, value[i]); - } - - if (entry) { - *entry = value[i]; - } - } -} - -/* =============================================================== - * - * PANEL - * - * ===============================================================*/ -NK_LIB void * -nk_create_panel(struct nk_context *ctx) -{ - struct nk_page_element *elem; - elem = nk_create_page_element(ctx); - if (!elem) { - return 0; - } - return &elem->data.pan; -} -NK_LIB void -nk_free_panel(struct nk_context *ctx, struct nk_panel *pan) -{ - union nk_page_data *pd = NK_CONTAINER_OF(pan, union nk_page_data, pan); - struct nk_page_element *pe = NK_CONTAINER_OF(pd, struct nk_page_element, data); - nk_free_page_element(ctx, pe); -} -NK_LIB nk_bool -nk_panel_has_header(nk_flags flags, const char *title) -{ - nk_bool active = 0; - active = (flags & (NK_WINDOW_CLOSABLE | NK_WINDOW_MINIMIZABLE)); - active = active || (flags & NK_WINDOW_TITLE); - active = active && !(flags & NK_WINDOW_HIDDEN) && title; - return active; -} -NK_LIB struct nk_vec2 -nk_panel_get_padding(const struct nk_style *style, enum nk_panel_type type) -{ - switch (type) { - default: - case NK_PANEL_WINDOW: - return style->window.padding; - case NK_PANEL_GROUP: - return style->window.group_padding; - case NK_PANEL_POPUP: - return style->window.popup_padding; - case NK_PANEL_CONTEXTUAL: - return style->window.contextual_padding; - case NK_PANEL_COMBO: - return style->window.combo_padding; - case NK_PANEL_MENU: - return style->window.menu_padding; - case NK_PANEL_TOOLTIP: - return style->window.menu_padding; - } -} -NK_LIB float -nk_panel_get_border(const struct nk_style *style, nk_flags flags, enum nk_panel_type type) -{ - if (flags & NK_WINDOW_BORDER) { - switch (type) { - default: - case NK_PANEL_WINDOW: - return style->window.border; - case NK_PANEL_GROUP: - return style->window.group_border; - case NK_PANEL_POPUP: - return style->window.popup_border; - case NK_PANEL_CONTEXTUAL: - return style->window.contextual_border; - case NK_PANEL_COMBO: - return style->window.combo_border; - case NK_PANEL_MENU: - return style->window.menu_border; - case NK_PANEL_TOOLTIP: - return style->window.menu_border; - } - } else { - return 0; - } -} -NK_LIB struct nk_color -nk_panel_get_border_color(const struct nk_style *style, enum nk_panel_type type) -{ - switch (type) { - default: - case NK_PANEL_WINDOW: - return style->window.border_color; - case NK_PANEL_GROUP: - return style->window.group_border_color; - case NK_PANEL_POPUP: - return style->window.popup_border_color; - case NK_PANEL_CONTEXTUAL: - return style->window.contextual_border_color; - case NK_PANEL_COMBO: - return style->window.combo_border_color; - case NK_PANEL_MENU: - return style->window.menu_border_color; - case NK_PANEL_TOOLTIP: - return style->window.menu_border_color; - } -} - -NK_LIB nk_bool -nk_panel_is_sub(enum nk_panel_type type) -{ - return ((int)type & (int)NK_PANEL_SET_SUB) ? 1 : 0; -} - -NK_LIB nk_bool -nk_panel_is_nonblock(enum nk_panel_type type) -{ - return ((int)type & (int)NK_PANEL_SET_NONBLOCK) ? 1 : 0; -} - -NK_LIB nk_bool -nk_panel_begin(struct nk_context *ctx, const char *title, enum nk_panel_type panel_type) -{ - struct nk_input *in; - struct nk_window *win; - struct nk_panel *layout; - struct nk_command_buffer *out; - const struct nk_style *style; - const struct nk_user_font *font; - - struct nk_vec2 scrollbar_size; - struct nk_vec2 panel_padding; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - nk_zero(ctx->current->layout, sizeof(*ctx->current->layout)); - if ((ctx->current->flags & NK_WINDOW_HIDDEN) || (ctx->current->flags & NK_WINDOW_CLOSED)) { - nk_zero(ctx->current->layout, sizeof(struct nk_panel)); - ctx->current->layout->type = panel_type; - return 0; - } - /* pull state into local stack */ - style = &ctx->style; - font = style->font; - win = ctx->current; - layout = win->layout; - out = &win->buffer; - in = (win->flags & NK_WINDOW_NO_INPUT) ? 0 : &ctx->input; - if (panel_type == NK_PANEL_WINDOW) { - layout->text_selection_scope = nk_murmur_hash(&win->name, sizeof(win->name), (nk_hash)panel_type); - } else { - layout->text_selection_scope = nk_murmur_hash(title, title ? (int)nk_strlen(title) : 0, win->name ^ (nk_hash)panel_type); - } -#ifdef NK_INCLUDE_COMMAND_USERDATA - win->buffer.userdata = ctx->userdata; -#endif - /* pull style configuration into local stack */ - scrollbar_size = style->window.scrollbar_size; - panel_padding = nk_panel_get_padding(style, panel_type); - - /* window movement */ - if ((win->flags & NK_WINDOW_MOVABLE) && !(win->flags & NK_WINDOW_ROM) && !(win->flags & NK_WINDOW_NO_INPUT)) { - nk_bool left_mouse_down; - unsigned int left_mouse_clicked; - int left_mouse_click_in_cursor; - - /* calculate draggable window space */ - struct nk_rect header; - header.x = win->bounds.x; - header.y = win->bounds.y; - header.w = win->bounds.w; - if (nk_panel_has_header(win->flags, title)) { - header.h = style->font_size + 2.0f * style->window.header.padding.y; - header.h += 2.0f * style->window.header.label_padding.y; - } else { - header.h = panel_padding.y; - } - - /* window movement by dragging */ - left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down; - left_mouse_clicked = in->mouse.buttons[NK_BUTTON_LEFT].clicked; - left_mouse_click_in_cursor = nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, header, nk_true); - if (!(win->flags & NK_WINDOW_MAXIMIZED) && left_mouse_down && left_mouse_click_in_cursor && !left_mouse_clicked) { - win->bounds.x = win->bounds.x + in->mouse.delta.x; - win->bounds.y = win->bounds.y + in->mouse.delta.y; - in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x += in->mouse.delta.x; - in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.y += in->mouse.delta.y; - ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_MOVE]; - } - } - - /* setup panel */ - layout->type = panel_type; - layout->flags = win->flags; - layout->bounds = win->bounds; - layout->bounds.x += panel_padding.x; - layout->bounds.w -= 2 * panel_padding.x; - if (win->flags & NK_WINDOW_BORDER) { - layout->border = nk_panel_get_border(style, win->flags, panel_type); - layout->bounds = nk_shrink_rect(layout->bounds, layout->border); - } else { - layout->border = 0; - } - layout->at_y = layout->bounds.y; - layout->at_x = layout->bounds.x; - layout->max_x = 0; - layout->header_height = 0; - layout->footer_height = 0; - nk_layout_reset_min_row_height(ctx); - layout->row.index = 0; - layout->row.columns = 0; - layout->row.ratio = 0; - layout->row.item_width = 0; - layout->row.tree_depth = 0; - layout->row.height = panel_padding.y; - layout->has_scrolling = nk_true; - - if (!(win->flags & NK_WINDOW_NO_SCROLLBAR_V)) { - layout->bounds.w -= scrollbar_size.x; - } - - if (!nk_panel_is_nonblock(panel_type)) { - layout->footer_height = 0; - if (!(win->flags & NK_WINDOW_NO_SCROLLBAR_H) || win->flags & NK_WINDOW_SCALABLE) { - layout->footer_height = scrollbar_size.y; - } - layout->bounds.h -= layout->footer_height; - } - - /* panel header */ - if (nk_panel_has_header(win->flags, title)) { - struct nk_text text; - struct nk_rect header; - const struct nk_style_item *background = 0; - - /* calculate header bounds */ - header.x = win->bounds.x; - header.y = win->bounds.y; - header.w = win->bounds.w; - header.h = style->font_size + 2.0f * style->window.header.padding.y; - header.h += (2.0f * style->window.header.label_padding.y); - - /* shrink panel by header */ - layout->header_height = header.h; - layout->bounds.y += header.h; - layout->bounds.h -= header.h; - layout->at_y += header.h; - - /* select correct header background and text color */ - if (ctx->active == win) { - background = &style->window.header.active; - text.text = style->window.header.label_active; - } else if (nk_input_is_mouse_hovering_rect(&ctx->input, header)) { - background = &style->window.header.hover; - text.text = style->window.header.label_hover; - } else { - background = &style->window.header.normal; - text.text = style->window.header.label_normal; - } - - /* draw header background */ - header.h += 1.0f; - - switch (background->type) { - case NK_STYLE_ITEM_IMAGE: - text.background = nk_rgba(0, 0, 0, 0); - nk_draw_image(&win->buffer, header, &background->data.image, nk_white); - break; - case NK_STYLE_ITEM_NINE_SLICE: - text.background = nk_rgba(0, 0, 0, 0); - nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_white); - break; - case NK_STYLE_ITEM_COLOR: - text.background = background->data.color; - nk_fill_rect(out, header, 0, background->data.color); - break; - } - - /* window buttons */ - { - struct nk_rect button; - button.y = header.y + style->window.header.padding.y; - button.h = header.h - 2 * style->window.header.padding.y; - button.w = button.h; - - /* window close button */ - if (win->flags & NK_WINDOW_CLOSABLE) { - nk_flags ws = 0; - if (style->window.header.align == NK_HEADER_RIGHT) { - button.x = (header.w + header.x) - (button.w + style->window.header.padding.x); - header.w -= button.w + style->window.header.spacing.x + style->window.header.padding.x; - } else { - button.x = header.x + style->window.header.padding.x; - header.x += button.w + style->window.header.spacing.x + style->window.header.padding.x; - } - - if (nk_do_button_symbol(&ws, &win->buffer, button, style->window.header.close_symbol, NK_BUTTON_DEFAULT, &style->window.header.close_button, in, style->font) && - !(win->flags & NK_WINDOW_ROM)) { - layout->flags |= NK_WINDOW_HIDDEN; - if (!(layout->flags & NK_WINDOW_CLOSE_BUTTON_HIDES)) { - layout->flags |= NK_WINDOW_CLOSED; - } - layout->flags &= (nk_flags)~NK_WINDOW_MINIMIZED; - } - } - - /* window maximize button */ - if (win->flags & NK_WINDOW_MAXIMIZABLE) { - struct nk_style_button maximize_button; - nk_flags ws = 0; - float icon_pad; - - if (style->window.header.align == NK_HEADER_RIGHT) { - button.x = (header.w + header.x) - button.w; - if (!(win->flags & NK_WINDOW_CLOSABLE)) { - button.x -= style->window.header.padding.x; - header.w -= style->window.header.padding.x; - } - header.w -= button.w + style->window.header.spacing.x; - } else { - button.x = header.x; - header.x += button.w + style->window.header.spacing.x + style->window.header.padding.x; - } - - maximize_button = style->window.header.minimize_button; - icon_pad = NK_MAX(4.0f, button.h * 0.25f); - maximize_button.padding.x = NK_MAX(maximize_button.padding.x, icon_pad); - maximize_button.padding.y = NK_MAX(maximize_button.padding.y, icon_pad); - - if (nk_do_button_symbol(&ws, - &win->buffer, - button, - (win->flags & NK_WINDOW_MAXIMIZED) ? NK_SYMBOL_RECT_SOLID : NK_SYMBOL_RECT_OUTLINE, - NK_BUTTON_DEFAULT, - &maximize_button, - in, - style->font) && - !(win->flags & NK_WINDOW_ROM)) { - if (win->flags & NK_WINDOW_MAXIMIZED) { - win->bounds = win->restore_bounds; - win->flags &= (nk_flags)~NK_WINDOW_MAXIMIZED; - layout->flags &= (nk_flags)~NK_WINDOW_MAXIMIZED; - } else { - struct nk_rect target = ctx->window_maximize_bounds; - - if (target.w > 0.0f && target.h > 0.0f) { - win->restore_bounds = win->bounds; - win->bounds = target; - - win->flags |= NK_WINDOW_MAXIMIZED; - layout->flags |= NK_WINDOW_MAXIMIZED; - - win->flags &= (nk_flags)~NK_WINDOW_MINIMIZED; - layout->flags &= (nk_flags)~NK_WINDOW_MINIMIZED; - } - } - } - } - - /* window minimize button */ - if (win->flags & NK_WINDOW_MINIMIZABLE) { - nk_flags ws = 0; - if (style->window.header.align == NK_HEADER_RIGHT) { - button.x = (header.w + header.x) - button.w; - if (!(win->flags & NK_WINDOW_CLOSABLE)) { - button.x -= style->window.header.padding.x; - header.w -= style->window.header.padding.x; - } - header.w -= button.w + style->window.header.spacing.x; - } else { - button.x = header.x; - header.x += button.w + style->window.header.spacing.x + style->window.header.padding.x; - } - if (nk_do_button_symbol(&ws, - &win->buffer, - button, - (layout->flags & NK_WINDOW_MINIMIZED) ? style->window.header.maximize_symbol : style->window.header.minimize_symbol, - NK_BUTTON_DEFAULT, - &style->window.header.minimize_button, - in, - style->font) && - !(win->flags & NK_WINDOW_ROM)) { - layout->flags = (layout->flags & NK_WINDOW_MINIMIZED) ? layout->flags & (nk_flags)~NK_WINDOW_MINIMIZED : layout->flags | NK_WINDOW_MINIMIZED; - } - } - } - - { /* window header title */ - int text_len = nk_strlen(title); - struct nk_rect label = {0, 0, 0, 0}; - float t = nk_text_width(ctx, font, style->font_size, title, text_len); - text.padding = nk_vec2(0, 0); - - label.x = header.x + style->window.header.padding.x; - label.x += style->window.header.label_padding.x; - label.y = header.y + style->window.header.label_padding.y; - label.h = style->font_size + 2 * style->window.header.label_padding.y; - label.w = t + 2 * style->window.header.spacing.x; - label.w = NK_CLAMP(0, label.w, header.x + header.w - label.x); - nk_widget_text(out, label, (const char *)title, text_len, &text, NK_TEXT_LEFT, font); - } - } - - /* draw window background */ - if (!(layout->flags & NK_WINDOW_MINIMIZED) && !(layout->flags & NK_WINDOW_DYNAMIC)) { - struct nk_rect body; - body.x = win->bounds.x; - body.w = win->bounds.w; - body.y = (win->bounds.y + layout->header_height); - body.h = (win->bounds.h - layout->header_height); - - switch (style->window.fixed_background.type) { - case NK_STYLE_ITEM_IMAGE: - nk_draw_image(out, body, &style->window.fixed_background.data.image, nk_white); - break; - case NK_STYLE_ITEM_NINE_SLICE: - nk_draw_nine_slice(out, body, &style->window.fixed_background.data.slice, nk_white); - break; - case NK_STYLE_ITEM_COLOR: - nk_fill_rect(out, body, style->window.rounding, style->window.fixed_background.data.color); - break; - } - } - - /* set clipping rectangle */ - { - struct nk_rect clip; - layout->clip = layout->bounds; - nk_unify(&clip, &win->buffer.clip, layout->clip.x, layout->clip.y, layout->clip.x + layout->clip.w, layout->clip.y + layout->clip.h); - nk_push_scissor(out, clip); - layout->clip = clip; - } - return !(layout->flags & NK_WINDOW_HIDDEN) && !(layout->flags & NK_WINDOW_MINIMIZED); -} - -NK_INTERN void -nk_panel_disable_parent_scrolling(struct nk_panel *layout) -{ - struct nk_panel *parent; - for (parent = layout ? layout->parent : 0; parent; parent = parent->parent) { - parent->has_scrolling = nk_false; - } -} - -NK_LIB void -nk_panel_end(struct nk_context *ctx) -{ - struct nk_input *in; - struct nk_window *window; - struct nk_panel *layout; - const struct nk_style *style; - struct nk_command_buffer *out; - - struct nk_vec2 scrollbar_size; - struct nk_vec2 panel_padding; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - window = ctx->current; - layout = window->layout; - style = &ctx->style; - out = &window->buffer; - in = (layout->flags & NK_WINDOW_ROM || layout->flags & NK_WINDOW_NO_INPUT) ? 0 : &ctx->input; - if (layout->text_selection_loaded) { - nk_text_selection_panel_save(ctx, layout); - } - - if (!nk_panel_is_sub(layout->type)) { - nk_push_scissor(out, nk_null_rect); - } - - /* cache configuration data */ - scrollbar_size = style->window.scrollbar_size; - panel_padding = nk_panel_get_padding(style, layout->type); - - /* update the current cursor Y-position to point over the last added widget */ - layout->at_y += layout->row.height; - - /* dynamic panels */ - if (layout->flags & NK_WINDOW_DYNAMIC && !(layout->flags & NK_WINDOW_MINIMIZED)) { - /* update panel height to fit dynamic growth */ - struct nk_rect empty_space; - if (layout->at_y < (layout->bounds.y + layout->bounds.h)) { - layout->bounds.h = layout->at_y - layout->bounds.y; - } - - /* fill top empty space */ - empty_space.x = window->bounds.x; - empty_space.y = layout->bounds.y; - empty_space.h = panel_padding.y; - empty_space.w = window->bounds.w; - nk_fill_rect(out, empty_space, 0, style->window.background); - - /* fill left empty space */ - empty_space.x = window->bounds.x; - empty_space.y = layout->bounds.y; - empty_space.w = panel_padding.x + layout->border; - empty_space.h = layout->bounds.h; - nk_fill_rect(out, empty_space, 0, style->window.background); - - /* fill right empty space */ - empty_space.x = layout->bounds.x + layout->bounds.w; - empty_space.y = layout->bounds.y; - empty_space.w = panel_padding.x + layout->border; - empty_space.h = layout->bounds.h; - if (*layout->offset_y == 0 && !(layout->flags & NK_WINDOW_NO_SCROLLBAR_V)) { - empty_space.w += scrollbar_size.x; - } - nk_fill_rect(out, empty_space, 0, style->window.background); - - /* fill bottom empty space */ - if (layout->footer_height > 0) { - empty_space.x = window->bounds.x; - empty_space.y = layout->bounds.y + layout->bounds.h; - empty_space.w = window->bounds.w; - empty_space.h = layout->footer_height; - nk_fill_rect(out, empty_space, 0, style->window.background); - } - } - - /* scrollbars */ - if ((!(layout->flags & NK_WINDOW_NO_SCROLLBAR_V) || !(layout->flags & NK_WINDOW_NO_SCROLLBAR_H)) && !(layout->flags & NK_WINDOW_MINIMIZED) && - window->scrollbar_hiding_timer < NK_SCROLLBAR_HIDING_TIMEOUT) { - struct nk_rect scroll; - int scroll_has_scrolling; - float scroll_target; - float scroll_offset; - float scroll_step; - float scroll_inc; - nk_bool scroll_consumed = nk_false; - nk_bool shift_down; - nk_bool can_shift_scroll_h; - float h_scroll_target; - float h_max_offset; - - /* mouse wheel scrolling */ - if (nk_panel_is_sub(layout->type)) { - /* sub-window mouse wheel scrolling */ - struct nk_window *root_window = window; - struct nk_panel *root_panel = window->layout; - while (root_panel->parent) { - root_panel = root_panel->parent; - } - - while (root_window->parent) { - root_window = root_window->parent; - } - - /* only allow scrolling if parent window is active */ - scroll_has_scrolling = nk_false; - if ((root_window == ctx->active) && layout->has_scrolling) { - /* and panel is being hovered and inside clip rect*/ - if (nk_input_is_mouse_hovering_rect(in, layout->bounds) && - NK_INTERSECT(layout->bounds.x, layout->bounds.y, layout->bounds.w, layout->bounds.h, root_panel->clip.x, root_panel->clip.y, root_panel->clip.w, root_panel->clip.h)) { - scroll_has_scrolling = nk_true; - } - } - } else { - /* window mouse wheel scrolling */ - scroll_has_scrolling = (window == ctx->active) && layout->has_scrolling; - if (in && (in->mouse.scroll_delta.y != 0.0f || in->mouse.scroll_delta.x != 0.0f) && scroll_has_scrolling) { - window->scrolled = nk_true; - } else { - window->scrolled = nk_false; - } - } - - shift_down = in && nk_input_is_key_down(in, NK_KEY_SHIFT); - h_scroll_target = (float)(int)(layout->max_x - layout->bounds.x); - h_max_offset = NK_MAX(h_scroll_target - layout->bounds.w, 0.0f); - can_shift_scroll_h = shift_down && !(layout->flags & NK_WINDOW_NO_SCROLLBAR_H) && h_max_offset > 0.0f; - - if (!(layout->flags & NK_WINDOW_NO_SCROLLBAR_V)) { - /* vertical scrollbar */ - nk_flags state = 0; - float old_max_offset = 0.0f; - float new_max_offset = 0.0f; - float input_scroll_y; - nk_bool has_y_wheel_input; - nk_uint before_offset_y; - nk_uint after_offset_y; - nk_bool y_consumed; - - scroll.x = layout->bounds.x + layout->bounds.w + panel_padding.x; - scroll.y = layout->bounds.y; - scroll.w = scrollbar_size.x; - scroll.h = layout->bounds.h; - - scroll_offset = (float)*layout->offset_y; - scroll_step = scroll.h * 0.10f; - scroll_inc = scroll.h * 0.01f; - scroll_target = (float)(int)(layout->at_y - scroll.y); - - old_max_offset = layout->prev_max_y ? (float)*layout->prev_max_y : 0.0f; - new_max_offset = NK_MAX(scroll_target - scroll.h, 0.0f); - - if (layout->prev_max_y && layout->scroll_flags && (*layout->scroll_flags & NK_SCROLL_HAS_PREV_MAX_Y)) { - nk_bool had_scrollbar = old_max_offset > 0.0f; - nk_bool was_at_end = had_scrollbar && (scroll_offset >= NK_MAX(old_max_offset - 1.0f, 0.0f)); - - if (was_at_end && new_max_offset > old_max_offset) { - scroll_offset = new_max_offset; - } - } - - input_scroll_y = in ? in->mouse.scroll_delta.y : 0.0f; - has_y_wheel_input = input_scroll_y != 0.0f && !can_shift_scroll_h; - before_offset_y = *layout->offset_y; - - scroll_offset = nk_do_scrollbarv( - &state, out, scroll, scroll_has_scrolling && !can_shift_scroll_h, scroll_offset, scroll_target, scroll_step, scroll_inc, &ctx->style.scrollv, in, style->font); - - after_offset_y = (nk_uint)scroll_offset; - y_consumed = has_y_wheel_input && after_offset_y != before_offset_y; - - *layout->offset_y = after_offset_y; - - if (y_consumed) { - scroll_consumed = nk_true; - in->mouse.scroll_delta.y = 0.0f; - } - - if (layout->prev_max_y && layout->scroll_flags) { - *layout->prev_max_y = (nk_uint)new_max_offset; - *layout->scroll_flags |= NK_SCROLL_HAS_PREV_MAX_Y; - } - } else if (layout->offset_y) { - *layout->offset_y = 0; - if (layout->prev_max_y && layout->scroll_flags) { - *layout->prev_max_y = 0; - *layout->scroll_flags &= ~(nk_uint)NK_SCROLL_HAS_PREV_MAX_Y; - } - } - - if (!(layout->flags & NK_WINDOW_NO_SCROLLBAR_H)) { - /* horizontal scrollbar */ - nk_flags state = 0; - float old_max_offset = 0.0f; - float new_max_offset = 0.0f; - float input_scroll_x; - nk_bool has_x_wheel_input; - nk_uint before_offset_x; - nk_uint after_offset_x; - nk_bool x_consumed; - - scroll.x = layout->bounds.x; - scroll.y = layout->bounds.y + layout->bounds.h; - scroll.w = layout->bounds.w; - scroll.h = scrollbar_size.y; - - scroll_offset = (float)*layout->offset_x; - scroll_target = (float)(int)(layout->max_x - scroll.x); - scroll_step = layout->max_x * 0.05f; - scroll_inc = layout->max_x * 0.005f; - - old_max_offset = layout->prev_max_x ? (float)*layout->prev_max_x : 0.0f; - new_max_offset = NK_MAX(scroll_target - scroll.w, 0.0f); - - if (layout->prev_max_x && layout->scroll_flags && (*layout->scroll_flags & NK_SCROLL_HAS_PREV_MAX_X)) { - nk_bool had_scrollbar = old_max_offset > 0.0f; - nk_bool was_at_end = had_scrollbar && (scroll_offset >= NK_MAX(old_max_offset - 1.0f, 0.0f)); - - if (was_at_end && new_max_offset > old_max_offset) { - scroll_offset = new_max_offset; - } - } - - input_scroll_x = in ? in->mouse.scroll_delta.x : 0.0f; - if (input_scroll_x == 0.0f && shift_down && in) { - input_scroll_x = in->mouse.scroll_delta.y; - } - - has_x_wheel_input = input_scroll_x != 0.0f; - before_offset_x = *layout->offset_x; - - scroll_offset = nk_do_scrollbarh(&state, out, scroll, scroll_has_scrolling, scroll_offset, scroll_target, scroll_step, scroll_inc, &ctx->style.scrollh, in, style->font); - - after_offset_x = (nk_uint)scroll_offset; - x_consumed = has_x_wheel_input && after_offset_x != before_offset_x; - - *layout->offset_x = after_offset_x; - - if (x_consumed) { - scroll_consumed = nk_true; - - if (in->mouse.scroll_delta.x != 0.0f) { - in->mouse.scroll_delta.x = 0.0f; - } - - if (shift_down) { - in->mouse.scroll_delta.y = 0.0f; - } - } - - if (layout->prev_max_x && layout->scroll_flags) { - *layout->prev_max_x = (nk_uint)new_max_offset; - *layout->scroll_flags |= NK_SCROLL_HAS_PREV_MAX_X; - } - } else if (layout->offset_x) { - *layout->offset_x = 0; - if (layout->prev_max_x && layout->scroll_flags) { - *layout->prev_max_x = 0; - *layout->scroll_flags &= ~(nk_uint)NK_SCROLL_HAS_PREV_MAX_X; - } - } - - if (scroll_consumed && nk_panel_is_sub(layout->type)) { - nk_panel_disable_parent_scrolling(layout); - } - } - - /* hide scroll if no user input */ - if (window->flags & NK_WINDOW_SCROLL_AUTO_HIDE) { - int has_input = nk_input_is_mouse_moved(&ctx->input) || ctx->input.mouse.scroll_delta.y != 0; - int is_window_hovered = nk_window_is_hovered(ctx); - int any_item_active = (ctx->last_widget_state & NK_WIDGET_STATE_MODIFIED); - if ((!has_input && is_window_hovered) || (!is_window_hovered && !any_item_active)) { - window->scrollbar_hiding_timer += ctx->delta_time_seconds; - } else { - window->scrollbar_hiding_timer = 0; - } - } else { - window->scrollbar_hiding_timer = 0; - } - - /* window border */ - if (layout->flags & NK_WINDOW_BORDER) { - struct nk_color border_color = nk_panel_get_border_color(style, layout->type); - const float padding_y = (layout->flags & NK_WINDOW_MINIMIZED) - ? (style->window.border + window->bounds.y + layout->header_height) - : ((layout->flags & NK_WINDOW_DYNAMIC) ? (layout->bounds.y + layout->bounds.h + layout->footer_height) : (window->bounds.y + window->bounds.h)); - struct nk_rect b = window->bounds; - b.h = padding_y - window->bounds.y; - nk_stroke_rect(out, b, style->window.rounding, layout->border, border_color); - } - - /* scaler */ - if ((layout->flags & NK_WINDOW_SCALABLE) && !(layout->flags & NK_WINDOW_MAXIMIZED) && in && !(layout->flags & NK_WINDOW_MINIMIZED)) { - /* calculate scaler bounds */ - struct nk_rect scaler; - scaler.w = scrollbar_size.x; - scaler.h = scrollbar_size.y; - scaler.y = layout->bounds.y + layout->bounds.h; - - if (layout->flags & NK_WINDOW_SCALE_LEFT) { - scaler.x = layout->bounds.x - panel_padding.x * 0.5f; - } else { - scaler.x = layout->bounds.x + layout->bounds.w + panel_padding.x; - - if (layout->flags & NK_WINDOW_NO_SCROLLBAR_V) { - scaler.x -= scaler.w; - } - } - - /* draw scaler */ - { - const struct nk_style_item *item = &style->window.scaler; - if (item->type == NK_STYLE_ITEM_IMAGE) { - nk_draw_image(out, scaler, &item->data.image, nk_white); - } else { - if (layout->flags & NK_WINDOW_SCALE_LEFT) { - nk_fill_triangle(out, scaler.x, scaler.y, scaler.x, scaler.y + scaler.h, scaler.x + scaler.w, scaler.y + scaler.h, item->data.color); - } else { - nk_fill_triangle(out, scaler.x + scaler.w, scaler.y, scaler.x + scaler.w, scaler.y + scaler.h, scaler.x, scaler.y + scaler.h, item->data.color); - } - } - } - - /* do window scaling */ - if (!(window->flags & NK_WINDOW_ROM)) { - struct nk_vec2 window_size = style->window.min_size; - int left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down; - int left_mouse_click_in_scaler = nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, scaler, nk_true); - - if (left_mouse_down && left_mouse_click_in_scaler) { - float delta_x = in->mouse.delta.x; - if (layout->flags & NK_WINDOW_SCALE_LEFT) { - delta_x = -delta_x; - window->bounds.x += in->mouse.delta.x; - } - /* dragging in x-direction */ - if (window->bounds.w + delta_x >= window_size.x) { - if ((delta_x < 0) || (delta_x > 0 && in->mouse.pos.x >= scaler.x)) { - window->bounds.w = window->bounds.w + delta_x; - scaler.x += in->mouse.delta.x; - } - } - /* dragging in y-direction (only possible if static window) */ - if (!(layout->flags & NK_WINDOW_DYNAMIC)) { - if (window_size.y < window->bounds.h + in->mouse.delta.y) { - if ((in->mouse.delta.y < 0) || (in->mouse.delta.y > 0 && in->mouse.pos.y >= scaler.y)) { - window->bounds.h = window->bounds.h + in->mouse.delta.y; - scaler.y += in->mouse.delta.y; - } - } - } - ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_RESIZE_TOP_RIGHT_DOWN_LEFT]; - in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = scaler.x + scaler.w / 2.0f; - in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.y = scaler.y + scaler.h / 2.0f; - } - } - } - if (!nk_panel_is_sub(layout->type)) { - /* window is hidden so clear command buffer */ - if (layout->flags & NK_WINDOW_HIDDEN) { - nk_command_buffer_reset(&window->buffer); - } - /* window is visible and not tab */ - else { - nk_finish(ctx, window); - } - } - - /* NK_WINDOW_REMOVE_ROM flag was set so remove NK_WINDOW_ROM */ - if (layout->flags & NK_WINDOW_REMOVE_ROM) { - layout->flags &= ~(nk_flags)NK_WINDOW_ROM; - layout->flags &= ~(nk_flags)NK_WINDOW_REMOVE_ROM; - } - window->flags = layout->flags; - - /* property garbage collector */ - if (window->property.active && window->property.old != window->property.seq && window->property.active == window->property.prev) { - nk_zero(&window->property, sizeof(window->property)); - } else { - window->property.old = window->property.seq; - window->property.prev = window->property.active; - window->property.seq = 0; - } - /* edit garbage collector */ - if (window->edit.active && window->edit.old != window->edit.seq && window->edit.active == window->edit.prev) { - nk_zero(&window->edit, sizeof(window->edit)); - } else { - window->edit.old = window->edit.seq; - window->edit.prev = window->edit.active; - window->edit.seq = 0; - } - /* contextual garbage collector */ - if (window->popup.active_con && window->popup.con_old != window->popup.con_count) { - window->popup.con_count = 0; - window->popup.con_old = 0; - window->popup.active_con = 0; - } else { - window->popup.con_old = window->popup.con_count; - window->popup.con_count = 0; - } - window->popup.combo_count = 0; - /* helper to make sure you have a 'nk_tree_push' for every 'nk_tree_pop' */ - NK_ASSERT(!layout->row.tree_depth); -} - -/* =============================================================== - * - * WINDOW - * - * ===============================================================*/ -NK_LIB void * -nk_create_window(struct nk_context *ctx) -{ - struct nk_page_element *elem; - elem = nk_create_page_element(ctx); - if (!elem) { - return 0; - } - elem->data.win.seq = ctx->seq; - return &elem->data.win; -} -NK_LIB void -nk_free_window(struct nk_context *ctx, struct nk_window *win) -{ - /* unlink windows from list */ - struct nk_table *it = win->tables; - if (win->popup.win) { - nk_free_window(ctx, win->popup.win); - win->popup.win = 0; - } - win->next = 0; - win->prev = 0; - - while (it) { - /*free window state tables */ - struct nk_table *n = it->next; - nk_remove_table(win, it); - nk_free_table(ctx, it); - if (it == win->tables) { - win->tables = n; - } - it = n; - } - - /* link windows into freelist */ - { - union nk_page_data *pd = NK_CONTAINER_OF(win, union nk_page_data, win); - struct nk_page_element *pe = NK_CONTAINER_OF(pd, struct nk_page_element, data); - nk_free_page_element(ctx, pe); - } -} -NK_LIB struct nk_window * -nk_find_window(const struct nk_context *ctx, nk_hash hash, const char *name) -{ - struct nk_window *iter; - iter = ctx->begin; - while (iter) { - NK_ASSERT(iter != iter->next); - if (iter->name == hash) { - int max_len = nk_strlen(iter->name_string); - if (!nk_stricmpn(iter->name_string, name, max_len)) { - return iter; - } - } - iter = iter->next; - } - return 0; -} -NK_LIB void -nk_insert_window(struct nk_context *ctx, struct nk_window *win, enum nk_window_insert_location loc) -{ - const struct nk_window *iter; - NK_ASSERT(ctx); - NK_ASSERT(win); - if (!win || !ctx) { - return; - } - - iter = ctx->begin; - while (iter) { - NK_ASSERT(iter != iter->next); - NK_ASSERT(iter != win); - if (iter == win) { - return; - } - iter = iter->next; - } - - if (!ctx->begin) { - win->next = 0; - win->prev = 0; - ctx->begin = win; - ctx->end = win; - ctx->count = 1; - return; - } - if (loc == NK_INSERT_BACK) { - struct nk_window *end; - end = ctx->end; - end->flags |= NK_WINDOW_ROM; - end->next = win; - win->prev = ctx->end; - win->next = 0; - ctx->end = win; - ctx->active = ctx->end; - ctx->end->flags &= ~(nk_flags)NK_WINDOW_ROM; - } else { - /*ctx->end->flags |= NK_WINDOW_ROM;*/ - ctx->begin->prev = win; - win->next = ctx->begin; - win->prev = 0; - ctx->begin = win; - ctx->begin->flags &= ~(nk_flags)NK_WINDOW_ROM; - } - ctx->count++; -} -NK_LIB void -nk_remove_window(struct nk_context *ctx, struct nk_window *win) -{ - if (win == ctx->begin || win == ctx->end) { - if (win == ctx->begin) { - ctx->begin = win->next; - if (win->next) { - win->next->prev = 0; - } - } - if (win == ctx->end) { - ctx->end = win->prev; - if (win->prev) { - win->prev->next = 0; - } - } - } else { - if (win->next) { - win->next->prev = win->prev; - } - if (win->prev) { - win->prev->next = win->next; - } - } - if (win == ctx->active || !ctx->active) { - ctx->active = ctx->end; - if (ctx->end) { - ctx->end->flags &= ~(nk_flags)NK_WINDOW_ROM; - } - } - win->next = 0; - win->prev = 0; - ctx->count--; -} - -NK_API nk_bool -nk_begin(struct nk_context *ctx, const char *title, struct nk_rect bounds, nk_flags flags) -{ - return nk_begin_titled(ctx, title, title, bounds, flags); -} - -NK_API nk_bool -nk_begin_titled(struct nk_context *ctx, const char *name, const char *title, struct nk_rect bounds, nk_flags flags) -{ - struct nk_window *win; - struct nk_style *style; - nk_hash name_hash; - int name_len; - int ret = 0; - - NK_ASSERT(ctx); - NK_ASSERT(name); - NK_ASSERT(title); - NK_ASSERT(ctx->style.font && "if this triggers you forgot to add a font"); - NK_ASSERT(!ctx->current && "if this triggers you missed a `nk_end` call"); - if (!ctx || ctx->current || !title || !name) { - return 0; - } - - /* find or create window */ - style = &ctx->style; - name_len = (int)nk_strlen(name); - name_hash = nk_murmur_hash(name, (int)name_len, NK_WINDOW_TITLE); - win = nk_find_window(ctx, name_hash, name); - if (!win) { - /* create new window */ - nk_size name_length = (nk_size)name_len; - win = (struct nk_window *)nk_create_window(ctx); - NK_ASSERT(win); - if (!win) { - return 0; - } - - if (flags & NK_WINDOW_BACKGROUND) { - nk_insert_window(ctx, win, NK_INSERT_FRONT); - } else { - nk_insert_window(ctx, win, NK_INSERT_BACK); - } - nk_command_buffer_init(&win->buffer, &ctx->memory, NK_CLIPPING_ON); - - win->flags = flags; - win->bounds = bounds; - win->name = name_hash; - name_length = NK_MIN(name_length, NK_WINDOW_MAX_NAME - 1); - NK_MEMCPY(win->name_string, name, name_length); - win->name_string[name_length] = 0; - win->popup.win = 0; - win->widgets_disabled = nk_false; - if (!ctx->active) { - ctx->active = win; - } - } else { - /* update window */ - win->flags &= ~(nk_flags)(NK_WINDOW_PRIVATE - 1); - win->flags |= flags; - if (!(win->flags & (NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE))) { - win->bounds = bounds; - } - /* If this assert triggers you either: - * - * I.) Have more than one window with the same name or - * II.) You forgot to actually draw the window. - * More specific you did not call `nk_clear` (nk_clear will be - * automatically called for you if you are using one of the - * provided demo backends). */ - NK_ASSERT(win->seq != ctx->seq); - win->seq = ctx->seq; - if (!ctx->active && !(win->flags & NK_WINDOW_HIDDEN)) { - ctx->active = win; - ctx->end = win; - } - } - if (win->flags & NK_WINDOW_HIDDEN) { - ctx->current = win; - win->layout = 0; - return 0; - } else { - nk_start(ctx, win); - } - - if ((win->flags & NK_WINDOW_MAXIMIZED) && ctx->window_maximize_bounds.w > 0.0f && ctx->window_maximize_bounds.h > 0.0f) { - win->bounds = ctx->window_maximize_bounds; - } - - /* window overlapping */ - if (!(win->flags & NK_WINDOW_HIDDEN) && !(win->flags & NK_WINDOW_NO_INPUT)) { - int inpanel, ishovered; - struct nk_window *iter = win; - float h = style->font_size + 2.0f * style->window.header.padding.y + (2.0f * style->window.header.label_padding.y); - struct nk_rect win_bounds = (!(win->flags & NK_WINDOW_MINIMIZED)) ? win->bounds : nk_rect(win->bounds.x, win->bounds.y, win->bounds.w, h); - - /* activate window if hovered and no other window is overlapping this window */ - inpanel = nk_input_has_mouse_click_down_in_rect(&ctx->input, NK_BUTTON_LEFT, win_bounds, nk_true); - inpanel = inpanel && ctx->input.mouse.buttons[NK_BUTTON_LEFT].clicked; - ishovered = nk_input_is_mouse_hovering_rect(&ctx->input, win_bounds); - if ((win != ctx->active) && ishovered && !ctx->input.mouse.buttons[NK_BUTTON_LEFT].down) { - iter = win->next; - while (iter) { - struct nk_rect iter_bounds = (!(iter->flags & NK_WINDOW_MINIMIZED)) ? iter->bounds : nk_rect(iter->bounds.x, iter->bounds.y, iter->bounds.w, h); - if (NK_INTERSECT(win_bounds.x, win_bounds.y, win_bounds.w, win_bounds.h, iter_bounds.x, iter_bounds.y, iter_bounds.w, iter_bounds.h) && - (!(iter->flags & NK_WINDOW_HIDDEN))) { - break; - } - - if (iter->popup.win && iter->popup.active && !(iter->flags & NK_WINDOW_HIDDEN) && - NK_INTERSECT(win->bounds.x, - win_bounds.y, - win_bounds.w, - win_bounds.h, - iter->popup.win->bounds.x, - iter->popup.win->bounds.y, - iter->popup.win->bounds.w, - iter->popup.win->bounds.h)) { - break; - } - iter = iter->next; - } - } - - /* activate window if clicked */ - if (iter && inpanel && (win != ctx->end)) { - iter = win->next; - while (iter) { - /* try to find a panel with higher priority in the same position */ - struct nk_rect iter_bounds = (!(iter->flags & NK_WINDOW_MINIMIZED)) ? iter->bounds : nk_rect(iter->bounds.x, iter->bounds.y, iter->bounds.w, h); - if (NK_INBOX(ctx->input.mouse.pos.x, ctx->input.mouse.pos.y, iter_bounds.x, iter_bounds.y, iter_bounds.w, iter_bounds.h) && !(iter->flags & NK_WINDOW_HIDDEN)) { - break; - } - if (iter->popup.win && iter->popup.active && !(iter->flags & NK_WINDOW_HIDDEN) && - NK_INTERSECT( - win_bounds.x, win_bounds.y, win_bounds.w, win_bounds.h, iter->popup.win->bounds.x, iter->popup.win->bounds.y, iter->popup.win->bounds.w, iter->popup.win->bounds.h)) { - break; - } - iter = iter->next; - } - } - if (iter && !(win->flags & NK_WINDOW_ROM) && (win->flags & NK_WINDOW_BACKGROUND)) { - win->flags |= (nk_flags)NK_WINDOW_ROM; - iter->flags &= ~(nk_flags)NK_WINDOW_ROM; - ctx->active = iter; - if (!(iter->flags & NK_WINDOW_BACKGROUND)) { - /* current window is active in that position so transfer to top - * at the highest priority in stack */ - nk_remove_window(ctx, iter); - nk_insert_window(ctx, iter, NK_INSERT_BACK); - } - } else { - if (!iter && ctx->end != win) { - if (!(win->flags & NK_WINDOW_BACKGROUND)) { - /* current window is active in that position so transfer to top - * at the highest priority in stack */ - nk_remove_window(ctx, win); - nk_insert_window(ctx, win, NK_INSERT_BACK); - } - win->flags &= ~(nk_flags)NK_WINDOW_ROM; - ctx->active = win; - } - if (ctx->end != win && !(win->flags & NK_WINDOW_BACKGROUND)) { - win->flags |= NK_WINDOW_ROM; - } - } - } - win->layout = (struct nk_panel *)nk_create_panel(ctx); - ctx->current = win; - ret = nk_panel_begin(ctx, title, NK_PANEL_WINDOW); - win->layout->offset_x = &win->scrollbar.x; - win->layout->offset_y = &win->scrollbar.y; - win->layout->prev_max_x = &win->scrollbar.prev_max_x; - win->layout->prev_max_y = &win->scrollbar.prev_max_y; - win->layout->scroll_flags = &win->scrollbar.flags; - return ret; -} -NK_API void -nk_end(struct nk_context *ctx) -{ - struct nk_panel *layout; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current && "if this triggers you forgot to call `nk_begin`"); - if (!ctx || !ctx->current) { - return; - } - - layout = ctx->current->layout; - if (!layout || (layout->type == NK_PANEL_WINDOW && (ctx->current->flags & NK_WINDOW_HIDDEN))) { - ctx->current = 0; - return; - } - nk_panel_end(ctx); - nk_free_panel(ctx, ctx->current->layout); - ctx->current = 0; -} -NK_API struct nk_rect -nk_window_get_bounds(const struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) { - return nk_rect(0, 0, 0, 0); - } - return ctx->current->bounds; -} -NK_API struct nk_vec2 -nk_window_get_position(const struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) { - return nk_vec2(0, 0); - } - return nk_vec2(ctx->current->bounds.x, ctx->current->bounds.y); -} -NK_API struct nk_vec2 -nk_window_get_size(const struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) { - return nk_vec2(0, 0); - } - return nk_vec2(ctx->current->bounds.w, ctx->current->bounds.h); -} -NK_API float -nk_window_get_width(const struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) { - return 0; - } - return ctx->current->bounds.w; -} -NK_API float -nk_window_get_height(const struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) { - return 0; - } - return ctx->current->bounds.h; -} -NK_API struct nk_rect -nk_window_get_content_region(const struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) { - return nk_rect(0, 0, 0, 0); - } - return ctx->current->layout->clip; -} -NK_API struct nk_vec2 -nk_window_get_content_region_min(const struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current) { - return nk_vec2(0, 0); - } - return nk_vec2(ctx->current->layout->clip.x, ctx->current->layout->clip.y); -} -NK_API struct nk_vec2 -nk_window_get_content_region_max(const struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current) { - return nk_vec2(0, 0); - } - return nk_vec2(ctx->current->layout->clip.x + ctx->current->layout->clip.w, ctx->current->layout->clip.y + ctx->current->layout->clip.h); -} -NK_API struct nk_vec2 -nk_window_get_content_region_size(const struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current) { - return nk_vec2(0, 0); - } - return nk_vec2(ctx->current->layout->clip.w, ctx->current->layout->clip.h); -} -NK_API struct nk_command_buffer * -nk_window_get_canvas(const struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current) { - return 0; - } - return &ctx->current->buffer; -} -NK_API struct nk_panel * -nk_window_get_panel(const struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) { - return 0; - } - return ctx->current->layout; -} -NK_API void -nk_window_get_scroll(const struct nk_context *ctx, nk_uint *offset_x, nk_uint *offset_y) -{ - struct nk_window *win; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) { - return; - } - win = ctx->current; - if (offset_x) { - *offset_x = win->scrollbar.x; - } - if (offset_y) { - *offset_y = win->scrollbar.y; - } -} -NK_API nk_bool -nk_window_has_focus(const struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current) { - return 0; - } - return ctx->current == ctx->active; -} -NK_API nk_bool -nk_window_is_hovered(const struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current || (ctx->current->flags & NK_WINDOW_HIDDEN)) { - return 0; - } else { - struct nk_rect actual_bounds = ctx->current->bounds; - if (ctx->current->flags & NK_WINDOW_MINIMIZED) { - actual_bounds.h = ctx->current->layout->header_height; - } - return nk_input_is_mouse_hovering_rect(&ctx->input, actual_bounds); - } -} -NK_API nk_bool -nk_window_is_any_hovered(const struct nk_context *ctx) -{ - struct nk_window *iter; - NK_ASSERT(ctx); - if (!ctx) { - return 0; - } - iter = ctx->begin; - while (iter) { - /* check if window is being hovered */ - if (!(iter->flags & NK_WINDOW_HIDDEN)) { - /* check if window popup is being hovered */ - if (iter->popup.active && iter->popup.win && nk_input_is_mouse_hovering_rect(&ctx->input, iter->popup.win->bounds)) { - return 1; - } - - if (iter->flags & NK_WINDOW_MINIMIZED) { - struct nk_rect header = iter->bounds; - header.h = ctx->style.font_size + 2 * ctx->style.window.header.padding.y; - if (nk_input_is_mouse_hovering_rect(&ctx->input, header)) { - return 1; - } - } else if (nk_input_is_mouse_hovering_rect(&ctx->input, iter->bounds)) { - return 1; - } - } - iter = iter->next; - } - return 0; -} -NK_API nk_bool -nk_item_is_any_active(const struct nk_context *ctx) -{ - int any_hovered = nk_window_is_any_hovered(ctx); - int any_active = (ctx->last_widget_state & NK_WIDGET_STATE_MODIFIED); - return any_hovered || any_active; -} -NK_API nk_bool -nk_window_is_collapsed(const struct nk_context *ctx, const char *name) -{ - int title_len; - nk_hash title_hash; - struct nk_window *win; - NK_ASSERT(ctx); - if (!ctx) { - return 0; - } - - title_len = (int)nk_strlen(name); - title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE); - win = nk_find_window(ctx, title_hash, name); - if (!win) { - return 0; - } - return win->flags & NK_WINDOW_MINIMIZED; -} -NK_API nk_bool -nk_window_is_closed(const struct nk_context *ctx, const char *name) -{ - int title_len; - nk_hash title_hash; - struct nk_window *win; - NK_ASSERT(ctx); - if (!ctx) { - return 1; - } - - title_len = (int)nk_strlen(name); - title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE); - win = nk_find_window(ctx, title_hash, name); - if (!win) { - return 1; - } - return (win->flags & NK_WINDOW_CLOSED); -} -NK_API nk_bool -nk_window_is_hidden(const struct nk_context *ctx, const char *name) -{ - int title_len; - nk_hash title_hash; - struct nk_window *win; - NK_ASSERT(ctx); - if (!ctx) { - return 1; - } - - title_len = (int)nk_strlen(name); - title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE); - win = nk_find_window(ctx, title_hash, name); - if (!win) { - return 1; - } - return (win->flags & NK_WINDOW_HIDDEN); -} -NK_API nk_bool -nk_window_is_active(const struct nk_context *ctx, const char *name) -{ - int title_len; - nk_hash title_hash; - struct nk_window *win; - NK_ASSERT(ctx); - if (!ctx) { - return 0; - } - - title_len = (int)nk_strlen(name); - title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE); - win = nk_find_window(ctx, title_hash, name); - if (!win) { - return 0; - } - return win == ctx->active; -} -NK_API struct nk_window * -nk_window_find(const struct nk_context *ctx, const char *name) -{ - int title_len; - nk_hash title_hash; - title_len = (int)nk_strlen(name); - title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE); - return nk_find_window(ctx, title_hash, name); -} -NK_API void -nk_window_set_maximize_bounds(struct nk_context *ctx, struct nk_rect bounds) -{ - if (ctx) { - ctx->window_maximize_bounds = bounds; - } -} -NK_API void -nk_window_close(struct nk_context *ctx, const char *name) -{ - struct nk_window *win; - NK_ASSERT(ctx); - if (!ctx) { - return; - } - win = nk_window_find(ctx, name); - if (!win) { - return; - } - NK_ASSERT(ctx->current != win && "You cannot close a currently active window"); - if (ctx->current == win) { - return; - } - win->flags |= NK_WINDOW_HIDDEN; - win->flags |= NK_WINDOW_CLOSED; -} -NK_API void -nk_window_set_bounds(struct nk_context *ctx, const char *name, struct nk_rect bounds) -{ - struct nk_window *win; - NK_ASSERT(ctx); - if (!ctx) { - return; - } - win = nk_window_find(ctx, name); - if (!win) { - return; - } - win->bounds = bounds; -} -NK_API void -nk_window_set_position(struct nk_context *ctx, const char *name, struct nk_vec2 pos) -{ - struct nk_window *win = nk_window_find(ctx, name); - if (!win) { - return; - } - win->bounds.x = pos.x; - win->bounds.y = pos.y; -} -NK_API void -nk_window_set_size(struct nk_context *ctx, const char *name, struct nk_vec2 size) -{ - struct nk_window *win = nk_window_find(ctx, name); - if (!win) { - return; - } - win->bounds.w = size.x; - win->bounds.h = size.y; -} -NK_API void -nk_window_set_scroll(struct nk_context *ctx, nk_uint offset_x, nk_uint offset_y) -{ - struct nk_window *win; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) { - return; - } - win = ctx->current; - win->scrollbar.x = offset_x; - win->scrollbar.y = offset_y; -} -NK_API void -nk_window_collapse(struct nk_context *ctx, const char *name, enum nk_collapse_states c) -{ - int title_len; - nk_hash title_hash; - struct nk_window *win; - NK_ASSERT(ctx); - if (!ctx) { - return; - } - - title_len = (int)nk_strlen(name); - title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE); - win = nk_find_window(ctx, title_hash, name); - if (!win) { - return; - } - if (c == NK_MINIMIZED) { - win->flags |= NK_WINDOW_MINIMIZED; - } else { - win->flags &= ~(nk_flags)NK_WINDOW_MINIMIZED; - } -} -NK_API void -nk_window_collapse_if(struct nk_context *ctx, const char *name, enum nk_collapse_states c, int cond) -{ - NK_ASSERT(ctx); - if (!ctx || !cond) { - return; - } - nk_window_collapse(ctx, name, c); -} -NK_API void -nk_window_show(struct nk_context *ctx, const char *name, enum nk_show_states s) -{ - int title_len; - nk_hash title_hash; - struct nk_window *win; - NK_ASSERT(ctx); - if (!ctx) { - return; - } - - title_len = (int)nk_strlen(name); - title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE); - win = nk_find_window(ctx, title_hash, name); - if (!win) { - return; - } - if (s == NK_HIDDEN) { - win->flags |= NK_WINDOW_HIDDEN; - } else { - win->flags &= ~(nk_flags)NK_WINDOW_HIDDEN; - } -} -NK_API void -nk_window_show_if(struct nk_context *ctx, const char *name, enum nk_show_states s, int cond) -{ - NK_ASSERT(ctx); - if (!ctx || !cond) { - return; - } - nk_window_show(ctx, name, s); -} - -NK_API void -nk_window_set_focus(struct nk_context *ctx, const char *name) -{ - int title_len; - nk_hash title_hash; - struct nk_window *win; - NK_ASSERT(ctx); - if (!ctx) { - return; - } - - title_len = (int)nk_strlen(name); - title_hash = nk_murmur_hash(name, (int)title_len, NK_WINDOW_TITLE); - win = nk_find_window(ctx, title_hash, name); - if (win && ctx->end != win) { - nk_remove_window(ctx, win); - nk_insert_window(ctx, win, NK_INSERT_BACK); - } - ctx->active = win; -} -NK_API void -nk_rule_horizontal(struct nk_context *ctx, struct nk_color color, nk_bool rounding) -{ - struct nk_rect space; - enum nk_widget_layout_states state = nk_widget(&space, ctx); - struct nk_command_buffer *canvas = nk_window_get_canvas(ctx); - if (!state) { - return; - } - nk_fill_rect(canvas, space, rounding && space.h > 1.5f ? space.h / 2.0f : 0, color); -} - -/* =============================================================== - * - * POPUP - * - * ===============================================================*/ -NK_API nk_bool -nk_popup_begin(struct nk_context *ctx, enum nk_popup_type type, const char *title, nk_flags flags, struct nk_rect rect) -{ - struct nk_window *popup; - struct nk_window *win; - struct nk_panel *panel; - - int title_len; - nk_hash title_hash; - nk_size allocated; - - NK_ASSERT(ctx); - NK_ASSERT(title); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - win = ctx->current; - panel = win->layout; - NK_ASSERT(!((int)panel->type & (int)NK_PANEL_SET_POPUP) && "popups are not allowed to have popups"); - (void)panel; - title_len = (int)nk_strlen(title); - title_hash = nk_murmur_hash(title, (int)title_len, NK_PANEL_POPUP); - - popup = win->popup.win; - if (!popup) { - popup = (struct nk_window *)nk_create_window(ctx); - popup->parent = win; - win->popup.win = popup; - win->popup.active = 0; - win->popup.type = NK_PANEL_POPUP; - } - - /* make sure we have correct popup */ - if (win->popup.name != title_hash) { - if (!win->popup.active) { - nk_zero(popup, sizeof(*popup)); - win->popup.name = title_hash; - win->popup.active = 1; - win->popup.type = NK_PANEL_POPUP; - } else { - return 0; - } - } - - /* popup position is local to window */ - ctx->current = popup; - rect.x += win->layout->clip.x; - rect.y += win->layout->clip.y; - - /* setup popup data */ - popup->parent = win; - popup->bounds = rect; - popup->seq = ctx->seq; - popup->layout = (struct nk_panel *)nk_create_panel(ctx); - popup->flags = flags; - popup->flags |= NK_WINDOW_BORDER; - if (type == NK_POPUP_DYNAMIC) { - popup->flags |= NK_WINDOW_DYNAMIC; - } - - popup->buffer = win->buffer; - nk_start_popup(ctx, win); - allocated = ctx->memory.allocated; - nk_push_scissor(&popup->buffer, nk_null_rect); - - if (nk_panel_begin(ctx, title, NK_PANEL_POPUP)) { - /* popup is running therefore invalidate parent panels */ - struct nk_panel *root; - root = win->layout; - while (root) { - root->flags |= NK_WINDOW_ROM; - root->flags &= ~(nk_flags)NK_WINDOW_REMOVE_ROM; - root = root->parent; - } - win->popup.active = 1; - popup->layout->offset_x = &popup->scrollbar.x; - popup->layout->offset_y = &popup->scrollbar.y; - popup->layout->prev_max_x = &popup->scrollbar.prev_max_x; - popup->layout->prev_max_y = &popup->scrollbar.prev_max_y; - popup->layout->scroll_flags = &popup->scrollbar.flags; - popup->layout->parent = win->layout; - return 1; - } else { - /* popup was closed/is invalid so cleanup */ - struct nk_panel *root; - root = win->layout; - while (root) { - root->flags |= NK_WINDOW_REMOVE_ROM; - root = root->parent; - } - win->popup.buf.active = 0; - win->popup.active = 0; - ctx->memory.allocated = allocated; - ctx->current = win; - nk_free_panel(ctx, popup->layout); - popup->layout = 0; - return 0; - } -} -NK_LIB nk_bool -nk_nonblock_begin(struct nk_context *ctx, nk_flags flags, struct nk_rect body, struct nk_rect header, enum nk_panel_type panel_type) -{ - struct nk_window *popup; - struct nk_window *win; - struct nk_panel *panel; - int is_active = nk_true; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - /* popups cannot have popups */ - win = ctx->current; - panel = win->layout; - NK_ASSERT(!((int)panel->type & (int)NK_PANEL_SET_POPUP)); - (void)panel; - popup = win->popup.win; - if (!popup) { - /* create window for nonblocking popup */ - popup = (struct nk_window *)nk_create_window(ctx); - popup->parent = win; - win->popup.win = popup; - win->popup.type = panel_type; - nk_command_buffer_init(&popup->buffer, &ctx->memory, NK_CLIPPING_ON); - } else { - /* close the popup if user pressed outside or in the header */ - int pressed, in_body, in_header; -#ifdef NK_BUTTON_TRIGGER_ON_RELEASE - pressed = nk_input_is_mouse_released(&ctx->input, NK_BUTTON_LEFT); -#else - pressed = nk_input_is_mouse_pressed(&ctx->input, NK_BUTTON_LEFT); -#endif - in_body = nk_input_is_mouse_hovering_rect(&ctx->input, body); - in_header = nk_input_is_mouse_hovering_rect(&ctx->input, header); - if (pressed && (!in_body || in_header)) { - is_active = nk_false; - } - } - win->popup.header = header; - - if (!is_active) { - /* remove read only mode from all parent panels */ - struct nk_panel *root = win->layout; - while (root) { - root->flags |= NK_WINDOW_REMOVE_ROM; - root = root->parent; - } - return is_active; - } - popup->bounds = body; - popup->parent = win; - popup->layout = (struct nk_panel *)nk_create_panel(ctx); - popup->flags = flags; - popup->flags |= NK_WINDOW_BORDER; - popup->flags |= NK_WINDOW_DYNAMIC; - popup->seq = ctx->seq; - win->popup.active = 1; - NK_ASSERT(popup->layout); - - nk_start_popup(ctx, win); - popup->buffer = win->buffer; - nk_push_scissor(&popup->buffer, nk_null_rect); - ctx->current = popup; - - nk_panel_begin(ctx, 0, panel_type); - win->buffer = popup->buffer; - popup->layout->parent = win->layout; - popup->layout->offset_x = &popup->scrollbar.x; - popup->layout->offset_y = &popup->scrollbar.y; - popup->layout->prev_max_x = &popup->scrollbar.prev_max_x; - popup->layout->prev_max_y = &popup->scrollbar.prev_max_y; - popup->layout->scroll_flags = &popup->scrollbar.flags; - - /* set read only mode to all parent panels */ - { - struct nk_panel *root; - root = win->layout; - while (root) { - root->flags |= NK_WINDOW_ROM; - root = root->parent; - } - } - return is_active; -} -NK_API void -nk_popup_close(struct nk_context *ctx) -{ - struct nk_window *popup; - NK_ASSERT(ctx); - if (!ctx || !ctx->current) { - return; - } - - popup = ctx->current; - NK_ASSERT(popup->parent); - NK_ASSERT((int)popup->layout->type & (int)NK_PANEL_SET_POPUP); - popup->flags |= NK_WINDOW_HIDDEN; -} -NK_API void -nk_popup_end(struct nk_context *ctx) -{ - struct nk_window *win; - struct nk_window *popup; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - popup = ctx->current; - if (!popup->parent) { - return; - } - win = popup->parent; - if (popup->flags & NK_WINDOW_HIDDEN) { - struct nk_panel *root; - root = win->layout; - while (root) { - root->flags |= NK_WINDOW_REMOVE_ROM; - root = root->parent; - } - win->popup.active = 0; - } - nk_push_scissor(&popup->buffer, nk_null_rect); - nk_end(ctx); - - win->buffer = popup->buffer; - nk_finish_popup(ctx, win); - ctx->current = win; - nk_push_scissor(&win->buffer, win->layout->clip); -} -NK_API void -nk_popup_get_scroll(const struct nk_context *ctx, nk_uint *offset_x, nk_uint *offset_y) -{ - struct nk_window *popup; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - popup = ctx->current; - if (offset_x) { - *offset_x = popup->scrollbar.x; - } - if (offset_y) { - *offset_y = popup->scrollbar.y; - } -} -NK_API void -nk_popup_set_scroll(struct nk_context *ctx, nk_uint offset_x, nk_uint offset_y) -{ - struct nk_window *popup; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - popup = ctx->current; - popup->scrollbar.x = offset_x; - popup->scrollbar.y = offset_y; -} - -/* ============================================================== - * - * CONTEXTUAL - * - * ===============================================================*/ -NK_API nk_bool -nk_contextual_begin(struct nk_context *ctx, nk_flags flags, struct nk_vec2 size, struct nk_rect trigger_bounds) -{ - struct nk_window *win; - struct nk_window *popup; - struct nk_rect body; - struct nk_input *in; - - NK_STORAGE const struct nk_rect null_rect = {-1, -1, 0, 0}; - int is_clicked = 0; - int is_open = 0; - int ret = 0; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - win = ctx->current; - ++win->popup.con_count; - if (ctx->current != ctx->active) { - return 0; - } - - /* check if currently active contextual is active */ - popup = win->popup.win; - is_open = (popup && win->popup.type == NK_PANEL_CONTEXTUAL); - in = win->widgets_disabled ? 0 : &ctx->input; - if (in) { - int right_pressed = nk_input_is_mouse_pressed(in, NK_BUTTON_RIGHT); - - is_clicked = nk_input_mouse_clicked(in, NK_BUTTON_RIGHT, trigger_bounds); - - /* - * The currently active contextual was reached before the newly right-clicked target - * Close it now so the later target can claim the popup during the same frame - */ - if (is_open && win->popup.active_con == win->popup.con_count && right_pressed && !is_clicked) { - struct nk_panel *root = win->layout; - while (root) { - root->flags &= ~(nk_flags)NK_WINDOW_ROM; - root = root->parent; - } - - win->popup.active = 0; - win->popup.active_con = 0; - win->popup.type = NK_PANEL_NONE; - - popup->seq = 0; - popup->flags |= NK_WINDOW_HIDDEN; - - is_open = 0; - } - - /* - * Ignore other contextual targets unless this target was just right-clicked - * A clicked target takes ownership of the popup - */ - if (win->popup.active_con && win->popup.con_count != win->popup.active_con && !is_clicked) { - return 0; - } - - if (!is_open && !is_clicked) { - return 0; - } - - win->popup.active_con = win->popup.con_count; - - if (is_clicked) { - body.x = in->mouse.pos.x; - body.y = in->mouse.pos.y; - } else { - body.x = popup->bounds.x; - body.y = popup->bounds.y; - } - - body.w = size.x; - body.h = size.y; - - { - struct nk_rect client = ctx->window_maximize_bounds; - - if (client.w > 0.0f && client.h > 0.0f) { - body.w = NK_MIN(body.w, client.w); - body.h = NK_MIN(body.h, client.h); - body.x = NK_CLAMP(client.x, body.x, client.x + client.w - body.w); - body.y = NK_CLAMP(client.y, body.y, client.y + client.h - body.h); - } - } - - ret = nk_nonblock_begin(ctx, flags | NK_WINDOW_NO_SCROLLBAR, body, null_rect, NK_PANEL_CONTEXTUAL); - if (ret) { - win->popup.type = NK_PANEL_CONTEXTUAL; - } else { - win->popup.active_con = 0; - win->popup.type = NK_PANEL_NONE; - - if (win->popup.win) { - win->popup.win->flags = 0; - } - } - } - return ret; -} -NK_API nk_bool -nk_contextual_item_text(struct nk_context *ctx, const char *text, int len, nk_flags alignment) -{ - struct nk_window *win; - const struct nk_input *in; - const struct nk_style *style; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - win = ctx->current; - style = &ctx->style; - state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding); - if (!state) { - return nk_false; - } - - in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - if (nk_do_button_text(&ctx->last_widget_state, &win->buffer, bounds, text, len, alignment, NK_BUTTON_DEFAULT, &style->contextual_button, in, style->font)) { - nk_contextual_close(ctx); - return nk_true; - } - return nk_false; -} -NK_API nk_bool -nk_contextual_item_label(struct nk_context *ctx, const char *label, nk_flags align) -{ - return nk_contextual_item_text(ctx, label, nk_strlen(label), align); -} -NK_API nk_bool -nk_contextual_item_image_text(struct nk_context *ctx, struct nk_image img, const char *text, int len, nk_flags align) -{ - struct nk_window *win; - const struct nk_input *in; - const struct nk_style *style; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - win = ctx->current; - style = &ctx->style; - state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding); - if (!state) { - return nk_false; - } - - in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - if (nk_do_button_text_image(&ctx->last_widget_state, &win->buffer, bounds, img, text, len, align, NK_BUTTON_DEFAULT, &style->contextual_button, style->font, in)) { - nk_contextual_close(ctx); - return nk_true; - } - return nk_false; -} -NK_API nk_bool -nk_contextual_item_image_label(struct nk_context *ctx, struct nk_image img, const char *label, nk_flags align) -{ - return nk_contextual_item_image_text(ctx, img, label, nk_strlen(label), align); -} -NK_API nk_bool -nk_contextual_item_symbol_text(struct nk_context *ctx, enum nk_symbol_type symbol, const char *text, int len, nk_flags align) -{ - struct nk_window *win; - const struct nk_input *in; - const struct nk_style *style; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - win = ctx->current; - style = &ctx->style; - state = nk_widget_fitting(&bounds, ctx, style->contextual_button.padding); - if (!state) { - return nk_false; - } - - in = (state == NK_WIDGET_ROM || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - if (nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer, bounds, symbol, text, len, align, NK_BUTTON_DEFAULT, &style->contextual_button, style->font, in)) { - nk_contextual_close(ctx); - return nk_true; - } - return nk_false; -} -NK_API nk_bool -nk_contextual_item_symbol_label(struct nk_context *ctx, enum nk_symbol_type symbol, const char *text, nk_flags align) -{ - return nk_contextual_item_symbol_text(ctx, symbol, text, nk_strlen(text), align); -} -NK_API void -nk_contextual_close(struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - nk_popup_close(ctx); -} -NK_API void -nk_contextual_end(struct nk_context *ctx) -{ - struct nk_window *popup; - struct nk_panel *panel; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) { - return; - } - - popup = ctx->current; - panel = popup->layout; - NK_ASSERT(popup->parent); - NK_ASSERT((int)panel->type & (int)NK_PANEL_SET_POPUP); - if (panel->flags & NK_WINDOW_DYNAMIC) { - /* Close behavior - This is a bit of a hack solution since we do not know before we end our popup - how big it will be. We therefore do not directly know when a - click outside the non-blocking popup must close it at that direct frame. - Instead it will be closed in the next frame.*/ - struct nk_rect body = {0, 0, 0, 0}; - if (panel->at_y < (panel->bounds.y + panel->bounds.h)) { - struct nk_vec2 padding = nk_panel_get_padding(&ctx->style, panel->type); - body = panel->bounds; - body.y = (panel->at_y + panel->footer_height + panel->border + padding.y + panel->row.height); - body.h = (panel->bounds.y + panel->bounds.h) - body.y; - } - { - int pressed = nk_input_is_mouse_pressed(&ctx->input, NK_BUTTON_LEFT); - int in_body = nk_input_is_mouse_hovering_rect(&ctx->input, body); - if (pressed && in_body) { - popup->flags |= NK_WINDOW_HIDDEN; - } - } - } - if (popup->flags & NK_WINDOW_HIDDEN) { - popup->seq = 0; - } - nk_popup_end(ctx); - return; -} - -/* =============================================================== - * - * MENU - * - * ===============================================================*/ -NK_API void -nk_menubar_begin(struct nk_context *ctx) -{ - struct nk_panel *layout; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - layout = ctx->current->layout; - NK_ASSERT(layout->at_y == layout->bounds.y); - /* if this assert triggers you allocated space between nk_begin and nk_menubar_begin. - If you want a menubar the first nuklear function after `nk_begin` has to be a - `nk_menubar_begin` call. Inside the menubar you then have to allocate space for - widgets (also supports multiple rows). - Example: - if (nk_begin(...)) { - nk_menubar_begin(...); - nk_layout_xxxx(...); - nk_button(...); - nk_layout_xxxx(...); - nk_button(...); - nk_menubar_end(...); - } - nk_end(...); - */ - if (layout->flags & NK_WINDOW_HIDDEN || layout->flags & NK_WINDOW_MINIMIZED) { - return; - } - - layout->menu.x = layout->at_x; - layout->menu.y = layout->at_y + layout->row.height; - layout->menu.w = layout->bounds.w; - layout->menu.offset.x = *layout->offset_x; - layout->menu.offset.y = *layout->offset_y; - *layout->offset_y = 0; -} -NK_API void -nk_menubar_end(struct nk_context *ctx) -{ - struct nk_window *win; - struct nk_panel *layout; - struct nk_command_buffer *out; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - win = ctx->current; - out = &win->buffer; - layout = win->layout; - if (layout->flags & NK_WINDOW_HIDDEN || layout->flags & NK_WINDOW_MINIMIZED) { - return; - } - - layout->menu.h = layout->at_y - layout->menu.y; - layout->menu.h += layout->row.height + ctx->style.window.spacing.y; - - layout->bounds.y += layout->menu.h; - layout->bounds.h -= layout->menu.h; - - *layout->offset_x = layout->menu.offset.x; - *layout->offset_y = layout->menu.offset.y; - layout->at_y = layout->bounds.y - layout->row.height; - - layout->clip.y = layout->bounds.y; - layout->clip.h = layout->bounds.h; - nk_push_scissor(out, layout->clip); -} -NK_INTERN int -nk_menu_begin(struct nk_context *ctx, struct nk_window *win, const char *id, int is_clicked, struct nk_rect header, struct nk_vec2 size) -{ - int is_open = 0; - int is_active = 0; - struct nk_rect body; - struct nk_window *popup; - nk_hash hash = nk_murmur_hash(id, (int)nk_strlen(id), NK_PANEL_MENU); - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - body.x = header.x; - body.w = size.x; - body.y = header.y + header.h; - body.h = size.y; - - popup = win->popup.win; - is_open = popup ? nk_true : nk_false; - is_active = (popup && (win->popup.name == hash) && win->popup.type == NK_PANEL_MENU); - if ((is_clicked && is_open && !is_active) || (is_open && !is_active) || (!is_open && !is_active && !is_clicked)) { - return 0; - } - if (!nk_nonblock_begin(ctx, NK_WINDOW_NO_SCROLLBAR, body, header, NK_PANEL_MENU)) { - return 0; - } - - win->popup.type = NK_PANEL_MENU; - win->popup.name = hash; - return 1; -} -NK_API nk_bool -nk_menu_begin_text(struct nk_context *ctx, const char *title, int len, nk_flags align, struct nk_vec2 size) -{ - struct nk_window *win; - const struct nk_input *in; - struct nk_rect header; - int is_clicked = nk_false; - nk_flags state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - win = ctx->current; - state = nk_widget(&header, ctx); - if (!state) { - return 0; - } - in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || win->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - if (nk_do_button_text(&ctx->last_widget_state, &win->buffer, header, title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in, ctx->style.font)) { - is_clicked = nk_true; - } - return nk_menu_begin(ctx, win, title, is_clicked, header, size); -} -NK_API nk_bool -nk_menu_begin_label(struct nk_context *ctx, const char *text, nk_flags align, struct nk_vec2 size) -{ - return nk_menu_begin_text(ctx, text, nk_strlen(text), align, size); -} -NK_API nk_bool -nk_menu_begin_image(struct nk_context *ctx, const char *id, struct nk_image img, struct nk_vec2 size) -{ - struct nk_window *win; - struct nk_rect header; - const struct nk_input *in; - int is_clicked = nk_false; - nk_flags state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - win = ctx->current; - state = nk_widget(&header, ctx); - if (!state) { - return 0; - } - in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - if (nk_do_button_image(&ctx->last_widget_state, &win->buffer, header, img, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in)) { - is_clicked = nk_true; - } - return nk_menu_begin(ctx, win, id, is_clicked, header, size); -} -NK_API nk_bool -nk_menu_begin_symbol(struct nk_context *ctx, const char *id, enum nk_symbol_type sym, struct nk_vec2 size) -{ - struct nk_window *win; - const struct nk_input *in; - struct nk_rect header; - int is_clicked = nk_false; - nk_flags state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - win = ctx->current; - state = nk_widget(&header, ctx); - if (!state) { - return 0; - } - in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - if (nk_do_button_symbol(&ctx->last_widget_state, &win->buffer, header, sym, NK_BUTTON_DEFAULT, &ctx->style.menu_button, in, ctx->style.font)) { - is_clicked = nk_true; - } - return nk_menu_begin(ctx, win, id, is_clicked, header, size); -} -NK_API nk_bool -nk_menu_begin_image_text(struct nk_context *ctx, const char *title, int len, nk_flags align, struct nk_image img, struct nk_vec2 size) -{ - struct nk_window *win; - struct nk_rect header; - const struct nk_input *in; - int is_clicked = nk_false; - nk_flags state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - win = ctx->current; - state = nk_widget(&header, ctx); - if (!state) { - return 0; - } - in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - if (nk_do_button_text_image(&ctx->last_widget_state, &win->buffer, header, img, title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button, ctx->style.font, in)) { - is_clicked = nk_true; - } - return nk_menu_begin(ctx, win, title, is_clicked, header, size); -} -NK_API nk_bool -nk_menu_begin_image_label(struct nk_context *ctx, const char *title, nk_flags align, struct nk_image img, struct nk_vec2 size) -{ - return nk_menu_begin_image_text(ctx, title, nk_strlen(title), align, img, size); -} -NK_API nk_bool -nk_menu_begin_symbol_text(struct nk_context *ctx, const char *title, int len, nk_flags align, enum nk_symbol_type sym, struct nk_vec2 size) -{ - struct nk_window *win; - struct nk_rect header; - const struct nk_input *in; - int is_clicked = nk_false; - nk_flags state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - win = ctx->current; - state = nk_widget(&header, ctx); - if (!state) { - return 0; - } - - in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - if (nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer, header, sym, title, len, align, NK_BUTTON_DEFAULT, &ctx->style.menu_button, ctx->style.font, in)) { - is_clicked = nk_true; - } - return nk_menu_begin(ctx, win, title, is_clicked, header, size); -} -NK_API nk_bool -nk_menu_begin_symbol_label(struct nk_context *ctx, const char *title, nk_flags align, enum nk_symbol_type sym, struct nk_vec2 size) -{ - return nk_menu_begin_symbol_text(ctx, title, nk_strlen(title), align, sym, size); -} -NK_API nk_bool -nk_menu_item_text(struct nk_context *ctx, const char *title, int len, nk_flags align) -{ - return nk_contextual_item_text(ctx, title, len, align); -} -NK_API nk_bool -nk_menu_item_label(struct nk_context *ctx, const char *label, nk_flags align) -{ - return nk_contextual_item_label(ctx, label, align); -} -NK_API nk_bool -nk_menu_item_image_label(struct nk_context *ctx, struct nk_image img, const char *label, nk_flags align) -{ - return nk_contextual_item_image_label(ctx, img, label, align); -} -NK_API nk_bool -nk_menu_item_image_text(struct nk_context *ctx, struct nk_image img, const char *text, int len, nk_flags align) -{ - return nk_contextual_item_image_text(ctx, img, text, len, align); -} -NK_API nk_bool -nk_menu_item_symbol_text(struct nk_context *ctx, enum nk_symbol_type sym, const char *text, int len, nk_flags align) -{ - return nk_contextual_item_symbol_text(ctx, sym, text, len, align); -} -NK_API nk_bool -nk_menu_item_symbol_label(struct nk_context *ctx, enum nk_symbol_type sym, const char *label, nk_flags align) -{ - return nk_contextual_item_symbol_label(ctx, sym, label, align); -} -NK_API void -nk_menu_close(struct nk_context *ctx) -{ - nk_contextual_close(ctx); -} -NK_API void -nk_menu_end(struct nk_context *ctx) -{ - nk_contextual_end(ctx); -} - -/* =============================================================== - * - * LAYOUT - * - * ===============================================================*/ -NK_API void -nk_layout_set_min_row_height(struct nk_context *ctx, float height) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - win = ctx->current; - layout = win->layout; - layout->row.min_height = height; -} -NK_API void -nk_layout_reset_min_row_height(struct nk_context *ctx) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - win = ctx->current; - layout = win->layout; - layout->row.min_height = ctx->style.font_size; - layout->row.min_height += ctx->style.text.padding.y * 2; - layout->row.min_height += ctx->style.window.min_row_height_padding * 2; -} -NK_LIB float -nk_layout_row_calculate_usable_space(const struct nk_style *style, enum nk_panel_type type, float total_space, int columns) -{ - float panel_spacing; - float panel_space; - - struct nk_vec2 spacing; - - NK_UNUSED(type); - - spacing = style->window.spacing; - - /* calculate the usable panel space */ - panel_spacing = (float)NK_MAX(columns - 1, 0) * spacing.x; - panel_space = total_space - panel_spacing; - return panel_space; -} -NK_LIB void -nk_panel_layout(const struct nk_context *ctx, struct nk_window *win, float height, int cols) -{ - struct nk_panel *layout; - const struct nk_style *style; - struct nk_command_buffer *out; - - struct nk_vec2 item_spacing; - struct nk_color color; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - /* prefetch some configuration data */ - layout = win->layout; - style = &ctx->style; - out = &win->buffer; - color = style->window.background; - item_spacing = style->window.spacing; - - /* if one of these triggers you forgot to add an `if` condition around either - a window, group, popup, combobox or contextual menu `begin` and `end` block. - Example: - if (nk_begin(...) {...} nk_end(...); or - if (nk_group_begin(...) { nk_group_end(...);} */ - NK_ASSERT(!(layout->flags & NK_WINDOW_MINIMIZED)); - NK_ASSERT(!(layout->flags & NK_WINDOW_HIDDEN)); - NK_ASSERT(!(layout->flags & NK_WINDOW_CLOSED)); - - /* update the current row and set the current row layout */ - layout->row.index = 0; - layout->at_y += layout->row.height; - layout->row.columns = cols; - if (height == 0.0f) { - layout->row.height = NK_MAX(height, layout->row.min_height) + item_spacing.y; - } else { - layout->row.height = height + item_spacing.y; - } - - layout->row.item_offset = 0; - if (layout->flags & NK_WINDOW_DYNAMIC) { - /* draw background for dynamic panels */ - struct nk_rect background; - background.x = win->bounds.x; - background.w = win->bounds.w; - background.y = layout->at_y - 1.0f; - background.h = layout->row.height + 1.0f; - nk_fill_rect(out, background, 0, color); - } -} -NK_LIB void -nk_row_layout(struct nk_context *ctx, enum nk_layout_format fmt, float height, int cols, int width) -{ - /* update the current row and set the current row layout */ - struct nk_window *win; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - win = ctx->current; - nk_panel_layout(ctx, win, height, cols); - if (fmt == NK_DYNAMIC) { - win->layout->row.type = NK_LAYOUT_DYNAMIC_FIXED; - } else { - win->layout->row.type = NK_LAYOUT_STATIC_FIXED; - } - - win->layout->row.ratio = 0; - win->layout->row.filled = 0; - win->layout->row.item_offset = 0; - win->layout->row.item_width = (float)width; -} -NK_API float -nk_layout_ratio_from_pixel(const struct nk_context *ctx, float pixel_width) -{ - struct nk_window *win; - NK_ASSERT(ctx); - NK_ASSERT(pixel_width); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - win = ctx->current; - return NK_CLAMP(0.0f, pixel_width / win->bounds.x, 1.0f); -} -NK_API void -nk_layout_row_dynamic(struct nk_context *ctx, float height, int cols) -{ - nk_row_layout(ctx, NK_DYNAMIC, height, cols, 0); -} -NK_API void -nk_layout_row_static(struct nk_context *ctx, float height, int item_width, int cols) -{ - nk_row_layout(ctx, NK_STATIC, height, cols, item_width); -} -NK_API void -nk_layout_row_begin(struct nk_context *ctx, enum nk_layout_format fmt, float row_height, int cols) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - win = ctx->current; - layout = win->layout; - nk_panel_layout(ctx, win, row_height, cols); - if (fmt == NK_DYNAMIC) { - layout->row.type = NK_LAYOUT_DYNAMIC_ROW; - } else { - layout->row.type = NK_LAYOUT_STATIC_ROW; - } - - layout->row.ratio = 0; - layout->row.filled = 0; - layout->row.item_width = 0; - layout->row.item_offset = 0; - layout->row.columns = cols; -} -NK_API void -nk_layout_row_push(struct nk_context *ctx, float ratio_or_width) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - win = ctx->current; - layout = win->layout; - NK_ASSERT(layout->row.type == NK_LAYOUT_STATIC_ROW || layout->row.type == NK_LAYOUT_DYNAMIC_ROW); - if (layout->row.type != NK_LAYOUT_STATIC_ROW && layout->row.type != NK_LAYOUT_DYNAMIC_ROW) { - return; - } - - if (layout->row.type == NK_LAYOUT_DYNAMIC_ROW) { - float ratio = ratio_or_width; - if ((ratio + layout->row.filled) > 1.0f) { - return; - } - if (ratio > 0.0f) { - layout->row.item_width = NK_SATURATE(ratio); - } else { - layout->row.item_width = 1.0f - layout->row.filled; - } - } else { - layout->row.item_width = ratio_or_width; - } -} -NK_API void -nk_layout_row_end(struct nk_context *ctx) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - win = ctx->current; - layout = win->layout; - NK_ASSERT(layout->row.type == NK_LAYOUT_STATIC_ROW || layout->row.type == NK_LAYOUT_DYNAMIC_ROW); - if (layout->row.type != NK_LAYOUT_STATIC_ROW && layout->row.type != NK_LAYOUT_DYNAMIC_ROW) { - return; - } - layout->row.item_width = 0; - layout->row.item_offset = 0; -} -NK_API void -nk_layout_row(struct nk_context *ctx, enum nk_layout_format fmt, float height, int cols, const float *ratio) -{ - int i; - int n_undef = 0; - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - win = ctx->current; - layout = win->layout; - nk_panel_layout(ctx, win, height, cols); - if (fmt == NK_DYNAMIC) { - /* calculate width of undefined widget ratios */ - float r = 0; - layout->row.ratio = ratio; - for (i = 0; i < cols; ++i) { - if (ratio[i] < 0.0f) { - n_undef++; - } else { - r += ratio[i]; - } - } - r = NK_SATURATE(1.0f - r); - layout->row.type = NK_LAYOUT_DYNAMIC; - layout->row.item_width = (r > 0 && n_undef > 0) ? (r / (float)n_undef) : 0; - } else { - layout->row.ratio = ratio; - layout->row.type = NK_LAYOUT_STATIC; - layout->row.item_width = 0; - layout->row.item_offset = 0; - } - layout->row.item_offset = 0; - layout->row.filled = 0; -} -NK_API void -nk_layout_row_template_begin(struct nk_context *ctx, float height) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - win = ctx->current; - layout = win->layout; - nk_panel_layout(ctx, win, height, 1); - layout->row.type = NK_LAYOUT_TEMPLATE; - layout->row.columns = 0; - layout->row.ratio = 0; - layout->row.item_width = 0; - layout->row.item_height = 0; - layout->row.item_offset = 0; - layout->row.filled = 0; - layout->row.item.x = 0; - layout->row.item.y = 0; - layout->row.item.w = 0; - layout->row.item.h = 0; -} -NK_API void -nk_layout_row_template_push_dynamic(struct nk_context *ctx) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - win = ctx->current; - layout = win->layout; - NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE); - NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS); - if (layout->row.type != NK_LAYOUT_TEMPLATE) { - return; - } - if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS) { - return; - } - layout->row.templates[layout->row.columns++] = -1.0f; -} -NK_API void -nk_layout_row_template_push_variable(struct nk_context *ctx, float min_width) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - win = ctx->current; - layout = win->layout; - NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE); - NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS); - if (layout->row.type != NK_LAYOUT_TEMPLATE) { - return; - } - if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS) { - return; - } - layout->row.templates[layout->row.columns++] = -min_width; -} -NK_API void -nk_layout_row_template_push_static(struct nk_context *ctx, float width) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - win = ctx->current; - layout = win->layout; - NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE); - NK_ASSERT(layout->row.columns < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS); - if (layout->row.type != NK_LAYOUT_TEMPLATE) { - return; - } - if (layout->row.columns >= NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS) { - return; - } - layout->row.templates[layout->row.columns++] = width; -} -NK_API void -nk_layout_row_template_end(struct nk_context *ctx) -{ - struct nk_window *win; - struct nk_panel *layout; - - int i = 0; - int variable_count = 0; - int min_variable_count = 0; - float min_fixed_width = 0.0f; - float total_fixed_width = 0.0f; - float max_variable_width = 0.0f; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - win = ctx->current; - layout = win->layout; - NK_ASSERT(layout->row.type == NK_LAYOUT_TEMPLATE); - if (layout->row.type != NK_LAYOUT_TEMPLATE) { - return; - } - for (i = 0; i < layout->row.columns; ++i) { - float width = layout->row.templates[i]; - if (width >= 0.0f) { - total_fixed_width += width; - min_fixed_width += width; - } else if (width < -1.0f) { - width = -width; - total_fixed_width += width; - max_variable_width = NK_MAX(max_variable_width, width); - variable_count++; - } else { - min_variable_count++; - variable_count++; - } - } - if (variable_count) { - float space = nk_layout_row_calculate_usable_space(&ctx->style, layout->type, layout->bounds.w, layout->row.columns); - float var_width = (NK_MAX(space - min_fixed_width, 0.0f)) / (float)variable_count; - int enough_space = var_width >= max_variable_width; - if (!enough_space) { - var_width = (NK_MAX(space - total_fixed_width, 0)) / (float)min_variable_count; - } - for (i = 0; i < layout->row.columns; ++i) { - float *width = &layout->row.templates[i]; - *width = (*width >= 0.0f) ? *width : (*width < -1.0f && !enough_space) ? -(*width) : var_width; - } - } -} -NK_API void -nk_layout_space_begin(struct nk_context *ctx, enum nk_layout_format fmt, float height, int widget_count) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - win = ctx->current; - layout = win->layout; - nk_panel_layout(ctx, win, height, widget_count); - if (fmt == NK_STATIC) { - layout->row.type = NK_LAYOUT_STATIC_FREE; - } else { - layout->row.type = NK_LAYOUT_DYNAMIC_FREE; - } - - layout->row.ratio = 0; - layout->row.filled = 0; - layout->row.item_width = 0; - layout->row.item_offset = 0; -} -NK_API void -nk_layout_space_end(struct nk_context *ctx) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - win = ctx->current; - layout = win->layout; - layout->row.item_width = 0; - layout->row.item_height = 0; - layout->row.item_offset = 0; - nk_zero(&layout->row.item, sizeof(layout->row.item)); -} -NK_API void -nk_layout_space_push(struct nk_context *ctx, struct nk_rect rect) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - win = ctx->current; - layout = win->layout; - layout->row.item = rect; -} -NK_API struct nk_rect -nk_layout_space_bounds(const struct nk_context *ctx) -{ - struct nk_rect ret; - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - win = ctx->current; - layout = win->layout; - - ret.x = layout->clip.x; - ret.y = layout->clip.y; - ret.w = layout->clip.w; - ret.h = layout->row.height; - return ret; -} -NK_API struct nk_rect -nk_layout_widget_bounds(const struct nk_context *ctx) -{ - struct nk_rect ret; - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - win = ctx->current; - layout = win->layout; - - ret.x = layout->at_x; - ret.y = layout->at_y; - ret.w = layout->bounds.w - NK_MAX(layout->at_x - layout->bounds.x, 0); - ret.h = layout->row.height; - return ret; -} -NK_API struct nk_vec2 -nk_layout_space_to_screen(const struct nk_context *ctx, struct nk_vec2 ret) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - win = ctx->current; - layout = win->layout; - - ret.x += layout->at_x - (float)*layout->offset_x; - ret.y += layout->at_y - (float)*layout->offset_y; - return ret; -} -NK_API struct nk_vec2 -nk_layout_space_to_local(const struct nk_context *ctx, struct nk_vec2 ret) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - win = ctx->current; - layout = win->layout; - - ret.x += -layout->at_x + (float)*layout->offset_x; - ret.y += -layout->at_y + (float)*layout->offset_y; - return ret; -} -NK_API struct nk_rect -nk_layout_space_rect_to_screen(const struct nk_context *ctx, struct nk_rect ret) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - win = ctx->current; - layout = win->layout; - - ret.x += layout->at_x - (float)*layout->offset_x; - ret.y += layout->at_y - (float)*layout->offset_y; - return ret; -} -NK_API struct nk_rect -nk_layout_space_rect_to_local(const struct nk_context *ctx, struct nk_rect ret) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - win = ctx->current; - layout = win->layout; - - ret.x += -layout->at_x + (float)*layout->offset_x; - ret.y += -layout->at_y + (float)*layout->offset_y; - return ret; -} - -NK_API void -nk_grid_state_reset(struct nk_grid_state *state) -{ - NK_ASSERT(state); - NK_MEMSET(state, 0, sizeof(*state)); -} - -NK_INTERN float -nk_grid_column_width(const struct nk_grid_column *column, float width) -{ - width = NK_MAX(width, column->min_width); - if (column->max_width > 0.0f) { - width = NK_MIN(width, column->max_width); - } - return width; -} - -NK_INTERN void -nk_grid_solve(struct nk_grid *grid) -{ - float used_width; - float remaining; - int column; - int pass; - - used_width = grid->padding_x * 2.0f + grid->column_gap * (float)NK_MAX(0, grid->column_count - 1); - for (column = 0; column < grid->column_count; ++column) { - const struct nk_grid_column *config = &grid->columns[column]; - float width; - - if (config->sizing == NK_GRID_COLUMN_FIXED) { - width = config->width; - } else if (config->sizing == NK_GRID_COLUMN_CONTENT) { - width = grid->state->content_widths[column]; - } else { - width = config->min_width; - } - - grid->widths[column] = nk_grid_column_width(config, width); - used_width += grid->widths[column]; - } - - remaining = NK_MAX(0.0f, grid->available_width - used_width); - for (pass = 0; pass < grid->column_count && remaining > 0.0f; ++pass) { - float weight_sum = 0.0f; - float distributed = 0.0f; - - for (column = 0; column < grid->column_count; ++column) { - const struct nk_grid_column *config = &grid->columns[column]; - if (config->sizing == NK_GRID_COLUMN_FLEX && (config->max_width <= 0.0f || grid->widths[column] < config->max_width)) { - weight_sum += config->width > 0.0f ? config->width : 1.0f; - } - } - - if (weight_sum == 0.0f) { - break; - } - - for (column = 0; column < grid->column_count; ++column) { - const struct nk_grid_column *config = &grid->columns[column]; - float weight; - float add; - - if (config->sizing != NK_GRID_COLUMN_FLEX || (config->max_width > 0.0f && grid->widths[column] >= config->max_width)) { - continue; - } - - weight = config->width > 0.0f ? config->width : 1.0f; - add = remaining * weight / weight_sum; - if (config->max_width > 0.0f) { - add = NK_MIN(add, config->max_width - grid->widths[column]); - } - - grid->widths[column] += add; - distributed += add; - } - - if (distributed == 0.0f) { - break; - } - remaining -= distributed; - } - - used_width = grid->padding_x * 2.0f; - for (column = 0; column < grid->column_count; ++column) { - grid->offsets[column] = used_width; - used_width += grid->widths[column] + grid->column_gap; - } - - if (grid->column_count) { - used_width -= grid->column_gap; - } - - grid->row_width = NK_MAX(grid->available_width, used_width); -} - -NK_API void -nk_grid_begin(struct nk_context *ctx, struct nk_grid *grid, struct nk_grid_state *state, const struct nk_grid_column *columns, int column_count, const struct nk_grid_options *options) -{ - NK_ASSERT(ctx); - NK_ASSERT(grid); - NK_ASSERT(state); - NK_ASSERT(columns); - NK_ASSERT(options); - NK_ASSERT(column_count > 0 && column_count <= NK_GRID_MAX_COLUMNS); - - if (state->column_count != column_count || state->generation != options->generation || state->font != ctx->style.font || state->font_size != ctx->style.font_size) { - nk_grid_state_reset(state); - state->column_count = column_count; - state->generation = options->generation; - state->font = ctx->style.font; - state->font_size = ctx->style.font_size; - } - - NK_MEMSET(grid, 0, sizeof(*grid)); - grid->ctx = ctx; - grid->state = state; - grid->columns = columns; - grid->column_count = column_count; - grid->row_height = options->row_height; - grid->column_gap = options->column_gap; - grid->padding_x = options->padding_x; - grid->available_width = NK_MAX(0.0f, nk_layout_widget_bounds(ctx).w); - nk_grid_solve(grid); -} - -NK_API void -nk_grid_end(struct nk_grid *grid) -{ - NK_ASSERT(grid); - NK_ASSERT(!grid->row_active); - grid->ctx = NULL; -} - -NK_API nk_bool -nk_grid_row_begin(struct nk_grid *grid) -{ - struct nk_rect row; - struct nk_rect clip; - - NK_ASSERT(grid); - NK_ASSERT(grid->ctx); - NK_ASSERT(!grid->row_active); - - nk_layout_space_begin(grid->ctx, NK_STATIC, grid->row_height, NK_SINT_MAX); - grid->row_active = nk_true; - nk_layout_space_push(grid->ctx, nk_rect(0.0f, 0.0f, grid->row_width, grid->row_height)); - nk_spacer(grid->ctx); - - row = nk_layout_space_rect_to_screen(grid->ctx, nk_rect(0.0f, 0.0f, grid->row_width, grid->row_height)); - clip = grid->ctx->current->layout->clip; - grid->row_visible = NK_INTERSECT(row.x, row.y, row.w, row.h, clip.x, clip.y, clip.w, clip.h); - return grid->row_visible; -} - -NK_API void -nk_grid_row_end(struct nk_grid *grid) -{ - NK_ASSERT(grid); - NK_ASSERT(grid->ctx); - NK_ASSERT(grid->row_active); - nk_layout_space_end(grid->ctx); - grid->row_active = nk_false; - grid->row_visible = nk_false; -} - -NK_API void -nk_grid_push_row(struct nk_grid *grid) -{ - NK_ASSERT(grid); - NK_ASSERT(grid->ctx && grid->row_active); - nk_layout_space_push(grid->ctx, nk_rect(0.0f, 0.0f, grid->row_width, grid->row_height)); -} - -NK_API struct nk_rect -nk_grid_cell_bounds(struct nk_grid *grid, int column, struct nk_vec2 intrinsic_size) -{ - struct nk_rect bounds; - - NK_ASSERT(grid); - NK_ASSERT(grid->ctx && grid->row_active); - NK_ASSERT(column >= 0 && column < grid->column_count); - - if (grid->row_visible && grid->columns[column].sizing == NK_GRID_COLUMN_CONTENT) { - float width = nk_grid_column_width(&grid->columns[column], intrinsic_size.x); - grid->state->content_widths[column] = NK_MAX(grid->state->content_widths[column], width); - } - - bounds = nk_rect(grid->offsets[column], 0.0f, grid->widths[column], grid->row_height); - return nk_layout_space_rect_to_screen(grid->ctx, bounds); -} - -NK_API void -nk_grid_push(struct nk_grid *grid, int column, struct nk_vec2 intrinsic_size) -{ - NK_ASSERT(grid); - NK_ASSERT(grid->ctx && grid->row_active); - NK_ASSERT(column >= 0 && column < grid->column_count); - - nk_grid_cell_bounds(grid, column, intrinsic_size); - nk_layout_space_push(grid->ctx, nk_rect(grid->offsets[column], 0.0f, grid->widths[column], grid->row_height)); -} - -NK_INTERN nk_bool -nk_text_selection_widget_clipped(struct nk_context *ctx, const char *text, int len, - const struct nk_text_options *options, struct nk_rect bounds); - -NK_API nk_bool -nk_grid_text(struct nk_grid *grid, int column, const char *text, int len, const struct nk_text_options *options) -{ - struct nk_rect bounds; - float width; - - NK_ASSERT(grid); - NK_ASSERT(grid->ctx); - NK_ASSERT(text || len == 0); - NK_ASSERT(options); - - if (!text) { - text = ""; - } - - if (!grid->row_visible) { - bounds = nk_grid_cell_bounds(grid, column, nk_vec2(0.0f, grid->ctx->style.font_size)); - return nk_text_selection_widget_clipped(grid->ctx, text, len, options, bounds); - } - - width = len > 0 ? nk_text_width(grid->ctx, grid->ctx->style.font, grid->ctx->style.font_size, text, len) : 0.0f; - nk_grid_push(grid, column, nk_vec2(width, grid->ctx->style.font_size)); - return nk_text_ex(grid->ctx, text, len, options); -} - -NK_LIB void -nk_panel_alloc_row(const struct nk_context *ctx, struct nk_window *win) -{ - struct nk_panel *layout = win->layout; - struct nk_vec2 spacing = ctx->style.window.spacing; - const float row_height = layout->row.height - spacing.y; - nk_panel_layout(ctx, win, row_height, layout->row.columns); -} -NK_LIB void -nk_layout_widget_space(struct nk_rect *bounds, const struct nk_context *ctx, struct nk_window *win, int modify) -{ - struct nk_panel *layout; - const struct nk_style *style; - - struct nk_vec2 spacing; - - float item_offset = 0; - float item_width = 0; - float item_spacing = 0; - float panel_space = 0; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - win = ctx->current; - layout = win->layout; - style = &ctx->style; - NK_ASSERT(bounds); - - spacing = style->window.spacing; - panel_space = nk_layout_row_calculate_usable_space(&ctx->style, layout->type, layout->bounds.w, layout->row.columns); - -#define NK_FRAC(x) (x - (float)(int)nk_roundf(x)) /* will be used to remove fookin gaps */ - /* calculate the width of one item inside the current layout space */ - switch (layout->row.type) { - case NK_LAYOUT_DYNAMIC_FIXED: { - /* scaling fixed size widgets item width */ - float w = NK_MAX(1.0f, panel_space) / (float)layout->row.columns; - item_offset = (float)layout->row.index * w; - item_width = w + NK_FRAC(item_offset); - item_spacing = (float)layout->row.index * spacing.x; - } break; - case NK_LAYOUT_DYNAMIC_ROW: { - /* scaling single ratio widget width */ - float w = layout->row.item_width * panel_space; - item_offset = layout->row.item_offset; - item_width = w + NK_FRAC(item_offset); - item_spacing = 0; - - if (modify) { - layout->row.item_offset += w + spacing.x; - layout->row.filled += layout->row.item_width; - layout->row.index = 0; - } - } break; - case NK_LAYOUT_DYNAMIC_FREE: { - /* panel width depended free widget placing */ - bounds->x = layout->at_x + (layout->bounds.w * layout->row.item.x); - bounds->x -= (float)*layout->offset_x; - bounds->y = layout->at_y + (layout->row.height * layout->row.item.y); - bounds->y -= (float)*layout->offset_y; - bounds->w = layout->bounds.w * layout->row.item.w + NK_FRAC(bounds->x); - bounds->h = layout->row.height * layout->row.item.h + NK_FRAC(bounds->y); - return; - } - case NK_LAYOUT_DYNAMIC: { - /* scaling arrays of panel width ratios for every widget */ - float ratio, w; - NK_ASSERT(layout->row.ratio); - ratio = (layout->row.ratio[layout->row.index] < 0) ? layout->row.item_width : layout->row.ratio[layout->row.index]; - - w = (ratio * panel_space); - item_spacing = (float)layout->row.index * spacing.x; - item_offset = layout->row.item_offset; - item_width = w + NK_FRAC(item_offset); - - if (modify) { - layout->row.item_offset += w; - layout->row.filled += ratio; - } - } break; - case NK_LAYOUT_STATIC_FIXED: { - /* non-scaling fixed widgets item width */ - item_width = layout->row.item_width; - item_offset = (float)layout->row.index * item_width; - item_spacing = (float)layout->row.index * spacing.x; - } break; - case NK_LAYOUT_STATIC_ROW: { - /* scaling single ratio widget width */ - item_width = layout->row.item_width; - item_offset = layout->row.item_offset; - item_spacing = (float)layout->row.index * spacing.x; - if (modify) { - layout->row.item_offset += item_width; - } - } break; - case NK_LAYOUT_STATIC_FREE: { - /* free widget placing */ - bounds->x = layout->at_x + layout->row.item.x; - bounds->w = layout->row.item.w; - if (((bounds->x + bounds->w) > layout->max_x) && modify) { - layout->max_x = (bounds->x + bounds->w); - } - bounds->x -= (float)*layout->offset_x; - bounds->y = layout->at_y + layout->row.item.y; - bounds->y -= (float)*layout->offset_y; - bounds->h = layout->row.item.h; - return; - } - case NK_LAYOUT_STATIC: { - /* non-scaling array of panel pixel width for every widget */ - item_spacing = (float)layout->row.index * spacing.x; - item_width = layout->row.ratio[layout->row.index]; - item_offset = layout->row.item_offset; - if (modify) { - layout->row.item_offset += item_width; - } - } break; - case NK_LAYOUT_TEMPLATE: { - /* stretchy row layout with combined dynamic/static widget width*/ - float w; - NK_ASSERT(layout->row.index < layout->row.columns); - NK_ASSERT(layout->row.index < NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS); - w = layout->row.templates[layout->row.index]; - item_offset = layout->row.item_offset; - item_width = w + NK_FRAC(item_offset); - item_spacing = (float)layout->row.index * spacing.x; - if (modify) { - layout->row.item_offset += w; - } - } break; -#undef NK_FRAC - default: - NK_ASSERT(0); - break; - }; - - /* set the bounds of the newly allocated widget */ - bounds->w = item_width; - bounds->h = layout->row.height - spacing.y; - bounds->y = layout->at_y - (float)*layout->offset_y; - bounds->x = layout->at_x + item_offset + item_spacing; - if (((bounds->x + bounds->w) > layout->max_x) && modify) { - layout->max_x = bounds->x + bounds->w; - } - bounds->x -= (float)*layout->offset_x; -} -NK_LIB void -nk_panel_alloc_space(struct nk_rect *bounds, const struct nk_context *ctx) -{ - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - /* check if the end of the row has been hit and begin new row if so */ - win = ctx->current; - layout = win->layout; - if (layout->row.index >= layout->row.columns) { - nk_panel_alloc_row(ctx, win); - } - - /* calculate widget position and size */ - nk_layout_widget_space(bounds, ctx, win, nk_true); - layout->row.index++; -} -NK_LIB void -nk_layout_peek(struct nk_rect *bounds, const struct nk_context *ctx) -{ - float y; - int index; - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - *bounds = nk_rect(0, 0, 0, 0); - return; - } - - win = ctx->current; - layout = win->layout; - y = layout->at_y; - index = layout->row.index; - if (layout->row.index >= layout->row.columns) { - layout->at_y += layout->row.height; - layout->row.index = 0; - } - nk_layout_widget_space(bounds, ctx, win, nk_false); - if (!layout->row.index) { - bounds->x -= layout->row.item_offset; - } - layout->at_y = y; - layout->row.index = index; -} -NK_API void -nk_spacer(struct nk_context *ctx) -{ - struct nk_rect dummy_rect = {0, 0, 0, 0}; - nk_panel_alloc_space(&dummy_rect, ctx); -} -NK_API float -nk_layout_get_remaining_height(const struct nk_context *ctx) -{ - struct nk_panel *p = ctx->current->layout; - float pad_y = nk_panel_get_padding(&ctx->style, p->type).y; - float gap_y = ctx->style.window.spacing.y; - - float used = (p->at_y - p->bounds.y) + p->row.height; // includes top pad + previous rows + previous gaps - float remain_h = p->bounds.h - used - pad_y - gap_y; - if (remain_h < 0) { - remain_h = 0; - } - - return remain_h; -} - -/* =============================================================== - * - * TREE - * - * ===============================================================*/ -NK_INTERN int -nk_tree_state_base(struct nk_context *ctx, enum nk_tree_type type, struct nk_image *img, const char *title, int title_len, enum nk_collapse_states *state) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_style *style; - struct nk_command_buffer *out; - const struct nk_input *in; - const struct nk_style_button *button; - enum nk_symbol_type symbol; - float row_height; - - struct nk_vec2 item_spacing; - struct nk_rect header = {0, 0, 0, 0}; - struct nk_rect sym = {0, 0, 0, 0}; - struct nk_text text; - - nk_flags ws = 0; - enum nk_widget_layout_states widget_state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - /* cache some data */ - win = ctx->current; - layout = win->layout; - out = &win->buffer; - style = &ctx->style; - item_spacing = style->window.spacing; - - /* calculate header bounds and draw background */ - row_height = style->font_size + 2 * style->tab.padding.y; - nk_layout_set_min_row_height(ctx, row_height); - nk_layout_row_dynamic(ctx, row_height, 1); - nk_layout_reset_min_row_height(ctx); - - widget_state = nk_widget(&header, ctx); - if (type == NK_TREE_TAB) { - const struct nk_style_item *background = &style->tab.background; - - switch (background->type) { - case NK_STYLE_ITEM_IMAGE: - nk_draw_image(out, header, &background->data.image, nk_rgb_factor(nk_white, style->tab.color_factor)); - break; - case NK_STYLE_ITEM_NINE_SLICE: - nk_draw_nine_slice(out, header, &background->data.slice, nk_rgb_factor(nk_white, style->tab.color_factor)); - break; - case NK_STYLE_ITEM_COLOR: - nk_fill_rect(out, header, 0, nk_rgb_factor(style->tab.border_color, style->tab.color_factor)); - nk_fill_rect(out, nk_shrink_rect(header, style->tab.border), style->tab.rounding, nk_rgb_factor(background->data.color, style->tab.color_factor)); - break; - } - } else { - text.background = style->window.background; - } - - /* update node state */ - in = (!(layout->flags & NK_WINDOW_ROM)) ? &ctx->input : 0; - in = (in && widget_state == NK_WIDGET_VALID) ? &ctx->input : 0; - if (nk_button_behavior(&ws, header, in, NK_BUTTON_DEFAULT)) { - *state = (*state == NK_MAXIMIZED) ? NK_MINIMIZED : NK_MAXIMIZED; - } - - /* select correct button style */ - if (*state == NK_MAXIMIZED) { - symbol = style->tab.sym_maximize; - if (type == NK_TREE_TAB) { - button = &style->tab.tab_maximize_button; - } else { - button = &style->tab.node_maximize_button; - } - } else { - symbol = style->tab.sym_minimize; - if (type == NK_TREE_TAB) { - button = &style->tab.tab_minimize_button; - } else { - button = &style->tab.node_minimize_button; - } - } - - { /* draw triangle button */ - sym.w = sym.h = style->font_size; - sym.y = header.y + style->tab.padding.y; - sym.x = header.x + style->tab.padding.x; - nk_do_button_symbol(&ws, &win->buffer, sym, symbol, NK_BUTTON_DEFAULT, button, 0, style->font); - - if (img) { - /* draw optional image icon */ - sym.x = sym.x + sym.w + 4 * item_spacing.x; - nk_draw_image(&win->buffer, sym, img, nk_white); - sym.w = style->font_size + style->tab.spacing.x; - } - } - - { /* draw label */ - struct nk_rect label; - header.w = NK_MAX(header.w, sym.w + item_spacing.x); - label.x = sym.x + sym.w + item_spacing.x; - label.y = sym.y; - label.w = header.w - (sym.w + item_spacing.y + style->tab.indent); - label.h = style->font_size; - text.text = nk_rgb_factor(style->tab.text, style->tab.color_factor); - text.padding = nk_vec2(0, 0); - nk_widget_text(out, label, title, title_len, &text, NK_TEXT_LEFT, style->font); - } - - /* increase x-axis cursor widget position pointer */ - if (*state == NK_MAXIMIZED) { - layout->at_x = header.x + (float)*layout->offset_x + style->tab.indent; - layout->bounds.w = NK_MAX(layout->bounds.w, style->tab.indent); - layout->bounds.w -= (style->tab.indent + style->window.padding.x); - layout->row.tree_depth++; - return nk_true; - } else { - return nk_false; - } -} -NK_INTERN int -nk_tree_base(struct nk_context *ctx, - enum nk_tree_type type, - struct nk_image *img, - const char *title, - int title_len, - enum nk_collapse_states initial_state, - const char *hash, - int len, - int line) -{ - struct nk_window *win = ctx->current; - nk_hash tree_hash = 0; - nk_uint *state = 0; - - /* retrieve tree state from internal widget state tables */ - if (!hash) { - tree_hash = nk_murmur_hash(title, title_len, (nk_hash)line); - } else { - tree_hash = nk_murmur_hash(hash, len, (nk_hash)line); - } - state = nk_find_value(win, tree_hash); - if (!state) { - state = nk_add_value(ctx, win, tree_hash, 0); - *state = initial_state; - } - return nk_tree_state_base(ctx, type, img, title, title_len, (enum nk_collapse_states *)state); -} -NK_API nk_bool -nk_tree_state_push(struct nk_context *ctx, enum nk_tree_type type, const char *title, enum nk_collapse_states *state) -{ - return nk_tree_state_base(ctx, type, 0, title, nk_strlen(title), state); -} -NK_API nk_bool -nk_tree_state_push_text(struct nk_context *ctx, enum nk_tree_type type, const char *title, int title_len, enum nk_collapse_states *state) -{ - return nk_tree_state_base(ctx, type, 0, title, title_len, state); -} -NK_API nk_bool -nk_tree_state_image_push(struct nk_context *ctx, enum nk_tree_type type, struct nk_image img, const char *title, enum nk_collapse_states *state) -{ - return nk_tree_state_base(ctx, type, &img, title, nk_strlen(title), state); -} -NK_API void -nk_tree_state_pop(struct nk_context *ctx) -{ - struct nk_window *win = 0; - struct nk_panel *layout = 0; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - win = ctx->current; - layout = win->layout; - layout->at_x -= ctx->style.tab.indent + (float)*layout->offset_x; - layout->bounds.w += ctx->style.tab.indent + ctx->style.window.padding.x; - NK_ASSERT(layout->row.tree_depth); - layout->row.tree_depth--; -} -NK_API nk_bool -nk_tree_push_hashed(struct nk_context *ctx, enum nk_tree_type type, const char *title, enum nk_collapse_states initial_state, const char *hash, int len, int line) -{ - return nk_tree_base(ctx, type, 0, title, nk_strlen(title), initial_state, hash, len, line); -} -NK_API nk_bool -nk_tree_push_hashed_text( - struct nk_context *ctx, enum nk_tree_type type, const char *title, int title_len, enum nk_collapse_states initial_state, const char *hash, int len, int line) -{ - return nk_tree_base(ctx, type, 0, title, title_len, initial_state, hash, len, line); -} -NK_API nk_bool -nk_tree_image_push_hashed( - struct nk_context *ctx, enum nk_tree_type type, struct nk_image img, const char *title, enum nk_collapse_states initial_state, const char *hash, int len, int seed) -{ - return nk_tree_base(ctx, type, &img, title, nk_strlen(title), initial_state, hash, len, seed); -} -NK_API void -nk_tree_pop(struct nk_context *ctx) -{ - nk_tree_state_pop(ctx); -} -NK_INTERN int -nk_tree_element_image_push_hashed_base( - struct nk_context *ctx, enum nk_tree_type type, struct nk_image *img, const char *title, int title_len, enum nk_collapse_states *state, nk_bool *selected) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_style *style; - struct nk_command_buffer *out; - const struct nk_input *in; - const struct nk_style_button *button; - enum nk_symbol_type symbol; - float row_height; - struct nk_vec2 padding; - - int text_len; - float text_width; - - struct nk_vec2 item_spacing; - struct nk_rect header = {0, 0, 0, 0}; - struct nk_rect sym = {0, 0, 0, 0}; - - nk_flags ws = 0; - enum nk_widget_layout_states widget_state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - /* cache some data */ - win = ctx->current; - layout = win->layout; - out = &win->buffer; - style = &ctx->style; - item_spacing = style->window.spacing; - padding = style->selectable.padding; - - /* calculate header bounds and draw background */ - row_height = style->font_size + 2 * style->tab.padding.y; - nk_layout_set_min_row_height(ctx, row_height); - nk_layout_row_dynamic(ctx, row_height, 1); - nk_layout_reset_min_row_height(ctx); - - widget_state = nk_widget(&header, ctx); - if (type == NK_TREE_TAB) { - const struct nk_style_item *background = &style->tab.background; - - switch (background->type) { - case NK_STYLE_ITEM_IMAGE: - nk_draw_image(out, header, &background->data.image, nk_rgb_factor(nk_white, style->tab.color_factor)); - break; - case NK_STYLE_ITEM_NINE_SLICE: - nk_draw_nine_slice(out, header, &background->data.slice, nk_rgb_factor(nk_white, style->tab.color_factor)); - break; - case NK_STYLE_ITEM_COLOR: - nk_fill_rect(out, header, 0, nk_rgb_factor(style->tab.border_color, style->tab.color_factor)); - nk_fill_rect(out, nk_shrink_rect(header, style->tab.border), style->tab.rounding, nk_rgb_factor(background->data.color, style->tab.color_factor)); - - break; - } - } - - in = (!(layout->flags & NK_WINDOW_ROM)) ? &ctx->input : 0; - in = (in && widget_state == NK_WIDGET_VALID) ? &ctx->input : 0; - - /* select correct button style */ - if (*state == NK_MAXIMIZED) { - symbol = style->tab.sym_maximize; - if (type == NK_TREE_TAB) { - button = &style->tab.tab_maximize_button; - } else { - button = &style->tab.node_maximize_button; - } - } else { - symbol = style->tab.sym_minimize; - if (type == NK_TREE_TAB) { - button = &style->tab.tab_minimize_button; - } else { - button = &style->tab.node_minimize_button; - } - } - { /* draw triangle button */ - sym.w = sym.h = style->font_size; - sym.y = header.y + style->tab.padding.y; - sym.x = header.x + style->tab.padding.x; - if (nk_do_button_symbol(&ws, &win->buffer, sym, symbol, NK_BUTTON_DEFAULT, button, in, style->font)) { - *state = (*state == NK_MAXIMIZED) ? NK_MINIMIZED : NK_MAXIMIZED; - } - } - - /* draw label */ - { - nk_flags dummy = 0; - struct nk_rect label; - /* calculate size of the text and tooltip */ - text_len = nk_strlen(title); - text_width = nk_text_width(ctx, style->font, style->font_size, title, text_len); - text_width += (4 * padding.x); - - header.w = NK_MAX(header.w, sym.w + item_spacing.x); - label.x = sym.x + sym.w + item_spacing.x; - label.y = sym.y; - label.w = NK_MIN(header.w - (sym.w + item_spacing.y + style->tab.indent), text_width); - label.h = style->font_size; - - if (img) { - nk_do_selectable_image(&dummy, &win->buffer, label, title, title_len, NK_TEXT_LEFT, selected, img, &style->selectable, in, style->font); - } else { - nk_do_selectable(&dummy, &win->buffer, label, title, title_len, NK_TEXT_LEFT, selected, &style->selectable, in, style->font); - } - } - /* increase x-axis cursor widget position pointer */ - if (*state == NK_MAXIMIZED) { - layout->at_x = header.x + (float)*layout->offset_x + style->tab.indent; - layout->bounds.w = NK_MAX(layout->bounds.w, style->tab.indent); - layout->bounds.w -= (style->tab.indent + style->window.padding.x); - layout->row.tree_depth++; - return nk_true; - } else { - return nk_false; - } -} -NK_INTERN int -nk_tree_element_base(struct nk_context *ctx, - enum nk_tree_type type, - struct nk_image *img, - const char *title, - enum nk_collapse_states initial_state, - nk_bool *selected, - const char *hash, - int len, - int line) -{ - struct nk_window *win = ctx->current; - int title_len = 0; - nk_hash tree_hash = 0; - nk_uint *state = 0; - - /* retrieve tree state from internal widget state tables */ - if (!hash) { - title_len = (int)nk_strlen(title); - tree_hash = nk_murmur_hash(title, (int)title_len, (nk_hash)line); - } else { - tree_hash = nk_murmur_hash(hash, len, (nk_hash)line); - } - state = nk_find_value(win, tree_hash); - if (!state) { - state = nk_add_value(ctx, win, tree_hash, 0); - *state = initial_state; - } - return nk_tree_element_image_push_hashed_base(ctx, type, img, title, nk_strlen(title), (enum nk_collapse_states *)state, selected); -} -NK_API nk_bool -nk_tree_element_push_hashed( - struct nk_context *ctx, enum nk_tree_type type, const char *title, enum nk_collapse_states initial_state, nk_bool *selected, const char *hash, int len, int seed) -{ - return nk_tree_element_base(ctx, type, 0, title, initial_state, selected, hash, len, seed); -} -NK_API nk_bool -nk_tree_element_image_push_hashed(struct nk_context *ctx, - enum nk_tree_type type, - struct nk_image img, - const char *title, - enum nk_collapse_states initial_state, - nk_bool *selected, - const char *hash, - int len, - int seed) -{ - return nk_tree_element_base(ctx, type, &img, title, initial_state, selected, hash, len, seed); -} -NK_API void -nk_tree_element_pop(struct nk_context *ctx) -{ - nk_tree_state_pop(ctx); -} - -/* =============================================================== - * - * GROUP - * - * ===============================================================*/ -NK_API nk_bool -nk_group_scrolled_offset_begin( - struct nk_context *ctx, nk_uint *x_offset, nk_uint *y_offset, nk_uint *prev_max_x, nk_uint *prev_max_y, nk_uint *scroll_flags, const char *title, nk_flags flags) -{ - struct nk_rect bounds; - struct nk_window panel; - struct nk_window *win; - - win = ctx->current; - nk_panel_alloc_space(&bounds, ctx); - { - const struct nk_rect *c = &win->layout->clip; - if (!NK_INTERSECT(c->x, c->y, c->w, c->h, bounds.x, bounds.y, bounds.w, bounds.h) && !(flags & NK_WINDOW_MOVABLE)) { - return 0; - } - } - if (win->flags & NK_WINDOW_ROM) { - flags |= NK_WINDOW_ROM; - } - - /* initialize a fake window to create the panel from */ - nk_zero(&panel, sizeof(panel)); - panel.bounds = bounds; - panel.flags = flags; - panel.scrollbar.x = *x_offset; - panel.scrollbar.y = *y_offset; - panel.buffer = win->buffer; - panel.layout = (struct nk_panel *)nk_create_panel(ctx); - ctx->current = &panel; - nk_panel_begin(ctx, (flags & NK_WINDOW_TITLE) ? title : 0, NK_PANEL_GROUP); - - win->buffer = panel.buffer; - win->buffer.clip = panel.layout->clip; - panel.layout->offset_x = x_offset; - panel.layout->offset_y = y_offset; - panel.layout->prev_max_x = prev_max_x; - panel.layout->prev_max_y = prev_max_y; - panel.layout->scroll_flags = scroll_flags; - panel.layout->parent = win->layout; - panel.layout->text_selection_scope = nk_murmur_hash(title, title ? (int)nk_strlen(title) : 0, win->layout->text_selection_scope); - win->layout = panel.layout; - - ctx->current = win; - if ((panel.layout->flags & NK_WINDOW_CLOSED) || (panel.layout->flags & NK_WINDOW_MINIMIZED)) { - nk_flags f = panel.layout->flags; - nk_group_scrolled_end(ctx); - if (f & NK_WINDOW_CLOSED) { - return NK_WINDOW_CLOSED; - } - if (f & NK_WINDOW_MINIMIZED) { - return NK_WINDOW_MINIMIZED; - } - } - return 1; -} - -NK_API void -nk_group_scrolled_end(struct nk_context *ctx) -{ - struct nk_window *win; - struct nk_panel *parent; - struct nk_panel *g; - - struct nk_rect clip; - struct nk_window pan; - struct nk_vec2 panel_padding; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) { - return; - } - - /* make sure nk_group_begin was called correctly */ - NK_ASSERT(ctx->current); - win = ctx->current; - NK_ASSERT(win->layout); - g = win->layout; - NK_ASSERT(g->parent); - parent = g->parent; - - /* dummy window */ - nk_zero_struct(pan); - panel_padding = nk_panel_get_padding(&ctx->style, NK_PANEL_GROUP); - pan.bounds.y = g->bounds.y - (g->header_height + g->menu.h); - pan.bounds.x = g->bounds.x - panel_padding.x; - pan.bounds.w = g->bounds.w + 2 * panel_padding.x; - pan.bounds.h = g->bounds.h + g->header_height + g->menu.h; - - if (g->flags & NK_WINDOW_BORDER) { - pan.bounds.x -= g->border; - pan.bounds.y -= g->border; - pan.bounds.w += 2 * g->border; - pan.bounds.h += 2 * g->border; - } - - if (!(g->flags & NK_WINDOW_NO_SCROLLBAR_V)) { - pan.bounds.w += ctx->style.window.scrollbar_size.x; - } - - if (!(g->flags & NK_WINDOW_NO_SCROLLBAR_H)) { - pan.bounds.h += ctx->style.window.scrollbar_size.y; - } - - pan.scrollbar.x = *g->offset_x; - pan.scrollbar.y = *g->offset_y; - pan.flags = g->flags; - pan.buffer = win->buffer; - pan.layout = g; - pan.parent = win; - ctx->current = &pan; - - /* make sure group has correct clipping rectangle */ - nk_unify(&clip, &parent->clip, pan.bounds.x, pan.bounds.y, pan.bounds.x + pan.bounds.w, pan.bounds.y + pan.bounds.h + panel_padding.x); - nk_push_scissor(&pan.buffer, clip); - nk_end(ctx); - - win->buffer = pan.buffer; - nk_push_scissor(&win->buffer, parent->clip); - ctx->current = win; - win->layout = parent; - g->bounds = pan.bounds; - return; -} - -NK_API nk_bool -nk_group_scrolled_begin(struct nk_context *ctx, struct nk_scroll *scroll, const char *title, nk_flags flags) -{ - return nk_group_scrolled_offset_begin(ctx, &scroll->x, &scroll->y, &scroll->prev_max_x, &scroll->prev_max_y, &scroll->flags, title, flags); -} - -NK_API nk_bool -nk_group_begin_titled(struct nk_context *ctx, const char *id, const char *title, nk_flags flags) -{ - int id_len; - nk_hash id_hash; - struct nk_window *win; - nk_uint *x_offset; - nk_uint *y_offset; - nk_uint *prev_max_x; - nk_uint *prev_max_y; - nk_uint *scroll_flags; - - NK_ASSERT(ctx); - NK_ASSERT(id); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout || !id) { - return 0; - } - - /* find persistent group scrollbar value */ - win = ctx->current; - id_len = (int)nk_strlen(id); - id_hash = nk_murmur_hash(id, (int)id_len, NK_PANEL_GROUP); - x_offset = nk_find_value(win, id_hash + 0); - y_offset = nk_find_value(win, id_hash + 1); - prev_max_x = nk_find_value(win, id_hash + 2); - prev_max_y = nk_find_value(win, id_hash + 3); - scroll_flags = nk_find_value(win, id_hash + 4); - - if (!x_offset) { - x_offset = nk_add_value(ctx, win, id_hash + 0, 0); - } - - if (!y_offset) { - y_offset = nk_add_value(ctx, win, id_hash + 1, 0); - } - - if (!prev_max_x) { - prev_max_x = nk_add_value(ctx, win, id_hash + 2, 0); - } - - if (!prev_max_y) { - prev_max_y = nk_add_value(ctx, win, id_hash + 3, 0); - } - - if (!scroll_flags) { - scroll_flags = nk_add_value(ctx, win, id_hash + 4, 0); - } - - if (!x_offset || !y_offset || !prev_max_x || !prev_max_y || !scroll_flags) { - return 0; - } - - return nk_group_scrolled_offset_begin(ctx, x_offset, y_offset, prev_max_x, prev_max_y, scroll_flags, title, flags); -} - -NK_API nk_bool -nk_group_begin(struct nk_context *ctx, const char *title, nk_flags flags) -{ - return nk_group_begin_titled(ctx, title, title, flags); -} - -NK_API void -nk_group_end(struct nk_context *ctx) -{ - nk_group_scrolled_end(ctx); -} - -NK_API void -nk_group_get_scroll(struct nk_context *ctx, const char *id, nk_uint *x_offset, nk_uint *y_offset, nk_uint *prev_max_x, nk_uint *prev_max_y, nk_uint *scroll_flags) -{ - int id_len; - nk_hash id_hash; - struct nk_window *win; - nk_uint *x_offset_ptr; - nk_uint *y_offset_ptr; - nk_uint *prev_max_x_ptr; - nk_uint *prev_max_y_ptr; - nk_uint *scroll_flags_ptr; - - NK_ASSERT(ctx); - NK_ASSERT(id); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout || !id) { - return; - } - - /* find persistent group scrollbar value */ - win = ctx->current; - id_len = (int)nk_strlen(id); - id_hash = nk_murmur_hash(id, (int)id_len, NK_PANEL_GROUP); - - x_offset_ptr = nk_find_value(win, id_hash + 0); - y_offset_ptr = nk_find_value(win, id_hash + 1); - prev_max_x_ptr = nk_find_value(win, id_hash + 2); - prev_max_y_ptr = nk_find_value(win, id_hash + 3); - scroll_flags_ptr = nk_find_value(win, id_hash + 4); - - if (!x_offset_ptr) { - x_offset_ptr = nk_add_value(ctx, win, id_hash + 0, 0); - } - - if (!y_offset_ptr) { - y_offset_ptr = nk_add_value(ctx, win, id_hash + 1, 0); - } - - if (!prev_max_x_ptr) { - prev_max_x_ptr = nk_add_value(ctx, win, id_hash + 2, 0); - } - - if (!prev_max_y_ptr) { - prev_max_y_ptr = nk_add_value(ctx, win, id_hash + 3, 0); - } - - if (!scroll_flags_ptr) { - scroll_flags_ptr = nk_add_value(ctx, win, id_hash + 4, 0); - } - - if (!x_offset_ptr || !y_offset_ptr || !prev_max_x_ptr || !prev_max_y_ptr || !scroll_flags_ptr) { - return; - } - - if (x_offset) { - *x_offset = *x_offset_ptr; - } - - if (y_offset) { - *y_offset = *y_offset_ptr; - } - - if (prev_max_x) { - *prev_max_x = *prev_max_x_ptr; - } - - if (prev_max_y) { - *prev_max_y = *prev_max_y_ptr; - } - - if (scroll_flags) { - *scroll_flags = *scroll_flags_ptr; - } -} - -NK_API void -nk_group_set_scroll(struct nk_context *ctx, const char *id, nk_uint x_offset, nk_uint y_offset) -{ - int id_len; - nk_hash id_hash; - struct nk_window *win; - nk_uint *x_offset_ptr; - nk_uint *y_offset_ptr; - - NK_ASSERT(ctx); - NK_ASSERT(id); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout || !id) { - return; - } - - /* find persistent group scrollbar value */ - win = ctx->current; - id_len = (int)nk_strlen(id); - id_hash = nk_murmur_hash(id, (int)id_len, NK_PANEL_GROUP); - - x_offset_ptr = nk_find_value(win, id_hash + 0); - y_offset_ptr = nk_find_value(win, id_hash + 1); - - if (!x_offset_ptr) { - x_offset_ptr = nk_add_value(ctx, win, id_hash + 0, 0); - } - - if (!y_offset_ptr) { - y_offset_ptr = nk_add_value(ctx, win, id_hash + 1, 0); - } - - if (!x_offset_ptr || !y_offset_ptr) { - return; - } - - *x_offset_ptr = x_offset; - *y_offset_ptr = y_offset; -} - -/* =============================================================== - * - * LIST VIEW - * - * ===============================================================*/ -NK_API nk_bool -nk_list_view_begin(struct nk_context *ctx, struct nk_list_view *view, const char *title, nk_flags flags, int row_height, int row_count) -{ - int title_len; - nk_hash title_hash; - nk_uint *x_offset; - nk_uint *y_offset; - nk_uint *prev_max_x; - nk_uint *prev_max_y; - nk_uint *scroll_flags; - - int result; - struct nk_window *win; - struct nk_panel *layout; - const struct nk_style *style; - struct nk_vec2 item_spacing; - - NK_ASSERT(ctx); - NK_ASSERT(view); - NK_ASSERT(title); - if (!ctx || !view || !title) { - return 0; - } - - win = ctx->current; - style = &ctx->style; - item_spacing = style->window.spacing; - row_height += NK_MAX(0, (int)item_spacing.y); - - /* find persistent list view scrollbar offset */ - title_len = (int)nk_strlen(title); - title_hash = nk_murmur_hash(title, (int)title_len, NK_PANEL_GROUP); - - x_offset = nk_find_value(win, title_hash + 0); - y_offset = nk_find_value(win, title_hash + 1); - prev_max_x = nk_find_value(win, title_hash + 2); - prev_max_y = nk_find_value(win, title_hash + 3); - scroll_flags = nk_find_value(win, title_hash + 4); - - if (!x_offset) { - x_offset = nk_add_value(ctx, win, title_hash + 0, 0); - } - - if (!y_offset) { - y_offset = nk_add_value(ctx, win, title_hash + 1, 0); - } - - if (!prev_max_x) { - prev_max_x = nk_add_value(ctx, win, title_hash + 2, 0); - } - - if (!prev_max_y) { - prev_max_y = nk_add_value(ctx, win, title_hash + 3, 0); - } - - if (!scroll_flags) { - scroll_flags = nk_add_value(ctx, win, title_hash + 4, 0); - } - - if (!x_offset || !y_offset || !prev_max_x || !prev_max_y || !scroll_flags) { - return 0; - } - - view->scroll_value = *y_offset; - view->scroll_pointer = y_offset; - view->prev_max_value = *prev_max_y; - view->prev_max_pointer = prev_max_y; - view->prev_flags_pointer = scroll_flags; - - *y_offset = 0; - result = nk_group_scrolled_offset_begin(ctx, x_offset, y_offset, NULL, NULL, NULL, title, flags); - win = ctx->current; - layout = win->layout; - - view->total_height = row_height * NK_MAX(row_count, 1); - { - float old_max_offset = (float)view->prev_max_value; - float new_max_offset = NK_MAX((float)view->total_height - layout->clip.h, 0.0f); - nk_bool has_prev = (*view->prev_flags_pointer & NK_SCROLL_HAS_PREV_MAX_Y) != 0; - - if (has_prev) { - nk_bool had_scrollbar = old_max_offset > 0.0f; - nk_bool was_at_end = had_scrollbar && ((float)view->scroll_value >= NK_MAX(old_max_offset - 1.0f, 0.0f)); - - if (was_at_end && new_max_offset > old_max_offset) { - view->scroll_value = (nk_uint)new_max_offset; - } - } - - if ((float)view->scroll_value > new_max_offset) { - view->scroll_value = (nk_uint)new_max_offset; - } - - *view->prev_max_pointer = (nk_uint)new_max_offset; - *view->prev_flags_pointer |= NK_SCROLL_HAS_PREV_MAX_Y; - } - - view->begin = (int)NK_MAX(((float)view->scroll_value / (float)row_height), 0.0f); - view->begin = NK_MIN(view->begin, NK_MAX(row_count - 1, 0)); - view->count = (int)NK_MAX(nk_iceilf(layout->clip.h / (float)row_height), 0); - view->count = NK_MIN(view->count, NK_MAX(row_count - view->begin, 0)); - view->end = view->begin + view->count; - view->ctx = ctx; - return result; -} -NK_API void -nk_list_view_end(struct nk_list_view *view) -{ - struct nk_context *ctx; - struct nk_window *win; - struct nk_panel *layout; - - NK_ASSERT(view); - NK_ASSERT(view->ctx); - NK_ASSERT(view->scroll_pointer); - if (!view || !view->ctx) { - return; - } - - ctx = view->ctx; - win = ctx->current; - layout = win->layout; - layout->at_y = layout->bounds.y + (float)view->total_height; - *view->scroll_pointer = *view->scroll_pointer + view->scroll_value; - nk_group_end(view->ctx); -} - -/* =============================================================== - * - * WIDGET - * - * ===============================================================*/ -NK_API struct nk_rect -nk_widget_bounds(const struct nk_context *ctx) -{ - struct nk_rect bounds; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) { - return nk_rect(0, 0, 0, 0); - } - nk_layout_peek(&bounds, ctx); - return bounds; -} -NK_API struct nk_vec2 -nk_widget_position(const struct nk_context *ctx) -{ - struct nk_rect bounds; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) { - return nk_vec2(0, 0); - } - - nk_layout_peek(&bounds, ctx); - return nk_vec2(bounds.x, bounds.y); -} -NK_API struct nk_vec2 -nk_widget_size(const struct nk_context *ctx) -{ - struct nk_rect bounds; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) { - return nk_vec2(0, 0); - } - - nk_layout_peek(&bounds, ctx); - return nk_vec2(bounds.w, bounds.h); -} -NK_API float -nk_widget_width(const struct nk_context *ctx) -{ - struct nk_rect bounds; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) { - return 0; - } - - nk_layout_peek(&bounds, ctx); - return bounds.w; -} -NK_API float -nk_widget_height(const struct nk_context *ctx) -{ - struct nk_rect bounds; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) { - return 0; - } - - nk_layout_peek(&bounds, ctx); - return bounds.h; -} -NK_API nk_bool -nk_widget_is_hovered(const struct nk_context *ctx) -{ - struct nk_rect c, v; - struct nk_rect bounds; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout || (ctx->active != ctx->current && !((int)ctx->current->layout->type & (int)NK_PANEL_SET_POPUP))) { - return 0; - } - - c = ctx->current->layout->clip; - c.x = (float)((int)c.x); - c.y = (float)((int)c.y); - c.w = (float)((int)c.w); - c.h = (float)((int)c.h); - - nk_layout_peek(&bounds, ctx); - nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h); - if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h)) { - return 0; - } - return nk_input_is_mouse_hovering_rect(&ctx->input, bounds); -} -NK_API nk_bool -nk_widget_is_mouse_clicked(const struct nk_context *ctx, enum nk_buttons btn) -{ - struct nk_rect c, v; - struct nk_rect bounds; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout || (ctx->active != ctx->current && !((int)ctx->current->layout->type & (int)NK_PANEL_SET_POPUP))) { - return 0; - } - - c = ctx->current->layout->clip; - c.x = (float)((int)c.x); - c.y = (float)((int)c.y); - c.w = (float)((int)c.w); - c.h = (float)((int)c.h); - - nk_layout_peek(&bounds, ctx); - nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h); - if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h)) { - return 0; - } - return nk_input_mouse_clicked(&ctx->input, btn, bounds); -} -NK_API nk_bool -nk_widget_has_mouse_click_down(const struct nk_context *ctx, enum nk_buttons btn, nk_bool down) -{ - struct nk_rect c, v; - struct nk_rect bounds; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout || (ctx->active != ctx->current && !((int)ctx->current->layout->type & (int)NK_PANEL_SET_POPUP))) { - return 0; - } - - c = ctx->current->layout->clip; - c.x = (float)((int)c.x); - c.y = (float)((int)c.y); - c.w = (float)((int)c.w); - c.h = (float)((int)c.h); - - nk_layout_peek(&bounds, ctx); - nk_unify(&v, &c, bounds.x, bounds.y, bounds.x + bounds.w, bounds.y + bounds.h); - if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds.x, bounds.y, bounds.w, bounds.h)) { - return 0; - } - return nk_input_has_mouse_click_down_in_rect(&ctx->input, btn, bounds, down); -} -NK_API enum nk_widget_layout_states -nk_widget(struct nk_rect *bounds, const struct nk_context *ctx) -{ - struct nk_rect c, v; - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return NK_WIDGET_INVALID; - } - - /* allocate space and check if the widget needs to be updated and drawn */ - nk_panel_alloc_space(bounds, ctx); - win = ctx->current; - layout = win->layout; - in = &ctx->input; - c = layout->clip; - - /* if one of these triggers you forgot to add an `if` condition around either - a window, group, popup, combobox or contextual menu `begin` and `end` block. - Example: - if (nk_begin(...) {...} nk_end(...); or - if (nk_group_begin(...) { nk_group_end(...);} */ - NK_ASSERT(!(layout->flags & NK_WINDOW_MINIMIZED)); - NK_ASSERT(!(layout->flags & NK_WINDOW_HIDDEN)); - NK_ASSERT(!(layout->flags & NK_WINDOW_CLOSED)); - - /* need to convert to int here to remove floating point errors */ - bounds->x = (float)((int)bounds->x); - bounds->y = (float)((int)bounds->y); - bounds->w = (float)((int)bounds->w); - bounds->h = (float)((int)bounds->h); - - c.x = (float)((int)c.x); - c.y = (float)((int)c.y); - c.w = (float)((int)c.w); - c.h = (float)((int)c.h); - - nk_unify(&v, &c, bounds->x, bounds->y, bounds->x + bounds->w, bounds->y + bounds->h); - if (!NK_INTERSECT(c.x, c.y, c.w, c.h, bounds->x, bounds->y, bounds->w, bounds->h)) { - return NK_WIDGET_INVALID; - } - if (win->widgets_disabled) { - return NK_WIDGET_DISABLED; - } - if (!NK_INBOX(in->mouse.pos.x, in->mouse.pos.y, v.x, v.y, v.w, v.h)) { - return NK_WIDGET_ROM; - } - return NK_WIDGET_VALID; -} -NK_API enum nk_widget_layout_states -nk_widget_fitting(struct nk_rect *bounds, const struct nk_context *ctx, struct nk_vec2 item_padding) -{ - /* update the bounds to stand without padding */ - enum nk_widget_layout_states state; - NK_UNUSED(item_padding); - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return NK_WIDGET_INVALID; - } - - state = nk_widget(bounds, ctx); - return state; -} -NK_API void -nk_spacing(struct nk_context *ctx, int cols) -{ - struct nk_window *win; - struct nk_panel *layout; - struct nk_rect none; - int i, index, rows; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - /* spacing over row boundaries */ - win = ctx->current; - layout = win->layout; - index = (layout->row.index + cols) % layout->row.columns; - rows = (layout->row.index + cols) / layout->row.columns; - if (rows) { - for (i = 0; i < rows; ++i) { - nk_panel_alloc_row(ctx, win); - } - cols = index; - } - /* non table layout need to allocate space */ - if (layout->row.type != NK_LAYOUT_DYNAMIC_FIXED && layout->row.type != NK_LAYOUT_STATIC_FIXED) { - for (i = 0; i < cols; ++i) { - nk_panel_alloc_space(&none, ctx); - } - } - layout->row.index = index; -} -NK_API void -nk_widget_disable_begin(struct nk_context *ctx) -{ - struct nk_window *win; - struct nk_style *style; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - - if (!ctx || !ctx->current) { - return; - } - - win = ctx->current; - style = &ctx->style; - - win->widgets_disabled = nk_true; - - style->button.color_factor_text = style->button.disabled_factor; - style->button.color_factor_background = style->button.disabled_factor; - style->chart.color_factor = style->chart.disabled_factor; - style->checkbox.color_factor = style->checkbox.disabled_factor; - style->combo.color_factor = style->combo.disabled_factor; - style->combo.button.color_factor_text = style->combo.button.disabled_factor; - style->combo.button.color_factor_background = style->combo.button.disabled_factor; - style->contextual_button.color_factor_text = style->contextual_button.disabled_factor; - style->contextual_button.color_factor_background = style->contextual_button.disabled_factor; - style->edit.color_factor = style->edit.disabled_factor; - style->edit.scrollbar.color_factor = style->edit.scrollbar.disabled_factor; - style->menu_button.color_factor_text = style->menu_button.disabled_factor; - style->menu_button.color_factor_background = style->menu_button.disabled_factor; - style->option.color_factor = style->option.disabled_factor; - style->progress.color_factor = style->progress.disabled_factor; - style->property.color_factor = style->property.disabled_factor; - style->property.inc_button.color_factor_text = style->property.inc_button.disabled_factor; - style->property.inc_button.color_factor_background = style->property.inc_button.disabled_factor; - style->property.dec_button.color_factor_text = style->property.dec_button.disabled_factor; - style->property.dec_button.color_factor_background = style->property.dec_button.disabled_factor; - style->property.edit.color_factor = style->property.edit.disabled_factor; - style->scrollh.color_factor = style->scrollh.disabled_factor; - style->scrollh.inc_button.color_factor_text = style->scrollh.inc_button.disabled_factor; - style->scrollh.inc_button.color_factor_background = style->scrollh.inc_button.disabled_factor; - style->scrollh.dec_button.color_factor_text = style->scrollh.dec_button.disabled_factor; - style->scrollh.dec_button.color_factor_background = style->scrollh.dec_button.disabled_factor; - style->scrollv.color_factor = style->scrollv.disabled_factor; - style->scrollv.inc_button.color_factor_text = style->scrollv.inc_button.disabled_factor; - style->scrollv.inc_button.color_factor_background = style->scrollv.inc_button.disabled_factor; - style->scrollv.dec_button.color_factor_text = style->scrollv.dec_button.disabled_factor; - style->scrollv.dec_button.color_factor_background = style->scrollv.dec_button.disabled_factor; - style->selectable.color_factor = style->selectable.disabled_factor; - style->slider.color_factor = style->slider.disabled_factor; - style->slider.inc_button.color_factor_text = style->slider.inc_button.disabled_factor; - style->slider.inc_button.color_factor_background = style->slider.inc_button.disabled_factor; - style->slider.dec_button.color_factor_text = style->slider.dec_button.disabled_factor; - style->slider.dec_button.color_factor_background = style->slider.dec_button.disabled_factor; - style->tab.color_factor = style->tab.disabled_factor; - style->tab.node_maximize_button.color_factor_text = style->tab.node_maximize_button.disabled_factor; - style->tab.node_minimize_button.color_factor_text = style->tab.node_minimize_button.disabled_factor; - style->tab.tab_maximize_button.color_factor_text = style->tab.tab_maximize_button.disabled_factor; - style->tab.tab_maximize_button.color_factor_background = style->tab.tab_maximize_button.disabled_factor; - style->tab.tab_minimize_button.color_factor_text = style->tab.tab_minimize_button.disabled_factor; - style->tab.tab_minimize_button.color_factor_background = style->tab.tab_minimize_button.disabled_factor; - style->text.color_factor = style->text.disabled_factor; -} -NK_API void -nk_widget_disable_end(struct nk_context *ctx) -{ - struct nk_window *win; - struct nk_style *style; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - - if (!ctx || !ctx->current) { - return; - } - - win = ctx->current; - style = &ctx->style; - - win->widgets_disabled = nk_false; - - style->button.color_factor_text = 1.0f; - style->button.color_factor_background = 1.0f; - style->chart.color_factor = 1.0f; - style->checkbox.color_factor = 1.0f; - style->combo.color_factor = 1.0f; - style->combo.button.color_factor_text = 1.0f; - style->combo.button.color_factor_background = 1.0f; - style->contextual_button.color_factor_text = 1.0f; - style->contextual_button.color_factor_background = 1.0f; - style->edit.color_factor = 1.0f; - style->edit.scrollbar.color_factor = 1.0f; - style->menu_button.color_factor_text = 1.0f; - style->menu_button.color_factor_background = 1.0f; - style->option.color_factor = 1.0f; - style->progress.color_factor = 1.0f; - style->property.color_factor = 1.0f; - style->property.inc_button.color_factor_text = 1.0f; - style->property.inc_button.color_factor_background = 1.0f; - style->property.dec_button.color_factor_text = 1.0f; - style->property.dec_button.color_factor_background = 1.0f; - style->property.edit.color_factor = 1.0f; - style->scrollh.color_factor = 1.0f; - style->scrollh.inc_button.color_factor_text = 1.0f; - style->scrollh.inc_button.color_factor_background = 1.0f; - style->scrollh.dec_button.color_factor_text = 1.0f; - style->scrollh.dec_button.color_factor_background = 1.0f; - style->scrollv.color_factor = 1.0f; - style->scrollv.inc_button.color_factor_text = 1.0f; - style->scrollv.inc_button.color_factor_background = 1.0f; - style->scrollv.dec_button.color_factor_text = 1.0f; - style->scrollv.dec_button.color_factor_background = 1.0f; - style->selectable.color_factor = 1.0f; - style->slider.color_factor = 1.0f; - style->slider.inc_button.color_factor_text = 1.0f; - style->slider.inc_button.color_factor_background = 1.0f; - style->slider.dec_button.color_factor_text = 1.0f; - style->slider.dec_button.color_factor_background = 1.0f; - style->tab.color_factor = 1.0f; - style->tab.node_maximize_button.color_factor_text = 1.0f; - style->tab.node_minimize_button.color_factor_text = 1.0f; - style->tab.tab_maximize_button.color_factor_text = 1.0f; - style->tab.tab_maximize_button.color_factor_background = 1.0f; - style->tab.tab_minimize_button.color_factor_text = 1.0f; - style->tab.tab_minimize_button.color_factor_background = 1.0f; - style->text.color_factor = 1.0f; -} - -/* =============================================================== - * - * TEXT - * - * ===============================================================*/ -NK_INTERN struct nk_rect -nk_widget_text_layout(const struct nk_context *ctx, struct nk_rect bounds, const struct nk_text *text, nk_flags alignment, float text_width) -{ - struct nk_rect label; - - if (!(alignment & (NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_CENTERED | NK_TEXT_ALIGN_RIGHT))) { - alignment |= NK_TEXT_ALIGN_LEFT; - } - - if (!(alignment & (NK_TEXT_ALIGN_TOP | NK_TEXT_ALIGN_MIDDLE | NK_TEXT_ALIGN_BOTTOM))) { - alignment |= NK_TEXT_ALIGN_TOP; - } - - if (alignment & NK_TEXT_ALIGN_LEFT) { - label.x = bounds.x + text->padding.x; - label.w = NK_MAX(0, bounds.w - 2 * text->padding.x); - } else if (alignment & NK_TEXT_ALIGN_CENTERED) { - label.w = NK_MAX(1, 2 * text->padding.x + text_width); - label.x = bounds.x + text->padding.x + ((bounds.w - 2 * text->padding.x) - label.w) / 2; - label.x = NK_MAX(bounds.x + text->padding.x, label.x); - label.w = NK_MIN(bounds.x + bounds.w, label.x + label.w); - if (label.w >= label.x) { - label.w -= label.x; - } - } else { - label.x = NK_MAX(bounds.x + text->padding.x, bounds.x + bounds.w - (2 * text->padding.x + text_width)); - label.w = text_width + 2 * text->padding.x; - } - - if (alignment & NK_TEXT_ALIGN_TOP) { - label.y = bounds.y + text->padding.y; - label.h = NK_MIN(ctx->style.font_size, bounds.h - 2 * text->padding.y); - } else if (alignment & NK_TEXT_ALIGN_MIDDLE) { - label.h = NK_MIN(ctx->style.font_size, NK_MAX(0, bounds.h - 2 * text->padding.y)); - label.y = bounds.y + (bounds.h - label.h) / 2.0f; - } else { - label.y = bounds.y + bounds.h - ctx->style.font_size; - label.h = ctx->style.font_size; - } - return label; -} - -NK_LIB void -nk_widget_text(struct nk_command_buffer *o, struct nk_rect b, const char *string, int len, const struct nk_text *t, nk_flags a, const struct nk_user_font *f) -{ - struct nk_text_shape *shape; - struct nk_rect label; - float text_width; - - NK_ASSERT(o); - NK_ASSERT(t); - if (!o || !t) { - return; - } - - b.h = NK_MAX(b.h, 2 * t->padding.y); - - shape = nk_text_shape_build_default(o->context, f, o->context->style.font_size, string, len); - text_width = shape ? shape->advance.x : 0.0f; - text_width += (2.0f * t->padding.x); - - label = nk_widget_text_layout(o->context, b, t, a, text_width); - nk_draw_text(o, label, (const char *)string, len, f, t->background, t->text); -} -NK_LIB void -nk_widget_text_wrap(struct nk_command_buffer *o, struct nk_rect b, const char *string, int len, const struct nk_text *t, const struct nk_user_font *f) -{ - struct nk_text_shape *shape; - struct nk_text_wrap_iterator iterator; - struct nk_text_wrap_line wrapped; - struct nk_rect line; - float bottom; - - NK_ASSERT(o); - NK_ASSERT(t); - if (!o || !t) { - return; - } - - b.w = NK_MAX(b.w, 2 * t->padding.x); - b.h = NK_MAX(b.h, 2 * t->padding.y); - - line.x = b.x + t->padding.x; - line.y = b.y + t->padding.y; - line.w = b.w - 2 * t->padding.x; - line.h = 2 * t->padding.y + o->context->style.font_size; - bottom = b.y + b.h - t->padding.y; - - shape = nk_text_shape_build_default(o->context, f, o->context->style.font_size, string, len); - if (!shape) { - return; - } - - nk_text_wrap_iterator_begin(&iterator, shape, line.w); - while (line.y + line.h <= bottom && nk_text_wrap_iterator_next(&iterator, &wrapped)) { - int draw_end = wrapped.source_end; - while (draw_end > wrapped.source_begin && (string[draw_end - 1] == '\r' || string[draw_end - 1] == '\n')) { - draw_end -= 1; - } - nk_push_draw_text(o, line, string + wrapped.source_begin, draw_end - wrapped.source_begin, - f, o->context->style.font_size, t->background, t->text); - line.y += line.h; - } -} -NK_INTERN void -nk_text_widget_colored(struct nk_context *ctx, const char *str, int len, nk_flags alignment, struct nk_color color) -{ - struct nk_window *win; - struct nk_style *style; - - struct nk_vec2 item_padding; - struct nk_rect bounds; - struct nk_text text; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - win = ctx->current; - style = &ctx->style; - nk_panel_alloc_space(&bounds, ctx); - item_padding = style->text.padding; - - text.padding.x = item_padding.x; - text.padding.y = item_padding.y; - text.background = style->window.background; - text.text = nk_rgb_factor(color, style->text.color_factor); - nk_widget_text(&win->buffer, bounds, str, len, &text, alignment, style->font); -} -NK_INTERN void -nk_text_wrap_widget_colored(struct nk_context *ctx, const char *str, int len, struct nk_color color) -{ - struct nk_window *win; - struct nk_style *style; - - struct nk_vec2 item_padding; - struct nk_rect bounds; - struct nk_text text; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - win = ctx->current; - style = &ctx->style; - nk_panel_alloc_space(&bounds, ctx); - item_padding = style->text.padding; - - text.padding.x = item_padding.x; - text.padding.y = item_padding.y; - text.background = style->window.background; - text.text = nk_rgb_factor(color, style->text.color_factor); - nk_widget_text_wrap(&win->buffer, bounds, str, len, &text, style->font); -} - -NK_API void -nk_text_colored(struct nk_context *ctx, const char *str, int len, nk_flags alignment, struct nk_color color) -{ - struct nk_text_options options; - - NK_MEMSET(&options, 0, sizeof(options)); - options.alignment = alignment; - options.color = color; -#ifdef NK_DEFAULT_TEXT_SELECTABLE - options.flags |= NK_TEXT_OPTION_SELECTABLE; -#endif - - (void)nk_text_ex(ctx, str, len, &options); -} - -NK_API void -nk_text_wrap_colored(struct nk_context *ctx, const char *str, int len, struct nk_color color) -{ - struct nk_text_options options; - - NK_MEMSET(&options, 0, sizeof(options)); - options.alignment = NK_TEXT_LEFT; - options.flags = NK_TEXT_OPTION_WRAP; - options.color = color; -#ifdef NK_DEFAULT_TEXT_SELECTABLE - options.flags |= NK_TEXT_OPTION_SELECTABLE; -#endif - - (void)nk_text_ex(ctx, str, len, &options); -} -#ifdef NK_INCLUDE_STANDARD_VARARGS -NK_API void -nk_labelf_colored(struct nk_context *ctx, nk_flags flags, struct nk_color color, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - nk_labelfv_colored(ctx, flags, color, fmt, args); - va_end(args); -} -NK_API void -nk_labelf_colored_wrap(struct nk_context *ctx, struct nk_color color, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - nk_labelfv_colored_wrap(ctx, color, fmt, args); - va_end(args); -} -NK_API void -nk_labelf(struct nk_context *ctx, nk_flags flags, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - nk_labelfv(ctx, flags, fmt, args); - va_end(args); -} -NK_API void -nk_labelf_wrap(struct nk_context *ctx, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - nk_labelfv_wrap(ctx, fmt, args); - va_end(args); -} -NK_API void -nk_labelfv_colored(struct nk_context *ctx, nk_flags flags, struct nk_color color, const char *fmt, va_list args) -{ - char buf[256]; - nk_strfmt(buf, NK_LEN(buf), fmt, args); - nk_label_colored(ctx, buf, flags, color); -} - -NK_API void -nk_labelfv_colored_wrap(struct nk_context *ctx, struct nk_color color, const char *fmt, va_list args) -{ - char buf[256]; - nk_strfmt(buf, NK_LEN(buf), fmt, args); - nk_label_colored_wrap(ctx, buf, color); -} - -NK_API void -nk_labelfv(struct nk_context *ctx, nk_flags flags, const char *fmt, va_list args) -{ - char buf[256]; - nk_strfmt(buf, NK_LEN(buf), fmt, args); - nk_label(ctx, buf, flags); -} - -NK_API void -nk_labelfv_wrap(struct nk_context *ctx, const char *fmt, va_list args) -{ - char buf[256]; - nk_strfmt(buf, NK_LEN(buf), fmt, args); - nk_label_wrap(ctx, buf); -} - -NK_API void -nk_value_bool(struct nk_context *ctx, const char *prefix, int value) -{ - nk_labelf(ctx, NK_TEXT_LEFT, "%s: %s", prefix, ((value) ? "true" : "false")); -} -NK_API void -nk_value_int(struct nk_context *ctx, const char *prefix, int value) -{ - nk_labelf(ctx, NK_TEXT_LEFT, "%s: %d", prefix, value); -} -NK_API void -nk_value_uint(struct nk_context *ctx, const char *prefix, unsigned int value) -{ - nk_labelf(ctx, NK_TEXT_LEFT, "%s: %u", prefix, value); -} -NK_API void -nk_value_float(struct nk_context *ctx, const char *prefix, float value) -{ - double double_value = (double)value; - nk_labelf(ctx, NK_TEXT_LEFT, "%s: %.3f", prefix, double_value); -} -NK_API void -nk_value_color_byte(struct nk_context *ctx, const char *p, struct nk_color c) -{ - nk_labelf(ctx, NK_TEXT_LEFT, "%s: (%d, %d, %d, %d)", p, c.r, c.g, c.b, c.a); -} -NK_API void -nk_value_color_float(struct nk_context *ctx, const char *p, struct nk_color color) -{ - double c[4]; - nk_color_dv(c, color); - nk_labelf(ctx, NK_TEXT_LEFT, "%s: (%.2f, %.2f, %.2f, %.2f)", p, c[0], c[1], c[2], c[3]); -} -NK_API void -nk_value_color_hex(struct nk_context *ctx, const char *prefix, struct nk_color color) -{ - char hex[16]; - nk_color_hex_rgba(hex, color); - nk_labelf(ctx, NK_TEXT_LEFT, "%s: %s", prefix, hex); -} -#endif -NK_API void -nk_text(struct nk_context *ctx, const char *str, int len, nk_flags alignment) -{ - NK_ASSERT(ctx); - if (!ctx) { - return; - } - nk_text_colored(ctx, str, len, alignment, ctx->style.text.color); -} -NK_API void -nk_text_wrap(struct nk_context *ctx, const char *str, int len) -{ - NK_ASSERT(ctx); - if (!ctx) { - return; - } - nk_text_wrap_colored(ctx, str, len, ctx->style.text.color); -} -NK_API void -nk_label(struct nk_context *ctx, const char *str, nk_flags alignment) -{ - nk_text(ctx, str, nk_strlen(str), alignment); -} -NK_API void -nk_label_colored(struct nk_context *ctx, const char *str, nk_flags align, struct nk_color color) -{ - nk_text_colored(ctx, str, nk_strlen(str), align, color); -} -NK_API void -nk_label_wrap(struct nk_context *ctx, const char *str) -{ - nk_text_wrap(ctx, str, nk_strlen(str)); -} -NK_API void -nk_label_colored_wrap(struct nk_context *ctx, const char *str, struct nk_color color) -{ - nk_text_wrap_colored(ctx, str, nk_strlen(str), color); -} - -NK_INTERN void -nk_text_selection_collapse(const struct nk_text_shape *shape, struct nk_text_selection *selection, int direction) -{ - struct nk_text_cursor anchor = nk_text_shape_cursor_at(shape, selection->anchor, (enum nk_text_affinity)selection->anchor_affinity); - struct nk_text_cursor cursor = nk_text_shape_cursor_at(shape, selection->cursor, (enum nk_text_affinity)selection->affinity); - nk_bool use_anchor = direction < 0 ? anchor.x < cursor.x : anchor.x > cursor.x; - struct nk_text_cursor edge = use_anchor ? anchor : cursor; - - selection->anchor = edge.source_offset; - selection->cursor = edge.source_offset; - selection->affinity = (unsigned char)edge.affinity; - selection->anchor_affinity = (unsigned char)edge.affinity; -} - -NK_INTERN struct nk_text_selection_context * -nk_text_selection_panel_context(struct nk_context *ctx) -{ - struct nk_panel *panel = ctx->current->layout; - if (!panel->text_selection_loaded) { - nk_text_selection_panel_load(ctx, panel); - } - return &panel->text_selection; -} - -struct nk_text_selection_copy_chunk { - struct nk_command header; - nk_size next; - int length; - char data[1]; -}; - -struct nk_text_selection_copy_result { - struct nk_command header; - char data[1]; -}; - -NK_INTERN struct nk_text_selection_copy_chunk * -nk_text_selection_copy_chunk_at(struct nk_context *ctx, nk_size offset) -{ - if (!offset) { - return NULL; - } - return nk_ptr_add(struct nk_text_selection_copy_chunk, ctx->memory.memory.ptr, offset - 1); -} - -NK_INTERN nk_bool -nk_text_selection_context_empty(const struct nk_text_selection_context *context) -{ - return context->anchor_widget == context->cursor_widget && context->selection.anchor == context->selection.cursor; -} - -NK_INTERN void -nk_text_selection_context_collapse(struct nk_text_selection_context *context, const struct nk_text_shape *shape, int direction) -{ - struct nk_text_selection *selection = &context->selection; - nk_bool use_anchor; - - if (context->anchor_widget == context->cursor_widget) { - nk_text_selection_collapse(shape, selection, direction); - return; - } - - use_anchor = direction < 0 ? context->anchor_widget < context->cursor_widget - : context->anchor_widget > context->cursor_widget; - if (use_anchor) { - context->cursor_widget = context->anchor_widget; - selection->cursor = selection->anchor; - selection->affinity = selection->anchor_affinity; - } else { - context->anchor_widget = context->cursor_widget; - selection->anchor = selection->cursor; - selection->anchor_affinity = selection->affinity; - } - - context->anchor_widget = context->cursor_widget; - selection->anchor = selection->cursor; - selection->anchor_affinity = selection->affinity; -} - -NK_INTERN nk_bool -nk_text_selection_widget_range(struct nk_text_selection_context *context, unsigned int widget, int len, int *begin, int *end) -{ - struct nk_text_selection *selection = &context->selection; - if (!selection->active) { - return nk_false; - } - - if (context->anchor_widget == context->cursor_widget) { - if (widget != context->anchor_widget) { - return nk_false; - } - *begin = NK_MIN(selection->anchor, selection->cursor); - *end = NK_MAX(selection->anchor, selection->cursor); - } else if (context->anchor_widget < context->cursor_widget) { - if (widget < context->anchor_widget || widget > context->cursor_widget) { - return nk_false; - } - *begin = widget == context->anchor_widget ? selection->anchor : 0; - *end = widget == context->cursor_widget ? selection->cursor : len; - } else { - if (widget < context->cursor_widget || widget > context->anchor_widget) { - return nk_false; - } - *begin = widget == context->cursor_widget ? selection->cursor : 0; - *end = widget == context->anchor_widget ? selection->anchor : len; - } - - *begin = NK_CLAMP(0, *begin, len); - *end = NK_CLAMP(0, *end, len); - return nk_true; -} - -NK_INTERN void -nk_text_selection_copy_append(struct nk_context *ctx, struct nk_text_selection_context *context, - const char *text, int length, struct nk_rect bounds) -{ - int prefix = context->copy_first ? 1 : 0; - nk_size size = offsetof(struct nk_text_selection_copy_chunk, data) + prefix + length; - struct nk_text_selection_copy_chunk *chunk; - nk_size offset; - - chunk = nk_command_buffer_push(&ctx->current->buffer, NK_COMMAND_NOP, size); - if (!chunk) { - return; - } - - offset = (nk_size)((nk_byte *)chunk - (nk_byte *)ctx->memory.memory.ptr) + 1; - chunk->next = 0; - chunk->length = prefix + length; - if (prefix) { - nk_bool same_row = bounds.y < context->copy_bounds.y + context->copy_bounds.h && context->copy_bounds.y < bounds.y + bounds.h; - chunk->data[0] = same_row ? '\t' : '\n'; - } - if (length) { - NK_MEMCPY(chunk->data + prefix, text, length); - } - - if (context->copy_last) { - nk_text_selection_copy_chunk_at(ctx, context->copy_last)->next = offset; - } else { - context->copy_first = offset; - } - context->copy_last = offset; - context->copy_length += chunk->length; - context->copy_bounds = bounds; -} - -NK_INTERN void -nk_text_selection_copy_finish(struct nk_context *ctx, struct nk_text_selection_context *context) -{ - struct nk_text_selection_copy_result *result; - nk_size chunk_offset = context->copy_first; - int text_offset = 0; - - if (!chunk_offset || !ctx->clip.copy) { - return; - } - - result = nk_command_buffer_push(&ctx->current->buffer, NK_COMMAND_NOP, offsetof(struct nk_text_selection_copy_result, data) + context->copy_length); - if (!result) { - return; - } - - while (chunk_offset) { - struct nk_text_selection_copy_chunk *chunk = nk_text_selection_copy_chunk_at(ctx, chunk_offset); - NK_MEMCPY(result->data + text_offset, chunk->data, chunk->length); - text_offset += chunk->length; - chunk_offset = chunk->next; - } - ctx->clip.copy(ctx->clip.userdata, result->data, context->copy_length); -} - -NK_INTERN unsigned int -nk_text_selection_widget_begin(struct nk_context *ctx, struct nk_text_selection_context *context) -{ - if (context->frame != ctx->seq) { - context->widget_count = context->widget_index; - context->frame = ctx->seq; - context->widget_index = 0; - context->copy_first = 0; - context->copy_last = 0; - context->copy_length = 0; - if (nk_input_is_mouse_pressed(&ctx->input, NK_BUTTON_LEFT)) { - context->selection.active = nk_false; - context->selection.dragging = nk_false; - } else if (!ctx->input.mouse.buttons[NK_BUTTON_LEFT].down && !nk_input_is_mouse_released(&ctx->input, NK_BUTTON_LEFT)) { - context->selection.dragging = nk_false; - } - } - return ++context->widget_index; -} - -NK_INTERN nk_bool -nk_text_selection_widget_clipped(struct nk_context *ctx, const char *text, int len, - const struct nk_text_options *options, struct nk_rect bounds) -{ - struct nk_text_selection_context *context; - unsigned int widget; - int selected_begin; - int selected_end; - - if (!(options->flags & NK_TEXT_OPTION_SELECTABLE)) { - return nk_false; - } - - context = options->selection ? options->selection : nk_text_selection_panel_context(ctx); - widget = nk_text_selection_widget_begin(ctx, context); - if (nk_text_selection_widget_range(context, widget, len, &selected_begin, &selected_end) && nk_input_is_key_pressed(&ctx->input, NK_KEY_COPY) && ctx->clip.copy) { - nk_text_selection_copy_append(ctx, context, text + selected_begin, selected_end - selected_begin, bounds); - if (widget == NK_MAX(context->anchor_widget, context->cursor_widget)) { - nk_text_selection_copy_finish(ctx, context); - } - } - return nk_false; -} - -NK_INTERN void -nk_text_selection_keyboard(struct nk_context *ctx, const struct nk_text_shape *shape, struct nk_text_selection_context *context, unsigned int widget) -{ - struct nk_input *input = &ctx->input; - struct nk_text_selection *selection = &context->selection; - nk_bool shift; - - if (!selection->active || context->cursor_widget != widget || context->keyboard_frame == ctx->seq) { - return; - } - - shift = input->keyboard.keys[NK_KEY_SHIFT].down; - if (nk_input_is_key_pressed(input, NK_KEY_TEXT_SELECT_ALL)) { - context->keyboard_frame = ctx->seq; - context->anchor_widget = 1; - context->cursor_widget = context->widget_count; - selection->anchor = 0; - selection->cursor = NK_SINT_MAX; - selection->anchor_affinity = NK_TEXT_AFFINITY_LEADING; - selection->affinity = NK_TEXT_AFFINITY_TRAILING; - } else if (nk_input_is_key_pressed(input, NK_KEY_LEFT)) { - context->keyboard_frame = ctx->seq; - if (!shift && !nk_text_selection_context_empty(context)) { - nk_text_selection_context_collapse(context, shape, -1); - } else { - struct nk_text_cursor cursor; - cursor.source_offset = selection->cursor; - cursor.affinity = (enum nk_text_affinity)selection->affinity; - cursor = nk_text_shape_cursor_move(shape, cursor, -1); - - if (cursor.source_offset == selection->cursor && widget > 1) { - context->cursor_widget = widget - 1; - selection->cursor = NK_SINT_MAX; - selection->affinity = NK_TEXT_AFFINITY_TRAILING; - } else { - selection->cursor = cursor.source_offset; - selection->affinity = (unsigned char)cursor.affinity; - } - - if (!shift) { - context->anchor_widget = context->cursor_widget; - selection->anchor = selection->cursor; - selection->anchor_affinity = selection->affinity; - } - } - } else if (nk_input_is_key_pressed(input, NK_KEY_RIGHT)) { - context->keyboard_frame = ctx->seq; - if (!shift && !nk_text_selection_context_empty(context)) { - nk_text_selection_context_collapse(context, shape, 1); - } else { - struct nk_text_cursor cursor; - cursor.source_offset = selection->cursor; - cursor.affinity = (enum nk_text_affinity)selection->affinity; - cursor = nk_text_shape_cursor_move(shape, cursor, 1); - - if (cursor.source_offset == selection->cursor && widget < context->widget_count) { - context->cursor_widget = widget + 1; - selection->cursor = 0; - selection->affinity = NK_TEXT_AFFINITY_LEADING; - } else { - selection->cursor = cursor.source_offset; - selection->affinity = (unsigned char)cursor.affinity; - } - - if (!shift) { - context->anchor_widget = context->cursor_widget; - selection->anchor = selection->cursor; - selection->anchor_affinity = selection->affinity; - } - } - } else if (nk_input_is_key_pressed(input, NK_KEY_TEXT_WORD_LEFT)) { - int cursor = selection->cursor; - - context->keyboard_frame = ctx->seq; - selection->cursor = nk_text_shape_boundary_previous(shape, selection->cursor, NK_TEXT_BOUNDARY_WORD); - selection->affinity = selection->cursor ? NK_TEXT_AFFINITY_TRAILING : NK_TEXT_AFFINITY_LEADING; - if (selection->cursor == cursor && widget > 1) { - context->cursor_widget = widget - 1; - selection->cursor = NK_SINT_MAX; - selection->affinity = NK_TEXT_AFFINITY_TRAILING; - } - - if (!shift) { - context->anchor_widget = context->cursor_widget; - selection->anchor = selection->cursor; - selection->anchor_affinity = selection->affinity; - } - } else if (nk_input_is_key_pressed(input, NK_KEY_TEXT_WORD_RIGHT)) { - int cursor = selection->cursor; - context->keyboard_frame = ctx->seq; - selection->cursor = nk_text_shape_boundary_next(shape, selection->cursor, NK_TEXT_BOUNDARY_WORD); - selection->affinity = selection->cursor ? NK_TEXT_AFFINITY_TRAILING : NK_TEXT_AFFINITY_LEADING; - - if (selection->cursor == cursor && widget < context->widget_count) { - context->cursor_widget = widget + 1; - selection->cursor = 0; - selection->affinity = NK_TEXT_AFFINITY_LEADING; - } - - if (!shift) { - context->anchor_widget = context->cursor_widget; - selection->anchor = selection->cursor; - selection->anchor_affinity = selection->affinity; - } - } -} - -NK_INTERN nk_bool -nk_text_selection_panel_accepts_input(struct nk_context *ctx, enum nk_widget_layout_states widget_state) -{ - return widget_state != NK_WIDGET_INVALID && - widget_state != NK_WIDGET_DISABLED && - !(ctx->current->layout->flags & NK_WINDOW_ROM) && - !(ctx->current->layout->flags & NK_WINDOW_NO_INPUT) && - !ctx->current->widgets_disabled; -} - -NK_INTERN nk_bool -nk_text_selectable_widget(struct nk_context *ctx, const char *str, int len, nk_flags align, struct nk_color color, struct nk_text_selection_context *selection_context) -{ - struct nk_window *win; - struct nk_style *style; - struct nk_text_shape *shape; - struct nk_text_selection *selection; - struct nk_text text; - struct nk_rect bounds; - struct nk_rect label; - enum nk_widget_layout_states widget_state; - unsigned int widget; - unsigned int old_anchor_widget; - unsigned int old_cursor_widget; - nk_bool selected_widget; - int selected_begin = 0; - int selected_end = 0; - int old_anchor; - int old_cursor; - - widget = nk_text_selection_widget_begin(ctx, selection_context); - selection = &selection_context->selection; - old_anchor_widget = selection_context->anchor_widget; - old_cursor_widget = selection_context->cursor_widget; - old_anchor = selection->anchor; - old_cursor = selection->cursor; - - win = ctx->current; - style = &ctx->style; - widget_state = nk_widget(&bounds, ctx); - text.padding = style->text.padding; - text.background = style->window.background; - text.text = nk_rgb_factor(color, style->text.color_factor); - - shape = nk_text_shape_build_default(ctx, style->font, style->font_size, str, len); - label = nk_widget_text_layout(ctx, bounds, &text, align, (shape ? shape->advance.x : 0.0f) + 2 * text.padding.x); - - if (widget == selection_context->anchor_widget) { - selection->anchor = NK_CLAMP(0, selection->anchor, len); - if (shape && selection->anchor > 0 && selection->anchor < len) { - selection->anchor = nk_text_shape_boundary_previous(shape, selection->anchor + 1, NK_TEXT_BOUNDARY_GRAPHEME); - } - } - - if (widget == selection_context->cursor_widget) { - selection->cursor = NK_CLAMP(0, selection->cursor, len); - if (shape && selection->cursor > 0 && selection->cursor < len) { - selection->cursor = nk_text_shape_boundary_previous(shape, selection->cursor + 1, NK_TEXT_BOUNDARY_GRAPHEME); - } - } - - if (widget_state != NK_WIDGET_INVALID) { - struct nk_input *input = &ctx->input; - nk_bool pressed = nk_input_is_mouse_pressed(input, NK_BUTTON_LEFT); - nk_bool released = nk_input_is_mouse_released(input, NK_BUTTON_LEFT); - struct nk_vec2 position = released ? input->mouse.buttons[NK_BUTTON_LEFT].clicked_pos : input->mouse.pos; - nk_bool pressed_on_widget = pressed && nk_input_has_mouse_click_down_in_rect(input, NK_BUTTON_LEFT, bounds, nk_true); - nk_bool on_widget = NK_INBOX(position.x, position.y, bounds.x, bounds.y, bounds.w, bounds.h); - nk_bool panel_input = nk_text_selection_panel_accepts_input(ctx, widget_state); - - if (pressed_on_widget && panel_input && shape) { - struct nk_text_cursor cursor; - - cursor = nk_text_shape_hit_test(shape, input->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x - label.x); - selection->anchor = cursor.source_offset; - selection->cursor = cursor.source_offset; - selection->affinity = (unsigned char)cursor.affinity; - selection->anchor_affinity = (unsigned char)cursor.affinity; - selection->active = nk_true; - selection->dragging = nk_true; - selection_context->anchor_widget = widget; - selection_context->cursor_widget = widget; - } - - if (!pressed && selection->active && selection->dragging && panel_input && on_widget && (input->mouse.buttons[NK_BUTTON_LEFT].down || released) && shape) { - struct nk_text_cursor cursor; - - cursor = nk_text_shape_hit_test(shape, position.x - label.x); - selection_context->cursor_widget = widget; - selection->cursor = cursor.source_offset; - selection->affinity = (unsigned char)cursor.affinity; - - if (released) { - selection->dragging = nk_false; - } - } - - if (shape) { - nk_text_selection_keyboard(ctx, shape, selection_context, widget); - } - } - - selected_widget = nk_text_selection_widget_range(selection_context, widget, len, &selected_begin, &selected_end); - if (selected_widget && nk_input_is_key_pressed(&ctx->input, NK_KEY_COPY) && ctx->clip.copy) { - nk_text_selection_copy_append(ctx, selection_context, str + selected_begin, selected_end - selected_begin, bounds); - if (widget == NK_MAX(selection_context->anchor_widget, selection_context->cursor_widget)) { - nk_text_selection_copy_finish(ctx, selection_context); - } - } - - nk_draw_text(&win->buffer, label, str, len, style->font, text.background, text.text); - if (shape && selected_widget) { - if (selected_begin != selected_end) { - struct nk_text_selection_iterator iterator; - struct nk_text_selection_span span; - nk_text_selection_iterator_begin(&iterator, shape, selected_begin, selected_end); - while (nk_text_selection_iterator_next(&iterator, &span)) { - struct nk_rect selected = nk_rect(label.x + span.x, label.y, span.width, label.h); - struct nk_rect old_clip = win->buffer.clip; - struct nk_rect selected_clip; - - nk_fill_rect(&win->buffer, selected, 0, style->edit.selected_normal); - nk_unify(&selected_clip, &old_clip, selected.x, selected.y, selected.x + selected.w, selected.y + selected.h); - nk_push_scissor(&win->buffer, selected_clip); - nk_draw_text(&win->buffer, label, str, len, style->font, style->edit.selected_normal, style->edit.selected_text_normal); - nk_push_scissor(&win->buffer, old_clip); - } - } else if (nk_text_selection_context_empty(selection_context) && selection_context->cursor_widget == widget) { - struct nk_text_cursor cursor = nk_text_shape_cursor_at(shape, selection->cursor, (enum nk_text_affinity)selection->affinity); - nk_fill_rect(&win->buffer, nk_rect(label.x + cursor.x, label.y, 1.0f, label.h), 0, style->edit.cursor_normal); - } - } - return old_anchor_widget != selection_context->anchor_widget || - old_cursor_widget != selection_context->cursor_widget || - old_anchor != selection->anchor || old_cursor != selection->cursor; -} - -NK_INTERN int -nk_text_wrap_draw_end(const char *text, struct nk_text_wrap_line line) -{ - while (line.source_end > line.source_begin && (text[line.source_end - 1] == '\r' || text[line.source_end - 1] == '\n')) { - line.source_end -= 1; - } - return line.source_end; -} - -NK_INTERN nk_bool -nk_text_selectable_wrap_hit_test(struct nk_context *ctx, const struct nk_text_shape *shape, - const char *str, struct nk_rect bounds, struct nk_vec2 position, - struct nk_text_cursor *cursor) -{ - struct nk_style *style = &ctx->style; - struct nk_text_wrap_iterator iterator; - struct nk_text_wrap_line wrapped; - struct nk_rect line; - struct nk_rect target_bounds; - nk_bool found = nk_false; - float bottom; - - cursor->source_offset = 0; - cursor->affinity = NK_TEXT_AFFINITY_LEADING; - if (!shape->source_len) { - return nk_true; - } - - line.x = bounds.x + style->text.padding.x; - line.y = bounds.y + style->text.padding.y; - line.w = NK_MAX(1.0f, bounds.w - 2.0f * style->text.padding.x); - line.h = style->font_size + 2.0f * style->text.padding.y; - bottom = bounds.y + bounds.h - style->text.padding.y; - - nk_text_wrap_iterator_begin(&iterator, shape, line.w); - while (line.y + line.h <= bottom && nk_text_wrap_iterator_next(&iterator, &wrapped)) { - found = nk_true; - target_bounds = line; - if (position.y < line.y + line.h) { - break; - } - line.y += line.h; - } - - if (found) { - int draw_end; - struct nk_text_shape *line_shape; - - draw_end = nk_text_wrap_draw_end(str, wrapped); - line_shape = nk_text_shape_build_default(ctx, style->font, style->font_size, str + wrapped.source_begin, draw_end - wrapped.source_begin); - if (line_shape) { - struct nk_text_cursor line_cursor; - - line_cursor = nk_text_shape_hit_test(line_shape, position.x - target_bounds.x); - cursor->source_offset = wrapped.source_begin + line_cursor.source_offset; - cursor->affinity = line_cursor.affinity; - } - } - return found; -} - -NK_INTERN nk_bool -nk_text_shape_is_cached(struct nk_context *ctx, const struct nk_text_shape *shape, - const struct nk_user_font *font, float font_height, const char *text, int len) -{ - struct nk_text_request request; - struct nk_text_cache_entry *entry; - - NK_MEMSET(&request, 0, sizeof(request)); - request.source = text; - request.source_len = len; - request.font = font; - request.font_height = font_height; - entry = nk_text_cache_find(ctx, &request, nk_text_request_hash(&request)); - return entry && entry->shape == shape; -} - -NK_INTERN void -nk_text_selectable_wrap_draw(struct nk_context *ctx, const struct nk_text_shape *shape, - const char *str, struct nk_rect bounds, struct nk_color color, - struct nk_text_selection_context *selection_context, - nk_bool selected_widget, int selected_begin, int selected_end, - unsigned int widget, nk_bool shape_cached) -{ - struct nk_window *win = ctx->current; - struct nk_style *style = &ctx->style; - struct nk_text_selection *selection = &selection_context->selection; - struct nk_text_wrap_iterator iterator; - struct nk_text_wrap_line wrapped; - struct nk_rect line; - int source_len = shape->source_len; - float bottom; - - line.x = bounds.x + style->text.padding.x; - line.y = bounds.y + style->text.padding.y; - line.w = NK_MAX(1.0f, bounds.w - 2.0f * style->text.padding.x); - line.h = style->font_size + 2.0f * style->text.padding.y; - bottom = bounds.y + bounds.h - style->text.padding.y; - - nk_text_wrap_iterator_begin(&iterator, shape, line.w); - while (line.y + line.h <= bottom && nk_text_wrap_iterator_next(&iterator, &wrapped)) { - int draw_end; - int source_begin; - int line_len; - struct nk_text_shape *line_shape = 0; - - draw_end = nk_text_wrap_draw_end(str, wrapped); - source_begin = wrapped.source_begin; - line_len = draw_end - source_begin; - - nk_push_draw_text(&win->buffer, line, str + source_begin, line_len, style->font, style->font_size, style->window.background, color); - - if (selected_widget && shape_cached) { - line_shape = nk_text_shape_build_default(ctx, style->font, style->font_size, str + source_begin, line_len); - } - - if (line_shape) { - int line_begin = NK_CLAMP(source_begin, selected_begin, draw_end) - source_begin; - int line_end = NK_CLAMP(source_begin, selected_end, draw_end) - source_begin; - if (line_begin != line_end) { - struct nk_text_selection_iterator selection_iterator; - struct nk_text_selection_span span; - nk_text_selection_iterator_begin(&selection_iterator, line_shape, line_begin, line_end); - while (nk_text_selection_iterator_next(&selection_iterator, &span)) { - struct nk_rect selected; - struct nk_rect old_clip; - struct nk_rect selected_clip; - - selected = nk_rect(line.x + span.x, line.y, span.width, line.h); - old_clip = win->buffer.clip; - - nk_fill_rect(&win->buffer, selected, 0, style->edit.selected_normal); - nk_unify(&selected_clip, &old_clip, selected.x, selected.y, selected.x + selected.w, selected.y + selected.h); - nk_push_scissor(&win->buffer, selected_clip); - nk_draw_text(&win->buffer, line, str + source_begin, line_len, style->font, style->edit.selected_normal, style->edit.selected_text_normal); - nk_push_scissor(&win->buffer, old_clip); - } - } - } - - if (line_shape && nk_text_selection_context_empty(selection_context) && - selection_context->cursor_widget == widget && - selection->cursor >= source_begin && - (selection->cursor < wrapped.source_end || wrapped.source_end == source_len || - (selection->cursor == wrapped.source_end && selection->affinity == NK_TEXT_AFFINITY_TRAILING && - !(wrapped.break_flags & NK_TEXT_BOUNDARY_LINE_HARD)))) { - struct nk_text_cursor cursor; - - cursor = nk_text_shape_cursor_at(line_shape, NK_CLAMP(0, selection->cursor - source_begin, line_len), (enum nk_text_affinity)selection->affinity); - nk_fill_rect(&win->buffer, nk_rect(line.x + cursor.x, line.y, 1.0f, line.h), 0, style->edit.cursor_normal); - } - line.y += line.h; - } -} - -NK_INTERN nk_bool -nk_text_selectable_wrap_widget(struct nk_context *ctx, const char *str, int len, struct nk_color color, - struct nk_text_selection_context *selection_context) -{ - struct nk_style *style = &ctx->style; - struct nk_text_shape *shape; - struct nk_text_selection *selection = &selection_context->selection; - struct nk_rect bounds; - enum nk_widget_layout_states widget_state; - unsigned int widget; - unsigned int old_anchor_widget; - unsigned int old_cursor_widget; - nk_bool selected_widget; - nk_bool shape_invalidated = nk_false; - nk_bool shape_cached; - int selected_begin = 0; - int selected_end = 0; - int old_anchor; - int old_cursor; - - widget = nk_text_selection_widget_begin(ctx, selection_context); - old_anchor_widget = selection_context->anchor_widget; - old_cursor_widget = selection_context->cursor_widget; - old_anchor = selection->anchor; - old_cursor = selection->cursor; - widget_state = nk_widget(&bounds, ctx); - shape = nk_text_shape_build_default(ctx, style->font, style->font_size, str, len); - shape_cached = shape && nk_text_shape_is_cached(ctx, shape, style->font, style->font_size, str, len); - - if (widget == selection_context->anchor_widget) { - selection->anchor = NK_CLAMP(0, selection->anchor, len); - if (shape && selection->anchor > 0 && selection->anchor < len) { - selection->anchor = nk_text_shape_boundary_previous(shape, selection->anchor + 1, NK_TEXT_BOUNDARY_GRAPHEME); - } - } - - if (widget == selection_context->cursor_widget) { - selection->cursor = NK_CLAMP(0, selection->cursor, len); - if (shape && selection->cursor > 0 && selection->cursor < len) { - selection->cursor = nk_text_shape_boundary_previous(shape, selection->cursor + 1, NK_TEXT_BOUNDARY_GRAPHEME); - } - } - - if (widget_state != NK_WIDGET_INVALID && shape) { - struct nk_input *input = &ctx->input; - nk_bool pressed = nk_input_is_mouse_pressed(input, NK_BUTTON_LEFT); - nk_bool released = nk_input_is_mouse_released(input, NK_BUTTON_LEFT); - struct nk_vec2 position = released ? input->mouse.buttons[NK_BUTTON_LEFT].clicked_pos : input->mouse.pos; - nk_bool pressed_on_widget = pressed && nk_input_has_mouse_click_down_in_rect(input, NK_BUTTON_LEFT, bounds, nk_true); - nk_bool on_widget = NK_INBOX(position.x, position.y, bounds.x, bounds.y, bounds.w, bounds.h); - nk_bool panel_input = nk_text_selection_panel_accepts_input(ctx, widget_state); - - if (pressed_on_widget && panel_input) { - struct nk_text_cursor cursor; - nk_text_selectable_wrap_hit_test(ctx, shape, str, bounds, input->mouse.buttons[NK_BUTTON_LEFT].clicked_pos, &cursor); - shape_invalidated = nk_true; - selection->anchor = cursor.source_offset; - selection->cursor = cursor.source_offset; - selection->affinity = (unsigned char)cursor.affinity; - selection->anchor_affinity = (unsigned char)cursor.affinity; - selection->active = nk_true; - selection->dragging = nk_true; - selection_context->anchor_widget = widget; - selection_context->cursor_widget = widget; - } - - if (!pressed && selection->active && selection->dragging && panel_input && on_widget && (input->mouse.buttons[NK_BUTTON_LEFT].down || released)) { - struct nk_text_cursor cursor; - - nk_text_selectable_wrap_hit_test(ctx, shape, str, bounds, position, &cursor); - shape_invalidated = nk_true; - selection_context->cursor_widget = widget; - selection->cursor = cursor.source_offset; - selection->affinity = (unsigned char)cursor.affinity; - if (released) { - selection->dragging = nk_false; - } - } - - if (shape_invalidated) { - shape = nk_text_shape_build_default(ctx, style->font, style->font_size, str, len); - shape_cached = shape && nk_text_shape_is_cached(ctx, shape, style->font, style->font_size, str, len); - } - - if (shape) { - nk_text_selection_keyboard(ctx, shape, selection_context, widget); - } - } - - selected_widget = nk_text_selection_widget_range(selection_context, widget, len, &selected_begin, &selected_end); - if (selected_widget && nk_input_is_key_pressed(&ctx->input, NK_KEY_COPY) && ctx->clip.copy) { - nk_text_selection_copy_append(ctx, selection_context, str + selected_begin, selected_end - selected_begin, bounds); - if (widget == NK_MAX(selection_context->anchor_widget, selection_context->cursor_widget)) { - nk_text_selection_copy_finish(ctx, selection_context); - } - } - - if (shape && widget_state != NK_WIDGET_INVALID) { - nk_text_selectable_wrap_draw(ctx, shape, str, bounds, nk_rgb_factor(color, style->text.color_factor), - selection_context, selected_widget, selected_begin, selected_end, widget, - shape_cached); - } - return old_anchor_widget != selection_context->anchor_widget || - old_cursor_widget != selection_context->cursor_widget || - old_anchor != selection->anchor || old_cursor != selection->cursor; -} - -NK_INTERN void -nk_text_layout_auto_height(struct nk_context *ctx, const char *str, int len) -{ - struct nk_panel *layout = ctx->current->layout; - struct nk_text_wrap_iterator iterator; - struct nk_text_wrap_line line; - struct nk_text_shape *shape; - struct nk_vec2 padding = ctx->style.text.padding; - float width; - float line_height; - int line_count = 0; - - width = nk_layout_row_calculate_usable_space(&ctx->style, layout->type, layout->bounds.w, 1); - width = NK_MAX(1.0f, width - 2.0f * padding.x); - - shape = nk_text_shape_build_default(ctx, ctx->style.font, ctx->style.font_size, str, len); - if (shape) { - nk_text_wrap_iterator_begin(&iterator, shape, width); - while (nk_text_wrap_iterator_next(&iterator, &line)) { - line_count += 1; - } - } - - line_count = NK_MAX(1, line_count); - line_height = ctx->style.font_size + 2.0f * padding.y; - nk_layout_row_dynamic(ctx, line_height * (float)line_count + 2.0f * padding.y, 1); -} - -NK_API nk_bool -nk_text_ex(struct nk_context *ctx, const char *str, int len, const struct nk_text_options *options) -{ - struct nk_text_selection_context *selection; - - NK_ASSERT(ctx); - NK_ASSERT(options); - if (!ctx || !options) { - return nk_false; - } - - if ((options->flags & (NK_TEXT_OPTION_WRAP | NK_TEXT_OPTION_AUTO_HEIGHT)) == - (NK_TEXT_OPTION_WRAP | NK_TEXT_OPTION_AUTO_HEIGHT)) { - nk_text_layout_auto_height(ctx, str, len); - } - - if (options->flags & NK_TEXT_OPTION_SELECTABLE) { - selection = options->selection ? options->selection : nk_text_selection_panel_context(ctx); - if (options->flags & NK_TEXT_OPTION_WRAP) { - return nk_text_selectable_wrap_widget(ctx, str, len, options->color, selection); - } - return nk_text_selectable_widget(ctx, str, len, options->alignment, options->color, selection); - } - - if (options->flags & NK_TEXT_OPTION_WRAP) { - nk_text_wrap_widget_colored(ctx, str, len, options->color); - } else { - nk_text_widget_colored(ctx, str, len, options->alignment, options->color); - } - return nk_false; -} - -#ifdef NK_INCLUDE_STANDARD_VARARGS -NK_API nk_bool -nk_textfv_ex(struct nk_context *ctx, const struct nk_text_options *options, const char *fmt, va_list args) -{ - char buf[256]; - nk_strfmt(buf, NK_LEN(buf), fmt, args); - return nk_text_ex(ctx, buf, nk_strlen(buf), options); -} - -NK_API nk_bool -nk_textf_ex(struct nk_context *ctx, const struct nk_text_options *options, const char *fmt, ...) -{ - nk_bool result; - va_list args; - va_start(args, fmt); - result = nk_textfv_ex(ctx, options, fmt, args); - va_end(args); - return result; -} -#endif - -NK_API nk_bool -nk_text_selectable_ctx(struct nk_context *ctx, const char *str, int len, nk_flags align, - struct nk_text_selection_context *selection) -{ - struct nk_text_options options; - - NK_MEMSET(&options, 0, sizeof(options)); - options.alignment = align; - options.flags = NK_TEXT_OPTION_SELECTABLE; - options.color = ctx->style.text.color; - options.selection = selection; - return nk_text_ex(ctx, str, len, &options); -} -NK_API nk_bool -nk_text_selectable_colored_ctx(struct nk_context *ctx, const char *str, int len, nk_flags align, struct nk_color color, - struct nk_text_selection_context *selection) -{ - struct nk_text_options options; - - NK_MEMSET(&options, 0, sizeof(options)); - options.alignment = align; - options.flags = NK_TEXT_OPTION_SELECTABLE; - options.color = color; - options.selection = selection; - return nk_text_ex(ctx, str, len, &options); -} -NK_API nk_bool -nk_label_selectable_ctx(struct nk_context *ctx, const char *str, nk_flags align, - struct nk_text_selection_context *selection) -{ - return nk_text_selectable_ctx(ctx, str, nk_strlen(str), align, selection); -} -NK_API nk_bool -nk_label_selectable_colored_ctx(struct nk_context *ctx, const char *str, nk_flags align, struct nk_color color, - struct nk_text_selection_context *selection) -{ - return nk_text_selectable_colored_ctx(ctx, str, nk_strlen(str), align, color, selection); -} -NK_API nk_bool -nk_text_selectable(struct nk_context *ctx, const char *str, int len, nk_flags align) -{ - return nk_text_selectable_ctx(ctx, str, len, align, NULL); -} -NK_API nk_bool -nk_text_selectable_colored(struct nk_context *ctx, const char *str, int len, nk_flags align, struct nk_color color) -{ - return nk_text_selectable_colored_ctx(ctx, str, len, align, color, NULL); -} -NK_API nk_bool -nk_label_selectable(struct nk_context *ctx, const char *str, nk_flags align) -{ - return nk_text_selectable(ctx, str, nk_strlen(str), align); -} -NK_API nk_bool -nk_label_selectable_colored(struct nk_context *ctx, const char *str, nk_flags align, struct nk_color color) -{ - return nk_text_selectable_colored(ctx, str, nk_strlen(str), align, color); -} -NK_API nk_bool -nk_text_selectable_wrap_ctx(struct nk_context *ctx, const char *str, int len, struct nk_text_selection_context *selection) -{ - struct nk_text_options options; - - NK_MEMSET(&options, 0, sizeof(options)); - options.alignment = NK_TEXT_LEFT; - options.flags = NK_TEXT_OPTION_WRAP | NK_TEXT_OPTION_SELECTABLE; - options.color = ctx->style.text.color; - options.selection = selection; - return nk_text_ex(ctx, str, len, &options); -} -NK_API nk_bool -nk_text_selectable_wrap_colored_ctx(struct nk_context *ctx, const char *str, int len, struct nk_color color, struct nk_text_selection_context *selection) -{ - struct nk_text_options options; - - NK_MEMSET(&options, 0, sizeof(options)); - options.alignment = NK_TEXT_LEFT; - options.flags = NK_TEXT_OPTION_WRAP | NK_TEXT_OPTION_SELECTABLE; - options.color = color; - options.selection = selection; - return nk_text_ex(ctx, str, len, &options); -} -NK_API nk_bool -nk_label_selectable_wrap_ctx(struct nk_context *ctx, const char *str, struct nk_text_selection_context *selection) -{ - return nk_text_selectable_wrap_ctx(ctx, str, nk_strlen(str), selection); -} -NK_API nk_bool -nk_label_selectable_colored_wrap_ctx(struct nk_context *ctx, const char *str, struct nk_color color, struct nk_text_selection_context *selection) -{ - return nk_text_selectable_wrap_colored_ctx(ctx, str, nk_strlen(str), color, selection); -} -NK_API nk_bool -nk_text_selectable_wrap(struct nk_context *ctx, const char *str, int len) -{ - return nk_text_selectable_wrap_ctx(ctx, str, len, NULL); -} -NK_API nk_bool -nk_text_selectable_wrap_colored(struct nk_context *ctx, const char *str, int len, struct nk_color color) -{ - return nk_text_selectable_wrap_colored_ctx(ctx, str, len, color, NULL); -} -NK_API nk_bool -nk_label_selectable_wrap(struct nk_context *ctx, const char *str) -{ - return nk_text_selectable_wrap(ctx, str, nk_strlen(str)); -} -NK_API nk_bool -nk_label_selectable_colored_wrap(struct nk_context *ctx, const char *str, struct nk_color color) -{ - return nk_text_selectable_wrap_colored(ctx, str, nk_strlen(str), color); -} -#ifdef NK_INCLUDE_STANDARD_VARARGS -NK_API nk_bool -nk_labelfv_selectable_ctx(struct nk_context *ctx, nk_flags align, struct nk_text_selection_context *selection, const char *fmt, va_list args) -{ - char buf[256]; - nk_strfmt(buf, NK_LEN(buf), fmt, args); - return nk_label_selectable_ctx(ctx, buf, align, selection); -} -NK_API nk_bool -nk_labelfv_selectable_colored_ctx(struct nk_context *ctx, nk_flags align, struct nk_color color, struct nk_text_selection_context *selection, const char *fmt, va_list args) -{ - char buf[256]; - nk_strfmt(buf, NK_LEN(buf), fmt, args); - return nk_label_selectable_colored_ctx(ctx, buf, align, color, selection); -} -NK_API nk_bool -nk_labelfv_selectable(struct nk_context *ctx, nk_flags align, const char *fmt, va_list args) -{ - char buf[256]; - nk_strfmt(buf, NK_LEN(buf), fmt, args); - return nk_label_selectable(ctx, buf, align); -} -NK_API nk_bool -nk_labelfv_selectable_colored(struct nk_context *ctx, nk_flags align, struct nk_color color, const char *fmt, va_list args) -{ - char buf[256]; - nk_strfmt(buf, NK_LEN(buf), fmt, args); - return nk_label_selectable_colored(ctx, buf, align, color); -} -NK_API nk_bool -nk_labelf_selectable_ctx(struct nk_context *ctx, nk_flags align, struct nk_text_selection_context *selection, const char *fmt, ...) -{ - nk_bool result; - va_list args; - va_start(args, fmt); - result = nk_labelfv_selectable_ctx(ctx, align, selection, fmt, args); - va_end(args); - return result; -} -NK_API nk_bool -nk_labelf_selectable_colored_ctx(struct nk_context *ctx, nk_flags align, struct nk_color color, struct nk_text_selection_context *selection, const char *fmt, ...) -{ - nk_bool result; - va_list args; - va_start(args, fmt); - result = nk_labelfv_selectable_colored_ctx(ctx, align, color, selection, fmt, args); - va_end(args); - return result; -} -NK_API nk_bool -nk_labelf_selectable(struct nk_context *ctx, nk_flags align, const char *fmt, ...) -{ - nk_bool result; - va_list args; - va_start(args, fmt); - result = nk_labelfv_selectable(ctx, align, fmt, args); - va_end(args); - return result; -} -NK_API nk_bool -nk_labelf_selectable_colored(struct nk_context *ctx, nk_flags align, struct nk_color color, const char *fmt, ...) -{ - nk_bool result; - va_list args; - va_start(args, fmt); - result = nk_labelfv_selectable_colored(ctx, align, color, fmt, args); - va_end(args); - return result; -} -NK_API nk_bool -nk_textfv_selectable_ctx(struct nk_context *ctx, nk_flags align, struct nk_text_selection_context *selection, const char *fmt, va_list args) -{ - return nk_labelfv_selectable_ctx(ctx, align, selection, fmt, args); -} -NK_API nk_bool -nk_textfv_selectable_colored_ctx(struct nk_context *ctx, nk_flags align, struct nk_color color, struct nk_text_selection_context *selection, const char *fmt, va_list args) -{ - return nk_labelfv_selectable_colored_ctx(ctx, align, color, selection, fmt, args); -} -NK_API nk_bool -nk_textfv_selectable(struct nk_context *ctx, nk_flags align, const char *fmt, va_list args) -{ - return nk_labelfv_selectable(ctx, align, fmt, args); -} -NK_API nk_bool -nk_textfv_selectable_colored(struct nk_context *ctx, nk_flags align, struct nk_color color, const char *fmt, va_list args) -{ - return nk_labelfv_selectable_colored(ctx, align, color, fmt, args); -} -NK_API nk_bool -nk_textf_selectable_ctx(struct nk_context *ctx, nk_flags align, struct nk_text_selection_context *selection, - const char *fmt, ...) -{ - nk_bool result; - va_list args; - va_start(args, fmt); - result = nk_textfv_selectable_ctx(ctx, align, selection, fmt, args); - va_end(args); - return result; -} -NK_API nk_bool -nk_textf_selectable_colored_ctx(struct nk_context *ctx, nk_flags align, struct nk_color color, struct nk_text_selection_context *selection, const char *fmt, ...) -{ - nk_bool result; - va_list args; - va_start(args, fmt); - result = nk_textfv_selectable_colored_ctx(ctx, align, color, selection, fmt, args); - va_end(args); - return result; -} -NK_API nk_bool -nk_textf_selectable(struct nk_context *ctx, nk_flags align, const char *fmt, ...) -{ - nk_bool result; - va_list args; - va_start(args, fmt); - result = nk_textfv_selectable(ctx, align, fmt, args); - va_end(args); - return result; -} -NK_API nk_bool -nk_textf_selectable_colored(struct nk_context *ctx, nk_flags align, struct nk_color color, const char *fmt, ...) -{ - nk_bool result; - va_list args; - va_start(args, fmt); - result = nk_textfv_selectable_colored(ctx, align, color, fmt, args); - va_end(args); - return result; -} -NK_API nk_bool -nk_labelfv_selectable_wrap_ctx(struct nk_context *ctx, struct nk_text_selection_context *selection, const char *fmt, va_list args) -{ - char buf[256]; - nk_strfmt(buf, NK_LEN(buf), fmt, args); - return nk_label_selectable_wrap_ctx(ctx, buf, selection); -} -NK_API nk_bool -nk_labelfv_selectable_colored_wrap_ctx(struct nk_context *ctx, struct nk_color color, struct nk_text_selection_context *selection, const char *fmt, va_list args) -{ - char buf[256]; - nk_strfmt(buf, NK_LEN(buf), fmt, args); - return nk_label_selectable_colored_wrap_ctx(ctx, buf, color, selection); -} -NK_API nk_bool -nk_labelfv_selectable_wrap(struct nk_context *ctx, const char *fmt, va_list args) -{ - char buf[256]; - nk_strfmt(buf, NK_LEN(buf), fmt, args); - return nk_label_selectable_wrap(ctx, buf); -} -NK_API nk_bool -nk_labelfv_selectable_colored_wrap(struct nk_context *ctx, struct nk_color color, const char *fmt, va_list args) -{ - char buf[256]; - nk_strfmt(buf, NK_LEN(buf), fmt, args); - return nk_label_selectable_colored_wrap(ctx, buf, color); -} -NK_API nk_bool -nk_labelf_selectable_wrap_ctx(struct nk_context *ctx, struct nk_text_selection_context *selection, const char *fmt, ...) -{ - nk_bool result; - va_list args; - va_start(args, fmt); - result = nk_labelfv_selectable_wrap_ctx(ctx, selection, fmt, args); - va_end(args); - return result; -} -NK_API nk_bool -nk_labelf_selectable_colored_wrap_ctx(struct nk_context *ctx, struct nk_color color, struct nk_text_selection_context *selection, const char *fmt, ...) -{ - nk_bool result; - va_list args; - va_start(args, fmt); - result = nk_labelfv_selectable_colored_wrap_ctx(ctx, color, selection, fmt, args); - va_end(args); - return result; -} -NK_API nk_bool -nk_labelf_selectable_wrap(struct nk_context *ctx, const char *fmt, ...) -{ - nk_bool result; - va_list args; - va_start(args, fmt); - result = nk_labelfv_selectable_wrap(ctx, fmt, args); - va_end(args); - return result; -} -NK_API nk_bool -nk_labelf_selectable_colored_wrap(struct nk_context *ctx, struct nk_color color, const char *fmt, ...) -{ - nk_bool result; - va_list args; - va_start(args, fmt); - result = nk_labelfv_selectable_colored_wrap(ctx, color, fmt, args); - va_end(args); - return result; -} -NK_API nk_bool -nk_textfv_selectable_wrap_ctx(struct nk_context *ctx, struct nk_text_selection_context *selection, const char *fmt, va_list args) -{ - return nk_labelfv_selectable_wrap_ctx(ctx, selection, fmt, args); -} -NK_API nk_bool -nk_textfv_selectable_wrap_colored_ctx(struct nk_context *ctx, struct nk_color color, struct nk_text_selection_context *selection, const char *fmt, va_list args) -{ - return nk_labelfv_selectable_colored_wrap_ctx(ctx, color, selection, fmt, args); -} -NK_API nk_bool -nk_textfv_selectable_wrap(struct nk_context *ctx, const char *fmt, va_list args) -{ - return nk_labelfv_selectable_wrap(ctx, fmt, args); -} -NK_API nk_bool -nk_textfv_selectable_wrap_colored(struct nk_context *ctx, struct nk_color color, const char *fmt, va_list args) -{ - return nk_labelfv_selectable_colored_wrap(ctx, color, fmt, args); -} -NK_API nk_bool -nk_textf_selectable_wrap_ctx(struct nk_context *ctx, struct nk_text_selection_context *selection, const char *fmt, ...) -{ - nk_bool result; - va_list args; - va_start(args, fmt); - result = nk_textfv_selectable_wrap_ctx(ctx, selection, fmt, args); - va_end(args); - return result; -} -NK_API nk_bool -nk_textf_selectable_wrap_colored_ctx(struct nk_context *ctx, struct nk_color color, struct nk_text_selection_context *selection, const char *fmt, ...) -{ - nk_bool result; - va_list args; - va_start(args, fmt); - result = nk_textfv_selectable_wrap_colored_ctx(ctx, color, selection, fmt, args); - va_end(args); - return result; -} -NK_API nk_bool -nk_textf_selectable_wrap(struct nk_context *ctx, const char *fmt, ...) -{ - nk_bool result; - va_list args; - va_start(args, fmt); - result = nk_textfv_selectable_wrap(ctx, fmt, args); - va_end(args); - return result; -} -NK_API nk_bool -nk_textf_selectable_wrap_colored(struct nk_context *ctx, struct nk_color color, const char *fmt, ...) -{ - nk_bool result; - va_list args; - va_start(args, fmt); - result = nk_textfv_selectable_wrap_colored(ctx, color, fmt, args); - va_end(args); - return result; -} -#endif - -/* =============================================================== - * - * IMAGE - * - * ===============================================================*/ -NK_API nk_handle -nk_handle_ptr(void *ptr) -{ - nk_handle handle = {0}; - handle.ptr = ptr; - return handle; -} -NK_API nk_handle -nk_handle_id(int id) -{ - nk_handle handle; - nk_zero_struct(handle); - handle.id = id; - return handle; -} -NK_API struct nk_image -nk_subimage_ptr(void *ptr, nk_ushort w, nk_ushort h, struct nk_rect r) -{ - struct nk_image s; - nk_zero(&s, sizeof(s)); - s.handle.ptr = ptr; - s.w = w; - s.h = h; - s.region[0] = (nk_ushort)r.x; - s.region[1] = (nk_ushort)r.y; - s.region[2] = (nk_ushort)r.w; - s.region[3] = (nk_ushort)r.h; - return s; -} -NK_API struct nk_image -nk_subimage_id(int id, nk_ushort w, nk_ushort h, struct nk_rect r) -{ - struct nk_image s; - nk_zero(&s, sizeof(s)); - s.handle.id = id; - s.w = w; - s.h = h; - s.region[0] = (nk_ushort)r.x; - s.region[1] = (nk_ushort)r.y; - s.region[2] = (nk_ushort)r.w; - s.region[3] = (nk_ushort)r.h; - return s; -} -NK_API struct nk_image -nk_subimage_handle(nk_handle handle, nk_ushort w, nk_ushort h, struct nk_rect r) -{ - struct nk_image s; - nk_zero(&s, sizeof(s)); - s.handle = handle; - s.w = w; - s.h = h; - s.region[0] = (nk_ushort)r.x; - s.region[1] = (nk_ushort)r.y; - s.region[2] = (nk_ushort)r.w; - s.region[3] = (nk_ushort)r.h; - return s; -} -NK_API struct nk_image -nk_image_handle(nk_handle handle) -{ - struct nk_image s; - nk_zero(&s, sizeof(s)); - s.handle = handle; - s.w = 0; - s.h = 0; - s.region[0] = 0; - s.region[1] = 0; - s.region[2] = 0; - s.region[3] = 0; - return s; -} -NK_API struct nk_image -nk_image_ptr(void *ptr) -{ - struct nk_image s; - nk_zero(&s, sizeof(s)); - NK_ASSERT(ptr); - s.handle.ptr = ptr; - s.w = 0; - s.h = 0; - s.region[0] = 0; - s.region[1] = 0; - s.region[2] = 0; - s.region[3] = 0; - return s; -} -NK_API struct nk_image -nk_image_id(int id) -{ - struct nk_image s; - nk_zero(&s, sizeof(s)); - s.handle.id = id; - s.w = 0; - s.h = 0; - s.region[0] = 0; - s.region[1] = 0; - s.region[2] = 0; - s.region[3] = 0; - return s; -} -NK_API nk_bool -nk_image_is_subimage(const struct nk_image *img) -{ - NK_ASSERT(img); - return !(img->w == 0 && img->h == 0); -} -NK_API void -nk_image(struct nk_context *ctx, struct nk_image img) -{ - struct nk_window *win; - struct nk_rect bounds; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - win = ctx->current; - if (!nk_widget(&bounds, ctx)) { - return; - } - nk_draw_image(&win->buffer, bounds, &img, nk_white); -} -NK_API void -nk_image_color(struct nk_context *ctx, struct nk_image img, struct nk_color col) -{ - struct nk_window *win; - struct nk_rect bounds; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - win = ctx->current; - if (!nk_widget(&bounds, ctx)) { - return; - } - nk_draw_image(&win->buffer, bounds, &img, col); -} - -/* =============================================================== - * - * 9-SLICE - * - * ===============================================================*/ -NK_API struct nk_nine_slice -nk_sub9slice_ptr(void *ptr, nk_ushort w, nk_ushort h, struct nk_rect rgn, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b) -{ - struct nk_nine_slice s; - struct nk_image *i = &s.img; - nk_zero(&s, sizeof(s)); - i->handle.ptr = ptr; - i->w = w; - i->h = h; - i->region[0] = (nk_ushort)rgn.x; - i->region[1] = (nk_ushort)rgn.y; - i->region[2] = (nk_ushort)rgn.w; - i->region[3] = (nk_ushort)rgn.h; - s.l = l; - s.t = t; - s.r = r; - s.b = b; - return s; -} -NK_API struct nk_nine_slice -nk_sub9slice_id(int id, nk_ushort w, nk_ushort h, struct nk_rect rgn, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b) -{ - struct nk_nine_slice s; - struct nk_image *i = &s.img; - nk_zero(&s, sizeof(s)); - i->handle.id = id; - i->w = w; - i->h = h; - i->region[0] = (nk_ushort)rgn.x; - i->region[1] = (nk_ushort)rgn.y; - i->region[2] = (nk_ushort)rgn.w; - i->region[3] = (nk_ushort)rgn.h; - s.l = l; - s.t = t; - s.r = r; - s.b = b; - return s; -} -NK_API struct nk_nine_slice -nk_sub9slice_handle(nk_handle handle, nk_ushort w, nk_ushort h, struct nk_rect rgn, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b) -{ - struct nk_nine_slice s; - struct nk_image *i = &s.img; - nk_zero(&s, sizeof(s)); - i->handle = handle; - i->w = w; - i->h = h; - i->region[0] = (nk_ushort)rgn.x; - i->region[1] = (nk_ushort)rgn.y; - i->region[2] = (nk_ushort)rgn.w; - i->region[3] = (nk_ushort)rgn.h; - s.l = l; - s.t = t; - s.r = r; - s.b = b; - return s; -} -NK_API struct nk_nine_slice -nk_nine_slice_handle(nk_handle handle, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b) -{ - struct nk_nine_slice s; - struct nk_image *i = &s.img; - nk_zero(&s, sizeof(s)); - i->handle = handle; - i->w = 0; - i->h = 0; - i->region[0] = 0; - i->region[1] = 0; - i->region[2] = 0; - i->region[3] = 0; - s.l = l; - s.t = t; - s.r = r; - s.b = b; - return s; -} -NK_API struct nk_nine_slice -nk_nine_slice_ptr(void *ptr, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b) -{ - struct nk_nine_slice s; - struct nk_image *i = &s.img; - nk_zero(&s, sizeof(s)); - NK_ASSERT(ptr); - i->handle.ptr = ptr; - i->w = 0; - i->h = 0; - i->region[0] = 0; - i->region[1] = 0; - i->region[2] = 0; - i->region[3] = 0; - s.l = l; - s.t = t; - s.r = r; - s.b = b; - return s; -} -NK_API struct nk_nine_slice -nk_nine_slice_id(int id, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b) -{ - struct nk_nine_slice s; - struct nk_image *i = &s.img; - nk_zero(&s, sizeof(s)); - i->handle.id = id; - i->w = 0; - i->h = 0; - i->region[0] = 0; - i->region[1] = 0; - i->region[2] = 0; - i->region[3] = 0; - s.l = l; - s.t = t; - s.r = r; - s.b = b; - return s; -} -NK_API int -nk_nine_slice_is_sub9slice(const struct nk_nine_slice *slice) -{ - NK_ASSERT(slice); - return !(slice->img.w == 0 && slice->img.h == 0); -} - -/* ============================================================== - * - * BUTTON - * - * ===============================================================*/ -NK_LIB void -nk_draw_symbol(struct nk_command_buffer *out, - enum nk_symbol_type type, - struct nk_rect content, - struct nk_color background, - struct nk_color foreground, - float border_width, - const struct nk_user_font *font) -{ - switch (type) { - case NK_SYMBOL_X: - case NK_SYMBOL_UNDERSCORE: - case NK_SYMBOL_PLUS: - case NK_SYMBOL_MINUS: { - /* single character text symbol */ - const char *X = (type == NK_SYMBOL_X) ? "X" : (type == NK_SYMBOL_UNDERSCORE) ? "_" : (type == NK_SYMBOL_PLUS) ? "+" : "-"; - - struct nk_text text; - text.padding = nk_vec2(0, 0); - text.background = background; - text.text = foreground; - nk_widget_text(out, content, X, 1, &text, NK_TEXT_CENTERED, font); - } break; - case NK_SYMBOL_CIRCLE_SOLID: - case NK_SYMBOL_CIRCLE_OUTLINE: - case NK_SYMBOL_RECT_SOLID: - case NK_SYMBOL_RECT_OUTLINE: { - /* simple empty/filled shapes */ - if (type == NK_SYMBOL_RECT_SOLID || type == NK_SYMBOL_RECT_OUTLINE) { - nk_fill_rect(out, content, 0, foreground); - if (type == NK_SYMBOL_RECT_OUTLINE) { - nk_fill_rect(out, nk_shrink_rect(content, border_width), 0, background); - } - } else { - nk_fill_circle(out, content, foreground); - if (type == NK_SYMBOL_CIRCLE_OUTLINE) { - nk_fill_circle(out, nk_shrink_rect(content, 1), background); - } - } - } break; - case NK_SYMBOL_TRIANGLE_UP: - case NK_SYMBOL_TRIANGLE_DOWN: - case NK_SYMBOL_TRIANGLE_LEFT: - case NK_SYMBOL_TRIANGLE_RIGHT: { - enum nk_heading heading; - struct nk_vec2 points[3]; - heading = (type == NK_SYMBOL_TRIANGLE_RIGHT) ? NK_RIGHT : (type == NK_SYMBOL_TRIANGLE_LEFT) ? NK_LEFT : (type == NK_SYMBOL_TRIANGLE_UP) ? NK_UP : NK_DOWN; - nk_triangle_from_direction(points, content, 0, 0, heading); - nk_fill_triangle(out, points[0].x, points[0].y, points[1].x, points[1].y, points[2].x, points[2].y, foreground); - } break; - case NK_SYMBOL_TRIANGLE_UP_OUTLINE: - case NK_SYMBOL_TRIANGLE_DOWN_OUTLINE: - case NK_SYMBOL_TRIANGLE_LEFT_OUTLINE: - case NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE: { - enum nk_heading heading; - struct nk_vec2 points[3]; - heading = (type == NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE) ? NK_RIGHT - : (type == NK_SYMBOL_TRIANGLE_LEFT_OUTLINE) ? NK_LEFT - : (type == NK_SYMBOL_TRIANGLE_UP_OUTLINE) ? NK_UP - : NK_DOWN; - nk_triangle_from_direction(points, content, 0, 0, heading); - nk_stroke_triangle(out, points[0].x, points[0].y, points[1].x, points[1].y, points[2].x, points[2].y, border_width, foreground); - } break; - default: - case NK_SYMBOL_NONE: - case NK_SYMBOL_MAX: - break; - } -} -NK_LIB nk_bool -nk_button_behavior(nk_flags *state, struct nk_rect r, const struct nk_input *i, enum nk_button_behavior behavior) -{ - int ret = 0; - nk_widget_state_reset(state); - if (!i) { - return 0; - } - if (nk_input_is_mouse_hovering_rect(i, r)) { - *state = NK_WIDGET_STATE_HOVERED; - if (nk_input_is_mouse_down(i, NK_BUTTON_LEFT)) { - *state = NK_WIDGET_STATE_ACTIVE; - } - if (nk_input_has_mouse_click_in_button_rect(i, NK_BUTTON_LEFT, r)) { - ret = (behavior != NK_BUTTON_DEFAULT) ? nk_input_is_mouse_down(i, NK_BUTTON_LEFT) : -#ifdef NK_BUTTON_TRIGGER_ON_RELEASE - nk_input_is_mouse_released(i, NK_BUTTON_LEFT); -#else - nk_input_is_mouse_pressed(i, NK_BUTTON_LEFT); -#endif - } - } - if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(i, r)) { - *state |= NK_WIDGET_STATE_ENTERED; - } else if (nk_input_is_mouse_prev_hovering_rect(i, r)) { - *state |= NK_WIDGET_STATE_LEFT; - } - return ret; -} -NK_LIB const struct nk_style_item * -nk_draw_button(struct nk_command_buffer *out, const struct nk_rect *bounds, nk_flags state, const struct nk_style_button *style) -{ - const struct nk_style_item *background; - if (state & NK_WIDGET_STATE_HOVER) { - background = &style->hover; - } else if (state & NK_WIDGET_STATE_ACTIVED) { - background = &style->active; - } else { - background = &style->normal; - } - - switch (background->type) { - case NK_STYLE_ITEM_IMAGE: - nk_draw_image(out, *bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor_background)); - break; - case NK_STYLE_ITEM_NINE_SLICE: - nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor_background)); - break; - case NK_STYLE_ITEM_COLOR: - nk_fill_rect(out, *bounds, style->rounding, nk_rgb_factor(background->data.color, style->color_factor_background)); - nk_stroke_rect(out, *bounds, style->rounding, style->border, nk_rgb_factor(style->border_color, style->color_factor_background)); - break; - } - return background; -} -NK_LIB nk_bool -nk_do_button(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect r, - const struct nk_style_button *style, - const struct nk_input *in, - enum nk_button_behavior behavior, - struct nk_rect *content) -{ - struct nk_rect bounds; - NK_ASSERT(style); - NK_ASSERT(state); - NK_ASSERT(out); - if (!out || !style) { - return nk_false; - } - - /* calculate button content space */ - content->x = r.x + style->padding.x + style->border + style->rounding; - content->y = r.y + style->padding.y + style->border + style->rounding; - content->w = r.w - (2 * (style->padding.x + style->border + style->rounding)); - content->h = r.h - (2 * (style->padding.y + style->border + style->rounding)); - - /* execute button behavior */ - bounds.x = r.x - style->touch_padding.x; - bounds.y = r.y - style->touch_padding.y; - bounds.w = r.w + 2 * style->touch_padding.x; - bounds.h = r.h + 2 * style->touch_padding.y; - return nk_button_behavior(state, bounds, in, behavior); -} -NK_LIB void -nk_draw_button_text(struct nk_command_buffer *out, - const struct nk_rect *bounds, - const struct nk_rect *content, - nk_flags state, - const struct nk_style_button *style, - const char *txt, - int len, - nk_flags text_alignment, - const struct nk_user_font *font) -{ - struct nk_text text; - const struct nk_style_item *background; - background = nk_draw_button(out, bounds, state, style); - - /* select correct colors/images */ - if (background->type == NK_STYLE_ITEM_COLOR) { - text.background = background->data.color; - } else { - text.background = style->text_background; - } - if (state & NK_WIDGET_STATE_HOVER) { - text.text = style->text_hover; - } else if (state & NK_WIDGET_STATE_ACTIVED) { - text.text = style->text_active; - } else { - text.text = style->text_normal; - } - - text.text = nk_rgb_factor(text.text, style->color_factor_text); - - text.padding = nk_vec2(0, 0); - nk_widget_text(out, *content, txt, len, &text, text_alignment, font); -} -NK_LIB nk_bool -nk_do_button_text(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect bounds, - const char *string, - int len, - nk_flags align, - enum nk_button_behavior behavior, - const struct nk_style_button *style, - const struct nk_input *in, - const struct nk_user_font *font) -{ - struct nk_rect content; - int ret = nk_false; - - NK_ASSERT(state); - NK_ASSERT(style); - NK_ASSERT(out); - NK_ASSERT(string); - NK_ASSERT(font); - if (!out || !style || !font || !string) { - return nk_false; - } - - ret = nk_do_button(state, out, bounds, style, in, behavior, &content); - if (style->draw_begin) { - style->draw_begin(out, style->userdata); - } - nk_draw_button_text(out, &bounds, &content, *state, style, string, len, align, font); - if (style->draw_end) { - style->draw_end(out, style->userdata); - } - return ret; -} -NK_LIB void -nk_draw_button_symbol(struct nk_command_buffer *out, - const struct nk_rect *bounds, - const struct nk_rect *content, - nk_flags state, - const struct nk_style_button *style, - enum nk_symbol_type type, - const struct nk_user_font *font) -{ - struct nk_color sym, bg; - const struct nk_style_item *background; - - /* select correct colors/images */ - background = nk_draw_button(out, bounds, state, style); - if (background->type == NK_STYLE_ITEM_COLOR) { - bg = background->data.color; - } else { - bg = style->text_background; - } - - if (state & NK_WIDGET_STATE_HOVER) { - sym = style->text_hover; - } else if (state & NK_WIDGET_STATE_ACTIVED) { - sym = style->text_active; - } else { - sym = style->text_normal; - } - - sym = nk_rgb_factor(sym, style->color_factor_text); - nk_draw_symbol(out, type, *content, bg, sym, 1, font); -} -NK_LIB nk_bool -nk_do_button_symbol(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect bounds, - enum nk_symbol_type symbol, - enum nk_button_behavior behavior, - const struct nk_style_button *style, - const struct nk_input *in, - const struct nk_user_font *font) -{ - int ret; - struct nk_rect content; - - NK_ASSERT(state); - NK_ASSERT(style); - NK_ASSERT(font); - NK_ASSERT(out); - if (!out || !style || !font || !state) { - return nk_false; - } - - ret = nk_do_button(state, out, bounds, style, in, behavior, &content); - if (style->draw_begin) { - style->draw_begin(out, style->userdata); - } - nk_draw_button_symbol(out, &bounds, &content, *state, style, symbol, font); - if (style->draw_end) { - style->draw_end(out, style->userdata); - } - return ret; -} -NK_LIB void -nk_draw_button_image( - struct nk_command_buffer *out, const struct nk_rect *bounds, const struct nk_rect *content, nk_flags state, const struct nk_style_button *style, const struct nk_image *img) -{ - nk_draw_button(out, bounds, state, style); - nk_draw_image(out, *content, img, nk_rgb_factor(nk_white, style->color_factor_background)); -} -NK_LIB nk_bool -nk_do_button_image(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect bounds, - struct nk_image img, - enum nk_button_behavior b, - const struct nk_style_button *style, - const struct nk_input *in) -{ - int ret; - struct nk_rect content; - - NK_ASSERT(state); - NK_ASSERT(style); - NK_ASSERT(out); - if (!out || !style || !state) { - return nk_false; - } - - ret = nk_do_button(state, out, bounds, style, in, b, &content); - content.x += style->image_padding.x; - content.y += style->image_padding.y; - content.w -= 2 * style->image_padding.x; - content.h -= 2 * style->image_padding.y; - - if (style->draw_begin) { - style->draw_begin(out, style->userdata); - } - nk_draw_button_image(out, &bounds, &content, *state, style, &img); - if (style->draw_end) { - style->draw_end(out, style->userdata); - } - return ret; -} -NK_LIB void -nk_draw_button_text_symbol(struct nk_command_buffer *out, - const struct nk_rect *bounds, - const struct nk_rect *label, - const struct nk_rect *symbol, - nk_flags state, - const struct nk_style_button *style, - const char *str, - int len, - enum nk_symbol_type type, - const struct nk_user_font *font) -{ - struct nk_color sym; - struct nk_text text; - const struct nk_style_item *background; - - /* select correct background colors/images */ - background = nk_draw_button(out, bounds, state, style); - if (background->type == NK_STYLE_ITEM_COLOR) { - text.background = background->data.color; - } else { - text.background = style->text_background; - } - - /* select correct text colors */ - if (state & NK_WIDGET_STATE_HOVER) { - sym = style->text_hover; - text.text = style->text_hover; - } else if (state & NK_WIDGET_STATE_ACTIVED) { - sym = style->text_active; - text.text = style->text_active; - } else { - sym = style->text_normal; - text.text = style->text_normal; - } - - sym = nk_rgb_factor(sym, style->color_factor_text); - text.text = nk_rgb_factor(text.text, style->color_factor_text); - text.padding = nk_vec2(0, 0); - nk_draw_symbol(out, type, *symbol, style->text_background, sym, 0, font); - nk_widget_text(out, *label, str, len, &text, NK_TEXT_CENTERED, font); -} -NK_LIB nk_bool -nk_do_button_text_symbol(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect bounds, - enum nk_symbol_type symbol, - const char *str, - int len, - nk_flags align, - enum nk_button_behavior behavior, - const struct nk_style_button *style, - const struct nk_user_font *font, - const struct nk_input *in) -{ - int ret; - struct nk_rect tri = {0, 0, 0, 0}; - struct nk_rect content; - - NK_ASSERT(style); - NK_ASSERT(out); - NK_ASSERT(font); - if (!out || !style || !font) { - return nk_false; - } - - ret = nk_do_button(state, out, bounds, style, in, behavior, &content); - tri.y = content.y + (content.h / 2) - out->context->style.font_size / 2; - tri.w = out->context->style.font_size; - tri.h = out->context->style.font_size; - if (align & NK_TEXT_ALIGN_LEFT) { - tri.x = (content.x + content.w) - (2 * style->padding.x + tri.w); - tri.x = NK_MAX(tri.x, 0); - } else { - tri.x = content.x + 2 * style->padding.x; - } - - /* draw button */ - if (style->draw_begin) { - style->draw_begin(out, style->userdata); - } - nk_draw_button_text_symbol(out, &bounds, &content, &tri, *state, style, str, len, symbol, font); - if (style->draw_end) { - style->draw_end(out, style->userdata); - } - return ret; -} -NK_LIB void -nk_draw_button_text_image(struct nk_command_buffer *out, - const struct nk_rect *bounds, - const struct nk_rect *label, - const struct nk_rect *image, - nk_flags state, - const struct nk_style_button *style, - const char *str, - int len, - const struct nk_user_font *font, - const struct nk_image *img) -{ - struct nk_text text; - const struct nk_style_item *background; - background = nk_draw_button(out, bounds, state, style); - - /* select correct colors */ - if (background->type == NK_STYLE_ITEM_COLOR) { - text.background = background->data.color; - } else { - text.background = style->text_background; - } - if (state & NK_WIDGET_STATE_HOVER) { - text.text = style->text_hover; - } else if (state & NK_WIDGET_STATE_ACTIVED) { - text.text = style->text_active; - } else { - text.text = style->text_normal; - } - - text.text = nk_rgb_factor(text.text, style->color_factor_text); - text.padding = nk_vec2(0, 0); - nk_widget_text(out, *label, str, len, &text, NK_TEXT_CENTERED, font); - nk_draw_image(out, *image, img, nk_rgb_factor(nk_white, style->color_factor_background)); -} -NK_LIB nk_bool -nk_do_button_text_image(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect bounds, - struct nk_image img, - const char *str, - int len, - nk_flags align, - enum nk_button_behavior behavior, - const struct nk_style_button *style, - const struct nk_user_font *font, - const struct nk_input *in) -{ - int ret; - struct nk_rect icon; - struct nk_rect content; - - NK_ASSERT(style); - NK_ASSERT(state); - NK_ASSERT(font); - NK_ASSERT(out); - if (!out || !font || !style || !str) { - return nk_false; - } - - ret = nk_do_button(state, out, bounds, style, in, behavior, &content); - icon.y = bounds.y + style->padding.y; - icon.w = icon.h = bounds.h - 2 * style->padding.y; - if (align & NK_TEXT_ALIGN_LEFT) { - icon.x = (bounds.x + bounds.w) - (2 * style->padding.x + icon.w); - icon.x = NK_MAX(icon.x, 0); - } else { - icon.x = bounds.x + 2 * style->padding.x; - } - - icon.x += style->image_padding.x; - icon.y += style->image_padding.y; - icon.w -= 2 * style->image_padding.x; - icon.h -= 2 * style->image_padding.y; - - if (style->draw_begin) { - style->draw_begin(out, style->userdata); - } - nk_draw_button_text_image(out, &bounds, &content, &icon, *state, style, str, len, font, &img); - if (style->draw_end) { - style->draw_end(out, style->userdata); - } - return ret; -} -NK_API void -nk_button_set_behavior(struct nk_context *ctx, enum nk_button_behavior behavior) -{ - NK_ASSERT(ctx); - if (!ctx) { - return; - } - ctx->button_behavior = behavior; -} -NK_API nk_bool -nk_button_push_behavior(struct nk_context *ctx, enum nk_button_behavior behavior) -{ - struct nk_config_stack_button_behavior *button_stack; - struct nk_config_stack_button_behavior_element *element; - - NK_ASSERT(ctx); - if (!ctx) { - return 0; - } - - button_stack = &ctx->stacks.button_behaviors; - NK_ASSERT(button_stack->head < (int)NK_LEN(button_stack->elements)); - if (button_stack->head >= (int)NK_LEN(button_stack->elements)) { - return 0; - } - - element = &button_stack->elements[button_stack->head++]; - element->address = &ctx->button_behavior; - element->old_value = ctx->button_behavior; - ctx->button_behavior = behavior; - return 1; -} -NK_API nk_bool -nk_button_pop_behavior(struct nk_context *ctx) -{ - struct nk_config_stack_button_behavior *button_stack; - struct nk_config_stack_button_behavior_element *element; - - NK_ASSERT(ctx); - if (!ctx) { - return 0; - } - - button_stack = &ctx->stacks.button_behaviors; - NK_ASSERT(button_stack->head > 0); - if (button_stack->head < 1) { - return 0; - } - - element = &button_stack->elements[--button_stack->head]; - *element->address = element->old_value; - return 1; -} -NK_API nk_bool -nk_button_text_styled(struct nk_context *ctx, const struct nk_style_button *style, const char *title, int len) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(style); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!style || !ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - win = ctx->current; - layout = win->layout; - state = nk_widget(&bounds, ctx); - - if (!state) { - return 0; - } - in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - return nk_do_button_text(&ctx->last_widget_state, &win->buffer, bounds, title, len, style->text_alignment, ctx->button_behavior, style, in, ctx->style.font); -} -NK_API nk_bool -nk_button_text(struct nk_context *ctx, const char *title, int len) -{ - NK_ASSERT(ctx); - if (!ctx) { - return 0; - } - return nk_button_text_styled(ctx, &ctx->style.button, title, len); -} -NK_API nk_bool -nk_button_label_styled(struct nk_context *ctx, const struct nk_style_button *style, const char *title) -{ - return nk_button_text_styled(ctx, style, title, nk_strlen(title)); -} -NK_API nk_bool -nk_button_label(struct nk_context *ctx, const char *title) -{ - return nk_button_text(ctx, title, nk_strlen(title)); -} -NK_API nk_bool -nk_button_color(struct nk_context *ctx, struct nk_color color) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - struct nk_style_button button; - - int ret = 0; - struct nk_rect bounds; - struct nk_rect content; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - win = ctx->current; - layout = win->layout; - - state = nk_widget(&bounds, ctx); - if (!state) { - return 0; - } - in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - - button = ctx->style.button; - button.normal = nk_style_item_color(color); - button.hover = nk_style_item_color(color); - button.active = nk_style_item_color(color); - ret = nk_do_button(&ctx->last_widget_state, &win->buffer, bounds, &button, in, ctx->button_behavior, &content); - nk_draw_button(&win->buffer, &bounds, ctx->last_widget_state, &button); - return ret; -} -NK_API nk_bool -nk_button_symbol_styled(struct nk_context *ctx, const struct nk_style_button *style, enum nk_symbol_type symbol) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - win = ctx->current; - layout = win->layout; - state = nk_widget(&bounds, ctx); - if (!state) { - return 0; - } - in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - return nk_do_button_symbol(&ctx->last_widget_state, &win->buffer, bounds, symbol, ctx->button_behavior, style, in, ctx->style.font); -} -NK_API nk_bool -nk_button_symbol(struct nk_context *ctx, enum nk_symbol_type symbol) -{ - NK_ASSERT(ctx); - if (!ctx) { - return 0; - } - return nk_button_symbol_styled(ctx, &ctx->style.button, symbol); -} -NK_API nk_bool -nk_button_image_styled(struct nk_context *ctx, const struct nk_style_button *style, struct nk_image img) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - win = ctx->current; - layout = win->layout; - - state = nk_widget(&bounds, ctx); - if (!state) { - return 0; - } - in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - return nk_do_button_image(&ctx->last_widget_state, &win->buffer, bounds, img, ctx->button_behavior, style, in); -} -NK_API nk_bool -nk_button_image(struct nk_context *ctx, struct nk_image img) -{ - NK_ASSERT(ctx); - if (!ctx) { - return 0; - } - return nk_button_image_styled(ctx, &ctx->style.button, img); -} -NK_API nk_bool -nk_button_symbol_text_styled(struct nk_context *ctx, const struct nk_style_button *style, enum nk_symbol_type symbol, const char *text, int len, nk_flags align) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - win = ctx->current; - layout = win->layout; - - state = nk_widget(&bounds, ctx); - if (!state) { - return 0; - } - in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - return nk_do_button_text_symbol(&ctx->last_widget_state, &win->buffer, bounds, symbol, text, len, align, ctx->button_behavior, style, ctx->style.font, in); -} -NK_API nk_bool -nk_button_symbol_text(struct nk_context *ctx, enum nk_symbol_type symbol, const char *text, int len, nk_flags align) -{ - NK_ASSERT(ctx); - if (!ctx) { - return 0; - } - return nk_button_symbol_text_styled(ctx, &ctx->style.button, symbol, text, len, align); -} -NK_API nk_bool -nk_button_symbol_label(struct nk_context *ctx, enum nk_symbol_type symbol, const char *label, nk_flags align) -{ - return nk_button_symbol_text(ctx, symbol, label, nk_strlen(label), align); -} -NK_API nk_bool -nk_button_symbol_label_styled(struct nk_context *ctx, const struct nk_style_button *style, enum nk_symbol_type symbol, const char *title, nk_flags align) -{ - return nk_button_symbol_text_styled(ctx, style, symbol, title, nk_strlen(title), align); -} -NK_API nk_bool -nk_button_image_text_styled(struct nk_context *ctx, const struct nk_style_button *style, struct nk_image img, const char *text, int len, nk_flags align) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - win = ctx->current; - layout = win->layout; - - state = nk_widget(&bounds, ctx); - if (!state) { - return 0; - } - in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - return nk_do_button_text_image(&ctx->last_widget_state, &win->buffer, bounds, img, text, len, align, ctx->button_behavior, style, ctx->style.font, in); -} -NK_API nk_bool -nk_button_image_text(struct nk_context *ctx, struct nk_image img, const char *text, int len, nk_flags align) -{ - return nk_button_image_text_styled(ctx, &ctx->style.button, img, text, len, align); -} -NK_API nk_bool -nk_button_image_label(struct nk_context *ctx, struct nk_image img, const char *label, nk_flags align) -{ - return nk_button_image_text(ctx, img, label, nk_strlen(label), align); -} -NK_API nk_bool -nk_button_image_label_styled(struct nk_context *ctx, const struct nk_style_button *style, struct nk_image img, const char *label, nk_flags text_alignment) -{ - return nk_button_image_text_styled(ctx, style, img, label, nk_strlen(label), text_alignment); -} - -/* =============================================================== - * - * TOGGLE - * - * ===============================================================*/ -NK_LIB nk_bool -nk_toggle_behavior(const struct nk_input *in, struct nk_rect select, nk_flags *state, nk_bool active) -{ - nk_widget_state_reset(state); - if (nk_button_behavior(state, select, in, NK_BUTTON_DEFAULT)) { - *state = NK_WIDGET_STATE_ACTIVE; - active = !active; - } - if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, select)) { - *state |= NK_WIDGET_STATE_ENTERED; - } else if (nk_input_is_mouse_prev_hovering_rect(in, select)) { - *state |= NK_WIDGET_STATE_LEFT; - } - return active; -} -NK_LIB void -nk_draw_checkbox(struct nk_command_buffer *out, - nk_flags state, - const struct nk_style_toggle *style, - nk_bool active, - const struct nk_rect *label, - const struct nk_rect *selector, - const struct nk_rect *cursors, - const char *string, - int len, - const struct nk_user_font *font, - nk_flags text_alignment) -{ - const struct nk_style_item *background; - const struct nk_style_item *cursor; - struct nk_text text; - - /* select correct colors/images */ - if (state & NK_WIDGET_STATE_HOVER) { - background = &style->hover; - cursor = &style->cursor_hover; - text.text = style->text_hover; - } else if (state & NK_WIDGET_STATE_ACTIVED) { - background = &style->hover; - cursor = &style->cursor_hover; - text.text = style->text_active; - } else { - background = &style->normal; - cursor = &style->cursor_normal; - text.text = style->text_normal; - } - - text.text = nk_rgb_factor(text.text, style->color_factor); - text.padding.x = 0; - text.padding.y = 0; - text.background = style->text_background; - nk_widget_text(out, *label, string, len, &text, text_alignment, font); - - /* draw background and cursor */ - if (background->type == NK_STYLE_ITEM_COLOR) { - nk_fill_rect(out, *selector, 0, nk_rgb_factor(style->border_color, style->color_factor)); - nk_fill_rect(out, nk_shrink_rect(*selector, style->border), 0, nk_rgb_factor(background->data.color, style->color_factor)); - } else { - nk_draw_image(out, *selector, &background->data.image, nk_rgb_factor(nk_white, style->color_factor)); - } - if (active) { - if (cursor->type == NK_STYLE_ITEM_IMAGE) { - nk_draw_image(out, *cursors, &cursor->data.image, nk_rgb_factor(nk_white, style->color_factor)); - } else { - nk_fill_rect(out, *cursors, 0, cursor->data.color); - } - } -} -NK_LIB void -nk_draw_option(struct nk_command_buffer *out, - nk_flags state, - const struct nk_style_toggle *style, - nk_bool active, - const struct nk_rect *label, - const struct nk_rect *selector, - const struct nk_rect *cursors, - const char *string, - int len, - const struct nk_user_font *font, - nk_flags text_alignment) -{ - const struct nk_style_item *background; - const struct nk_style_item *cursor; - struct nk_text text; - - /* select correct colors/images */ - if (state & NK_WIDGET_STATE_HOVER) { - background = &style->hover; - cursor = &style->cursor_hover; - text.text = style->text_hover; - } else if (state & NK_WIDGET_STATE_ACTIVED) { - background = &style->hover; - cursor = &style->cursor_hover; - text.text = style->text_active; - } else { - background = &style->normal; - cursor = &style->cursor_normal; - text.text = style->text_normal; - } - - text.text = nk_rgb_factor(text.text, style->color_factor); - text.padding.x = 0; - text.padding.y = 0; - text.background = style->text_background; - nk_widget_text(out, *label, string, len, &text, text_alignment, font); - - /* draw background and cursor */ - if (background->type == NK_STYLE_ITEM_COLOR) { - nk_fill_circle(out, *selector, nk_rgb_factor(style->border_color, style->color_factor)); - nk_fill_circle(out, nk_shrink_rect(*selector, style->border), nk_rgb_factor(background->data.color, style->color_factor)); - } else { - nk_draw_image(out, *selector, &background->data.image, nk_rgb_factor(nk_white, style->color_factor)); - } - if (active) { - if (cursor->type == NK_STYLE_ITEM_IMAGE) { - nk_draw_image(out, *cursors, &cursor->data.image, nk_rgb_factor(nk_white, style->color_factor)); - } else { - nk_fill_circle(out, *cursors, cursor->data.color); - } - } -} -NK_LIB nk_bool -nk_do_toggle(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect r, - nk_bool *active, - const char *str, - int len, - enum nk_toggle_type type, - const struct nk_style_toggle *style, - const struct nk_input *in, - const struct nk_user_font *font, - nk_flags widget_alignment, - nk_flags text_alignment) -{ - int was_active; - struct nk_rect bounds; - struct nk_rect select; - struct nk_rect cursor; - struct nk_rect label; - - NK_ASSERT(style); - NK_ASSERT(out); - NK_ASSERT(font); - if (!out || !style || !font || !active) { - return 0; - } - - r.w = NK_MAX(r.w, out->context->style.font_size + 2 * style->padding.x); - r.h = NK_MAX(r.h, out->context->style.font_size + 2 * style->padding.y); - - /* add additional touch padding for touch screen devices */ - bounds.x = r.x - style->touch_padding.x; - bounds.y = r.y - style->touch_padding.y; - bounds.w = r.w + 2 * style->touch_padding.x; - bounds.h = r.h + 2 * style->touch_padding.y; - - /* calculate the selector space */ - select.w = out->context->style.font_size; - select.h = select.w; - - if (widget_alignment & NK_WIDGET_ALIGN_RIGHT) { - select.x = r.x + r.w - out->context->style.font_size; - - /* label in front of the selector */ - label.x = r.x; - label.w = r.w - select.w - style->spacing * 2; - } else if (widget_alignment & NK_WIDGET_ALIGN_CENTERED) { - select.x = r.x + (r.w - select.w) / 2; - - /* label in front of selector */ - label.x = r.x; - label.w = (r.w - select.w - style->spacing * 2) / 2; - } else { /* Default: NK_WIDGET_ALIGN_LEFT */ - select.x = r.x; - - /* label behind the selector */ - label.x = select.x + select.w + style->spacing; - label.w = NK_MAX(r.x + r.w, label.x) - label.x; - } - - if (widget_alignment & NK_WIDGET_ALIGN_TOP) { - select.y = r.y; - } else if (widget_alignment & NK_WIDGET_ALIGN_BOTTOM) { - select.y = r.y + r.h - select.h - 2 * style->padding.y; - } else { /* Default: NK_WIDGET_ALIGN_MIDDLE */ - select.y = r.y + r.h / 2.0f - select.h / 2.0f; - } - - label.y = select.y; - label.h = select.w; - - /* calculate the bounds of the cursor inside the selector */ - cursor.x = select.x + style->padding.x + style->border; - cursor.y = select.y + style->padding.y + style->border; - cursor.w = select.w - (2 * style->padding.x + 2 * style->border); - cursor.h = select.h - (2 * style->padding.y + 2 * style->border); - - /* update selector */ - was_active = *active; - *active = nk_toggle_behavior(in, bounds, state, *active); - - /* draw selector */ - if (style->draw_begin) { - style->draw_begin(out, style->userdata); - } - if (type == NK_TOGGLE_CHECK) { - nk_draw_checkbox(out, *state, style, *active, &label, &select, &cursor, str, len, font, text_alignment); - } else { - nk_draw_option(out, *state, style, *active, &label, &select, &cursor, str, len, font, text_alignment); - } - if (style->draw_end) { - style->draw_end(out, style->userdata); - } - return (was_active != *active); -} -/*---------------------------------------------------------------- - * - * CHECKBOX - * - * --------------------------------------------------------------*/ -NK_API nk_bool -nk_check_text(struct nk_context *ctx, const char *text, int len, nk_bool active) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - const struct nk_style *style; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return active; - } - - win = ctx->current; - style = &ctx->style; - layout = win->layout; - - state = nk_widget(&bounds, ctx); - if (!state) { - return active; - } - in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &active, text, len, NK_TOGGLE_CHECK, &style->checkbox, in, style->font, NK_WIDGET_LEFT, NK_TEXT_LEFT); - return active; -} -NK_API nk_bool -nk_check_text_align(struct nk_context *ctx, const char *text, int len, nk_bool active, nk_flags widget_alignment, nk_flags text_alignment) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - const struct nk_style *style; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return active; - } - - win = ctx->current; - style = &ctx->style; - layout = win->layout; - - state = nk_widget(&bounds, ctx); - if (!state) { - return active; - } - in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &active, text, len, NK_TOGGLE_CHECK, &style->checkbox, in, style->font, widget_alignment, text_alignment); - return active; -} -NK_API unsigned int -nk_check_flags_text(struct nk_context *ctx, const char *text, int len, unsigned int flags, unsigned int value) -{ - int old_active; - NK_ASSERT(ctx); - NK_ASSERT(text); - if (!ctx || !text) { - return flags; - } - old_active = (int)((flags & value) & value); - if (nk_check_text(ctx, text, len, old_active)) { - flags |= value; - } else { - flags &= ~value; - } - return flags; -} -NK_API nk_bool -nk_checkbox_text(struct nk_context *ctx, const char *text, int len, nk_bool *active) -{ - int old_val; - NK_ASSERT(ctx); - NK_ASSERT(text); - NK_ASSERT(active); - if (!ctx || !text || !active) { - return 0; - } - old_val = *active; - *active = nk_check_text(ctx, text, len, *active); - return old_val != *active; -} -NK_API nk_bool -nk_checkbox_text_align(struct nk_context *ctx, const char *text, int len, nk_bool *active, nk_flags widget_alignment, nk_flags text_alignment) -{ - int old_val; - NK_ASSERT(ctx); - NK_ASSERT(text); - NK_ASSERT(active); - if (!ctx || !text || !active) { - return 0; - } - old_val = *active; - *active = nk_check_text_align(ctx, text, len, *active, widget_alignment, text_alignment); - return old_val != *active; -} -NK_API nk_bool -nk_checkbox_flags_text(struct nk_context *ctx, const char *text, int len, unsigned int *flags, unsigned int value) -{ - nk_bool active; - NK_ASSERT(ctx); - NK_ASSERT(text); - NK_ASSERT(flags); - if (!ctx || !text || !flags) { - return 0; - } - - active = (int)((*flags & value) & value); - if (nk_checkbox_text(ctx, text, len, &active)) { - if (active) { - *flags |= value; - } else { - *flags &= ~value; - } - return 1; - } - return 0; -} -NK_API nk_bool -nk_check_label(struct nk_context *ctx, const char *label, nk_bool active) -{ - return nk_check_text(ctx, label, nk_strlen(label), active); -} -NK_API unsigned int -nk_check_flags_label(struct nk_context *ctx, const char *label, unsigned int flags, unsigned int value) -{ - return nk_check_flags_text(ctx, label, nk_strlen(label), flags, value); -} -NK_API nk_bool -nk_checkbox_label(struct nk_context *ctx, const char *label, nk_bool *active) -{ - return nk_checkbox_text(ctx, label, nk_strlen(label), active); -} -NK_API nk_bool -nk_checkbox_label_align(struct nk_context *ctx, const char *label, nk_bool *active, nk_flags widget_alignment, nk_flags text_alignment) -{ - return nk_checkbox_text_align(ctx, label, nk_strlen(label), active, widget_alignment, text_alignment); -} -NK_API nk_bool -nk_checkbox_flags_label(struct nk_context *ctx, const char *label, unsigned int *flags, unsigned int value) -{ - return nk_checkbox_flags_text(ctx, label, nk_strlen(label), flags, value); -} -/*---------------------------------------------------------------- - * - * OPTION - * - * --------------------------------------------------------------*/ -NK_API nk_bool -nk_option_text(struct nk_context *ctx, const char *text, int len, nk_bool is_active) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - const struct nk_style *style; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return is_active; - } - - win = ctx->current; - style = &ctx->style; - layout = win->layout; - - state = nk_widget(&bounds, ctx); - if (!state) { - return (int)state; - } - in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &is_active, text, len, NK_TOGGLE_OPTION, &style->option, in, style->font, NK_WIDGET_LEFT, NK_TEXT_LEFT); - return is_active; -} -NK_API nk_bool -nk_option_text_align(struct nk_context *ctx, const char *text, int len, nk_bool is_active, nk_flags widget_alignment, nk_flags text_alignment) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - const struct nk_style *style; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return is_active; - } - - win = ctx->current; - style = &ctx->style; - layout = win->layout; - - state = nk_widget(&bounds, ctx); - if (!state) { - return (int)state; - } - in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - nk_do_toggle(&ctx->last_widget_state, &win->buffer, bounds, &is_active, text, len, NK_TOGGLE_OPTION, &style->option, in, style->font, widget_alignment, text_alignment); - return is_active; -} -NK_API nk_bool -nk_radio_text(struct nk_context *ctx, const char *text, int len, nk_bool *active) -{ - int old_value; - NK_ASSERT(ctx); - NK_ASSERT(text); - NK_ASSERT(active); - if (!ctx || !text || !active) { - return 0; - } - old_value = *active; - *active = nk_option_text(ctx, text, len, old_value); - return old_value != *active; -} -NK_API nk_bool -nk_radio_text_align(struct nk_context *ctx, const char *text, int len, nk_bool *active, nk_flags widget_alignment, nk_flags text_alignment) -{ - int old_value; - NK_ASSERT(ctx); - NK_ASSERT(text); - NK_ASSERT(active); - if (!ctx || !text || !active) { - return 0; - } - old_value = *active; - *active = nk_option_text_align(ctx, text, len, old_value, widget_alignment, text_alignment); - return old_value != *active; -} -NK_API nk_bool -nk_option_label(struct nk_context *ctx, const char *label, nk_bool active) -{ - return nk_option_text(ctx, label, nk_strlen(label), active); -} -NK_API nk_bool -nk_option_label_align(struct nk_context *ctx, const char *label, nk_bool active, nk_flags widget_alignment, nk_flags text_alignment) -{ - return nk_option_text_align(ctx, label, nk_strlen(label), active, widget_alignment, text_alignment); -} -NK_API nk_bool -nk_radio_label(struct nk_context *ctx, const char *label, nk_bool *active) -{ - return nk_radio_text(ctx, label, nk_strlen(label), active); -} -NK_API nk_bool -nk_radio_label_align(struct nk_context *ctx, const char *label, nk_bool *active, nk_flags widget_alignment, nk_flags text_alignment) -{ - return nk_radio_text_align(ctx, label, nk_strlen(label), active, widget_alignment, text_alignment); -} - -/* =============================================================== - * - * SELECTABLE - * - * ===============================================================*/ -NK_LIB void -nk_draw_selectable(struct nk_command_buffer *out, - nk_flags state, - const struct nk_style_selectable *style, - nk_bool active, - const struct nk_rect *bounds, - const struct nk_rect *icon, - const struct nk_image *img, - enum nk_symbol_type sym, - const char *string, - int len, - nk_flags align, - const struct nk_user_font *font) -{ - const struct nk_style_item *background; - struct nk_text text; - text.padding = style->padding; - - /* select correct colors/images */ - if (!active) { - if (state & NK_WIDGET_STATE_ACTIVED) { - background = &style->pressed; - text.text = style->text_pressed; - } else if (state & NK_WIDGET_STATE_HOVER) { - background = &style->hover; - text.text = style->text_hover; - } else { - background = &style->normal; - text.text = style->text_normal; - } - } else { - if (state & NK_WIDGET_STATE_ACTIVED) { - background = &style->pressed_active; - text.text = style->text_pressed_active; - } else if (state & NK_WIDGET_STATE_HOVER) { - background = &style->hover_active; - text.text = style->text_hover_active; - } else { - background = &style->normal_active; - text.text = style->text_normal_active; - } - } - - text.text = nk_rgb_factor(text.text, style->color_factor); - - /* draw selectable background and text */ - switch (background->type) { - case NK_STYLE_ITEM_IMAGE: - text.background = nk_rgba(0, 0, 0, 0); - nk_draw_image(out, *bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor)); - break; - case NK_STYLE_ITEM_NINE_SLICE: - text.background = nk_rgba(0, 0, 0, 0); - nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor)); - break; - case NK_STYLE_ITEM_COLOR: - text.background = background->data.color; - nk_fill_rect(out, *bounds, style->rounding, background->data.color); - break; - } - if (icon) { - if (img) { - nk_draw_image(out, *icon, img, nk_rgb_factor(nk_white, style->color_factor)); - } else { - nk_draw_symbol(out, sym, *icon, text.background, text.text, 1, font); - } - } - nk_widget_text(out, *bounds, string, len, &text, align, font); -} -NK_LIB nk_bool -nk_do_selectable(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect bounds, - const char *str, - int len, - nk_flags align, - nk_bool *value, - const struct nk_style_selectable *style, - const struct nk_input *in, - const struct nk_user_font *font) -{ - int old_value; - struct nk_rect touch; - - NK_ASSERT(state); - NK_ASSERT(out); - NK_ASSERT(str); - NK_ASSERT(len); - NK_ASSERT(value); - NK_ASSERT(style); - NK_ASSERT(font); - - if (!state || !out || !str || !len || !value || !style || !font) { - return 0; - } - old_value = *value; - - /* remove padding */ - touch.x = bounds.x - style->touch_padding.x; - touch.y = bounds.y - style->touch_padding.y; - touch.w = bounds.w + style->touch_padding.x * 2; - touch.h = bounds.h + style->touch_padding.y * 2; - - /* update button */ - if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT)) { - *value = !(*value); - } - - /* draw selectable */ - if (style->draw_begin) { - style->draw_begin(out, style->userdata); - } - nk_draw_selectable(out, *state, style, *value, &bounds, 0, 0, NK_SYMBOL_NONE, str, len, align, font); - if (style->draw_end) { - style->draw_end(out, style->userdata); - } - return old_value != *value; -} -NK_LIB nk_bool -nk_do_selectable_image(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect bounds, - const char *str, - int len, - nk_flags align, - nk_bool *value, - const struct nk_image *img, - const struct nk_style_selectable *style, - const struct nk_input *in, - const struct nk_user_font *font) -{ - nk_bool old_value; - struct nk_rect touch; - struct nk_rect icon; - - NK_ASSERT(state); - NK_ASSERT(out); - NK_ASSERT(str); - NK_ASSERT(len); - NK_ASSERT(value); - NK_ASSERT(style); - NK_ASSERT(font); - - if (!state || !out || !str || !len || !value || !style || !font) { - return 0; - } - old_value = *value; - - /* toggle behavior */ - touch.x = bounds.x - style->touch_padding.x; - touch.y = bounds.y - style->touch_padding.y; - touch.w = bounds.w + style->touch_padding.x * 2; - touch.h = bounds.h + style->touch_padding.y * 2; - if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT)) { - *value = !(*value); - } - - icon.y = bounds.y + style->padding.y; - icon.w = icon.h = bounds.h - 2 * style->padding.y; - if (align & NK_TEXT_ALIGN_LEFT) { - icon.x = (bounds.x + bounds.w) - (2 * style->padding.x + icon.w); - icon.x = NK_MAX(icon.x, 0); - } else { - icon.x = bounds.x + 2 * style->padding.x; - } - - icon.x += style->image_padding.x; - icon.y += style->image_padding.y; - icon.w -= 2 * style->image_padding.x; - icon.h -= 2 * style->image_padding.y; - - /* draw selectable */ - if (style->draw_begin) { - style->draw_begin(out, style->userdata); - } - nk_draw_selectable(out, *state, style, *value, &bounds, &icon, img, NK_SYMBOL_NONE, str, len, align, font); - if (style->draw_end) { - style->draw_end(out, style->userdata); - } - return old_value != *value; -} -NK_LIB nk_bool -nk_do_selectable_symbol(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect bounds, - const char *str, - int len, - nk_flags align, - nk_bool *value, - enum nk_symbol_type sym, - const struct nk_style_selectable *style, - const struct nk_input *in, - const struct nk_user_font *font) -{ - int old_value; - struct nk_rect touch; - struct nk_rect icon; - - NK_ASSERT(state); - NK_ASSERT(out); - NK_ASSERT(str); - NK_ASSERT(len); - NK_ASSERT(value); - NK_ASSERT(style); - NK_ASSERT(font); - - if (!state || !out || !str || !len || !value || !style || !font) { - return 0; - } - old_value = *value; - - /* toggle behavior */ - touch.x = bounds.x - style->touch_padding.x; - touch.y = bounds.y - style->touch_padding.y; - touch.w = bounds.w + style->touch_padding.x * 2; - touch.h = bounds.h + style->touch_padding.y * 2; - if (nk_button_behavior(state, touch, in, NK_BUTTON_DEFAULT)) { - *value = !(*value); - } - - icon.y = bounds.y + style->padding.y; - icon.w = icon.h = bounds.h - 2 * style->padding.y; - if (align & NK_TEXT_ALIGN_LEFT) { - icon.x = (bounds.x + bounds.w) - (2 * style->padding.x + icon.w); - icon.x = NK_MAX(icon.x, 0); - } else { - icon.x = bounds.x + 2 * style->padding.x; - } - - icon.x += style->image_padding.x; - icon.y += style->image_padding.y; - icon.w -= 2 * style->image_padding.x; - icon.h -= 2 * style->image_padding.y; - - /* draw selectable */ - if (style->draw_begin) { - style->draw_begin(out, style->userdata); - } - nk_draw_selectable(out, *state, style, *value, &bounds, &icon, 0, sym, str, len, align, font); - if (style->draw_end) { - style->draw_end(out, style->userdata); - } - return old_value != *value; -} - -NK_API nk_bool -nk_selectable_text(struct nk_context *ctx, const char *str, int len, nk_flags align, nk_bool *value) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - const struct nk_style *style; - - enum nk_widget_layout_states state; - struct nk_rect bounds; - - NK_ASSERT(ctx); - NK_ASSERT(value); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout || !value) { - return 0; - } - - win = ctx->current; - layout = win->layout; - style = &ctx->style; - - state = nk_widget(&bounds, ctx); - if (!state) { - return 0; - } - in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - return nk_do_selectable(&ctx->last_widget_state, &win->buffer, bounds, str, len, align, value, &style->selectable, in, style->font); -} -NK_API nk_bool -nk_selectable_image_text(struct nk_context *ctx, struct nk_image img, const char *str, int len, nk_flags align, nk_bool *value) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - const struct nk_style *style; - - enum nk_widget_layout_states state; - struct nk_rect bounds; - - NK_ASSERT(ctx); - NK_ASSERT(value); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout || !value) { - return 0; - } - - win = ctx->current; - layout = win->layout; - style = &ctx->style; - - state = nk_widget(&bounds, ctx); - if (!state) { - return 0; - } - in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - return nk_do_selectable_image(&ctx->last_widget_state, &win->buffer, bounds, str, len, align, value, &img, &style->selectable, in, style->font); -} -NK_API nk_bool -nk_selectable_symbol_text(struct nk_context *ctx, enum nk_symbol_type sym, const char *str, int len, nk_flags align, nk_bool *value) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_input *in; - const struct nk_style *style; - - enum nk_widget_layout_states state; - struct nk_rect bounds; - - NK_ASSERT(ctx); - NK_ASSERT(value); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout || !value) { - return 0; - } - - win = ctx->current; - layout = win->layout; - style = &ctx->style; - - state = nk_widget(&bounds, ctx); - if (!state) { - return 0; - } - in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - return nk_do_selectable_symbol(&ctx->last_widget_state, &win->buffer, bounds, str, len, align, value, sym, &style->selectable, in, style->font); -} -NK_API nk_bool -nk_selectable_symbol_label(struct nk_context *ctx, enum nk_symbol_type sym, const char *title, nk_flags align, nk_bool *value) -{ - return nk_selectable_symbol_text(ctx, sym, title, nk_strlen(title), align, value); -} -NK_API nk_bool -nk_select_text(struct nk_context *ctx, const char *str, int len, nk_flags align, nk_bool value) -{ - nk_selectable_text(ctx, str, len, align, &value); - return value; -} -NK_API nk_bool -nk_selectable_label(struct nk_context *ctx, const char *str, nk_flags align, nk_bool *value) -{ - return nk_selectable_text(ctx, str, nk_strlen(str), align, value); -} -NK_API nk_bool -nk_selectable_image_label(struct nk_context *ctx, struct nk_image img, const char *str, nk_flags align, nk_bool *value) -{ - return nk_selectable_image_text(ctx, img, str, nk_strlen(str), align, value); -} -NK_API nk_bool -nk_select_label(struct nk_context *ctx, const char *str, nk_flags align, nk_bool value) -{ - nk_selectable_text(ctx, str, nk_strlen(str), align, &value); - return value; -} -NK_API nk_bool -nk_select_image_label(struct nk_context *ctx, struct nk_image img, const char *str, nk_flags align, nk_bool value) -{ - nk_selectable_image_text(ctx, img, str, nk_strlen(str), align, &value); - return value; -} -NK_API nk_bool -nk_select_image_text(struct nk_context *ctx, struct nk_image img, const char *str, int len, nk_flags align, nk_bool value) -{ - nk_selectable_image_text(ctx, img, str, len, align, &value); - return value; -} -NK_API nk_bool -nk_select_symbol_text(struct nk_context *ctx, enum nk_symbol_type sym, const char *title, int title_len, nk_flags align, nk_bool value) -{ - nk_selectable_symbol_text(ctx, sym, title, title_len, align, &value); - return value; -} -NK_API nk_bool -nk_select_symbol_label(struct nk_context *ctx, enum nk_symbol_type sym, const char *title, nk_flags align, nk_bool value) -{ - return nk_select_symbol_text(ctx, sym, title, nk_strlen(title), align, value); -} - -/* =============================================================== - * - * SLIDER - * - * ===============================================================*/ -NK_LIB float -nk_slider_behavior(nk_flags *state, - struct nk_rect *logical_cursor, - struct nk_rect *visual_cursor, - struct nk_input *in, - struct nk_rect bounds, - float slider_min, - float slider_max, - float slider_value, - float slider_step, - float slider_steps) -{ - int left_mouse_down; - int left_mouse_click_in_cursor; - - /* check if visual cursor is being dragged */ - nk_widget_state_reset(state); - left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down; - left_mouse_click_in_cursor = in && nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, *visual_cursor, nk_true); - - if (left_mouse_down && left_mouse_click_in_cursor) { - float ratio = 0; - const float d = in->mouse.pos.x - (visual_cursor->x + visual_cursor->w * 0.5f); - const float pxstep = bounds.w / slider_steps; - - /* only update value if the next slider step is reached */ - *state = NK_WIDGET_STATE_ACTIVE; - if (NK_ABS(d) >= pxstep) { - const float steps = (float)((int)(NK_ABS(d) / pxstep)); - slider_value += (d > 0) ? (slider_step * steps) : -(slider_step * steps); - slider_value = NK_CLAMP(slider_min, slider_value, slider_max); - ratio = (slider_value - slider_min) / slider_step; - logical_cursor->x = bounds.x + (logical_cursor->w * ratio); - in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = logical_cursor->x; - } - } - - /* slider widget state */ - if (nk_input_is_mouse_hovering_rect(in, bounds)) { - *state = NK_WIDGET_STATE_HOVERED; - } - if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, bounds)) { - *state |= NK_WIDGET_STATE_ENTERED; - } else if (nk_input_is_mouse_prev_hovering_rect(in, bounds)) { - *state |= NK_WIDGET_STATE_LEFT; - } - return slider_value; -} -NK_LIB void -nk_draw_slider(struct nk_command_buffer *out, - nk_flags state, - const struct nk_style_slider *style, - const struct nk_rect *bounds, - const struct nk_rect *visual_cursor, - float min, - float value, - float max) -{ - struct nk_rect fill; - struct nk_rect bar; - const struct nk_style_item *background; - - /* select correct slider images/colors */ - struct nk_color bar_color; - const struct nk_style_item *cursor; - - NK_UNUSED(min); - NK_UNUSED(max); - NK_UNUSED(value); - - if (state & NK_WIDGET_STATE_ACTIVED) { - background = &style->active; - bar_color = style->bar_active; - cursor = &style->cursor_active; - } else if (state & NK_WIDGET_STATE_HOVER) { - background = &style->hover; - bar_color = style->bar_hover; - cursor = &style->cursor_hover; - } else { - background = &style->normal; - bar_color = style->bar_normal; - cursor = &style->cursor_normal; - } - - /* calculate slider background bar */ - bar.x = bounds->x; - bar.y = (visual_cursor->y + visual_cursor->h / 2) - bounds->h / 12; - bar.w = bounds->w; - bar.h = bounds->h / 6; - - /* filled background bar style */ - fill.w = (visual_cursor->x + (visual_cursor->w / 2.0f)) - bar.x; - fill.x = bar.x; - fill.y = bar.y; - fill.h = bar.h; - - /* draw background */ - switch (background->type) { - case NK_STYLE_ITEM_IMAGE: - nk_draw_image(out, *bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor)); - break; - case NK_STYLE_ITEM_NINE_SLICE: - nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor)); - break; - case NK_STYLE_ITEM_COLOR: - nk_fill_rect(out, *bounds, style->rounding, nk_rgb_factor(background->data.color, style->color_factor)); - nk_stroke_rect(out, *bounds, style->rounding, style->border, nk_rgb_factor(style->border_color, style->color_factor)); - break; - } - - /* draw slider bar */ - nk_fill_rect(out, bar, style->rounding, nk_rgb_factor(bar_color, style->color_factor)); - nk_fill_rect(out, fill, style->rounding, nk_rgb_factor(style->bar_filled, style->color_factor)); - - /* draw cursor */ - if (cursor->type == NK_STYLE_ITEM_IMAGE) { - nk_draw_image(out, *visual_cursor, &cursor->data.image, nk_rgb_factor(nk_white, style->color_factor)); - } else { - nk_fill_circle(out, *visual_cursor, nk_rgb_factor(cursor->data.color, style->color_factor)); - } -} -NK_LIB float -nk_do_slider(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect bounds, - float min, - float val, - float max, - float step, - const struct nk_style_slider *style, - struct nk_input *in, - const struct nk_user_font *font) -{ - float slider_range; - float slider_min; - float slider_max; - float slider_value; - float slider_steps; - float cursor_offset; - - struct nk_rect visual_cursor; - struct nk_rect logical_cursor; - - NK_ASSERT(style); - NK_ASSERT(out); - if (!out || !style) { - return 0; - } - - /* remove padding from slider bounds */ - bounds.x = bounds.x + style->padding.x; - bounds.y = bounds.y + style->padding.y; - bounds.h = NK_MAX(bounds.h, 2 * style->padding.y); - bounds.w = NK_MAX(bounds.w, 2 * style->padding.x + style->cursor_size.x); - bounds.w -= 2 * style->padding.x; - bounds.h -= 2 * style->padding.y; - - /* optional buttons */ - if (style->show_buttons) { - nk_flags ws; - struct nk_rect button; - button.y = bounds.y; - button.w = bounds.h; - button.h = bounds.h; - - /* decrement button */ - button.x = bounds.x; - if (nk_do_button_symbol(&ws, out, button, style->dec_symbol, NK_BUTTON_DEFAULT, &style->dec_button, in, font)) { - val -= step; - } - - /* increment button */ - button.x = (bounds.x + bounds.w) - button.w; - if (nk_do_button_symbol(&ws, out, button, style->inc_symbol, NK_BUTTON_DEFAULT, &style->inc_button, in, font)) { - val += step; - } - - bounds.x = bounds.x + button.w + style->spacing.x; - bounds.w = bounds.w - (2 * button.w + 2 * style->spacing.x); - } - - /* remove one cursor size to support visual cursor */ - bounds.x += style->cursor_size.x * 0.5f; - bounds.w -= style->cursor_size.x; - - /* make sure the provided values are correct */ - slider_max = NK_MAX(min, max); - slider_min = NK_MIN(min, max); - slider_value = NK_CLAMP(slider_min, val, slider_max); - slider_range = slider_max - slider_min; - slider_steps = slider_range / step; - cursor_offset = (slider_value - slider_min) / step; - - /* calculate cursor - Basically you have two cursors. One for visual representation and interaction - and one for updating the actual cursor value. */ - logical_cursor.h = bounds.h; - logical_cursor.w = bounds.w / slider_steps; - logical_cursor.x = bounds.x + (logical_cursor.w * cursor_offset); - logical_cursor.y = bounds.y; - - visual_cursor.h = style->cursor_size.y; - visual_cursor.w = style->cursor_size.x; - visual_cursor.y = (bounds.y + bounds.h * 0.5f) - visual_cursor.h * 0.5f; - visual_cursor.x = logical_cursor.x - visual_cursor.w * 0.5f; - - slider_value = nk_slider_behavior(state, &logical_cursor, &visual_cursor, in, bounds, slider_min, slider_max, slider_value, step, slider_steps); - visual_cursor.x = logical_cursor.x - visual_cursor.w * 0.5f; - - /* draw slider */ - if (style->draw_begin) { - style->draw_begin(out, style->userdata); - } - nk_draw_slider(out, *state, style, &bounds, &visual_cursor, slider_min, slider_value, slider_max); - if (style->draw_end) { - style->draw_end(out, style->userdata); - } - return slider_value; -} -NK_API nk_bool -nk_slider_float(struct nk_context *ctx, float min_value, float *value, float max_value, float value_step) -{ - struct nk_window *win; - struct nk_panel *layout; - struct nk_input *in; - const struct nk_style *style; - - int ret = 0; - float old_value; - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - NK_ASSERT(value); - if (!ctx || !ctx->current || !ctx->current->layout || !value) { - return ret; - } - - win = ctx->current; - style = &ctx->style; - layout = win->layout; - - state = nk_widget(&bounds, ctx); - if (!state) { - return ret; - } - in = (/*state == NK_WIDGET_ROM || */ state == NK_WIDGET_DISABLED || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - - old_value = *value; - *value = nk_do_slider(&ctx->last_widget_state, &win->buffer, bounds, min_value, old_value, max_value, value_step, &style->slider, in, style->font); - return (old_value > *value || old_value < *value); -} -NK_API float -nk_slide_float(struct nk_context *ctx, float min, float val, float max, float step) -{ - nk_slider_float(ctx, min, &val, max, step); - return val; -} -NK_API int -nk_slide_int(struct nk_context *ctx, int min, int val, int max, int step) -{ - float value = (float)val; - nk_slider_float(ctx, (float)min, &value, (float)max, (float)step); - return (int)value; -} -NK_API nk_bool -nk_slider_int(struct nk_context *ctx, int min, int *val, int max, int step) -{ - int ret; - float value = (float)*val; - ret = nk_slider_float(ctx, (float)min, &value, (float)max, (float)step); - *val = (int)value; - return ret; -} - -/* =============================================================== - * - * KNOB - * - * ===============================================================*/ - -NK_LIB float -nk_knob_behavior(nk_flags *state, - struct nk_input *in, - struct nk_rect bounds, - float knob_min, - float knob_max, - float knob_value, - float knob_step, - float knob_steps, - enum nk_heading zero_direction, - float dead_zone_percent) -{ - struct nk_vec2 origin; - float angle = 0.0f; - origin.x = bounds.x + (bounds.w / 2); - origin.y = bounds.y + (bounds.h / 2); - - nk_widget_state_reset(state); - - /* handle click and drag input */ - if (in && in->mouse.buttons[NK_BUTTON_LEFT].down && nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, bounds, nk_true)) { - /* calculate angle from origin and rotate */ - const float direction_rads[4] = { - NK_PI * 2.5f, /* 90 NK_UP */ - NK_PI * 2.0f, /* 0 NK_RIGHT */ - NK_PI * 1.5f, /* 270 NK_DOWN */ - NK_PI, /* 180 NK_LEFT */ - }; - *state = NK_WIDGET_STATE_ACTIVE; - - angle = NK_ATAN2(in->mouse.pos.y - origin.y, in->mouse.pos.x - origin.x) + direction_rads[zero_direction]; - angle -= (angle > NK_PI * 2) ? NK_PI * 3 : NK_PI; - - /* account for dead space applied when drawing */ - angle *= 1.0f / (1.0f - dead_zone_percent); - angle = NK_CLAMP(-NK_PI, angle, NK_PI); - - /* convert -pi -> pi range to 0.0 -> 1.0 */ - angle = (angle + NK_PI) / (NK_PI * 2); - - /* click to closest step */ - knob_value = knob_min + ((int)(angle * knob_steps + (knob_step / 2))) * knob_step; - knob_value = NK_CLAMP(knob_min, knob_value, knob_max); - } - - /* knob widget state */ - if (nk_input_is_mouse_hovering_rect(in, bounds)) { - *state = NK_WIDGET_STATE_HOVERED; - /* handle scroll and arrow inputs */ - if (in->mouse.scroll_delta.y > 0 || (in->keyboard.keys[NK_KEY_UP].down && in->keyboard.keys[NK_KEY_UP].clicked)) { - knob_value += knob_step; - } - - if (in->mouse.scroll_delta.y < 0 || (in->keyboard.keys[NK_KEY_DOWN].down && in->keyboard.keys[NK_KEY_DOWN].clicked)) { - knob_value -= knob_step; - } - /* easiest way to disable scrolling of parent panels..knob eats scrolling */ - in->mouse.scroll_delta.y = 0; - knob_value = NK_CLAMP(knob_min, knob_value, knob_max); - } - if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, bounds)) { - *state |= NK_WIDGET_STATE_ENTERED; - } else if (nk_input_is_mouse_prev_hovering_rect(in, bounds)) { - *state |= NK_WIDGET_STATE_LEFT; - } - - return knob_value; -} -NK_LIB void -nk_draw_knob(struct nk_command_buffer *out, - nk_flags state, - const struct nk_style_knob *style, - const struct nk_rect *bounds, - float min, - float value, - float max, - enum nk_heading zero_direction, - float dead_zone_percent) -{ - const struct nk_style_item *background; - struct nk_color knob_color, cursor; - - NK_UNUSED(min); - NK_UNUSED(max); - NK_UNUSED(value); - - if (state & NK_WIDGET_STATE_ACTIVED) { - background = &style->active; - knob_color = style->knob_active; - cursor = style->cursor_active; - } else if (state & NK_WIDGET_STATE_HOVER) { - background = &style->hover; - knob_color = style->knob_hover; - cursor = style->cursor_hover; - } else { - background = &style->normal; - knob_color = style->knob_normal; - cursor = style->cursor_normal; - } - - /* draw background */ - switch (background->type) { - case NK_STYLE_ITEM_IMAGE: - nk_draw_image(out, *bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor)); - break; - case NK_STYLE_ITEM_NINE_SLICE: - nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor)); - break; - case NK_STYLE_ITEM_COLOR: - nk_fill_rect(out, *bounds, 0, nk_rgb_factor(background->data.color, style->color_factor)); - nk_stroke_rect(out, *bounds, 0, style->border, nk_rgb_factor(style->border_color, style->color_factor)); - break; - } - - /* draw knob */ - nk_fill_circle(out, *bounds, nk_rgb_factor(knob_color, style->color_factor)); - if (style->knob_border > 0) { - struct nk_rect border_bounds = *bounds; - border_bounds.x += style->knob_border / 2; - border_bounds.y += style->knob_border / 2; - border_bounds.w -= style->knob_border; - border_bounds.h -= style->knob_border; - nk_stroke_circle(out, border_bounds, style->knob_border, nk_rgb_factor(style->knob_border_color, style->color_factor)); - } - { /* calculate cursor line cords */ - float half_circle_size = (bounds->w / 2); - float angle = (value - min) / (max - min); - float alive_zone = 1.0f - dead_zone_percent; - struct nk_vec2 cursor_start, cursor_end; - const float direction_rads[4] = { - NK_PI * 1.5f, /* 90 NK_UP */ - 0.0f, /* 0 NK_RIGHT */ - NK_PI * 0.5f, /* 270 NK_DOWN */ - NK_PI, /* 180 NK_LEFT */ - }; - /* calculate + apply dead zone */ - angle = (angle * alive_zone) + (dead_zone_percent / 2); - - /* percentage 0.0 -> 1.0 to radians, rads are 0.0 to (2*pi) NOT -pi to pi */ - angle *= NK_PI * 2; - - /* apply zero angle */ - angle += direction_rads[zero_direction]; - if (angle > NK_PI * 2) { - angle -= NK_PI * 2; - } - - cursor_start.x = bounds->x + half_circle_size + (angle > NK_PI); - cursor_start.y = bounds->y + half_circle_size + (angle < NK_PI_HALF || angle > (NK_PI * 1.5f)); - - cursor_end.x = cursor_start.x + (half_circle_size * NK_COS(angle)); - cursor_end.y = cursor_start.y + (half_circle_size * NK_SIN(angle)); - - /* cut off half of the cursor */ - cursor_start.x = (cursor_start.x + cursor_end.x) / 2; - cursor_start.y = (cursor_start.y + cursor_end.y) / 2; - - /* draw cursor */ - nk_stroke_line(out, cursor_start.x, cursor_start.y, cursor_end.x, cursor_end.y, 2, nk_rgb_factor(cursor, style->color_factor)); - } -} -NK_LIB float -nk_do_knob(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect bounds, - float min, - float val, - float max, - float step, - enum nk_heading zero_direction, - float dead_zone_percent, - const struct nk_style_knob *style, - struct nk_input *in) -{ - float knob_range; - float knob_min; - float knob_max; - float knob_value; - float knob_steps; - - NK_ASSERT(style); - NK_ASSERT(out); - if (!out || !style) { - return 0; - } - - /* remove padding from knob bounds */ - bounds.y = bounds.y + style->padding.y; - bounds.x = bounds.x + style->padding.x; - bounds.h = NK_MAX(bounds.h, 2 * style->padding.y); - bounds.w = NK_MAX(bounds.w, 2 * style->padding.x); - bounds.w -= 2 * style->padding.x; - bounds.h -= 2 * style->padding.y; - if (bounds.h < bounds.w) { - bounds.x += (bounds.w - bounds.h) / 2; - bounds.w = bounds.h; - } - - /* make sure the provided values are correct */ - knob_max = NK_MAX(min, max); - knob_min = NK_MIN(min, max); - knob_value = NK_CLAMP(knob_min, val, knob_max); - knob_range = knob_max - knob_min; - knob_steps = knob_range / step; - - knob_value = nk_knob_behavior(state, in, bounds, knob_min, knob_max, knob_value, step, knob_steps, zero_direction, dead_zone_percent); - - /* draw knob */ - if (style->draw_begin) { - style->draw_begin(out, style->userdata); - } - nk_draw_knob(out, *state, style, &bounds, knob_min, knob_value, knob_max, zero_direction, dead_zone_percent); - if (style->draw_end) { - style->draw_end(out, style->userdata); - } - return knob_value; -} -NK_API nk_bool -nk_knob_float(struct nk_context *ctx, float min_value, float *value, float max_value, float value_step, enum nk_heading zero_direction, float dead_zone_degrees) -{ - struct nk_window *win; - struct nk_panel *layout; - struct nk_input *in; - const struct nk_style *style; - - int ret = 0; - float old_value; - struct nk_rect bounds; - enum nk_widget_layout_states state; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - NK_ASSERT(value); - NK_ASSERT(NK_BETWEEN(dead_zone_degrees, 0.0f, 360.0f)); - if (!ctx || !ctx->current || !ctx->current->layout || !value) { - return ret; - } - - win = ctx->current; - style = &ctx->style; - layout = win->layout; - - state = nk_widget(&bounds, ctx); - if (!state) { - return ret; - } - in = (state == NK_WIDGET_DISABLED || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - - old_value = *value; - *value = nk_do_knob(&ctx->last_widget_state, &win->buffer, bounds, min_value, old_value, max_value, value_step, zero_direction, dead_zone_degrees / 360.0f, &style->knob, in); - - return (old_value > *value || old_value < *value); -} -NK_API nk_bool -nk_knob_int(struct nk_context *ctx, int min, int *val, int max, int step, enum nk_heading zero_direction, float dead_zone_degrees) -{ - int ret; - float value = (float)*val; - ret = nk_knob_float(ctx, (float)min, &value, (float)max, (float)step, zero_direction, dead_zone_degrees); - *val = (int)value; - return ret; -} - -/* =============================================================== - * - * PROGRESS - * - * ===============================================================*/ -NK_LIB nk_size -nk_progress_behavior(nk_flags *state, struct nk_input *in, struct nk_rect r, struct nk_rect cursor, nk_size max, nk_size value, nk_bool modifiable) -{ - int left_mouse_down = 0; - int left_mouse_click_in_cursor = 0; - - nk_widget_state_reset(state); - if (!in || !modifiable) { - return value; - } - left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down; - left_mouse_click_in_cursor = in && nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, cursor, nk_true); - if (nk_input_is_mouse_hovering_rect(in, r)) { - *state = NK_WIDGET_STATE_HOVERED; - } - - if (in && left_mouse_down && left_mouse_click_in_cursor) { - if (left_mouse_down && left_mouse_click_in_cursor) { - float ratio = NK_MAX(0, (float)(in->mouse.pos.x - cursor.x)) / (float)cursor.w; - value = (nk_size)NK_CLAMP(0, (float)max * ratio, (float)max); - in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = cursor.x + cursor.w / 2.0f; - *state |= NK_WIDGET_STATE_ACTIVE; - } - } - /* set progressbar widget state */ - if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, r)) { - *state |= NK_WIDGET_STATE_ENTERED; - } else if (nk_input_is_mouse_prev_hovering_rect(in, r)) { - *state |= NK_WIDGET_STATE_LEFT; - } - return value; -} -NK_LIB void -nk_draw_progress( - struct nk_command_buffer *out, nk_flags state, const struct nk_style_progress *style, const struct nk_rect *bounds, const struct nk_rect *scursor, nk_size value, nk_size max) -{ - const struct nk_style_item *background; - const struct nk_style_item *cursor; - - NK_UNUSED(max); - NK_UNUSED(value); - - /* select correct colors/images to draw */ - if (state & NK_WIDGET_STATE_ACTIVED) { - background = &style->active; - cursor = &style->cursor_active; - } else if (state & NK_WIDGET_STATE_HOVER) { - background = &style->hover; - cursor = &style->cursor_hover; - } else { - background = &style->normal; - cursor = &style->cursor_normal; - } - - /* draw background */ - switch (background->type) { - case NK_STYLE_ITEM_IMAGE: - nk_draw_image(out, *bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor)); - break; - case NK_STYLE_ITEM_NINE_SLICE: - nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor)); - break; - case NK_STYLE_ITEM_COLOR: - nk_fill_rect(out, *bounds, style->rounding, nk_rgb_factor(background->data.color, style->color_factor)); - nk_stroke_rect(out, *bounds, style->rounding, style->border, nk_rgb_factor(style->border_color, style->color_factor)); - break; - } - - /* draw cursor */ - switch (cursor->type) { - case NK_STYLE_ITEM_IMAGE: - nk_draw_image(out, *scursor, &cursor->data.image, nk_rgb_factor(nk_white, style->color_factor)); - break; - case NK_STYLE_ITEM_NINE_SLICE: - nk_draw_nine_slice(out, *scursor, &cursor->data.slice, nk_rgb_factor(nk_white, style->color_factor)); - break; - case NK_STYLE_ITEM_COLOR: - nk_fill_rect(out, *scursor, style->rounding, nk_rgb_factor(cursor->data.color, style->color_factor)); - nk_stroke_rect(out, *scursor, style->rounding, style->border, nk_rgb_factor(style->border_color, style->color_factor)); - break; - } -} -NK_LIB nk_size -nk_do_progress( - nk_flags *state, struct nk_command_buffer *out, struct nk_rect bounds, nk_size value, nk_size max, nk_bool modifiable, const struct nk_style_progress *style, struct nk_input *in) -{ - float prog_scale; - nk_size prog_value; - struct nk_rect cursor; - - NK_ASSERT(style); - NK_ASSERT(out); - if (!out || !style) { - return 0; - } - - /* calculate progressbar cursor */ - cursor.w = NK_MAX(bounds.w, 2 * style->padding.x + 2 * style->border); - cursor.h = NK_MAX(bounds.h, 2 * style->padding.y + 2 * style->border); - cursor = nk_pad_rect(bounds, nk_vec2(style->padding.x + style->border, style->padding.y + style->border)); - prog_scale = (float)value / (float)max; - - /* update progressbar */ - prog_value = NK_MIN(value, max); - prog_value = nk_progress_behavior(state, in, bounds, cursor, max, prog_value, modifiable); - cursor.w = cursor.w * prog_scale; - - /* draw progressbar */ - if (style->draw_begin) { - style->draw_begin(out, style->userdata); - } - nk_draw_progress(out, *state, style, &bounds, &cursor, value, max); - if (style->draw_end) { - style->draw_end(out, style->userdata); - } - return prog_value; -} -NK_API nk_bool -nk_progress(struct nk_context *ctx, nk_size *cur, nk_size max, nk_bool is_modifyable) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_style *style; - struct nk_input *in; - - struct nk_rect bounds; - enum nk_widget_layout_states state; - nk_size old_value; - - NK_ASSERT(ctx); - NK_ASSERT(cur); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout || !cur) { - return 0; - } - - win = ctx->current; - style = &ctx->style; - layout = win->layout; - state = nk_widget(&bounds, ctx); - if (!state) { - return 0; - } - - in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - old_value = *cur; - *cur = nk_do_progress(&ctx->last_widget_state, &win->buffer, bounds, *cur, max, is_modifyable, &style->progress, in); - return (*cur != old_value); -} -NK_API nk_size -nk_prog(struct nk_context *ctx, nk_size cur, nk_size max, nk_bool modifyable) -{ - nk_progress(ctx, &cur, max, modifyable); - return cur; -} - -/* =============================================================== - * - * SCROLLBAR - * - * ===============================================================*/ -NK_LIB float -nk_scrollbar_behavior(nk_flags *state, - struct nk_input *in, - int has_scrolling, - const struct nk_rect *scroll, - const struct nk_rect *cursor, - const struct nk_rect *empty0, - const struct nk_rect *empty1, - float scroll_offset, - float max_offset, - float scroll_step, - float cursor_travel, - enum nk_orientation o) -{ - nk_flags ws = 0; - int left_mouse_down; - unsigned int left_mouse_clicked; - int left_mouse_click_in_cursor; - float scroll_delta; - nk_bool shift_down; - - nk_widget_state_reset(state); - if (!in) { - return scroll_offset; - } - - left_mouse_down = in->mouse.buttons[NK_BUTTON_LEFT].down; - left_mouse_clicked = in->mouse.buttons[NK_BUTTON_LEFT].clicked; - left_mouse_click_in_cursor = nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, *cursor, nk_true); - if (nk_input_is_mouse_hovering_rect(in, *scroll)) { - *state = NK_WIDGET_STATE_HOVERED; - } - - shift_down = nk_input_is_key_down(in, NK_KEY_SHIFT); - - if (o == NK_VERTICAL) { - scroll_delta = shift_down ? 0.0f : in->mouse.scroll_delta.y; - } else { - scroll_delta = in->mouse.scroll_delta.x; - - if (scroll_delta == 0.0f && shift_down) { - scroll_delta = in->mouse.scroll_delta.y; - } - } - - if (left_mouse_down && left_mouse_click_in_cursor && !left_mouse_clicked) { - float pixel; - float delta; - float old_offset = scroll_offset; - - *state = NK_WIDGET_STATE_ACTIVE; - - if (o == NK_VERTICAL) { - pixel = in->mouse.delta.y; - } else { - pixel = in->mouse.delta.x; - } - - if (cursor_travel > 0.0f && max_offset > 0.0f) { - delta = (pixel / cursor_travel) * max_offset; - scroll_offset = NK_CLAMP(0.0f, scroll_offset + delta, max_offset); - } - - if (max_offset > 0.0f && cursor_travel > 0.0f) { - float cursor_delta = ((scroll_offset - old_offset) / max_offset) * cursor_travel; - - if (o == NK_VERTICAL) { - in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.y = cursor->y + cursor_delta + cursor->h * 0.5f; - } else { - in->mouse.buttons[NK_BUTTON_LEFT].clicked_pos.x = cursor->x + cursor_delta + cursor->w * 0.5f; - } - } - } else if ((nk_input_is_key_pressed(in, NK_KEY_SCROLL_UP) && o == NK_VERTICAL && has_scrolling) || nk_button_behavior(&ws, *empty0, in, NK_BUTTON_DEFAULT)) { - /* scroll page up by click on empty space or shortcut */ - if (o == NK_VERTICAL) { - scroll_offset = NK_CLAMP(0, scroll_offset - scroll->h, max_offset); - } else { - scroll_offset = NK_CLAMP(0, scroll_offset - scroll->w, max_offset); - } - } else if ((nk_input_is_key_pressed(in, NK_KEY_SCROLL_DOWN) && o == NK_VERTICAL && has_scrolling) || nk_button_behavior(&ws, *empty1, in, NK_BUTTON_DEFAULT)) { - /* scroll page down by click on empty space or shortcut */ - if (o == NK_VERTICAL) { - scroll_offset = NK_CLAMP(0, scroll_offset + scroll->h, max_offset); - } else { - scroll_offset = NK_CLAMP(0, scroll_offset + scroll->w, max_offset); - } - } else if (has_scrolling) { - if (scroll_delta != 0.0f && max_offset > 0.0f) { - scroll_offset = NK_CLAMP(0.0f, scroll_offset + scroll_step * (-scroll_delta), max_offset); - } else if (nk_input_is_key_pressed(in, NK_KEY_SCROLL_START)) { - scroll_offset = 0.0f; - } else if (nk_input_is_key_pressed(in, NK_KEY_SCROLL_END)) { - scroll_offset = max_offset; - } - } - if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, *scroll)) { - *state |= NK_WIDGET_STATE_ENTERED; - } else if (nk_input_is_mouse_prev_hovering_rect(in, *scroll)) { - *state |= NK_WIDGET_STATE_LEFT; - } - return scroll_offset; -} -NK_LIB void -nk_draw_scrollbar(struct nk_command_buffer *out, nk_flags state, const struct nk_style_scrollbar *style, const struct nk_rect *bounds, const struct nk_rect *scroll) -{ - const struct nk_style_item *background; - const struct nk_style_item *cursor; - - /* select correct colors/images to draw */ - if (state & NK_WIDGET_STATE_ACTIVED) { - background = &style->active; - cursor = &style->cursor_active; - } else if (state & NK_WIDGET_STATE_HOVER) { - background = &style->hover; - cursor = &style->cursor_hover; - } else { - background = &style->normal; - cursor = &style->cursor_normal; - } - - /* draw background */ - switch (background->type) { - case NK_STYLE_ITEM_IMAGE: - nk_draw_image(out, *bounds, &background->data.image, nk_white); - break; - case NK_STYLE_ITEM_NINE_SLICE: - nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_white); - break; - case NK_STYLE_ITEM_COLOR: - nk_fill_rect(out, *bounds, style->rounding, background->data.color); - nk_stroke_rect(out, *bounds, style->rounding, style->border, style->border_color); - break; - } - - /* draw cursor */ - switch (cursor->type) { - case NK_STYLE_ITEM_IMAGE: - nk_draw_image(out, *scroll, &cursor->data.image, nk_white); - break; - case NK_STYLE_ITEM_NINE_SLICE: - nk_draw_nine_slice(out, *scroll, &cursor->data.slice, nk_white); - break; - case NK_STYLE_ITEM_COLOR: - nk_fill_rect(out, *scroll, style->rounding_cursor, cursor->data.color); - nk_stroke_rect(out, *scroll, style->rounding_cursor, style->border_cursor, style->cursor_border_color); - break; - } -} - -NK_LIB float -nk_scrollbar_cursor_size(float track_size, float view_size, float target_size, float min_size) -{ - float size = 0.0f; - - if (target_size > 0.0f) { - size = (view_size / target_size) * track_size; - } - - size = NK_MAX(size, min_size); - size = NK_CLAMP(0.0f, size, track_size); - return size; -} - -NK_LIB float -nk_scrollbar_cursor_pos(float track_pos, float track_size, float cursor_size, float offset, float max_offset) -{ - float travel = NK_MAX(track_size - cursor_size, 0.0f); - - if (max_offset <= 0.0f || travel <= 0.0f) { - return track_pos; - } - - offset = NK_CLAMP(0.0f, offset, max_offset); - return track_pos + (offset / max_offset) * travel; -} - -NK_LIB float -nk_do_scrollbarv(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect scroll, - int has_scrolling, - float offset, - float target, - float step, - float button_pixel_inc, - const struct nk_style_scrollbar *style, - struct nk_input *in, - const struct nk_user_font *font) -{ - struct nk_rect empty_north; - struct nk_rect empty_south; - struct nk_rect cursor; - - float track_y; - float track_h; - float max_offset; - - float scroll_step; - float scroll_offset; - - NK_ASSERT(out); - NK_ASSERT(style); - NK_ASSERT(state); - if (!out || !style) { - return 0; - } - - scroll.w = NK_MAX(scroll.w, 1); - scroll.h = NK_MAX(scroll.h, 0); - if (target <= scroll.h) { - return 0; - } - - /* optional scrollbar buttons */ - if (style->show_buttons) { - nk_flags ws; - float scroll_h; - struct nk_rect button; - - button.x = scroll.x; - button.w = scroll.w; - button.h = scroll.w; - - scroll_h = NK_MAX(scroll.h - 2 * button.h, 0); - scroll_step = NK_MIN(step, button_pixel_inc); - - /* decrement button */ - button.y = scroll.y; - if (nk_do_button_symbol(&ws, out, button, style->dec_symbol, NK_BUTTON_REPEATER, &style->dec_button, in, font)) { - offset = offset - scroll_step; - } - - /* increment button */ - button.y = scroll.y + scroll.h - button.h; - if (nk_do_button_symbol(&ws, out, button, style->inc_symbol, NK_BUTTON_REPEATER, &style->inc_button, in, font)) { - offset = offset + scroll_step; - } - - scroll.y = scroll.y + button.h; - scroll.h = scroll_h; - } - - /* calculate scrollbar constants */ - track_y = scroll.y + style->border + style->padding.y; - track_h = NK_MAX(scroll.h - 2.0f * (style->border + style->padding.y), 0.0f); - max_offset = NK_MAX(target - scroll.h, 0.0f); - scroll_step = NK_MIN(step, scroll.h); - scroll_offset = NK_CLAMP(0, offset, max_offset); - - /* calculate scrollbar cursor bounds */ - cursor.h = nk_scrollbar_cursor_size(track_h, scroll.h, target, style->cursor_min_size); - cursor.y = nk_scrollbar_cursor_pos(track_y, track_h, cursor.h, scroll_offset, max_offset); - cursor.w = NK_MAX(scroll.w - 2.0f * (style->border + style->padding.x), 0.0f); - cursor.x = scroll.x + style->border + style->padding.x; - - /* calculate empty space around cursor */ - empty_north.x = scroll.x; - empty_north.y = scroll.y; - empty_north.w = scroll.w; - empty_north.h = NK_MAX(cursor.y - scroll.y, 0); - - empty_south.x = scroll.x; - empty_south.y = cursor.y + cursor.h; - empty_south.w = scroll.w; - empty_south.h = NK_MAX((scroll.y + scroll.h) - (cursor.y + cursor.h), 0); - - /* update scrollbar */ - scroll_offset = nk_scrollbar_behavior( - state, in, has_scrolling, &scroll, &cursor, &empty_north, &empty_south, scroll_offset, max_offset, scroll_step, NK_MAX(track_h - cursor.h, 0.0f), NK_VERTICAL); - cursor.y = nk_scrollbar_cursor_pos(track_y, track_h, cursor.h, scroll_offset, max_offset); - - /* draw scrollbar */ - if (style->draw_begin) { - style->draw_begin(out, style->userdata); - } - nk_draw_scrollbar(out, *state, style, &scroll, &cursor); - if (style->draw_end) { - style->draw_end(out, style->userdata); - } - return scroll_offset; -} - -NK_LIB float -nk_do_scrollbarh(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect scroll, - int has_scrolling, - float offset, - float target, - float step, - float button_pixel_inc, - const struct nk_style_scrollbar *style, - struct nk_input *in, - const struct nk_user_font *font) -{ - struct nk_rect cursor; - struct nk_rect empty_west; - struct nk_rect empty_east; - - float track_x; - float track_w; - float max_offset; - - float scroll_step; - float scroll_offset; - - NK_ASSERT(out); - NK_ASSERT(style); - if (!out || !style) { - return 0; - } - - /* scrollbar background */ - scroll.h = NK_MAX(scroll.h, 1); - scroll.w = NK_MAX(scroll.w, 2 * scroll.h); - if (target <= scroll.w) { - return 0; - } - - /* optional scrollbar buttons */ - if (style->show_buttons) { - nk_flags ws; - float scroll_w; - struct nk_rect button; - button.y = scroll.y; - button.w = scroll.h; - button.h = scroll.h; - - scroll_w = scroll.w - 2 * button.w; - scroll_step = NK_MIN(step, button_pixel_inc); - - /* decrement button */ - button.x = scroll.x; - if (nk_do_button_symbol(&ws, out, button, style->dec_symbol, NK_BUTTON_REPEATER, &style->dec_button, in, font)) { - offset = offset - scroll_step; - } - - /* increment button */ - button.x = scroll.x + scroll.w - button.w; - if (nk_do_button_symbol(&ws, out, button, style->inc_symbol, NK_BUTTON_REPEATER, &style->inc_button, in, font)) { - offset = offset + scroll_step; - } - - scroll.x = scroll.x + button.w; - scroll.w = scroll_w; - } - - /* calculate scrollbar constants */ - track_x = scroll.x + style->border + style->padding.x; - track_w = NK_MAX(scroll.w - 2.0f * (style->border + style->padding.x), 0.0f); - max_offset = NK_MAX(target - scroll.w, 0.0f); - scroll_step = NK_MIN(step, scroll.w); - scroll_offset = NK_CLAMP(0.0f, offset, max_offset); - - /* calculate cursor bounds */ - cursor.w = nk_scrollbar_cursor_size(track_w, scroll.w, target, style->cursor_min_size); - cursor.x = nk_scrollbar_cursor_pos(track_x, track_w, cursor.w, scroll_offset, max_offset); - cursor.h = NK_MAX(scroll.h - 2.0f * (style->border + style->padding.y), 0.0f); - cursor.y = scroll.y + style->border + style->padding.y; - - /* calculate empty space around cursor */ - empty_west.x = scroll.x; - empty_west.y = scroll.y; - empty_west.w = cursor.x - scroll.x; - empty_west.h = scroll.h; - - empty_east.x = cursor.x + cursor.w; - empty_east.y = scroll.y; - empty_east.w = (scroll.x + scroll.w) - (cursor.x + cursor.w); - empty_east.h = scroll.h; - - /* update scrollbar */ - scroll_offset = nk_scrollbar_behavior( - state, in, has_scrolling, &scroll, &cursor, &empty_west, &empty_east, scroll_offset, max_offset, scroll_step, NK_MAX(track_w - cursor.w, 0.0f), NK_HORIZONTAL); - cursor.x = nk_scrollbar_cursor_pos(track_x, track_w, cursor.w, scroll_offset, max_offset); - - /* draw scrollbar */ - if (style->draw_begin) { - style->draw_begin(out, style->userdata); - } - nk_draw_scrollbar(out, *state, style, &scroll, &cursor); - if (style->draw_end) { - style->draw_end(out, style->userdata); - } - return scroll_offset; -} - -/* =============================================================== - * - * TEXT EDITOR - * - * ===============================================================*/ -/* stb_textedit.h - v1.8 - public domain - Sean Barrett */ -struct nk_text_find { - float x, y; /* position of n'th character */ - float height; /* height of line */ - int first_char, length; /* first char of row, and length */ - int prev_first; /*_ first char of previous row */ -}; - -struct nk_text_edit_row { - float x0, x1; - /* starting x location, end x location (allows for align=right, etc) */ - float baseline_y_delta; - /* position of baseline relative to previous row's baseline*/ - float ymin, ymax; - /* height of row above and below baseline */ - int num_chars; -}; - -/* forward declarations */ -NK_INTERN void -nk_textedit_makeundo_delete(struct nk_text_edit *, int, int); -NK_INTERN void -nk_textedit_makeundo_insert(struct nk_text_edit *, int, int); -NK_INTERN void -nk_textedit_makeundo_replace(struct nk_text_edit *, int, int, int); -#define NK_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end) - -NK_INTERN int -nk_textedit_byte_offset(const struct nk_text_edit *edit, int rune_offset) -{ - const char *text; - nk_rune rune; - int len; - - text = nk_str_get_const(&edit->string); - if (rune_offset >= edit->string.len) { - return nk_str_len_char(&edit->string); - } - return (int)(nk_str_at_const(&edit->string, rune_offset, &rune, &len) - text); -} - -NK_INTERN int -nk_textedit_rune_offset(const struct nk_text_edit *edit, int byte_offset) -{ - return nk_utf_len(nk_str_get_const(&edit->string), byte_offset); -} - -NK_INTERN struct nk_text_shape * -nk_textedit_line_shape(struct nk_text_edit *edit, int line_start, const struct nk_user_font *font) -{ - const char *text; - const char *begin; - const char *line_end; - const char *text_end; - - text = nk_str_get_const(&edit->string); - if (!text) { - return NULL; - } - - begin = text + nk_textedit_byte_offset(edit, line_start); - line_end = begin; - text_end = text + nk_str_len_char(&edit->string); - - while (line_end < text_end && *line_end != '\n') { - line_end += 1; - } - return nk_text_shape_build_default(edit->context, font, edit->context->style.font_size, begin, (int)(line_end - begin)); -} -NK_INTERN void -nk_textedit_layout_row(struct nk_text_edit_row *r, struct nk_text_edit *edit, int line_start_id, float row_height, const struct nk_user_font *font) -{ - int l; - int glyphs = 0; - nk_rune unicode; - const char *remaining; - int len; - const char *end; - const char *text; - struct nk_vec2 size; - - len = nk_str_len_char(&edit->string); - end = nk_str_get_const(&edit->string); - - r->x0 = 0.0f; - r->x1 = 0.0f; - r->baseline_y_delta = row_height; - r->ymin = 0.0f; - r->ymax = row_height; - r->num_chars = 0; - - if (!end || line_start_id >= edit->string.len) { - return; - } - - end += len; - text = nk_str_at_const(&edit->string, line_start_id, &unicode, &l); - size = nk_text_calculate_text_bounds(edit->context, font, text, (int)(end - text), row_height, - &remaining, 0, &glyphs, NK_STOP_ON_NEW_LINE); - - r->x1 = size.x; - r->num_chars = glyphs; -} -NK_INTERN int -nk_textedit_locate_coord(struct nk_text_edit *edit, float x, float y, const struct nk_user_font *font, - float row_height, enum nk_text_affinity *affinity) -{ - struct nk_text_edit_row r; - int n = edit->string.len; - float base_y = 0; - int i = 0; - - r.x0 = r.x1 = 0; - r.ymin = r.ymax = 0; - r.num_chars = 0; - - /* search rows to find one that straddles 'y' */ - while (i < n) { - nk_textedit_layout_row(&r, edit, i, row_height, font); - if (r.num_chars <= 0) { - *affinity = NK_TEXT_AFFINITY_TRAILING; - return n; - } - - if (i == 0 && y < base_y + r.ymin) { - *affinity = NK_TEXT_AFFINITY_LEADING; - return 0; - } - - if (y < base_y + r.ymax) { - break; - } - - i += r.num_chars; - base_y += r.baseline_y_delta; - } - - /* below all text, return 'after' last character */ - if (i >= n) { - *affinity = NK_TEXT_AFFINITY_TRAILING; - return n; - } - - /* check if it's before the beginning of the line */ - if (x < r.x0) { - *affinity = NK_TEXT_AFFINITY_LEADING; - return i; - } - - if (x < r.x1) { - struct nk_text_shape *shape = nk_textedit_line_shape(edit, i, font); - if (shape) { - struct nk_text_cursor cursor = nk_text_shape_hit_test(shape, x - r.x0); - int line_byte_offset = nk_textedit_byte_offset(edit, i); - *affinity = cursor.affinity; - return nk_textedit_rune_offset(edit, line_byte_offset + cursor.source_offset); - } - } - - *affinity = NK_TEXT_AFFINITY_TRAILING; - if (nk_str_rune_at(&edit->string, i + r.num_chars - 1) == '\n') { - return i + r.num_chars - 1; - } else { - return i + r.num_chars; - } -} -NK_LIB void -nk_textedit_click(struct nk_text_edit *state, float x, float y, const struct nk_user_font *font, float row_height) -{ - /* API click: on mouse down, move the cursor to the clicked location, - * and reset the selection */ - enum nk_text_affinity affinity; - state->cursor = nk_textedit_locate_coord(state, x, y, font, row_height, &affinity); - state->cursor_affinity = (unsigned char)affinity; - state->select_start = state->cursor; - state->select_end = state->cursor; - state->select_start_affinity = state->cursor_affinity; - state->has_preferred_x = 0; -} -NK_LIB void -nk_textedit_drag(struct nk_text_edit *state, float x, float y, const struct nk_user_font *font, float row_height) -{ - /* API drag: on mouse drag, move the cursor and selection endpoint - * to the clicked location */ - enum nk_text_affinity affinity; - int p = nk_textedit_locate_coord(state, x, y, font, row_height, &affinity); - if (state->select_start == state->select_end) { - state->select_start = state->cursor; - state->select_start_affinity = state->cursor_affinity; - } - state->cursor = state->select_end = p; - state->cursor_affinity = (unsigned char)affinity; -} -NK_INTERN void -nk_textedit_find_charpos(struct nk_text_find *find, struct nk_text_edit *state, int n, int single_line, - const struct nk_user_font *font, float row_height, enum nk_text_affinity affinity) -{ - struct nk_text_edit_row r; - int previous = 0; - int first = 0; - - nk_zero_struct(r); - find->y = 0.0f; - while (1) { - nk_bool ends_with_newline; - - nk_textedit_layout_row(&r, state, first, row_height, font); - ends_with_newline = r.num_chars > 0 && nk_str_rune_at(&state->string, first + r.num_chars - 1) == '\n'; - if (single_line || n < first + r.num_chars || - (n == first + r.num_chars && !ends_with_newline) || !r.num_chars) { - break; - } - previous = first; - first += r.num_chars; - find->y += r.baseline_y_delta; - } - - find->first_char = first; - find->length = r.num_chars; - find->height = r.ymax - r.ymin; - find->prev_first = previous; - - { - struct nk_text_shape *shape = nk_textedit_line_shape(state, first, font); - int line_byte_offset = nk_textedit_byte_offset(state, first); - int byte_offset = nk_textedit_byte_offset(state, n) - line_byte_offset; - find->x = shape ? nk_text_shape_cursor_at(shape, byte_offset, affinity).x : r.x0; - } -} -NK_INTERN void -nk_textedit_clamp(struct nk_text_edit *state) -{ - /* make the selection/cursor state valid if client altered the string */ - int n = state->string.len; - if (NK_TEXT_HAS_SELECTION(state)) { - if (state->select_start > n) { - state->select_start = n; - } - - if (state->select_end > n) { - state->select_end = n; - } - - /* if clamping forced them to be equal, move the cursor to match */ - if (state->select_start == state->select_end) { - state->cursor = state->select_start; - } - } - - if (state->cursor > n) { - state->cursor = n; - } -} -NK_API void -nk_textedit_delete(struct nk_text_edit *state, int where, int len) -{ - /* delete characters while updating undo */ - nk_textedit_makeundo_delete(state, where, len); - nk_str_delete_runes(&state->string, where, len); - state->has_preferred_x = 0; -} -NK_API void -nk_textedit_delete_selection(struct nk_text_edit *state) -{ - /* delete the section */ - nk_textedit_clamp(state); - if (NK_TEXT_HAS_SELECTION(state)) { - if (state->select_start < state->select_end) { - nk_textedit_delete(state, state->select_start, state->select_end - state->select_start); - state->select_end = state->cursor = state->select_start; - state->cursor_affinity = state->select_start_affinity; - } else { - nk_textedit_delete(state, state->select_end, state->select_start - state->select_end); - state->select_start = state->cursor = state->select_end; - } - state->select_start_affinity = state->cursor_affinity; - state->has_preferred_x = 0; - } -} -NK_INTERN void -nk_textedit_sortselection(struct nk_text_edit *state) -{ - /* canonicalize the selection so start <= end */ - if (state->select_end < state->select_start) { - int temp = state->select_end; - unsigned char temp_affinity = state->cursor_affinity; - state->select_end = state->select_start; - state->cursor_affinity = state->select_start_affinity; - state->select_start = temp; - state->select_start_affinity = temp_affinity; - } -} -NK_INTERN void -nk_textedit_move_to_first(struct nk_text_edit *state) -{ - /* move cursor to first character of selection */ - if (NK_TEXT_HAS_SELECTION(state)) { - nk_textedit_sortselection(state); - state->cursor = state->select_start; - state->cursor_affinity = state->select_start_affinity; - state->select_end = state->select_start; - state->has_preferred_x = 0; - } -} -NK_INTERN void -nk_textedit_move_to_last(struct nk_text_edit *state) -{ - /* move cursor to last character of selection */ - if (NK_TEXT_HAS_SELECTION(state)) { - nk_textedit_sortselection(state); - nk_textedit_clamp(state); - state->cursor = state->select_end; - state->select_start = state->select_end; - state->select_start_affinity = state->cursor_affinity; - state->has_preferred_x = 0; - } -} -NK_INTERN int -nk_is_word_boundary(struct nk_text_edit *state, int idx) -{ - int len; - nk_rune c; - if (idx < 0) { - return 1; - } - if (!nk_str_at_rune(&state->string, idx, &c, &len)) { - return 1; - } -#ifndef NK_IS_WORD_BOUNDARY - return (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v' || c == 0x3000); -#else - return NK_IS_WORD_BOUNDARY(c); -#endif -} -NK_INTERN int -nk_textedit_move_to_word_previous_fallback(struct nk_text_edit *state) -{ - int c = state->cursor - 1; - if (c > 0) { - if (nk_is_word_boundary(state, c)) { - while (c > 0 && nk_is_word_boundary(state, --c)) - ; - } - while (!nk_is_word_boundary(state, --c)) - ; - c++; - } else { - return 0; - } - - return c; -} -NK_INTERN int -nk_textedit_move_to_word_next_fallback(struct nk_text_edit *state) -{ - const int len = state->string.len; - int c = state->cursor; - if (c < len) { - if (!nk_is_word_boundary(state, c)) { - while (c < len && !nk_is_word_boundary(state, ++c)) - ; - } - while (c < len && nk_is_word_boundary(state, ++c)) - ; - } else { - return len; - } - - return c; -} -NK_INTERN int -nk_textedit_move_to_boundary(struct nk_text_edit *state, const struct nk_user_font *font, nk_flags flags, nk_bool next) -{ - const char *text = nk_str_get_const(&state->string); - int len = nk_str_len_char(&state->string); - int byte_offset; - struct nk_text_shape *shape; - - if (!len) { - return 0; - } - - shape = nk_text_shape_build_default(state->context, font, state->context->style.font_size, text, len); - if (!shape) { - if (flags == NK_TEXT_BOUNDARY_WORD) { - return next ? nk_textedit_move_to_word_next_fallback(state) : nk_textedit_move_to_word_previous_fallback(state); - } - return NK_CLAMP(0, state->cursor + (next ? 1 : -1), state->string.len); - } - - byte_offset = nk_textedit_byte_offset(state, state->cursor); - byte_offset = next ? nk_text_shape_boundary_next(shape, byte_offset, flags) - : nk_text_shape_boundary_previous(shape, byte_offset, flags); - return nk_textedit_rune_offset(state, byte_offset); -} -NK_INTERN int -nk_textedit_move_visual(struct nk_text_edit *state, const struct nk_user_font *font, float row_height, int direction) -{ - struct nk_text_find find; - struct nk_text_shape *shape; - struct nk_text_cursor cursor; - int line_byte_offset; - - nk_textedit_find_charpos(&find, state, state->cursor, state->single_line, font, row_height, - (enum nk_text_affinity)state->cursor_affinity); - shape = nk_textedit_line_shape(state, find.first_char, font); - if (!shape) { - return nk_textedit_move_to_boundary(state, font, NK_TEXT_BOUNDARY_GRAPHEME, direction > 0); - } - - line_byte_offset = nk_textedit_byte_offset(state, find.first_char); - cursor.source_offset = nk_textedit_byte_offset(state, state->cursor) - line_byte_offset; - cursor.affinity = (enum nk_text_affinity)state->cursor_affinity; - cursor = nk_text_shape_cursor_move(shape, cursor, direction); - state->cursor_affinity = (unsigned char)cursor.affinity; - return nk_textedit_rune_offset(state, line_byte_offset + cursor.source_offset); -} -NK_INTERN void -nk_textedit_collapse_visual(struct nk_text_edit *state, const struct nk_user_font *font, float row_height, int direction) -{ - struct nk_text_find start; - struct nk_text_find end; - nk_bool use_start; - - nk_textedit_find_charpos(&start, state, state->select_start, state->single_line, font, row_height, - (enum nk_text_affinity)state->select_start_affinity); - nk_textedit_find_charpos(&end, state, state->select_end, state->single_line, font, row_height, - (enum nk_text_affinity)state->cursor_affinity); - - if (start.y == end.y) { - use_start = direction < 0 ? start.x < end.x : start.x > end.x; - } else { - use_start = direction < 0 ? state->select_start < state->select_end : state->select_start > state->select_end; - } - - if (use_start) { - state->cursor = state->select_start; - state->cursor_affinity = state->select_start_affinity; - } else { - state->cursor = state->select_end; - } - state->select_start = state->cursor; - state->select_end = state->cursor; - state->select_start_affinity = state->cursor_affinity; - state->has_preferred_x = 0; -} -NK_INTERN void -nk_textedit_prep_selection_at_cursor(struct nk_text_edit *state) -{ - /* update selection and cursor to match each other */ - if (!NK_TEXT_HAS_SELECTION(state)) { - state->select_start = state->select_end = state->cursor; - state->select_start_affinity = state->cursor_affinity; - } else { - state->cursor = state->select_end; - } -} -NK_API nk_bool -nk_textedit_cut(struct nk_text_edit *state) -{ - /* API cut: delete selection */ - if (state->mode == NK_TEXT_EDIT_MODE_VIEW) { - return 0; - } - if (NK_TEXT_HAS_SELECTION(state)) { - nk_textedit_delete_selection(state); /* implicitly clamps */ - state->has_preferred_x = 0; - return 1; - } - return 0; -} -NK_API nk_bool -nk_textedit_paste(struct nk_text_edit *state, char const *ctext, int len) -{ - /* API paste: replace existing selection with passed-in text */ - int glyphs; - const char *text = (const char *)ctext; - if (state->mode == NK_TEXT_EDIT_MODE_VIEW) { - return 0; - } - - /* if there's a selection, the paste should delete it */ - nk_textedit_clamp(state); - nk_textedit_delete_selection(state); - - /* try to insert the characters */ - glyphs = nk_utf_len(ctext, len); - if (nk_str_insert_text_char(&state->string, state->cursor, text, len)) { - nk_textedit_makeundo_insert(state, state->cursor, glyphs); - state->cursor += glyphs; - state->cursor_affinity = NK_TEXT_AFFINITY_TRAILING; - state->has_preferred_x = 0; - return 1; - } - /* remove the undo since we didn't actually insert the characters */ - if (state->undo.undo_point) { - --state->undo.undo_point; - } - return 0; -} -NK_API void -nk_textedit_text(struct nk_text_edit *state, const char *text, int total_len) -{ - nk_rune unicode; - int glyph_len; - int text_len = 0; - - NK_ASSERT(state); - NK_ASSERT(text); - if (!text || !total_len || state->mode == NK_TEXT_EDIT_MODE_VIEW) { - return; - } - - glyph_len = nk_utf_decode(text, &unicode, total_len); - while ((text_len < total_len) && glyph_len) { - /* don't insert a backward delete, just process the event */ - if (unicode == 127) { - goto next; - } - /* can't add newline in single-line mode */ - if (unicode == '\n' && state->single_line) { - goto next; - } - /* filter incoming text */ - if (state->filter && !state->filter(state, unicode)) { - goto next; - } - - if (!NK_TEXT_HAS_SELECTION(state) && state->cursor < state->string.len) { - if (state->mode == NK_TEXT_EDIT_MODE_REPLACE) { - nk_textedit_makeundo_replace(state, state->cursor, 1, 1); - nk_str_delete_runes(&state->string, state->cursor, 1); - } - if (nk_str_insert_text_utf8(&state->string, state->cursor, text + text_len, 1)) { - ++state->cursor; - state->cursor_affinity = NK_TEXT_AFFINITY_TRAILING; - state->has_preferred_x = 0; - } - } else { - nk_textedit_delete_selection(state); /* implicitly clamps */ - if (nk_str_insert_text_utf8(&state->string, state->cursor, text + text_len, 1)) { - nk_textedit_makeundo_insert(state, state->cursor, 1); - state->cursor = NK_MIN(state->cursor + 1, state->string.len); - state->cursor_affinity = NK_TEXT_AFFINITY_TRAILING; - state->has_preferred_x = 0; - } - } - next: - text_len += glyph_len; - glyph_len = nk_utf_decode(text + text_len, &unicode, total_len - text_len); - } -} -NK_LIB void -nk_textedit_key(struct nk_text_edit *state, enum nk_keys key, int shift_mod, const struct nk_user_font *font, float row_height) -{ -retry: - switch (key) { - case NK_KEY_NONE: - case NK_KEY_CTRL: - case NK_KEY_ENTER: - case NK_KEY_SHIFT: - case NK_KEY_TAB: - case NK_KEY_COPY: - case NK_KEY_CUT: - case NK_KEY_PASTE: - case NK_KEY_MAX: - default: - break; - case NK_KEY_TEXT_UNDO: - nk_textedit_undo(state); - state->has_preferred_x = 0; - break; - - case NK_KEY_TEXT_REDO: - nk_textedit_redo(state); - state->has_preferred_x = 0; - break; - - case NK_KEY_TEXT_SELECT_ALL: - nk_textedit_select_all(state); - state->has_preferred_x = 0; - break; - - case NK_KEY_TEXT_INSERT_MODE: - state->mode = NK_TEXT_EDIT_MODE_INSERT; - break; - case NK_KEY_TEXT_REPLACE_MODE: - state->mode = NK_TEXT_EDIT_MODE_REPLACE; - break; - case NK_KEY_TEXT_RESET_MODE: - state->mode = NK_TEXT_EDIT_MODE_VIEW; - break; - - case NK_KEY_LEFT: - if (shift_mod) { - nk_textedit_clamp(state); - nk_textedit_prep_selection_at_cursor(state); - /* move selection left */ - state->select_end = nk_textedit_move_visual(state, font, row_height, -1); - state->cursor = state->select_end; - state->has_preferred_x = 0; - } else { - /* if currently there's a selection, - * move cursor to start of selection */ - if (NK_TEXT_HAS_SELECTION(state)) { - nk_textedit_collapse_visual(state, font, row_height, -1); - } else { - state->cursor = nk_textedit_move_visual(state, font, row_height, -1); - } - state->has_preferred_x = 0; - } - break; - - case NK_KEY_RIGHT: - if (shift_mod) { - nk_textedit_prep_selection_at_cursor(state); - /* move selection right */ - state->select_end = nk_textedit_move_visual(state, font, row_height, 1); - nk_textedit_clamp(state); - state->cursor = state->select_end; - state->has_preferred_x = 0; - } else { - /* if currently there's a selection, - * move cursor to end of selection */ - if (NK_TEXT_HAS_SELECTION(state)) { - nk_textedit_collapse_visual(state, font, row_height, 1); - } else { - state->cursor = nk_textedit_move_visual(state, font, row_height, 1); - } - nk_textedit_clamp(state); - state->has_preferred_x = 0; - } - break; - - case NK_KEY_TEXT_WORD_LEFT: - if (shift_mod) { - if (!NK_TEXT_HAS_SELECTION(state)) { - nk_textedit_prep_selection_at_cursor(state); - } - state->cursor = nk_textedit_move_to_boundary(state, font, NK_TEXT_BOUNDARY_WORD, nk_false); - state->select_end = state->cursor; - state->cursor_affinity = state->cursor ? NK_TEXT_AFFINITY_TRAILING : NK_TEXT_AFFINITY_LEADING; - nk_textedit_clamp(state); - } else { - if (NK_TEXT_HAS_SELECTION(state)) { - nk_textedit_move_to_first(state); - } else { - state->cursor = nk_textedit_move_to_boundary(state, font, NK_TEXT_BOUNDARY_WORD, nk_false); - state->cursor_affinity = state->cursor ? NK_TEXT_AFFINITY_TRAILING : NK_TEXT_AFFINITY_LEADING; - nk_textedit_clamp(state); - } - } - break; - - case NK_KEY_TEXT_WORD_RIGHT: - if (shift_mod) { - if (!NK_TEXT_HAS_SELECTION(state)) { - nk_textedit_prep_selection_at_cursor(state); - } - state->cursor = nk_textedit_move_to_boundary(state, font, NK_TEXT_BOUNDARY_WORD, nk_true); - state->select_end = state->cursor; - state->cursor_affinity = state->cursor ? NK_TEXT_AFFINITY_TRAILING : NK_TEXT_AFFINITY_LEADING; - nk_textedit_clamp(state); - } else { - if (NK_TEXT_HAS_SELECTION(state)) { - nk_textedit_move_to_last(state); - } else { - state->cursor = nk_textedit_move_to_boundary(state, font, NK_TEXT_BOUNDARY_WORD, nk_true); - state->cursor_affinity = state->cursor ? NK_TEXT_AFFINITY_TRAILING : NK_TEXT_AFFINITY_LEADING; - nk_textedit_clamp(state); - } - } - break; - - case NK_KEY_DOWN: { - struct nk_text_find find; - int sel = shift_mod; - - if (state->single_line) { - /* on windows, up&down in single-line behave like left&right */ - key = NK_KEY_RIGHT; - goto retry; - } - - if (sel) { - nk_textedit_prep_selection_at_cursor(state); - } else if (NK_TEXT_HAS_SELECTION(state)) { - nk_textedit_move_to_last(state); - } - - /* compute current position of cursor point */ - nk_textedit_clamp(state); - nk_textedit_find_charpos(&find, state, state->cursor, state->single_line, font, row_height, - (enum nk_text_affinity)state->cursor_affinity); - - /* find the closest visual caret on the next row */ - if (find.length) { - enum nk_text_affinity affinity; - float goal_x = state->has_preferred_x ? state->preferred_x : find.x; - - state->cursor = nk_textedit_locate_coord(state, goal_x, find.y + find.height + 0.5f, - font, row_height, &affinity); - state->cursor_affinity = (unsigned char)affinity; - - state->has_preferred_x = 1; - state->preferred_x = goal_x; - if (sel) { - state->select_end = state->cursor; - } - } - } break; - - case NK_KEY_UP: { - struct nk_text_find find; - int sel = shift_mod; - - if (state->single_line) { - /* on windows, up&down become left&right */ - key = NK_KEY_LEFT; - goto retry; - } - - if (sel) { - nk_textedit_prep_selection_at_cursor(state); - } else if (NK_TEXT_HAS_SELECTION(state)) { - nk_textedit_move_to_first(state); - } - - /* compute current position of cursor point */ - nk_textedit_clamp(state); - nk_textedit_find_charpos(&find, state, state->cursor, state->single_line, font, row_height, - (enum nk_text_affinity)state->cursor_affinity); - - /* can only go up if there's a previous row */ - if (find.prev_first != find.first_char) { - enum nk_text_affinity affinity; - float goal_x = state->has_preferred_x ? state->preferred_x : find.x; - - state->cursor = nk_textedit_locate_coord(state, goal_x, find.y - 0.5f, - font, row_height, &affinity); - state->cursor_affinity = (unsigned char)affinity; - - state->has_preferred_x = 1; - state->preferred_x = goal_x; - if (sel) { - state->select_end = state->cursor; - } - } - } break; - - case NK_KEY_DEL: - if (state->mode == NK_TEXT_EDIT_MODE_VIEW) { - break; - } - if (NK_TEXT_HAS_SELECTION(state)) { - nk_textedit_delete_selection(state); - } else { - int n = state->string.len; - if (state->cursor < n) { - int next = nk_textedit_move_to_boundary(state, font, NK_TEXT_BOUNDARY_GRAPHEME, nk_true); - nk_textedit_delete(state, state->cursor, next - state->cursor); - } - } - state->has_preferred_x = 0; - break; - - case NK_KEY_BACKSPACE: - if (state->mode == NK_TEXT_EDIT_MODE_VIEW) { - break; - } - if (NK_TEXT_HAS_SELECTION(state)) { - nk_textedit_delete_selection(state); - } else { - nk_textedit_clamp(state); - if (state->cursor > 0) { - int previous = nk_textedit_move_to_boundary(state, font, NK_TEXT_BOUNDARY_GRAPHEME, nk_false); - nk_textedit_delete(state, previous, state->cursor - previous); - state->cursor = previous; - state->cursor_affinity = state->cursor ? NK_TEXT_AFFINITY_TRAILING : NK_TEXT_AFFINITY_LEADING; - } - } - state->has_preferred_x = 0; - break; - - case NK_KEY_TEXT_START: - if (shift_mod) { - nk_textedit_prep_selection_at_cursor(state); - state->cursor = state->select_end = 0; - state->cursor_affinity = NK_TEXT_AFFINITY_LEADING; - state->has_preferred_x = 0; - } else { - state->cursor = state->select_start = state->select_end = 0; - state->cursor_affinity = NK_TEXT_AFFINITY_LEADING; - state->select_start_affinity = NK_TEXT_AFFINITY_LEADING; - state->has_preferred_x = 0; - } - break; - - case NK_KEY_TEXT_END: - if (shift_mod) { - nk_textedit_prep_selection_at_cursor(state); - state->cursor = state->select_end = state->string.len; - state->cursor_affinity = NK_TEXT_AFFINITY_TRAILING; - state->has_preferred_x = 0; - } else { - state->cursor = state->string.len; - state->cursor_affinity = NK_TEXT_AFFINITY_TRAILING; - state->select_start = state->select_end = state->cursor; - state->select_start_affinity = state->cursor_affinity; - state->has_preferred_x = 0; - } - break; - - case NK_KEY_TEXT_LINE_START: { - if (shift_mod) { - struct nk_text_find find; - nk_textedit_clamp(state); - nk_textedit_prep_selection_at_cursor(state); - if (state->string.len && state->cursor == state->string.len) { - --state->cursor; - } - nk_textedit_find_charpos(&find, state, state->cursor, state->single_line, font, row_height, - (enum nk_text_affinity)state->cursor_affinity); - state->cursor = state->select_end = find.first_char; - state->cursor_affinity = NK_TEXT_AFFINITY_LEADING; - state->has_preferred_x = 0; - } else { - struct nk_text_find find; - if (state->string.len && state->cursor == state->string.len) { - --state->cursor; - } - nk_textedit_clamp(state); - nk_textedit_move_to_first(state); - nk_textedit_find_charpos(&find, state, state->cursor, state->single_line, font, row_height, - (enum nk_text_affinity)state->cursor_affinity); - state->cursor = find.first_char; - state->cursor_affinity = NK_TEXT_AFFINITY_LEADING; - state->select_start = state->select_end = state->cursor; - state->select_start_affinity = state->cursor_affinity; - state->has_preferred_x = 0; - } - } break; - - case NK_KEY_TEXT_LINE_END: { - if (shift_mod) { - struct nk_text_find find; - nk_textedit_clamp(state); - nk_textedit_prep_selection_at_cursor(state); - nk_textedit_find_charpos(&find, state, state->cursor, state->single_line, font, row_height, - (enum nk_text_affinity)state->cursor_affinity); - state->has_preferred_x = 0; - state->cursor = find.first_char + find.length; - if (find.length > 0 && nk_str_rune_at(&state->string, state->cursor - 1) == '\n') { - --state->cursor; - } - state->select_end = state->cursor; - state->cursor_affinity = NK_TEXT_AFFINITY_TRAILING; - } else { - struct nk_text_find find; - nk_textedit_clamp(state); - nk_textedit_move_to_first(state); - nk_textedit_find_charpos(&find, state, state->cursor, state->single_line, font, row_height, - (enum nk_text_affinity)state->cursor_affinity); - - state->has_preferred_x = 0; - state->cursor = find.first_char + find.length; - if (find.length > 0 && nk_str_rune_at(&state->string, state->cursor - 1) == '\n') { - --state->cursor; - } - state->cursor_affinity = NK_TEXT_AFFINITY_TRAILING; - state->select_start = state->select_end = state->cursor; - state->select_start_affinity = state->cursor_affinity; - } - } break; - - case NK_KEY_TEXT_WORD_DELETE_LEFT: { - if (state->mode == NK_TEXT_EDIT_MODE_VIEW) { - break; - } - - if (NK_TEXT_HAS_SELECTION(state)) { - nk_textedit_delete_selection(state); - } else { - int old_cursor; - - nk_textedit_clamp(state); - old_cursor = state->cursor; - - if (old_cursor > 0) { - int new_cursor = nk_textedit_move_to_boundary(state, font, NK_TEXT_BOUNDARY_WORD, nk_false); - if (new_cursor < old_cursor) { - nk_textedit_delete(state, new_cursor, old_cursor - new_cursor); - state->cursor = new_cursor; - state->cursor_affinity = state->cursor ? NK_TEXT_AFFINITY_TRAILING : NK_TEXT_AFFINITY_LEADING; - } - } - } - - state->has_preferred_x = 0; - } break; - - case NK_KEY_TEXT_WORD_DELETE_RIGHT: { - if (state->mode == NK_TEXT_EDIT_MODE_VIEW) { - break; - } - - if (NK_TEXT_HAS_SELECTION(state)) { - nk_textedit_delete_selection(state); - } else { - int old_cursor; - int new_cursor; - - nk_textedit_clamp(state); - old_cursor = state->cursor; - - new_cursor = nk_textedit_move_to_boundary(state, font, NK_TEXT_BOUNDARY_WORD, nk_true); - nk_textedit_clamp(state); - - if (new_cursor > old_cursor) { - nk_textedit_delete(state, old_cursor, new_cursor - old_cursor); - state->cursor = old_cursor; - state->cursor_affinity = state->cursor ? NK_TEXT_AFFINITY_TRAILING : NK_TEXT_AFFINITY_LEADING; - } - } - - state->has_preferred_x = 0; - } break; - } -} -NK_INTERN void -nk_textedit_flush_redo(struct nk_text_undo_state *state) -{ - state->redo_point = NK_TEXTEDIT_UNDOSTATECOUNT; - state->redo_char_point = NK_TEXTEDIT_UNDOCHARCOUNT; -} -NK_INTERN void -nk_textedit_discard_undo(struct nk_text_undo_state *state) -{ - /* discard the oldest entry in the undo list */ - if (state->undo_point > 0) { - /* if the 0th undo state has characters, clean those up */ - if (state->undo_rec[0].char_storage >= 0) { - int n = state->undo_rec[0].insert_length, i; - /* delete n characters from all other records */ - state->undo_char_point = (short)(state->undo_char_point - n); - NK_MEMCPY(state->undo_char, state->undo_char + n, (nk_size)state->undo_char_point * sizeof(nk_rune)); - for (i = 0; i < state->undo_point; ++i) { - if (state->undo_rec[i].char_storage >= 0) { - state->undo_rec[i].char_storage = (short)(state->undo_rec[i].char_storage - n); - } - } - } - --state->undo_point; - NK_MEMCPY(state->undo_rec, state->undo_rec + 1, (nk_size)((nk_size)state->undo_point * sizeof(state->undo_rec[0]))); - } -} -NK_INTERN void -nk_textedit_discard_redo(struct nk_text_undo_state *state) -{ - /* discard the oldest entry in the redo list--it's bad if this - ever happens, but because undo & redo have to store the actual - characters in different cases, the redo character buffer can - fill up even though the undo buffer didn't */ - nk_size num; - int k = NK_TEXTEDIT_UNDOSTATECOUNT - 1; - if (state->redo_point <= k) { - /* if the k'th undo state has characters, clean those up */ - if (state->undo_rec[k].char_storage >= 0) { - int n = state->undo_rec[k].insert_length, i; - /* delete n characters from all other records */ - state->redo_char_point = (short)(state->redo_char_point + n); - num = (nk_size)(NK_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point); - NK_MEMCPY(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point - n, num * sizeof(char)); - for (i = state->redo_point; i < k; ++i) { - if (state->undo_rec[i].char_storage >= 0) { - state->undo_rec[i].char_storage = (short)(state->undo_rec[i].char_storage + n); - } - } - } - ++state->redo_point; - num = (nk_size)(NK_TEXTEDIT_UNDOSTATECOUNT - state->redo_point); - if (num) { - NK_MEMCPY(state->undo_rec + state->redo_point - 1, state->undo_rec + state->redo_point, num * sizeof(state->undo_rec[0])); - } - } -} -NK_INTERN struct nk_text_undo_record * -nk_textedit_create_undo_record(struct nk_text_undo_state *state, int numchars) -{ - /* any time we create a new undo record, we discard redo*/ - nk_textedit_flush_redo(state); - - /* if we have no free records, we have to make room, - * by sliding the existing records down */ - if (state->undo_point == NK_TEXTEDIT_UNDOSTATECOUNT) { - nk_textedit_discard_undo(state); - } - - /* if the characters to store won't possibly fit in the buffer, - * we can't undo */ - if (numchars > NK_TEXTEDIT_UNDOCHARCOUNT) { - state->undo_point = 0; - state->undo_char_point = 0; - return 0; - } - - /* if we don't have enough free characters in the buffer, - * we have to make room */ - while (state->undo_char_point + numchars > NK_TEXTEDIT_UNDOCHARCOUNT) { - nk_textedit_discard_undo(state); - } - return &state->undo_rec[state->undo_point++]; -} -NK_INTERN nk_rune * -nk_textedit_createundo(struct nk_text_undo_state *state, int pos, int insert_len, int delete_len) -{ - struct nk_text_undo_record *r = nk_textedit_create_undo_record(state, insert_len); - if (r == 0) { - return 0; - } - - r->where = pos; - r->insert_length = (short)insert_len; - r->delete_length = (short)delete_len; - - if (insert_len == 0) { - r->char_storage = -1; - return 0; - } else { - r->char_storage = state->undo_char_point; - state->undo_char_point = (short)(state->undo_char_point + insert_len); - return &state->undo_char[r->char_storage]; - } -} -NK_API void -nk_textedit_undo(struct nk_text_edit *state) -{ - struct nk_text_undo_state *s = &state->undo; - struct nk_text_undo_record u, *r; - if (s->undo_point == 0) { - return; - } - - /* we need to do two things: apply the undo record, and create a redo record */ - u = s->undo_rec[s->undo_point - 1]; - r = &s->undo_rec[s->redo_point - 1]; - r->char_storage = -1; - - r->insert_length = u.delete_length; - r->delete_length = u.insert_length; - r->where = u.where; - - if (u.delete_length) { - /* if the undo record says to delete characters, then the redo record will - need to re-insert the characters that get deleted, so we need to store - them. - there are three cases: - - there's enough room to store the characters - - characters stored for *redoing* don't leave room for redo - - characters stored for *undoing* don't leave room for redo - if the last is true, we have to bail */ - if (s->undo_char_point + u.delete_length >= NK_TEXTEDIT_UNDOCHARCOUNT) { - /* the undo records take up too much character space; there's no space - * to store the redo characters */ - r->insert_length = 0; - } else { - int i; - /* there's definitely room to store the characters eventually */ - while (s->undo_char_point + u.delete_length > s->redo_char_point) { - /* there's currently not enough room, so discard a redo record */ - nk_textedit_discard_redo(s); - /* should never happen: */ - if (s->redo_point == NK_TEXTEDIT_UNDOSTATECOUNT) { - return; - } - } - - r = &s->undo_rec[s->redo_point - 1]; - r->char_storage = (short)(s->redo_char_point - u.delete_length); - s->redo_char_point = (short)(s->redo_char_point - u.delete_length); - - /* now save the characters */ - for (i = 0; i < u.delete_length; ++i) { - s->undo_char[r->char_storage + i] = nk_str_rune_at(&state->string, u.where + i); - } - } - /* now we can carry out the deletion */ - nk_str_delete_runes(&state->string, u.where, u.delete_length); - } - - /* check type of recorded action: */ - if (u.insert_length) { - /* easy case: was a deletion, so we need to insert n characters */ - nk_str_insert_text_runes(&state->string, u.where, &s->undo_char[u.char_storage], u.insert_length); - s->undo_char_point = (short)(s->undo_char_point - u.insert_length); - } - state->cursor = (short)(u.where + u.insert_length); - - s->undo_point--; - s->redo_point--; -} -NK_API void -nk_textedit_redo(struct nk_text_edit *state) -{ - struct nk_text_undo_state *s = &state->undo; - struct nk_text_undo_record *u, r; - if (s->redo_point == NK_TEXTEDIT_UNDOSTATECOUNT) { - return; - } - - /* we need to do two things: apply the redo record, and create an undo record */ - u = &s->undo_rec[s->undo_point]; - r = s->undo_rec[s->redo_point]; - - /* we KNOW there must be room for the undo record, because the redo record - was derived from an undo record */ - u->delete_length = r.insert_length; - u->insert_length = r.delete_length; - u->where = r.where; - u->char_storage = -1; - - if (r.delete_length) { - /* the redo record requires us to delete characters, so the undo record - needs to store the characters */ - if (s->undo_char_point + u->insert_length > s->redo_char_point) { - u->insert_length = 0; - u->delete_length = 0; - } else { - int i; - u->char_storage = s->undo_char_point; - s->undo_char_point = (short)(s->undo_char_point + u->insert_length); - - /* now save the characters */ - for (i = 0; i < u->insert_length; ++i) { - s->undo_char[u->char_storage + i] = nk_str_rune_at(&state->string, u->where + i); - } - } - nk_str_delete_runes(&state->string, r.where, r.delete_length); - } - - if (r.insert_length) { - /* easy case: need to insert n characters */ - nk_str_insert_text_runes(&state->string, r.where, &s->undo_char[r.char_storage], r.insert_length); - } - state->cursor = r.where + r.insert_length; - - s->undo_point++; - s->redo_point++; -} -NK_INTERN void -nk_textedit_makeundo_insert(struct nk_text_edit *state, int where, int length) -{ - nk_textedit_createundo(&state->undo, where, 0, length); -} -NK_INTERN void -nk_textedit_makeundo_delete(struct nk_text_edit *state, int where, int length) -{ - int i; - nk_rune *p = nk_textedit_createundo(&state->undo, where, length, 0); - if (p) { - for (i = 0; i < length; ++i) { - p[i] = nk_str_rune_at(&state->string, where + i); - } - } -} -NK_INTERN void -nk_textedit_makeundo_replace(struct nk_text_edit *state, int where, int old_length, int new_length) -{ - int i; - nk_rune *p = nk_textedit_createundo(&state->undo, where, old_length, new_length); - if (p) { - for (i = 0; i < old_length; ++i) { - p[i] = nk_str_rune_at(&state->string, where + i); - } - } -} -NK_LIB void -nk_textedit_clear_state(struct nk_text_edit *state, enum nk_text_edit_type type, nk_plugin_filter filter) -{ - /* reset the state to default */ - state->undo.undo_point = 0; - state->undo.undo_char_point = 0; - state->undo.redo_point = NK_TEXTEDIT_UNDOSTATECOUNT; - state->undo.redo_char_point = NK_TEXTEDIT_UNDOCHARCOUNT; - state->select_end = state->select_start = 0; - state->cursor = 0; - state->has_preferred_x = 0; - state->preferred_x = 0; - state->cursor_at_end_of_line = 0; - state->cursor_affinity = NK_TEXT_AFFINITY_LEADING; - state->select_start_affinity = NK_TEXT_AFFINITY_LEADING; - state->initialized = 1; - state->single_line = (unsigned char)(type == NK_TEXT_EDIT_SINGLE_LINE); - state->mode = NK_TEXT_EDIT_MODE_VIEW; - state->filter = filter; - state->scrollbar = nk_vec2(0, 0); - state->scrollbar_prev_max = nk_vec2(0, 0); - state->scrollbar_flags = 0; -} -NK_API void -nk_textedit_init_fixed(struct nk_text_edit *state, void *memory, nk_size size) -{ - NK_ASSERT(state); - NK_ASSERT(memory); - if (!state || !memory || !size) { - return; - } - NK_MEMSET(state, 0, sizeof(struct nk_text_edit)); - nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0); - nk_str_init_fixed(&state->string, memory, size); -} -NK_API void -nk_textedit_init(struct nk_text_edit *state, const struct nk_allocator *alloc, nk_size size) -{ - NK_ASSERT(state); - NK_ASSERT(alloc); - if (!state || !alloc) { - return; - } - NK_MEMSET(state, 0, sizeof(struct nk_text_edit)); - nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0); - nk_str_init(&state->string, alloc, size); -} -#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR -NK_API void -nk_textedit_init_default(struct nk_text_edit *state) -{ - NK_ASSERT(state); - if (!state) { - return; - } - NK_MEMSET(state, 0, sizeof(struct nk_text_edit)); - nk_textedit_clear_state(state, NK_TEXT_EDIT_SINGLE_LINE, 0); - nk_str_init_default(&state->string); -} -#endif -NK_API void -nk_textedit_select_all(struct nk_text_edit *state) -{ - NK_ASSERT(state); - state->select_start = 0; - state->select_end = state->string.len; - state->cursor = state->select_end; - state->select_start_affinity = NK_TEXT_AFFINITY_LEADING; - state->cursor_affinity = NK_TEXT_AFFINITY_TRAILING; -} -NK_API void -nk_textedit_free(struct nk_text_edit *state) -{ - NK_ASSERT(state); - if (!state) { - return; - } - nk_str_free(&state->string); -} - -/* =============================================================== - * - * FILTER - * - * ===============================================================*/ -NK_API nk_bool -nk_filter_default(const struct nk_text_edit *box, nk_rune unicode) -{ - NK_UNUSED(unicode); - NK_UNUSED(box); - return nk_true; -} -NK_API nk_bool -nk_filter_ascii(const struct nk_text_edit *box, nk_rune unicode) -{ - NK_UNUSED(box); - if (unicode > 128) { - return nk_false; - } else { - return nk_true; - } -} -NK_API nk_bool -nk_filter_float(const struct nk_text_edit *box, nk_rune unicode) -{ - NK_UNUSED(box); - if ((unicode < '0' || unicode > '9') && unicode != '.' && unicode != '-') { - return nk_false; - } else { - return nk_true; - } -} -NK_API nk_bool -nk_filter_decimal(const struct nk_text_edit *box, nk_rune unicode) -{ - NK_UNUSED(box); - if ((unicode < '0' || unicode > '9') && unicode != '-') { - return nk_false; - } else { - return nk_true; - } -} -NK_API nk_bool -nk_filter_hex(const struct nk_text_edit *box, nk_rune unicode) -{ - NK_UNUSED(box); - if ((unicode < '0' || unicode > '9') && (unicode < 'a' || unicode > 'f') && (unicode < 'A' || unicode > 'F')) { - return nk_false; - } else { - return nk_true; - } -} -NK_API nk_bool -nk_filter_oct(const struct nk_text_edit *box, nk_rune unicode) -{ - NK_UNUSED(box); - if (unicode < '0' || unicode > '7') { - return nk_false; - } else { - return nk_true; - } -} -NK_API nk_bool -nk_filter_binary(const struct nk_text_edit *box, nk_rune unicode) -{ - NK_UNUSED(box); - if (unicode != '0' && unicode != '1') { - return nk_false; - } else { - return nk_true; - } -} - -/* =============================================================== - * - * EDIT - * - * ===============================================================*/ -NK_LIB void -nk_edit_draw_text(struct nk_command_buffer *out, - const struct nk_style_edit *style, - float pos_x, - float pos_y, - float x_offset, - const char *text, - int byte_len, - float row_height, - const struct nk_user_font *font, - struct nk_color background, - struct nk_color foreground, - nk_bool is_selected) -{ - NK_ASSERT(out); - NK_ASSERT(font); - NK_ASSERT(style); - if (!text || !byte_len || !out || !style) { - return; - } - - { - int glyph_len = 0; - nk_rune unicode = 0; - int text_len = 0; - float line_width = 0; - const char *line = text; - float line_offset = 0; - int line_count = 0; - - struct nk_text txt; - txt.padding = nk_vec2(0, 0); - txt.background = background; - txt.text = foreground; - - foreground = nk_rgb_factor(foreground, style->color_factor); - background = nk_rgb_factor(background, style->color_factor); - - glyph_len = nk_utf_decode(text + text_len, &unicode, byte_len - text_len); - if (!glyph_len) { - return; - } - while ((text_len < byte_len) && glyph_len) { - if (unicode == '\n') { - /* new line separator so draw previous line */ - struct nk_rect label; - line_width = nk_text_width(out->context, font, out->context->style.font_size, line, (int)((text + text_len) - line)); - label.y = pos_y + line_offset; - label.h = row_height; - label.w = line_width; - label.x = pos_x; - if (!line_count) { - label.x += x_offset; - } - - if (is_selected) { /* selection needs to draw different background color */ - nk_fill_rect(out, label, 0, background); - } - nk_widget_text(out, label, line, (int)((text + text_len) - line), &txt, NK_TEXT_CENTERED, font); - - text_len++; - line_count++; - line_width = 0; - line = text + text_len; - line_offset += row_height; - glyph_len = nk_utf_decode(text + text_len, &unicode, (int)(byte_len - text_len)); - continue; - } - if (unicode == '\r') { - text_len++; - glyph_len = nk_utf_decode(text + text_len, &unicode, byte_len - text_len); - continue; - } - text_len += glyph_len; - glyph_len = nk_utf_decode(text + text_len, &unicode, byte_len - text_len); - continue; - } - line_width = nk_text_width(out->context, font, out->context->style.font_size, line, (int)((text + text_len) - line)); - if (line_width > 0) { - /* draw last line */ - struct nk_rect label; - label.y = pos_y + line_offset; - label.h = row_height; - label.w = line_width; - label.x = pos_x; - if (!line_count) { - label.x += x_offset; - } - - if (is_selected) { - nk_fill_rect(out, label, 0, background); - } - nk_widget_text(out, label, line, (int)((text + text_len) - line), &txt, NK_TEXT_LEFT, font); - } - } -} -NK_INTERN void -nk_edit_draw_text_selection(struct nk_command_buffer *out, const struct nk_style_edit *style, - float pos_x, float pos_y, struct nk_text_edit *edit, float row_height, - const struct nk_user_font *font, struct nk_color background, struct nk_color foreground, - struct nk_color selected_background, struct nk_color selected_foreground) -{ - const char *text = nk_str_get_const(&edit->string); - int text_len = nk_str_len_char(&edit->string); - int selection_begin = nk_textedit_byte_offset(edit, NK_MIN(edit->select_start, edit->select_end)); - int selection_end = nk_textedit_byte_offset(edit, NK_MAX(edit->select_start, edit->select_end)); - int line_begin = 0; - int line_idx = 0; - - nk_edit_draw_text(out, style, pos_x, pos_y, 0, text, text_len, row_height, font, background, foreground, nk_false); - while (line_begin < text_len && selection_begin != selection_end) { - struct nk_text_selection_iterator iterator; - struct nk_text_selection_span span; - struct nk_text_shape *shape; - int line_end = line_begin; - int select_begin; - int select_end; - - while (line_end < text_len && text[line_end] != '\n') { - line_end += 1; - } - - select_begin = NK_CLAMP(line_begin, selection_begin, line_end) - line_begin; - select_end = NK_CLAMP(line_begin, selection_end, line_end) - line_begin; - shape = nk_text_shape_build_default(out->context, font, out->context->style.font_size, - text + line_begin, line_end - line_begin); - - if (shape && select_begin < select_end) { - nk_text_selection_iterator_begin(&iterator, shape, select_begin, select_end); - while (nk_text_selection_iterator_next(&iterator, &span)) { - struct nk_rect selection = nk_rect(pos_x + span.x, pos_y + line_idx * row_height, span.width, row_height); - struct nk_rect old_clip = out->clip; - struct nk_rect span_clip; - struct nk_text selected; - - nk_fill_rect(out, selection, 0, selected_background); - nk_unify(&span_clip, &old_clip, selection.x, selection.y, selection.x + selection.w, selection.y + selection.h); - nk_push_scissor(out, span_clip); - - selected.padding = nk_vec2(0, 0); - selected.background = selected_background; - selected.text = selected_foreground; - nk_draw_text(out, nk_rect(pos_x, selection.y, shape->advance.x, row_height), - text + line_begin, line_end - line_begin, font, selected.background, selected.text); - nk_push_scissor(out, old_clip); - } - } - - line_begin = line_end + 1; - line_idx += 1; - } -} -NK_LIB nk_flags -nk_do_edit(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect bounds, - nk_flags flags, - nk_plugin_filter filter, - struct nk_text_edit *edit, - const struct nk_style_edit *style, - struct nk_input *in, - const struct nk_user_font *font) -{ - struct nk_rect area; - nk_flags ret = 0; - float row_height; - char prev_state = 0; - char is_hovered = 0; - char select_all = 0; - char cursor_follow = 0; - struct nk_rect old_clip; - struct nk_rect clip; - - NK_ASSERT(state); - NK_ASSERT(out); - NK_ASSERT(style); - if (!state || !out || !style) { - return ret; - } - edit->context = out->context; - - /* visible text area calculation */ - area.x = bounds.x + style->padding.x + style->border; - area.y = bounds.y + style->padding.y + style->border; - area.w = bounds.w - (2.0f * style->padding.x + 2 * style->border); - area.h = bounds.h - (2.0f * style->padding.y + 2 * style->border); - if (flags & NK_EDIT_MULTILINE) { - area.w = NK_MAX(0, area.w - style->scrollbar_size.x); - } - row_height = (flags & NK_EDIT_MULTILINE) ? out->context->style.font_size + style->row_padding : area.h; - - /* calculate clipping rectangle */ - old_clip = out->clip; - nk_unify(&clip, &old_clip, area.x, area.y, area.x + area.w, area.y + area.h); - - /* update edit state */ - prev_state = (char)edit->active; - if (in && in->mouse.buttons[NK_BUTTON_LEFT].clicked && in->mouse.buttons[NK_BUTTON_LEFT].down) { - edit->active = NK_INBOX(in->mouse.pos.x, in->mouse.pos.y, bounds.x, bounds.y, bounds.w, bounds.h); - } - - /* (de)activate text editor */ - if (!prev_state && edit->active) { - const enum nk_text_edit_type type = (flags & NK_EDIT_MULTILINE) ? NK_TEXT_EDIT_MULTI_LINE : NK_TEXT_EDIT_SINGLE_LINE; - /* keep scroll position when re-activating edit widget */ - struct nk_vec2 oldscrollbar = edit->scrollbar; - struct nk_vec2 oldscrollbar_prev_max = edit->scrollbar_prev_max; - nk_uint oldscrollbar_flags = edit->scrollbar_flags; - - nk_textedit_clear_state(edit, type, filter); - - edit->scrollbar = oldscrollbar; - edit->scrollbar_prev_max = oldscrollbar_prev_max; - edit->scrollbar_flags = oldscrollbar_flags; - - if (flags & NK_EDIT_AUTO_SELECT) { - select_all = nk_true; - } - - if (flags & NK_EDIT_GOTO_END_ON_ACTIVATE) { - edit->cursor = edit->string.len; - in = 0; - } - } else if (!edit->active) { - edit->mode = NK_TEXT_EDIT_MODE_VIEW; - } - - if (flags & NK_EDIT_READ_ONLY) { - edit->mode = NK_TEXT_EDIT_MODE_VIEW; - } else if (flags & NK_EDIT_ALWAYS_INSERT_MODE) { - edit->mode = NK_TEXT_EDIT_MODE_INSERT; - } - - ret = (edit->active) ? NK_EDIT_ACTIVE : NK_EDIT_INACTIVE; - if (prev_state != edit->active) { - ret |= (edit->active) ? NK_EDIT_ACTIVATED : NK_EDIT_DEACTIVATED; - } - - /* handle user input */ - if (edit->active && in) { - int shift_mod = in->keyboard.keys[NK_KEY_SHIFT].down; - const float mouse_x = (in->mouse.pos.x - area.x) + edit->scrollbar.x; - const float mouse_y = (in->mouse.pos.y - area.y) + edit->scrollbar.y; - - /* mouse click handler */ - is_hovered = (char)nk_input_is_mouse_hovering_rect(in, area); - if (select_all) { - nk_textedit_select_all(edit); - } else if (is_hovered && in->mouse.buttons[NK_BUTTON_LEFT].down && in->mouse.buttons[NK_BUTTON_LEFT].clicked) { - nk_textedit_click(edit, mouse_x, mouse_y, font, row_height); - } else if (is_hovered && in->mouse.buttons[NK_BUTTON_LEFT].down && nk_input_is_mouse_moved(in)) { - nk_textedit_drag(edit, mouse_x, mouse_y, font, row_height); - cursor_follow = nk_true; - } else if (is_hovered && in->mouse.buttons[NK_BUTTON_RIGHT].clicked && in->mouse.buttons[NK_BUTTON_RIGHT].down) { - nk_textedit_key(edit, NK_KEY_TEXT_WORD_LEFT, nk_false, font, row_height); - nk_textedit_key(edit, NK_KEY_TEXT_WORD_RIGHT, nk_true, font, row_height); - cursor_follow = nk_true; - } - - { - int i; /* keyboard input */ - int old_mode = edit->mode; - for (i = 0; i < NK_KEY_MAX; ++i) { - if (i == NK_KEY_ENTER || i == NK_KEY_TAB) { - continue; /* special case */ - } - if (nk_input_is_key_pressed(in, (enum nk_keys)i)) { - int old_cursor = edit->cursor; - int old_length = edit->string.len; - short old_undo_point = edit->undo.undo_point; - short old_redo_point = edit->undo.redo_point; - - nk_textedit_key(edit, (enum nk_keys)i, shift_mod, font, row_height); - if ((i != NK_KEY_TEXT_SELECT_ALL) && - (edit->cursor != old_cursor || - edit->string.len != old_length || - edit->undo.undo_point != old_undo_point || - edit->undo.redo_point != old_redo_point)) { - cursor_follow = nk_true; - } - } - } - if (old_mode != edit->mode) { - in->keyboard.text_len = 0; - } - } - - /* text input */ - edit->filter = filter; - if (in->keyboard.text_len) { - nk_textedit_text(edit, in->keyboard.text, in->keyboard.text_len); - cursor_follow = nk_true; - in->keyboard.text_len = 0; - } - - /* enter key handler */ - if (nk_input_is_key_pressed(in, NK_KEY_ENTER)) { - cursor_follow = nk_true; - if (flags & NK_EDIT_CTRL_ENTER_NEWLINE && shift_mod) { - nk_textedit_text(edit, "\n", 1); - } else if (flags & NK_EDIT_SIG_ENTER) { - ret |= NK_EDIT_COMMITED; - } else { - nk_textedit_text(edit, "\n", 1); - } - } - - /* cut & copy handler */ - { - int copy = nk_input_is_key_pressed(in, NK_KEY_COPY); - int cut = nk_input_is_key_pressed(in, NK_KEY_CUT); - if ((copy || cut) && (flags & NK_EDIT_CLIPBOARD)) { - int begin = NK_MIN(edit->select_start, edit->select_end); - int end = NK_MAX(edit->select_start, edit->select_end); - if (edit->clip.copy) { - int glyph_len; - nk_rune unicode; - const char *text_begin, *text_end; - text_begin = nk_str_at_const(&edit->string, begin, &unicode, &glyph_len); - text_end = nk_str_at_const(&edit->string, end, &unicode, &glyph_len); - edit->clip.copy(edit->clip.userdata, text_begin, (int)(text_end - text_begin)); - } - if (cut && !(flags & NK_EDIT_READ_ONLY)) { - nk_textedit_cut(edit); - cursor_follow = nk_true; - } - } - } - - /* paste handler */ - { - int paste = nk_input_is_key_pressed(in, NK_KEY_PASTE); - if (paste && (flags & NK_EDIT_CLIPBOARD) && edit->clip.paste) { - edit->clip.paste(edit->clip.userdata, edit); - cursor_follow = nk_true; - } - } - - /* tab handler */ - { - int tab = nk_input_is_key_pressed(in, NK_KEY_TAB); - if (tab && (flags & NK_EDIT_ALLOW_TAB)) { - nk_textedit_text(edit, " ", 4); - cursor_follow = nk_true; - } - } - } - - /* set widget state */ - if (edit->active) { - *state = NK_WIDGET_STATE_ACTIVE; - } else { - nk_widget_state_reset(state); - } - - if (is_hovered) { - *state |= NK_WIDGET_STATE_HOVERED; - } - - /* DRAW EDIT */ - { - const char *text = nk_str_get_const(&edit->string); - int len = nk_str_len_char(&edit->string); - - { /* select background colors/images */ - const struct nk_style_item *background; - if (*state & NK_WIDGET_STATE_ACTIVED) { - background = &style->active; - } else if (*state & NK_WIDGET_STATE_HOVER) { - background = &style->hover; - } else { - background = &style->normal; - } - - /* draw background frame */ - switch (background->type) { - case NK_STYLE_ITEM_IMAGE: - nk_draw_image(out, bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor)); - break; - case NK_STYLE_ITEM_NINE_SLICE: - nk_draw_nine_slice(out, bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor)); - break; - case NK_STYLE_ITEM_COLOR: - nk_fill_rect(out, bounds, style->rounding, nk_rgb_factor(background->data.color, style->color_factor)); - nk_stroke_rect(out, bounds, style->rounding, style->border, nk_rgb_factor(style->border_color, style->color_factor)); - break; - } - } - - area.w = NK_MAX(0, area.w - style->cursor_size); - if (edit->active) { - int total_lines = 1; - struct nk_vec2 text_size = nk_vec2(0, 0); - struct nk_vec2 cursor_pos = nk_vec2(0, 0); - - if (text && len) { - int line_begin = 0; - int line_end; - - for (line_end = 0; line_end < len; ++line_end) { - if (text[line_end] == '\n') { - float width = nk_text_width(out->context, font, out->context->style.font_size, - text + line_begin, line_end - line_begin); - text_size.x = NK_MAX(text_size.x, width); - line_begin = line_end + 1; - total_lines += 1; - } - } - text_size.x = NK_MAX(text_size.x, nk_text_width(out->context, font, out->context->style.font_size, - text + line_begin, len - line_begin)); - text_size.y = (float)total_lines * row_height; - } - { - struct nk_text_find cursor_find; - nk_textedit_find_charpos(&cursor_find, edit, edit->cursor, edit->single_line, font, row_height, - (enum nk_text_affinity)edit->cursor_affinity); - cursor_pos.x = cursor_find.x; - cursor_pos.y = cursor_find.y; - } - { - /* scrollbar */ - if (cursor_follow) { - /* update scrollbar to follow cursor */ - if (!(flags & NK_EDIT_NO_HORIZONTAL_SCROLL)) { - /* horizontal scroll */ - const float scroll_increment = area.w * 0.25f; - if (cursor_pos.x < edit->scrollbar.x) { - edit->scrollbar.x = (float)(int)NK_MAX(0.0f, cursor_pos.x - scroll_increment); - } - if (cursor_pos.x >= edit->scrollbar.x + area.w) { - edit->scrollbar.x = (float)(int)NK_MAX(0.0f, cursor_pos.x - area.w + scroll_increment); - } - } else { - edit->scrollbar.x = 0; - } - - if (flags & NK_EDIT_MULTILINE) { - /* vertical scroll: like horizontal, it only adjusts if the - * cursor leaves the visible area, and then only just enough - * to keep it visible */ - if (cursor_pos.y < edit->scrollbar.y) { - edit->scrollbar.y = NK_MAX(0.0f, cursor_pos.y); - } - if (cursor_pos.y > edit->scrollbar.y + area.h - row_height) { - edit->scrollbar.y = edit->scrollbar.y + row_height; - } - } else { - edit->scrollbar.y = 0; - } - } - - /* scrollbar widget */ - if (flags & NK_EDIT_MULTILINE) { - nk_flags ws; - struct nk_rect scroll; - float scroll_target; - float scroll_offset; - float scroll_step; - float scroll_inc; - float old_max_offset; - float new_max_offset; - - scroll = area; - scroll.x = (bounds.x + bounds.w - style->border) - style->scrollbar_size.x; - scroll.w = style->scrollbar_size.x; - - scroll_offset = edit->scrollbar.y; - scroll_step = scroll.h * 0.10f; - scroll_inc = scroll.h * 0.01f; - scroll_target = text_size.y; - - old_max_offset = edit->scrollbar_prev_max.y; - new_max_offset = NK_MAX(scroll_target - scroll.h, 0.0f); - - if ((edit->scrollbar_flags & NK_SCROLL_HAS_PREV_MAX_Y) && scroll_offset >= NK_MAX(old_max_offset - 1.0f, 0.0f) && new_max_offset > old_max_offset) { - scroll_offset = new_max_offset; - } - - edit->scrollbar.y = nk_do_scrollbarv(&ws, out, scroll, is_hovered, scroll_offset, scroll_target, scroll_step, scroll_inc, &style->scrollbar, in, font); - edit->scrollbar_prev_max.y = new_max_offset; - edit->scrollbar_flags |= NK_SCROLL_HAS_PREV_MAX_Y; - - /* Eat mouse scroll if we're active */ - if (in && is_hovered && in->mouse.scroll_delta.y) { - in->mouse.scroll_delta.y = 0; - } - } - } - - /* draw text */ - { - struct nk_color background_color; - struct nk_color text_color; - struct nk_color sel_background_color; - struct nk_color sel_text_color; - struct nk_color cursor_color; - const struct nk_style_item *background; - nk_push_scissor(out, clip); - - /* select correct colors to draw */ - if (*state & NK_WIDGET_STATE_ACTIVED) { - background = &style->active; - text_color = style->text_active; - sel_text_color = style->selected_text_hover; - sel_background_color = style->selected_hover; - cursor_color = style->cursor_hover; - } else if (*state & NK_WIDGET_STATE_HOVER) { - background = &style->hover; - text_color = style->text_hover; - sel_text_color = style->selected_text_hover; - sel_background_color = style->selected_hover; - cursor_color = style->cursor_hover; - } else { - background = &style->normal; - text_color = style->text_normal; - sel_text_color = style->selected_text_normal; - sel_background_color = style->selected_normal; - cursor_color = style->cursor_normal; - } - if (background->type == NK_STYLE_ITEM_IMAGE) { - background_color = nk_rgba(0, 0, 0, 0); - } else { - background_color = background->data.color; - } - - cursor_color = nk_rgb_factor(cursor_color, style->color_factor); - - nk_edit_draw_text_selection(out, style, area.x - edit->scrollbar.x, area.y - edit->scrollbar.y, - edit, row_height, font, background_color, text_color, - sel_background_color, sel_text_color); - - /* cursor */ - if (edit->select_start == edit->select_end) { - struct nk_rect cursor; - cursor.w = style->cursor_size; - cursor.h = out->context->style.font_size; - cursor.x = area.x + cursor_pos.x - edit->scrollbar.x; - cursor.y = area.y + cursor_pos.y + row_height / 2.0f - cursor.h / 2.0f - edit->scrollbar.y; - nk_fill_rect(out, cursor, 0, cursor_color); - } - } - } else { - /* not active so just draw text */ - int l = nk_str_len_char(&edit->string); - const char *begin = nk_str_get_const(&edit->string); - - const struct nk_style_item *background; - struct nk_color background_color; - struct nk_color text_color; - nk_push_scissor(out, clip); - if (*state & NK_WIDGET_STATE_ACTIVED) { - background = &style->active; - text_color = style->text_active; - } else if (*state & NK_WIDGET_STATE_HOVER) { - background = &style->hover; - text_color = style->text_hover; - } else { - background = &style->normal; - text_color = style->text_normal; - } - if (background->type == NK_STYLE_ITEM_IMAGE) { - background_color = nk_rgba(0, 0, 0, 0); - } else { - background_color = background->data.color; - } - - background_color = nk_rgb_factor(background_color, style->color_factor); - text_color = nk_rgb_factor(text_color, style->color_factor); - - nk_edit_draw_text(out, style, area.x - edit->scrollbar.x, area.y - edit->scrollbar.y, 0, begin, l, row_height, font, background_color, text_color, nk_false); - } - nk_push_scissor(out, old_clip); - } - return ret; -} -NK_API void -nk_edit_focus(struct nk_context *ctx, nk_flags flags) -{ - nk_hash hash; - struct nk_window *win; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) { - return; - } - - win = ctx->current; - hash = win->edit.seq; - win->edit.active = nk_true; - win->edit.name = hash; - if (flags & NK_EDIT_ALWAYS_INSERT_MODE) { - win->edit.mode = NK_TEXT_EDIT_MODE_INSERT; - } -} -NK_API void -nk_edit_unfocus(struct nk_context *ctx) -{ - struct nk_window *win; - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) { - return; - } - - win = ctx->current; - win->edit.active = nk_false; - win->edit.name = 0; -} -NK_API nk_flags -nk_edit_string(struct nk_context *ctx, nk_flags flags, char *memory, int *len, int max, nk_plugin_filter filter) -{ - nk_hash hash; - nk_flags state; - struct nk_text_edit *edit; - struct nk_window *win; - - NK_ASSERT(ctx); - NK_ASSERT(memory); - NK_ASSERT(len); - if (!ctx || !memory || !len) { - return 0; - } - - filter = (!filter) ? nk_filter_default : filter; - win = ctx->current; - hash = win->edit.seq; - edit = &ctx->text_edit; - nk_textedit_clear_state(&ctx->text_edit, (flags & NK_EDIT_MULTILINE) ? NK_TEXT_EDIT_MULTI_LINE : NK_TEXT_EDIT_SINGLE_LINE, filter); - - if (win->edit.active && hash == win->edit.name) { - if (flags & NK_EDIT_NO_CURSOR) { - edit->cursor = nk_utf_len(memory, *len); - } else { - edit->cursor = win->edit.cursor; - } - if (!(flags & NK_EDIT_SELECTABLE)) { - edit->select_start = win->edit.cursor; - edit->select_end = win->edit.cursor; - } else { - edit->select_start = win->edit.sel_start; - edit->select_end = win->edit.sel_end; - } - edit->mode = win->edit.mode; - edit->scrollbar.x = (float)win->edit.scrollbar.x; - edit->scrollbar.y = (float)win->edit.scrollbar.y; - edit->scrollbar_prev_max.x = (float)win->edit.scrollbar.prev_max_x; - edit->scrollbar_prev_max.y = (float)win->edit.scrollbar.prev_max_y; - edit->scrollbar_flags = win->edit.scrollbar.flags; - edit->active = nk_true; - } else { - edit->active = nk_false; - } - - max = NK_MAX(1, max); - *len = NK_MIN(*len, max - 1); - nk_str_init_fixed(&edit->string, memory, (nk_size)max); - edit->string.buffer.allocated = (nk_size)*len; - edit->string.len = nk_utf_len(memory, *len); - state = nk_edit_buffer(ctx, flags, edit, filter); - *len = (int)edit->string.buffer.allocated; - - if (edit->active) { - win->edit.cursor = edit->cursor; - win->edit.sel_start = edit->select_start; - win->edit.sel_end = edit->select_end; - win->edit.mode = edit->mode; - win->edit.scrollbar.x = (nk_uint)edit->scrollbar.x; - win->edit.scrollbar.y = (nk_uint)edit->scrollbar.y; - win->edit.scrollbar.prev_max_x = (nk_uint)edit->scrollbar_prev_max.x; - win->edit.scrollbar.prev_max_y = (nk_uint)edit->scrollbar_prev_max.y; - win->edit.scrollbar.flags = edit->scrollbar_flags; - } - return state; -} -NK_API nk_flags -nk_edit_buffer(struct nk_context *ctx, nk_flags flags, struct nk_text_edit *edit, nk_plugin_filter filter) -{ - struct nk_window *win; - struct nk_style *style; - struct nk_input *in; - - enum nk_widget_layout_states state; - struct nk_rect bounds; - - nk_flags ret_flags = 0; - unsigned char prev_state; - nk_hash hash; - - /* make sure correct values */ - NK_ASSERT(ctx); - NK_ASSERT(edit); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - win = ctx->current; - style = &ctx->style; - state = nk_widget(&bounds, ctx); - if (!state) { - return state; - } else if (state == NK_WIDGET_DISABLED) { - flags |= NK_EDIT_READ_ONLY; - } - in = (win->layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - - /* check if edit is currently hot item */ - hash = win->edit.seq++; - if (win->edit.active && hash == win->edit.name) { - if (flags & NK_EDIT_NO_CURSOR) { - edit->cursor = edit->string.len; - } - if (!(flags & NK_EDIT_SELECTABLE)) { - edit->select_start = edit->cursor; - edit->select_end = edit->cursor; - } - if (flags & NK_EDIT_CLIPBOARD) { - edit->clip = ctx->clip; - } - edit->active = (unsigned char)win->edit.active; - } else { - edit->active = nk_false; - } - edit->mode = win->edit.mode; - - filter = (!filter) ? nk_filter_default : filter; - prev_state = (unsigned char)edit->active; - in = (flags & NK_EDIT_READ_ONLY) ? 0 : in; - ret_flags = nk_do_edit(&ctx->last_widget_state, &win->buffer, bounds, flags, filter, edit, &style->edit, in, style->font); - - if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) { - ctx->style.cursor_active = ctx->style.cursors[NK_CURSOR_TEXT]; - } - if (edit->active && prev_state != edit->active) { - /* current edit is now hot */ - win->edit.active = nk_true; - win->edit.name = hash; - } else if (prev_state && !edit->active) { - /* current edit is now cold */ - win->edit.active = nk_false; - } - return ret_flags; -} -NK_API nk_flags -nk_edit_string_zero_terminated(struct nk_context *ctx, nk_flags flags, char *buffer, int max, nk_plugin_filter filter) -{ - nk_flags result; - int len = nk_strlen(buffer); - result = nk_edit_string(ctx, flags, buffer, &len, max, filter); - buffer[NK_MIN(NK_MAX(max - 1, 0), len)] = '\0'; - return result; -} - -/* =============================================================== - * - * PROPERTY - * - * ===============================================================*/ -NK_LIB void -nk_drag_behavior(nk_flags *state, const struct nk_input *in, struct nk_rect drag, struct nk_property_variant *variant, float inc_per_pixel) -{ - int left_mouse_down = in && in->mouse.buttons[NK_BUTTON_LEFT].down; - int left_mouse_click_in_cursor = in && nk_input_has_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, drag, nk_true); - - nk_widget_state_reset(state); - if (nk_input_is_mouse_hovering_rect(in, drag)) { - *state = NK_WIDGET_STATE_HOVERED; - } - - if (left_mouse_down && left_mouse_click_in_cursor) { - float delta, pixels; - pixels = in->mouse.delta.x; - delta = pixels * inc_per_pixel; - switch (variant->kind) { - default: - break; - case NK_PROPERTY_INT: - variant->value.i = variant->value.i + (int)delta; - variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i); - break; - case NK_PROPERTY_FLOAT: - variant->value.f = variant->value.f + (float)delta; - variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f); - break; - case NK_PROPERTY_DOUBLE: - variant->value.d = variant->value.d + (double)delta; - variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d); - break; - } - *state = NK_WIDGET_STATE_ACTIVE; - } - if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, drag)) { - *state |= NK_WIDGET_STATE_ENTERED; - } else if (nk_input_is_mouse_prev_hovering_rect(in, drag)) { - *state |= NK_WIDGET_STATE_LEFT; - } -} -NK_LIB void -nk_property_behavior(nk_flags *ws, - const struct nk_input *in, - struct nk_rect property, - struct nk_rect label, - struct nk_rect edit, - struct nk_rect empty, - int *state, - struct nk_property_variant *variant, - float inc_per_pixel) -{ - nk_widget_state_reset(ws); - if (in && *state == NK_PROPERTY_DEFAULT) { - if (nk_button_behavior(ws, edit, in, NK_BUTTON_DEFAULT)) { - *state = NK_PROPERTY_EDIT; - } else if (nk_input_is_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, label, nk_true)) { - *state = NK_PROPERTY_DRAG; - } else if (nk_input_is_mouse_click_down_in_rect(in, NK_BUTTON_LEFT, empty, nk_true)) { - *state = NK_PROPERTY_DRAG; - } - } - if (*state == NK_PROPERTY_DRAG) { - nk_drag_behavior(ws, in, property, variant, inc_per_pixel); - if (!(*ws & NK_WIDGET_STATE_ACTIVED)) { - *state = NK_PROPERTY_DEFAULT; - } - } -} -NK_LIB void -nk_draw_property(struct nk_command_buffer *out, - const struct nk_style_property *style, - const struct nk_rect *bounds, - const struct nk_rect *label, - nk_flags state, - const char *name, - int len, - const struct nk_user_font *font) -{ - struct nk_text text; - const struct nk_style_item *background; - - /* select correct background and text color */ - if (state & NK_WIDGET_STATE_ACTIVED) { - background = &style->active; - text.text = style->label_active; - } else if (state & NK_WIDGET_STATE_HOVER) { - background = &style->hover; - text.text = style->label_hover; - } else { - background = &style->normal; - text.text = style->label_normal; - } - - text.text = nk_rgb_factor(text.text, style->color_factor); - - /* draw background */ - switch (background->type) { - case NK_STYLE_ITEM_IMAGE: - text.background = nk_rgba(0, 0, 0, 0); - nk_draw_image(out, *bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor)); - break; - case NK_STYLE_ITEM_NINE_SLICE: - text.background = nk_rgba(0, 0, 0, 0); - nk_draw_nine_slice(out, *bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor)); - break; - case NK_STYLE_ITEM_COLOR: - text.background = background->data.color; - nk_fill_rect(out, *bounds, style->rounding, nk_rgb_factor(background->data.color, style->color_factor)); - nk_stroke_rect(out, *bounds, style->rounding, style->border, nk_rgb_factor(style->border_color, style->color_factor)); - break; - } - - /* draw label */ - text.padding = nk_vec2(0, 0); - if (name && name[0] != '#') { - nk_widget_text(out, *label, name, len, &text, NK_TEXT_CENTERED, font); - } -} -NK_INTERN void -nk_property_save(struct nk_property_variant *variant, char *buffer, int len) -{ - buffer[len] = '\0'; - switch (variant->kind) { - default: - break; - case NK_PROPERTY_INT: - variant->value.i = nk_strtoi(buffer, 0); - variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i, variant->max_value.i); - break; - case NK_PROPERTY_FLOAT: - nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION); - variant->value.f = nk_strtof(buffer, 0); - variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f, variant->max_value.f); - break; - case NK_PROPERTY_DOUBLE: - nk_string_float_limit(buffer, NK_MAX_FLOAT_PRECISION); - variant->value.d = NK_STRTOD(buffer, 0); - variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d, variant->max_value.d); - break; - } -} -NK_LIB void -nk_do_property(nk_flags *ws, - struct nk_command_buffer *out, - struct nk_rect property, - const char *name, - struct nk_property_variant *variant, - float inc_per_pixel, - char *buffer, - int *len, - int *state, - int *cursor, - int *select_begin, - int *select_end, - const struct nk_style_property *style, - enum nk_property_filter filter, - struct nk_input *in, - const struct nk_user_font *font, - struct nk_text_edit *text_edit, - enum nk_button_behavior behavior) -{ - const nk_plugin_filter filters[] = {nk_filter_decimal, nk_filter_float}; - nk_bool active, old; - int num_len = 0, name_len = 0; - char string[NK_MAX_NUMBER_BUFFER]; - float size; - - char *dst = 0; - int *length; - - struct nk_rect left; - struct nk_rect right; - struct nk_rect label; - struct nk_rect edit; - struct nk_rect empty; - - /* left decrement button */ - left.h = out->context->style.font_size / 2; - left.w = left.h; - left.x = property.x + style->border + style->padding.x; - left.y = property.y + style->border + property.h / 2.0f - left.h / 2; - - /* text label */ - if (name && name[0] != '#') { - name_len = nk_strlen(name); - } - size = nk_text_width(out->context, font, out->context->style.font_size, name, name_len); - label.x = left.x + left.w + style->padding.x; - label.w = (float)size + 2 * style->padding.x; - label.y = property.y + style->border + style->padding.y; - label.h = property.h - (2 * style->border + 2 * style->padding.y); - - /* right increment button */ - right.y = left.y; - right.w = left.w; - right.h = left.h; - right.x = property.x + property.w - (right.w + style->padding.x); - - /* edit */ - if (*state == NK_PROPERTY_EDIT) { - size = nk_text_width(out->context, font, out->context->style.font_size, buffer, *len); - size += style->edit.cursor_size; - length = len; - dst = buffer; - } else { - switch (variant->kind) { - default: - break; - case NK_PROPERTY_INT: - nk_itoa(string, variant->value.i); - num_len = nk_strlen(string); - break; - case NK_PROPERTY_FLOAT: - NK_DTOA(string, (double)variant->value.f); - num_len = nk_string_float_limit(string, NK_MAX_FLOAT_PRECISION); - break; - case NK_PROPERTY_DOUBLE: - NK_DTOA(string, variant->value.d); - num_len = nk_string_float_limit(string, NK_MAX_FLOAT_PRECISION); - break; - } - size = nk_text_width(out->context, font, out->context->style.font_size, string, num_len); - dst = string; - length = &num_len; - } - - edit.w = (float)size + 2 * style->padding.x; - edit.w = NK_MIN(edit.w, right.x - (label.x + label.w)); - edit.x = right.x - (edit.w + style->padding.x); - edit.y = property.y + style->border; - edit.h = property.h - (2 * style->border); - - /* empty left space activator */ - empty.w = edit.x - (label.x + label.w); - empty.x = label.x + label.w; - empty.y = property.y; - empty.h = property.h; - - /* update property */ - old = (*state == NK_PROPERTY_EDIT); - nk_property_behavior(ws, in, property, label, edit, empty, state, variant, inc_per_pixel); - - /* draw property */ - if (style->draw_begin) { - style->draw_begin(out, style->userdata); - } - nk_draw_property(out, style, &property, &label, *ws, name, name_len, font); - if (style->draw_end) { - style->draw_end(out, style->userdata); - } - - /* execute right button */ - if (nk_do_button_symbol(ws, out, left, style->sym_left, behavior, &style->dec_button, in, font)) { - switch (variant->kind) { - default: - break; - case NK_PROPERTY_INT: - variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i - variant->step.i, variant->max_value.i); - break; - case NK_PROPERTY_FLOAT: - variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f - variant->step.f, variant->max_value.f); - break; - case NK_PROPERTY_DOUBLE: - variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d - variant->step.d, variant->max_value.d); - break; - } - } - /* execute left button */ - if (nk_do_button_symbol(ws, out, right, style->sym_right, behavior, &style->inc_button, in, font)) { - switch (variant->kind) { - default: - break; - case NK_PROPERTY_INT: - variant->value.i = NK_CLAMP(variant->min_value.i, variant->value.i + variant->step.i, variant->max_value.i); - break; - case NK_PROPERTY_FLOAT: - variant->value.f = NK_CLAMP(variant->min_value.f, variant->value.f + variant->step.f, variant->max_value.f); - break; - case NK_PROPERTY_DOUBLE: - variant->value.d = NK_CLAMP(variant->min_value.d, variant->value.d + variant->step.d, variant->max_value.d); - break; - } - } - if (!old && (*state == NK_PROPERTY_EDIT)) { - /* property has been activated so setup buffer */ - NK_MEMCPY(buffer, dst, (nk_size)*length); - *cursor = nk_utf_len(buffer, *length); - *len = *length; - length = len; - dst = buffer; - active = 0; - } else { - active = (*state == NK_PROPERTY_EDIT); - } - - /* execute and run text edit field */ - nk_textedit_clear_state(text_edit, NK_TEXT_EDIT_SINGLE_LINE, filters[filter]); - text_edit->active = (unsigned char)active; - text_edit->string.len = *length; - text_edit->cursor = NK_CLAMP(0, *cursor, *length); - text_edit->select_start = NK_CLAMP(0, *select_begin, *length); - text_edit->select_end = NK_CLAMP(0, *select_end, *length); - text_edit->string.buffer.allocated = (nk_size)*length; - text_edit->string.buffer.memory.size = NK_MAX_NUMBER_BUFFER; - text_edit->string.buffer.memory.ptr = dst; - text_edit->string.buffer.size = NK_MAX_NUMBER_BUFFER; - text_edit->mode = NK_TEXT_EDIT_MODE_INSERT; - nk_do_edit(ws, out, edit, NK_EDIT_ALWAYS_INSERT_MODE | NK_EDIT_SELECTABLE | NK_EDIT_CLIPBOARD | NK_EDIT_AUTO_SELECT, filters[filter], text_edit, &style->edit, (*state == NK_PROPERTY_EDIT) ? in : 0, font); - - *length = text_edit->string.len; - *cursor = text_edit->cursor; - *select_begin = text_edit->select_start; - *select_end = text_edit->select_end; - if (text_edit->active && nk_input_is_key_pressed(in, NK_KEY_ENTER)) { - text_edit->active = nk_false; - } - - if (active && !text_edit->active) { - /* property is now not active so convert edit text to value*/ - *state = NK_PROPERTY_DEFAULT; - nk_property_save(variant, buffer, *len); - } -} -NK_LIB struct nk_property_variant -nk_property_variant_int(int value, int min_value, int max_value, int step) -{ - struct nk_property_variant result; - result.kind = NK_PROPERTY_INT; - result.value.i = value; - result.min_value.i = min_value; - result.max_value.i = max_value; - result.step.i = step; - return result; -} -NK_LIB struct nk_property_variant -nk_property_variant_float(float value, float min_value, float max_value, float step) -{ - struct nk_property_variant result; - result.kind = NK_PROPERTY_FLOAT; - result.value.f = value; - result.min_value.f = min_value; - result.max_value.f = max_value; - result.step.f = step; - return result; -} -NK_LIB struct nk_property_variant -nk_property_variant_double(double value, double min_value, double max_value, double step) -{ - struct nk_property_variant result; - result.kind = NK_PROPERTY_DOUBLE; - result.value.d = value; - result.min_value.d = min_value; - result.max_value.d = max_value; - result.step.d = step; - return result; -} -NK_LIB void -nk_property(struct nk_context *ctx, const char *name, struct nk_property_variant *variant, float inc_per_pixel, const enum nk_property_filter filter) -{ - struct nk_window *win; - struct nk_panel *layout; - struct nk_input *in; - const struct nk_style *style; - - struct nk_rect bounds; - enum nk_widget_layout_states s; - nk_bool hot; - - int *state = 0; - nk_hash hash = 0; - char *buffer = 0; - int *len = 0; - int *cursor = 0; - int *select_begin = 0; - int *select_end = 0; - int old_state; - int prev_state; - - char dummy_buffer[NK_MAX_NUMBER_BUFFER]; - int dummy_state = NK_PROPERTY_DEFAULT; - int dummy_length = 0; - int dummy_cursor = 0; - int dummy_select_begin = 0; - int dummy_select_end = 0; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - - win = ctx->current; - layout = win->layout; - style = &ctx->style; - s = nk_widget(&bounds, ctx); - if (!s) { - return; - } - - /* calculate hash from name */ - if (name[0] == '#') { - hash = nk_murmur_hash(name, (int)nk_strlen(name), win->property.seq++); - name++; /* special number hash */ - } else { - hash = nk_murmur_hash(name, (int)nk_strlen(name), 42); - } - - /* check if property is previously hot */ - if (win->property.prev_state == NK_PROPERTY_EDIT && hash == win->property.prev_name) { - nk_property_save(variant, win->property.prev_buffer, win->property.prev_length); - win->property.prev_state = NK_PROPERTY_DEFAULT; - } - - /* check if property is currently hot item */ - hot = win->property.active && hash == win->property.name; - if (hot) { - buffer = win->property.buffer; - len = &win->property.length; - cursor = &win->property.cursor; - state = &win->property.state; - select_begin = &win->property.select_start; - select_end = &win->property.select_end; - } else { - buffer = dummy_buffer; - len = &dummy_length; - cursor = &dummy_cursor; - state = &dummy_state; - select_begin = &dummy_select_begin; - select_end = &dummy_select_end; - } - - /* execute property widget */ - old_state = *state; - prev_state = win->property.state; - ctx->text_edit.clip = ctx->clip; - in = ((s == NK_WIDGET_ROM && !win->property.active) || layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_DISABLED) ? 0 : &ctx->input; - nk_do_property(&ctx->last_widget_state, - &win->buffer, - bounds, - name, - variant, - inc_per_pixel, - buffer, - len, - state, - cursor, - select_begin, - select_end, - &style->property, - filter, - in, - style->font, - &ctx->text_edit, - ctx->button_behavior); - - if (in && *state != NK_PROPERTY_DEFAULT && !hot) { - /* another property was active */ - if (win->property.active /* && hash != win->property.name */) { - win->property.prev_state = prev_state; - win->property.prev_name = win->property.name; - win->property.prev_length = win->property.length; - NK_MEMCPY(win->property.prev_buffer, win->property.buffer, (nk_size)win->property.length); - } - /* current property is now hot */ - win->property.active = 1; - NK_MEMCPY(win->property.buffer, buffer, (nk_size)*len); - win->property.length = *len; - win->property.cursor = *cursor; - win->property.state = *state; - win->property.name = hash; - win->property.select_start = *select_begin; - win->property.select_end = *select_end; - win->edit.active = nk_true; - if (*state == NK_PROPERTY_DRAG) { - ctx->input.mouse.grab = nk_true; - ctx->input.mouse.grabbed = nk_true; - } - } - /* check if previously active property is now inactive */ - if (*state == NK_PROPERTY_DEFAULT && old_state != NK_PROPERTY_DEFAULT) { - if (old_state == NK_PROPERTY_DRAG) { - ctx->input.mouse.grab = nk_false; - ctx->input.mouse.grabbed = nk_false; - ctx->input.mouse.ungrab = nk_true; - } - win->property.select_start = 0; - win->property.select_end = 0; - win->property.active = 0; - win->edit.active = nk_false; - } -} -NK_API nk_bool -nk_property_int(struct nk_context *ctx, const char *name, int min, int *val, int max, int step, float inc_per_pixel) -{ - struct nk_property_variant variant; - nk_bool changed; - NK_ASSERT(ctx); - NK_ASSERT(name); - NK_ASSERT(val); - - if (!ctx || !ctx->current || !name || !val) { - return nk_false; - } - variant = nk_property_variant_int(*val, min, max, step); - nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_INT); - changed = variant.value.i != *val; - *val = variant.value.i; - return changed; -} -NK_API nk_bool -nk_property_float(struct nk_context *ctx, const char *name, float min, float *val, float max, float step, float inc_per_pixel) -{ - struct nk_property_variant variant; - nk_bool changed; - NK_ASSERT(ctx); - NK_ASSERT(name); - NK_ASSERT(val); - - if (!ctx || !ctx->current || !name || !val) { - return nk_false; - } - variant = nk_property_variant_float(*val, min, max, step); - nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT); - changed = variant.value.f != *val; - *val = variant.value.f; - return changed; -} -NK_API nk_bool -nk_property_double(struct nk_context *ctx, const char *name, double min, double *val, double max, double step, float inc_per_pixel) -{ - struct nk_property_variant variant; - nk_bool changed; - NK_ASSERT(ctx); - NK_ASSERT(name); - NK_ASSERT(val); - - if (!ctx || !ctx->current || !name || !val) { - return nk_false; - } - variant = nk_property_variant_double(*val, min, max, step); - nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT); - changed = variant.value.d != *val; - *val = variant.value.d; - return changed; -} -NK_API int -nk_propertyi(struct nk_context *ctx, const char *name, int min, int val, int max, int step, float inc_per_pixel) -{ - struct nk_property_variant variant; - NK_ASSERT(ctx); - NK_ASSERT(name); - - if (!ctx || !ctx->current || !name) { - return val; - } - variant = nk_property_variant_int(val, min, max, step); - nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_INT); - val = variant.value.i; - return val; -} -NK_API float -nk_propertyf(struct nk_context *ctx, const char *name, float min, float val, float max, float step, float inc_per_pixel) -{ - struct nk_property_variant variant; - NK_ASSERT(ctx); - NK_ASSERT(name); - - if (!ctx || !ctx->current || !name) { - return val; - } - variant = nk_property_variant_float(val, min, max, step); - nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT); - val = variant.value.f; - return val; -} -NK_API double -nk_propertyd(struct nk_context *ctx, const char *name, double min, double val, double max, double step, float inc_per_pixel) -{ - struct nk_property_variant variant; - NK_ASSERT(ctx); - NK_ASSERT(name); - - if (!ctx || !ctx->current || !name) { - return val; - } - variant = nk_property_variant_double(val, min, max, step); - nk_property(ctx, name, &variant, inc_per_pixel, NK_FILTER_FLOAT); - val = variant.value.d; - return val; -} - -/* ============================================================== - * - * CHART - * - * ===============================================================*/ -NK_API nk_bool -nk_chart_begin_colored(struct nk_context *ctx, enum nk_chart_type type, struct nk_color color, struct nk_color highlight, int count, float min_value, float max_value) -{ - struct nk_window *win; - struct nk_chart *chart; - const struct nk_style *config; - const struct nk_style_chart *style; - - const struct nk_style_item *background; - struct nk_rect bounds = {0, 0, 0, 0}; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - if (!nk_widget(&bounds, ctx)) { - chart = &ctx->current->layout->chart; - nk_zero(chart, sizeof(*chart)); - return 0; - } - - win = ctx->current; - config = &ctx->style; - chart = &win->layout->chart; - style = &config->chart; - - /* setup basic generic chart */ - nk_zero(chart, sizeof(*chart)); - chart->x = bounds.x + style->padding.x; - chart->y = bounds.y + style->padding.y; - chart->w = bounds.w - 2 * style->padding.x; - chart->h = bounds.h - 2 * style->padding.y; - chart->w = NK_MAX(chart->w, 2 * style->padding.x); - chart->h = NK_MAX(chart->h, 2 * style->padding.y); - - /* add first slot into chart */ - { - struct nk_chart_slot *slot = &chart->slots[chart->slot++]; - slot->type = type; - slot->count = count; - slot->color = nk_rgb_factor(color, style->color_factor); - slot->highlight = highlight; - slot->min = NK_MIN(min_value, max_value); - slot->max = NK_MAX(min_value, max_value); - slot->range = slot->max - slot->min; - slot->show_markers = style->show_markers; - } - - /* draw chart background */ - background = &style->background; - - switch (background->type) { - case NK_STYLE_ITEM_IMAGE: - nk_draw_image(&win->buffer, bounds, &background->data.image, nk_rgb_factor(nk_white, style->color_factor)); - break; - case NK_STYLE_ITEM_NINE_SLICE: - nk_draw_nine_slice(&win->buffer, bounds, &background->data.slice, nk_rgb_factor(nk_white, style->color_factor)); - break; - case NK_STYLE_ITEM_COLOR: - nk_fill_rect(&win->buffer, bounds, style->rounding, nk_rgb_factor(style->border_color, style->color_factor)); - nk_fill_rect(&win->buffer, nk_shrink_rect(bounds, style->border), style->rounding, nk_rgb_factor(style->background.data.color, style->color_factor)); - break; - } - return 1; -} -NK_API nk_bool -nk_chart_begin(struct nk_context *ctx, const enum nk_chart_type type, int count, float min_value, float max_value) -{ - return nk_chart_begin_colored(ctx, type, ctx->style.chart.color, ctx->style.chart.selected_color, count, min_value, max_value); -} -NK_API void -nk_chart_add_slot_colored(struct nk_context *ctx, const enum nk_chart_type type, struct nk_color color, struct nk_color highlight, int count, float min_value, float max_value) -{ - const struct nk_style_chart *style; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - NK_ASSERT(ctx->current->layout->chart.slot < NK_CHART_MAX_SLOT); - if (!ctx || !ctx->current || !ctx->current->layout) { - return; - } - if (ctx->current->layout->chart.slot >= NK_CHART_MAX_SLOT) { - return; - } - - style = &ctx->style.chart; - - /* add another slot into the graph */ - { - struct nk_chart *chart = &ctx->current->layout->chart; - struct nk_chart_slot *slot = &chart->slots[chart->slot++]; - slot->type = type; - slot->count = count; - slot->color = nk_rgb_factor(color, style->color_factor); - slot->highlight = highlight; - slot->min = NK_MIN(min_value, max_value); - slot->max = NK_MAX(min_value, max_value); - slot->range = slot->max - slot->min; - slot->show_markers = style->show_markers; - } -} -NK_API void -nk_chart_add_slot(struct nk_context *ctx, const enum nk_chart_type type, int count, float min_value, float max_value) -{ - nk_chart_add_slot_colored(ctx, type, ctx->style.chart.color, ctx->style.chart.selected_color, count, min_value, max_value); -} -NK_INTERN nk_flags -nk_chart_push_line(struct nk_context *ctx, struct nk_window *win, struct nk_chart *g, float value, int slot) -{ - struct nk_panel *layout = win->layout; - const struct nk_input *i = ctx->current->widgets_disabled ? 0 : &ctx->input; - struct nk_command_buffer *out = &win->buffer; - - nk_flags ret = 0; - struct nk_vec2 cur; - struct nk_rect bounds; - struct nk_color color; - float step; - float range; - float ratio; - - NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT); - step = g->w / (float)g->slots[slot].count; - range = g->slots[slot].max - g->slots[slot].min; - ratio = (value - g->slots[slot].min) / range; - - if (g->slots[slot].index == 0) { - /* first data point does not have a connection */ - g->slots[slot].last.x = g->x; - g->slots[slot].last.y = (g->y + g->h) - ratio * (float)g->h; - - bounds.x = g->slots[slot].last.x - 2; - bounds.y = g->slots[slot].last.y - 2; - bounds.w = bounds.h = 4; - - color = g->slots[slot].color; - if (!(layout->flags & NK_WINDOW_ROM) && i && NK_INBOX(i->mouse.pos.x, i->mouse.pos.y, g->slots[slot].last.x - 3, g->slots[slot].last.y - 3, 6, 6)) { - ret = nk_input_is_mouse_hovering_rect(i, bounds) ? NK_CHART_HOVERING : 0; - ret |= (i->mouse.buttons[NK_BUTTON_LEFT].down && i->mouse.buttons[NK_BUTTON_LEFT].clicked) ? NK_CHART_CLICKED : 0; - color = g->slots[slot].highlight; - } - if (g->slots[slot].show_markers) { - nk_fill_rect(out, bounds, 0, color); - } - g->slots[slot].index += 1; - return ret; - } - - /* draw a line between the last data point and the new one */ - color = g->slots[slot].color; - cur.x = g->x + (float)(step * (float)g->slots[slot].index); - cur.y = (g->y + g->h) - (ratio * (float)g->h); - nk_stroke_line(out, g->slots[slot].last.x, g->slots[slot].last.y, cur.x, cur.y, 1.0f, color); - - bounds.x = cur.x - 3; - bounds.y = cur.y - 3; - bounds.w = bounds.h = 6; - - /* user selection of current data point */ - if (!(layout->flags & NK_WINDOW_ROM)) { - if (nk_input_is_mouse_hovering_rect(i, bounds)) { - ret = NK_CHART_HOVERING; - ret |= (!i->mouse.buttons[NK_BUTTON_LEFT].down && i->mouse.buttons[NK_BUTTON_LEFT].clicked) ? NK_CHART_CLICKED : 0; - color = g->slots[slot].highlight; - } - } - if (g->slots[slot].show_markers) { - nk_fill_rect(out, nk_rect(cur.x - 2, cur.y - 2, 4, 4), 0, color); - } - - /* save current data point position */ - g->slots[slot].last.x = cur.x; - g->slots[slot].last.y = cur.y; - g->slots[slot].index += 1; - return ret; -} -NK_INTERN nk_flags -nk_chart_push_column(const struct nk_context *ctx, struct nk_window *win, struct nk_chart *chart, float value, int slot) -{ - struct nk_command_buffer *out = &win->buffer; - const struct nk_input *in = ctx->current->widgets_disabled ? 0 : &ctx->input; - struct nk_panel *layout = win->layout; - - float ratio; - nk_flags ret = 0; - struct nk_color color; - struct nk_rect item = {0, 0, 0, 0}; - - NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT); - if (chart->slots[slot].index >= chart->slots[slot].count) { - return nk_false; - } - if (chart->slots[slot].count) { - float padding = (float)(chart->slots[slot].count - 1); - item.w = (chart->w - padding) / (float)(chart->slots[slot].count); - } - - /* calculate bounds of current bar chart entry */ - color = chart->slots[slot].color; - item.h = chart->h * NK_ABS((value / chart->slots[slot].range)); - if (value >= 0) { - ratio = (value + NK_ABS(chart->slots[slot].min)) / NK_ABS(chart->slots[slot].range); - item.y = (chart->y + chart->h) - chart->h * ratio; - } else { - ratio = (value - chart->slots[slot].max) / chart->slots[slot].range; - item.y = chart->y + (chart->h * NK_ABS(ratio)) - item.h; - } - item.x = chart->x + ((float)chart->slots[slot].index * item.w); - item.x = item.x + ((float)chart->slots[slot].index); - - /* user chart bar selection */ - if (!(layout->flags & NK_WINDOW_ROM) && in && NK_INBOX(in->mouse.pos.x, in->mouse.pos.y, item.x, item.y, item.w, item.h)) { - ret = NK_CHART_HOVERING; - ret |= (!in->mouse.buttons[NK_BUTTON_LEFT].down && in->mouse.buttons[NK_BUTTON_LEFT].clicked) ? NK_CHART_CLICKED : 0; - color = chart->slots[slot].highlight; - } - nk_fill_rect(out, item, 0, color); - chart->slots[slot].index += 1; - return ret; -} -NK_API nk_flags -nk_chart_push_slot(struct nk_context *ctx, float value, int slot) -{ - nk_flags flags; - struct nk_window *win; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(slot >= 0 && slot < NK_CHART_MAX_SLOT); - NK_ASSERT(slot < ctx->current->layout->chart.slot); - if (!ctx || !ctx->current || slot >= NK_CHART_MAX_SLOT) { - return nk_false; - } - if (slot >= ctx->current->layout->chart.slot) { - return nk_false; - } - - win = ctx->current; - if (win->layout->chart.slot < slot) { - return nk_false; - } - switch (win->layout->chart.slots[slot].type) { - case NK_CHART_LINES: - flags = nk_chart_push_line(ctx, win, &win->layout->chart, value, slot); - break; - case NK_CHART_COLUMN: - flags = nk_chart_push_column(ctx, win, &win->layout->chart, value, slot); - break; - default: - case NK_CHART_MAX: - flags = 0; - } - return flags; -} -NK_API nk_flags -nk_chart_push(struct nk_context *ctx, float value) -{ - return nk_chart_push_slot(ctx, value, 0); -} -NK_API void -nk_chart_end(struct nk_context *ctx) -{ - struct nk_window *win; - struct nk_chart *chart; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) { - return; - } - - win = ctx->current; - chart = &win->layout->chart; - NK_MEMSET(chart, 0, sizeof(*chart)); - return; -} -NK_API void -nk_plot(struct nk_context *ctx, enum nk_chart_type type, const float *values, int count, int offset) -{ - int i = 0; - float min_value; - float max_value; - - NK_ASSERT(ctx); - NK_ASSERT(values); - if (!ctx || !values || !count) { - return; - } - - min_value = values[offset]; - max_value = values[offset]; - for (i = 0; i < count; ++i) { - min_value = NK_MIN(values[i + offset], min_value); - max_value = NK_MAX(values[i + offset], max_value); - } - - if (nk_chart_begin(ctx, type, count, min_value, max_value)) { - for (i = 0; i < count; ++i) { - nk_chart_push(ctx, values[i + offset]); - } - nk_chart_end(ctx); - } -} -NK_API void -nk_plot_function(struct nk_context *ctx, enum nk_chart_type type, void *userdata, float (*value_getter)(void *user, int index), int count, int offset) -{ - int i = 0; - float min_value; - float max_value; - - NK_ASSERT(ctx); - NK_ASSERT(value_getter); - if (!ctx || !value_getter || !count) { - return; - } - - max_value = min_value = value_getter(userdata, offset); - for (i = 0; i < count; ++i) { - float value = value_getter(userdata, i + offset); - min_value = NK_MIN(value, min_value); - max_value = NK_MAX(value, max_value); - } - - if (nk_chart_begin(ctx, type, count, min_value, max_value)) { - for (i = 0; i < count; ++i) { - nk_chart_push(ctx, value_getter(userdata, i + offset)); - } - nk_chart_end(ctx); - } -} - -/* ============================================================== - * - * COLOR PICKER - * - * ===============================================================*/ -NK_LIB nk_bool -nk_color_picker_behavior(nk_flags *state, - const struct nk_rect *bounds, - const struct nk_rect *matrix, - const struct nk_rect *hue_bar, - const struct nk_rect *alpha_bar, - struct nk_colorf *color, - const struct nk_input *in) -{ - float hsva[4]; - nk_bool value_changed = 0; - nk_bool hsv_changed = 0; - - NK_ASSERT(state); - NK_ASSERT(matrix); - NK_ASSERT(hue_bar); - NK_ASSERT(color); - - /* color matrix */ - nk_colorf_hsva_fv(hsva, *color); - if (nk_button_behavior(state, *matrix, in, NK_BUTTON_REPEATER)) { - hsva[1] = NK_SATURATE((in->mouse.pos.x - matrix->x) / (matrix->w - 1)); - hsva[2] = 1.0f - NK_SATURATE((in->mouse.pos.y - matrix->y) / (matrix->h - 1)); - value_changed = hsv_changed = 1; - } - /* hue bar */ - if (nk_button_behavior(state, *hue_bar, in, NK_BUTTON_REPEATER)) { - hsva[0] = NK_SATURATE((in->mouse.pos.y - hue_bar->y) / (hue_bar->h - 1)); - value_changed = hsv_changed = 1; - } - /* alpha bar */ - if (alpha_bar) { - if (nk_button_behavior(state, *alpha_bar, in, NK_BUTTON_REPEATER)) { - hsva[3] = 1.0f - NK_SATURATE((in->mouse.pos.y - alpha_bar->y) / (alpha_bar->h - 1)); - value_changed = 1; - } - } - nk_widget_state_reset(state); - if (hsv_changed) { - *color = nk_hsva_colorfv(hsva); - *state = NK_WIDGET_STATE_ACTIVE; - } - if (value_changed) { - color->a = hsva[3]; - *state = NK_WIDGET_STATE_ACTIVE; - } - /* set color picker widget state */ - if (nk_input_is_mouse_hovering_rect(in, *bounds)) { - *state = NK_WIDGET_STATE_HOVERED; - } - if (*state & NK_WIDGET_STATE_HOVER && !nk_input_is_mouse_prev_hovering_rect(in, *bounds)) { - *state |= NK_WIDGET_STATE_ENTERED; - } else if (nk_input_is_mouse_prev_hovering_rect(in, *bounds)) { - *state |= NK_WIDGET_STATE_LEFT; - } - return value_changed; -} -NK_LIB void -nk_draw_color_picker(struct nk_command_buffer *o, const struct nk_rect *matrix, const struct nk_rect *hue_bar, const struct nk_rect *alpha_bar, struct nk_colorf col) -{ - NK_STORAGE const struct nk_color black = {0, 0, 0, 255}; - NK_STORAGE const struct nk_color white = {255, 255, 255, 255}; - NK_STORAGE const struct nk_color black_trans = {0, 0, 0, 0}; - - const float crosshair_size = 7.0f; - struct nk_color temp; - float hsva[4]; - float line_y; - int i; - - NK_ASSERT(o); - NK_ASSERT(matrix); - NK_ASSERT(hue_bar); - - /* draw hue bar */ - nk_colorf_hsva_fv(hsva, col); - for (i = 0; i < 6; ++i) { - NK_GLOBAL const struct nk_color hue_colors[] = { - {255, 0, 0, 255}, {255, 255, 0, 255}, {0, 255, 0, 255}, {0, 255, 255, 255}, {0, 0, 255, 255}, {255, 0, 255, 255}, {255, 0, 0, 255}}; - nk_fill_rect_multi_color(o, - nk_rect(hue_bar->x, hue_bar->y + (float)i * (hue_bar->h / 6.0f) + 0.5f, hue_bar->w, (hue_bar->h / 6.0f) + 0.5f), - hue_colors[i], - hue_colors[i], - hue_colors[i + 1], - hue_colors[i + 1]); - } - line_y = (float)(int)(hue_bar->y + hsva[0] * matrix->h + 0.5f); - nk_stroke_line(o, hue_bar->x - 1, line_y, hue_bar->x + hue_bar->w + 2, line_y, 1, nk_rgb(255, 255, 255)); - - /* draw alpha bar */ - if (alpha_bar) { - float alpha = NK_SATURATE(col.a); - line_y = (float)(int)(alpha_bar->y + (1.0f - alpha) * matrix->h + 0.5f); - - nk_fill_rect_multi_color(o, *alpha_bar, white, white, black, black); - nk_stroke_line(o, alpha_bar->x - 1, line_y, alpha_bar->x + alpha_bar->w + 2, line_y, 1, nk_rgb(255, 255, 255)); - } - - /* draw color matrix */ - temp = nk_hsv_f(hsva[0], 1.0f, 1.0f); - nk_fill_rect_multi_color(o, *matrix, white, temp, temp, white); - nk_fill_rect_multi_color(o, *matrix, black_trans, black_trans, black, black); - - /* draw cross-hair */ - { - struct nk_vec2 p; - float S = hsva[1]; - float V = hsva[2]; - p.x = (float)(int)(matrix->x + S * matrix->w); - p.y = (float)(int)(matrix->y + (1.0f - V) * matrix->h); - nk_stroke_line(o, p.x - crosshair_size, p.y, p.x - 2, p.y, 1.0f, white); - nk_stroke_line(o, p.x + crosshair_size + 1, p.y, p.x + 3, p.y, 1.0f, white); - nk_stroke_line(o, p.x, p.y + crosshair_size + 1, p.x, p.y + 3, 1.0f, white); - nk_stroke_line(o, p.x, p.y - crosshair_size, p.x, p.y - 2, 1.0f, white); - } -} -NK_LIB nk_bool -nk_do_color_picker(nk_flags *state, - struct nk_command_buffer *out, - struct nk_colorf *col, - enum nk_color_format fmt, - struct nk_rect bounds, - struct nk_vec2 padding, - const struct nk_input *in, - const struct nk_user_font *font) -{ - int ret = 0; - struct nk_rect matrix; - struct nk_rect hue_bar; - struct nk_rect alpha_bar; - float bar_w; - - NK_ASSERT(out); - NK_ASSERT(col); - NK_ASSERT(state); - NK_ASSERT(font); - if (!out || !col || !state || !font) { - return ret; - } - - bar_w = out->context->style.font_size; - bounds.x += padding.x; - bounds.y += padding.x; - bounds.w -= 2 * padding.x; - bounds.h -= 2 * padding.y; - - matrix.x = bounds.x; - matrix.y = bounds.y; - matrix.h = bounds.h; - matrix.w = bounds.w - (3 * padding.x + 2 * bar_w); - - hue_bar.w = bar_w; - hue_bar.y = bounds.y; - hue_bar.h = matrix.h; - hue_bar.x = matrix.x + matrix.w + padding.x; - - alpha_bar.x = hue_bar.x + hue_bar.w + padding.x; - alpha_bar.y = bounds.y; - alpha_bar.w = bar_w; - alpha_bar.h = matrix.h; - - ret = nk_color_picker_behavior(state, &bounds, &matrix, &hue_bar, (fmt == NK_RGBA) ? &alpha_bar : 0, col, in); - nk_draw_color_picker(out, &matrix, &hue_bar, (fmt == NK_RGBA) ? &alpha_bar : 0, *col); - return ret; -} -NK_API nk_bool -nk_color_pick(struct nk_context *ctx, struct nk_colorf *color, enum nk_color_format fmt) -{ - struct nk_window *win; - struct nk_panel *layout; - const struct nk_style *config; - const struct nk_input *in; - - enum nk_widget_layout_states state; - struct nk_rect bounds; - - NK_ASSERT(ctx); - NK_ASSERT(color); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout || !color) { - return 0; - } - - win = ctx->current; - config = &ctx->style; - layout = win->layout; - state = nk_widget(&bounds, ctx); - if (!state) { - return 0; - } - in = (state == NK_WIDGET_ROM || state == NK_WIDGET_DISABLED || layout->flags & NK_WINDOW_ROM) ? 0 : &ctx->input; - return nk_do_color_picker(&ctx->last_widget_state, &win->buffer, color, fmt, bounds, nk_vec2(0, 0), in, config->font); -} -NK_API struct nk_colorf -nk_color_picker(struct nk_context *ctx, struct nk_colorf color, enum nk_color_format fmt) -{ - nk_color_pick(ctx, &color, fmt); - return color; -} - -/* ============================================================== - * - * COMBO - * - * ===============================================================*/ -NK_INTERN nk_bool -nk_combo_begin(struct nk_context *ctx, struct nk_window *win, struct nk_vec2 size, nk_bool is_clicked, struct nk_rect header) -{ - struct nk_window *popup; - int is_open = 0; - int is_active = 0; - struct nk_rect body; - struct nk_rect limits; - nk_hash hash; - float border; - float down_y; - float limits_right; - float limits_bottom; - float room_below; - float room_above; - nk_bool open_up; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - popup = win->popup.win; - body.x = header.x; - body.w = size.x; - body.h = size.y; - - border = ctx->style.window.combo_border; - down_y = header.y + header.h - border; - body.y = down_y; - - limits = ctx->window_maximize_bounds; - if (limits.w > 0.0f && limits.h > 0.0f) { - limits_right = limits.x + limits.w; - limits_bottom = limits.y + limits.h; - - body.w = NK_MIN(body.w, limits.w); - body.x = NK_CLAMP(limits.x, body.x, limits_right - body.w); - - room_below = limits_bottom - down_y; - room_above = header.y + border - limits.y; - - room_below = NK_MAX(room_below, 0.0f); - room_above = NK_MAX(room_above, 0.0f); - - open_up = body.h > room_below && room_above > room_below; - if (open_up) { - body.h = NK_MIN(body.h, room_above); - body.y = header.y - body.h + border; - } else { - body.h = NK_MIN(body.h, room_below); - body.y = down_y; - } - - body.h = NK_MAX(body.h, 1.0f); - } - - hash = win->popup.combo_count++; - is_open = (popup) ? nk_true : nk_false; - is_active = (popup && (win->popup.name == hash) && win->popup.type == NK_PANEL_COMBO); - if ((is_clicked && is_open && !is_active) || (is_open && !is_active) || (!is_open && !is_active && !is_clicked)) { - return 0; - } - if (!nk_nonblock_begin(ctx, 0, body, (is_clicked && is_open) ? nk_rect(0, 0, 0, 0) : header, NK_PANEL_COMBO)) { - return 0; - } - - win->popup.type = NK_PANEL_COMBO; - win->popup.name = hash; - return 1; -} -NK_API nk_bool -nk_combo_begin_text(struct nk_context *ctx, const char *selected, int len, struct nk_vec2 size) -{ - const struct nk_input *in; - struct nk_window *win; - struct nk_style *style; - - enum nk_widget_layout_states s; - int is_clicked = nk_false; - struct nk_rect header; - const struct nk_style_item *background; - struct nk_text text; - - NK_ASSERT(ctx); - NK_ASSERT(selected); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout || !selected) { - return 0; - } - - win = ctx->current; - style = &ctx->style; - s = nk_widget(&header, ctx); - if (s == NK_WIDGET_INVALID) { - return 0; - } - - in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_DISABLED || s == NK_WIDGET_ROM) ? 0 : &ctx->input; - if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT)) { - is_clicked = nk_true; - } - - /* draw combo box header background and border */ - if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) { - background = &style->combo.active; - text.text = style->combo.label_active; - } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) { - background = &style->combo.hover; - text.text = style->combo.label_hover; - } else { - background = &style->combo.normal; - text.text = style->combo.label_normal; - } - - text.text = nk_rgb_factor(text.text, style->combo.color_factor); - - switch (background->type) { - case NK_STYLE_ITEM_IMAGE: - text.background = nk_rgba(0, 0, 0, 0); - nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor)); - break; - case NK_STYLE_ITEM_NINE_SLICE: - text.background = nk_rgba(0, 0, 0, 0); - nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor)); - break; - case NK_STYLE_ITEM_COLOR: - text.background = background->data.color; - nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor)); - nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor)); - break; - } - { - /* print currently selected text item */ - struct nk_rect label; - struct nk_rect button; - struct nk_rect content; - int draw_button_symbol; - - enum nk_symbol_type sym; - if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) { - sym = style->combo.sym_hover; - } else if (is_clicked) { - sym = style->combo.sym_active; - } else { - sym = style->combo.sym_normal; - } - - /* represents whether or not the combo's button symbol should be drawn */ - draw_button_symbol = sym != NK_SYMBOL_NONE; - - /* calculate button */ - button.w = header.h - 2 * style->combo.button_padding.y; - button.x = (header.x + header.w - header.h) - style->combo.button_padding.x; - button.y = header.y + style->combo.button_padding.y; - button.h = button.w; - - content.x = button.x + style->combo.button.padding.x; - content.y = button.y + style->combo.button.padding.y; - content.w = button.w - 2 * style->combo.button.padding.x; - content.h = button.h - 2 * style->combo.button.padding.y; - - /* draw selected label */ - text.padding = nk_vec2(0, 0); - label.x = header.x + style->combo.content_padding.x; - label.y = header.y + style->combo.content_padding.y; - label.h = header.h - 2 * style->combo.content_padding.y; - if (draw_button_symbol) { - label.w = button.x - (style->combo.content_padding.x + style->combo.spacing.x) - label.x; - } else { - label.w = header.w - 2 * style->combo.content_padding.x; - } - nk_widget_text(&win->buffer, label, selected, len, &text, NK_TEXT_LEFT, ctx->style.font); - - /* draw open/close button */ - if (draw_button_symbol) { - nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state, &ctx->style.combo.button, sym, style->font); - } - } - return nk_combo_begin(ctx, win, size, is_clicked, header); -} -NK_API nk_bool -nk_combo_begin_label(struct nk_context *ctx, const char *selected, struct nk_vec2 size) -{ - return nk_combo_begin_text(ctx, selected, nk_strlen(selected), size); -} -NK_API nk_bool -nk_combo_begin_color(struct nk_context *ctx, struct nk_color color, struct nk_vec2 size) -{ - struct nk_window *win; - struct nk_style *style; - const struct nk_input *in; - - struct nk_rect header; - int is_clicked = nk_false; - enum nk_widget_layout_states s; - const struct nk_style_item *background; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - win = ctx->current; - style = &ctx->style; - s = nk_widget(&header, ctx); - if (s == NK_WIDGET_INVALID) { - return 0; - } - - in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_DISABLED || s == NK_WIDGET_ROM) ? 0 : &ctx->input; - if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT)) { - is_clicked = nk_true; - } - - /* draw combo box header background and border */ - if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) { - background = &style->combo.active; - } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) { - background = &style->combo.hover; - } else { - background = &style->combo.normal; - } - - switch (background->type) { - case NK_STYLE_ITEM_IMAGE: - nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor)); - break; - case NK_STYLE_ITEM_NINE_SLICE: - nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor)); - break; - case NK_STYLE_ITEM_COLOR: - nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor)); - nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor)); - break; - } - { - struct nk_rect content; - struct nk_rect button; - struct nk_rect bounds; - int draw_button_symbol; - - enum nk_symbol_type sym; - if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) { - sym = style->combo.sym_hover; - } else if (is_clicked) { - sym = style->combo.sym_active; - } else { - sym = style->combo.sym_normal; - } - - /* represents whether or not the combo's button symbol should be drawn */ - draw_button_symbol = sym != NK_SYMBOL_NONE; - - /* calculate button */ - button.w = header.h - 2 * style->combo.button_padding.y; - button.x = (header.x + header.w - header.h) - style->combo.button_padding.x; - button.y = header.y + style->combo.button_padding.y; - button.h = button.w; - - content.x = button.x + style->combo.button.padding.x; - content.y = button.y + style->combo.button.padding.y; - content.w = button.w - 2 * style->combo.button.padding.x; - content.h = button.h - 2 * style->combo.button.padding.y; - - /* draw color */ - bounds.h = header.h - 4 * style->combo.content_padding.y; - bounds.y = header.y + 2 * style->combo.content_padding.y; - bounds.x = header.x + 2 * style->combo.content_padding.x; - if (draw_button_symbol) { - bounds.w = (button.x - (style->combo.content_padding.x + style->combo.spacing.x)) - bounds.x; - } else { - bounds.w = header.w - 4 * style->combo.content_padding.x; - } - nk_fill_rect(&win->buffer, bounds, 0, nk_rgb_factor(color, style->combo.color_factor)); - - /* draw open/close button */ - if (draw_button_symbol) { - nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state, &ctx->style.combo.button, sym, style->font); - } - } - return nk_combo_begin(ctx, win, size, is_clicked, header); -} -NK_API nk_bool -nk_combo_begin_symbol(struct nk_context *ctx, enum nk_symbol_type symbol, struct nk_vec2 size) -{ - struct nk_window *win; - struct nk_style *style; - const struct nk_input *in; - - struct nk_rect header; - int is_clicked = nk_false; - enum nk_widget_layout_states s; - const struct nk_style_item *background; - struct nk_color sym_background; - struct nk_color symbol_color; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - win = ctx->current; - style = &ctx->style; - s = nk_widget(&header, ctx); - if (s == NK_WIDGET_INVALID) { - return 0; - } - - in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_DISABLED || s == NK_WIDGET_ROM) ? 0 : &ctx->input; - if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT)) { - is_clicked = nk_true; - } - - /* draw combo box header background and border */ - if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) { - background = &style->combo.active; - symbol_color = style->combo.symbol_active; - } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) { - background = &style->combo.hover; - symbol_color = style->combo.symbol_hover; - } else { - background = &style->combo.normal; - symbol_color = style->combo.symbol_hover; - } - - symbol_color = nk_rgb_factor(symbol_color, style->combo.color_factor); - - switch (background->type) { - case NK_STYLE_ITEM_IMAGE: - sym_background = nk_rgba(0, 0, 0, 0); - nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor)); - break; - case NK_STYLE_ITEM_NINE_SLICE: - sym_background = nk_rgba(0, 0, 0, 0); - nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor)); - break; - case NK_STYLE_ITEM_COLOR: - sym_background = background->data.color; - nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor)); - nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor)); - break; - } - { - struct nk_rect bounds = {0, 0, 0, 0}; - struct nk_rect content; - struct nk_rect button; - - enum nk_symbol_type sym; - if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) { - sym = style->combo.sym_hover; - } else if (is_clicked) { - sym = style->combo.sym_active; - } else { - sym = style->combo.sym_normal; - } - - /* calculate button */ - button.w = header.h - 2 * style->combo.button_padding.y; - button.x = (header.x + header.w - header.h) - style->combo.button_padding.y; - button.y = header.y + style->combo.button_padding.y; - button.h = button.w; - - content.x = button.x + style->combo.button.padding.x; - content.y = button.y + style->combo.button.padding.y; - content.w = button.w - 2 * style->combo.button.padding.x; - content.h = button.h - 2 * style->combo.button.padding.y; - - /* draw symbol */ - bounds.h = header.h - 2 * style->combo.content_padding.y; - bounds.y = header.y + style->combo.content_padding.y; - bounds.x = header.x + style->combo.content_padding.x; - bounds.w = (button.x - style->combo.content_padding.y) - bounds.x; - nk_draw_symbol(&win->buffer, symbol, bounds, sym_background, symbol_color, 1.0f, style->font); - - /* draw open/close button */ - nk_draw_button_symbol(&win->buffer, &bounds, &content, ctx->last_widget_state, &ctx->style.combo.button, sym, style->font); - } - return nk_combo_begin(ctx, win, size, is_clicked, header); -} -NK_API nk_bool -nk_combo_begin_symbol_text(struct nk_context *ctx, const char *selected, int len, enum nk_symbol_type symbol, struct nk_vec2 size) -{ - struct nk_window *win; - struct nk_style *style; - struct nk_input *in; - - struct nk_rect header; - int is_clicked = nk_false; - enum nk_widget_layout_states s; - const struct nk_style_item *background; - struct nk_color symbol_color; - struct nk_text text; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - win = ctx->current; - style = &ctx->style; - s = nk_widget(&header, ctx); - if (!s) { - return 0; - } - - in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_DISABLED || s == NK_WIDGET_ROM) ? 0 : &ctx->input; - if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT)) { - is_clicked = nk_true; - } - - /* draw combo box header background and border */ - if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) { - background = &style->combo.active; - symbol_color = style->combo.symbol_active; - text.text = style->combo.label_active; - } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) { - background = &style->combo.hover; - symbol_color = style->combo.symbol_hover; - text.text = style->combo.label_hover; - } else { - background = &style->combo.normal; - symbol_color = style->combo.symbol_normal; - text.text = style->combo.label_normal; - } - - text.text = nk_rgb_factor(text.text, style->combo.color_factor); - symbol_color = nk_rgb_factor(symbol_color, style->combo.color_factor); - - switch (background->type) { - case NK_STYLE_ITEM_IMAGE: - text.background = nk_rgba(0, 0, 0, 0); - nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor)); - break; - case NK_STYLE_ITEM_NINE_SLICE: - text.background = nk_rgba(0, 0, 0, 0); - nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor)); - break; - case NK_STYLE_ITEM_COLOR: - text.background = background->data.color; - nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor)); - nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor)); - break; - } - { - struct nk_rect content; - struct nk_rect button; - struct nk_rect label; - struct nk_rect image; - - enum nk_symbol_type sym; - if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) { - sym = style->combo.sym_hover; - } else if (is_clicked) { - sym = style->combo.sym_active; - } else { - sym = style->combo.sym_normal; - } - - /* calculate button */ - button.w = header.h - 2 * style->combo.button_padding.y; - button.x = (header.x + header.w - header.h) - style->combo.button_padding.x; - button.y = header.y + style->combo.button_padding.y; - button.h = button.w; - - content.x = button.x + style->combo.button.padding.x; - content.y = button.y + style->combo.button.padding.y; - content.w = button.w - 2 * style->combo.button.padding.x; - content.h = button.h - 2 * style->combo.button.padding.y; - nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state, &ctx->style.combo.button, sym, style->font); - - /* draw symbol */ - image.x = header.x + style->combo.content_padding.x; - image.y = header.y + style->combo.content_padding.y; - image.h = header.h - 2 * style->combo.content_padding.y; - image.w = image.h; - nk_draw_symbol(&win->buffer, symbol, image, text.background, symbol_color, 1.0f, style->font); - - /* draw label */ - text.padding = nk_vec2(0, 0); - label.x = image.x + image.w + style->combo.spacing.x + style->combo.content_padding.x; - label.y = header.y + style->combo.content_padding.y; - label.w = (button.x - style->combo.content_padding.x) - label.x; - label.h = header.h - 2 * style->combo.content_padding.y; - nk_widget_text(&win->buffer, label, selected, len, &text, NK_TEXT_LEFT, style->font); - } - return nk_combo_begin(ctx, win, size, is_clicked, header); -} -NK_API nk_bool -nk_combo_begin_image(struct nk_context *ctx, struct nk_image img, struct nk_vec2 size) -{ - struct nk_window *win; - struct nk_style *style; - const struct nk_input *in; - - struct nk_rect header; - int is_clicked = nk_false; - enum nk_widget_layout_states s; - const struct nk_style_item *background; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - win = ctx->current; - style = &ctx->style; - s = nk_widget(&header, ctx); - if (s == NK_WIDGET_INVALID) { - return 0; - } - - in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_DISABLED || s == NK_WIDGET_ROM) ? 0 : &ctx->input; - if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT)) { - is_clicked = nk_true; - } - - /* draw combo box header background and border */ - if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) { - background = &style->combo.active; - } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) { - background = &style->combo.hover; - } else { - background = &style->combo.normal; - } - - switch (background->type) { - case NK_STYLE_ITEM_IMAGE: - nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor)); - break; - case NK_STYLE_ITEM_NINE_SLICE: - nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor)); - break; - case NK_STYLE_ITEM_COLOR: - nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor)); - nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor)); - break; - } - { - struct nk_rect bounds = {0, 0, 0, 0}; - struct nk_rect content; - struct nk_rect button; - int draw_button_symbol; - - enum nk_symbol_type sym; - if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) { - sym = style->combo.sym_hover; - } else if (is_clicked) { - sym = style->combo.sym_active; - } else { - sym = style->combo.sym_normal; - } - - /* represents whether or not the combo's button symbol should be drawn */ - draw_button_symbol = sym != NK_SYMBOL_NONE; - - /* calculate button */ - button.w = header.h - 2 * style->combo.button_padding.y; - button.x = (header.x + header.w - header.h) - style->combo.button_padding.y; - button.y = header.y + style->combo.button_padding.y; - button.h = button.w; - - content.x = button.x + style->combo.button.padding.x; - content.y = button.y + style->combo.button.padding.y; - content.w = button.w - 2 * style->combo.button.padding.x; - content.h = button.h - 2 * style->combo.button.padding.y; - - /* draw image */ - bounds.h = header.h - 2 * style->combo.content_padding.y; - bounds.y = header.y + style->combo.content_padding.y; - bounds.x = header.x + style->combo.content_padding.x; - if (draw_button_symbol) { - bounds.w = (button.x - style->combo.content_padding.y) - bounds.x; - } else { - bounds.w = header.w - 2 * style->combo.content_padding.x; - } - nk_draw_image(&win->buffer, bounds, &img, nk_rgb_factor(nk_white, style->combo.color_factor)); - - /* draw open/close button */ - if (draw_button_symbol) { - nk_draw_button_symbol(&win->buffer, &bounds, &content, ctx->last_widget_state, &ctx->style.combo.button, sym, style->font); - } - } - return nk_combo_begin(ctx, win, size, is_clicked, header); -} -NK_API nk_bool -nk_combo_begin_image_text(struct nk_context *ctx, const char *selected, int len, struct nk_image img, struct nk_vec2 size) -{ - struct nk_window *win; - struct nk_style *style; - struct nk_input *in; - - struct nk_rect header; - int is_clicked = nk_false; - enum nk_widget_layout_states s; - const struct nk_style_item *background; - struct nk_text text; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - win = ctx->current; - style = &ctx->style; - s = nk_widget(&header, ctx); - if (!s) { - return 0; - } - - in = (win->layout->flags & NK_WINDOW_ROM || s == NK_WIDGET_DISABLED || s == NK_WIDGET_ROM) ? 0 : &ctx->input; - if (nk_button_behavior(&ctx->last_widget_state, header, in, NK_BUTTON_DEFAULT)) { - is_clicked = nk_true; - } - - /* draw combo box header background and border */ - if (ctx->last_widget_state & NK_WIDGET_STATE_ACTIVED) { - background = &style->combo.active; - text.text = style->combo.label_active; - } else if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) { - background = &style->combo.hover; - text.text = style->combo.label_hover; - } else { - background = &style->combo.normal; - text.text = style->combo.label_normal; - } - - text.text = nk_rgb_factor(text.text, style->combo.color_factor); - - switch (background->type) { - case NK_STYLE_ITEM_IMAGE: - text.background = nk_rgba(0, 0, 0, 0); - nk_draw_image(&win->buffer, header, &background->data.image, nk_rgb_factor(nk_white, style->combo.color_factor)); - break; - case NK_STYLE_ITEM_NINE_SLICE: - text.background = nk_rgba(0, 0, 0, 0); - nk_draw_nine_slice(&win->buffer, header, &background->data.slice, nk_rgb_factor(nk_white, style->combo.color_factor)); - break; - case NK_STYLE_ITEM_COLOR: - text.background = background->data.color; - nk_fill_rect(&win->buffer, header, style->combo.rounding, nk_rgb_factor(background->data.color, style->combo.color_factor)); - nk_stroke_rect(&win->buffer, header, style->combo.rounding, style->combo.border, nk_rgb_factor(style->combo.border_color, style->combo.color_factor)); - break; - } - { - struct nk_rect content; - struct nk_rect button; - struct nk_rect label; - struct nk_rect image; - int draw_button_symbol; - - enum nk_symbol_type sym; - if (ctx->last_widget_state & NK_WIDGET_STATE_HOVER) { - sym = style->combo.sym_hover; - } else if (is_clicked) { - sym = style->combo.sym_active; - } else { - sym = style->combo.sym_normal; - } - - /* represents whether or not the combo's button symbol should be drawn */ - draw_button_symbol = sym != NK_SYMBOL_NONE; - - /* calculate button */ - button.w = header.h - 2 * style->combo.button_padding.y; - button.x = (header.x + header.w - header.h) - style->combo.button_padding.x; - button.y = header.y + style->combo.button_padding.y; - button.h = button.w; - - content.x = button.x + style->combo.button.padding.x; - content.y = button.y + style->combo.button.padding.y; - content.w = button.w - 2 * style->combo.button.padding.x; - content.h = button.h - 2 * style->combo.button.padding.y; - if (draw_button_symbol) { - nk_draw_button_symbol(&win->buffer, &button, &content, ctx->last_widget_state, &ctx->style.combo.button, sym, style->font); - } - - /* draw image */ - image.x = header.x + style->combo.content_padding.x; - image.y = header.y + style->combo.content_padding.y; - image.h = header.h - 2 * style->combo.content_padding.y; - image.w = image.h; - nk_draw_image(&win->buffer, image, &img, nk_rgb_factor(nk_white, style->combo.color_factor)); - - /* draw label */ - text.padding = nk_vec2(0, 0); - label.x = image.x + image.w + style->combo.spacing.x + style->combo.content_padding.x; - label.y = header.y + style->combo.content_padding.y; - label.h = header.h - 2 * style->combo.content_padding.y; - if (draw_button_symbol) { - label.w = (button.x - style->combo.content_padding.x) - label.x; - } else { - label.w = (header.x + header.w - style->combo.content_padding.x) - label.x; - } - nk_widget_text(&win->buffer, label, selected, len, &text, NK_TEXT_LEFT, style->font); - } - return nk_combo_begin(ctx, win, size, is_clicked, header); -} -NK_API nk_bool -nk_combo_begin_symbol_label(struct nk_context *ctx, const char *selected, enum nk_symbol_type type, struct nk_vec2 size) -{ - return nk_combo_begin_symbol_text(ctx, selected, nk_strlen(selected), type, size); -} -NK_API nk_bool -nk_combo_begin_image_label(struct nk_context *ctx, const char *selected, struct nk_image img, struct nk_vec2 size) -{ - return nk_combo_begin_image_text(ctx, selected, nk_strlen(selected), img, size); -} -NK_API nk_bool -nk_combo_item_text(struct nk_context *ctx, const char *text, int len, nk_flags align) -{ - return nk_contextual_item_text(ctx, text, len, align); -} -NK_API nk_bool -nk_combo_item_label(struct nk_context *ctx, const char *label, nk_flags align) -{ - return nk_contextual_item_label(ctx, label, align); -} -NK_API nk_bool -nk_combo_item_image_text(struct nk_context *ctx, struct nk_image img, const char *text, int len, nk_flags alignment) -{ - return nk_contextual_item_image_text(ctx, img, text, len, alignment); -} -NK_API nk_bool -nk_combo_item_image_label(struct nk_context *ctx, struct nk_image img, const char *text, nk_flags alignment) -{ - return nk_contextual_item_image_label(ctx, img, text, alignment); -} -NK_API nk_bool -nk_combo_item_symbol_text(struct nk_context *ctx, enum nk_symbol_type sym, const char *text, int len, nk_flags alignment) -{ - return nk_contextual_item_symbol_text(ctx, sym, text, len, alignment); -} -NK_API nk_bool -nk_combo_item_symbol_label(struct nk_context *ctx, enum nk_symbol_type sym, const char *label, nk_flags alignment) -{ - return nk_contextual_item_symbol_label(ctx, sym, label, alignment); -} -NK_API void -nk_combo_end(struct nk_context *ctx) -{ - nk_contextual_end(ctx); -} -NK_API void -nk_combo_close(struct nk_context *ctx) -{ - nk_contextual_close(ctx); -} -NK_API int -nk_combo(struct nk_context *ctx, const char *const *items, int count, int selected, int item_height, struct nk_vec2 size) -{ - int i = 0; - int max_height; - struct nk_vec2 item_spacing; - struct nk_vec2 window_padding; - - NK_ASSERT(ctx); - NK_ASSERT(items); - NK_ASSERT(ctx->current); - if (!ctx || !items || !count) { - return selected; - } - - item_spacing = ctx->style.window.spacing; - window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type); - max_height = count * item_height + count * (int)item_spacing.y; - max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2; - size.y = NK_MIN(size.y, (float)max_height); - if (nk_combo_begin_label(ctx, items[selected], size)) { - nk_layout_row_dynamic(ctx, (float)item_height, 1); - for (i = 0; i < count; ++i) { - if (nk_combo_item_label(ctx, items[i], NK_TEXT_LEFT)) { - selected = i; - } - } - nk_combo_end(ctx); - } - return selected; -} -NK_API int -nk_combo_separator(struct nk_context *ctx, const char *items_separated_by_separator, int separator, int selected, int count, int item_height, struct nk_vec2 size) -{ - int i; - int max_height; - struct nk_vec2 item_spacing; - struct nk_vec2 window_padding; - const char *current_item; - const char *iter; - int length = 0; - - NK_ASSERT(ctx); - NK_ASSERT(items_separated_by_separator); - if (!ctx || !items_separated_by_separator) { - return selected; - } - - /* calculate popup window */ - item_spacing = ctx->style.window.spacing; - window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type); - max_height = count * item_height + count * (int)item_spacing.y; - max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2; - size.y = NK_MIN(size.y, (float)max_height); - - /* find selected item */ - current_item = items_separated_by_separator; - for (i = 0; i < count; ++i) { - iter = current_item; - while (*iter && *iter != separator) { - iter++; - } - length = (int)(iter - current_item); - if (i == selected) { - break; - } - current_item = iter + 1; - } - - if (nk_combo_begin_text(ctx, current_item, length, size)) { - current_item = items_separated_by_separator; - nk_layout_row_dynamic(ctx, (float)item_height, 1); - for (i = 0; i < count; ++i) { - iter = current_item; - while (*iter && *iter != separator) { - iter++; - } - length = (int)(iter - current_item); - if (nk_combo_item_text(ctx, current_item, length, NK_TEXT_LEFT)) { - selected = i; - } - current_item = current_item + length + 1; - } - nk_combo_end(ctx); - } - return selected; -} -NK_API int -nk_combo_string(struct nk_context *ctx, const char *items_separated_by_zeros, int selected, int count, int item_height, struct nk_vec2 size) -{ - return nk_combo_separator(ctx, items_separated_by_zeros, '\0', selected, count, item_height, size); -} -NK_API int -nk_combo_callback(struct nk_context *ctx, void (*item_getter)(void *, int, const char **), void *userdata, int selected, int count, int item_height, struct nk_vec2 size) -{ - int i; - int max_height; - struct nk_vec2 item_spacing; - struct nk_vec2 window_padding; - const char *item; - - NK_ASSERT(ctx); - NK_ASSERT(item_getter); - if (!ctx || !item_getter) { - return selected; - } - - /* calculate popup window */ - item_spacing = ctx->style.window.spacing; - window_padding = nk_panel_get_padding(&ctx->style, ctx->current->layout->type); - max_height = count * item_height + count * (int)item_spacing.y; - max_height += (int)item_spacing.y * 2 + (int)window_padding.y * 2; - size.y = NK_MIN(size.y, (float)max_height); - - item_getter(userdata, selected, &item); - if (nk_combo_begin_label(ctx, item, size)) { - nk_layout_row_dynamic(ctx, (float)item_height, 1); - for (i = 0; i < count; ++i) { - item_getter(userdata, i, &item); - if (nk_combo_item_label(ctx, item, NK_TEXT_LEFT)) { - selected = i; - } - } - nk_combo_end(ctx); - } - return selected; -} -NK_API nk_bool -nk_combobox(struct nk_context *ctx, const char *const *items, int count, int *selected, int item_height, struct nk_vec2 size) -{ - int tmp = *selected; - *selected = nk_combo(ctx, items, count, *selected, item_height, size); - return tmp != *selected; -} -NK_API nk_bool -nk_combobox_string(struct nk_context *ctx, const char *items_separated_by_zeros, int *selected, int count, int item_height, struct nk_vec2 size) -{ - int tmp = *selected; - *selected = nk_combo_string(ctx, items_separated_by_zeros, *selected, count, item_height, size); - return tmp != *selected; -} -NK_API nk_bool -nk_combobox_separator(struct nk_context *ctx, const char *items_separated_by_separator, int separator, int *selected, int count, int item_height, struct nk_vec2 size) -{ - int tmp = *selected; - *selected = nk_combo_separator(ctx, items_separated_by_separator, separator, *selected, count, item_height, size); - return tmp != *selected; -} -NK_API nk_bool -nk_combobox_callback( - struct nk_context *ctx, void (*item_getter)(void *data, int id, const char **out_text), void *userdata, int *selected, int count, int item_height, struct nk_vec2 size) -{ - int tmp = *selected; - *selected = nk_combo_callback(ctx, item_getter, userdata, *selected, count, item_height, size); - return tmp != *selected; -} - -/* =============================================================== - * - * TOOLTIP - * - * ===============================================================*/ -NK_API nk_bool -nk_tooltip_begin(struct nk_context *ctx, float width) -{ - NK_ASSERT(ctx); - return nk_tooltip_begin_offset(ctx, width, ctx->style.window.tooltip_origin, ctx->style.window.tooltip_offset); -} - -NK_API nk_bool -nk_tooltip_begin_offset(struct nk_context *ctx, float width, enum nk_tooltip_pos position, struct nk_vec2 offset) -{ - int x, y, w, h; - struct nk_window *win; - const struct nk_input *in; - struct nk_rect bounds; - int ret; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) { - return 0; - } - - /* make sure that no nonblocking popup is currently active */ - win = ctx->current; - in = &ctx->input; - if (win->popup.win && ((int)win->popup.type & (int)NK_PANEL_SET_NONBLOCK)) { - return 0; - } - - w = nk_iceilf(width); - h = (int)NK_MAX(win->layout->row.min_height, ctx->style.font_size + 2 * ctx->style.window.padding.y); - - /* Default origin is top left, plus user offset */ - x = nk_ifloorf(in->mouse.pos.x + 1) - (int)win->layout->clip.x + (int)offset.x; - y = nk_ifloorf(in->mouse.pos.y + 1) - (int)win->layout->clip.y + (int)offset.y; - - /* Adjust origin based on enum */ - switch (position) { - case NK_TOP_LEFT: - /* no change */ - break; - case NK_TOP_CENTER: - x -= w / 2; - break; - case NK_TOP_RIGHT: - x -= w; - break; - - case NK_MIDDLE_LEFT: - y -= h / 2; - break; - case NK_MIDDLE_CENTER: - x -= w / 2; - y -= h / 2; - break; - case NK_MIDDLE_RIGHT: - x -= w; - y -= h / 2; - break; - - case NK_BOTTOM_LEFT: - y -= h; - break; - case NK_BOTTOM_CENTER: - x -= w / 2; - y -= h; - break; - case NK_BOTTOM_RIGHT: - x -= w; - y -= h; - break; - default: - NK_ASSERT(0 && "Invalid tooltip position"); - } - - bounds.x = (float)x; - bounds.y = (float)y; - bounds.w = (float)w; - bounds.h = (float)nk_iceilf(nk_null_rect.h); - - ret = nk_popup_begin(ctx, NK_POPUP_DYNAMIC, "__##Tooltip##__", NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_BORDER, bounds); - if (ret) { - win->layout->flags &= ~(nk_flags)NK_WINDOW_ROM; - } - win->popup.type = NK_PANEL_TOOLTIP; - ctx->current->layout->type = NK_PANEL_TOOLTIP; - return ret; -} - -NK_API void -nk_tooltip_end(struct nk_context *ctx) -{ - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - if (!ctx || !ctx->current) { - return; - } - ctx->current->seq--; - nk_popup_close(ctx); - nk_popup_end(ctx); -} - -NK_API void -nk_tooltip_text_offset(struct nk_context *ctx, const char *text, int len, enum nk_tooltip_pos position, struct nk_vec2 offset) -{ - const struct nk_style *style; - struct nk_vec2 padding; - - float text_width; - float text_height; - - NK_ASSERT(ctx); - NK_ASSERT(ctx->current); - NK_ASSERT(ctx->current->layout); - NK_ASSERT(text); - NK_ASSERT(len >= 0); - if (!ctx || !ctx->current || !ctx->current->layout || !text || len < 0) { - return; - } - - /* fetch configuration data */ - style = &ctx->style; - padding = style->window.padding; - - /* calculate size of the text and tooltip */ - text_width = nk_text_width(ctx, style->font, style->font_size, text, len); - text_width += (4 * padding.x); - text_height = (style->font_size + 2 * padding.y); - - /* execute tooltip and fill with text */ - if (nk_tooltip_begin_offset(ctx, (float)text_width, position, offset)) { - nk_layout_row_dynamic(ctx, (float)text_height, 1); - nk_text(ctx, text, len, NK_TEXT_LEFT); - nk_tooltip_end(ctx); - } -} - -NK_API void -nk_tooltip_offset(struct nk_context *ctx, const char *text, enum nk_tooltip_pos position, struct nk_vec2 offset) -{ - NK_ASSERT(ctx); - nk_tooltip_text_offset(ctx, text, nk_strlen(text), position, offset); -} - -NK_API void -nk_tooltip(struct nk_context *ctx, const char *text) -{ - NK_ASSERT(ctx); - nk_tooltip_offset(ctx, text, ctx->style.window.tooltip_origin, ctx->style.window.tooltip_offset); -} -NK_API void -nk_tooltip_text(struct nk_context *ctx, const char *text, int len) -{ - NK_ASSERT(ctx); - nk_tooltip_text_offset(ctx, text, len, ctx->style.window.tooltip_origin, ctx->style.window.tooltip_offset); -} -#ifdef NK_INCLUDE_STANDARD_VARARGS -NK_API void -nk_tooltipf_offset(struct nk_context *ctx, enum nk_tooltip_pos position, struct nk_vec2 offset, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - nk_tooltipfv_offset(ctx, position, offset, fmt, args); - va_end(args); -} -NK_API void -nk_tooltipf(struct nk_context *ctx, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - nk_tooltipfv(ctx, fmt, args); - va_end(args); -} -NK_API void -nk_tooltipfv_offset(struct nk_context *ctx, enum nk_tooltip_pos position, struct nk_vec2 offset, const char *fmt, va_list args) -{ - char buf[256]; - nk_strfmt(buf, NK_LEN(buf), fmt, args); - nk_tooltip_text_offset(ctx, buf, nk_strlen(buf), position, offset); -} -NK_API void -nk_tooltipfv(struct nk_context *ctx, const char *fmt, va_list args) -{ - char buf[256]; - nk_strfmt(buf, NK_LEN(buf), fmt, args); - nk_tooltip(ctx, buf); -} -#endif diff --git a/mod/mod_nuklear.h b/mod/mod_nuklear.h deleted file mode 100644 index f2686fe..0000000 --- a/mod/mod_nuklear.h +++ /dev/null @@ -1,8001 +0,0 @@ -#ifndef NK_NUKLEAR_H_ -#define NK_NUKLEAR_H_ - -#include "mod_sdk.h" - -#define NK_ASSERT MOD_ASSERT -#define NK_MASSERT MOD_ASSERT_MSG -#define NK_INCLUDE_FIXED_TYPES -#define NK_INCLUDE_STANDARD_IO -#define NK_INCLUDE_STANDARD_VARARGS -#define NK_INCLUDE_DEFAULT_ALLOCATOR -#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT -#define NK_INCLUDE_FONT_BAKING -#define NK_BUTTON_TRIGGER_ON_RELEASE -#define NK_UINT_DRAW_INDEX -#define NK_DEFAULT_TEXT_SELECTABLE - -#ifdef __cplusplus -extern "C" { -#endif -/* - * ============================================================== - * - * CONSTANTS - * - * =============================================================== - */ - -#define NK_UNDEFINED (-1.0f) -#define NK_UTF_INVALID 0xFFFD /**< internal invalid utf8 rune */ -#define NK_UTF_SIZE 4 /**< describes the number of bytes a glyph consists of*/ -#ifndef NK_INPUT_MAX -# define NK_INPUT_MAX 16 -#endif -#ifndef NK_MAX_NUMBER_BUFFER -# define NK_MAX_NUMBER_BUFFER 64 -#endif -#ifndef NK_SCROLLBAR_HIDING_TIMEOUT -# define NK_SCROLLBAR_HIDING_TIMEOUT 4.0f -#endif - -/* - * ============================================================== - * - * HELPER - * - * =============================================================== - */ - -#ifndef NK_API -# ifdef NK_PRIVATE -# if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199409L)) -# define NK_API static inline -# elif defined(__cplusplus) -# define NK_API static inline -# else -# define NK_API static -# endif -# else -# define NK_API extern -# endif -#endif -#ifndef NK_LIB -# ifdef NK_SINGLE_FILE -# define NK_LIB static -# else -# define NK_LIB extern -# endif -#endif - -#define NK_INTERN static -#define NK_STORAGE static -#define NK_GLOBAL static - -#define NK_FLAG(x) (1 << (x)) -#define NK_STRINGIFY(x) #x -#define NK_MACRO_STRINGIFY(x) NK_STRINGIFY(x) -#define NK_STRING_JOIN_IMMEDIATE(arg1, arg2) arg1##arg2 -#define NK_STRING_JOIN_DELAY(arg1, arg2) NK_STRING_JOIN_IMMEDIATE(arg1, arg2) -#define NK_STRING_JOIN(arg1, arg2) NK_STRING_JOIN_DELAY(arg1, arg2) - -#ifdef _MSC_VER -# define NK_UNIQUE_NAME(name) NK_STRING_JOIN(name, __COUNTER__) -#else -# define NK_UNIQUE_NAME(name) NK_STRING_JOIN(name, __LINE__) -#endif - -#ifndef NK_STATIC_ASSERT -# define NK_STATIC_ASSERT(exp) typedef char NK_UNIQUE_NAME(_dummy_array)[(exp) ? 1 : -1] -#endif - -#ifndef NK_FILE_LINE -# ifdef _MSC_VER -# define NK_FILE_LINE __FILE__ ":" NK_MACRO_STRINGIFY(__COUNTER__) -# else -# define NK_FILE_LINE __FILE__ ":" NK_MACRO_STRINGIFY(__LINE__) -# endif -#endif - -#define NK_MIN(a, b) ((a) < (b) ? (a) : (b)) -#define NK_MAX(a, b) ((a) < (b) ? (b) : (a)) -#define NK_CLAMP(i, v, x) (NK_MAX(NK_MIN(v, x), i)) - -#ifdef NK_INCLUDE_STANDARD_VARARGS -# include -# if defined(_MSC_VER) && (_MSC_VER >= 1600) /* VS 2010 and above */ -# include -# define NK_PRINTF_FORMAT_STRING _Printf_format_string_ -# else -# define NK_PRINTF_FORMAT_STRING -# endif -# if defined(__GNUC__) -# define NK_PRINTF_VARARG_FUNC(fmtargnumber) __attribute__((format(__printf__, fmtargnumber, fmtargnumber + 1))) -# define NK_PRINTF_VALIST_FUNC(fmtargnumber) __attribute__((format(__printf__, fmtargnumber, 0))) -# else -# define NK_PRINTF_VARARG_FUNC(fmtargnumber) -# define NK_PRINTF_VALIST_FUNC(fmtargnumber) -# endif -#endif - -/* - * =============================================================== - * - * BASIC - * - * =============================================================== - */ -#ifdef NK_INCLUDE_FIXED_TYPES -# include -# define NK_INT8 int8_t -# define NK_UINT8 uint8_t -# define NK_INT16 int16_t -# define NK_UINT16 uint16_t -# define NK_INT32 int32_t -# define NK_UINT32 uint32_t -# define NK_SIZE_TYPE uintptr_t -# define NK_POINTER_TYPE uintptr_t -#else -# ifndef NK_INT8 -# define NK_INT8 signed char -# endif -# ifndef NK_UINT8 -# define NK_UINT8 unsigned char -# endif -# ifndef NK_INT16 -# define NK_INT16 signed short -# endif -# ifndef NK_UINT16 -# define NK_UINT16 unsigned short -# endif -# ifndef NK_INT32 -# if defined(_MSC_VER) -# define NK_INT32 __int32 -# else -# define NK_INT32 signed int -# endif -# endif -# ifndef NK_UINT32 -# if defined(_MSC_VER) -# define NK_UINT32 unsigned __int32 -# else -# define NK_UINT32 unsigned int -# endif -# endif -# ifndef NK_SIZE_TYPE -# if defined(_WIN64) && defined(_MSC_VER) -# define NK_SIZE_TYPE unsigned __int64 -# elif defined(_WIN64) && (defined(__MINGW64__) || defined(__clang__)) -# define NK_SIZE_TYPE unsigned long long -# elif (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER) -# define NK_SIZE_TYPE unsigned __int32 -# elif (defined(_WIN32) || defined(WIN32)) && (defined(__MINGW32__) || defined(__clang__)) -# define NK_SIZE_TYPE unsigned long -# elif defined(__GNUC__) || defined(__clang__) -# if defined(__x86_64__) || defined(__ppc64__) || defined(__PPC64__) || defined(__aarch64__) -# define NK_SIZE_TYPE unsigned long -# else -# define NK_SIZE_TYPE unsigned int -# endif -# else -# define NK_SIZE_TYPE unsigned long -# endif -# endif -# ifndef NK_POINTER_TYPE -# if defined(_WIN64) && defined(_MSC_VER) -# define NK_POINTER_TYPE unsigned __int64 -# elif defined(_WIN64) && (defined(__MINGW64__) || defined(__clang__)) -# define NK_POINTER_TYPE unsigned long long -# elif (defined(_WIN32) || defined(WIN32)) && defined(_MSC_VER) -# define NK_POINTER_TYPE unsigned __int32 -# elif (defined(_WIN32) || defined(WIN32)) && (defined(__MINGW32__) || defined(__clang__)) -# define NK_POINTER_TYPE unsigned long -# elif defined(__GNUC__) || defined(__clang__) -# if defined(__x86_64__) || defined(__ppc64__) || defined(__PPC64__) || defined(__aarch64__) -# define NK_POINTER_TYPE unsigned long -# else -# define NK_POINTER_TYPE unsigned int -# endif -# else -# define NK_POINTER_TYPE unsigned long -# endif -# endif -#endif - -/**< could be any type with semantic of standard bool, either equal or smaller than int */ -#ifndef NK_BOOL -# ifdef NK_INCLUDE_STANDARD_BOOL -# include -# define NK_BOOL bool -# else -# define NK_BOOL int -# endif -#endif - -typedef NK_INT8 nk_char; -typedef NK_UINT8 nk_uchar; -typedef NK_UINT8 nk_byte; -typedef NK_INT16 nk_short; -typedef NK_UINT16 nk_ushort; -typedef NK_INT32 nk_int; -typedef NK_UINT32 nk_uint; -typedef NK_SIZE_TYPE nk_size; -typedef NK_POINTER_TYPE nk_ptr; -typedef NK_BOOL nk_bool; - -typedef nk_uint nk_hash; -typedef nk_uint nk_flags; -typedef nk_uint nk_rune; - -/* Make sure correct type size: - * This will fire with a negative subscript error if the type sizes - * are set incorrectly by the compiler, and compile out if not */ -NK_STATIC_ASSERT(sizeof(nk_short) == 2); -NK_STATIC_ASSERT(sizeof(nk_ushort) == 2); -NK_STATIC_ASSERT(sizeof(nk_uint) == 4); -NK_STATIC_ASSERT(sizeof(nk_int) == 4); -NK_STATIC_ASSERT(sizeof(nk_byte) == 1); -NK_STATIC_ASSERT(sizeof(nk_flags) >= 4); -NK_STATIC_ASSERT(sizeof(nk_rune) >= 4); -NK_STATIC_ASSERT(sizeof(nk_size) >= sizeof(void *)); -NK_STATIC_ASSERT(sizeof(nk_ptr) >= sizeof(void *)); -NK_STATIC_ASSERT(sizeof(nk_bool) <= sizeof(int)); - -/* ============================================================================ - * - * API - * - * =========================================================================== */ -struct nk_buffer; -struct nk_allocator; -struct nk_command_buffer; -struct nk_draw_command; -struct nk_convert_config; -struct nk_style_item; -struct nk_text_edit; -struct nk_draw_list; -struct nk_user_font; -struct nk_panel; -struct nk_context; -struct nk_draw_vertex_layout_element; -struct nk_style_button; -struct nk_style_toggle; -struct nk_style_selectable; -struct nk_style_slide; -struct nk_style_progress; -struct nk_style_scrollbar; -struct nk_style_edit; -struct nk_style_property; -struct nk_style_chart; -struct nk_style_combo; -struct nk_style_tab; -struct nk_style_window_header; -struct nk_style_window; - -enum { - nk_false, - nk_true, -}; - -struct nk_color { - nk_byte r, g, b, a; -}; - -struct nk_colorf { - float r, g, b, a; -}; - -struct nk_vec2 { - float x, y; -}; - -struct nk_vec2i { - short x, y; -}; - -struct nk_rect { - float x, y, w, h; -}; - -struct nk_recti { - short x, y, w, h; -}; - -typedef char nk_glyph[NK_UTF_SIZE]; -typedef union { - void *ptr; - int id; -} nk_handle; - -struct nk_image { - nk_handle handle; - nk_ushort w, h; - nk_ushort region[4]; -}; - -struct nk_nine_slice { - struct nk_image img; - nk_ushort l, t, r, b; -}; - -struct nk_cursor { - struct nk_image img; - struct nk_vec2 size, offset; -}; - -enum { - NK_SCROLL_HAS_PREV_MAX_X = NK_FLAG(0), - NK_SCROLL_HAS_PREV_MAX_Y = NK_FLAG(1), -}; - -struct nk_scroll { - nk_uint x; - nk_uint y; - nk_uint prev_max_x; - nk_uint prev_max_y; - nk_uint flags; -}; - -/* Make sure the semantic of nk_true/nk_false is compatible with nk_bool */ -NK_STATIC_ASSERT(!((nk_bool)0) == !(nk_false)); -NK_STATIC_ASSERT(!((nk_bool)1) == !(nk_true)); - -enum nk_heading { - NK_UP, - NK_RIGHT, - NK_DOWN, - NK_LEFT, -}; - -enum nk_button_behavior { - NK_BUTTON_DEFAULT, - NK_BUTTON_REPEATER, -}; - -enum nk_modify { - NK_FIXED = nk_false, - NK_MODIFIABLE = nk_true, -}; - -enum nk_orientation { - NK_VERTICAL, - NK_HORIZONTAL, -}; - -enum nk_collapse_states { - NK_MINIMIZED = nk_false, - NK_MAXIMIZED = nk_true, -}; - -enum nk_show_states { - NK_HIDDEN = nk_false, - NK_SHOWN = nk_true, -}; - -enum nk_chart_type { - NK_CHART_LINES, - NK_CHART_COLUMN, - NK_CHART_MAX, -}; - -enum nk_chart_event { - NK_CHART_HOVERING = 0x01, - NK_CHART_CLICKED = 0x02, -}; - -enum nk_color_format { - NK_RGB, - NK_RGBA, -}; - -enum nk_popup_type { - NK_POPUP_STATIC, - NK_POPUP_DYNAMIC, -}; - -enum nk_layout_format { - NK_DYNAMIC, - NK_STATIC, -}; - -enum nk_tree_type { - NK_TREE_NODE, - NK_TREE_TAB, -}; - -enum nk_tooltip_pos { - NK_TOP_LEFT, - NK_TOP_CENTER, - NK_TOP_RIGHT, - - NK_MIDDLE_LEFT, - NK_MIDDLE_CENTER, - NK_MIDDLE_RIGHT, - - NK_BOTTOM_LEFT, - NK_BOTTOM_CENTER, - NK_BOTTOM_RIGHT -}; - -typedef void *(*nk_plugin_alloc)(nk_handle, void *old, nk_size); -typedef void (*nk_plugin_free)(nk_handle, void *old); -typedef nk_bool (*nk_plugin_filter)(const struct nk_text_edit *, nk_rune unicode); -typedef void (*nk_plugin_paste)(nk_handle, struct nk_text_edit *); -typedef void (*nk_plugin_copy)(nk_handle, const char *, int len); - -struct nk_allocator { - nk_handle userdata; - nk_plugin_alloc alloc; - nk_plugin_free free; -}; - -enum nk_symbol_type { - NK_SYMBOL_NONE, - NK_SYMBOL_X, - NK_SYMBOL_UNDERSCORE, - NK_SYMBOL_CIRCLE_SOLID, - NK_SYMBOL_CIRCLE_OUTLINE, - NK_SYMBOL_RECT_SOLID, - NK_SYMBOL_RECT_OUTLINE, - NK_SYMBOL_TRIANGLE_UP, - NK_SYMBOL_TRIANGLE_DOWN, - NK_SYMBOL_TRIANGLE_LEFT, - NK_SYMBOL_TRIANGLE_RIGHT, - NK_SYMBOL_PLUS, - NK_SYMBOL_MINUS, - NK_SYMBOL_TRIANGLE_UP_OUTLINE, - NK_SYMBOL_TRIANGLE_DOWN_OUTLINE, - NK_SYMBOL_TRIANGLE_LEFT_OUTLINE, - NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE, - NK_SYMBOL_MAX, -}; -/* ============================================================================= - * - * CONTEXT - * - * =============================================================================*/ -/** - * \page Context - * Contexts are the main entry point and the majestro of nuklear and contain all required state. - * They are used for window, memory, input, style, stack, commands and time management and need - * to be passed into all nuklear GUI specific functions. - * - * # Usage - * To use a context it first has to be initialized which can be achieved by calling - * one of either `nk_init_default`, `nk_init_fixed`, `nk_init`, `nk_init_custom`. - * Each takes in a font handle and a specific way of handling memory. Memory control - * hereby ranges from standard library to just specifying a fixed sized block of memory - * which nuklear has to manage itself from. - * - * ```c - * struct nk_context ctx; - * nk_init_xxx(&ctx, ...); - * while (1) { - * // [...] - * nk_clear(&ctx); - * } - * nk_free(&ctx); - * ``` - * - * # Reference - * Function | Description - * --------------------|------------------------------------------------------- - * \ref nk_init_default | Initializes context with standard library memory allocation (malloc,free) - * \ref nk_init_fixed | Initializes context from single fixed size memory block - * \ref nk_init | Initializes context with memory allocator callbacks for alloc and free - * \ref nk_init_custom | Initializes context from two buffers. One for draw commands the other for window/panel/table - * allocations - * \ref nk_clear | Called at the end of the frame to reset and prepare the context for the next frame - * \ref nk_free | Shutdown and free all memory allocated inside the context - * \ref nk_set_user_data| Utility function to pass user data to draw command - */ - -#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR - -/** - * # nk_init_default - * Initializes a `nk_context` struct with a default standard library allocator. - * Should be used if you don't want to be bothered with memory management in nuklear. - * - * ```c - * nk_bool nk_init_default(struct nk_context *ctx, const struct nk_user_font *font); - * ``` - * - * Parameter | Description - * ------------|--------------------------------------------------------------- - * \param[in] ctx | Must point to an either stack or heap allocated `nk_context` struct - * \param[in] font | Must point to a previously initialized font handle for more info look at font documentation - * - * \returns either `false(0)` on failure or `true(1)` on success. - */ -NK_API nk_bool -nk_init_default(struct nk_context *, const struct nk_user_font *); -#endif -/** - * # nk_init_fixed - * Initializes a `nk_context` struct from single fixed size memory block - * Should be used if you want complete control over nuklear's memory management. - * Especially recommended for system with little memory or systems with virtual memory. - * For the later case you can just allocate for example 16MB of virtual memory - * and only the required amount of memory will actually be committed. - * - * ```c - * nk_bool nk_init_fixed(struct nk_context *ctx, void *memory, nk_size size, const struct nk_user_font *font); - * ``` - * - * !!! Warning - * make sure the passed memory block is aligned correctly for `nk_draw_commands`. - * - * Parameter | Description - * ------------|-------------------------------------------------------------- - * \param[in] ctx | Must point to an either stack or heap allocated `nk_context` struct - * \param[in] memory | Must point to a previously allocated memory block - * \param[in] size | Must contain the total size of memory - * \param[in] font | Must point to a previously initialized font handle for more info look at font documentation - * - * \returns either `false(0)` on failure or `true(1)` on success. - */ -NK_API nk_bool -nk_init_fixed(struct nk_context *, void *memory, nk_size size, const struct nk_user_font *); - -/** - * # nk_init - * Initializes a `nk_context` struct with memory allocation callbacks for nuklear to allocate - * memory from. Used internally for `nk_init_default` and provides a kitchen sink allocation - * interface to nuklear. Can be useful for cases like monitoring memory consumption. - * - * ```c - * nk_bool nk_init(struct nk_context *ctx, const struct nk_allocator *alloc, const struct nk_user_font *font); - * ``` - * - * Parameter | Description - * ------------|--------------------------------------------------------------- - * \param[in] ctx | Must point to an either stack or heap allocated `nk_context` struct - * \param[in] alloc | Must point to a previously allocated memory allocator - * \param[in] font | Must point to a previously initialized font handle for more info look at font documentation - * - * \returns either `false(0)` on failure or `true(1)` on success. - */ -NK_API nk_bool -nk_init(struct nk_context *, const struct nk_allocator *, const struct nk_user_font *); - -/** - * \brief Initializes a `nk_context` struct from two different either fixed or growing buffers. - * - * \details - * The first buffer is for allocating draw commands while the second buffer is - * used for allocating windows, panels and state tables. - * - * ```c - * nk_bool nk_init_custom(struct nk_context *ctx, struct nk_buffer *cmds, struct nk_buffer *pool, const struct - * nk_user_font *font); - * ``` - * - * \param[in] ctx Must point to an either stack or heap allocated `nk_context` struct - * \param[in] cmds Must point to a previously initialized memory buffer either fixed or dynamic to store draw commands - * into - * \param[in] pool Must point to a previously initialized memory buffer either fixed or dynamic to store windows, - * panels and tables - * \param[in] font Must point to a previously initialized font handle for more info look at font documentation - * - * \returns either `false(0)` on failure or `true(1)` on success. - */ -NK_API nk_bool -nk_init_custom(struct nk_context *, struct nk_buffer *cmds, struct nk_buffer *pool, const struct nk_user_font *); - -/** - * \brief Resets the context state at the end of the frame. - * - * \details - * This includes mostly garbage collector tasks like removing windows or table - * not called and therefore used anymore. - * - * ```c - * void nk_clear(struct nk_context *ctx); - * ``` - * - * \param[in] ctx Must point to a previously initialized `nk_context` struct - */ -NK_API void -nk_clear(struct nk_context *); - -/** - * \brief Frees all memory allocated by nuklear; Not needed if context was initialized with `nk_init_fixed`. - * - * \details - * ```c - * void nk_free(struct nk_context *ctx); - * ``` - * - * \param[in] ctx Must point to a previously initialized `nk_context` struct - */ -NK_API void -nk_free(struct nk_context *); - -#ifdef NK_INCLUDE_COMMAND_USERDATA -/** - * \brief Sets the currently passed userdata passed down into each draw command. - * - * \details - * ```c - * void nk_set_user_data(struct nk_context *ctx, nk_handle data); - * ``` - * - * \param[in] ctx Must point to a previously initialized `nk_context` struct - * \param[in] data Handle with either pointer or index to be passed into every draw commands - */ -NK_API void -nk_set_user_data(struct nk_context *, nk_handle handle); -#endif -/* ============================================================================= - * - * INPUT - * - * =============================================================================*/ -/** - * \page Input - * - * The input API is responsible for holding the current input state composed of - * mouse, key and text input states. - * It is worth noting that no direct OS or window handling is done in nuklear. - * Instead all input state has to be provided by platform specific code. This on one hand - * expects more work from the user and complicates usage but on the other hand - * provides simple abstraction over a big number of platforms, libraries and other - * already provided functionality. - * - * ```c - * nk_input_begin(&ctx); - * while (GetEvent(&evt)) { - * if (evt.type == MOUSE_MOVE) - * nk_input_motion(&ctx, evt.motion.x, evt.motion.y); - * else if (evt.type == [...]) { - * // [...] - * } - * } nk_input_end(&ctx); - * ``` - * - * # Usage - * Input state needs to be provided to nuklear by first calling `nk_input_begin` - * which resets internal state like delta mouse position and button transitions. - * After `nk_input_begin` all current input state needs to be provided. This includes - * mouse motion, button and key pressed and released, text input and scrolling. - * Both event- or state-based input handling are supported by this API - * and should work without problems. Finally after all input state has been - * mirrored `nk_input_end` needs to be called to finish input process. - * - * ```c - * struct nk_context ctx; - * nk_init_xxx(&ctx, ...); - * while (1) { - * Event evt; - * nk_input_begin(&ctx); - * while (GetEvent(&evt)) { - * if (evt.type == MOUSE_MOVE) - * nk_input_motion(&ctx, evt.motion.x, evt.motion.y); - * else if (evt.type == [...]) { - * // [...] - * } - * } - * nk_input_end(&ctx); - * // [...] - * nk_clear(&ctx); - * } nk_free(&ctx); - * ``` - * - * # Reference - * Function | Description - * --------------------|------------------------------------------------------- - * \ref nk_input_begin | Begins the input mirroring process. Needs to be called before all other `nk_input_xxx` calls - * \ref nk_input_motion | Mirrors mouse cursor position - * \ref nk_input_key | Mirrors key state with either pressed or released - * \ref nk_input_button | Mirrors mouse button state with either pressed or released - * \ref nk_input_scroll | Mirrors mouse scroll values - * \ref nk_input_char | Adds a single ASCII text character into an internal text buffer - * \ref nk_input_glyph | Adds a single multi-byte UTF-8 character into an internal text buffer - * \ref nk_input_unicode| Adds a single unicode rune into an internal text buffer - * \ref nk_input_end | Ends the input mirroring process by calculating state changes. Don't call any `nk_input_xxx` - * function referenced above after this call - */ - -enum nk_keys { - NK_KEY_NONE, - NK_KEY_SHIFT, - NK_KEY_CTRL, - NK_KEY_DEL, - NK_KEY_ENTER, - NK_KEY_TAB, - NK_KEY_BACKSPACE, - NK_KEY_COPY, - NK_KEY_CUT, - NK_KEY_PASTE, - NK_KEY_UP, - NK_KEY_DOWN, - NK_KEY_LEFT, - NK_KEY_RIGHT, - /* Shortcuts: text field */ - NK_KEY_TEXT_INSERT_MODE, - NK_KEY_TEXT_REPLACE_MODE, - NK_KEY_TEXT_RESET_MODE, - NK_KEY_TEXT_LINE_START, - NK_KEY_TEXT_LINE_END, - NK_KEY_TEXT_START, - NK_KEY_TEXT_END, - NK_KEY_TEXT_UNDO, - NK_KEY_TEXT_REDO, - NK_KEY_TEXT_SELECT_ALL, - NK_KEY_TEXT_WORD_LEFT, - NK_KEY_TEXT_WORD_RIGHT, - NK_KEY_TEXT_WORD_DELETE_LEFT, - NK_KEY_TEXT_WORD_DELETE_RIGHT, - /* Shortcuts: scrollbar */ - NK_KEY_SCROLL_START, - NK_KEY_SCROLL_END, - NK_KEY_SCROLL_DOWN, - NK_KEY_SCROLL_UP, - NK_KEY_MAX -}; -enum nk_buttons { - NK_BUTTON_LEFT, - NK_BUTTON_MIDDLE, - NK_BUTTON_RIGHT, - NK_BUTTON_DOUBLE, /* Double click of the Left mouse button. */ - NK_BUTTON_X1, /* Commonly used for "Back" in UI navigation. Mouse Button 4. */ - NK_BUTTON_X2, /* Commonly used for "Forward" in UI navigation. Mouse Button 5. */ - NK_BUTTON_MAX -}; - -/** - * \brief Begins the input mirroring process by resetting text, scroll - * mouse, previous mouse position and movement as well as key state transitions. - * - * \details - * ```c - * void nk_input_begin(struct nk_context*); - * ``` - * - * \param[in] ctx Must point to a previously initialized `nk_context` struct - */ -NK_API void -nk_input_begin(struct nk_context *); - -/** - * \brief Mirrors current mouse position to nuklear - * - * \details - * ```c - * void nk_input_motion(struct nk_context *ctx, int x, int y); - * ``` - * - * \param[in] ctx Must point to a previously initialized `nk_context` struct - * \param[in] x Must hold an integer describing the current mouse cursor x-position - * \param[in] y Must hold an integer describing the current mouse cursor y-position - */ -NK_API void -nk_input_motion(struct nk_context *, int x, int y); - -/** - * \brief Mirrors the state of a specific key to nuklear - * - * \details - * ```c - * void nk_input_key(struct nk_context*, enum nk_keys key, nk_bool down); - * ``` - * - * \param[in] ctx Must point to a previously initialized `nk_context` struct - * \param[in] key Must be any value specified in enum `nk_keys` that needs to be mirrored - * \param[in] down Must be 0 for key is up and 1 for key is down - */ -NK_API void -nk_input_key(struct nk_context *, enum nk_keys, nk_bool down); - -/** - * \brief Mirrors the state of a specific mouse button to nuklear - * - * \details - * ```c - * void nk_input_button(struct nk_context *ctx, enum nk_buttons btn, int x, int y, nk_bool down); - * ``` - * - * \param[in] ctx Must point to a previously initialized `nk_context` struct - * \param[in] btn Must be any value specified in enum `nk_buttons` that needs to be mirrored - * \param[in] x Must contain an integer describing mouse cursor x-position on click up/down - * \param[in] y Must contain an integer describing mouse cursor y-position on click up/down - * \param[in] down Must be 0 for key is up and 1 for key is down - */ -NK_API void -nk_input_button(struct nk_context *, enum nk_buttons, int x, int y, nk_bool down); - -/** - * \brief Copies the last mouse scroll value to nuklear. - * - * \details - * Is generally a scroll value. So does not have to come from mouse and could - * also originate from balls, tracks, linear guide rails, or other programs. - * - * ```c - * void nk_input_scroll(struct nk_context *ctx, struct nk_vec2 val); - * ``` - * - * \param[in] ctx | Must point to a previously initialized `nk_context` struct - * \param[in] val | vector with both X- as well as Y-scroll value - */ -NK_API void -nk_input_scroll(struct nk_context *, struct nk_vec2 val); - -/** - * \brief Copies a single ASCII character into an internal text buffer - * - * \details - * This is basically a helper function to quickly push ASCII characters into - * nuklear. - * - * \note - * Stores up to NK_INPUT_MAX bytes between `nk_input_begin` and `nk_input_end`. - * - * ```c - * void nk_input_char(struct nk_context *ctx, char c); - * ``` - * - * \param[in] ctx | Must point to a previously initialized `nk_context` struct - * \param[in] c | Must be a single ASCII character preferable one that can be printed - */ -NK_API void -nk_input_char(struct nk_context *, char); - -/** - * \brief Converts an encoded unicode rune into UTF-8 and copies the result into an - * internal text buffer. - * - * \note - * Stores up to NK_INPUT_MAX bytes between `nk_input_begin` and `nk_input_end`. - * - * ```c - * void nk_input_glyph(struct nk_context *ctx, const nk_glyph g); - * ``` - * - * \param[in] ctx | Must point to a previously initialized `nk_context` struct - * \param[in] g | UTF-32 unicode codepoint - */ -NK_API void -nk_input_glyph(struct nk_context *, const nk_glyph); - -/** - * \brief Converts a unicode rune into UTF-8 and copies the result - * into an internal text buffer. - * - * \details - * \note - * Stores up to NK_INPUT_MAX bytes between `nk_input_begin` and `nk_input_end`. - * - * ```c - * void nk_input_unicode(struct nk_context*, nk_rune rune); - * ``` - * - * \param[in] ctx | Must point to a previously initialized `nk_context` struct - * \param[in] rune | UTF-32 unicode codepoint - */ -NK_API void -nk_input_unicode(struct nk_context *, nk_rune); - -/** - * \brief End the input mirroring process by resetting mouse grabbing - * state to ensure the mouse cursor is not grabbed indefinitely. - * - * \details - * ```c - * void nk_input_end(struct nk_context *ctx); - * ``` - * - * \param[in] ctx | Must point to a previously initialized `nk_context` struct - */ -NK_API void -nk_input_end(struct nk_context *); - -/* ============================================================================= - * - * DRAWING - * - * =============================================================================*/ -/** - * \page Drawing - * This library was designed to be render backend agnostic so it does - * not draw anything to screen directly. Instead all drawn shapes, widgets - * are made of, are buffered into memory and make up a command queue. - * Each frame therefore fills the command buffer with draw commands - * that then need to be executed by the user and his own render backend. - * After that the command buffer needs to be cleared and a new frame can be - * started. It is probably important to note that the command buffer is the main - * drawing API and the optional vertex buffer API only takes this format and - * converts it into a hardware accessible format. - * - * # Usage - * To draw all draw commands accumulated over a frame you need your own render - * backend able to draw a number of 2D primitives. This includes at least - * filled and stroked rectangles, circles, text, lines, triangles and scissors. - * As soon as this criterion is met you can iterate over each draw command - * and execute each draw command in a interpreter like fashion: - * - * ```c - * const struct nk_command *cmd = 0; - * nk_foreach(cmd, &ctx) { - * switch (cmd->type) { - * case NK_COMMAND_LINE: - * your_draw_line_function(...) - * break; - * case NK_COMMAND_RECT - * your_draw_rect_function(...) - * break; - * case //...: - * //[...] - * } - * } - * ``` - * - * In program flow context draw commands need to be executed after input has been - * gathered and the complete UI with windows and their contained widgets have - * been executed and before calling `nk_clear` which frees all previously - * allocated draw commands. - * - * ```c - * struct nk_context ctx; - * nk_init_xxx(&ctx, ...); - * while (1) { - * Event evt; - * nk_input_begin(&ctx); - * while (GetEvent(&evt)) { - * if (evt.type == MOUSE_MOVE) - * nk_input_motion(&ctx, evt.motion.x, evt.motion.y); - * else if (evt.type == [...]) { - * [...] - * } - * } - * nk_input_end(&ctx); - * // - * // [...] - * // - * const struct nk_command *cmd = 0; - * nk_foreach(cmd, &ctx) { - * switch (cmd->type) { - * case NK_COMMAND_LINE: - * your_draw_line_function(...) - * break; - * case NK_COMMAND_RECT - * your_draw_rect_function(...) - * break; - * case ...: - * // [...] - * } - * nk_clear(&ctx); - * } - * nk_free(&ctx); - * ``` - * - * You probably noticed that you have to draw all of the UI each frame which is - * quite wasteful. While the actual UI updating loop is quite fast rendering - * without actually needing it is not. So there are multiple things you could do. - * - * First is only update on input. This of course is only an option if your - * application only depends on the UI and does not require any outside calculations. - * If you actually only update on input make sure to update the UI two times each - * frame and call `nk_clear` directly after the first pass and only draw in - * the second pass. In addition it is recommended to also add additional timers - * to make sure the UI is not drawn more than a fixed number of frames per second. - * - * ```c - * struct nk_context ctx; - * nk_init_xxx(&ctx, ...); - * while (1) { - * // [...wait for input ] - * // [...do two UI passes ...] - * do_ui(...) - * nk_clear(&ctx); - * do_ui(...) - * // - * // draw - * const struct nk_command *cmd = 0; - * nk_foreach(cmd, &ctx) { - * switch (cmd->type) { - * case NK_COMMAND_LINE: - * your_draw_line_function(...) - * break; - * case NK_COMMAND_RECT - * your_draw_rect_function(...) - * break; - * case ...: - * //[...] - * } - * nk_clear(&ctx); - * } - * nk_free(&ctx); - * ``` - * - * The second probably more applicable trick is to only draw if anything changed. - * It is not really useful for applications with continuous draw loop but - * quite useful for desktop applications. To actually get nuklear to only - * draw on changes you first have to define `NK_ZERO_COMMAND_MEMORY` and - * allocate a memory buffer that will store each unique drawing output. - * After each frame you compare the draw command memory inside the library - * with your allocated buffer by memcmp. If memcmp detects differences - * you have to copy the command buffer into the allocated buffer - * and then draw like usual (this example uses fixed memory but you could - * use dynamically allocated memory). - * - * ```c - * //[... other defines ...] - * #define NK_ZERO_COMMAND_MEMORY - * #include "nuklear.h" - * // - * // setup context - * struct nk_context ctx; - * void *last = calloc(1,64*1024); - * void *buf = calloc(1,64*1024); - * nk_init_fixed(&ctx, buf, 64*1024); - * // - * // loop - * while (1) { - * // [...input...] - * // [...ui...] - * void *cmds = nk_buffer_memory(&ctx.memory); - * if (memcmp(cmds, last, ctx.memory.allocated)) { - * memcpy(last,cmds,ctx.memory.allocated); - * const struct nk_command *cmd = 0; - * nk_foreach(cmd, &ctx) { - * switch (cmd->type) { - * case NK_COMMAND_LINE: - * your_draw_line_function(...) - * break; - * case NK_COMMAND_RECT - * your_draw_rect_function(...) - * break; - * case ...: - * // [...] - * } - * } - * } - * nk_clear(&ctx); - * } - * nk_free(&ctx); - * ``` - * - * Finally while using draw commands makes sense for higher abstracted platforms like - * X11 and Win32 or drawing libraries it is often desirable to use graphics - * hardware directly. Therefore it is possible to just define - * `NK_INCLUDE_VERTEX_BUFFER_OUTPUT` which includes optional vertex output. - * To access the vertex output you first have to convert all draw commands into - * vertexes by calling `nk_convert` which takes in your preferred vertex format. - * After successfully converting all draw commands just iterate over and execute all - * vertex draw commands: - * - * ```c - * // fill configuration - * struct your_vertex - * { - * float pos[2]; // important to keep it to 2 floats - * float uv[2]; - * unsigned char col[4]; - * }; - * struct nk_convert_config cfg = {}; - * static const struct nk_draw_vertex_layout_element vertex_layout[] = { - * {NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct your_vertex, pos)}, - * {NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct your_vertex, uv)}, - * {NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct your_vertex, col)}, - * {NK_VERTEX_LAYOUT_END} - * }; - * cfg.shape_AA = NK_ANTI_ALIASING_ON; - * cfg.line_AA = NK_ANTI_ALIASING_ON; - * cfg.vertex_layout = vertex_layout; - * cfg.vertex_size = sizeof(struct your_vertex); - * cfg.vertex_alignment = NK_ALIGNOF(struct your_vertex); - * cfg.circle_segment_count = 22; - * cfg.curve_segment_count = 22; - * cfg.arc_segment_count = 22; - * cfg.global_alpha = 1.0f; - * cfg.tex_null = dev->tex_null; - * // - * // setup buffers and convert - * struct nk_buffer cmds, verts, idx; - * nk_buffer_init_default(&cmds); - * nk_buffer_init_default(&verts); - * nk_buffer_init_default(&idx); - * nk_convert(&ctx, &cmds, &verts, &idx, &cfg); - * // - * // draw - * nk_draw_foreach(cmd, &ctx, &cmds) { - * if (!cmd->elem_count) continue; - * //[...] - * } - * nk_buffer_free(&cms); - * nk_buffer_free(&verts); - * nk_buffer_free(&idx); - * ``` - * - * # Reference - * Function | Description - * --------------------|------------------------------------------------------- - * \ref nk__begin | Returns the first draw command in the context draw command list to be drawn - * \ref nk__next | Increments the draw command iterator to the next command inside the context draw command list - * \ref nk_foreach | Iterates over each draw command inside the context draw command list - * \ref nk_convert | Converts from the abstract draw commands list into a hardware accessible vertex format - * \ref nk_draw_begin | Returns the first vertex command in the context vertex draw list to be executed - * \ref nk__draw_next | Increments the vertex command iterator to the next command inside the context vertex command - * list - * \ref nk__draw_end | Returns the end of the vertex draw list - * \ref nk_draw_foreach | Iterates over each vertex draw command inside the vertex draw list - */ - -enum nk_anti_aliasing { NK_ANTI_ALIASING_OFF, NK_ANTI_ALIASING_ON }; -enum nk_convert_result { - NK_CONVERT_SUCCESS = 0, - NK_CONVERT_INVALID_PARAM = 1, - NK_CONVERT_COMMAND_BUFFER_FULL = NK_FLAG(1), - NK_CONVERT_VERTEX_BUFFER_FULL = NK_FLAG(2), - NK_CONVERT_ELEMENT_BUFFER_FULL = NK_FLAG(3) -}; -struct nk_draw_null_texture { - nk_handle texture; /**!< texture handle to a texture with a white pixel */ - struct nk_vec2 uv; /**!< coordinates to a white pixel in the texture */ -}; -struct nk_convert_config { - float global_alpha; /**!< global alpha value */ - enum nk_anti_aliasing line_AA; /**!< line anti-aliasing flag can be turned off if you are tight on memory */ - enum nk_anti_aliasing shape_AA; /**!< shape anti-aliasing flag can be turned off if you are tight on memory */ - unsigned circle_segment_count; /**!< number of segments used for circles: default to 22 */ - unsigned arc_segment_count; /**!< number of segments used for arcs: default to 22 */ - unsigned curve_segment_count; /**!< number of segments used for curves: default to 22 */ - struct nk_draw_null_texture tex_null; /**!< handle to texture with a white pixel for shape drawing */ - const struct nk_draw_vertex_layout_element *vertex_layout; /**!< describes the vertex output format and packing */ - nk_size vertex_size; /**!< sizeof one vertex for vertex packing */ - nk_size vertex_alignment; /**!< vertex alignment: Can be obtained by NK_ALIGNOF */ -}; - -/** - * \brief Returns a draw command list iterator to iterate all draw - * commands accumulated over one frame. - * - * \details - * ```c - * const struct nk_command* nk__begin(struct nk_context*); - * ``` - * - * \param[in] ctx | must point to an previously initialized `nk_context` struct at the end of a frame - * - * \returns draw command pointer pointing to the first command inside the draw command list - */ -NK_API const struct nk_command * -nk__begin(struct nk_context *); - -/** - * \brief Returns draw command pointer pointing to the next command inside the draw command list - * - * \details - * ```c - * const struct nk_command* nk__next(struct nk_context*, const struct nk_command*); - * ``` - * - * \param[in] ctx | Must point to an previously initialized `nk_context` struct at the end of a frame - * \param[in] cmd | Must point to an previously a draw command either returned by `nk__begin` or `nk__next` - * - * \returns draw command pointer pointing to the next command inside the draw command list - */ -NK_API const struct nk_command * -nk__next(struct nk_context *, const struct nk_command *); - -/** - * \brief Iterates over each draw command inside the context draw command list - * - * ```c - * #define nk_foreach(c, ctx) - * ``` - * - * \param[in] ctx | Must point to an previously initialized `nk_context` struct at the end of a frame - * \param[in] cmd | Command pointer initialized to NULL - */ -#define nk_foreach(c, ctx) for ((c) = nk__begin(ctx); (c) != 0; (c) = nk__next(ctx, c)) - -#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT - -/** - * \brief Converts all internal draw commands into vertex draw commands and fills - * three buffers with vertexes, vertex draw commands and vertex indices. - * - * \details - * The vertex format as well as some other configuration values have to be - * configured by filling out a `nk_convert_config` struct. - * - * ```c - * nk_flags nk_convert(struct nk_context *ctx, struct nk_buffer *cmds, - * struct nk_buffer *vertices, struct nk_buffer *elements, const struct nk_convert_config*); - * ``` - * - * \param[in] ctx Must point to an previously initialized `nk_context` struct at the end of a frame - * \param[out] cmds Must point to a previously initialized buffer to hold converted vertex draw commands - * \param[out] vertices Must point to a previously initialized buffer to hold all produced vertices - * \param[out] elements Must point to a previously initialized buffer to hold all produced vertex indices - * \param[in] config Must point to a filled out `nk_config` struct to configure the conversion process - * - * \returns one of enum nk_convert_result error codes - * - * Parameter | Description - * --------------------------------|----------------------------------------------------------- - * NK_CONVERT_SUCCESS | Signals a successful draw command to vertex buffer conversion - * NK_CONVERT_INVALID_PARAM | An invalid argument was passed in the function call - * NK_CONVERT_COMMAND_BUFFER_FULL | The provided buffer for storing draw commands is full or failed to allocate more - * memory NK_CONVERT_VERTEX_BUFFER_FULL | The provided buffer for storing vertices is full or failed to allocate more - * memory NK_CONVERT_ELEMENT_BUFFER_FULL | The provided buffer for storing indices is full or failed to allocate more - * memory - */ -NK_API nk_flags -nk_convert(struct nk_context *, - struct nk_buffer *cmds, - struct nk_buffer *vertices, - struct nk_buffer *elements, - const struct nk_convert_config *); - -/** - * \brief Returns a draw vertex command buffer iterator to iterate over the vertex draw command buffer - * - * \details - * ```c - * const struct nk_draw_command* nk__draw_begin(const struct nk_context*, const struct nk_buffer*); - * ``` - * - * \param[in] ctx | Must point to an previously initialized `nk_context` struct at the end of a frame - * \param[in] buf | Must point to an previously by `nk_convert` filled out vertex draw command buffer - * - * \returns vertex draw command pointer pointing to the first command inside the vertex draw command buffer - */ -NK_API const struct nk_draw_command * -nk__draw_begin(const struct nk_context *, const struct nk_buffer *); - -/** - - * # # nk__draw_end - * \returns the vertex draw command at the end of the vertex draw command buffer - * - * ```c - * const struct nk_draw_command* nk__draw_end(const struct nk_context *ctx, const struct nk_buffer *buf); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct at the end of a frame - * \param[in] buf | Must point to an previously by `nk_convert` filled out vertex draw command buffer - * - * \returns vertex draw command pointer pointing to the end of the last vertex draw command inside the vertex draw - command buffer - - */ -NK_API const struct nk_draw_command * -nk__draw_end(const struct nk_context *, const struct nk_buffer *); - -/** - * # # nk__draw_next - * Increments the vertex draw command buffer iterator - * - * ```c - * const struct nk_draw_command* nk__draw_next(const struct nk_draw_command*, const struct nk_buffer*, const struct - nk_context*); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] cmd | Must point to an previously either by `nk__draw_begin` or `nk__draw_next` returned vertex draw - command - * \param[in] buf | Must point to an previously by `nk_convert` filled out vertex draw command buffer - * \param[in] ctx | Must point to an previously initialized `nk_context` struct at the end of a frame - * - * \returns vertex draw command pointer pointing to the end of the last vertex draw command inside the vertex draw - command buffer - - */ -NK_API const struct nk_draw_command * -nk__draw_next(const struct nk_draw_command *, const struct nk_buffer *, const struct nk_context *); - -/** - * # # nk_draw_foreach - * Iterates over each vertex draw command inside a vertex draw command buffer - * - * ```c - * #define nk_draw_foreach(cmd,ctx, b) - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] cmd | `nk_draw_command`iterator set to NULL - * \param[in] buf | Must point to an previously by `nk_convert` filled out vertex draw command buffer - * \param[in] ctx | Must point to an previously initialized `nk_context` struct at the end of a frame - */ - -# define nk_draw_foreach(cmd, ctx, b) \ - for ((cmd) = nk__draw_begin(ctx, b); (cmd) != 0; (cmd) = nk__draw_next(cmd, b, ctx)) -#endif - -/* ============================================================================= - * - * WINDOW - * - * =============================================================================*/ -/** - * \page Window - * Windows are the main persistent state used inside nuklear and are life time - * controlled by simply "retouching" (i.e.\ calling) each window each frame. - * All widgets inside nuklear can only be added inside the function pair `nk_begin_xxx` - * and `nk_end`. Calling any widgets outside these two functions will result in an - * assert in debug or no state change in release mode.

- * - * Each window holds frame persistent state like position, size, flags, state tables, - * and some garbage collected internal persistent widget state. Each window - * is linked into a window stack list which determines the drawing and overlapping - * order. The topmost window thereby is the currently active window.

- * - * To change window position inside the stack occurs either automatically by - * user input by being clicked on or programmatically by calling `nk_window_focus`. - * Windows by default are visible unless explicitly being defined with flag - * `NK_WINDOW_HIDDEN`, the user clicked the close button on windows with flag - * `NK_WINDOW_CLOSABLE` or if a window was explicitly hidden by calling - * `nk_window_show`. To explicitly close and destroy a window call `nk_window_close`.

- * - * # Usage - * To create and keep a window you have to call one of the two `nk_begin_xxx` - * functions to start window declarations and `nk_end` at the end. Furthermore it - * is recommended to check the return value of `nk_begin_xxx` and only process - * widgets inside the window if the value is not 0. Either way you have to call - * `nk_end` at the end of window declarations. Furthermore, do not attempt to - * nest `nk_begin_xxx` calls which will hopefully result in an assert or if not - * in a segmentation fault. - * - * ```c - * if (nk_begin_xxx(...) { - * // [... widgets ...] - * } - * nk_end(ctx); - * ``` - * - * In the grand concept window and widget declarations need to occur after input - * handling and before drawing to screen. Not doing so can result in higher - * latency or at worst invalid behavior. Furthermore make sure that `nk_clear` - * is called at the end of the frame. While nuklear's default platform backends - * already call `nk_clear` for you if you write your own backend not calling - * `nk_clear` can cause asserts or even worse undefined behavior. - * - * ```c - * struct nk_context ctx; - * nk_init_xxx(&ctx, ...); - * while (1) { - * Event evt; - * nk_input_begin(&ctx); - * while (GetEvent(&evt)) { - * if (evt.type == MOUSE_MOVE) - * nk_input_motion(&ctx, evt.motion.x, evt.motion.y); - * else if (evt.type == [...]) { - * nk_input_xxx(...); - * } - * } - * nk_input_end(&ctx); - * - * if (nk_begin_xxx(...) { - * //[...] - * } - * nk_end(ctx); - * - * const struct nk_command *cmd = 0; - * nk_foreach(cmd, &ctx) { - * case NK_COMMAND_LINE: - * your_draw_line_function(...) - * break; - * case NK_COMMAND_RECT - * your_draw_rect_function(...) - * break; - * case //...: - * //[...] - * } - * nk_clear(&ctx); - * } - * nk_free(&ctx); - * ``` - * - * # Reference - * Function | Description - * -----------------------------------------|---------------------------------------- - * \ref nk_begin | Starts a new window; needs to be called every frame for every window (unless hidden) or otherwise the window gets removed - * \ref nk_begin_titled | Extended window start with separated title and identifier to allow multiple windows with same name but not title - * \ref nk_end | Needs to be called at the end of the window building process to process scaling, scrollbars and general cleanup - * - * Function | Description - * -----------------------------------------|---------------------------------------- - * \ref nk_window_find | Finds and returns the window with give name - * \ref nk_window_get_bounds | Returns a rectangle with screen position and size of the currently processed window. - * \ref nk_window_get_position | Returns the position of the currently processed window - * \ref nk_window_get_size | Returns the size with width and height of the currently processed window - * \ref nk_window_get_width | Returns the width of the currently processed window - * \ref nk_window_get_height | Returns the height of the currently processed window - * \ref nk_window_get_panel | Returns the underlying panel which contains all processing state of the current window - * \ref nk_window_get_content_region | Returns the position and size of the currently visible and non-clipped space inside the currently processed window - * \ref nk_window_get_content_region_min | Returns the upper rectangle position of the currently visible and non-clipped space inside the currently processed window - * \ref nk_window_get_content_region_max | Returns the upper rectangle position of the currently visible and non-clipped space inside the currently processed window - * \ref nk_window_get_content_region_size | Returns the size of the currently visible and non-clipped space inside the currently processed window - * \ref nk_window_get_canvas | Returns the draw command buffer. Can be used to draw custom widgets - * \ref nk_window_get_scroll | Gets the scroll offset of the current window - * \ref nk_window_has_focus | Returns if the currently processed window is currently active - * \ref nk_window_is_collapsed | Returns if the window with given name is currently minimized/collapsed - * \ref nk_window_is_closed | Returns if the currently processed window was closed - * \ref nk_window_is_hidden | Returns if the currently processed window was hidden - * \ref nk_window_is_active | Same as nk_window_has_focus for some reason - * \ref nk_window_is_hovered | Returns if the currently processed window is currently being hovered by mouse - * \ref nk_window_is_any_hovered | Return if any window currently hovered - * \ref nk_item_is_any_active | Returns if any window or widgets is currently hovered or active - * - * Function | Description - * -----------------------------------------|---------------------------------------- - * \ref nk_window_set_bounds | Updates position and size of the currently processed window - * \ref nk_window_set_position | Updates position of the currently process window - * \ref nk_window_set_size | Updates the size of the currently processed window - * \ref nk_window_set_focus | Set the currently processed window as active window - * \ref nk_window_set_scroll | Sets the scroll offset of the current window - * - * Function | Description - * -----------------------------------------|---------------------------------------- - * \ref nk_window_close | Closes the window with given window name which deletes the window at the end of the frame - * \ref nk_window_collapse | Collapses the window with given window name - * \ref nk_window_collapse_if | Collapses the window with given window name if the given condition was met - * \ref nk_window_show | Hides a visible or reshows a hidden window - * \ref nk_window_show_if | Hides/shows a window depending on condition - - * # nk_panel_flags - * Flag | Description - * ----------------------------------|---------------------------------------- - * NK_WINDOW_BORDER | Draws a border around the window to visually separate window from the background - * NK_WINDOW_MOVABLE | The movable flag indicates that a window can be moved by user input or by dragging the window header - * NK_WINDOW_SCALABLE | The scalable flag indicates that a window can be scaled by user input by dragging a scaler icon at the button of the window - * NK_WINDOW_CLOSABLE | Adds a closable icon into the header - * NK_WINDOW_MINIMIZABLE | Adds a minimize icon into the header - * NK_WINDOW_TITLE | Forces a header at the top at the window showing the title - * NK_WINDOW_SCROLL_AUTO_HIDE | Automatically hides the window scrollbar if no user interaction: also requires delta time in `nk_context` to be set each frame - * NK_WINDOW_BACKGROUND | Always keep window in the background - * NK_WINDOW_SCALE_LEFT | Puts window scaler in the left-bottom corner instead right-bottom - * NK_WINDOW_NO_INPUT | Prevents window of scaling, moving or getting focus - * NK_WINDOW_NO_VERTICAL_SCROLLBAR | Disables vertical scrolling and vertical scrollbar - * NK_WINDOW_NO_HORIZONTAL_SCROLLBAR | Disables horizontal scrolling and horizontal scrollbar - * NK_WINDOW_NO_SCROLLBAR | Disables both vertical and horizontal scrolling - * NK_WINDOW_CLOSE_BUTTON_HIDES | Header close button hides the window instead of closing/destroying it - * - * # nk_collapse_states - * State | Description - * ----------------|----------------------------------------------------------- - * NK_MINIMIZED| UI section is collapsed and not visible until maximized - * NK_MAXIMIZED| UI section is extended and visible until minimized - */ - -enum nk_panel_flags { - NK_WINDOW_BORDER = NK_FLAG(0), - NK_WINDOW_MOVABLE = NK_FLAG(1), - NK_WINDOW_SCALABLE = NK_FLAG(2), - NK_WINDOW_CLOSABLE = NK_FLAG(3), - NK_WINDOW_MINIMIZABLE = NK_FLAG(4), - NK_WINDOW_MAXIMIZABLE = NK_FLAG(5), - NK_WINDOW_NO_SCROLLBAR_V = NK_FLAG(6), - NK_WINDOW_NO_SCROLLBAR_H = NK_FLAG(7), - NK_WINDOW_TITLE = NK_FLAG(8), - NK_WINDOW_SCROLL_AUTO_HIDE = NK_FLAG(9), - NK_WINDOW_BACKGROUND = NK_FLAG(10), - NK_WINDOW_SCALE_LEFT = NK_FLAG(11), - NK_WINDOW_NO_INPUT = NK_FLAG(12), - NK_WINDOW_CLOSE_BUTTON_HIDES = NK_FLAG(13), - NK_WINDOW_NO_SCROLLBAR = NK_WINDOW_NO_SCROLLBAR_V | NK_WINDOW_NO_SCROLLBAR_H, -}; - -/** - * # # nk_begin - * Starts a new window; needs to be called every frame for every - * window (unless hidden) or otherwise the window gets removed - * - * ```c - * nk_bool nk_begin(struct nk_context *ctx, const char *title, struct nk_rect bounds, nk_flags flags); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] title | Window title and identifier. Needs to be persistent over frames to identify the window - * \param[in] bounds | Initial position and window size. However if you do not define `NK_WINDOW_SCALABLE` or - `NK_WINDOW_MOVABLE` you can set window position and size every frame - * \param[in] flags | Window flags defined in the nk_panel_flags section with a number of different window behaviors - * - * \returns `true(1)` if the window can be filled up with widgets from this point - * until `nk_end` or `false(0)` otherwise for example if minimized - - */ -NK_API nk_bool -nk_begin(struct nk_context *ctx, const char *title, struct nk_rect bounds, nk_flags flags); - -/** - * # # nk_begin_titled - * Extended window start with separated title and identifier to allow multiple - * windows with same title but not name - * - * ```c - * nk_bool nk_begin_titled(struct nk_context *ctx, const char *name, const char *title, struct nk_rect bounds, nk_flags - flags); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] name | Window identifier. Needs to be persistent over frames to identify the window - * \param[in] title | Window title displayed inside header if flag `NK_WINDOW_TITLE` or either `NK_WINDOW_CLOSABLE` or - `NK_WINDOW_MINIMIZED` was set - * \param[in] bounds | Initial position and window size. However if you do not define `NK_WINDOW_SCALABLE` or - `NK_WINDOW_MOVABLE` you can set window position and size every frame - * \param[in] flags | Window flags defined in the nk_panel_flags section with a number of different window behaviors - * - * \returns `true(1)` if the window can be filled up with widgets from this point - * until `nk_end` or `false(0)` otherwise for example if minimized - - */ -NK_API nk_bool -nk_begin_titled(struct nk_context *ctx, const char *name, const char *title, struct nk_rect bounds, nk_flags flags); - -/** - * # # nk_end - * Needs to be called at the end of the window building process to process scaling, scrollbars and general cleanup. - * All widget calls after this functions will result in asserts or no state changes - * - * ```c - * void nk_end(struct nk_context *ctx); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - - */ -NK_API void -nk_end(struct nk_context *ctx); - -/** - * # # nk_window_find - * Finds and returns a window from passed name - * - * ```c - * struct nk_window *nk_window_find(struct nk_context *ctx, const char *name); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] name | Window identifier - * - * \returns a `nk_window` struct pointing to the identified window or NULL if - * no window with the given name was found - */ -NK_API struct nk_window * -nk_window_find(const struct nk_context *ctx, const char *name); - -NK_API void -nk_window_set_maximize_bounds(struct nk_context *ctx, struct nk_rect bounds); - -/** - * # # nk_window_get_bounds - * \returns a rectangle with screen position and size of the currently processed window - * - * !!! \warning - * Only call this function between calls `nk_begin_xxx` and `nk_end` - * ```c - * struct nk_rect nk_window_get_bounds(const struct nk_context *ctx); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * - * \returns a `nk_rect` struct with window upper left window position and size - - */ -NK_API struct nk_rect -nk_window_get_bounds(const struct nk_context *ctx); - -/** - * # # nk_window_get_position - * \returns the position of the currently processed window. - * - * !!! \warning - * Only call this function between calls `nk_begin_xxx` and `nk_end` - * ```c - * struct nk_vec2 nk_window_get_position(const struct nk_context *ctx); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * - * \returns a `nk_vec2` struct with window upper left position - - */ -NK_API struct nk_vec2 -nk_window_get_position(const struct nk_context *ctx); - -/** - * # # nk_window_get_size - * \returns the size with width and height of the currently processed window. - * - * !!! \warning - * Only call this function between calls `nk_begin_xxx` and `nk_end` - * ```c - * struct nk_vec2 nk_window_get_size(const struct nk_context *ctx); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * - * \returns a `nk_vec2` struct with window width and height - - */ -NK_API struct nk_vec2 -nk_window_get_size(const struct nk_context *ctx); - -/** - * nk_window_get_width - * \returns the width of the currently processed window. - * - * !!! \warning - * Only call this function between calls `nk_begin_xxx` and `nk_end` - * ```c - * float nk_window_get_width(const struct nk_context *ctx); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * - * \returns the current window width - */ -NK_API float -nk_window_get_width(const struct nk_context *ctx); - -/** - * # # nk_window_get_height - * \returns the height of the currently processed window. - * - * !!! \warning - * Only call this function between calls `nk_begin_xxx` and `nk_end` - * ```c - * float nk_window_get_height(const struct nk_context *ctx); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * - * \returns the current window height - - */ -NK_API float -nk_window_get_height(const struct nk_context *ctx); - -/** - * # # nk_window_get_panel - * \returns the underlying panel which contains all processing state of the current window. - * - * !!! \warning - * Only call this function between calls `nk_begin_xxx` and `nk_end` - * !!! \warning - * Do not keep the returned panel pointer around, it is only valid until `nk_end` - * ```c - * struct nk_panel* nk_window_get_panel(struct nk_context *ctx); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * - * \returns a pointer to window internal `nk_panel` state. - - */ -NK_API struct nk_panel * -nk_window_get_panel(const struct nk_context *ctx); - -/** - * # # nk_window_get_content_region - * \returns the position and size of the currently visible and non-clipped space - * inside the currently processed window. - * - * !!! \warning - * Only call this function between calls `nk_begin_xxx` and `nk_end` - * - * ```c - * struct nk_rect nk_window_get_content_region(struct nk_context *ctx); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * - * \returns `nk_rect` struct with screen position and size (no scrollbar offset) - * of the visible space inside the current window - - */ -NK_API struct nk_rect -nk_window_get_content_region(const struct nk_context *ctx); - -/** - * # # nk_window_get_content_region_min - * \returns the upper left position of the currently visible and non-clipped - * space inside the currently processed window. - * - * !!! \warning - * Only call this function between calls `nk_begin_xxx` and `nk_end` - * - * ```c - * struct nk_vec2 nk_window_get_content_region_min(struct nk_context *ctx); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * - * returns `nk_vec2` struct with upper left screen position (no scrollbar offset) - * of the visible space inside the current window - - */ -NK_API struct nk_vec2 -nk_window_get_content_region_min(const struct nk_context *ctx); - -/** - * # # nk_window_get_content_region_max - * \returns the lower right screen position of the currently visible and - * non-clipped space inside the currently processed window. - * - * !!! \warning - * Only call this function between calls `nk_begin_xxx` and `nk_end` - * - * ```c - * struct nk_vec2 nk_window_get_content_region_max(struct nk_context *ctx); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * - * \returns `nk_vec2` struct with lower right screen position (no scrollbar offset) - * of the visible space inside the current window - - */ -NK_API struct nk_vec2 -nk_window_get_content_region_max(const struct nk_context *ctx); - -/** - * # # nk_window_get_content_region_size - * \returns the size of the currently visible and non-clipped space inside the - * currently processed window - * - * !!! \warning - * Only call this function between calls `nk_begin_xxx` and `nk_end` - * - * ```c - * struct nk_vec2 nk_window_get_content_region_size(struct nk_context *ctx); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * - * \returns `nk_vec2` struct with size the visible space inside the current window - - */ -NK_API struct nk_vec2 -nk_window_get_content_region_size(const struct nk_context *ctx); - -/** - * # # nk_window_get_canvas - * \returns the draw command buffer. Can be used to draw custom widgets - * !!! \warning - * Only call this function between calls `nk_begin_xxx` and `nk_end` - * !!! \warning - * Do not keep the returned command buffer pointer around it is only valid until `nk_end` - * - * ```c - * struct nk_command_buffer* nk_window_get_canvas(struct nk_context *ctx); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * - * \returns a pointer to window internal `nk_command_buffer` struct used as - * drawing canvas. Can be used to do custom drawing. - */ -NK_API struct nk_command_buffer * -nk_window_get_canvas(const struct nk_context *ctx); - -/** - * # # nk_window_get_scroll - * Gets the scroll offset for the current window - * !!! \warning - * Only call this function between calls `nk_begin_xxx` and `nk_end` - * - * ```c - * void nk_window_get_scroll(struct nk_context *ctx, nk_uint *offset_x, nk_uint *offset_y); - * ``` - * - * Parameter | Description - * -------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] offset_x | A pointer to the x offset output (or NULL to ignore) - * \param[in] offset_y | A pointer to the y offset output (or NULL to ignore) - - */ -NK_API void -nk_window_get_scroll(const struct nk_context *ctx, nk_uint *offset_x, nk_uint *offset_y); - -/** - * # # nk_window_has_focus - * \returns if the currently processed window is currently active - * !!! \warning - * Only call this function between calls `nk_begin_xxx` and `nk_end` - * ```c - * nk_bool nk_window_has_focus(const struct nk_context *ctx); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * - * \returns `false(0)` if current window is not active or `true(1)` if it is - - */ -NK_API nk_bool -nk_window_has_focus(const struct nk_context *ctx); - -/** - * # # nk_window_is_hovered - * Return if the current window is being hovered - * !!! \warning - * Only call this function between calls `nk_begin_xxx` and `nk_end` - * ```c - * nk_bool nk_window_is_hovered(struct nk_context *ctx); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * - * \returns `true(1)` if current window is hovered or `false(0)` otherwise - - */ -NK_API nk_bool -nk_window_is_hovered(const struct nk_context *ctx); - -/** - * # # nk_window_is_collapsed - * \returns if the window with given name is currently minimized/collapsed - * ```c - * nk_bool nk_window_is_collapsed(struct nk_context *ctx, const char *name); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] name | Identifier of window you want to check if it is collapsed - * - * \returns `true(1)` if current window is minimized and `false(0)` if window not - * found or is not minimized - - */ -NK_API nk_bool -nk_window_is_collapsed(const struct nk_context *ctx, const char *name); - -/** - * # # nk_window_is_closed - * \returns if the window with given name was closed by calling `nk_close` - * ```c - * nk_bool nk_window_is_closed(struct nk_context *ctx, const char *name); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] name | Identifier of window you want to check if it is closed - * - * \returns `true(1)` if current window was closed or `false(0)` window not found or not closed - - */ -NK_API nk_bool -nk_window_is_closed(const struct nk_context *ctx, const char *name); - -/** - * # # nk_window_is_hidden - * \returns if the window with given name is hidden - * ```c - * nk_bool nk_window_is_hidden(struct nk_context *ctx, const char *name); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] name | Identifier of window you want to check if it is hidden - * - * \returns `true(1)` if current window is hidden or `false(0)` window not found or visible - - */ -NK_API nk_bool -nk_window_is_hidden(const struct nk_context *ctx, const char *name); - -/** - * # # nk_window_is_active - * Same as nk_window_has_focus for some reason - * ```c - * nk_bool nk_window_is_active(struct nk_context *ctx, const char *name); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] name | Identifier of window you want to check if it is active - * - * \returns `true(1)` if current window is active or `false(0)` window not found or not active - */ -NK_API nk_bool -nk_window_is_active(const struct nk_context *ctx, const char *name); - -/** - * # # nk_window_is_any_hovered - * \returns if the any window is being hovered - * ```c - * nk_bool nk_window_is_any_hovered(struct nk_context*); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * - * \returns `true(1)` if any window is hovered or `false(0)` otherwise - */ -NK_API nk_bool -nk_window_is_any_hovered(const struct nk_context *ctx); - -/** - * # # nk_item_is_any_active - * \returns if the any window is being hovered or any widget is currently active. - * Can be used to decide if input should be processed by UI or your specific input handling. - * Example could be UI and 3D camera to move inside a 3D space. - * ```c - * nk_bool nk_item_is_any_active(struct nk_context*); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * - * \returns `true(1)` if any window is hovered or any item is active or `false(0)` otherwise - - */ -NK_API nk_bool -nk_item_is_any_active(const struct nk_context *ctx); - -/** - * # # nk_window_set_bounds - * Updates position and size of window with passed in name - * ```c - * void nk_window_set_bounds(struct nk_context*, const char *name, struct nk_rect bounds); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] name | Identifier of the window to modify both position and size - * \param[in] bounds | Must point to a `nk_rect` struct with the new position and size - - */ -NK_API void -nk_window_set_bounds(struct nk_context *ctx, const char *name, struct nk_rect bounds); - -/** - * # # nk_window_set_position - * Updates position of window with passed name - * ```c - * void nk_window_set_position(struct nk_context*, const char *name, struct nk_vec2 pos); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] name | Identifier of the window to modify both position - * \param[in] pos | Must point to a `nk_vec2` struct with the new position - - */ -NK_API void -nk_window_set_position(struct nk_context *ctx, const char *name, struct nk_vec2 pos); - -/** - * # # nk_window_set_size - * Updates size of window with passed in name - * ```c - * void nk_window_set_size(struct nk_context*, const char *name, struct nk_vec2); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] name | Identifier of the window to modify both window size - * \param[in] size | Must point to a `nk_vec2` struct with new window size - - */ -NK_API void -nk_window_set_size(struct nk_context *ctx, const char *name, struct nk_vec2 size); - -/** - * # # nk_window_set_focus - * Sets the window with given name as active - * ```c - * void nk_window_set_focus(struct nk_context*, const char *name); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] name | Identifier of the window to set focus on - - */ -NK_API void -nk_window_set_focus(struct nk_context *ctx, const char *name); - -/** - * # # nk_window_set_scroll - * Sets the scroll offset for the current window - * !!! \warning - * Only call this function between calls `nk_begin_xxx` and `nk_end` - * - * ```c - * void nk_window_set_scroll(struct nk_context *ctx, nk_uint offset_x, nk_uint offset_y); - * ``` - * - * Parameter | Description - * -------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] offset_x | The x offset to scroll to - * \param[in] offset_y | The y offset to scroll to - - */ -NK_API void -nk_window_set_scroll(struct nk_context *ctx, nk_uint offset_x, nk_uint offset_y); - -/** - * # # nk_window_close - * Closes a window and marks it for being freed at the end of the frame - * ```c - * void nk_window_close(struct nk_context *ctx, const char *name); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] name | Identifier of the window to close - - */ -NK_API void -nk_window_close(struct nk_context *ctx, const char *name); - -/** - * # # nk_window_collapse - * Updates collapse state of a window with given name - * ```c - * void nk_window_collapse(struct nk_context*, const char *name, enum nk_collapse_states state); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] name | Identifier of the window to close - * \param[in] state | value out of nk_collapse_states section - - */ -NK_API void -nk_window_collapse(struct nk_context *ctx, const char *name, enum nk_collapse_states state); - -/** - * # # nk_window_collapse_if - * Updates collapse state of a window with given name if given condition is met - * ```c - * void nk_window_collapse_if(struct nk_context*, const char *name, enum nk_collapse_states, int cond); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] name | Identifier of the window to either collapse or maximize - * \param[in] state | value out of nk_collapse_states section the window should be put into - * \param[in] cond | condition that has to be met to actually commit the collapse state change - - */ -NK_API void -nk_window_collapse_if(struct nk_context *ctx, const char *name, enum nk_collapse_states state, int cond); - -/** - * # # nk_window_show - * updates visibility state of a window with given name - * ```c - * void nk_window_show(struct nk_context*, const char *name, enum nk_show_states); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] name | Identifier of the window to either collapse or maximize - * \param[in] state | state with either visible or hidden to modify the window with - */ -NK_API void -nk_window_show(struct nk_context *ctx, const char *name, enum nk_show_states state); - -/** - * # # nk_window_show_if - * Updates visibility state of a window with given name if a given condition is met - * ```c - * void nk_window_show_if(struct nk_context*, const char *name, enum nk_show_states, int cond); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] name | Identifier of the window to either hide or show - * \param[in] state | state with either visible or hidden to modify the window with - * \param[in] cond | condition that has to be met to actually commit the visibility state change - - */ -NK_API void -nk_window_show_if(struct nk_context *ctx, const char *name, enum nk_show_states state, int cond); - -/** - * # # nk_window_show_if - * Line for visual separation. Draws a line with thickness determined by the current row height. - * ```c - * void nk_rule_horizontal(struct nk_context *ctx, struct nk_color color, nk_bool rounding) - * ``` - * - * Parameter | Description - * ----------------|------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] color | Color of the horizontal line - * \param[in] rounding | Whether or not to make the line round - */ -NK_API void -nk_rule_horizontal(struct nk_context *ctx, struct nk_color color, nk_bool rounding); - -/* ============================================================================= - * - * LAYOUT - * - * =============================================================================*/ -/** - * \page Layouting - * Layouting in general describes placing widget inside a window with position and size. - * While in this particular implementation there are five different APIs for layouting - * each with different trade offs between control and ease of use.

- * - * All layouting methods in this library are based around the concept of a row. - * A row has a height the window content grows by and a number of columns and each - * layouting method specifies how each widget is placed inside the row. - * After a row has been allocated by calling a layouting functions and then - * filled with widgets will advance an internal pointer over the allocated row.

- * - * To actually define a layout you just call the appropriate layouting function - * and each subsequent widget call will place the widget as specified. Important - * here is that if you define more widgets then columns defined inside the layout - * functions it will allocate the next row without you having to make another layouting call.

- * - * Biggest limitation with using all these APIs outside the `nk_layout_space_xxx` API - * is that you have to define the row height for each. However the row height - * often depends on the height of the font.

- * - * To fix that internally nuklear uses a minimum row height that is set to the - * height plus padding of currently active font and overwrites the row height - * value if zero.

- * - * If you manually want to change the minimum row height then - * use nk_layout_set_min_row_height, and use nk_layout_reset_min_row_height to - * reset it back to be derived from font height.

- * - * Also if you change the font in nuklear it will automatically change the minimum - * row height for you and. This means if you change the font but still want - * a minimum row height smaller than the font you have to repush your value.

- * - * For actually more advanced UI I would even recommend using the `nk_layout_space_xxx` - * layouting method in combination with a cassowary constraint solver (there are - * some versions on github with permissive license model) to take over all control over widget - * layouting yourself. However for quick and dirty layouting using all the other layouting - * functions should be fine. - * - * # Usage - * 1. __nk_layout_row_dynamic__

- * The easiest layouting function is `nk_layout_row_dynamic`. It provides each - * widgets with same horizontal space inside the row and dynamically grows - * if the owning window grows in width. So the number of columns dictates - * the size of each widget dynamically by formula: - * - * ```c - * widget_width = (window_width - padding - spacing) * (1/column_count) - * ``` - * - * Just like all other layouting APIs if you define more widget than columns this - * library will allocate a new row and keep all layouting parameters previously - * defined. - * - * ```c - * if (nk_begin_xxx(...) { - * // first row with height: 30 composed of two widgets - * nk_layout_row_dynamic(&ctx, 30, 2); - * nk_widget(...); - * nk_widget(...); - * // - * // second row with same parameter as defined above - * nk_widget(...); - * nk_widget(...); - * // - * // third row uses 0 for height which will use auto layouting - * nk_layout_row_dynamic(&ctx, 0, 2); - * nk_widget(...); - * nk_widget(...); - * } - * nk_end(...); - * ``` - * - * 2. __nk_layout_row_static__

- * Another easy layouting function is `nk_layout_row_static`. It provides each - * widget with same horizontal pixel width inside the row and does not grow - * if the owning window scales smaller or bigger. - * - * ```c - * if (nk_begin_xxx(...) { - * // first row with height: 30 composed of two widgets with width: 80 - * nk_layout_row_static(&ctx, 30, 80, 2); - * nk_widget(...); - * nk_widget(...); - * // - * // second row with same parameter as defined above - * nk_widget(...); - * nk_widget(...); - * // - * // third row uses 0 for height which will use auto layouting - * nk_layout_row_static(&ctx, 0, 80, 2); - * nk_widget(...); - * nk_widget(...); - * } - * nk_end(...); - * ``` - * - * 3. __nk_layout_row_xxx__

- * A little bit more advanced layouting API are functions `nk_layout_row_begin`, - * `nk_layout_row_push` and `nk_layout_row_end`. They allow to directly - * specify each column pixel or window ratio in a row. It supports either - * directly setting per column pixel width or widget window ratio but not - * both. Furthermore it is a immediate mode API so each value is directly - * pushed before calling a widget. Therefore the layout is not automatically - * repeating like the last two layouting functions. - * - * ```c - * if (nk_begin_xxx(...) { - * // first row with height: 25 composed of two widgets with width 60 and 40 - * nk_layout_row_begin(ctx, NK_STATIC, 25, 2); - * nk_layout_row_push(ctx, 60); - * nk_widget(...); - * nk_layout_row_push(ctx, 40); - * nk_widget(...); - * nk_layout_row_end(ctx); - * // - * // second row with height: 25 composed of two widgets with window ratio 0.25 and 0.75 - * nk_layout_row_begin(ctx, NK_DYNAMIC, 25, 2); - * nk_layout_row_push(ctx, 0.25f); - * nk_widget(...); - * nk_layout_row_push(ctx, 0.75f); - * nk_widget(...); - * nk_layout_row_end(ctx); - * // - * // third row with auto generated height: composed of two widgets with window ratio 0.25 and 0.75 - * nk_layout_row_begin(ctx, NK_DYNAMIC, 0, 2); - * nk_layout_row_push(ctx, 0.25f); - * nk_widget(...); - * nk_layout_row_push(ctx, 0.75f); - * nk_widget(...); - * nk_layout_row_end(ctx); - * } - * nk_end(...); - * ``` - * - * 4. __nk_layout_row__

- * The array counterpart to API nk_layout_row_xxx is the single nk_layout_row - * functions. Instead of pushing either pixel or window ratio for every widget - * it allows to define it by array. The trade of for less control is that - * `nk_layout_row` is automatically repeating. Otherwise the behavior is the - * same. - * - * ```c - * if (nk_begin_xxx(...) { - * // two rows with height: 30 composed of two widgets with width 60 and 40 - * const float ratio[] = {60,40}; - * nk_layout_row(ctx, NK_STATIC, 30, 2, ratio); - * nk_widget(...); - * nk_widget(...); - * nk_widget(...); - * nk_widget(...); - * // - * // two rows with height: 30 composed of two widgets with window ratio 0.25 and 0.75 - * const float ratio[] = {0.25, 0.75}; - * nk_layout_row(ctx, NK_DYNAMIC, 30, 2, ratio); - * nk_widget(...); - * nk_widget(...); - * nk_widget(...); - * nk_widget(...); - * // - * // two rows with auto generated height composed of two widgets with window ratio 0.25 and 0.75 - * const float ratio[] = {0.25, 0.75}; - * nk_layout_row(ctx, NK_DYNAMIC, 30, 2, ratio); - * nk_widget(...); - * nk_widget(...); - * nk_widget(...); - * nk_widget(...); - * } - * nk_end(...); - * ``` - * - * 5. __nk_layout_row_template_xxx__

- * The most complex and second most flexible API is a simplified flexbox version without - * line wrapping and weights for dynamic widgets. It is an immediate mode API but - * unlike `nk_layout_row_xxx` it has auto repeat behavior and needs to be called - * before calling the templated widgets. - * The row template layout has three different per widget size specifier. The first - * one is the `nk_layout_row_template_push_static` with fixed widget pixel width. - * They do not grow if the row grows and will always stay the same. - * The second size specifier is `nk_layout_row_template_push_variable` - * which defines a minimum widget size but it also can grow if more space is available - * not taken by other widgets. - * Finally there are dynamic widgets with `nk_layout_row_template_push_dynamic` - * which are completely flexible and unlike variable widgets can even shrink - * to zero if not enough space is provided. - * - * ```c - * if (nk_begin_xxx(...) { - * // two rows with height: 30 composed of three widgets - * nk_layout_row_template_begin(ctx, 30); - * nk_layout_row_template_push_dynamic(ctx); - * nk_layout_row_template_push_variable(ctx, 80); - * nk_layout_row_template_push_static(ctx, 80); - * nk_layout_row_template_end(ctx); - * // - * // first row - * nk_widget(...); // dynamic widget can go to zero if not enough space - * nk_widget(...); // variable widget with min 80 pixel but can grow bigger if enough space - * nk_widget(...); // static widget with fixed 80 pixel width - * // - * // second row same layout - * nk_widget(...); - * nk_widget(...); - * nk_widget(...); - * } - * nk_end(...); - * ``` - * - * 6. __nk_layout_space_xxx__

- * Finally the most flexible API directly allows you to place widgets inside the - * window. The space layout API is an immediate mode API which does not support - * row auto repeat and directly sets position and size of a widget. Position - * and size hereby can be either specified as ratio of allocated space or - * allocated space local position and pixel size. Since this API is quite - * powerful there are a number of utility functions to get the available space - * and convert between local allocated space and screen space. - * - * ```c - * if (nk_begin_xxx(...) { - * // static row with height: 500 (you can set column count to INT_MAX if you don't want to be bothered) - * nk_layout_space_begin(ctx, NK_STATIC, 500, INT_MAX); - * nk_layout_space_push(ctx, nk_rect(0,0,150,200)); - * nk_widget(...); - * nk_layout_space_push(ctx, nk_rect(200,200,100,200)); - * nk_widget(...); - * nk_layout_space_end(ctx); - * // - * // dynamic row with height: 500 (you can set column count to INT_MAX if you don't want to be bothered) - * nk_layout_space_begin(ctx, NK_DYNAMIC, 500, INT_MAX); - * nk_layout_space_push(ctx, nk_rect(0.5,0.5,0.1,0.1)); - * nk_widget(...); - * nk_layout_space_push(ctx, nk_rect(0.7,0.6,0.1,0.1)); - * nk_widget(...); - * } - * nk_end(...); - * ``` - * - * # Reference - * Function | Description - * ---------------------------------------------|------------------------------------ - * \ref nk_layout_set_min_row_height | Set the currently used minimum row height to a specified value - * \ref nk_layout_reset_min_row_height | Resets the currently used minimum row height to font height - * \ref nk_layout_widget_bounds | Calculates current width a static layout row can fit inside a window - * \ref nk_layout_ratio_from_pixel | Utility functions to calculate window ratio from pixel size - * \ref nk_layout_row_dynamic | Current layout is divided into n same sized growing columns - * \ref nk_layout_row_static | Current layout is divided into n same fixed sized columns - * \ref nk_layout_row_begin | Starts a new row with given height and number of columns - * \ref nk_layout_row_push | Pushes another column with given size or window ratio - * \ref nk_layout_row_end | Finished previously started row - * \ref nk_layout_row | Specifies row columns in array as either window ratio or size - * \ref nk_layout_row_template_begin | Begins the row template declaration - * \ref nk_layout_row_template_push_dynamic | Adds a dynamic column that dynamically grows and can go to zero if not - * enough space - * \ref nk_layout_row_template_push_variable | Adds a variable column that dynamically grows but does not shrink - * below specified pixel width - * \ref nk_layout_row_template_push_static | Adds a static column that does not grow and will always have the same - * size - * \ref nk_layout_row_template_end | Marks the end of the row template - * \ref nk_layout_space_begin | Begins a new layouting space that allows to specify each widgets - * position and size - * \ref nk_layout_space_push | Pushes position and size of the next widget in own coordinate space - * either as pixel or ratio - * \ref nk_layout_space_end | Marks the end of the layouting space - * \ref nk_layout_space_bounds | Callable after nk_layout_space_begin and returns total space allocated - * \ref nk_layout_space_to_screen | Converts vector from nk_layout_space coordinate space into screen - * space - * \ref nk_layout_space_to_local | Converts vector from screen space into nk_layout_space coordinates - * \ref nk_layout_space_rect_to_screen | Converts rectangle from nk_layout_space coordinate space into screen - * space - * \ref nk_layout_space_rect_to_local | Converts rectangle from screen space into nk_layout_space coordinates - */ - -enum nk_widget_align { - NK_WIDGET_ALIGN_LEFT = 0x01, - NK_WIDGET_ALIGN_CENTERED = 0x02, - NK_WIDGET_ALIGN_RIGHT = 0x04, - NK_WIDGET_ALIGN_TOP = 0x08, - NK_WIDGET_ALIGN_MIDDLE = 0x10, - NK_WIDGET_ALIGN_BOTTOM = 0x20 -}; -enum nk_widget_alignment { - NK_WIDGET_LEFT = NK_WIDGET_ALIGN_MIDDLE | NK_WIDGET_ALIGN_LEFT, - NK_WIDGET_CENTERED = NK_WIDGET_ALIGN_MIDDLE | NK_WIDGET_ALIGN_CENTERED, - NK_WIDGET_RIGHT = NK_WIDGET_ALIGN_MIDDLE | NK_WIDGET_ALIGN_RIGHT -}; - -/** - * Sets the currently used minimum row height. - * !!! \warning - * The passed height needs to include both your preferred row height - * as well as padding. No internal padding is added. - * - * ```c - * void nk_layout_set_min_row_height(struct nk_context*, float height); - * ``` - * - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx` - * \param[in] height | New minimum row height to be used for auto generating the row height - */ -NK_API void -nk_layout_set_min_row_height(struct nk_context *, float height); - -/** - * Reset the currently used minimum row height back to `font_height + text_padding + padding` - * ```c - * void nk_layout_reset_min_row_height(struct nk_context*); - * ``` - * - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx` - */ -NK_API void -nk_layout_reset_min_row_height(struct nk_context *); - -/** - * \brief Returns the width of the next row allocate by one of the layouting functions - * - * \details - * ```c - * struct nk_rect nk_layout_widget_bounds(struct nk_context*); - * ``` - * - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx` - * - * \return `nk_rect` with both position and size of the next row - */ -NK_API struct nk_rect -nk_layout_widget_bounds(const struct nk_context *ctx); - -/** - * \brief Utility functions to calculate window ratio from pixel size - * - * \details - * ```c - * float nk_layout_ratio_from_pixel(struct nk_context*, float pixel_width); - * ``` - * - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx` - * \param[in] pixel | Pixel_width to convert to window ratio - * - * \returns `nk_rect` with both position and size of the next row - */ -NK_API float -nk_layout_ratio_from_pixel(const struct nk_context *ctx, float pixel_width); - -/** - * \brief Sets current row layout to share horizontal space - * between @cols number of widgets evenly. Once called all subsequent widget - * calls greater than @cols will allocate a new row with same layout. - * - * \details - * ```c - * void nk_layout_row_dynamic(struct nk_context *ctx, float height, int cols); - * ``` - * - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx` - * \param[in] height | Holds height of each widget in row or zero for auto layouting - * \param[in] columns | Number of widget inside row - */ -NK_API void -nk_layout_row_dynamic(struct nk_context *ctx, float height, int cols); - -/** - * \brief Sets current row layout to fill @cols number of widgets - * in row with same @item_width horizontal size. Once called all subsequent widget - * calls greater than @cols will allocate a new row with same layout. - * - * \details - * ```c - * void nk_layout_row_static(struct nk_context *ctx, float height, int item_width, int cols); - * ``` - * - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx` - * \param[in] height | Holds height of each widget in row or zero for auto layouting - * \param[in] width | Holds pixel width of each widget in the row - * \param[in] columns | Number of widget inside row - */ -NK_API void -nk_layout_row_static(struct nk_context *ctx, float height, int item_width, int cols); - -/** - * \brief Starts a new dynamic or fixed row with given height and columns. - * - * \details - * ```c - * void nk_layout_row_begin(struct nk_context *ctx, enum nk_layout_format fmt, float row_height, int cols); - * ``` - * - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx` - * \param[in] fmt | either `NK_DYNAMIC` for window ratio or `NK_STATIC` for fixed size columns - * \param[in] height | holds height of each widget in row or zero for auto layouting - * \param[in] columns | Number of widget inside row - */ -NK_API void -nk_layout_row_begin(struct nk_context *ctx, enum nk_layout_format fmt, float row_height, int cols); - -/** - * \breif Specifies either window ratio or width of a single column - * - * \details - * ```c - * void nk_layout_row_push(struct nk_context*, float value); - * ``` - * - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx` - * \param[in] value | either a window ratio or fixed width depending on @fmt in previous `nk_layout_row_begin` call - */ -NK_API void -nk_layout_row_push(struct nk_context *, float value); - -/** - * \brief Finished previously started row - * - * \details - * ```c - * void nk_layout_row_end(struct nk_context*); - * ``` - * - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx` - */ -NK_API void -nk_layout_row_end(struct nk_context *); - -/** - * \brief Specifies row columns in array as either window ratio or size - * - * \details - * ```c - * void nk_layout_row(struct nk_context*, enum nk_layout_format, float height, int cols, const float *ratio); - * ``` - * - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx` - * \param[in] fmt | Either `NK_DYNAMIC` for window ratio or `NK_STATIC` for fixed size columns - * \param[in] height | Holds height of each widget in row or zero for auto layouting - * \param[in] columns | Number of widget inside row - */ -NK_API void -nk_layout_row(struct nk_context *, enum nk_layout_format, float height, int cols, const float *ratio); - -/** - * # # nk_layout_row_template_begin - * Begins the row template declaration - * ```c - * void nk_layout_row_template_begin(struct nk_context*, float row_height); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx` - * \param[in] height | Holds height of each widget in row or zero for auto layouting - */ -NK_API void -nk_layout_row_template_begin(struct nk_context *, float row_height); - -/** - * # # nk_layout_row_template_push_dynamic - * Adds a dynamic column that dynamically grows and can go to zero if not enough space - * ```c - * void nk_layout_row_template_push_dynamic(struct nk_context*); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx` - * \param[in] height | Holds height of each widget in row or zero for auto layouting - */ -NK_API void -nk_layout_row_template_push_dynamic(struct nk_context *); - -/** - * # # nk_layout_row_template_push_variable - * Adds a variable column that dynamically grows but does not shrink below specified pixel width - * ```c - * void nk_layout_row_template_push_variable(struct nk_context*, float min_width); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx` - * \param[in] width | Holds the minimum pixel width the next column must always be - */ -NK_API void -nk_layout_row_template_push_variable(struct nk_context *, float min_width); - -/** - * # # nk_layout_row_template_push_static - * Adds a static column that does not grow and will always have the same size - * ```c - * void nk_layout_row_template_push_static(struct nk_context*, float width); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx` - * \param[in] width | Holds the absolute pixel width value the next column must be - */ -NK_API void -nk_layout_row_template_push_static(struct nk_context *, float width); - -/** - * # # nk_layout_row_template_end - * Marks the end of the row template - * ```c - * void nk_layout_row_template_end(struct nk_context*); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx` - */ -NK_API void -nk_layout_row_template_end(struct nk_context *); - -/** - * # # nk_layout_space_begin - * Begins a new layouting space that allows to specify each widgets position and size. - * ```c - * void nk_layout_space_begin(struct nk_context*, enum nk_layout_format, float height, int widget_count); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_begin_xxx` - * \param[in] fmt | Either `NK_DYNAMIC` for window ratio or `NK_STATIC` for fixed size columns - * \param[in] height | Holds height of each widget in row or zero for auto layouting - * \param[in] columns | Number of widgets inside row - */ -NK_API void -nk_layout_space_begin(struct nk_context *, enum nk_layout_format, float height, int widget_count); - -/** - * # # nk_layout_space_push - * Pushes position and size of the next widget in own coordinate space either as pixel or ratio - * ```c - * void nk_layout_space_push(struct nk_context *ctx, struct nk_rect bounds); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin` - * \param[in] bounds | Position and size in laoyut space local coordinates - */ -NK_API void -nk_layout_space_push(struct nk_context *, struct nk_rect bounds); - -/** - * # # nk_layout_space_end - * Marks the end of the layout space - * ```c - * void nk_layout_space_end(struct nk_context*); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin` - */ -NK_API void -nk_layout_space_end(struct nk_context *); - -/** - * # # nk_layout_space_bounds - * Utility function to calculate total space allocated for `nk_layout_space` - * ```c - * struct nk_rect nk_layout_space_bounds(struct nk_context*); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin` - * - * \returns `nk_rect` holding the total space allocated - */ -NK_API struct nk_rect -nk_layout_space_bounds(const struct nk_context *ctx); - -/** - * # # nk_layout_space_to_screen - * Converts vector from nk_layout_space coordinate space into screen space - * ```c - * struct nk_vec2 nk_layout_space_to_screen(struct nk_context*, struct nk_vec2); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin` - * \param[in] vec | Position to convert from layout space into screen coordinate space - * - * \returns transformed `nk_vec2` in screen space coordinates - */ -NK_API struct nk_vec2 -nk_layout_space_to_screen(const struct nk_context *ctx, struct nk_vec2 vec); - -/** - * # # nk_layout_space_to_local - * Converts vector from layout space into screen space - * ```c - * struct nk_vec2 nk_layout_space_to_local(struct nk_context*, struct nk_vec2); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin` - * \param[in] vec | Position to convert from screen space into layout coordinate space - * - * \returns transformed `nk_vec2` in layout space coordinates - */ -NK_API struct nk_vec2 -nk_layout_space_to_local(const struct nk_context *ctx, struct nk_vec2 vec); - -/** - * # # nk_layout_space_rect_to_screen - * Converts rectangle from screen space into layout space - * ```c - * struct nk_rect nk_layout_space_rect_to_screen(struct nk_context*, struct nk_rect); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin` - * \param[in] bounds | Rectangle to convert from layout space into screen space - * - * \returns transformed `nk_rect` in screen space coordinates - */ -NK_API struct nk_rect -nk_layout_space_rect_to_screen(const struct nk_context *ctx, struct nk_rect bounds); - -/** - * # # nk_layout_space_rect_to_local - * Converts rectangle from layout space into screen space - * ```c - * struct nk_rect nk_layout_space_rect_to_local(struct nk_context*, struct nk_rect); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin` - * \param[in] bounds | Rectangle to convert from layout space into screen space - * - * \returns transformed `nk_rect` in layout space coordinates - */ -NK_API struct nk_rect -nk_layout_space_rect_to_local(const struct nk_context *ctx, struct nk_rect bounds); - -/** - * # # nk_spacer - * Spacer is a dummy widget that consumes space as usual but doesn't draw anything - * ```c - * void nk_spacer(struct nk_context* ); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after call `nk_layout_space_begin` - * - */ -NK_API void -nk_spacer(struct nk_context *ctx); - -NK_API float -nk_layout_get_remaining_height(const struct nk_context *ctx); - -/* ============================================================================= - * - * GROUP - * - * =============================================================================*/ -/** - * \page Groups - * Groups are basically windows inside windows. They allow to subdivide space - * in a window to layout widgets as a group. Almost all more complex widget - * layouting requirements can be solved using groups and basic layouting - * fuctionality. Groups just like windows are identified by an unique name and - * internally keep track of scrollbar offsets by default. However additional - * versions are provided to directly manage the scrollbar. - * - * # Usage - * To create a group you have to call one of the three `nk_group_begin_xxx` - * functions to start group declarations and `nk_group_end` at the end. Furthermore it - * is required to check the return value of `nk_group_begin_xxx` and only process - * widgets inside the window if the value is not 0. - * Nesting groups is possible and even encouraged since many layouting schemes - * can only be achieved by nesting. Groups, unlike windows, need `nk_group_end` - * to be only called if the corresponding `nk_group_begin_xxx` call does not return 0: - * - * ```c - * if (nk_group_begin_xxx(ctx, ...) { - * // [... widgets ...] - * nk_group_end(ctx); - * } - * ``` - * - * In the grand concept groups can be called after starting a window - * with `nk_begin_xxx` and before calling `nk_end`: - * - * ```c - * struct nk_context ctx; - * nk_init_xxx(&ctx, ...); - * while (1) { - * // Input - * Event evt; - * nk_input_begin(&ctx); - * while (GetEvent(&evt)) { - * if (evt.type == MOUSE_MOVE) - * nk_input_motion(&ctx, evt.motion.x, evt.motion.y); - * else if (evt.type == [...]) { - * nk_input_xxx(...); - * } - * } - * nk_input_end(&ctx); - * // - * // Window - * if (nk_begin_xxx(...) { - * // [...widgets...] - * nk_layout_row_dynamic(...); - * if (nk_group_begin_xxx(ctx, ...) { - * //[... widgets ...] - * nk_group_end(ctx); - * } - * } - * nk_end(ctx); - * // - * // Draw - * const struct nk_command *cmd = 0; - * nk_foreach(cmd, &ctx) { - * switch (cmd->type) { - * case NK_COMMAND_LINE: - * your_draw_line_function(...) - * break; - * case NK_COMMAND_RECT - * your_draw_rect_function(...) - * break; - * case ...: - * // [...] - * } - * nk_clear(&ctx); - * } - * nk_free(&ctx); - * ``` - * # Reference - * Function | Description - * --------------------------------|------------------------------------------- - * \ref nk_group_begin | Start a new group with internal scrollbar handling - * \ref nk_group_begin_titled | Start a new group with separated name and title and internal scrollbar - * handling - * \ref nk_group_end | Ends a group. Should only be called if nk_group_begin returned non-zero - * \ref nk_group_scrolled_offset_begin | Start a new group with manual separated handling of scrollbar x- and y-offset - * \ref nk_group_scrolled_begin | Start a new group with manual scrollbar handling - * \ref nk_group_scrolled_end | Ends a group with manual scrollbar handling. Should only be called if - * nk_group_begin returned non-zero - * \ref nk_group_get_scroll | Gets the scroll offset for the given group - * \ref nk_group_set_scroll | Sets the scroll offset for the given group - */ - -/** - * \brief Starts a new widget group. Requires a previous layouting function to specify a pos/size. - * ```c - * nk_bool nk_group_begin(struct nk_context*, const char *title, nk_flags); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] title | Must be an unique identifier for this group that is also used for the group header - * \param[in] flags | Window flags defined in the nk_panel_flags section with a number of different group behaviors - * - * \returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise - */ -NK_API nk_bool -nk_group_begin(struct nk_context *, const char *title, nk_flags); - -/** - * \brief Starts a new widget group. Requires a previous layouting function to specify a pos/size. - * ```c - * nk_bool nk_group_begin_titled(struct nk_context*, const char *name, const char *title, nk_flags); - * ``` - * - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] id | Must be an unique identifier for this group - * \param[in] title | Group header title - * \param[in] flags | Window flags defined in the nk_panel_flags section with a number of different group behaviors - * - * \returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise - */ -NK_API nk_bool -nk_group_begin_titled(struct nk_context *, const char *name, const char *title, nk_flags); - -/** - * # # nk_group_end - * Ends a widget group - * ```c - * void nk_group_end(struct nk_context*); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - */ -NK_API void -nk_group_end(struct nk_context *); - -/** - * # # nk_group_scrolled_offset_begin - * starts a new widget group. requires a previous layouting function to specify - * a size. Does not keep track of scrollbar. - * ```c - * nk_bool nk_group_scrolled_offset_begin(struct nk_context*, nk_uint *x_offset, nk_uint *y_offset, nk_uint *prev_max_x, - * nk_uint *prev_max_y, nk_uint *scroll_flags, const char *title, nk_flags flags); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] x_offset| Scrollbar x-offset to offset all widgets inside the group horizontally. - * \param[in] y_offset| Scrollbar y-offset to offset all widgets inside the group vertically - * \param[in] prev_max_x| - * \param[in] prev_max_y| - * \param[in] scroll_flags| - * \param[in] title | Window unique group title used to both identify and display in the group header - * \param[in] flags | Window flags from the nk_panel_flags section - * - * \returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise - */ -NK_API nk_bool -nk_group_scrolled_offset_begin(struct nk_context *, - nk_uint *x_offset, - nk_uint *y_offset, - nk_uint *prev_max_x, - nk_uint *prev_max_y, - nk_uint *scroll_flags, - const char *title, - nk_flags flags); - -/** - * # # nk_group_scrolled_begin - * Starts a new widget group. requires a previous - * layouting function to specify a size. Does not keep track of scrollbar. - * ```c - * nk_bool nk_group_scrolled_begin(struct nk_context*, struct nk_scroll *off, const char *title, nk_flags); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] off | Both x- and y- scroll offset. Allows for manual scrollbar control - * \param[in] title | Window unique group title used to both identify and display in the group header - * \param[in] flags | Window flags from nk_panel_flags section - * - * \returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise - */ -NK_API nk_bool -nk_group_scrolled_begin(struct nk_context *, struct nk_scroll *off, const char *title, nk_flags); - -/** - * # # nk_group_scrolled_end - * Ends a widget group after calling nk_group_scrolled_offset_begin or nk_group_scrolled_begin. - * ```c - * void nk_group_scrolled_end(struct nk_context*); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - */ -NK_API void -nk_group_scrolled_end(struct nk_context *); - -/** - * # # nk_group_get_scroll - * Gets the scroll position of the given group. - * ```c - * void nk_group_get_scroll(struct nk_context*, const char *id, nk_uint *x_offset, nk_uint *y_offset); - * ``` - * - * Parameter | Description - * -------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] id | The id of the group to get the scroll position of - * \param[in] x_offset | A pointer to the x offset output (or NULL to ignore) - * \param[in] x_offset | A pointer to the x offset output (or NULL to ignore) - * \param[in] prev_max_x | - * \param[in] prev_max_y | - * \param[in] scroll_flags | - */ -NK_API void -nk_group_get_scroll(struct nk_context *, - const char *id, - nk_uint *x_offset, - nk_uint *y_offset, - nk_uint *prev_max_x, - nk_uint *prev_max_y, - nk_uint *scroll_flags); - -/** - * # # nk_group_set_scroll - * Sets the scroll position of the given group. - * ```c - * void nk_group_set_scroll(struct nk_context*, const char *id, nk_uint x_offset, nk_uint y_offset); - * ``` - * - * Parameter | Description - * -------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] id | The id of the group to scroll - * \param[in] x_offset | The x offset to scroll to - * \param[in] y_offset | The y offset to scroll to - */ -NK_API void -nk_group_set_scroll(struct nk_context *, const char *id, nk_uint x_offset, nk_uint y_offset); - -/* ============================================================================= - * - * TREE - * - * =============================================================================*/ -/** - * \page Tree - * Trees represent two different concept. First the concept of a collapsible - * UI section that can be either in a hidden or visible state. They allow the UI - * user to selectively minimize the current set of visible UI to comprehend. - * The second concept are tree widgets for visual UI representation of trees.

- * - * Trees thereby can be nested for tree representations and multiple nested - * collapsible UI sections. All trees are started by calling of the - * `nk_tree_xxx_push_tree` functions and ended by calling one of the - * `nk_tree_xxx_pop_xxx()` functions. Each starting functions takes a title label - * and optionally an image to be displayed and the initial collapse state from - * the nk_collapse_states section.

- * - * The runtime state of the tree is either stored outside the library by the caller - * or inside which requires a unique ID. The unique ID can either be generated - * automatically from `__FILE__` and `__LINE__` with function `nk_tree_push`, - * by `__FILE__` and a user provided ID generated for example by loop index with - * function `nk_tree_push_id` or completely provided from outside by user with - * function `nk_tree_push_hashed`. - * - * # Usage - * To create a tree you have to call one of the seven `nk_tree_xxx_push_xxx` - * functions to start a collapsible UI section and `nk_tree_xxx_pop` to mark the - * end. - * Each starting function will either return `false(0)` if the tree is collapsed - * or hidden and therefore does not need to be filled with content or `true(1)` - * if visible and required to be filled. - * - * !!! Note - * The tree header does not require and layouting function and instead - * calculates a auto height based on the currently used font size - * - * The tree ending functions only need to be called if the tree content is - * actually visible. So make sure the tree push function is guarded by `if` - * and the pop call is only taken if the tree is visible. - * - * ```c - * if (nk_tree_push(ctx, NK_TREE_TAB, "Tree", NK_MINIMIZED)) { - * nk_layout_row_dynamic(...); - * nk_widget(...); - * nk_tree_pop(ctx); - * } - * ``` - * - * # Reference - * Function | Description - * ----------------------------|------------------------------------------- - * nk_tree_push | Start a collapsible UI section with internal state management - * nk_tree_push_id | Start a collapsible UI section with internal state management callable in a look - * nk_tree_push_hashed | Start a collapsible UI section with internal state management with full control over - * internal unique ID use to store state nk_tree_image_push | Start a collapsible UI section with image and - * label header nk_tree_image_push_id | Start a collapsible UI section with image and label header and internal - * state management callable in a look nk_tree_image_push_hashed | Start a collapsible UI section with image and label - * header and internal state management with full control over internal unique ID use to store state nk_tree_pop | Ends - * a collapsible UI section nk_tree_state_push | Start a collapsible UI section with external state management - * nk_tree_state_image_push | Start a collapsible UI section with image and label header and external state - * management nk_tree_state_pop | Ends a collapsabale UI section - * - * # nk_tree_type - * Flag | Description - * ----------------|---------------------------------------- - * NK_TREE_NODE | Highlighted tree header to mark a collapsible UI section - * NK_TREE_TAB | Non-highlighted tree header closer to tree representations - */ - -/** - * # # nk_tree_push - * Starts a collapsible UI section with internal state management - * !!! \warning - * To keep track of the runtime tree collapsible state this function uses - * defines `__FILE__` and `__LINE__` to generate a unique ID. If you want - * to call this function in a loop please use `nk_tree_push_id` or - * `nk_tree_push_hashed` instead. - * - * ```c - * #define nk_tree_push(ctx, type, title, state) - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] type | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable - * UI section or tree node - * \param[in] title | Label printed in the tree header - * \param[in] state | Initial tree state value out of nk_collapse_states - * - * \returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise - */ -#define nk_tree_push(ctx, type, title, state) \ - nk_tree_push_hashed(ctx, type, title, state, NK_FILE_LINE, nk_strlen(NK_FILE_LINE), __LINE__) -#define nk_tree_push_text(ctx, type, title, title_len, state) \ - nk_tree_push_hashed_text(ctx, type, title, title_len, state, NK_FILE_LINE, nk_strlen(NK_FILE_LINE), __LINE__) - -/** - * # # nk_tree_push_id - * Starts a collapsible UI section with internal state management callable in a look - * ```c - * #define nk_tree_push_id(ctx, type, title, state, id) - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] type | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable - * UI section or tree node - * \param[in] title | Label printed in the tree header - * \param[in] state | Initial tree state value out of nk_collapse_states - * \param[in] id | Loop counter index if this function is called in a loop - * - * \returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise - */ -#define nk_tree_push_id(ctx, type, title, state, id) \ - nk_tree_push_hashed(ctx, type, title, state, NK_FILE_LINE, nk_strlen(NK_FILE_LINE), id) -#define nk_tree_push_id_text(ctx, type, title, title_len, state, id) \ - nk_tree_push_hashed_text(ctx, type, title, title_len, state, NK_FILE_LINE, nk_strlen(NK_FILE_LINE), id) - -/** - * # # nk_tree_push_hashed - * Start a collapsible UI section with internal state management with full - * control over internal unique ID used to store state - * ```c - * nk_bool nk_tree_push_hashed(struct nk_context*, enum nk_tree_type, const char *title, enum nk_collapse_states - * initial_state, const char *hash, int len,int seed); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] type | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable - * UI section or tree node - * \param[in] title | Label printed in the tree header - * \param[in] state | Initial tree state value out of nk_collapse_states - * \param[in] hash | Memory block or string to generate the ID from - * \param[in] len | Size of passed memory block or string in __hash__ - * \param[in] seed | Seeding value if this function is called in a loop or default to `0` - * - * \returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise - */ -NK_API nk_bool -nk_tree_push_hashed(struct nk_context *, - enum nk_tree_type, - const char *title, - enum nk_collapse_states initial_state, - const char *hash, - int len, - int seed); -NK_API nk_bool -nk_tree_push_hashed_text(struct nk_context *, - enum nk_tree_type, - const char *title, - int title_len, - enum nk_collapse_states initial_state, - const char *hash, - int len, - int seed); - -/** - * # # nk_tree_image_push - * Start a collapsible UI section with image and label header - * !!! \warning - * To keep track of the runtime tree collapsible state this function uses - * defines `__FILE__` and `__LINE__` to generate a unique ID. If you want - * to call this function in a loop please use `nk_tree_image_push_id` or - * `nk_tree_image_push_hashed` instead. - * - * ```c - * #define nk_tree_image_push(ctx, type, img, title, state) - * ``` - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] type | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable - * UI section or tree node - * \param[in] img | Image to display inside the header on the left of the label - * \param[in] title | Label printed in the tree header - * \param[in] state | Initial tree state value out of nk_collapse_states - * - * \returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise - */ -#define nk_tree_image_push(ctx, type, img, title, state) \ - nk_tree_image_push_hashed(ctx, type, img, title, state, NK_FILE_LINE, nk_strlen(NK_FILE_LINE), __LINE__) - -/** - * # # nk_tree_image_push_id - * Start a collapsible UI section with image and label header and internal state - * management callable in a look - * - * ```c - * #define nk_tree_image_push_id(ctx, type, img, title, state, id) - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] type | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable - * UI section or tree node - * \param[in] img | Image to display inside the header on the left of the label - * \param[in] title | Label printed in the tree header - * \param[in] state | Initial tree state value out of nk_collapse_states - * \param[in] id | Loop counter index if this function is called in a loop - * - * \returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise - */ -#define nk_tree_image_push_id(ctx, type, img, title, state, id) \ - nk_tree_image_push_hashed(ctx, type, img, title, state, NK_FILE_LINE, nk_strlen(NK_FILE_LINE), id) - -/** - * # # nk_tree_image_push_hashed - * Start a collapsible UI section with internal state management with full - * control over internal unique ID used to store state - * ```c - * nk_bool nk_tree_image_push_hashed(struct nk_context*, enum nk_tree_type, struct nk_image, const char *title, enum - * nk_collapse_states initial_state, const char *hash, int len,int seed); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct - * \param[in] type | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable - * UI section or tree node - * \param[in] img | Image to display inside the header on the left of the label - * \param[in] title | Label printed in the tree header - * \param[in] state | Initial tree state value out of nk_collapse_states - * \param[in] hash | Memory block or string to generate the ID from - * \param[in] len | Size of passed memory block or string in __hash__ - * \param[in] seed | Seeding value if this function is called in a loop or default to `0` - * - * \returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise - */ -NK_API nk_bool -nk_tree_image_push_hashed(struct nk_context *, - enum nk_tree_type, - struct nk_image, - const char *title, - enum nk_collapse_states initial_state, - const char *hash, - int len, - int seed); - -/** - * # # nk_tree_pop - * Ends a collapsabale UI section - * ```c - * void nk_tree_pop(struct nk_context*); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after calling `nk_tree_xxx_push_xxx` - */ -NK_API void -nk_tree_pop(struct nk_context *); - -/** - * # # nk_tree_state_push - * Start a collapsible UI section with external state management - * ```c - * nk_bool nk_tree_state_push(struct nk_context*, enum nk_tree_type, const char *title, enum nk_collapse_states *state); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after calling `nk_tree_xxx_push_xxx` - * \param[in] type | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable - * UI section or tree node - * \param[in] title | Label printed in the tree header - * \param[in] state | Persistent state to update - * - * \returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise - */ -NK_API nk_bool -nk_tree_state_push(struct nk_context *, enum nk_tree_type, const char *title, enum nk_collapse_states *state); -NK_API nk_bool -nk_tree_state_push_text( - struct nk_context *ctx, enum nk_tree_type type, const char *title, int title_len, enum nk_collapse_states *state); - -/** - * # # nk_tree_state_image_push - * Start a collapsible UI section with image and label header and external state management - * ```c - * nk_bool nk_tree_state_image_push(struct nk_context*, enum nk_tree_type, struct nk_image, const char *title, enum - * nk_collapse_states *state); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after calling `nk_tree_xxx_push_xxx` - * \param[in] img | Image to display inside the header on the left of the label - * \param[in] type | Value from the nk_tree_type section to visually mark a tree node header as either a collapseable - * UI section or tree node - * \param[in] title | Label printed in the tree header - * \param[in] state | Persistent state to update - * - * \returns `true(1)` if visible and fillable with widgets or `false(0)` otherwise - */ -NK_API nk_bool -nk_tree_state_image_push( - struct nk_context *, enum nk_tree_type, struct nk_image, const char *title, enum nk_collapse_states *state); - -/** - * # # nk_tree_state_pop - * Ends a collapsabale UI section - * ```c - * void nk_tree_state_pop(struct nk_context*); - * ``` - * - * Parameter | Description - * ------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after calling `nk_tree_xxx_push_xxx` - */ -NK_API void -nk_tree_state_pop(struct nk_context *); - -#define nk_tree_element_push(ctx, type, title, state, sel) \ - nk_tree_element_push_hashed(ctx, type, title, state, sel, NK_FILE_LINE, nk_strlen(NK_FILE_LINE), __LINE__) -#define nk_tree_element_push_id(ctx, type, title, state, sel, id) \ - nk_tree_element_push_hashed(ctx, type, title, state, sel, NK_FILE_LINE, nk_strlen(NK_FILE_LINE), id) -NK_API nk_bool -nk_tree_element_push_hashed(struct nk_context *, - enum nk_tree_type, - const char *title, - enum nk_collapse_states initial_state, - nk_bool *selected, - const char *hash, - int len, - int seed); -NK_API nk_bool -nk_tree_element_image_push_hashed(struct nk_context *, - enum nk_tree_type, - struct nk_image, - const char *title, - enum nk_collapse_states initial_state, - nk_bool *selected, - const char *hash, - int len, - int seed); -NK_API void -nk_tree_element_pop(struct nk_context *); - -/* ============================================================================= - * - * LIST VIEW - * - * ============================================================================= */ -struct nk_list_view { - /* public: */ - int begin, end, count; - /* private: */ - int total_height; - struct nk_context *ctx; - nk_uint *scroll_pointer; - nk_uint scroll_value; - nk_uint *prev_max_pointer; - nk_uint prev_max_value; - nk_uint *prev_flags_pointer; -}; -NK_API nk_bool -nk_list_view_begin( - struct nk_context *, struct nk_list_view *out, const char *id, nk_flags, int row_height, int row_count); -NK_API void -nk_list_view_end(struct nk_list_view *); -/* ============================================================================= - * - * WIDGET - * - * ============================================================================= */ -enum nk_widget_layout_states { - NK_WIDGET_INVALID, /**< The widget cannot be seen and is completely out of view */ - NK_WIDGET_VALID, /**< The widget is completely inside the window and can be updated and drawn */ - NK_WIDGET_ROM, /**< The widget is partially visible and cannot be updated */ - NK_WIDGET_DISABLED /**< The widget is manually disabled and acts like NK_WIDGET_ROM */ -}; -enum nk_widget_states { - NK_WIDGET_STATE_MODIFIED = NK_FLAG(1), - NK_WIDGET_STATE_INACTIVE = NK_FLAG(2), /**!< widget is neither active nor hovered */ - NK_WIDGET_STATE_ENTERED = NK_FLAG(3), /**!< widget has been hovered on the current frame */ - NK_WIDGET_STATE_HOVER = NK_FLAG(4), /**!< widget is being hovered */ - NK_WIDGET_STATE_ACTIVED = NK_FLAG(5), /**!< widget is currently activated */ - NK_WIDGET_STATE_LEFT = NK_FLAG(6), /**!< widget is from this frame on not hovered anymore */ - NK_WIDGET_STATE_HOVERED = NK_WIDGET_STATE_HOVER | NK_WIDGET_STATE_MODIFIED, /**!< widget is being hovered */ - NK_WIDGET_STATE_ACTIVE = NK_WIDGET_STATE_ACTIVED | NK_WIDGET_STATE_MODIFIED /**!< widget is currently activated */ -}; -NK_API enum nk_widget_layout_states -nk_widget(struct nk_rect *, const struct nk_context *); -NK_API enum nk_widget_layout_states -nk_widget_fitting(struct nk_rect *, const struct nk_context *, struct nk_vec2); -NK_API struct nk_rect -nk_widget_bounds(const struct nk_context *); -NK_API struct nk_vec2 -nk_widget_position(const struct nk_context *); -NK_API struct nk_vec2 -nk_widget_size(const struct nk_context *); -NK_API float -nk_widget_width(const struct nk_context *); -NK_API float -nk_widget_height(const struct nk_context *); -NK_API nk_bool -nk_widget_is_hovered(const struct nk_context *); -NK_API nk_bool -nk_widget_is_mouse_clicked(const struct nk_context *, enum nk_buttons); -NK_API nk_bool -nk_widget_has_mouse_click_down(const struct nk_context *, enum nk_buttons, nk_bool down); -NK_API void -nk_spacing(struct nk_context *, int cols); -NK_API void -nk_widget_disable_begin(struct nk_context *ctx); -NK_API void -nk_widget_disable_end(struct nk_context *ctx); -/* ============================================================================= - * - * TEXT - * - * ============================================================================= */ -enum nk_text_align { - NK_TEXT_ALIGN_LEFT = 0x01, - NK_TEXT_ALIGN_CENTERED = 0x02, - NK_TEXT_ALIGN_RIGHT = 0x04, - NK_TEXT_ALIGN_TOP = 0x08, - NK_TEXT_ALIGN_MIDDLE = 0x10, - NK_TEXT_ALIGN_BOTTOM = 0x20 -}; -enum nk_text_alignment { - NK_TEXT_LEFT = NK_TEXT_ALIGN_MIDDLE | NK_TEXT_ALIGN_LEFT, - NK_TEXT_CENTERED = NK_TEXT_ALIGN_MIDDLE | NK_TEXT_ALIGN_CENTERED, - NK_TEXT_RIGHT = NK_TEXT_ALIGN_MIDDLE | NK_TEXT_ALIGN_RIGHT -}; -NK_API void -nk_text(struct nk_context *, const char *, int, nk_flags); -NK_API void -nk_text_colored(struct nk_context *, const char *, int, nk_flags, struct nk_color); -NK_API void -nk_text_wrap(struct nk_context *, const char *, int); -NK_API void -nk_text_wrap_colored(struct nk_context *, const char *, int, struct nk_color); -NK_API void -nk_label(struct nk_context *, const char *, nk_flags align); -NK_API void -nk_label_colored(struct nk_context *, const char *, nk_flags align, struct nk_color); -NK_API void -nk_label_wrap(struct nk_context *, const char *); -NK_API void -nk_label_colored_wrap(struct nk_context *, const char *, struct nk_color); - -struct nk_text_selection { - int anchor; - int cursor; - unsigned char active; - unsigned char dragging; - unsigned char affinity; - unsigned char anchor_affinity; -}; - -struct nk_text_selection_context { - struct nk_text_selection selection; - unsigned int anchor_widget; - unsigned int cursor_widget; - unsigned int widget_index; - unsigned int widget_count; - unsigned int frame; - unsigned int keyboard_frame; - nk_size copy_first; - nk_size copy_last; - int copy_length; - struct nk_rect copy_bounds; -}; - -enum nk_text_option_flags { - NK_TEXT_OPTION_WRAP = NK_FLAG(0), - NK_TEXT_OPTION_SELECTABLE = NK_FLAG(1), - /* Starts a one-column dynamic row sized to all wrapped lines. */ - NK_TEXT_OPTION_AUTO_HEIGHT = NK_FLAG(2) -}; - -/* Set selection to NULL to use the current panel's selection context. */ -struct nk_text_options { - nk_flags alignment; - nk_flags flags; - struct nk_color color; - struct nk_text_selection_context *selection; -}; - -NK_API nk_bool -nk_text_ex(struct nk_context *, const char *, int, const struct nk_text_options *); - -#ifndef NK_GRID_MAX_COLUMNS -# define NK_GRID_MAX_COLUMNS 16 -#endif - -enum nk_grid_column_sizing { - NK_GRID_COLUMN_FIXED, - NK_GRID_COLUMN_CONTENT, - NK_GRID_COLUMN_FLEX -}; - -struct nk_grid_column { - enum nk_grid_column_sizing sizing; - float width; - float min_width; - float max_width; -}; - -struct nk_grid_options { - float row_height; - float column_gap; - float padding_x; - nk_uint generation; /* change this to discard widths collected for an older data set or configuration */ -}; - -/* Content widths only grow from visible cells and are reused by later frames */ -struct nk_grid_state { - const struct nk_user_font *font; - float font_size; - nk_uint generation; - int column_count; - float content_widths[NK_GRID_MAX_COLUMNS]; -}; - -struct nk_grid { - struct nk_context *ctx; - struct nk_grid_state *state; - const struct nk_grid_column *columns; - int column_count; - float row_height; - float column_gap; - float padding_x; - float available_width; - float row_width; - float widths[NK_GRID_MAX_COLUMNS]; - float offsets[NK_GRID_MAX_COLUMNS]; - nk_bool row_active; - nk_bool row_visible; -}; - -NK_API void -nk_grid_state_reset(struct nk_grid_state *); -NK_API void -nk_grid_begin(struct nk_context *, struct nk_grid *, struct nk_grid_state *, const struct nk_grid_column *, int, - const struct nk_grid_options *); -NK_API void -nk_grid_end(struct nk_grid *); -NK_API nk_bool -nk_grid_row_begin(struct nk_grid *); -NK_API void -nk_grid_row_end(struct nk_grid *); -NK_API void -nk_grid_push_row(struct nk_grid *); -NK_API struct nk_rect -nk_grid_cell_bounds(struct nk_grid *, int column, struct nk_vec2 intrinsic_size); -NK_API void -nk_grid_push(struct nk_grid *, int column, struct nk_vec2 intrinsic_size); -NK_API nk_bool -nk_grid_text(struct nk_grid *, int column, const char *, int, const struct nk_text_options *); - -NK_API nk_bool -nk_text_selectable(struct nk_context *, const char *, int, nk_flags align); -NK_API nk_bool -nk_text_selectable_colored(struct nk_context *, const char *, int, nk_flags align, struct nk_color); -NK_API nk_bool -nk_text_selectable_ctx(struct nk_context *, const char *, int, nk_flags align, struct nk_text_selection_context *selection); -NK_API nk_bool -nk_text_selectable_colored_ctx(struct nk_context *, const char *, int, nk_flags align, struct nk_color, struct nk_text_selection_context *selection); -NK_API nk_bool -nk_text_selectable_wrap(struct nk_context *, const char *, int); -NK_API nk_bool -nk_text_selectable_wrap_colored(struct nk_context *, const char *, int, struct nk_color); -NK_API nk_bool -nk_text_selectable_wrap_ctx(struct nk_context *, const char *, int, struct nk_text_selection_context *selection); -NK_API nk_bool -nk_text_selectable_wrap_colored_ctx(struct nk_context *, const char *, int, struct nk_color, struct nk_text_selection_context *selection); - -NK_API nk_bool -nk_label_selectable(struct nk_context *, const char *, nk_flags align); -NK_API nk_bool -nk_label_selectable_colored(struct nk_context *, const char *, nk_flags align, struct nk_color); -NK_API nk_bool -nk_label_selectable_ctx(struct nk_context *, const char *, nk_flags align, struct nk_text_selection_context *selection); -NK_API nk_bool -nk_label_selectable_colored_ctx(struct nk_context *, const char *, nk_flags align, struct nk_color, struct nk_text_selection_context *selection); -NK_API nk_bool -nk_label_selectable_wrap(struct nk_context *, const char *); -NK_API nk_bool -nk_label_selectable_colored_wrap(struct nk_context *, const char *, struct nk_color); -NK_API nk_bool -nk_label_selectable_wrap_ctx(struct nk_context *, const char *, struct nk_text_selection_context *selection); -NK_API nk_bool -nk_label_selectable_colored_wrap_ctx(struct nk_context *, const char *, struct nk_color, struct nk_text_selection_context *selection); - -NK_API void -nk_image(struct nk_context *, struct nk_image); -NK_API void -nk_image_color(struct nk_context *, struct nk_image, struct nk_color); - -#ifdef NK_INCLUDE_STANDARD_VARARGS -NK_API nk_bool -nk_textf_ex(struct nk_context *, const struct nk_text_options *, NK_PRINTF_FORMAT_STRING const char *, ...) NK_PRINTF_VARARG_FUNC(3); -NK_API nk_bool -nk_textfv_ex(struct nk_context *, const struct nk_text_options *, NK_PRINTF_FORMAT_STRING const char *, va_list) NK_PRINTF_VALIST_FUNC(3); -NK_API nk_bool -nk_textf_selectable(struct nk_context *, nk_flags, NK_PRINTF_FORMAT_STRING const char *, ...) NK_PRINTF_VARARG_FUNC(3); -NK_API nk_bool -nk_textf_selectable_colored(struct nk_context *, nk_flags, struct nk_color, NK_PRINTF_FORMAT_STRING const char *, ...) NK_PRINTF_VARARG_FUNC(4); -NK_API nk_bool -nk_textf_selectable_ctx(struct nk_context *, nk_flags, struct nk_text_selection_context *, NK_PRINTF_FORMAT_STRING const char *, ...) NK_PRINTF_VARARG_FUNC(4); -NK_API nk_bool -nk_textf_selectable_colored_ctx(struct nk_context *, nk_flags, struct nk_color, struct nk_text_selection_context *, NK_PRINTF_FORMAT_STRING const char *, ...) NK_PRINTF_VARARG_FUNC(5); -NK_API nk_bool -nk_textfv_selectable(struct nk_context *, nk_flags, NK_PRINTF_FORMAT_STRING const char *, va_list) NK_PRINTF_VALIST_FUNC(3); -NK_API nk_bool -nk_textfv_selectable_colored(struct nk_context *, nk_flags, struct nk_color, NK_PRINTF_FORMAT_STRING const char *, va_list) NK_PRINTF_VALIST_FUNC(4); -NK_API nk_bool -nk_textfv_selectable_ctx(struct nk_context *, nk_flags, struct nk_text_selection_context *, NK_PRINTF_FORMAT_STRING const char *, va_list) NK_PRINTF_VALIST_FUNC(4); -NK_API nk_bool -nk_textfv_selectable_colored_ctx(struct nk_context *, nk_flags, struct nk_color, struct nk_text_selection_context *, NK_PRINTF_FORMAT_STRING const char *, va_list) NK_PRINTF_VALIST_FUNC(5); -NK_API nk_bool -nk_textf_selectable_wrap(struct nk_context *, NK_PRINTF_FORMAT_STRING const char *, ...) NK_PRINTF_VARARG_FUNC(2); -NK_API nk_bool -nk_textf_selectable_wrap_colored(struct nk_context *, struct nk_color, NK_PRINTF_FORMAT_STRING const char *, ...) NK_PRINTF_VARARG_FUNC(3); -NK_API nk_bool -nk_textf_selectable_wrap_ctx(struct nk_context *, struct nk_text_selection_context *, NK_PRINTF_FORMAT_STRING const char *, ...) NK_PRINTF_VARARG_FUNC(3); -NK_API nk_bool -nk_textf_selectable_wrap_colored_ctx(struct nk_context *, struct nk_color, struct nk_text_selection_context *, NK_PRINTF_FORMAT_STRING const char *, ...) NK_PRINTF_VARARG_FUNC(4); -NK_API nk_bool -nk_textfv_selectable_wrap(struct nk_context *, NK_PRINTF_FORMAT_STRING const char *, va_list) NK_PRINTF_VALIST_FUNC(2); -NK_API nk_bool -nk_textfv_selectable_wrap_colored(struct nk_context *, struct nk_color, NK_PRINTF_FORMAT_STRING const char *, va_list) NK_PRINTF_VALIST_FUNC(3); -NK_API nk_bool -nk_textfv_selectable_wrap_ctx(struct nk_context *, struct nk_text_selection_context *, NK_PRINTF_FORMAT_STRING const char *, va_list) NK_PRINTF_VALIST_FUNC(3); -NK_API nk_bool -nk_textfv_selectable_wrap_colored_ctx(struct nk_context *, struct nk_color, struct nk_text_selection_context *, NK_PRINTF_FORMAT_STRING const char *, va_list) NK_PRINTF_VALIST_FUNC(4); - -NK_API void -nk_labelf(struct nk_context *, nk_flags, NK_PRINTF_FORMAT_STRING const char *, ...) NK_PRINTF_VARARG_FUNC(3); -NK_API void -nk_labelf_colored(struct nk_context *, nk_flags, struct nk_color, NK_PRINTF_FORMAT_STRING const char *, ...) NK_PRINTF_VARARG_FUNC(4); -NK_API void -nk_labelf_wrap(struct nk_context *, NK_PRINTF_FORMAT_STRING const char *, ...) NK_PRINTF_VARARG_FUNC(2); -NK_API void -nk_labelf_colored_wrap(struct nk_context *, struct nk_color, NK_PRINTF_FORMAT_STRING const char *, ...) NK_PRINTF_VARARG_FUNC(3); -NK_API void -nk_labelfv(struct nk_context *, nk_flags, NK_PRINTF_FORMAT_STRING const char *, va_list) NK_PRINTF_VALIST_FUNC(3); -NK_API void -nk_labelfv_colored(struct nk_context *, nk_flags, struct nk_color, NK_PRINTF_FORMAT_STRING const char *, va_list) NK_PRINTF_VALIST_FUNC(4); -NK_API void -nk_labelfv_wrap(struct nk_context *, NK_PRINTF_FORMAT_STRING const char *, va_list) NK_PRINTF_VALIST_FUNC(2); -NK_API void -nk_labelfv_colored_wrap(struct nk_context *, struct nk_color, NK_PRINTF_FORMAT_STRING const char *, va_list) NK_PRINTF_VALIST_FUNC(3); -NK_API nk_bool -nk_labelf_selectable(struct nk_context *, nk_flags, NK_PRINTF_FORMAT_STRING const char *, ...) NK_PRINTF_VARARG_FUNC(3); -NK_API nk_bool -nk_labelf_selectable_colored(struct nk_context *, nk_flags, struct nk_color, NK_PRINTF_FORMAT_STRING const char *, ...) NK_PRINTF_VARARG_FUNC(4); -NK_API nk_bool -nk_labelf_selectable_ctx(struct nk_context *, nk_flags, struct nk_text_selection_context *, NK_PRINTF_FORMAT_STRING const char *, ...) NK_PRINTF_VARARG_FUNC(4); -NK_API nk_bool -nk_labelf_selectable_colored_ctx(struct nk_context *, nk_flags, struct nk_color, struct nk_text_selection_context *, NK_PRINTF_FORMAT_STRING const char *, ...) NK_PRINTF_VARARG_FUNC(5); -NK_API nk_bool -nk_labelfv_selectable(struct nk_context *, nk_flags, NK_PRINTF_FORMAT_STRING const char *, va_list) NK_PRINTF_VALIST_FUNC(3); -NK_API nk_bool -nk_labelfv_selectable_colored(struct nk_context *, nk_flags, struct nk_color, NK_PRINTF_FORMAT_STRING const char *, va_list) NK_PRINTF_VALIST_FUNC(4); -NK_API nk_bool -nk_labelfv_selectable_ctx(struct nk_context *, nk_flags, struct nk_text_selection_context *, NK_PRINTF_FORMAT_STRING const char *, va_list) NK_PRINTF_VALIST_FUNC(4); -NK_API nk_bool -nk_labelfv_selectable_colored_ctx(struct nk_context *, nk_flags, struct nk_color, struct nk_text_selection_context *, NK_PRINTF_FORMAT_STRING const char *, va_list) NK_PRINTF_VALIST_FUNC(5); -NK_API nk_bool -nk_labelf_selectable_wrap(struct nk_context *, NK_PRINTF_FORMAT_STRING const char *, ...) NK_PRINTF_VARARG_FUNC(2); -NK_API nk_bool -nk_labelf_selectable_colored_wrap(struct nk_context *, struct nk_color, NK_PRINTF_FORMAT_STRING const char *, ...) NK_PRINTF_VARARG_FUNC(3); -NK_API nk_bool -nk_labelf_selectable_wrap_ctx(struct nk_context *, struct nk_text_selection_context *, NK_PRINTF_FORMAT_STRING const char *, ...) NK_PRINTF_VARARG_FUNC(3); -NK_API nk_bool -nk_labelf_selectable_colored_wrap_ctx(struct nk_context *, struct nk_color, struct nk_text_selection_context *, NK_PRINTF_FORMAT_STRING const char *, ...) NK_PRINTF_VARARG_FUNC(4); -NK_API nk_bool -nk_labelfv_selectable_wrap(struct nk_context *, NK_PRINTF_FORMAT_STRING const char *, va_list) NK_PRINTF_VALIST_FUNC(2); -NK_API nk_bool -nk_labelfv_selectable_colored_wrap(struct nk_context *, struct nk_color, NK_PRINTF_FORMAT_STRING const char *, va_list) NK_PRINTF_VALIST_FUNC(3); -NK_API nk_bool -nk_labelfv_selectable_wrap_ctx(struct nk_context *, struct nk_text_selection_context *, NK_PRINTF_FORMAT_STRING const char *, va_list) NK_PRINTF_VALIST_FUNC(3); -NK_API nk_bool -nk_labelfv_selectable_colored_wrap_ctx(struct nk_context *, struct nk_color, struct nk_text_selection_context *, NK_PRINTF_FORMAT_STRING const char *, va_list) NK_PRINTF_VALIST_FUNC(4); - -NK_API void -nk_value_bool(struct nk_context *, const char *prefix, int); -NK_API void -nk_value_int(struct nk_context *, const char *prefix, int); -NK_API void -nk_value_uint(struct nk_context *, const char *prefix, unsigned int); -NK_API void -nk_value_float(struct nk_context *, const char *prefix, float); -NK_API void -nk_value_color_byte(struct nk_context *, const char *prefix, struct nk_color); -NK_API void -nk_value_color_float(struct nk_context *, const char *prefix, struct nk_color); -NK_API void -nk_value_color_hex(struct nk_context *, const char *prefix, struct nk_color); -#endif -/* ============================================================================= - * - * BUTTON - * - * ============================================================================= */ -NK_API nk_bool -nk_button_text(struct nk_context *, const char *title, int len); -NK_API nk_bool -nk_button_label(struct nk_context *, const char *title); -NK_API nk_bool -nk_button_color(struct nk_context *, struct nk_color); -NK_API nk_bool -nk_button_symbol(struct nk_context *, enum nk_symbol_type); -NK_API nk_bool -nk_button_image(struct nk_context *, struct nk_image img); -NK_API nk_bool -nk_button_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags text_alignment); -NK_API nk_bool -nk_button_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags alignment); -NK_API nk_bool -nk_button_image_label(struct nk_context *, struct nk_image img, const char *, nk_flags text_alignment); -NK_API nk_bool -nk_button_image_text(struct nk_context *, struct nk_image img, const char *, int, nk_flags alignment); -NK_API nk_bool -nk_button_text_styled(struct nk_context *, const struct nk_style_button *, const char *title, int len); -NK_API nk_bool -nk_button_label_styled(struct nk_context *, const struct nk_style_button *, const char *title); -NK_API nk_bool -nk_button_symbol_styled(struct nk_context *, const struct nk_style_button *, enum nk_symbol_type); -NK_API nk_bool -nk_button_image_styled(struct nk_context *, const struct nk_style_button *, struct nk_image img); -NK_API nk_bool -nk_button_symbol_text_styled(struct nk_context *, const struct nk_style_button *, enum nk_symbol_type, const char *, int, nk_flags alignment); -NK_API nk_bool -nk_button_symbol_label_styled(struct nk_context *ctx, const struct nk_style_button *style, enum nk_symbol_type symbol, const char *title, nk_flags align); -NK_API nk_bool -nk_button_image_label_styled(struct nk_context *, const struct nk_style_button *, struct nk_image img, const char *, nk_flags text_alignment); -NK_API nk_bool -nk_button_image_text_styled(struct nk_context *, const struct nk_style_button *, struct nk_image img, const char *, int, nk_flags alignment); -NK_API void -nk_button_set_behavior(struct nk_context *, enum nk_button_behavior); -NK_API nk_bool -nk_button_push_behavior(struct nk_context *, enum nk_button_behavior); -NK_API nk_bool -nk_button_pop_behavior(struct nk_context *); -/* ============================================================================= - * - * CHECKBOX - * - * ============================================================================= */ -NK_API nk_bool -nk_check_label(struct nk_context *, const char *, nk_bool active); -NK_API nk_bool -nk_check_text(struct nk_context *, const char *, int, nk_bool active); -NK_API nk_bool -nk_check_text_align(struct nk_context *, const char *, int, nk_bool active, nk_flags widget_alignment, nk_flags text_alignment); -NK_API unsigned -nk_check_flags_label(struct nk_context *, const char *, unsigned int flags, unsigned int value); -NK_API unsigned -nk_check_flags_text(struct nk_context *, const char *, int, unsigned int flags, unsigned int value); -NK_API nk_bool -nk_checkbox_label(struct nk_context *, const char *, nk_bool *active); -NK_API nk_bool -nk_checkbox_label_align(struct nk_context *ctx, const char *label, nk_bool *active, nk_flags widget_alignment, nk_flags text_alignment); -NK_API nk_bool -nk_checkbox_text(struct nk_context *, const char *, int, nk_bool *active); -NK_API nk_bool -nk_checkbox_text_align(struct nk_context *ctx, const char *text, int len, nk_bool *active, nk_flags widget_alignment, nk_flags text_alignment); -NK_API nk_bool -nk_checkbox_flags_label(struct nk_context *, const char *, unsigned int *flags, unsigned int value); -NK_API nk_bool -nk_checkbox_flags_text(struct nk_context *, const char *, int, unsigned int *flags, unsigned int value); -/* ============================================================================= - * - * RADIO BUTTON - * - * ============================================================================= */ -NK_API nk_bool -nk_radio_label(struct nk_context *, const char *, nk_bool *active); -NK_API nk_bool -nk_radio_label_align(struct nk_context *ctx, const char *label, nk_bool *active, nk_flags widget_alignment, nk_flags text_alignment); -NK_API nk_bool -nk_radio_text(struct nk_context *, const char *, int, nk_bool *active); -NK_API nk_bool -nk_radio_text_align(struct nk_context *ctx, const char *text, int len, nk_bool *active, nk_flags widget_alignment, nk_flags text_alignment); -NK_API nk_bool -nk_option_label(struct nk_context *, const char *, nk_bool active); -NK_API nk_bool -nk_option_label_align(struct nk_context *ctx, const char *label, nk_bool active, nk_flags widget_alignment, nk_flags text_alignment); -NK_API nk_bool -nk_option_text(struct nk_context *, const char *, int, nk_bool active); -NK_API nk_bool -nk_option_text_align(struct nk_context *ctx, const char *text, int len, nk_bool is_active, nk_flags widget_alignment, nk_flags text_alignment); -/* ============================================================================= - * - * SELECTABLE - * - * ============================================================================= */ -NK_API nk_bool -nk_selectable_label(struct nk_context *, const char *, nk_flags align, nk_bool *value); -NK_API nk_bool -nk_selectable_text(struct nk_context *, const char *, int, nk_flags align, nk_bool *value); -NK_API nk_bool -nk_selectable_image_label(struct nk_context *, struct nk_image, const char *, nk_flags align, nk_bool *value); -NK_API nk_bool -nk_selectable_image_text(struct nk_context *, struct nk_image, const char *, int, nk_flags align, nk_bool *value); -NK_API nk_bool -nk_selectable_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags align, nk_bool *value); -NK_API nk_bool -nk_selectable_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags align, nk_bool *value); - -NK_API nk_bool -nk_select_label(struct nk_context *, const char *, nk_flags align, nk_bool value); -NK_API nk_bool -nk_select_text(struct nk_context *, const char *, int, nk_flags align, nk_bool value); -NK_API nk_bool -nk_select_image_label(struct nk_context *, struct nk_image, const char *, nk_flags align, nk_bool value); -NK_API nk_bool -nk_select_image_text(struct nk_context *, struct nk_image, const char *, int, nk_flags align, nk_bool value); -NK_API nk_bool -nk_select_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags align, nk_bool value); -NK_API nk_bool -nk_select_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags align, nk_bool value); - -/* ============================================================================= - * - * SLIDER - * - * ============================================================================= */ -NK_API float -nk_slide_float(struct nk_context *, float min, float val, float max, float step); -NK_API int -nk_slide_int(struct nk_context *, int min, int val, int max, int step); -NK_API nk_bool -nk_slider_float(struct nk_context *, float min, float *val, float max, float step); -NK_API nk_bool -nk_slider_int(struct nk_context *, int min, int *val, int max, int step); - -/* ============================================================================= - * - * KNOB - * - * ============================================================================= */ -NK_API nk_bool -nk_knob_float(struct nk_context *, - float min, - float *val, - float max, - float step, - enum nk_heading zero_direction, - float dead_zone_degrees); -NK_API nk_bool -nk_knob_int( - struct nk_context *, int min, int *val, int max, int step, enum nk_heading zero_direction, float dead_zone_degrees); - -/* ============================================================================= - * - * PROGRESSBAR - * - * ============================================================================= */ -NK_API nk_bool -nk_progress(struct nk_context *, nk_size *cur, nk_size max, nk_bool modifyable); -NK_API nk_size -nk_prog(struct nk_context *, nk_size cur, nk_size max, nk_bool modifyable); - -/* ============================================================================= - * - * COLOR PICKER - * - * ============================================================================= */ -NK_API struct nk_colorf -nk_color_picker(struct nk_context *, struct nk_colorf, enum nk_color_format); -NK_API nk_bool -nk_color_pick(struct nk_context *, struct nk_colorf *, enum nk_color_format); -/* ============================================================================= - * - * PROPERTIES - * - * =============================================================================*/ -/** - * \page Properties - * Properties are the main value modification widgets in Nuklear. Changing a value - * can be achieved by dragging, adding/removing incremental steps on button click - * or by directly typing a number. - * - * # Usage - * Each property requires a unique name for identification that is also used for - * displaying a label. If you want to use the same name multiple times make sure - * add a '#' before your name. The '#' will not be shown but will generate a - * unique ID. Each property also takes in a minimum and maximum value. If you want - * to make use of the complete number range of a type just use the provided - * type limits from `limits.h`. For example `INT_MIN` and `INT_MAX` for - * `nk_property_int` and `nk_propertyi`. In additional each property takes in - * a increment value that will be added or subtracted if either the increment - * decrement button is clicked. Finally there is a value for increment per pixel - * dragged that is added or subtracted from the value. - * - * ```c - * int value = 0; - * struct nk_context ctx; - * nk_init_xxx(&ctx, ...); - * while (1) { - * // Input - * Event evt; - * nk_input_begin(&ctx); - * while (GetEvent(&evt)) { - * if (evt.type == MOUSE_MOVE) - * nk_input_motion(&ctx, evt.motion.x, evt.motion.y); - * else if (evt.type == [...]) { - * nk_input_xxx(...); - * } - * } - * nk_input_end(&ctx); - * // - * // Window - * if (nk_begin_xxx(...) { - * // Property - * nk_layout_row_dynamic(...); - * nk_property_int(ctx, "ID", INT_MIN, &value, INT_MAX, 1, 1); - * } - * nk_end(ctx); - * // - * // Draw - * const struct nk_command *cmd = 0; - * nk_foreach(cmd, &ctx) { - * switch (cmd->type) { - * case NK_COMMAND_LINE: - * your_draw_line_function(...) - * break; - * case NK_COMMAND_RECT - * your_draw_rect_function(...) - * break; - * case ...: - * // [...] - * } - * nk_clear(&ctx); - * } - * nk_free(&ctx); - * ``` - * - * # Reference - * Function | Description - * --------------------|------------------------------------------- - * \ref nk_property_int | Integer property directly modifying a passed in value - * \ref nk_property_float | Float property directly modifying a passed in value - * \ref nk_property_double | Double property directly modifying a passed in value - * \ref nk_propertyi | Integer property returning the modified int value - * \ref nk_propertyf | Float property returning the modified float value - * \ref nk_propertyd | Double property returning the modified double value - * - - * # # nk_property_int - * Integer property directly modifying a passed in value - * !!! \warning - * To generate a unique property ID using the same label make sure to insert - * a `#` at the beginning. It will not be shown but guarantees correct behavior. - * - * ```c - * nk_bool nk_property_int(struct nk_context *ctx, const char *name, int min, int *val, int max, int step, float - inc_per_pixel); - * ``` - * - * Parameter | Description - * --------------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after calling a layouting - function - * \param[in] name | String used both as a label as well as a unique identifier - * \param[in] min | Minimum value not allowed to be underflown - * \param[in] val | Integer pointer to be modified - * \param[in] max | Maximum value not allowed to be overflown - * \param[in] step | Increment added and subtracted on increment and decrement button - * \param[in] inc_per_pixel | Value per pixel added or subtracted on dragging - * - * \returns `true(1)` if the value changed - */ -NK_API nk_bool -nk_property_int(struct nk_context *, const char *name, int min, int *val, int max, int step, float inc_per_pixel); - -/** - * # # nk_property_float - * Float property directly modifying a passed in value - * !!! \warning - * To generate a unique property ID using the same label make sure to insert - * a `#` at the beginning. It will not be shown but guarantees correct behavior. - * - * ```c - * nk_bool nk_property_float(struct nk_context *ctx, const char *name, float min, float *val, float max, float step, - * float inc_per_pixel); - * ``` - * - * Parameter | Description - * --------------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after calling a layouting - * function - * \param[in] name | String used both as a label as well as a unique identifier - * \param[in] min | Minimum value not allowed to be underflown - * \param[in] val | Float pointer to be modified - * \param[in] max | Maximum value not allowed to be overflown - * \param[in] step | Increment added and subtracted on increment and decrement button - * \param[in] inc_per_pixel | Value per pixel added or subtracted on dragging - * - * \returns `true(1)` if the value changed - */ -NK_API nk_bool -nk_property_float( - struct nk_context *, const char *name, float min, float *val, float max, float step, float inc_per_pixel); - -/** - * # # nk_property_double - * Double property directly modifying a passed in value - * !!! \warning - * To generate a unique property ID using the same label make sure to insert - * a `#` at the beginning. It will not be shown but guarantees correct behavior. - * - * ```c - * nk_bool nk_property_double(struct nk_context *ctx, const char *name, double min, double *val, double max, double - * step, double inc_per_pixel); - * ``` - * - * Parameter | Description - * --------------------|----------------------------------------------------------- - * \param[in] ctx | Must point to an previously initialized `nk_context` struct after calling a layouting - * function - * \param[in] name | String used both as a label as well as a unique identifier - * \param[in] min | Minimum value not allowed to be underflown - * \param[in] val | Double pointer to be modified - * \param[in] max | Maximum value not allowed to be overflown - * \param[in] step | Increment added and subtracted on increment and decrement button - * \param[in] inc_per_pixel | Value per pixel added or subtracted on dragging - * - * \returns `true(1)` if the value changed - */ -NK_API nk_bool -nk_property_double( - struct nk_context *, const char *name, double min, double *val, double max, double step, float inc_per_pixel); - -/** - * # # nk_propertyi - * Integer property modifying a passed in value and returning the new value - * !!! \warning - * To generate a unique property ID using the same label make sure to insert - * a `#` at the beginning. It will not be shown but guarantees correct behavior. - * - * ```c - * int nk_propertyi(struct nk_context *ctx, const char *name, int min, int val, int max, int step, float inc_per_pixel); - * ``` - * - * \param[in] ctx Must point to an previously initialized `nk_context` struct after calling a layouting - * function - * \param[in] name String used both as a label as well as a unique identifier - * \param[in] min Minimum value not allowed to be underflown - * \param[in] val Current integer value to be modified and returned - * \param[in] max Maximum value not allowed to be overflown - * \param[in] step Increment added and subtracted on increment and decrement button - * \param[in] inc_per_pixel Value per pixel added or subtracted on dragging - * - * \returns the new modified integer value - */ -NK_API int -nk_propertyi(struct nk_context *, const char *name, int min, int val, int max, int step, float inc_per_pixel); - -/** - * # # nk_propertyf - * Float property modifying a passed in value and returning the new value - * !!! \warning - * To generate a unique property ID using the same label make sure to insert - * a `#` at the beginning. It will not be shown but guarantees correct behavior. - * - * ```c - * float nk_propertyf(struct nk_context *ctx, const char *name, float min, float val, float max, float step, float - * inc_per_pixel); - * ``` - * - * \param[in] ctx Must point to an previously initialized `nk_context` struct after calling a layouting - * function - * \param[in] name String used both as a label as well as a unique identifier - * \param[in] min Minimum value not allowed to be underflown - * \param[in] val Current float value to be modified and returned - * \param[in] max Maximum value not allowed to be overflown - * \param[in] step Increment added and subtracted on increment and decrement button - * \param[in] inc_per_pixel Value per pixel added or subtracted on dragging - * - * \returns the new modified float value - */ -NK_API float -nk_propertyf(struct nk_context *, const char *name, float min, float val, float max, float step, float inc_per_pixel); - -/** - * # # nk_propertyd - * Float property modifying a passed in value and returning the new value - * !!! \warning - * To generate a unique property ID using the same label make sure to insert - * a `#` at the beginning. It will not be shown but guarantees correct behavior. - * - * ```c - * float nk_propertyd(struct nk_context *ctx, const char *name, double min, double val, double max, double step, double - * inc_per_pixel); - * ``` - * - * \param[in] ctx Must point to an previously initialized `nk_context` struct after calling a layouting - * function - * \param[in] name String used both as a label as well as a unique identifier - * \param[in] min Minimum value not allowed to be underflown - * \param[in] val Current double value to be modified and returned - * \param[in] max Maximum value not allowed to be overflown - * \param[in] step Increment added and subtracted on increment and decrement button - * \param[in] inc_per_pixel Value per pixel added or subtracted on dragging - * - * \returns the new modified double value - */ -NK_API double -nk_propertyd( - struct nk_context *, const char *name, double min, double val, double max, double step, float inc_per_pixel); - -/* ============================================================================= - * - * TEXT EDIT - * - * ============================================================================= */ -enum nk_edit_flags { - NK_EDIT_DEFAULT = 0, - NK_EDIT_READ_ONLY = NK_FLAG(0), - NK_EDIT_AUTO_SELECT = NK_FLAG(1), - NK_EDIT_SIG_ENTER = NK_FLAG(2), - NK_EDIT_ALLOW_TAB = NK_FLAG(3), - NK_EDIT_NO_CURSOR = NK_FLAG(4), - NK_EDIT_SELECTABLE = NK_FLAG(5), - NK_EDIT_CLIPBOARD = NK_FLAG(6), - NK_EDIT_CTRL_ENTER_NEWLINE = NK_FLAG(7), - NK_EDIT_NO_HORIZONTAL_SCROLL = NK_FLAG(8), - NK_EDIT_ALWAYS_INSERT_MODE = NK_FLAG(9), - NK_EDIT_MULTILINE = NK_FLAG(10), - NK_EDIT_GOTO_END_ON_ACTIVATE = NK_FLAG(11) -}; -enum nk_edit_types { - NK_EDIT_SIMPLE = NK_EDIT_ALWAYS_INSERT_MODE, - NK_EDIT_FIELD = NK_EDIT_ALWAYS_INSERT_MODE | NK_EDIT_SELECTABLE | NK_EDIT_CLIPBOARD, - NK_EDIT_BOX = NK_EDIT_ALWAYS_INSERT_MODE | NK_EDIT_SELECTABLE | NK_EDIT_MULTILINE | NK_EDIT_ALLOW_TAB | NK_EDIT_CLIPBOARD, - NK_EDIT_EDITOR = NK_EDIT_SELECTABLE | NK_EDIT_MULTILINE | NK_EDIT_ALLOW_TAB | NK_EDIT_CLIPBOARD -}; -enum nk_edit_events { - NK_EDIT_ACTIVE = NK_FLAG(0), /**!< edit widget is currently being modified */ - NK_EDIT_INACTIVE = NK_FLAG(1), /**!< edit widget is not active and is not being modified */ - NK_EDIT_ACTIVATED = NK_FLAG(2), /**!< edit widget went from state inactive to state active */ - NK_EDIT_DEACTIVATED = NK_FLAG(3), /**!< edit widget went from state active to state inactive */ - NK_EDIT_COMMITED = NK_FLAG(4) /**!< edit widget has received an enter and lost focus */ -}; -NK_API nk_flags -nk_edit_string(struct nk_context *, nk_flags, char *buffer, int *len, int max, nk_plugin_filter); -NK_API nk_flags -nk_edit_string_zero_terminated(struct nk_context *, nk_flags, char *buffer, int max, nk_plugin_filter); -NK_API nk_flags -nk_edit_buffer(struct nk_context *, nk_flags, struct nk_text_edit *, nk_plugin_filter); -NK_API void -nk_edit_focus(struct nk_context *, nk_flags flags); -NK_API void -nk_edit_unfocus(struct nk_context *); -/* ============================================================================= - * - * CHART - * - * ============================================================================= */ -NK_API nk_bool -nk_chart_begin(struct nk_context *, enum nk_chart_type, int num, float min, float max); -NK_API nk_bool -nk_chart_begin_colored( - struct nk_context *, enum nk_chart_type, struct nk_color, struct nk_color active, int num, float min, float max); -NK_API void -nk_chart_add_slot(struct nk_context *ctx, const enum nk_chart_type, int count, float min_value, float max_value); -NK_API void -nk_chart_add_slot_colored(struct nk_context *ctx, - const enum nk_chart_type, - struct nk_color, - struct nk_color active, - int count, - float min_value, - float max_value); -NK_API nk_flags -nk_chart_push(struct nk_context *, float); -NK_API nk_flags -nk_chart_push_slot(struct nk_context *, float, int); -NK_API void -nk_chart_end(struct nk_context *); -NK_API void -nk_plot(struct nk_context *, enum nk_chart_type, const float *values, int count, int offset); -NK_API void -nk_plot_function(struct nk_context *, - enum nk_chart_type, - void *userdata, - float (*value_getter)(void *user, int index), - int count, - int offset); -/* ============================================================================= - * - * POPUP - * - * ============================================================================= */ -NK_API nk_bool -nk_popup_begin(struct nk_context *, enum nk_popup_type, const char *, nk_flags, struct nk_rect bounds); -NK_API void -nk_popup_close(struct nk_context *); -NK_API void -nk_popup_end(struct nk_context *); -NK_API void -nk_popup_get_scroll(const struct nk_context *, nk_uint *offset_x, nk_uint *offset_y); -NK_API void -nk_popup_set_scroll(struct nk_context *, nk_uint offset_x, nk_uint offset_y); -/* ============================================================================= - * - * COMBOBOX - * - * ============================================================================= */ -NK_API int -nk_combo(struct nk_context *, const char *const *items, int count, int selected, int item_height, struct nk_vec2 size); -NK_API int -nk_combo_separator(struct nk_context *, - const char *items_separated_by_separator, - int separator, - int selected, - int count, - int item_height, - struct nk_vec2 size); -NK_API int -nk_combo_string(struct nk_context *, - const char *items_separated_by_zeros, - int selected, - int count, - int item_height, - struct nk_vec2 size); -NK_API int -nk_combo_callback(struct nk_context *, - void (*item_getter)(void *, int, const char **), - void *userdata, - int selected, - int count, - int item_height, - struct nk_vec2 size); -NK_API nk_bool -nk_combobox( - struct nk_context *, const char *const *items, int count, int *selected, int item_height, struct nk_vec2 size); -NK_API nk_bool -nk_combobox_string(struct nk_context *, - const char *items_separated_by_zeros, - int *selected, - int count, - int item_height, - struct nk_vec2 size); -NK_API nk_bool -nk_combobox_separator(struct nk_context *, - const char *items_separated_by_separator, - int separator, - int *selected, - int count, - int item_height, - struct nk_vec2 size); -NK_API nk_bool -nk_combobox_callback(struct nk_context *, - void (*item_getter)(void *, int, const char **), - void *, - int *selected, - int count, - int item_height, - struct nk_vec2 size); -/* ============================================================================= - * - * ABSTRACT COMBOBOX - * - * ============================================================================= */ -NK_API nk_bool -nk_combo_begin_text(struct nk_context *, const char *selected, int, struct nk_vec2 size); -NK_API nk_bool -nk_combo_begin_label(struct nk_context *, const char *selected, struct nk_vec2 size); -NK_API nk_bool -nk_combo_begin_color(struct nk_context *, struct nk_color color, struct nk_vec2 size); -NK_API nk_bool -nk_combo_begin_symbol(struct nk_context *, enum nk_symbol_type, struct nk_vec2 size); -NK_API nk_bool -nk_combo_begin_symbol_label(struct nk_context *, const char *selected, enum nk_symbol_type, struct nk_vec2 size); -NK_API nk_bool -nk_combo_begin_symbol_text(struct nk_context *, const char *selected, int, enum nk_symbol_type, struct nk_vec2 size); -NK_API nk_bool -nk_combo_begin_image(struct nk_context *, struct nk_image img, struct nk_vec2 size); -NK_API nk_bool -nk_combo_begin_image_label(struct nk_context *, const char *selected, struct nk_image, struct nk_vec2 size); -NK_API nk_bool -nk_combo_begin_image_text(struct nk_context *, const char *selected, int, struct nk_image, struct nk_vec2 size); -NK_API nk_bool -nk_combo_item_label(struct nk_context *, const char *, nk_flags alignment); -NK_API nk_bool -nk_combo_item_text(struct nk_context *, const char *, int, nk_flags alignment); -NK_API nk_bool -nk_combo_item_image_label(struct nk_context *, struct nk_image, const char *, nk_flags alignment); -NK_API nk_bool -nk_combo_item_image_text(struct nk_context *, struct nk_image, const char *, int, nk_flags alignment); -NK_API nk_bool -nk_combo_item_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags alignment); -NK_API nk_bool -nk_combo_item_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags alignment); -NK_API void -nk_combo_close(struct nk_context *); -NK_API void -nk_combo_end(struct nk_context *); -/* ============================================================================= - * - * CONTEXTUAL - * - * ============================================================================= */ -NK_API nk_bool -nk_contextual_begin(struct nk_context *, nk_flags, struct nk_vec2, struct nk_rect trigger_bounds); -NK_API nk_bool -nk_contextual_item_text(struct nk_context *, const char *, int, nk_flags align); -NK_API nk_bool -nk_contextual_item_label(struct nk_context *, const char *, nk_flags align); -NK_API nk_bool -nk_contextual_item_image_label(struct nk_context *, struct nk_image, const char *, nk_flags alignment); -NK_API nk_bool -nk_contextual_item_image_text(struct nk_context *, struct nk_image, const char *, int len, nk_flags alignment); -NK_API nk_bool -nk_contextual_item_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags alignment); -NK_API nk_bool -nk_contextual_item_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags alignment); -NK_API void -nk_contextual_close(struct nk_context *); -NK_API void -nk_contextual_end(struct nk_context *); -/* ============================================================================= - * - * TOOLTIP - * - * ============================================================================= */ -NK_API void -nk_tooltip(struct nk_context *, const char *); -NK_API void -nk_tooltip_offset(struct nk_context *ctx, const char *text, enum nk_tooltip_pos position, struct nk_vec2 offset); -NK_API void -nk_tooltip_text(struct nk_context *, const char *, int); -NK_API void -nk_tooltip_text_offset( - struct nk_context *ctx, const char *text, int len, enum nk_tooltip_pos position, struct nk_vec2 offset); -#ifdef NK_INCLUDE_STANDARD_VARARGS -NK_API void -nk_tooltipf(struct nk_context *, NK_PRINTF_FORMAT_STRING const char *, ...) NK_PRINTF_VARARG_FUNC(2); -NK_API void -nk_tooltipfv(struct nk_context *, NK_PRINTF_FORMAT_STRING const char *, va_list) NK_PRINTF_VALIST_FUNC(2); -NK_API void -nk_tooltipf_offset(struct nk_context *, enum nk_tooltip_pos, struct nk_vec2, NK_PRINTF_FORMAT_STRING const char *, ...) - NK_PRINTF_VARARG_FUNC(4); -NK_API void -nk_tooltipfv_offset( - struct nk_context *, enum nk_tooltip_pos, struct nk_vec2, NK_PRINTF_FORMAT_STRING const char *, va_list) - NK_PRINTF_VALIST_FUNC(4); -#endif -NK_API nk_bool -nk_tooltip_begin(struct nk_context *, float width); -NK_API nk_bool -nk_tooltip_begin_offset(struct nk_context *, float, enum nk_tooltip_pos, struct nk_vec2); -NK_API void -nk_tooltip_end(struct nk_context *); -/* ============================================================================= - * - * MENU - * - * ============================================================================= */ -NK_API void -nk_menubar_begin(struct nk_context *); -NK_API void -nk_menubar_end(struct nk_context *); -NK_API nk_bool -nk_menu_begin_text(struct nk_context *, const char *title, int title_len, nk_flags align, struct nk_vec2 size); -NK_API nk_bool -nk_menu_begin_label(struct nk_context *, const char *, nk_flags align, struct nk_vec2 size); -NK_API nk_bool -nk_menu_begin_image(struct nk_context *, const char *, struct nk_image, struct nk_vec2 size); -NK_API nk_bool -nk_menu_begin_image_text(struct nk_context *, const char *, int, nk_flags align, struct nk_image, struct nk_vec2 size); -NK_API nk_bool -nk_menu_begin_image_label(struct nk_context *, const char *, nk_flags align, struct nk_image, struct nk_vec2 size); -NK_API nk_bool -nk_menu_begin_symbol(struct nk_context *, const char *, enum nk_symbol_type, struct nk_vec2 size); -NK_API nk_bool -nk_menu_begin_symbol_text( - struct nk_context *, const char *, int, nk_flags align, enum nk_symbol_type, struct nk_vec2 size); -NK_API nk_bool -nk_menu_begin_symbol_label(struct nk_context *, const char *, nk_flags align, enum nk_symbol_type, struct nk_vec2 size); -NK_API nk_bool -nk_menu_item_text(struct nk_context *, const char *, int, nk_flags align); -NK_API nk_bool -nk_menu_item_label(struct nk_context *, const char *, nk_flags alignment); -NK_API nk_bool -nk_menu_item_image_label(struct nk_context *, struct nk_image, const char *, nk_flags alignment); -NK_API nk_bool -nk_menu_item_image_text(struct nk_context *, struct nk_image, const char *, int len, nk_flags alignment); -NK_API nk_bool -nk_menu_item_symbol_text(struct nk_context *, enum nk_symbol_type, const char *, int, nk_flags alignment); -NK_API nk_bool -nk_menu_item_symbol_label(struct nk_context *, enum nk_symbol_type, const char *, nk_flags alignment); -NK_API void -nk_menu_close(struct nk_context *); -NK_API void -nk_menu_end(struct nk_context *); -/* ============================================================================= - * - * STYLE - * - * ============================================================================= */ - -#define NK_WIDGET_DISABLED_FACTOR 0.5f - -enum nk_style_colors { - NK_COLOR_TEXT, - NK_COLOR_WINDOW, - NK_COLOR_HEADER, - NK_COLOR_BORDER, - NK_COLOR_BUTTON, - NK_COLOR_BUTTON_HOVER, - NK_COLOR_BUTTON_ACTIVE, - NK_COLOR_TOGGLE, - NK_COLOR_TOGGLE_HOVER, - NK_COLOR_TOGGLE_CURSOR, - NK_COLOR_SELECT, - NK_COLOR_SELECT_ACTIVE, - NK_COLOR_SLIDER, - NK_COLOR_SLIDER_CURSOR, - NK_COLOR_SLIDER_CURSOR_HOVER, - NK_COLOR_SLIDER_CURSOR_ACTIVE, - NK_COLOR_PROPERTY, - NK_COLOR_EDIT, - NK_COLOR_EDIT_CURSOR, - NK_COLOR_COMBO, - NK_COLOR_CHART, - NK_COLOR_CHART_COLOR, - NK_COLOR_CHART_COLOR_HIGHLIGHT, - NK_COLOR_SCROLLBAR, - NK_COLOR_SCROLLBAR_CURSOR, - NK_COLOR_SCROLLBAR_CURSOR_HOVER, - NK_COLOR_SCROLLBAR_CURSOR_ACTIVE, - NK_COLOR_TAB_HEADER, - NK_COLOR_KNOB, - NK_COLOR_KNOB_CURSOR, - NK_COLOR_KNOB_CURSOR_HOVER, - NK_COLOR_KNOB_CURSOR_ACTIVE, - NK_COLOR_COUNT -}; - -enum nk_style_cursor { - NK_CURSOR_ARROW, - NK_CURSOR_TEXT, - NK_CURSOR_MOVE, - NK_CURSOR_RESIZE_VERTICAL, - NK_CURSOR_RESIZE_HORIZONTAL, - NK_CURSOR_RESIZE_TOP_LEFT_DOWN_RIGHT, - NK_CURSOR_RESIZE_TOP_RIGHT_DOWN_LEFT, - NK_CURSOR_COUNT -}; - -NK_API const struct nk_color nk_default_color_style[NK_COLOR_COUNT]; -NK_API const char *nk_color_names[NK_COLOR_COUNT]; - -NK_API void -nk_style_default(struct nk_context *); -NK_API void -nk_style_from_table(struct nk_context *, const struct nk_color *); -NK_API void -nk_style_load_cursor(struct nk_context *, enum nk_style_cursor, const struct nk_cursor *); -NK_API void -nk_style_load_all_cursors(struct nk_context *, const struct nk_cursor *); -NK_API const char *nk_style_get_color_by_name(enum nk_style_colors); -/** Sets the default face and resets font_size to font->height. */ -NK_API void -nk_style_set_font(struct nk_context *, const struct nk_user_font *); -NK_API void -nk_style_set_font_size(struct nk_context *, float); -NK_API nk_bool -nk_style_set_cursor(struct nk_context *, enum nk_style_cursor); -NK_API void -nk_style_show_cursor(struct nk_context *); -NK_API void -nk_style_hide_cursor(struct nk_context *); - -/** Temporarily switches faces without changing font_size. */ -NK_API nk_bool -nk_style_push_font(struct nk_context *, const struct nk_user_font *); -NK_API nk_bool -nk_style_push_font_size(struct nk_context *, float); -NK_API nk_bool -nk_style_push_float(struct nk_context *, float *, float); -NK_API nk_bool -nk_style_push_vec2(struct nk_context *, struct nk_vec2 *, struct nk_vec2); -NK_API nk_bool -nk_style_push_style_item(struct nk_context *, struct nk_style_item *, struct nk_style_item); -NK_API nk_bool -nk_style_push_flags(struct nk_context *, nk_flags *, nk_flags); -NK_API nk_bool -nk_style_push_color(struct nk_context *, struct nk_color *, struct nk_color); - -NK_API nk_bool -nk_style_pop_font(struct nk_context *); -NK_API nk_bool -nk_style_pop_font_size(struct nk_context *); -NK_API nk_bool -nk_style_pop_float(struct nk_context *); -NK_API nk_bool -nk_style_pop_vec2(struct nk_context *); -NK_API nk_bool -nk_style_pop_style_item(struct nk_context *); -NK_API nk_bool -nk_style_pop_flags(struct nk_context *); -NK_API nk_bool -nk_style_pop_color(struct nk_context *); -/* ============================================================================= - * - * COLOR - * - * ============================================================================= */ -NK_API struct nk_color -nk_rgb(int r, int g, int b); -NK_API struct nk_color -nk_rgb_iv(const int *rgb); -NK_API struct nk_color -nk_rgb_bv(const nk_byte *rgb); -NK_API struct nk_color -nk_rgb_f(float r, float g, float b); -NK_API struct nk_color -nk_rgb_fv(const float *rgb); -NK_API struct nk_color -nk_rgb_cf(struct nk_colorf c); -NK_API struct nk_color -nk_rgb_hex(const char *rgb); -NK_API struct nk_color -nk_rgb_factor(struct nk_color col, float factor); - -NK_API struct nk_color -nk_rgba(int r, int g, int b, int a); -NK_API struct nk_color -nk_rgba_u32(nk_uint v); -NK_API struct nk_color -nk_rgba_iv(const int *rgba); -NK_API struct nk_color -nk_rgba_bv(const nk_byte *rgba); -NK_API struct nk_color -nk_rgba_f(float r, float g, float b, float a); -NK_API struct nk_color -nk_rgba_fv(const float *rgba); -NK_API struct nk_color -nk_rgba_cf(struct nk_colorf c); -NK_API struct nk_color -nk_rgba_hex(const char *rgb); - -NK_API struct nk_colorf -nk_hsva_colorf(float h, float s, float v, float a); -NK_API struct nk_colorf -nk_hsva_colorfv(const float *c); -NK_API void -nk_colorf_hsva_f(float *out_h, float *out_s, float *out_v, float *out_a, struct nk_colorf in); -NK_API void -nk_colorf_hsva_fv(float *hsva, struct nk_colorf in); - -NK_API struct nk_color -nk_hsv(int h, int s, int v); -NK_API struct nk_color -nk_hsv_iv(const int *hsv); -NK_API struct nk_color -nk_hsv_bv(const nk_byte *hsv); -NK_API struct nk_color -nk_hsv_f(float h, float s, float v); -NK_API struct nk_color -nk_hsv_fv(const float *hsv); - -NK_API struct nk_color -nk_hsva(int h, int s, int v, int a); -NK_API struct nk_color -nk_hsva_iv(const int *hsva); -NK_API struct nk_color -nk_hsva_bv(const nk_byte *hsva); -NK_API struct nk_color -nk_hsva_f(float h, float s, float v, float a); -NK_API struct nk_color -nk_hsva_fv(const float *hsva); - -/* color (conversion nuklear --> user) */ -NK_API void -nk_color_f(float *r, float *g, float *b, float *a, struct nk_color); -NK_API void -nk_color_fv(float *rgba_out, struct nk_color); -NK_API struct nk_colorf nk_color_cf(struct nk_color); -NK_API void -nk_color_d(double *r, double *g, double *b, double *a, struct nk_color); -NK_API void -nk_color_dv(double *rgba_out, struct nk_color); - -NK_API nk_uint nk_color_u32(struct nk_color); -NK_API void -nk_color_hex_rgba(char *output, struct nk_color); -NK_API void -nk_color_hex_rgb(char *output, struct nk_color); - -NK_API void -nk_color_hsv_i(int *out_h, int *out_s, int *out_v, struct nk_color); -NK_API void -nk_color_hsv_b(nk_byte *out_h, nk_byte *out_s, nk_byte *out_v, struct nk_color); -NK_API void -nk_color_hsv_iv(int *hsv_out, struct nk_color); -NK_API void -nk_color_hsv_bv(nk_byte *hsv_out, struct nk_color); -NK_API void -nk_color_hsv_f(float *out_h, float *out_s, float *out_v, struct nk_color); -NK_API void -nk_color_hsv_fv(float *hsv_out, struct nk_color); - -NK_API void -nk_color_hsva_i(int *h, int *s, int *v, int *a, struct nk_color); -NK_API void -nk_color_hsva_b(nk_byte *h, nk_byte *s, nk_byte *v, nk_byte *a, struct nk_color); -NK_API void -nk_color_hsva_iv(int *hsva_out, struct nk_color); -NK_API void -nk_color_hsva_bv(nk_byte *hsva_out, struct nk_color); -NK_API void -nk_color_hsva_f(float *out_h, float *out_s, float *out_v, float *out_a, struct nk_color); -NK_API void -nk_color_hsva_fv(float *hsva_out, struct nk_color); -/* ============================================================================= - * - * IMAGE - * - * ============================================================================= */ -NK_API nk_handle -nk_handle_ptr(void *); -NK_API nk_handle -nk_handle_id(int); -NK_API struct nk_image nk_image_handle(nk_handle); -NK_API struct nk_image -nk_image_ptr(void *); -NK_API struct nk_image -nk_image_id(int); -NK_API nk_bool -nk_image_is_subimage(const struct nk_image *img); -NK_API struct nk_image -nk_subimage_ptr(void *, nk_ushort w, nk_ushort h, struct nk_rect sub_region); -NK_API struct nk_image -nk_subimage_id(int, nk_ushort w, nk_ushort h, struct nk_rect sub_region); -NK_API struct nk_image -nk_subimage_handle(nk_handle, nk_ushort w, nk_ushort h, struct nk_rect sub_region); -/* ============================================================================= - * - * 9-SLICE - * - * ============================================================================= */ -NK_API struct nk_nine_slice -nk_nine_slice_handle(nk_handle, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b); -NK_API struct nk_nine_slice -nk_nine_slice_ptr(void *, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b); -NK_API struct nk_nine_slice -nk_nine_slice_id(int, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b); -NK_API int -nk_nine_slice_is_sub9slice(const struct nk_nine_slice *img); -NK_API struct nk_nine_slice -nk_sub9slice_ptr( - void *, nk_ushort w, nk_ushort h, struct nk_rect sub_region, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b); -NK_API struct nk_nine_slice -nk_sub9slice_id( - int, nk_ushort w, nk_ushort h, struct nk_rect sub_region, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b); -NK_API struct nk_nine_slice -nk_sub9slice_handle( - nk_handle, nk_ushort w, nk_ushort h, struct nk_rect sub_region, nk_ushort l, nk_ushort t, nk_ushort r, nk_ushort b); -/* ============================================================================= - * - * MATH - * - * ============================================================================= */ -NK_API nk_hash -nk_murmur_hash(const void *key, int len, nk_hash seed); -NK_API void -nk_triangle_from_direction(struct nk_vec2 *result, struct nk_rect r, float pad_x, float pad_y, enum nk_heading); - -NK_API struct nk_vec2 -nk_vec2(float x, float y); -NK_API struct nk_vec2 -nk_vec2i(int x, int y); -NK_API struct nk_vec2 -nk_vec2v(const float *xy); -NK_API struct nk_vec2 -nk_vec2iv(const int *xy); - -NK_API struct nk_rect -nk_get_null_rect(void); -NK_API struct nk_rect -nk_rect(float x, float y, float w, float h); -NK_API struct nk_rect -nk_recti(int x, int y, int w, int h); -NK_API struct nk_rect -nk_recta(struct nk_vec2 pos, struct nk_vec2 size); -NK_API struct nk_rect -nk_rectv(const float *xywh); -NK_API struct nk_rect -nk_rectiv(const int *xywh); -NK_API struct nk_vec2 nk_rect_pos(struct nk_rect); -NK_API struct nk_vec2 nk_rect_size(struct nk_rect); -/* ============================================================================= - * - * STRING - * - * ============================================================================= */ -NK_API int -nk_strlen(const char *str); -NK_API int -nk_stricmp(const char *s1, const char *s2); -NK_API int -nk_stricmpn(const char *s1, const char *s2, int n); -NK_API int -nk_strtoi(const char *str, char **endptr); -NK_API float -nk_strtof(const char *str, char **endptr); -#ifndef NK_STRTOD -# define NK_STRTOD nk_strtod -# define NK_STRTOD_NEEDED -NK_API double -nk_strtod(const char *str, char **endptr); -#endif -NK_API int -nk_strfilter(const char *text, const char *regexp); -NK_API int -nk_strmatch_fuzzy_string(char const *str, char const *pattern, int *out_score); -NK_API int -nk_strmatch_fuzzy_text(const char *txt, int txt_len, const char *pattern, int *out_score); -/* ============================================================================= - * - * UTF-8 - * - * ============================================================================= */ -NK_API int -nk_utf_decode(const char *, nk_rune *, int); -NK_API int -nk_utf_encode(nk_rune, char *, int); -NK_API int -nk_utf_len(const char *, int byte_len); -NK_API const char * -nk_utf_at(const char *buffer, int length, int index, nk_rune *unicode, int *len); -/* =============================================================== - * - * FONT - * - * ===============================================================*/ -/** - * \page Font - * - * Text measurement and drawing always go through the configured shaping backend. - * A font identifies one face and provides glyph images by font-specific glyph ID. - * `height` is the face's default UI size; `nk_style_push_font_size` can override it. - * - * Nuklear's optional font atlas remains available as a raster atlas builder. Shaping - * is independent of it, so another rasterizer or atlas implementation may be used. - */ -struct nk_user_font_glyph; -typedef nk_uint nk_glyph_id; -typedef void (*nk_query_font_glyph_id_f)( - nk_handle handle, float font_height, struct nk_user_font_glyph *glyph, nk_glyph_id glyph_id); - -#if defined(NK_INCLUDE_VERTEX_BUFFER_OUTPUT) || defined(NK_INCLUDE_SOFTWARE_FONT) -struct nk_user_font_glyph { - struct nk_vec2 uv[2]; /**!< texture coordinates */ - struct nk_vec2 offset; /**!< bitmap top-left relative to the glyph origin and shared text baseline */ - float width, height; /**!< size of the glyph */ - float xadvance; /**!< offset to the next glyph */ -}; -#endif - -struct nk_user_font { - nk_handle userdata; /**!< user provided font handle */ - float height; /**!< default font size */ -#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT - nk_query_font_glyph_id_f query_glyph; /**!< glyph-id callback used by shaped text */ - nk_handle texture; /**!< texture handle to the used font atlas or texture */ -#endif -}; - -/** - * Backend-neutral output of a text shaping operation. - * - * Source offsets are byte offsets into the original UTF-8 string. - * Clusters are stored in logical source order. - * Runs and the glyphs inside each run are stored in *visual order*. - * All metrics are normalized to pixels at the requested font height before they enter this representation. - * - * These structures are non-owning views. - * The producer of an nk_text_shape must keep the source and all arrays alive while the shape is consumed. - * Nuklear will copy them when persistent ownership is required (for example, by a text cache). - */ -enum nk_text_direction { - NK_TEXT_DIRECTION_INVALID = 0, - NK_TEXT_DIRECTION_LTR, - NK_TEXT_DIRECTION_RTL, - NK_TEXT_DIRECTION_TTB, - NK_TEXT_DIRECTION_BTT -}; - -enum nk_text_boundary_flags { - NK_TEXT_BOUNDARY_NONE = 0, - NK_TEXT_BOUNDARY_GRAPHEME = NK_FLAG(0), - NK_TEXT_BOUNDARY_WORD = NK_FLAG(1), - NK_TEXT_BOUNDARY_LINE_SOFT = NK_FLAG(2), - NK_TEXT_BOUNDARY_LINE_HARD = NK_FLAG(3), - NK_TEXT_BOUNDARY_PARAGRAPH = NK_FLAG(4) -}; - -struct nk_text_glyph { - nk_glyph_id id; /**!< font-specific glyph identifier (not a unicode codepoint!!) */ - int cluster_idx; /**!< index into nk_text_shape.clusters */ - float offset_x; /**!< drawing offset from the current pen position (in pixels) */ - float offset_y; - float advance_x; /**!< pen position after drawing this glyph (in pixels) */ - float advance_y; -}; - -struct nk_text_boundary { - int source_offset; /**!< UTF-8 byte offset at which this boundary occurs */ - nk_flags flags; /**!< nk_text_boundary_flags present at this offset */ -}; - -struct nk_text_cluster { - int source_begin; /**!< inclusive UTF-8 byte offset */ - int source_end; /**!< exclusive UTF-8 byte offset */ - int glyph_begin; /**!< first associated glyph in the visual glyph array */ - int glyph_count; /**!< associated glyph count (may be zero for controls) */ -}; - -struct nk_text_run { - const struct nk_user_font *font; /**!< font selected for this run */ - int source_begin; - int source_end; - int glyph_begin; - int glyph_count; - enum nk_text_direction direction; - unsigned int bidi_level; -}; - -struct nk_text_shape { - char *source; - int source_len; - struct nk_text_boundary *boundaries; - int num_boundaries; - struct nk_text_cluster *clusters; - int num_clusters; - struct nk_text_run *runs; - int num_runs; - struct nk_text_glyph *glyphs; - int num_glyphs; - float baseline; /**!< shared glyph baseline measured from the top of the line */ - struct nk_vec2 advance; -}; - -enum nk_text_affinity { - NK_TEXT_AFFINITY_LEADING, - NK_TEXT_AFFINITY_TRAILING -}; - -struct nk_text_cursor { - int source_offset; - float x; - enum nk_text_affinity affinity; -}; - -struct nk_text_selection_span { - float x; - float width; -}; - -struct nk_text_selection_iterator { - const struct nk_text_shape *shape; - int source_begin; - int source_end; - int run_idx; - int glyph_idx; - float pen_x; - float pending_x; - float pending_width; - nk_bool has_pending; -}; - -struct nk_text_wrap_line { - int source_begin; - int source_end; - float width; - nk_flags break_flags; -}; - -struct nk_text_wrap_iterator { - const struct nk_text_shape *shape; - float max_width; - int source_offset; - int cluster_idx; - int boundary_idx; -}; - -#define NK_TEXT_TAG(A, B, C, D) \ - (((nk_uint)(nk_byte)(A) << 24) | \ - ((nk_uint)(nk_byte)(B) << 16) | \ - ((nk_uint)(nk_byte)(C) << 8) | \ - ((nk_uint)(nk_byte)(D) << 0)) - -struct nk_text_feature { - nk_uint tag; /**!< OpenType-style tag (created with NK_TEXT_TAG) */ - int value; /**!< feature value (zero disables the feature) */ -}; - -struct nk_text_request { - const char *source; - int source_len; - const struct nk_user_font *font; /**!< preferred font; a backend may select fallback fonts */ - float font_height; /**!< requested output size in pixels */ - enum nk_text_direction direction; /**!< INVALID requests automatic direction detection */ - nk_uint script_tag; /**!< zero requests automatic script detection */ - const char *lang; /**!< optional BCP-47 tag; it need not be NUL-terminated */ - int lang_len; - const struct nk_text_feature *features; - int num_features; -}; - -/** - * Optional append-only storage used by shaping backends while their output size is unknown. - * A list stores one fixed-size item type. The caller chooses the buffer that owns its chunks - * and may flatten the list into the same or a different buffer. - */ -#ifndef NK_TEXT_CHUNK_DATA_SIZE -#define NK_TEXT_CHUNK_DATA_SIZE 512 -#endif - -#ifndef NK_TEXT_CACHE_BUCKET_COUNT -#define NK_TEXT_CACHE_BUCKET_COUNT 1024 -#endif - -struct nk_text_chunk { - struct nk_text_chunk *next; - nk_size used; - nk_byte data[NK_TEXT_CHUNK_DATA_SIZE]; -}; - -struct nk_text_chunk_list { - struct nk_text_chunk *first; - struct nk_text_chunk *last; - nk_size item_size; - nk_uint count; -}; - -NK_API void -nk_text_chunk_list_init(struct nk_text_chunk_list *list, nk_size item_size); -NK_API nk_bool -nk_text_chunk_list_push(struct nk_text_chunk_list *list, struct nk_buffer *buffer, const void *item); -NK_API void * -nk_text_chunk_list_flatten(const struct nk_text_chunk_list *list, struct nk_buffer *buffer, nk_size alignment); - -/** Builds a shape using the supplied cache buffer. */ -typedef struct nk_text_shape *(*nk_text_shape_build_f)(nk_handle userdata, struct nk_buffer *cache, const struct nk_text_request *request); - -struct nk_text_backend { - nk_handle userdata; - nk_text_shape_build_f build; - struct nk_buffer *temporary; /**!< caller-owned output buffer used when a shape cannot be cached */ -}; - -/** Reserves a fixed cache region from an unused context created by nk_init_fixed. */ -NK_API nk_bool -nk_text_memory_init_fixed(struct nk_context *ctx, nk_size cache_size); - -/** Invalidates all cached text measurements and shapes, then reuses their memory. */ -NK_API void -nk_text_memory_clear(struct nk_context *ctx); - -/** Copies the backend descriptor into the context and invalidates its text cache. */ -NK_API void -nk_text_backend_set(struct nk_context *ctx, const struct nk_text_backend *backend); - -/** Returns a matching cached shape or builds one. An uncached result remains valid until the next shaping call. */ -NK_API struct nk_text_shape * -nk_text_shape_build(struct nk_context *ctx, const struct nk_text_request *request); -NK_API float -nk_text_shape_width(const struct nk_text_shape *shape, int source_begin, int source_end); -NK_API int -nk_text_shape_boundary_previous(const struct nk_text_shape *shape, int source_offset, nk_flags flags); -NK_API int -nk_text_shape_boundary_next(const struct nk_text_shape *shape, int source_offset, nk_flags flags); -NK_API struct nk_text_cursor -nk_text_shape_cursor_at(const struct nk_text_shape *shape, int source_offset, enum nk_text_affinity affinity); -NK_API struct nk_text_cursor -nk_text_shape_hit_test(const struct nk_text_shape *shape, float x); -NK_API struct nk_text_cursor -nk_text_shape_cursor_move(const struct nk_text_shape *shape, struct nk_text_cursor cursor, int direction); -NK_API void -nk_text_selection_iterator_begin(struct nk_text_selection_iterator *iterator, const struct nk_text_shape *shape, int source_begin, int source_end); -NK_API nk_bool -nk_text_selection_iterator_next(struct nk_text_selection_iterator *iterator, struct nk_text_selection_span *span); -NK_API void -nk_text_wrap_iterator_begin(struct nk_text_wrap_iterator *iterator, const struct nk_text_shape *shape, float max_width); -NK_API nk_bool -nk_text_wrap_iterator_next(struct nk_text_wrap_iterator *iterator, struct nk_text_wrap_line *line); -/** Returns a cached width, storing only the request key and width until a full shape is needed. */ -NK_API float -nk_text_width(struct nk_context *ctx, const struct nk_user_font *font, float height, const char *text, int len); - -#ifdef NK_INCLUDE_FONT_BAKING -enum nk_font_coord_type { - NK_COORD_UV, /**!< texture coordinates inside font glyphs are clamped between 0-1 */ - NK_COORD_PIXEL /**!< texture coordinates inside font glyphs are in absolute pixel */ -}; - -struct nk_font; -struct nk_baked_font { - float height; /**!< height of the font */ - float ascent; /**!< font glyphs ascent and descent */ - float descent; /**!< font glyphs ascent and descent */ - nk_rune glyph_offset; /**!< glyph array offset inside the font glyph baking output array */ - nk_rune glyph_count; /**!< number of glyphs of this font inside the glyph baking array output */ - const nk_rune *ranges; /**!< font codepoint ranges as pairs of (from/to) and 0 as last element */ -}; - -struct nk_font_config { - struct nk_font_config *next; /**!< NOTE: only used internally */ - void *ttf_blob; /**!< pointer to loaded TTF file memory block. * \note not needed for nk_font_atlas_add_from_memory - and nk_font_atlas_add_from_file. */ - nk_size ttf_size; /**!< size of the loaded TTF file memory block * \note not needed for nk_font_atlas_add_from_memory - and nk_font_atlas_add_from_file. */ - - unsigned char ttf_data_owned_by_atlas; /**!< used inside font atlas: default to: 0*/ - unsigned char merge_mode; /**!< merges this font into the last font */ - unsigned char pixel_snap; /**!< align every character to pixel boundary (if true set oversample (1,1)) */ - unsigned char oversample_v, oversample_h; /**!< rasterize at high quality for sub-pixel position */ - unsigned char padding[3]; - - float size; /**!< baked pixel height of the font */ - enum nk_font_coord_type coord_type; /**!< texture coordinate format with either pixel or UV coordinates */ - struct nk_vec2 spacing; /**!< extra pixel spacing between glyphs */ - const nk_rune *range; /**!< list of unicode ranges (2 values per range, zero terminated) */ - struct nk_baked_font *font; /**!< font to setup in the baking process: NOTE: not needed for font atlas */ - struct nk_font_config *n; - struct nk_font_config *p; -}; - -struct nk_font_glyph { - nk_rune codepoint; - nk_glyph_id id; - float xadvance; - float x0, y0, x1, y1, w, h; - float u0, v0, u1, v1; -}; - -struct nk_font { - struct nk_font *next; - struct nk_user_font handle; - struct nk_baked_font info; - struct nk_font_glyph *glyphs; - nk_handle texture; - struct nk_font_config *config; -}; - -enum nk_font_atlas_format { NK_FONT_ATLAS_ALPHA8, NK_FONT_ATLAS_RGBA32 }; - -struct nk_font_atlas { - void *pixel; - int tex_width; - int tex_height; - - struct nk_allocator permanent; - struct nk_allocator temporary; - - struct nk_recti custom; - struct nk_cursor cursors[NK_CURSOR_COUNT]; - - int glyph_count; - struct nk_font_glyph *glyphs; - struct nk_font *default_font; - struct nk_font *fonts; - struct nk_font_config *config; - int font_num; -}; - -/** some language glyph codepoint ranges */ -NK_API const nk_rune * -nk_font_default_glyph_ranges(void); -NK_API const nk_rune * -nk_font_chinese_glyph_ranges(void); -NK_API const nk_rune * -nk_font_cyrillic_glyph_ranges(void); -NK_API const nk_rune * -nk_font_korean_glyph_ranges(void); - -# ifdef NK_INCLUDE_DEFAULT_ALLOCATOR -NK_API void -nk_font_atlas_init_default(struct nk_font_atlas *); -# endif -NK_API void -nk_font_atlas_init(struct nk_font_atlas *, const struct nk_allocator *); -NK_API void -nk_font_atlas_init_custom(struct nk_font_atlas *, - const struct nk_allocator *persistent, - const struct nk_allocator *transient); -NK_API void -nk_font_atlas_begin(struct nk_font_atlas *); -NK_API struct nk_font_config -nk_font_config(float pixel_height); -NK_API struct nk_font * -nk_font_atlas_add(struct nk_font_atlas *, const struct nk_font_config *); -# ifdef NK_INCLUDE_DEFAULT_FONT -NK_API struct nk_font * -nk_font_atlas_add_default(struct nk_font_atlas *, float height, const struct nk_font_config *); -# endif -NK_API struct nk_font * -nk_font_atlas_add_from_memory( - struct nk_font_atlas *atlas, void *memory, nk_size size, float height, const struct nk_font_config *config); -# ifdef NK_INCLUDE_STANDARD_IO -NK_API struct nk_font * -nk_font_atlas_add_from_file(struct nk_font_atlas *atlas, - const char *file_path, - float height, - const struct nk_font_config *); -# endif -NK_API struct nk_font * -nk_font_atlas_add_compressed( - struct nk_font_atlas *, void *memory, nk_size size, float height, const struct nk_font_config *); -NK_API struct nk_font * -nk_font_atlas_add_compressed_base85(struct nk_font_atlas *, - const char *data, - float height, - const struct nk_font_config *config); -NK_API const void * -nk_font_atlas_bake(struct nk_font_atlas *, int *width, int *height, enum nk_font_atlas_format); -NK_API void -nk_font_atlas_end(struct nk_font_atlas *, nk_handle tex, struct nk_draw_null_texture *); -NK_API void -nk_font_atlas_cleanup(struct nk_font_atlas *atlas); -NK_API void -nk_font_atlas_clear(struct nk_font_atlas *); - -#endif - -/* ============================================================== - * - * MEMORY BUFFER - * - * ===============================================================*/ -/** - * \page Memory Buffer - * A basic (double)-buffer with linear allocation and resetting as only - * freeing policy. The buffer's main purpose is to control all memory management - * inside the GUI toolkit and still leave memory control as much as possible in - * the hand of the user while also making sure the library is easy to use if - * not as much control is needed. - * In general all memory inside this library can be provided from the user in - * three different ways. - * - * The first way and the one providing most control is by just passing a fixed - * size memory block. In this case all control lies in the hand of the user - * since he can exactly control where the memory comes from and how much memory - * the library should consume. Of course using the fixed size API removes the - * ability to automatically resize a buffer if not enough memory is provided so - * you have to take over the resizing. While being a fixed sized buffer sounds - * quite limiting, it is very effective in this library since the actual memory - * consumption is quite stable and has a fixed upper bound for a lot of cases. - * - * If you don't want to think about how much memory the library should allocate - * at all time or have a very dynamic UI with unpredictable memory consumption - * habits but still want control over memory allocation you can use the dynamic - * allocator based API. The allocator consists of two callbacks for allocating - * and freeing memory and optional userdata so you can plugin your own allocator. - * - * The final and easiest way can be used by defining - * NK_INCLUDE_DEFAULT_ALLOCATOR which uses the standard library memory - * allocation functions malloc and free and takes over complete control over - * memory in this library. - */ - -struct nk_memory_status { - void *memory; - unsigned int type; - nk_size size; - nk_size allocated; - nk_size needed; - nk_size calls; -}; - -enum nk_allocation_type { NK_BUFFER_FIXED, NK_BUFFER_DYNAMIC }; - -enum nk_buffer_allocation_type { NK_BUFFER_FRONT, NK_BUFFER_BACK, NK_BUFFER_MAX }; - -struct nk_buffer_marker { - nk_bool active; - nk_size offset; -}; - -struct nk_memory { - void *ptr; - nk_size size; -}; -struct nk_buffer { - struct nk_buffer_marker marker[NK_BUFFER_MAX]; /**!< buffer marker to free a buffer to a certain offset */ - struct nk_allocator pool; /**!< allocator callback for dynamic buffers */ - enum nk_allocation_type type; /**!< memory management type */ - struct nk_memory memory; /**!< memory and size of the current memory block */ - float grow_factor; /**!< growing factor for dynamic memory management */ - nk_size allocated; /**!< total amount of memory allocated */ - nk_size needed; /**!< totally consumed memory given that enough memory is present */ - nk_size calls; /**!< number of allocation calls */ - nk_size size; /**!< current size of the buffer */ -}; - -#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR -NK_API void -nk_buffer_init_default(struct nk_buffer *); -#endif -NK_API void -nk_buffer_init(struct nk_buffer *, const struct nk_allocator *, nk_size size); -NK_API void -nk_buffer_init_fixed(struct nk_buffer *, void *memory, nk_size size); -NK_API void -nk_buffer_info(struct nk_memory_status *, const struct nk_buffer *); -NK_API void -nk_buffer_push( - struct nk_buffer *, enum nk_buffer_allocation_type type, const void *memory, nk_size size, nk_size align); -NK_API void -nk_buffer_mark(struct nk_buffer *, enum nk_buffer_allocation_type type); -NK_API void -nk_buffer_reset(struct nk_buffer *, enum nk_buffer_allocation_type type); -NK_API void -nk_buffer_clear(struct nk_buffer *); -NK_API void -nk_buffer_free(struct nk_buffer *); -NK_API void * -nk_buffer_memory(struct nk_buffer *); -NK_API const void * -nk_buffer_memory_const(const struct nk_buffer *); -NK_API nk_size -nk_buffer_total(const struct nk_buffer *); - -/* ============================================================== - * - * STRING - * - * ===============================================================*/ -/** Basic string buffer which is only used in context with the text editor - * to manage and manipulate dynamic or fixed size string content. This is _NOT_ - * the default string handling method. The only instance you should have any contact - * with this API is if you interact with an `nk_text_edit` object inside one of the - * copy and paste functions and even there only for more advanced cases. */ -struct nk_str { - struct nk_buffer buffer; - int len; /**!< in codepoints/runes/glyphs */ -}; - -#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR -NK_API void -nk_str_init_default(struct nk_str *); -#endif -NK_API void -nk_str_init(struct nk_str *, const struct nk_allocator *, nk_size size); -NK_API void -nk_str_init_fixed(struct nk_str *, void *memory, nk_size size); -NK_API void -nk_str_clear(struct nk_str *); -NK_API void -nk_str_free(struct nk_str *); - -NK_API int -nk_str_append_text_char(struct nk_str *, const char *, int); -NK_API int -nk_str_append_str_char(struct nk_str *, const char *); -NK_API int -nk_str_append_text_utf8(struct nk_str *, const char *, int); -NK_API int -nk_str_append_str_utf8(struct nk_str *, const char *); -NK_API int -nk_str_append_text_runes(struct nk_str *, const nk_rune *, int); -NK_API int -nk_str_append_str_runes(struct nk_str *, const nk_rune *); - -NK_API int -nk_str_insert_at_char(struct nk_str *, int pos, const char *, int); -NK_API int -nk_str_insert_at_rune(struct nk_str *, int pos, const char *, int); - -NK_API int -nk_str_insert_text_char(struct nk_str *, int pos, const char *, int); -NK_API int -nk_str_insert_str_char(struct nk_str *, int pos, const char *); -NK_API int -nk_str_insert_text_utf8(struct nk_str *, int pos, const char *, int); -NK_API int -nk_str_insert_str_utf8(struct nk_str *, int pos, const char *); -NK_API int -nk_str_insert_text_runes(struct nk_str *, int pos, const nk_rune *, int); -NK_API int -nk_str_insert_str_runes(struct nk_str *, int pos, const nk_rune *); - -NK_API void -nk_str_remove_chars(struct nk_str *, int len); -NK_API void -nk_str_remove_runes(struct nk_str *str, int len); -NK_API void -nk_str_delete_chars(struct nk_str *, int pos, int len); -NK_API void -nk_str_delete_runes(struct nk_str *, int pos, int len); - -NK_API char * -nk_str_at_char(struct nk_str *, int pos); -NK_API char * -nk_str_at_rune(struct nk_str *, int pos, nk_rune *unicode, int *len); -NK_API nk_rune -nk_str_rune_at(const struct nk_str *, int pos); -NK_API const char * -nk_str_at_char_const(const struct nk_str *, int pos); -NK_API const char * -nk_str_at_const(const struct nk_str *, int pos, nk_rune *unicode, int *len); - -NK_API char * -nk_str_get(struct nk_str *); -NK_API const char * -nk_str_get_const(const struct nk_str *); -NK_API int -nk_str_len(const struct nk_str *); -NK_API int -nk_str_len_char(const struct nk_str *); - -/* =============================================================== - * - * TEXT EDITOR - * - * ===============================================================*/ -/** - * \page Text Editor - * Editing text in this library is handled by either `nk_edit_string` or - * `nk_edit_buffer`. But like almost everything in this library there are multiple - * ways of doing it and a balance between control and ease of use with memory - * as well as functionality controlled by flags. - * - * This library generally allows three different levels of memory control: - * First of is the most basic way of just providing a simple char array with - * string length. This method is probably the easiest way of handling simple - * user text input. Main upside is complete control over memory while the biggest - * downside in comparison with the other two approaches is missing undo/redo. - * - * For UIs that require undo/redo the second way was created. It is based on - * a fixed size nk_text_edit struct, which has an internal undo/redo stack. - * This is mainly useful if you want something more like a text editor but don't want - * to have a dynamically growing buffer. - * - * The final way is using a dynamically growing nk_text_edit struct, which - * has both a default version if you don't care where memory comes from and an - * allocator version if you do. While the text editor is quite powerful for its - * complexity I would not recommend editing gigabytes of data with it. - * It is rather designed for uses cases which make sense for a GUI library not for - * an full blown text editor. - */ - -#ifndef NK_TEXTEDIT_UNDOSTATECOUNT -# define NK_TEXTEDIT_UNDOSTATECOUNT 99 -#endif - -#ifndef NK_TEXTEDIT_UNDOCHARCOUNT -# define NK_TEXTEDIT_UNDOCHARCOUNT 999 -#endif - -struct nk_text_edit; -struct nk_clipboard { - nk_handle userdata; - nk_plugin_paste paste; - nk_plugin_copy copy; -}; - -struct nk_text_undo_record { - int where; - short insert_length; - short delete_length; - short char_storage; -}; - -struct nk_text_undo_state { - struct nk_text_undo_record undo_rec[NK_TEXTEDIT_UNDOSTATECOUNT]; - nk_rune undo_char[NK_TEXTEDIT_UNDOCHARCOUNT]; - short undo_point; - short redo_point; - short undo_char_point; - short redo_char_point; -}; - -enum nk_text_edit_type { - NK_TEXT_EDIT_SINGLE_LINE, - NK_TEXT_EDIT_MULTI_LINE, -}; - -enum nk_text_edit_mode { - NK_TEXT_EDIT_MODE_VIEW, - NK_TEXT_EDIT_MODE_INSERT, - NK_TEXT_EDIT_MODE_REPLACE, -}; - -struct nk_text_edit { - struct nk_context *context; - struct nk_clipboard clip; - struct nk_str string; - nk_plugin_filter filter; - struct nk_vec2 scrollbar; - struct nk_vec2 scrollbar_prev_max; - nk_uint scrollbar_flags; - - int cursor; - int select_start; - int select_end; - unsigned char mode; - unsigned char cursor_at_end_of_line; - unsigned char initialized; - unsigned char has_preferred_x; - unsigned char single_line; - unsigned char active; - unsigned char cursor_affinity; - unsigned char select_start_affinity; - float preferred_x; - struct nk_text_undo_state undo; -}; - -/** filter function */ -NK_API nk_bool -nk_filter_default(const struct nk_text_edit *, nk_rune unicode); -NK_API nk_bool -nk_filter_ascii(const struct nk_text_edit *, nk_rune unicode); -NK_API nk_bool -nk_filter_float(const struct nk_text_edit *, nk_rune unicode); -NK_API nk_bool -nk_filter_decimal(const struct nk_text_edit *, nk_rune unicode); -NK_API nk_bool -nk_filter_hex(const struct nk_text_edit *, nk_rune unicode); -NK_API nk_bool -nk_filter_oct(const struct nk_text_edit *, nk_rune unicode); -NK_API nk_bool -nk_filter_binary(const struct nk_text_edit *, nk_rune unicode); - -/** text editor */ -#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR -NK_API void -nk_textedit_init_default(struct nk_text_edit *); -#endif -NK_API void -nk_textedit_init(struct nk_text_edit *, const struct nk_allocator *, nk_size size); -NK_API void -nk_textedit_init_fixed(struct nk_text_edit *, void *memory, nk_size size); -NK_API void -nk_textedit_free(struct nk_text_edit *); -NK_API void -nk_textedit_text(struct nk_text_edit *, const char *, int total_len); -NK_API void -nk_textedit_delete(struct nk_text_edit *, int where, int len); -NK_API void -nk_textedit_delete_selection(struct nk_text_edit *); -NK_API void -nk_textedit_select_all(struct nk_text_edit *); -NK_API nk_bool -nk_textedit_cut(struct nk_text_edit *); -NK_API nk_bool -nk_textedit_paste(struct nk_text_edit *, char const *, int len); -NK_API void -nk_textedit_undo(struct nk_text_edit *); -NK_API void -nk_textedit_redo(struct nk_text_edit *); - -/* =============================================================== - * - * DRAWING - * - * ===============================================================*/ -/** - * \page Drawing - * This library was designed to be render backend agnostic so it does - * not draw anything to screen. Instead all drawn shapes, widgets - * are made of, are buffered into memory and make up a command queue. - * Each frame therefore fills the command buffer with draw commands - * that then need to be executed by the user and his own render backend. - * After that the command buffer needs to be cleared and a new frame can be - * started. It is probably important to note that the command buffer is the main - * drawing API and the optional vertex buffer API only takes this format and - * converts it into a hardware accessible format. - * - * To use the command queue to draw your own widgets you can access the - * command buffer of each window by calling `nk_window_get_canvas` after - * previously having called `nk_begin`: - * - * ```c - * void draw_red_rectangle_widget(struct nk_context *ctx) - * { - * struct nk_command_buffer *canvas; - * struct nk_input *input = &ctx->input; - * canvas = nk_window_get_canvas(ctx); - * - * struct nk_rect space; - * enum nk_widget_layout_states state; - * state = nk_widget(&space, ctx); - * if (!state) return; - * - * if (state != NK_WIDGET_ROM) - * update_your_widget_by_user_input(...); - * nk_fill_rect(canvas, space, 0, nk_rgb(255,0,0)); - * } - * - * if (nk_begin(...)) { - * nk_layout_row_dynamic(ctx, 25, 1); - * draw_red_rectangle_widget(ctx); - * } - * nk_end(..) - * - * ``` - * Important to know if you want to create your own widgets is the `nk_widget` - * call. It allocates space on the panel reserved for this widget to be used, - * but also returns the state of the widget space. If your widget is not seen and does - * not have to be updated it is '0' and you can just return. If it only has - * to be drawn the state will be `NK_WIDGET_ROM` otherwise you can do both - * update and draw your widget. The reason for separating is to only draw and - * update what is actually necessary which is crucial for performance. - */ - -enum nk_command_type { - NK_COMMAND_NOP, - NK_COMMAND_SCISSOR, - NK_COMMAND_LINE, - NK_COMMAND_CURVE, - NK_COMMAND_RECT, - NK_COMMAND_RECT_FILLED, - NK_COMMAND_RECT_MULTI_COLOR, - NK_COMMAND_CIRCLE, - NK_COMMAND_CIRCLE_FILLED, - NK_COMMAND_ARC, - NK_COMMAND_ARC_FILLED, - NK_COMMAND_TRIANGLE, - NK_COMMAND_TRIANGLE_FILLED, - NK_COMMAND_POLYGON, - NK_COMMAND_POLYGON_FILLED, - NK_COMMAND_POLYLINE, - NK_COMMAND_TEXT, - NK_COMMAND_IMAGE, - NK_COMMAND_CUSTOM -}; - -/** command base and header of every command inside the buffer */ -struct nk_command { - enum nk_command_type type; - nk_size next; -#ifdef NK_INCLUDE_COMMAND_USERDATA - nk_handle userdata; -#endif -}; - -struct nk_command_scissor { - struct nk_command header; - short x, y; - unsigned short w, h; -}; - -struct nk_command_line { - struct nk_command header; - unsigned short line_thickness; - struct nk_vec2i begin; - struct nk_vec2i end; - struct nk_color color; -}; - -struct nk_command_curve { - struct nk_command header; - unsigned short line_thickness; - struct nk_vec2i begin; - struct nk_vec2i end; - struct nk_vec2i ctrl[2]; - struct nk_color color; -}; - -struct nk_command_rect { - struct nk_command header; - unsigned short rounding; - unsigned short line_thickness; - short x, y; - unsigned short w, h; - struct nk_color color; -}; - -struct nk_command_rect_filled { - struct nk_command header; - unsigned short rounding; - short x, y; - unsigned short w, h; - struct nk_color color; -}; - -struct nk_command_rect_multi_color { - struct nk_command header; - short x, y; - unsigned short w, h; - struct nk_color left; - struct nk_color top; - struct nk_color bottom; - struct nk_color right; -}; - -struct nk_command_triangle { - struct nk_command header; - unsigned short line_thickness; - struct nk_vec2i a; - struct nk_vec2i b; - struct nk_vec2i c; - struct nk_color color; -}; - -struct nk_command_triangle_filled { - struct nk_command header; - struct nk_vec2i a; - struct nk_vec2i b; - struct nk_vec2i c; - struct nk_color color; -}; - -struct nk_command_circle { - struct nk_command header; - short x, y; - unsigned short line_thickness; - unsigned short w, h; - struct nk_color color; -}; - -struct nk_command_circle_filled { - struct nk_command header; - short x, y; - unsigned short w, h; - struct nk_color color; -}; - -struct nk_command_arc { - struct nk_command header; - short cx, cy; - unsigned short r; - unsigned short line_thickness; - float a[2]; - struct nk_color color; -}; - -struct nk_command_arc_filled { - struct nk_command header; - short cx, cy; - unsigned short r; - float a[2]; - struct nk_color color; -}; - -struct nk_command_polygon { - struct nk_command header; - struct nk_color color; - unsigned short line_thickness; - unsigned short point_count; - struct nk_vec2i points[1]; -}; - -struct nk_command_polygon_filled { - struct nk_command header; - struct nk_color color; - unsigned short point_count; - struct nk_vec2i points[1]; -}; - -struct nk_command_polyline { - struct nk_command header; - struct nk_color color; - unsigned short line_thickness; - unsigned short point_count; - struct nk_vec2i points[1]; -}; - -struct nk_command_image { - struct nk_command header; - short x, y; - unsigned short w, h; - struct nk_image img; - struct nk_color col; -}; - -typedef void (*nk_command_custom_callback)( - void *canvas, short x, short y, unsigned short w, unsigned short h, nk_handle callback_data); -struct nk_command_custom { - struct nk_command header; - short x, y; - unsigned short w, h; - nk_handle callback_data; - nk_command_custom_callback callback; -}; - -struct nk_command_text { - struct nk_command header; - const struct nk_user_font *font; - struct nk_color background; - struct nk_color foreground; - short x, y; - unsigned short w, h; - float height; - int length; - char string[2]; -}; - -enum nk_command_clipping { NK_CLIPPING_OFF = nk_false, NK_CLIPPING_ON = nk_true }; - -struct nk_command_buffer { - struct nk_context *context; - struct nk_buffer *base; - struct nk_rect clip; - int use_clipping; - nk_handle userdata; - nk_size begin, end, last; -}; - -/** shape outlines */ -NK_API void -nk_stroke_line( - struct nk_command_buffer *b, float x0, float y0, float x1, float y1, float line_thickness, struct nk_color); -NK_API void -nk_stroke_curve(struct nk_command_buffer *, - float, - float, - float, - float, - float, - float, - float, - float, - float line_thickness, - struct nk_color); -NK_API void -nk_stroke_rect(struct nk_command_buffer *, struct nk_rect, float rounding, float line_thickness, struct nk_color); -NK_API void -nk_stroke_circle(struct nk_command_buffer *, struct nk_rect, float line_thickness, struct nk_color); -NK_API void -nk_stroke_arc(struct nk_command_buffer *, - float cx, - float cy, - float radius, - float a_min, - float a_max, - float line_thickness, - struct nk_color); -NK_API void -nk_stroke_triangle( - struct nk_command_buffer *, float, float, float, float, float, float, float line_thichness, struct nk_color); -NK_API void -nk_stroke_polyline( - struct nk_command_buffer *, const float *points, int point_count, float line_thickness, struct nk_color col); -NK_API void -nk_stroke_polygon( - struct nk_command_buffer *, const float *points, int point_count, float line_thickness, struct nk_color); - -/** filled shades */ -NK_API void -nk_fill_rect(struct nk_command_buffer *, struct nk_rect, float rounding, struct nk_color); -NK_API void -nk_fill_rect_multi_color(struct nk_command_buffer *, - struct nk_rect, - struct nk_color left, - struct nk_color top, - struct nk_color right, - struct nk_color bottom); -NK_API void -nk_fill_circle(struct nk_command_buffer *, struct nk_rect, struct nk_color); -NK_API void -nk_fill_arc(struct nk_command_buffer *, float cx, float cy, float radius, float a_min, float a_max, struct nk_color); -NK_API void -nk_fill_triangle( - struct nk_command_buffer *, float x0, float y0, float x1, float y1, float x2, float y2, struct nk_color); -NK_API void -nk_fill_polygon(struct nk_command_buffer *, const float *points, int point_count, struct nk_color); - -/** misc */ -NK_API void -nk_draw_image(struct nk_command_buffer *, struct nk_rect, const struct nk_image *, struct nk_color); -NK_API void -nk_draw_nine_slice(struct nk_command_buffer *, struct nk_rect, const struct nk_nine_slice *, struct nk_color); -NK_API void -nk_draw_text(struct nk_command_buffer *, - struct nk_rect, - const char *text, - int len, - const struct nk_user_font *, - struct nk_color, - struct nk_color); -NK_API void -nk_push_scissor(struct nk_command_buffer *, struct nk_rect); -NK_API void -nk_push_custom(struct nk_command_buffer *, struct nk_rect, nk_command_custom_callback, nk_handle usr); - -/* =============================================================== - * - * INPUT - * - * ===============================================================*/ -struct nk_mouse_button { - nk_bool down; - unsigned int clicked; - struct nk_vec2 clicked_pos; -}; -struct nk_mouse { - struct nk_mouse_button buttons[NK_BUTTON_MAX]; - struct nk_vec2 pos; -#ifdef NK_BUTTON_TRIGGER_ON_RELEASE - struct nk_vec2 down_pos; -#endif - struct nk_vec2 prev; - struct nk_vec2 delta; - struct nk_vec2 scroll_delta; - unsigned char grab; - unsigned char grabbed; - unsigned char ungrab; -}; - -struct nk_key { - nk_bool down; - unsigned int clicked; -}; -struct nk_keyboard { - struct nk_key keys[NK_KEY_MAX]; - char text[NK_INPUT_MAX]; - int text_len; -}; - -struct nk_input { - struct nk_keyboard keyboard; - struct nk_mouse mouse; -}; - -NK_API nk_bool -nk_input_has_mouse_click(const struct nk_input *, enum nk_buttons); -NK_API nk_bool -nk_input_has_mouse_click_in_rect(const struct nk_input *, enum nk_buttons, struct nk_rect); -NK_API nk_bool -nk_input_has_mouse_click_in_button_rect(const struct nk_input *, enum nk_buttons, struct nk_rect); -NK_API nk_bool -nk_input_has_mouse_click_down_in_rect(const struct nk_input *, enum nk_buttons, struct nk_rect, nk_bool down); -NK_API nk_bool -nk_input_is_mouse_click_in_rect(const struct nk_input *, enum nk_buttons, struct nk_rect); -NK_API nk_bool -nk_input_is_mouse_click_down_in_rect(const struct nk_input *i, enum nk_buttons id, struct nk_rect b, nk_bool down); -NK_API nk_bool -nk_input_any_mouse_click_in_rect(const struct nk_input *, struct nk_rect); -NK_API nk_bool -nk_input_is_mouse_prev_hovering_rect(const struct nk_input *, struct nk_rect); -NK_API nk_bool -nk_input_is_mouse_hovering_rect(const struct nk_input *, struct nk_rect); -NK_API nk_bool -nk_input_is_mouse_moved(const struct nk_input *); -NK_API nk_bool -nk_input_mouse_clicked(const struct nk_input *, enum nk_buttons, struct nk_rect); -NK_API nk_bool -nk_input_is_mouse_down(const struct nk_input *, enum nk_buttons); -NK_API nk_bool -nk_input_is_mouse_pressed(const struct nk_input *, enum nk_buttons); -NK_API nk_bool -nk_input_is_mouse_released(const struct nk_input *, enum nk_buttons); -NK_API nk_bool -nk_input_is_key_pressed(const struct nk_input *, enum nk_keys); -NK_API nk_bool -nk_input_is_key_released(const struct nk_input *, enum nk_keys); -NK_API nk_bool -nk_input_is_key_down(const struct nk_input *, enum nk_keys); - -/* =============================================================== - * - * DRAW LIST - * - * ===============================================================*/ -#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT -/** - * \page "Draw List" - * The optional vertex buffer draw list provides a 2D drawing context - * with antialiasing functionality which takes basic filled or outlined shapes - * or a path and outputs vertexes, elements and draw commands. - * The actual draw list API is not required to be used directly while using this - * library since converting the default library draw command output is done by - * just calling `nk_convert` but I decided to still make this library accessible - * since it can be useful. - * - * The draw list is based on a path buffering and polygon and polyline - * rendering API which allows a lot of ways to draw 2D content to screen. - * In fact it is probably more powerful than needed but allows even more crazy - * things than this library provides by default. - */ - -# ifdef NK_UINT_DRAW_INDEX -typedef nk_uint nk_draw_index; -# else -typedef nk_ushort nk_draw_index; -# endif -enum nk_draw_list_stroke { - NK_STROKE_OPEN = nk_false, /***< build up path has no connection back to the beginning */ - NK_STROKE_CLOSED = nk_true /***< build up path has a connection back to the beginning */ -}; - -enum nk_draw_vertex_layout_attribute { - NK_VERTEX_POSITION, - NK_VERTEX_COLOR, - NK_VERTEX_TEXCOORD, - NK_VERTEX_ATTRIBUTE_COUNT -}; - -enum nk_draw_vertex_layout_format { - NK_FORMAT_SCHAR, - NK_FORMAT_SSHORT, - NK_FORMAT_SINT, - NK_FORMAT_UCHAR, - NK_FORMAT_USHORT, - NK_FORMAT_UINT, - NK_FORMAT_FLOAT, - NK_FORMAT_DOUBLE, - - NK_FORMAT_COLOR_BEGIN, - NK_FORMAT_R8G8B8 = NK_FORMAT_COLOR_BEGIN, - NK_FORMAT_R16G15B16, - NK_FORMAT_R32G32B32, - - NK_FORMAT_R8G8B8A8, - NK_FORMAT_B8G8R8A8, - NK_FORMAT_R16G15B16A16, - NK_FORMAT_R32G32B32A32, - NK_FORMAT_R32G32B32A32_FLOAT, - NK_FORMAT_R32G32B32A32_DOUBLE, - - NK_FORMAT_RGB32, - NK_FORMAT_RGBA32, - NK_FORMAT_COLOR_END = NK_FORMAT_RGBA32, - NK_FORMAT_COUNT -}; - -# define NK_VERTEX_LAYOUT_END NK_VERTEX_ATTRIBUTE_COUNT, NK_FORMAT_COUNT, 0 -struct nk_draw_vertex_layout_element { - enum nk_draw_vertex_layout_attribute attribute; - enum nk_draw_vertex_layout_format format; - nk_size offset; -}; - -struct nk_draw_command { - unsigned int elem_count; /**< number of elements in the current draw batch */ - struct nk_rect clip_rect; /**< current screen clipping rectangle */ - nk_handle texture; /**< current texture to set */ -# ifdef NK_INCLUDE_COMMAND_USERDATA - nk_handle userdata; -# endif -}; - -struct nk_draw_list { - struct nk_rect clip_rect; - struct nk_vec2 circle_vtx[12]; - struct nk_convert_config config; - - struct nk_buffer *buffer; - struct nk_buffer *vertices; - struct nk_buffer *elements; - - unsigned int element_count; - unsigned int vertex_count; - unsigned int cmd_count; - nk_size cmd_offset; - - unsigned int path_count; - unsigned int path_offset; - - enum nk_anti_aliasing line_AA; - enum nk_anti_aliasing shape_AA; - -# ifdef NK_INCLUDE_COMMAND_USERDATA - nk_handle userdata; -# endif -}; - -/* draw list */ -NK_API void -nk_draw_list_init(struct nk_draw_list *); -NK_API void -nk_draw_list_setup(struct nk_draw_list *, - const struct nk_convert_config *, - struct nk_buffer *cmds, - struct nk_buffer *vertices, - struct nk_buffer *elements, - enum nk_anti_aliasing line_aa, - enum nk_anti_aliasing shape_aa); - -/* drawing */ -# define nk_draw_list_foreach(cmd, can, b) \ - for ((cmd) = nk__draw_list_begin(can, b); (cmd) != 0; (cmd) = nk__draw_list_next(cmd, b, can)) -NK_API const struct nk_draw_command * -nk__draw_list_begin(const struct nk_draw_list *, const struct nk_buffer *); -NK_API const struct nk_draw_command * -nk__draw_list_next(const struct nk_draw_command *, const struct nk_buffer *, const struct nk_draw_list *); -NK_API const struct nk_draw_command * -nk__draw_list_end(const struct nk_draw_list *, const struct nk_buffer *); - -/* path */ -NK_API void -nk_draw_list_path_clear(struct nk_draw_list *); -NK_API void -nk_draw_list_path_line_to(struct nk_draw_list *, struct nk_vec2 pos); -NK_API void -nk_draw_list_path_arc_to_fast(struct nk_draw_list *, struct nk_vec2 center, float radius, int a_min, int a_max); -NK_API void -nk_draw_list_path_arc_to( - struct nk_draw_list *, struct nk_vec2 center, float radius, float a_min, float a_max, unsigned int segments); -NK_API void -nk_draw_list_path_rect_to(struct nk_draw_list *, struct nk_vec2 a, struct nk_vec2 b, float rounding); -NK_API void -nk_draw_list_path_curve_to( - struct nk_draw_list *, struct nk_vec2 p2, struct nk_vec2 p3, struct nk_vec2 p4, unsigned int num_segments); -NK_API void -nk_draw_list_path_fill(struct nk_draw_list *, struct nk_color); -NK_API void -nk_draw_list_path_stroke(struct nk_draw_list *, struct nk_color, enum nk_draw_list_stroke closed, float thickness); - -/* stroke */ -NK_API void -nk_draw_list_stroke_line(struct nk_draw_list *, struct nk_vec2 a, struct nk_vec2 b, struct nk_color, float thickness); -NK_API void -nk_draw_list_stroke_rect(struct nk_draw_list *, struct nk_rect rect, struct nk_color, float rounding, float thickness); -NK_API void -nk_draw_list_stroke_triangle( - struct nk_draw_list *, struct nk_vec2 a, struct nk_vec2 b, struct nk_vec2 c, struct nk_color, float thickness); -NK_API void -nk_draw_list_stroke_circle( - struct nk_draw_list *, struct nk_vec2 center, float radius, struct nk_color, unsigned int segs, float thickness); -NK_API void -nk_draw_list_stroke_curve(struct nk_draw_list *, - struct nk_vec2 p0, - struct nk_vec2 cp0, - struct nk_vec2 cp1, - struct nk_vec2 p1, - struct nk_color, - unsigned int segments, - float thickness); -NK_API void -nk_draw_list_stroke_poly_line(struct nk_draw_list *, - const struct nk_vec2 *pnts, - const unsigned int cnt, - struct nk_color, - enum nk_draw_list_stroke, - float thickness, - enum nk_anti_aliasing); - -/* fill */ -NK_API void -nk_draw_list_fill_rect(struct nk_draw_list *, struct nk_rect rect, struct nk_color, float rounding); -NK_API void -nk_draw_list_fill_rect_multi_color(struct nk_draw_list *, - struct nk_rect rect, - struct nk_color left, - struct nk_color top, - struct nk_color right, - struct nk_color bottom); -NK_API void -nk_draw_list_fill_triangle( - struct nk_draw_list *, struct nk_vec2 a, struct nk_vec2 b, struct nk_vec2 c, struct nk_color); -NK_API void -nk_draw_list_fill_circle( - struct nk_draw_list *, struct nk_vec2 center, float radius, struct nk_color col, unsigned int segs); -NK_API void -nk_draw_list_fill_poly_convex(struct nk_draw_list *, - const struct nk_vec2 *points, - const unsigned int count, - struct nk_color, - enum nk_anti_aliasing); - -/* misc */ -NK_API void -nk_draw_list_add_image(struct nk_draw_list *, struct nk_image texture, struct nk_rect rect, struct nk_color); -NK_API void -nk_draw_list_add_text_shape(struct nk_draw_list *, const struct nk_text_shape *, struct nk_rect, float font_height, struct nk_color); -# ifdef NK_INCLUDE_COMMAND_USERDATA -NK_API void -nk_draw_list_push_userdata(struct nk_draw_list *, nk_handle userdata); -# endif - -#endif - -/* =============================================================== - * - * GUI - * - * ===============================================================*/ -enum nk_style_item_type { NK_STYLE_ITEM_COLOR, NK_STYLE_ITEM_IMAGE, NK_STYLE_ITEM_NINE_SLICE }; - -union nk_style_item_data { - struct nk_color color; - struct nk_image image; - struct nk_nine_slice slice; -}; - -struct nk_style_item { - enum nk_style_item_type type; - union nk_style_item_data data; -}; - -struct nk_style_text { - struct nk_color color; - struct nk_vec2 padding; - float color_factor; - float disabled_factor; -}; - -struct nk_style_button { - /* background */ - struct nk_style_item normal; - struct nk_style_item hover; - struct nk_style_item active; - struct nk_color border_color; - float color_factor_background; - - /* text */ - struct nk_color text_background; - struct nk_color text_normal; - struct nk_color text_hover; - struct nk_color text_active; - nk_flags text_alignment; - float color_factor_text; - - /* properties */ - float border; - float rounding; - struct nk_vec2 padding; - struct nk_vec2 image_padding; - struct nk_vec2 touch_padding; - float disabled_factor; - - /* optional user callbacks */ - nk_handle userdata; - void (*draw_begin)(struct nk_command_buffer *, nk_handle userdata); - void (*draw_end)(struct nk_command_buffer *, nk_handle userdata); -}; - -struct nk_style_toggle { - /* background */ - struct nk_style_item normal; - struct nk_style_item hover; - struct nk_style_item active; - struct nk_color border_color; - - /* cursor */ - struct nk_style_item cursor_normal; - struct nk_style_item cursor_hover; - - /* text */ - struct nk_color text_normal; - struct nk_color text_hover; - struct nk_color text_active; - struct nk_color text_background; - nk_flags text_alignment; - - /* properties */ - struct nk_vec2 padding; - struct nk_vec2 touch_padding; - float spacing; - float border; - float color_factor; - float disabled_factor; - - /* optional user callbacks */ - nk_handle userdata; - void (*draw_begin)(struct nk_command_buffer *, nk_handle); - void (*draw_end)(struct nk_command_buffer *, nk_handle); -}; - -struct nk_style_selectable { - /* background (inactive) */ - struct nk_style_item normal; - struct nk_style_item hover; - struct nk_style_item pressed; - - /* background (active) */ - struct nk_style_item normal_active; - struct nk_style_item hover_active; - struct nk_style_item pressed_active; - - /* text color (inactive) */ - struct nk_color text_normal; - struct nk_color text_hover; - struct nk_color text_pressed; - - /* text color (active) */ - struct nk_color text_normal_active; - struct nk_color text_hover_active; - struct nk_color text_pressed_active; - struct nk_color text_background; - nk_flags text_alignment; - - /* properties */ - float rounding; - struct nk_vec2 padding; - struct nk_vec2 touch_padding; - struct nk_vec2 image_padding; - float color_factor; - float disabled_factor; - - /* optional user callbacks */ - nk_handle userdata; - void (*draw_begin)(struct nk_command_buffer *, nk_handle); - void (*draw_end)(struct nk_command_buffer *, nk_handle); -}; - -struct nk_style_slider { - /* background */ - struct nk_style_item normal; - struct nk_style_item hover; - struct nk_style_item active; - struct nk_color border_color; - - /* background bar */ - struct nk_color bar_normal; - struct nk_color bar_hover; - struct nk_color bar_active; - struct nk_color bar_filled; - - /* cursor */ - struct nk_style_item cursor_normal; - struct nk_style_item cursor_hover; - struct nk_style_item cursor_active; - - /* properties */ - float border; - float rounding; - float bar_height; - struct nk_vec2 padding; - struct nk_vec2 spacing; - struct nk_vec2 cursor_size; - float color_factor; - float disabled_factor; - - /* optional buttons */ - int show_buttons; - struct nk_style_button inc_button; - struct nk_style_button dec_button; - enum nk_symbol_type inc_symbol; - enum nk_symbol_type dec_symbol; - - /* optional user callbacks */ - nk_handle userdata; - void (*draw_begin)(struct nk_command_buffer *, nk_handle); - void (*draw_end)(struct nk_command_buffer *, nk_handle); -}; - -struct nk_style_knob { - /* background */ - struct nk_style_item normal; - struct nk_style_item hover; - struct nk_style_item active; - struct nk_color border_color; - - /* knob */ - struct nk_color knob_normal; - struct nk_color knob_hover; - struct nk_color knob_active; - struct nk_color knob_border_color; - - /* cursor */ - struct nk_color cursor_normal; - struct nk_color cursor_hover; - struct nk_color cursor_active; - - /* properties */ - float border; - float knob_border; - struct nk_vec2 padding; - struct nk_vec2 spacing; - float cursor_width; - float color_factor; - float disabled_factor; - - /* optional user callbacks */ - nk_handle userdata; - void (*draw_begin)(struct nk_command_buffer *, nk_handle); - void (*draw_end)(struct nk_command_buffer *, nk_handle); -}; - -struct nk_style_progress { - /* background */ - struct nk_style_item normal; - struct nk_style_item hover; - struct nk_style_item active; - struct nk_color border_color; - - /* cursor */ - struct nk_style_item cursor_normal; - struct nk_style_item cursor_hover; - struct nk_style_item cursor_active; - struct nk_color cursor_border_color; - - /* properties */ - float rounding; - float border; - float cursor_border; - float cursor_rounding; - struct nk_vec2 padding; - float color_factor; - float disabled_factor; - - /* optional user callbacks */ - nk_handle userdata; - void (*draw_begin)(struct nk_command_buffer *, nk_handle); - void (*draw_end)(struct nk_command_buffer *, nk_handle); -}; - -struct nk_style_scrollbar { - /* background */ - struct nk_style_item normal; - struct nk_style_item hover; - struct nk_style_item active; - struct nk_color border_color; - - /* cursor */ - struct nk_style_item cursor_normal; - struct nk_style_item cursor_hover; - struct nk_style_item cursor_active; - struct nk_color cursor_border_color; - - /* properties */ - float border; - float rounding; - float border_cursor; - float rounding_cursor; - struct nk_vec2 padding; - float cursor_min_size; - float color_factor; - float disabled_factor; - - /* optional buttons */ - int show_buttons; - struct nk_style_button inc_button; - struct nk_style_button dec_button; - enum nk_symbol_type inc_symbol; - enum nk_symbol_type dec_symbol; - - /* optional user callbacks */ - nk_handle userdata; - void (*draw_begin)(struct nk_command_buffer *, nk_handle); - void (*draw_end)(struct nk_command_buffer *, nk_handle); -}; - -struct nk_style_edit { - /* background */ - struct nk_style_item normal; - struct nk_style_item hover; - struct nk_style_item active; - struct nk_color border_color; - struct nk_style_scrollbar scrollbar; - - /* cursor */ - struct nk_color cursor_normal; - struct nk_color cursor_hover; - struct nk_color cursor_text_normal; - struct nk_color cursor_text_hover; - - /* text (unselected) */ - struct nk_color text_normal; - struct nk_color text_hover; - struct nk_color text_active; - - /* text (selected) */ - struct nk_color selected_normal; - struct nk_color selected_hover; - struct nk_color selected_text_normal; - struct nk_color selected_text_hover; - - /* properties */ - float border; - float rounding; - float cursor_size; - struct nk_vec2 scrollbar_size; - struct nk_vec2 padding; - float row_padding; - float color_factor; - float disabled_factor; -}; - -struct nk_style_property { - /* background */ - struct nk_style_item normal; - struct nk_style_item hover; - struct nk_style_item active; - struct nk_color border_color; - - /* text */ - struct nk_color label_normal; - struct nk_color label_hover; - struct nk_color label_active; - - /* symbols */ - enum nk_symbol_type sym_left; - enum nk_symbol_type sym_right; - - /* properties */ - float border; - float rounding; - struct nk_vec2 padding; - float color_factor; - float disabled_factor; - - struct nk_style_edit edit; - struct nk_style_button inc_button; - struct nk_style_button dec_button; - - /* optional user callbacks */ - nk_handle userdata; - void (*draw_begin)(struct nk_command_buffer *, nk_handle); - void (*draw_end)(struct nk_command_buffer *, nk_handle); -}; - -struct nk_style_chart { - /* colors */ - struct nk_style_item background; - struct nk_color border_color; - struct nk_color selected_color; - struct nk_color color; - - /* properties */ - float border; - float rounding; - struct nk_vec2 padding; - float color_factor; - float disabled_factor; - nk_bool show_markers; -}; - -struct nk_style_combo { - /* background */ - struct nk_style_item normal; - struct nk_style_item hover; - struct nk_style_item active; - struct nk_color border_color; - - /* label */ - struct nk_color label_normal; - struct nk_color label_hover; - struct nk_color label_active; - - /* symbol */ - struct nk_color symbol_normal; - struct nk_color symbol_hover; - struct nk_color symbol_active; - - /* button */ - struct nk_style_button button; - enum nk_symbol_type sym_normal; - enum nk_symbol_type sym_hover; - enum nk_symbol_type sym_active; - - /* properties */ - float border; - float rounding; - struct nk_vec2 content_padding; - struct nk_vec2 button_padding; - struct nk_vec2 spacing; - float color_factor; - float disabled_factor; -}; - -struct nk_style_tab { - /* background */ - struct nk_style_item background; - struct nk_color border_color; - struct nk_color text; - - /* button */ - struct nk_style_button tab_maximize_button; - struct nk_style_button tab_minimize_button; - struct nk_style_button node_maximize_button; - struct nk_style_button node_minimize_button; - enum nk_symbol_type sym_minimize; - enum nk_symbol_type sym_maximize; - - /* properties */ - float border; - float rounding; - float indent; - struct nk_vec2 padding; - struct nk_vec2 spacing; - float color_factor; - float disabled_factor; -}; - -enum nk_style_header_align { NK_HEADER_LEFT, NK_HEADER_RIGHT }; -struct nk_style_window_header { - /* background */ - struct nk_style_item normal; - struct nk_style_item hover; - struct nk_style_item active; - - /* button */ - struct nk_style_button close_button; - struct nk_style_button minimize_button; - enum nk_symbol_type close_symbol; - enum nk_symbol_type minimize_symbol; - enum nk_symbol_type maximize_symbol; - - /* title */ - struct nk_color label_normal; - struct nk_color label_hover; - struct nk_color label_active; - - /* properties */ - enum nk_style_header_align align; - struct nk_vec2 padding; - struct nk_vec2 label_padding; - struct nk_vec2 spacing; -}; - -struct nk_style_window { - struct nk_style_window_header header; - struct nk_style_item fixed_background; - struct nk_color background; - - struct nk_color border_color; - struct nk_color popup_border_color; - struct nk_color combo_border_color; - struct nk_color contextual_border_color; - struct nk_color menu_border_color; - struct nk_color group_border_color; - struct nk_color tooltip_border_color; - struct nk_style_item scaler; - - float border; - float combo_border; - float contextual_border; - float menu_border; - float group_border; - float tooltip_border; - float popup_border; - float min_row_height_padding; - - float rounding; - struct nk_vec2 spacing; - struct nk_vec2 scrollbar_size; - struct nk_vec2 min_size; - - struct nk_vec2 padding; - struct nk_vec2 group_padding; - struct nk_vec2 popup_padding; - struct nk_vec2 combo_padding; - struct nk_vec2 contextual_padding; - struct nk_vec2 menu_padding; - struct nk_vec2 tooltip_padding; - - enum nk_tooltip_pos tooltip_origin; - struct nk_vec2 tooltip_offset; -}; - -struct nk_style { - const struct nk_user_font *font; - float font_size; - const struct nk_cursor *cursors[NK_CURSOR_COUNT]; - const struct nk_cursor *cursor_active; - struct nk_cursor *cursor_last; - int cursor_visible; - - struct nk_style_text text; - struct nk_style_button button; - struct nk_style_button contextual_button; - struct nk_style_button menu_button; - struct nk_style_toggle option; - struct nk_style_toggle checkbox; - struct nk_style_selectable selectable; - struct nk_style_slider slider; - struct nk_style_knob knob; - struct nk_style_progress progress; - struct nk_style_property property; - struct nk_style_edit edit; - struct nk_style_chart chart; - struct nk_style_scrollbar scrollh; - struct nk_style_scrollbar scrollv; - struct nk_style_tab tab; - struct nk_style_combo combo; - struct nk_style_window window; -}; - -NK_API struct nk_style_item nk_style_item_color(struct nk_color); -NK_API struct nk_style_item -nk_style_item_image(struct nk_image img); -NK_API struct nk_style_item -nk_style_item_nine_slice(struct nk_nine_slice slice); -NK_API struct nk_style_item -nk_style_item_hide(void); - -/*============================================================== - * PANEL - * =============================================================*/ -#ifndef NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS -# define NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS 16 -#endif -#ifndef NK_CHART_MAX_SLOT -# define NK_CHART_MAX_SLOT 4 -#endif - -enum nk_panel_type { - NK_PANEL_NONE = 0, - NK_PANEL_WINDOW = NK_FLAG(0), - NK_PANEL_GROUP = NK_FLAG(1), - NK_PANEL_POPUP = NK_FLAG(2), - NK_PANEL_CONTEXTUAL = NK_FLAG(4), - NK_PANEL_COMBO = NK_FLAG(5), - NK_PANEL_MENU = NK_FLAG(6), - NK_PANEL_TOOLTIP = NK_FLAG(7) -}; -enum nk_panel_set { - NK_PANEL_SET_NONBLOCK = NK_PANEL_CONTEXTUAL | NK_PANEL_COMBO | NK_PANEL_MENU | NK_PANEL_TOOLTIP, - NK_PANEL_SET_POPUP = NK_PANEL_CONTEXTUAL | NK_PANEL_COMBO | NK_PANEL_MENU | NK_PANEL_TOOLTIP | NK_PANEL_POPUP, - NK_PANEL_SET_SUB = NK_PANEL_CONTEXTUAL | NK_PANEL_COMBO | NK_PANEL_MENU | NK_PANEL_TOOLTIP | NK_PANEL_POPUP | NK_PANEL_GROUP, -}; - -struct nk_chart_slot { - enum nk_chart_type type; - struct nk_color color; - struct nk_color highlight; - float min, max, range; - int count; - struct nk_vec2 last; - int index; - nk_bool show_markers; -}; - -struct nk_chart { - int slot; - float x, y, w, h; - struct nk_chart_slot slots[NK_CHART_MAX_SLOT]; -}; - -enum nk_panel_row_layout_type { - NK_LAYOUT_DYNAMIC_FIXED = 0, - NK_LAYOUT_DYNAMIC_ROW, - NK_LAYOUT_DYNAMIC_FREE, - NK_LAYOUT_DYNAMIC, - NK_LAYOUT_STATIC_FIXED, - NK_LAYOUT_STATIC_ROW, - NK_LAYOUT_STATIC_FREE, - NK_LAYOUT_STATIC, - NK_LAYOUT_TEMPLATE, - NK_LAYOUT_COUNT -}; -struct nk_row_layout { - enum nk_panel_row_layout_type type; - int index; - float height; - float min_height; - int columns; - const float *ratio; - float item_width; - float item_height; - float item_offset; - float filled; - struct nk_rect item; - int tree_depth; - float templates[NK_MAX_LAYOUT_ROW_TEMPLATE_COLUMNS]; -}; - -struct nk_popup_buffer { - nk_size begin; - nk_size parent; - nk_size last; - nk_size end; - nk_bool active; -}; - -struct nk_menu_state { - float x, y, w, h; - struct nk_scroll offset; -}; - -struct nk_panel { - enum nk_panel_type type; - nk_flags flags; - struct nk_rect bounds; - nk_uint *offset_x; - nk_uint *offset_y; - nk_uint *prev_max_x; - nk_uint *prev_max_y; - nk_uint *scroll_flags; - float at_x, at_y, max_x; - float footer_height; - float header_height; - float border; - unsigned int has_scrolling; - struct nk_rect clip; - struct nk_menu_state menu; - struct nk_row_layout row; - struct nk_chart chart; - struct nk_command_buffer *buffer; - struct nk_panel *parent; - struct nk_text_selection_context text_selection; - nk_hash text_selection_scope; - nk_bool text_selection_loaded; -}; - -/*============================================================== - * WINDOW - * =============================================================*/ -#ifndef NK_WINDOW_MAX_NAME -# define NK_WINDOW_MAX_NAME 64 -#endif - -struct nk_table; - -enum nk_window_flags { - NK_WINDOW_PRIVATE = NK_FLAG(14), - NK_WINDOW_DYNAMIC = NK_WINDOW_PRIVATE, /**< special window type growing up in height while being filled to a certain maximum height */ - NK_WINDOW_ROM = NK_FLAG(15), /**< sets window widgets into a read only mode and does not allow input changes */ - NK_WINDOW_NOT_INTERACTIVE = NK_FLAG(15) | NK_FLAG(12), /**< prevents all interaction caused by input to either window or widgets inside */ - NK_WINDOW_HIDDEN = NK_FLAG(16), /**< Hides window and stops any window interaction and drawing */ - NK_WINDOW_CLOSED = NK_FLAG(17), /**< Directly closes and frees the window at the end of the frame */ - NK_WINDOW_MINIMIZED = NK_FLAG(18), /**< marks the window as minimized */ - NK_WINDOW_MAXIMIZED = NK_FLAG(19), /**< marks the window as maximized */ - NK_WINDOW_REMOVE_ROM = NK_FLAG(20), /**< Removes read only mode at the end of the window */ -}; - -struct nk_popup_state { - struct nk_window *win; - enum nk_panel_type type; - struct nk_popup_buffer buf; - nk_hash name; - nk_bool active; - unsigned combo_count; - unsigned con_count, con_old; - unsigned active_con; - struct nk_rect header; -}; - -struct nk_edit_state { - nk_hash name; - unsigned int seq; - unsigned int old; - int active, prev; - int cursor; - int sel_start; - int sel_end; - struct nk_scroll scrollbar; - unsigned char mode; - unsigned char single_line; -}; - -struct nk_property_state { - int active, prev; - char buffer[NK_MAX_NUMBER_BUFFER]; - int length; - int cursor; - int select_start; - int select_end; - nk_hash name; - unsigned int seq; - unsigned int old; - int state; - int prev_state; - nk_hash prev_name; - char prev_buffer[NK_MAX_NUMBER_BUFFER]; - int prev_length; -}; - -struct nk_window { - unsigned int seq; - nk_hash name; - char name_string[NK_WINDOW_MAX_NAME]; - nk_flags flags; - - struct nk_rect bounds; - struct nk_rect restore_bounds; - struct nk_scroll scrollbar; - struct nk_command_buffer buffer; - struct nk_panel *layout; - float scrollbar_hiding_timer; - - /* persistent widget state */ - struct nk_property_state property; - struct nk_popup_state popup; - struct nk_edit_state edit; - unsigned int scrolled; - nk_bool widgets_disabled; - - struct nk_table *tables; - unsigned int table_count; - - /* window list hooks */ - struct nk_window *next; - struct nk_window *prev; - struct nk_window *parent; -}; - -/*============================================================== - * STACK - * =============================================================*/ -/** - * \page Stack - * The style modifier stack can be used to temporarily change a - * property inside `nk_style`. For example if you want a special - * red button you can temporarily push the old button color onto a stack - * draw the button with a red color and then you just pop the old color - * back from the stack: - * - * nk_style_push_style_item(ctx, &ctx->style.button.normal, nk_style_item_color(nk_rgb(255,0,0))); - * nk_style_push_style_item(ctx, &ctx->style.button.hover, nk_style_item_color(nk_rgb(255,0,0))); - * nk_style_push_style_item(ctx, &ctx->style.button.active, nk_style_item_color(nk_rgb(255,0,0))); - * nk_style_push_vec2(ctx, &cx->style.button.padding, nk_vec2(2,2)); - * - * nk_button(...); - * - * nk_style_pop_style_item(ctx); - * nk_style_pop_style_item(ctx); - * nk_style_pop_style_item(ctx); - * nk_style_pop_vec2(ctx); - * - * Nuklear has a stack for style_items, float properties, vector properties, - * flags, colors, fonts and for button_behavior. Each has it's own fixed size stack - * which can be changed at compile time. - */ - -#ifndef NK_BUTTON_BEHAVIOR_STACK_SIZE -# define NK_BUTTON_BEHAVIOR_STACK_SIZE 8 -#endif - -#ifndef NK_FONT_STACK_SIZE -# define NK_FONT_STACK_SIZE 8 -#endif - -#ifndef NK_STYLE_ITEM_STACK_SIZE -# define NK_STYLE_ITEM_STACK_SIZE 16 -#endif - -#ifndef NK_FLOAT_STACK_SIZE -# define NK_FLOAT_STACK_SIZE 32 -#endif - -#ifndef NK_VECTOR_STACK_SIZE -# define NK_VECTOR_STACK_SIZE 16 -#endif - -#ifndef NK_FLAGS_STACK_SIZE -# define NK_FLAGS_STACK_SIZE 32 -#endif - -#ifndef NK_COLOR_STACK_SIZE -# define NK_COLOR_STACK_SIZE 32 -#endif - -#define NK_CONFIGURATION_STACK_TYPE(prefix, name, type) \ - struct nk_config_stack_##name##_element { \ - prefix##_##type *address; \ - prefix##_##type old_value; \ - } -#define NK_CONFIG_STACK(type, size) \ - struct nk_config_stack_##type { \ - int head; \ - struct nk_config_stack_##type##_element elements[size]; \ - } - -#define nk_float float -NK_CONFIGURATION_STACK_TYPE(struct nk, style_item, style_item); -NK_CONFIGURATION_STACK_TYPE(nk, float, float); -NK_CONFIGURATION_STACK_TYPE(struct nk, vec2, vec2); -NK_CONFIGURATION_STACK_TYPE(nk, flags, flags); -NK_CONFIGURATION_STACK_TYPE(struct nk, color, color); -NK_CONFIGURATION_STACK_TYPE(const struct nk, user_font, user_font *); -NK_CONFIGURATION_STACK_TYPE(enum nk, button_behavior, button_behavior); - -NK_CONFIG_STACK(style_item, NK_STYLE_ITEM_STACK_SIZE); -NK_CONFIG_STACK(float, NK_FLOAT_STACK_SIZE); -NK_CONFIG_STACK(vec2, NK_VECTOR_STACK_SIZE); -NK_CONFIG_STACK(flags, NK_FLAGS_STACK_SIZE); -NK_CONFIG_STACK(color, NK_COLOR_STACK_SIZE); -NK_CONFIG_STACK(user_font, NK_FONT_STACK_SIZE); -NK_CONFIG_STACK(button_behavior, NK_BUTTON_BEHAVIOR_STACK_SIZE); - -struct nk_configuration_stacks { - struct nk_config_stack_style_item style_items; - struct nk_config_stack_float floats; - struct nk_config_stack_vec2 vectors; - struct nk_config_stack_flags flags; - struct nk_config_stack_color colors; - struct nk_config_stack_user_font fonts; - struct nk_config_stack_button_behavior button_behaviors; -}; - -/*============================================================== - * CONTEXT - * =============================================================*/ -#define NK_VALUE_PAGE_CAPACITY (((NK_MAX(sizeof(struct nk_window), sizeof(struct nk_panel)) / sizeof(nk_uint))) / 2) - -struct nk_table { - unsigned int seq; - unsigned int size; - nk_hash keys[NK_VALUE_PAGE_CAPACITY]; - nk_uint values[NK_VALUE_PAGE_CAPACITY]; - struct nk_table *next, *prev; -}; - -union nk_page_data { - struct nk_table tbl; - struct nk_panel pan; - struct nk_window win; -}; - -struct nk_page_element { - union nk_page_data data; - struct nk_page_element *next; - struct nk_page_element *prev; -}; - -struct nk_page { - unsigned int size; - struct nk_page *next; - struct nk_page_element win[1]; -}; - -struct nk_pool { - struct nk_allocator alloc; - enum nk_allocation_type type; - unsigned int page_count; - struct nk_page *pages; - struct nk_page_element *freelist; - unsigned capacity; - nk_size size; - nk_size cap; -}; - -struct nk_context { - /* public: can be accessed freely */ - struct nk_input input; - struct nk_style style; - struct nk_buffer memory; - struct nk_clipboard clip; - nk_flags last_widget_state; - enum nk_button_behavior button_behavior; - struct nk_configuration_stacks stacks; - float delta_time_seconds; - -/* private: - should only be accessed if you - know what you are doing */ -#ifdef NK_INCLUDE_VERTEX_BUFFER_OUTPUT - struct nk_draw_list draw_list; -#endif -#ifdef NK_INCLUDE_COMMAND_USERDATA - nk_handle userdata; -#endif - /** text editor objects are quite big because of an internal - * undo/redo stack. Therefore it does not make sense to have one for - * each window for temporary use cases, so I only provide *one* instance - * for all windows. This works because the content is cleared anyway */ - struct nk_text_edit text_edit; - /** draw buffer used for overlay drawing operation like cursor */ - struct nk_command_buffer overlay; - - /** optional fixed measurement and shaped-text cache, carved from nk_init_fixed memory */ - struct nk_buffer text_cache; - struct nk_text_cache_entry **text_cache_buckets; - struct nk_text_backend text_backend; - nk_bool text_memory_initialized; - - struct nk_rect window_maximize_bounds; - - /** windows */ - int build; - int use_pool; - struct nk_pool pool; - struct nk_window *begin; - struct nk_window *end; - struct nk_window *active; - struct nk_window *current; - struct nk_page_element *freelist; - unsigned int count; - unsigned int seq; -}; - -/* ============================================================== - * MATH - * =============================================================== */ -#define NK_PI 3.141592654f -#define NK_PI_HALF 1.570796326f -#define NK_UTF_INVALID 0xFFFD -#define NK_MAX_FLOAT_PRECISION 2 - -#define NK_UNUSED(x) ((void)(x)) -#define NK_SATURATE(x) (NK_MAX(0, NK_MIN(1.0f, x))) -#define NK_LEN(a) (sizeof(a) / sizeof(a)[0]) -#define NK_ABS(a) (((a) < 0) ? -(a) : (a)) -#define NK_BETWEEN(x, a, b) ((a) <= (x) && (x) < (b)) -#define NK_INBOX(px, py, x, y, w, h) (NK_BETWEEN(px, x, x + w) && NK_BETWEEN(py, y, y + h)) -#define NK_INTERSECT(x0, y0, w0, h0, x1, y1, w1, h1) \ - ((x1 < (x0 + w0)) && (x0 < (x1 + w1)) && (y1 < (y0 + h0)) && (y0 < (y1 + h1))) -#define NK_CONTAINS(x, y, w, h, bx, by, bw, bh) \ - (NK_INBOX(x, y, bx, by, bw, bh) && NK_INBOX(x + w, y + h, bx, by, bw, bh)) - -#define nk_vec2_sub(a, b) nk_vec2((a).x - (b).x, (a).y - (b).y) -#define nk_vec2_add(a, b) nk_vec2((a).x + (b).x, (a).y + (b).y) -#define nk_vec2_len_sqr(a) ((a).x * (a).x + (a).y * (a).y) -#define nk_vec2_muls(a, t) nk_vec2((a).x *(t), (a).y *(t)) - -#define nk_ptr_add(t, p, i) ((t *)((void *)((nk_byte *)(p) + (i)))) -#define nk_ptr_add_const(t, p, i) ((const t *)((const void *)((const nk_byte *)(p) + (i)))) -#define nk_zero_struct(s) nk_zero(&s, sizeof(s)) - -/* ============================================================== - * ALIGNMENT - * =============================================================== */ -/* Pointer to Integer type conversion for pointer alignment */ -#if defined(__PTRDIFF_TYPE__) /* This case should work for GCC*/ -# define NK_UINT_TO_PTR(x) ((void *)(__PTRDIFF_TYPE__)(x)) -# define NK_PTR_TO_UINT(x) ((nk_size)(__PTRDIFF_TYPE__)(x)) -#elif !defined(__GNUC__) /* works for compilers other than LLVM */ -# define NK_UINT_TO_PTR(x) ((void *)&((char *)0)[x]) -# define NK_PTR_TO_UINT(x) ((nk_size)(((char *)x) - (char *)0)) -#elif defined(NK_USE_FIXED_TYPES) /* used if we have */ -# define NK_UINT_TO_PTR(x) ((void *)(uintptr_t)(x)) -# define NK_PTR_TO_UINT(x) ((uintptr_t)(x)) -#else /* generates warning but works */ -# define NK_UINT_TO_PTR(x) ((void *)(x)) -# define NK_PTR_TO_UINT(x) ((nk_size)(x)) -#endif - -#define NK_ALIGN_PTR(x, mask) (NK_UINT_TO_PTR((NK_PTR_TO_UINT((nk_byte *)(x) + (mask - 1)) & ~(mask - 1)))) -#define NK_ALIGN_PTR_BACK(x, mask) (NK_UINT_TO_PTR((NK_PTR_TO_UINT((nk_byte *)(x)) & ~(mask - 1)))) - -#if ((defined(__GNUC__) && __GNUC__ >= 4) || defined(__clang__)) && !defined(EMSCRIPTEN) -# define NK_OFFSETOF(st, m) (__builtin_offsetof(st, m)) -#else -# define NK_OFFSETOF(st, m) ((nk_ptr) & (((st *)0)->m)) -#endif - -#ifdef __cplusplus -} -#endif - -#if defined(_MSC_VER) && !defined(__cplusplus) -# define NK_ALIGNOF(t) __alignof(t) -#elif defined(__cplusplus) -template struct nk_alignof; -template struct nk_helper { - enum { value = size_diff }; -}; -template struct nk_helper { - enum { value = nk_alignof::value }; -}; -template struct nk_alignof { - struct Big { - T x; - char c; - }; - enum { diff = sizeof(Big) - sizeof(T), value = nk_helper::value }; -}; -# define NK_ALIGNOF(t) (nk_alignof::value) -#else -# define NK_ALIGNOF(t) \ - NK_OFFSETOF( \ - struct { \ - char c; \ - t _h; \ - }, \ - _h) -#endif - -#define NK_CONTAINER_OF(ptr, type, member) \ - (type *)((void *)((char *)(1 ? (ptr) : &((type *)0)->member) - NK_OFFSETOF(type, member))) - -/* NK_INTERNAL_H */ - -#ifndef NK_POOL_DEFAULT_CAPACITY -# define NK_POOL_DEFAULT_CAPACITY 16 -#endif - -#ifndef NK_DEFAULT_COMMAND_BUFFER_SIZE -# define NK_DEFAULT_COMMAND_BUFFER_SIZE (4 * 1024) -#endif - -#ifndef NK_BUFFER_DEFAULT_INITIAL_SIZE -# define NK_BUFFER_DEFAULT_INITIAL_SIZE (4 * 1024) -#endif - -/* standard library headers */ -#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR -# include /* malloc, free */ -#endif -#ifdef NK_INCLUDE_STANDARD_IO -# include /* fopen, fclose,... */ -#endif -#ifdef NK_INCLUDE_STANDARD_VARARGS -# include /* valist, va_start, va_end, ... */ -#endif -#ifndef NK_ASSERT -# include -# define NK_ASSERT(expr) assert(expr) -#endif - -#define NK_DEFAULT (-1) - -#ifndef NK_VSNPRINTF -/* If your compiler does support `vsnprintf` I would highly recommend - * defining this to vsnprintf instead since `vsprintf` is basically - * unbelievable unsafe and should *NEVER* be used. But I have to support - * it since C89 only provides this unsafe version. */ -# if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ - (defined(__cplusplus) && (__cplusplus >= 201103L)) || \ - (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200112L)) || \ - (defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)) || defined(_ISOC99_SOURCE) || defined(_BSD_SOURCE) -# define NK_VSNPRINTF(s, n, f, a) vsnprintf(s, n, f, a) -# else -# define NK_VSNPRINTF(s, n, f, a) vsprintf(s, f, a) -# endif -#endif - -#define NK_SCHAR_MIN (-127) -#define NK_SCHAR_MAX 127 -#define NK_UCHAR_MIN 0 -#define NK_UCHAR_MAX 256 -#define NK_SSHORT_MIN (-32767) -#define NK_SSHORT_MAX 32767 -#define NK_USHORT_MIN 0 -#define NK_USHORT_MAX 65535 -#define NK_SINT_MIN (-2147483647) -#define NK_SINT_MAX 2147483647 -#define NK_UINT_MIN 0 -#define NK_UINT_MAX 4294967295u - -/* Make sure correct type size: - * This will fire with a negative subscript error if the type sizes - * are set incorrectly by the compiler, and compile out if not */ -NK_STATIC_ASSERT(sizeof(nk_size) >= sizeof(void *)); -NK_STATIC_ASSERT(sizeof(nk_ptr) == sizeof(void *)); -NK_STATIC_ASSERT(sizeof(nk_flags) >= 4); -NK_STATIC_ASSERT(sizeof(nk_rune) >= 4); -NK_STATIC_ASSERT(sizeof(nk_ushort) == 2); -NK_STATIC_ASSERT(sizeof(nk_short) == 2); -NK_STATIC_ASSERT(sizeof(nk_uint) == 4); -NK_STATIC_ASSERT(sizeof(nk_int) == 4); -NK_STATIC_ASSERT(sizeof(nk_byte) == 1); -NK_STATIC_ASSERT(sizeof(nk_bool) <= sizeof(int)); - -NK_GLOBAL const struct nk_rect nk_null_rect = {-8192.0f, -8192.0f, 16384, 16384}; -#define NK_FLOAT_PRECISION 0.00000000000001 - -NK_GLOBAL const struct nk_color nk_red = {255, 0, 0, 255}; -NK_GLOBAL const struct nk_color nk_green = {0, 255, 0, 255}; -NK_GLOBAL const struct nk_color nk_blue = {0, 0, 255, 255}; -NK_GLOBAL const struct nk_color nk_white = {255, 255, 255, 255}; -NK_GLOBAL const struct nk_color nk_black = {0, 0, 0, 255}; -NK_GLOBAL const struct nk_color nk_yellow = {255, 255, 0, 255}; - -/* widget */ -#define nk_widget_state_reset(s) \ - if ((*(s)) & NK_WIDGET_STATE_MODIFIED) \ - (*(s)) = NK_WIDGET_STATE_INACTIVE | NK_WIDGET_STATE_MODIFIED; \ - else \ - (*(s)) = NK_WIDGET_STATE_INACTIVE; - -/* math */ -#ifndef NK_INV_SQRT -# define NK_INV_SQRT nk_inv_sqrt -# define NK_INV_SQRT_NEEDED -NK_LIB float -nk_inv_sqrt(float n); -#endif -#ifndef NK_SIN -# define NK_SIN nk_sin -# define NK_SIN_NEEDED -NK_LIB float -nk_sin(float x); -#endif -#ifndef NK_COS -# define NK_COS nk_cos -# define NK_COS_NEEDED -NK_LIB float -nk_cos(float x); -#endif -#ifndef NK_ATAN -# define NK_ATAN nk_atan -# define NK_ATAN_NEEDED -NK_LIB float -nk_atan(float x); -#endif -#ifndef NK_ATAN2 -# define NK_ATAN2 nk_atan2 -# define NK_ATAN2_NEEDED -NK_LIB float -nk_atan2(float y, float x); -#endif -NK_LIB nk_uint -nk_round_up_pow2(nk_uint v); -NK_LIB struct nk_rect -nk_shrink_rect(struct nk_rect r, float amount); -NK_LIB struct nk_rect -nk_pad_rect(struct nk_rect r, struct nk_vec2 pad); -NK_LIB void -nk_unify(struct nk_rect *clip, const struct nk_rect *a, float x0, float y0, float x1, float y1); -NK_LIB int -nk_ifloorf(float x); -NK_LIB int -nk_iceilf(float x); -NK_LIB float -nk_roundf(float x); - -/* util */ -enum { NK_DO_NOT_STOP_ON_NEW_LINE, NK_STOP_ON_NEW_LINE }; -NK_LIB nk_bool -nk_is_lower(int c); -NK_LIB nk_bool -nk_is_upper(int c); -NK_LIB int -nk_to_upper(int c); -NK_LIB int -nk_to_lower(int c); - -#ifndef NK_MEMCPY -# define NK_MEMCPY nk_memcopy -# define NK_MEMCPY_NEEDED -NK_LIB void * -nk_memcopy(void *dst, const void *src, nk_size n); -#endif -#ifndef NK_MEMSET -# define NK_MEMSET nk_memset -# define NK_MEMSET_NEEDED -NK_LIB void -nk_memset(void *ptr, int c0, nk_size size); -#endif -NK_LIB void -nk_zero(void *ptr, nk_size size); -NK_LIB char * -nk_itoa(char *s, long n); -NK_LIB int -nk_string_float_limit(char *string, int prec); -#ifndef NK_DTOA -# define NK_DTOA nk_dtoa -# define NK_DTOA_NEEDED -NK_LIB char * -nk_dtoa(char *s, double n); -#endif -NK_LIB int -nk_text_clamp(struct nk_context *ctx, - const struct nk_user_font *font, - const char *text, - int text_len, - float space, - int *glyphs, - float *text_width, - nk_rune *sep_list, - int sep_count); -NK_LIB struct nk_vec2 -nk_text_calculate_text_bounds(struct nk_context *ctx, - const struct nk_user_font *font, - const char *begin, - int byte_len, - float row_height, - const char **remaining, - struct nk_vec2 *out_offset, - int *glyphs, - int op); -#ifdef NK_INCLUDE_STANDARD_VARARGS -NK_LIB int -nk_strfmt(char *buf, int buf_size, const char *fmt, va_list args); -#endif -#ifdef NK_INCLUDE_STANDARD_IO -NK_LIB char * -nk_file_load(const char *path, nk_size *siz, const struct nk_allocator *alloc); -#endif - -/* math helpers that are only used by nk_dtoa */ -#ifdef NK_DTOA_NEEDED -NK_LIB double -nk_pow(double x, int n); -NK_LIB int -nk_ifloord(double x); -NK_LIB int -nk_log10(double n); -#endif - -/* buffer */ -#ifdef NK_INCLUDE_DEFAULT_ALLOCATOR -NK_LIB void * -nk_malloc(nk_handle unused, void *old, nk_size size); -NK_LIB void -nk_mfree(nk_handle unused, void *ptr); -#endif -NK_LIB void * -nk_buffer_align(void *unaligned, nk_size align, nk_size *alignment, enum nk_buffer_allocation_type type); -NK_LIB void * -nk_buffer_alloc(struct nk_buffer *b, enum nk_buffer_allocation_type type, nk_size size, nk_size align); -NK_LIB void * -nk_buffer_realloc(struct nk_buffer *b, nk_size capacity, nk_size *size); - -/* draw */ -NK_LIB void -nk_command_buffer_init(struct nk_command_buffer *cb, struct nk_buffer *b, enum nk_command_clipping clip); -NK_LIB void -nk_command_buffer_reset(struct nk_command_buffer *b); -NK_LIB void * -nk_command_buffer_push(struct nk_command_buffer *b, enum nk_command_type t, nk_size size); -NK_LIB void -nk_draw_symbol(struct nk_command_buffer *out, - enum nk_symbol_type type, - struct nk_rect content, - struct nk_color background, - struct nk_color foreground, - float border_width, - const struct nk_user_font *font); - -/* buffering */ -NK_LIB void -nk_start_buffer(struct nk_context *ctx, struct nk_command_buffer *b); -NK_LIB void -nk_start(struct nk_context *ctx, struct nk_window *win); -NK_LIB void -nk_start_popup(struct nk_context *ctx, struct nk_window *win); -NK_LIB void -nk_finish_popup(struct nk_context *ctx, struct nk_window *); -NK_LIB void -nk_finish_buffer(struct nk_context *ctx, struct nk_command_buffer *b); -NK_LIB void -nk_finish(struct nk_context *ctx, struct nk_window *w); -NK_LIB void -nk_build(struct nk_context *ctx); - -/* text editor */ -NK_LIB void -nk_textedit_clear_state(struct nk_text_edit *state, enum nk_text_edit_type type, nk_plugin_filter filter); -NK_LIB void -nk_textedit_click(struct nk_text_edit *state, float x, float y, const struct nk_user_font *font, float row_height); -NK_LIB void -nk_textedit_drag(struct nk_text_edit *state, float x, float y, const struct nk_user_font *font, float row_height); -NK_LIB void -nk_textedit_key( - struct nk_text_edit *state, enum nk_keys key, int shift_mod, const struct nk_user_font *font, float row_height); - -/* window */ -enum nk_window_insert_location { - NK_INSERT_BACK, /* inserts window into the back of list (front of screen) */ - NK_INSERT_FRONT /* inserts window into the front of list (back of screen) */ -}; -NK_LIB void * -nk_create_window(struct nk_context *ctx); -NK_LIB void -nk_remove_window(struct nk_context *, struct nk_window *); -NK_LIB void -nk_free_window(struct nk_context *ctx, struct nk_window *win); -NK_LIB struct nk_window * -nk_find_window(const struct nk_context *ctx, nk_hash hash, const char *name); -NK_LIB void -nk_insert_window(struct nk_context *ctx, struct nk_window *win, enum nk_window_insert_location loc); - -/* pool */ -NK_LIB void -nk_pool_init(struct nk_pool *pool, const struct nk_allocator *alloc, unsigned int capacity); -NK_LIB void -nk_pool_free(struct nk_pool *pool); -NK_LIB void -nk_pool_init_fixed(struct nk_pool *pool, void *memory, nk_size size); -NK_LIB struct nk_page_element * -nk_pool_alloc(struct nk_pool *pool); - -/* page-element */ -NK_LIB struct nk_page_element * -nk_create_page_element(struct nk_context *ctx); -NK_LIB void -nk_link_page_element_into_freelist(struct nk_context *ctx, struct nk_page_element *elem); -NK_LIB void -nk_free_page_element(struct nk_context *ctx, struct nk_page_element *elem); - -/* table */ -NK_LIB struct nk_table * -nk_create_table(struct nk_context *ctx); -NK_LIB void -nk_remove_table(struct nk_window *win, struct nk_table *tbl); -NK_LIB void -nk_free_table(struct nk_context *ctx, struct nk_table *tbl); -NK_LIB void -nk_push_table(struct nk_window *win, struct nk_table *tbl); -NK_LIB nk_uint * -nk_add_value(struct nk_context *ctx, struct nk_window *win, nk_hash name, nk_uint value); -NK_LIB nk_uint * -nk_find_value(const struct nk_window *win, nk_hash name); - -/* panel */ -NK_LIB void * -nk_create_panel(struct nk_context *ctx); -NK_LIB void -nk_free_panel(struct nk_context *, struct nk_panel *pan); -NK_LIB nk_bool -nk_panel_has_header(nk_flags flags, const char *title); -NK_LIB struct nk_vec2 -nk_panel_get_padding(const struct nk_style *style, enum nk_panel_type type); -NK_LIB float -nk_panel_get_border(const struct nk_style *style, nk_flags flags, enum nk_panel_type type); -NK_LIB struct nk_color -nk_panel_get_border_color(const struct nk_style *style, enum nk_panel_type type); -NK_LIB nk_bool -nk_panel_is_sub(enum nk_panel_type type); -NK_LIB nk_bool -nk_panel_is_nonblock(enum nk_panel_type type); -NK_LIB nk_bool -nk_panel_begin(struct nk_context *ctx, const char *title, enum nk_panel_type panel_type); -NK_LIB void -nk_panel_end(struct nk_context *ctx); - -/* layout */ -NK_LIB float -nk_layout_row_calculate_usable_space(const struct nk_style *style, - enum nk_panel_type type, - float total_space, - int columns); -NK_LIB void -nk_panel_layout(const struct nk_context *ctx, struct nk_window *win, float height, int cols); -NK_LIB void -nk_row_layout(struct nk_context *ctx, enum nk_layout_format fmt, float height, int cols, int width); -NK_LIB void -nk_panel_alloc_row(const struct nk_context *ctx, struct nk_window *win); -NK_LIB void -nk_layout_widget_space(struct nk_rect *bounds, const struct nk_context *ctx, struct nk_window *win, int modify); -NK_LIB void -nk_panel_alloc_space(struct nk_rect *bounds, const struct nk_context *ctx); -NK_LIB void -nk_layout_peek(struct nk_rect *bounds, const struct nk_context *ctx); - -/* popup */ -NK_LIB nk_bool -nk_nonblock_begin( - struct nk_context *ctx, nk_flags flags, struct nk_rect body, struct nk_rect header, enum nk_panel_type panel_type); - -/* text */ -struct nk_text { - struct nk_vec2 padding; - struct nk_color background; - struct nk_color text; -}; -NK_LIB void -nk_widget_text(struct nk_command_buffer *o, - struct nk_rect b, - const char *string, - int len, - const struct nk_text *t, - nk_flags a, - const struct nk_user_font *f); -NK_LIB void -nk_widget_text_wrap(struct nk_command_buffer *o, - struct nk_rect b, - const char *string, - int len, - const struct nk_text *t, - const struct nk_user_font *f); - -/* button */ -NK_LIB nk_bool -nk_button_behavior(nk_flags *state, struct nk_rect r, const struct nk_input *i, enum nk_button_behavior behavior); -NK_LIB const struct nk_style_item * -nk_draw_button(struct nk_command_buffer *out, - const struct nk_rect *bounds, - nk_flags state, - const struct nk_style_button *style); -NK_LIB nk_bool -nk_do_button(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect r, - const struct nk_style_button *style, - const struct nk_input *in, - enum nk_button_behavior behavior, - struct nk_rect *content); -NK_LIB void -nk_draw_button_text(struct nk_command_buffer *out, - const struct nk_rect *bounds, - const struct nk_rect *content, - nk_flags state, - const struct nk_style_button *style, - const char *txt, - int len, - nk_flags text_alignment, - const struct nk_user_font *font); -NK_LIB nk_bool -nk_do_button_text(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect bounds, - const char *string, - int len, - nk_flags align, - enum nk_button_behavior behavior, - const struct nk_style_button *style, - const struct nk_input *in, - const struct nk_user_font *font); -NK_LIB void -nk_draw_button_symbol(struct nk_command_buffer *out, - const struct nk_rect *bounds, - const struct nk_rect *content, - nk_flags state, - const struct nk_style_button *style, - enum nk_symbol_type type, - const struct nk_user_font *font); -NK_LIB nk_bool -nk_do_button_symbol(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect bounds, - enum nk_symbol_type symbol, - enum nk_button_behavior behavior, - const struct nk_style_button *style, - const struct nk_input *in, - const struct nk_user_font *font); -NK_LIB void -nk_draw_button_image(struct nk_command_buffer *out, - const struct nk_rect *bounds, - const struct nk_rect *content, - nk_flags state, - const struct nk_style_button *style, - const struct nk_image *img); -NK_LIB nk_bool -nk_do_button_image(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect bounds, - struct nk_image img, - enum nk_button_behavior b, - const struct nk_style_button *style, - const struct nk_input *in); -NK_LIB void -nk_draw_button_text_symbol(struct nk_command_buffer *out, - const struct nk_rect *bounds, - const struct nk_rect *label, - const struct nk_rect *symbol, - nk_flags state, - const struct nk_style_button *style, - const char *str, - int len, - enum nk_symbol_type type, - const struct nk_user_font *font); -NK_LIB nk_bool -nk_do_button_text_symbol(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect bounds, - enum nk_symbol_type symbol, - const char *str, - int len, - nk_flags align, - enum nk_button_behavior behavior, - const struct nk_style_button *style, - const struct nk_user_font *font, - const struct nk_input *in); -NK_LIB void -nk_draw_button_text_image(struct nk_command_buffer *out, - const struct nk_rect *bounds, - const struct nk_rect *label, - const struct nk_rect *image, - nk_flags state, - const struct nk_style_button *style, - const char *str, - int len, - const struct nk_user_font *font, - const struct nk_image *img); -NK_LIB nk_bool -nk_do_button_text_image(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect bounds, - struct nk_image img, - const char *str, - int len, - nk_flags align, - enum nk_button_behavior behavior, - const struct nk_style_button *style, - const struct nk_user_font *font, - const struct nk_input *in); - -/* toggle */ -enum nk_toggle_type { NK_TOGGLE_CHECK, NK_TOGGLE_OPTION }; -NK_LIB nk_bool -nk_toggle_behavior(const struct nk_input *in, struct nk_rect select, nk_flags *state, nk_bool active); -NK_LIB void -nk_draw_checkbox(struct nk_command_buffer *out, - nk_flags state, - const struct nk_style_toggle *style, - nk_bool active, - const struct nk_rect *label, - const struct nk_rect *selector, - const struct nk_rect *cursors, - const char *string, - int len, - const struct nk_user_font *font, - nk_flags text_alignment); -NK_LIB void -nk_draw_option(struct nk_command_buffer *out, - nk_flags state, - const struct nk_style_toggle *style, - nk_bool active, - const struct nk_rect *label, - const struct nk_rect *selector, - const struct nk_rect *cursors, - const char *string, - int len, - const struct nk_user_font *font, - nk_flags text_alignment); -NK_LIB nk_bool -nk_do_toggle(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect r, - nk_bool *active, - const char *str, - int len, - enum nk_toggle_type type, - const struct nk_style_toggle *style, - const struct nk_input *in, - const struct nk_user_font *font, - nk_flags widget_alignment, - nk_flags text_alignment); - -/* progress */ -NK_LIB nk_size -nk_progress_behavior(nk_flags *state, - struct nk_input *in, - struct nk_rect r, - struct nk_rect cursor, - nk_size max, - nk_size value, - nk_bool modifiable); -NK_LIB void -nk_draw_progress(struct nk_command_buffer *out, - nk_flags state, - const struct nk_style_progress *style, - const struct nk_rect *bounds, - const struct nk_rect *scursor, - nk_size value, - nk_size max); -NK_LIB nk_size -nk_do_progress(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect bounds, - nk_size value, - nk_size max, - nk_bool modifiable, - const struct nk_style_progress *style, - struct nk_input *in); - -/* slider */ -NK_LIB float -nk_slider_behavior(nk_flags *state, - struct nk_rect *logical_cursor, - struct nk_rect *visual_cursor, - struct nk_input *in, - struct nk_rect bounds, - float slider_min, - float slider_max, - float slider_value, - float slider_step, - float slider_steps); -NK_LIB void -nk_draw_slider(struct nk_command_buffer *out, - nk_flags state, - const struct nk_style_slider *style, - const struct nk_rect *bounds, - const struct nk_rect *visual_cursor, - float min, - float value, - float max); -NK_LIB float -nk_do_slider(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect bounds, - float min, - float val, - float max, - float step, - const struct nk_style_slider *style, - struct nk_input *in, - const struct nk_user_font *font); - -/* scrollbar */ -NK_LIB float -nk_scrollbar_behavior(nk_flags *state, - struct nk_input *in, - int has_scrolling, - const struct nk_rect *scroll, - const struct nk_rect *cursor, - const struct nk_rect *empty0, - const struct nk_rect *empty1, - float scroll_offset, - float max_offset, - float scroll_step, - float cursor_travel, - enum nk_orientation o); -NK_LIB void -nk_draw_scrollbar(struct nk_command_buffer *out, - nk_flags state, - const struct nk_style_scrollbar *style, - const struct nk_rect *bounds, - const struct nk_rect *scroll); -NK_LIB float -nk_do_scrollbarv(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect scroll, - int has_scrolling, - float offset, - float target, - float step, - float button_pixel_inc, - const struct nk_style_scrollbar *style, - struct nk_input *in, - const struct nk_user_font *font); -NK_LIB float -nk_do_scrollbarh(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect scroll, - int has_scrolling, - float offset, - float target, - float step, - float button_pixel_inc, - const struct nk_style_scrollbar *style, - struct nk_input *in, - const struct nk_user_font *font); - -/* selectable */ -NK_LIB void -nk_draw_selectable(struct nk_command_buffer *out, - nk_flags state, - const struct nk_style_selectable *style, - nk_bool active, - const struct nk_rect *bounds, - const struct nk_rect *icon, - const struct nk_image *img, - enum nk_symbol_type sym, - const char *string, - int len, - nk_flags align, - const struct nk_user_font *font); -NK_LIB nk_bool -nk_do_selectable(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect bounds, - const char *str, - int len, - nk_flags align, - nk_bool *value, - const struct nk_style_selectable *style, - const struct nk_input *in, - const struct nk_user_font *font); -NK_LIB nk_bool -nk_do_selectable_image(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect bounds, - const char *str, - int len, - nk_flags align, - nk_bool *value, - const struct nk_image *img, - const struct nk_style_selectable *style, - const struct nk_input *in, - const struct nk_user_font *font); - -/* edit */ -NK_LIB void -nk_edit_draw_text(struct nk_command_buffer *out, - const struct nk_style_edit *style, - float pos_x, - float pos_y, - float x_offset, - const char *text, - int byte_len, - float row_height, - const struct nk_user_font *font, - struct nk_color background, - struct nk_color foreground, - nk_bool is_selected); -NK_LIB nk_flags -nk_do_edit(nk_flags *state, - struct nk_command_buffer *out, - struct nk_rect bounds, - nk_flags flags, - nk_plugin_filter filter, - struct nk_text_edit *edit, - const struct nk_style_edit *style, - struct nk_input *in, - const struct nk_user_font *font); - -/* color-picker */ -NK_LIB nk_bool -nk_color_picker_behavior(nk_flags *state, - const struct nk_rect *bounds, - const struct nk_rect *matrix, - const struct nk_rect *hue_bar, - const struct nk_rect *alpha_bar, - struct nk_colorf *color, - const struct nk_input *in); -NK_LIB void -nk_draw_color_picker(struct nk_command_buffer *o, - const struct nk_rect *matrix, - const struct nk_rect *hue_bar, - const struct nk_rect *alpha_bar, - struct nk_colorf col); -NK_LIB nk_bool -nk_do_color_picker(nk_flags *state, - struct nk_command_buffer *out, - struct nk_colorf *col, - enum nk_color_format fmt, - struct nk_rect bounds, - struct nk_vec2 padding, - const struct nk_input *in, - const struct nk_user_font *font); - -/* property */ -enum nk_property_status { - NK_PROPERTY_DEFAULT, - NK_PROPERTY_EDIT, - NK_PROPERTY_DRAG, -}; - -enum nk_property_filter { - NK_FILTER_INT, - NK_FILTER_FLOAT, -}; - -enum nk_property_kind { - NK_PROPERTY_INT, - NK_PROPERTY_FLOAT, - NK_PROPERTY_DOUBLE, -}; - -union nk_property { - int i; - float f; - double d; -}; - -struct nk_property_variant { - enum nk_property_kind kind; - union nk_property value; - union nk_property min_value; - union nk_property max_value; - union nk_property step; -}; -NK_LIB struct nk_property_variant -nk_property_variant_int(int value, int min_value, int max_value, int step); -NK_LIB struct nk_property_variant -nk_property_variant_float(float value, float min_value, float max_value, float step); -NK_LIB struct nk_property_variant -nk_property_variant_double(double value, double min_value, double max_value, double step); - -NK_LIB void -nk_drag_behavior(nk_flags *state, - const struct nk_input *in, - struct nk_rect drag, - struct nk_property_variant *variant, - float inc_per_pixel); -NK_LIB void -nk_property_behavior(nk_flags *ws, - const struct nk_input *in, - struct nk_rect property, - struct nk_rect label, - struct nk_rect edit, - struct nk_rect empty, - int *state, - struct nk_property_variant *variant, - float inc_per_pixel); -NK_LIB void -nk_draw_property(struct nk_command_buffer *out, - const struct nk_style_property *style, - const struct nk_rect *bounds, - const struct nk_rect *label, - nk_flags state, - const char *name, - int len, - const struct nk_user_font *font); -NK_LIB void -nk_do_property(nk_flags *ws, - struct nk_command_buffer *out, - struct nk_rect property, - const char *name, - struct nk_property_variant *variant, - float inc_per_pixel, - char *buffer, - int *len, - int *state, - int *cursor, - int *select_begin, - int *select_end, - const struct nk_style_property *style, - enum nk_property_filter filter, - struct nk_input *in, - const struct nk_user_font *font, - struct nk_text_edit *text_edit, - enum nk_button_behavior behavior); -NK_LIB void -nk_property(struct nk_context *ctx, - const char *name, - struct nk_property_variant *variant, - float inc_per_pixel, - const enum nk_property_filter filter); - -#ifdef NK_INCLUDE_FONT_BAKING - -/** - * @def NK_NO_STB_RECT_PACK_IMPLEMENTATION - * - * When defined, will avoid enabling STB_RECT_PACK_IMPLEMENTATION for when stb_rect_pack.h is already implemented - * elsewhere. - */ -# ifndef NK_NO_STB_RECT_PACK_IMPLEMENTATION -# define STB_RECT_PACK_IMPLEMENTATION -# endif /* NK_NO_STB_RECT_PACK_IMPLEMENTATION */ - -/** - * @def NK_NO_STB_TRUETYPE_IMPLEMENTATION - * - * When defined, will avoid enabling STB_TRUETYPE_IMPLEMENTATION for when stb_truetype.h is already implemented - * elsewhere. - */ -# ifndef NK_NO_STB_TRUETYPE_IMPLEMENTATION -# define STB_TRUETYPE_IMPLEMENTATION -# endif /* NK_NO_STB_TRUETYPE_IMPLEMENTATION */ - -/* Allow consumer to define own STBTT_malloc/STBTT_free, and use the font atlas' allocator otherwise */ -# ifndef STBTT_malloc -static void * -nk_stbtt_malloc(nk_size size, void *user_data) -{ - struct nk_allocator *alloc = (struct nk_allocator *)user_data; - return alloc->alloc(alloc->userdata, 0, size); -} - -static void -nk_stbtt_free(void *ptr, void *user_data) -{ - struct nk_allocator *alloc = (struct nk_allocator *)user_data; - alloc->free(alloc->userdata, ptr); -} - -# define STBTT_malloc(x, u) nk_stbtt_malloc(x, u) -# define STBTT_free(x, u) nk_stbtt_free(x, u) - -# endif /* STBTT_malloc */ - -#endif /* NK_INCLUDE_FONT_BAKING */ - -#endif /* NK_NUKLEAR_H_ */ diff --git a/mod/mod_sdk.c b/mod/mod_sdk.c deleted file mode 100644 index c539ca2..0000000 --- a/mod/mod_sdk.c +++ /dev/null @@ -1,2966 +0,0 @@ -#include "mod_sdk.h" - -#include -#include -#include -#include -#include -#include -#include - -#include - -#define QUEUE_PUSH(f, l, n) \ - ((f) == 0 ? (((f) = (l) = (n)), ((n)->next = 0)) : ((l)->next = (n), (l) = (n), ((n)->next = 0))) -#define QUEUE_PUSH_FRONT(f, l, n) \ - ((f) == 0 ? (((f) = (l) = (n)), ((n)->next = 0)) : ((n)->next = (f)), ((f) = (n))) -#define QUEUE_POP(f, l) \ - ((f) == (l) ? ((f) = 0, (l) = 0) : ((f) = (f)->next)) - -/* ======================================================= SDK ===================================================== */ - -mod_sdk_t g_sdk = {0}; - -#define MOD_HOST_API_REQUIRED_SIZE (offsetof(mod_host_api_t, hook_remove) + sizeof(((mod_host_api_t *)0)->hook_remove)) - -static bool -mod_version_compatible(mod_version_t host, mod_version_t mod) -{ - return host.major == mod.major && host.minor == mod.minor; -} - -bool -mod_sdk_init(const mod_host_api_t *host, mod_t mod) -{ - if (!host || mod == MOD_INVALID) { - return false; - } - - if (host->struct_size < MOD_HOST_API_REQUIRED_SIZE) { - return false; - } - - if (!mod_version_compatible(host->abi_version, (mod_version_t)MOD_ABI_VERSION)) { - return false; - } - - g_sdk.host = host; - g_sdk.mod = mod; - return true; -} - -const mod_host_api_t * -mod_sdk_host(void) -{ - MOD_ASSERT_MSG(g_sdk.host != NULL, "mod_sdk_init() must be called before using SDK functions"); - return g_sdk.host; -} - -mod_t -mod_sdk_mod_handle(void) -{ - MOD_ASSERT_MSG(g_sdk.mod != MOD_INVALID, "mod_sdk_init() must be called before using SDK functions"); - return g_sdk.mod; -} - -void -mod_assert_msg(const char *expr, const char *file, int line, const char *fmt, ...) -{ - char buf[4096]; - int len = snprintf(buf, sizeof(buf), - "Expression: %s\n" - "Location: %s:%d\n", - expr ? expr : "", - file ? file : "", - line); - - if (len < 0) { - buf[0] = '\0'; - len = 0; - } else if ((size_t)len >= sizeof(buf)) { - len = (int)sizeof(buf) - 1; - } - - if (fmt && fmt[0] != '\0' && (size_t)len < sizeof(buf) - 1) { - int written = snprintf(buf + len, sizeof(buf) - (size_t)len, "Message: "); - - if (written > 0) { - if ((size_t)written >= sizeof(buf) - (size_t)len) { - len = (int)sizeof(buf) - 1; - } else { - len += written; - - va_list args; - va_start(args, fmt); - written = vsnprintf(buf + len, sizeof(buf) - (size_t)len, fmt, args); - va_end(args); - - if (written < 0) { - buf[len] = '\0'; - } else if ((size_t)written >= sizeof(buf) - (size_t)len) { - len = (int)sizeof(buf) - 1; - } else { - len += written; - } - } - } - } - - if ((size_t)len < sizeof(buf) - 1) { - buf[len++] = '\n'; - buf[len] = '\0'; - } - - int result = MessageBoxA(NULL, buf, - "Assertion failed", - MB_ICONERROR | MB_ABORTRETRYIGNORE | MB_SETFOREGROUND | MB_TOPMOST); - - switch (result) { - case IDABORT: - abort(); - break; - case IDRETRY: - __debugbreak(); - break; - case IDIGNORE: - default: - break; - } -} - -/* ======================================================= MOD ===================================================== */ - -str_t -mod_get_mod_dir(void) -{ - const mod_host_api_t *host = mod_sdk_host(); - mod_t mod = mod_sdk_mod_handle(); - return (host && mod != MOD_INVALID) ? host->get_mod_dir(mod) : STR_NULL; -} - -str_t -mod_get_config_path(void) -{ - const mod_host_api_t *host = mod_sdk_host(); - mod_t mod = mod_sdk_mod_handle(); - return (host && mod != MOD_INVALID) ? host->get_config_path(mod) : STR_NULL; -} - -str_t -mod_get_manifest_path(void) -{ - const mod_host_api_t *host = mod_sdk_host(); - mod_t mod = mod_sdk_mod_handle(); - return (host && mod != MOD_INVALID) ? host->get_manifest_path(mod) : STR_NULL; -} - -void -mod_logv(log_level_t level, const char *fmt, va_list args) -{ - const mod_host_api_t *host = mod_sdk_host(); - mod_t mod = mod_sdk_mod_handle(); - if (host && mod != MOD_INVALID) { - host->logv(mod, level, fmt, args); - } -} - -void -mod_log(log_level_t level, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - mod_logv(level, fmt, args); - va_end(args); -} - -mod_cfg_t -mod_get_cfg_by_id(str_t id) -{ - const mod_host_api_t *host = mod_sdk_host(); - mod_t mod = mod_sdk_mod_handle(); - return (host && mod != MOD_INVALID) ? host->get_cfg_by_id(mod, id) : MOD_CFG_INVALID; -} - -bool -mod_register_cmd(str_t name, str_t description, mod_cmd_fn_t fn, void *user) -{ - const mod_host_api_t *host = mod_sdk_host(); - mod_t mod = mod_sdk_mod_handle(); - return (host && mod != MOD_INVALID)? host->register_cmd(mod, name, description, fn, user) : false; -} - -/* ======================================================== UI ====================================================== */ - -struct nk_context * -mod_get_nk_ctx(void) -{ - const mod_host_api_t *host = mod_sdk_host(); - return host ? host->get_nk_ctx() : NULL; -} - -void -mod_get_viewport_size(unsigned int *vw, unsigned int *vh) -{ - const mod_host_api_t *host = mod_sdk_host(); - if (host) { - host->get_viewport_size(vw, vh); - } -} - -uint64_t -mod_get_frame_counter(void) -{ - const mod_host_api_t *host = mod_sdk_host(); - if (!MOD_HOST_API_HAS_FIELD(host, get_frame_counter) || !host->get_frame_counter) { - return 0; - } - return host->get_frame_counter(); -} - -float -mod_get_fps(void) -{ - const mod_host_api_t *host = mod_sdk_host(); - if (!MOD_HOST_API_HAS_FIELD(host, get_fps) || !host->get_fps) { - return 0.0f; - } - return host->get_fps(); -} - -/* ======================================================= CFG ===================================================== */ - -bool -mod_cfg_get_bool(mod_cfg_t cfg) -{ - const mod_host_api_t *host = mod_sdk_host(); - bool result = false; - if (host) { - host->cfg_get_bool(cfg, &result); - } - return result; -} - -int -mod_cfg_get_int(mod_cfg_t cfg) -{ - const mod_host_api_t *host = mod_sdk_host(); - int result = 0; - if (host) { - host->cfg_get_int(cfg, &result); - } - return result; -} - -float -mod_cfg_get_float(mod_cfg_t cfg) -{ - const mod_host_api_t *host = mod_sdk_host(); - float result = 0.0f; - if (host) { - host->cfg_get_float(cfg, &result); - } - return result; -} - -int -mod_cfg_get_enum(mod_cfg_t cfg) -{ - const mod_host_api_t *host = mod_sdk_host(); - int result = -1; - if (host) { - host->cfg_get_enum(cfg, &result); - } - return result; -} - -uint64_t -mod_cfg_get_string_len(mod_cfg_t cfg) -{ - const mod_host_api_t *host = mod_sdk_host(); - uint64_t result = 0; - if (host) { - host->cfg_get_string_len(cfg, &result); - } - return result; -} - -uint64_t -mod_cfg_get_string_data(mod_cfg_t cfg, void *buf, uint64_t cap) -{ - const mod_host_api_t *host = mod_sdk_host(); - uint64_t len = 0; - if (host && buf && cap > 0) { - host->cfg_get_string_data(cfg, buf, cap, &len); - } - return len; -} - -str_t -mod_cfg_push_string(mod_cfg_t cfg, mod_arena_t arena) -{ - mod_t mod = mod_sdk_mod_handle(); - str_t result = STR_NULL; - if (mod != MOD_INVALID) { - uint64_t len = mod_cfg_get_string_len(cfg); - if (len > 0) { - uint8_t *data = MOD_ARENA_PUSH_ARRAY_ZERO(arena, uint8_t, len + 1); - if (data) { - uint64_t nread = mod_cfg_get_string_data(cfg, data, len); - result = str_make(data, nread); - } - } - } - return result; -} - -keybind_t -mod_cfg_get_keybind(mod_cfg_t cfg) -{ - const mod_host_api_t *host = mod_sdk_host(); - keybind_t result = {0}; - if (host) { - host->cfg_get_keybind(cfg, &result); - } - return result; -} - -mod_color_t -mod_cfg_get_color(mod_cfg_t cfg) -{ - const mod_host_api_t *host = mod_sdk_host(); - mod_color_t result = {0}; - if (host) { - host->cfg_get_color(cfg, &result); - } - return result; -} - -void -mod_cfg_set_bool(mod_cfg_t cfg, bool val) -{ - const mod_host_api_t *host = mod_sdk_host(); - if (host) { - host->cfg_set_bool(cfg, val); - } -} - -void -mod_cfg_set_int(mod_cfg_t cfg, int val) -{ - const mod_host_api_t *host = mod_sdk_host(); - if (host) { - host->cfg_set_int(cfg, val); - } -} - -void -mod_cfg_set_float(mod_cfg_t cfg, float val) -{ - const mod_host_api_t *host = mod_sdk_host(); - if (host) { - host->cfg_set_float(cfg, val); - } -} - -void -mod_cfg_set_enum(mod_cfg_t cfg, int val) -{ - const mod_host_api_t *host = mod_sdk_host(); - if (host) { - host->cfg_set_enum(cfg, val); - } -} - -void -mod_cfg_set_string(mod_cfg_t cfg, str_t val) -{ - const mod_host_api_t *host = mod_sdk_host(); - if (host) { - host->cfg_set_string(cfg, val); - } -} - -void -mod_cfg_set_keybind(mod_cfg_t cfg, keybind_t val) -{ - const mod_host_api_t *host = mod_sdk_host(); - if (host) { - host->cfg_set_keybind(cfg, val); - } -} - -void -mod_cfg_set_color(mod_cfg_t cfg, mod_color_t val) -{ - const mod_host_api_t *host = mod_sdk_host(); - if (host) { - host->cfg_set_color(cfg, val); - } -} - -/* ====================================================== ARENA ===================================================== */ - -mod_arena_t -mod_get_perm(void) -{ - const mod_host_api_t *host = mod_sdk_host(); - mod_t mod = mod_sdk_mod_handle(); - return (host && mod != MOD_INVALID) ? host->get_perm(mod) : MOD_ARENA_INVALID; -} - -mod_arena_t -mod_arena_create(uint64_t reserve_size, uint64_t commit_size) -{ - const mod_host_api_t *host = mod_sdk_host(); - mod_t mod = mod_sdk_mod_handle(); - return (host && mod != MOD_INVALID) ? host->arena_create(mod, reserve_size, commit_size) : MOD_ARENA_INVALID; -} - -void -mod_arena_destroy(mod_arena_t arena) -{ - const mod_host_api_t *host = mod_sdk_host(); - mod_t mod = mod_sdk_mod_handle(); - if (host && mod != MOD_INVALID) { - host->arena_destroy(mod, arena); - } -} - -void * -mod_arena_push(mod_arena_t arena, uint64_t size, uint64_t alignment) -{ - const mod_host_api_t *host = mod_sdk_host(); - return (host) ? host->arena_push(arena, size, alignment) : NULL; -} - -void * -mod_arena_push_zero(mod_arena_t arena, uint64_t size, uint64_t alignment) -{ - void *data = mod_arena_push(arena, size, alignment); - if (data) { - memset(data, 0, size); - } - return data; -} - -uint64_t -mod_arena_pos(mod_arena_t arena) -{ - const mod_host_api_t *host = mod_sdk_host(); - return (host) ? host->arena_pos(arena) : 0ULL; -} - -void -mod_arena_pop_to(mod_arena_t arena, uint64_t pos) -{ - const mod_host_api_t *host = mod_sdk_host(); - if (host) { - host->arena_pop_to(arena, pos); - } -} - -void -mod_arena_pop(mod_arena_t arena, uint64_t size) -{ - uint64_t used = mod_arena_pos(arena); - if (size > used) { - size = used; - } - mod_arena_pop_to(arena, used - size); -} - -void -mod_arena_reset(mod_arena_t arena) -{ - const mod_host_api_t *host = mod_sdk_host(); - if (host) { - host->arena_reset(arena); - } -} - -tmp_arena_t -mod_scratch_begin(mod_arena_t conflict) -{ - const mod_host_api_t *host = mod_sdk_host(); - return (host) ? host->scratch_begin(conflict) : (tmp_arena_t){0}; -} - -void -mod_scratch_end(tmp_arena_t tmp) -{ - const mod_host_api_t *host = mod_sdk_host(); - if (host) { - host->scratch_end(tmp); - } -} - -/* ====================================================== INPUT ===================================================== */ - -input_key_kind_t -mod_input_key_from_str(str_t name) -{ - const mod_host_api_t *host = mod_sdk_host(); - return (host) ? host->input_key_from_str(name) : INPUT_KEY_NONE; -} - -str_t -mod_input_key_to_str(input_key_kind_t key) -{ - const mod_host_api_t *host = mod_sdk_host(); - return (host) ? host->input_key_to_str(key) : STR_NULL; -} - -str_t -mod_input_event_kind_to_str(input_event_kind_t kind) -{ - const mod_host_api_t *host = mod_sdk_host(); - return (host) ? host->input_event_kind_to_str(kind) : STR_NULL; -} - -bool -mod_keybind_parse(str_t str, keybind_t *out) -{ - const mod_host_api_t *host = mod_sdk_host(); - return (host) ? host->keybind_parse(str, out) : false; -} - -uint64_t -mod_keybind_utf8_len(keybind_t bind) -{ - const mod_host_api_t *host = mod_sdk_host(); - return (host) ? host->keybind_utf8_len(bind) : 0ULL; -} - -uint64_t -mod_keybind_utf8_write(keybind_t bind, void *buf, uint64_t cap) -{ - const mod_host_api_t *host = mod_sdk_host(); - return (host && buf && cap > 0) ? host->keybind_utf8_write(bind, buf, cap) : 0ULL; -} - -str_t -mod_keybind_to_str(keybind_t bind, mod_arena_t arena) -{ - uint64_t len = mod_keybind_utf8_len(bind); - str_t result = STR_NULL; - if (len > 0) { - uint8_t *data = MOD_ARENA_PUSH_ARRAY_ZERO(arena, uint8_t, len + 1); // null-terminated just in case - if (data) { - uint64_t nread = mod_keybind_utf8_write(bind, data, len); - data[nread] = '\0'; - - result = str_make(data, nread); - } - } - return result; -} - -bool -mod_keybind_is_down(keybind_t bind) -{ - const mod_host_api_t *host = mod_sdk_host(); - return (host) ? host->keybind_is_down(bind) : false; -} - -bool -mod_keybind_is_pressed(keybind_t bind) -{ - const mod_host_api_t *host = mod_sdk_host(); - return (host) ? host->keybind_is_pressed(bind) : false; -} - -bool -mod_keybind_is_released(keybind_t bind) -{ - const mod_host_api_t *host = mod_sdk_host(); - return (host) ? host->keybind_is_released(bind) : false; -} - -bool -mod_keybind_str_is_down(str_t keybind_str) -{ - keybind_t bind = {0}; - if (!mod_keybind_parse(keybind_str, &bind)) { - return false; - } - return mod_keybind_is_down(bind); -} - -bool -mod_keybind_str_is_pressed(str_t keybind_str) -{ - keybind_t bind = {0}; - if (!mod_keybind_parse(keybind_str, &bind)) { - return false; - } - return mod_keybind_is_pressed(bind); -} - -bool -mod_keybind_str_is_released(str_t keybind_str) -{ - keybind_t bind = {0}; - if (!mod_keybind_parse(keybind_str, &bind)) { - return false; - } - return mod_keybind_is_released(bind); -} - -static bool -mod_keybind_key_matches_event(input_key_kind_t bind_key, input_key_kind_t event_key) -{ - switch (bind_key) { - case INPUT_KEY_CTRL: return event_key == INPUT_KEY_LEFT_CTRL || event_key == INPUT_KEY_RIGHT_CTRL; - case INPUT_KEY_SHIFT: return event_key == INPUT_KEY_LEFT_SHIFT || event_key == INPUT_KEY_RIGHT_SHIFT; - case INPUT_KEY_ALT: return event_key == INPUT_KEY_LEFT_ALT || event_key == INPUT_KEY_RIGHT_ALT; - default: return bind_key == event_key; - } -} - -bool -mod_keybind_activated_by_event(keybind_t bind, input_event_t *ev) -{ - if (ev->kind != INPUT_EVENT_KEY_DOWN && - ev->kind != INPUT_EVENT_MOUSE_DOWN && - ev->kind != INPUT_EVENT_MOUSE_DBLCLICK) { - return false; - } - - if (ev->is_repeat) { - return false; - } - - bool involved = false; - for (int i = 0; i < bind.count; ++i) { - if (mod_keybind_key_matches_event(bind.keys[i], ev->key)) { - involved = true; - break; - } - } - - return involved && mod_keybind_is_down(bind); -} - -/* ========================================== HOOKING / SIGNATURE SCANNING ========================================== */ - -sigscan_err_t -mod_sigscan(sigscan_entry_t *entry) -{ - const mod_host_api_t *host = mod_sdk_host(); - return (host && entry) ? host->sigscan(entry->name, entry->pattern, entry->op_off, entry->deref, entry->first_rvas, entry->pp) : SIGSCAN_ERR_NOT_FOUND; -} - -bool -mod_hook_create(void *target, void *detour, void **original) -{ - const mod_host_api_t *host = mod_sdk_host(); - mod_t mod = mod_sdk_mod_handle(); - return (host && mod != MOD_INVALID) ? host->hook_create(mod, target, detour, original) : false; -} - -bool -mod_hook_enable(void *target) -{ - const mod_host_api_t *host = mod_sdk_host(); - mod_t mod = mod_sdk_mod_handle(); - return (host && mod != MOD_INVALID) ? host->hook_enable(mod, target) : false; -} - -bool -mod_hook_disable(void *target) -{ - const mod_host_api_t *host = mod_sdk_host(); - mod_t mod = mod_sdk_mod_handle(); - return (host && mod != MOD_INVALID) ? host->hook_disable(mod, target) : false; -} - -bool -mod_hook_remove(void *target) -{ - const mod_host_api_t *host = mod_sdk_host(); - mod_t mod = mod_sdk_mod_handle(); - return (host && mod != MOD_INVALID) ? host->hook_remove(mod, target) : false; -} - -/* ===================================================== STRING ===================================================== */ - -uint64_t -calc_cstr_len(const char *s) -{ - if (!s) { - return 0; - } - - const char *p = s; - while (*p) { - ++p; - } - - return (uint64_t)(p - s); -} - -uint64_t -calc_cstr_len_with_cap(const char *s, uint64_t cap) -{ - if (!s || cap == 0) { - return 0; - } - - const char *p = s + 0; - const char *end = s + cap; - while (p < end && *p) { - ++p; - } - - return (uint64_t)(p - s); -} - -uint64_t -calc_wstr_len(const wchar_t *s) -{ - if (!s) { - return 0; - } - - const wchar_t *p = s; - while (*p) { - ++p; - } - - return (uint64_t)(p - s); -} - -uint64_t -calc_wstr_len_with_cap(const wchar_t *s, uint64_t cap) -{ - if (!s || cap == 0) { - return 0; - } - - const wchar_t *p = s + 0; - const wchar_t *end = s + cap; - - while (p < end && *p) { - ++p; - } - - return (uint64_t)(p - s); -} - -str_t -str_make(void *data, uint64_t size) -{ - str_t result = {0}; - if (data && size > 0) { - result = (str_t){ - .data = data, - .len = size, - }; - } - return result; -} - -str_t -str_from_cstr(const char *cstr) -{ - str_t result = {0}; - uint64_t len = calc_cstr_len(cstr); - if (len > 0) { - result = (str_t){ - .data = (uint8_t *)cstr, - .len = len, - }; - } - return result; -} - -str_t -str_from_cstr_with_cap(const char *cstr, uint64_t cap) -{ - str_t result = {0}; - uint64_t len = calc_cstr_len_with_cap(cstr, cap); - if (len > 0) { - result = (str_t){ - .data = (uint8_t *)cstr, - .len = len, - }; - } - return result; -} - -str16_t -str16_make(uint16_t *data, uint64_t size) -{ - str16_t result = {0}; - if (data && size > 0) { - result = (str16_t){ - .data = data, - .len = size, - }; - } - return result; -} - -str16_t -str16_from_wstr(const wchar_t *wstr) -{ - str16_t result = {0}; - uint64_t len = calc_wstr_len(wstr); - if (len > 0) { - result = (str16_t){ - .data = (uint16_t *)wstr, - .len = len, - }; - } - return result; -} - -str16_t -str16_from_wstr_with_cap(const wchar_t *wstr, uint64_t cap) -{ - str16_t result = {0}; - uint64_t len = calc_wstr_len_with_cap(wstr, cap); - if (len > 0) { - result = (str16_t){ - .data = (uint16_t *)wstr, - .len = len, - }; - } - return result; -} - -str_t -str_slice(str_t str, uint64_t start_idx, uint64_t end_idx) -{ - if (str.data && str.len > 0) { - if (end_idx > str.len) { - end_idx = str.len; - } - - if (start_idx > str.len) { - start_idx = str.len; - } - - if (start_idx > end_idx) { - uint64_t tmp = start_idx; - - start_idx = end_idx; - end_idx = tmp; - } - - str.len = end_idx - start_idx; - str.data += start_idx; - } - return str; -} - -static int -ascii_compare(uint8_t a, uint8_t b, str_cmp_flags_t flags) -{ - if (flags & STR_CMP_FLAG_IGNORE_SLASHES) { - a = ascii_to_forward_slash(a); - b = ascii_to_forward_slash(b); - } - - if (flags & STR_CMP_FLAG_IGNORE_CASE) { - a = ascii_to_lower(a); - b = ascii_to_lower(b); - } - - return (int)a - (int)b; -} - -bool -str_has_prefix(str_t s, str_t prefix, str_cmp_flags_t flags) -{ - if (prefix.len > s.len) { - return false; - } - - for (uint64_t i = 0; i < prefix.len; ++i) { - uint8_t ca = s.data[i]; - uint8_t cb = prefix.data[i]; - - if (!ascii_equal(ca, cb, flags)) { - return false; - } - } - - return true; -} - -bool -str_has_suffix(str_t s, str_t suffix, str_cmp_flags_t flags) -{ - if (suffix.len > s.len) { - return false; - } - - uint64_t offset = s.len - suffix.len; - for (uint64_t i = 0; i < suffix.len; ++i) { - uint8_t ca = s.data[offset + i]; - uint8_t cb = suffix.data[i]; - - if (!ascii_equal(ca, cb, flags)) { - return false; - } - } - - return true; -} - -int -str_compare(str_t a, str_t b, str_cmp_flags_t flags) -{ - uint64_t min_len = MIN_VAL(a.len, b.len); - - for (uint64_t i = 0; i < min_len; ++i) { - int result = ascii_compare(a.data[i], b.data[i], flags); - if (result != 0) { - return result; - } - } - - if (a.len < b.len) { - return -1; - } else if (a.len > b.len) { - return 1; - } - return 0; -} - -bool -str_equal(str_t a, str_t b, str_cmp_flags_t flags) -{ - if (a.len != b.len) { - return false; - } - - if (a.len == 0) { - return true; - } - - for (uint64_t i = 0; i < a.len; ++i) { - uint8_t ca = a.data[i]; - uint8_t cb = b.data[i]; - - if (!ascii_equal(ca, cb, flags)) { - return false; - } - } - - return true; -} - -bool -str_equal_icase(str_t a, str_t b) -{ - return str_equal(a, b, STR_CMP_FLAG_IGNORE_CASE); -} - -bool -str_find(str_t s, str_t sub, str_cmp_flags_t flags, uint64_t *idx) -{ - if (sub.len == 0) { - if (idx) { - *idx = 0; - } - return true; - } - - if (sub.len > s.len) { - return false; - } - - uint64_t last = s.len - sub.len; - for (uint64_t i = 0; i <= last; ++i) { - str_t win = str_make(&s.data[i], sub.len); - if (str_equal(win, sub, flags)) { - if (idx) { - *idx = i; - } - return true; - } - } - - return false; -} - -bool -str_rfind(str_t s, str_t sub, str_cmp_flags_t flags, uint64_t *idx) -{ - if (sub.len == 0) { - if (idx) { - *idx = 0; - } - return true; - } - - if (sub.len > s.len) { - return false; - } - - uint64_t last = s.len - sub.len; - for (uint64_t i = 0; i <= last; ++i) { - uint64_t j = last - i; - str_t win = str_make(&s.data[j], sub.len); - if (str_equal(win, sub, flags)) { - if (idx) { - *idx = j; - } - return true; - } - } - return false; -} - -bool -str_find_any(str_t s, str_t charset, str_cmp_flags_t flags, uint64_t *idx) -{ - if (charset.len == 0) { - if (idx) { - *idx = 0; - } - return true; - } - - for (uint64_t i = 0; i < s.len; ++i) { - for (uint64_t j = 0; j < charset.len; ++j) { - if (ascii_equal(s.data[i], charset.data[j], flags)) { - if (idx) { - *idx = i; - } - return true; - } - } - } - return false; -} - -bool -str_rfind_any(str_t s, str_t charset, str_cmp_flags_t flags, uint64_t *idx) -{ - if (charset.len == 0) { - if (idx) { - *idx = 0; - } - return true; - } - - for (uint64_t i = 0; i < s.len; ++i) { - for (uint64_t j = 0; j < charset.len; ++j) { - if (ascii_equal(s.data[s.len - i - 1], charset.data[j], flags)) { - if (idx) { - *idx = s.len - i - 1; - } - return true; - } - } - } - return false; -} - -bool -str_has_char(str_t s, char c, str_cmp_flags_t flags) -{ - for (uint64_t i = 0; i < s.len; ++i) { - if (ascii_equal(s.data[i], c, flags)) { - return true; - } - } - return false; -} - -str_t -str_push_copy(mod_arena_t arena, str_t str) -{ - str_t result = { - .len = str.len, - .data = mod_arena_push(arena, str.len + 1, 1), - }; - - if (result.data) { - if (result.len > 0) { - memcpy(result.data, str.data, str.len); - } - result.data[result.len] = '\0'; - } - return result; -} - -uint64_t -str_write_vfmt(void *buf, uint64_t cap, const char *fmt, va_list args) -{ - va_list args_copy; - va_copy(args_copy, args); - - int written; - if (!buf || cap == 0) { - written = vsnprintf(NULL, 0, fmt, args_copy); - } else { - written = vsnprintf((char *)buf, (size_t)cap, fmt, args_copy); - } - - va_end(args_copy); - - return written >= 0 ? (uint64_t)written : 0; -} - -uint64_t -str_write_fmt(void *buf, uint64_t cap, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - uint64_t written = str_write_vfmt(buf, cap, fmt, args); - va_end(args); - return written; -} - -str_t -str_push_vfmt(mod_arena_t arena, const char *fmt, va_list args) -{ - MOD_ASSERT(fmt != NULL); - - va_list args_copy; - va_copy(args_copy, args); - int needed = vsnprintf(NULL, 0, fmt, args_copy); - va_end(args_copy); - - if (needed < 0) { - return (str_t){0}; - } - - uint64_t cap = (uint64_t)needed + 1; - uint8_t *data = mod_arena_push(arena, cap, 1); - if (!data) { - return (str_t){0}; - } - - int written = vsnprintf((char *)data, (size_t)cap, fmt, args); - if (written < 0 || written != needed) { - return (str_t){0}; - } - - return (str_t){ - .data = data, - .len = (uint64_t)written, - }; -} - -str_t -str_push_fmt(mod_arena_t arena, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - str_t result = str_push_vfmt(arena, fmt, args); - va_end(args); - return result; -} - -str_t -str_push_fill_byte(mod_arena_t arena, uint64_t size, uint8_t byte) -{ - str_t result = { - .data = mod_arena_push(arena, size + 1, 1), - .len = size, - }; - - if (result.data) { - if (result.len > 0) { - memset(result.data, byte, size + 1); - } - result.data[result.len] = '\0'; - } - return result; -} - -str_t -str_push_hex(mod_arena_t arena, void *data, uint64_t size) -{ - uint64_t hex_size = size * 2; - str_t result = { - .data = mod_arena_push(arena, hex_size + 1, 1), - .len = hex_size, - }; - - if (result.data) { - if (result.len > 0) { - uint8_t *buf = (uint8_t *)data; - for (uint64_t i = 0; i < size; ++i) { - uint8_t lo = (buf[i] >> 0) & 0x0F; - uint8_t hi = (buf[i] >> 4) & 0x0F; - - result.data[2 * i + 0] = nibble_to_hex(hi); - result.data[2 * i + 1] = nibble_to_hex(lo); - } - } - - result.data[result.len] = '\0'; - } - return result; -} - -str_t -str_push_concat(mod_arena_t arena, str_t a, str_t b) -{ - uint64_t len = a.len + b.len; - str_t result = { - .data = mod_arena_push(arena, len + 1, 1), - .len = len, - }; - - if (result.data) { - if (result.len > 0) { - memcpy(result.data + 0, a.data, a.len); - memcpy(result.data + a.len, b.data, b.len); - } - result.data[result.len] = '\0'; - } - - return result; -} - -str_list_t -str_list_copy(mod_arena_t arena, str_list_t src) -{ - str_list_t dst = {0}; - for (str_node_t *node = src.first; node; node = node->next) { - str_list_push_copy(arena, &dst, node->str); - } - return dst; -} - -void -str_list_push_node(str_list_t *list, str_node_t *node) -{ - QUEUE_PUSH(list->first, list->last, node); - list->count += 1; - list->total_bytes += node->str.len; -} - -void -str_list_push_node_front(str_list_t *list, str_node_t *node) -{ - QUEUE_PUSH_FRONT(list->first, list->last, node); - list->count += 1; - list->total_bytes += node->str.len; -} - -void -str_list_push(mod_arena_t arena, str_list_t *list, str_t str) -{ - str_node_t *node = mod_arena_push(arena, sizeof(str_node_t), sizeof(str_node_t)); - if (node) { - node->str = str; - str_list_push_node(list, node); - } -} - -void -str_list_push_copy(mod_arena_t arena, str_list_t *list, str_t str) -{ - str_list_push(arena, list, str_push_copy(arena, str)); -} - -void -str_list_push_fmt(mod_arena_t arena, str_list_t *list, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - str_t s = str_push_vfmt(arena, fmt, args); - va_end(args); - str_list_push(arena, list, s); -} - -void -str_list_push_front(mod_arena_t arena, str_list_t *list, str_t str) -{ - str_node_t *node = mod_arena_push(arena, sizeof(str_node_t), sizeof(str_node_t)); - if (node) { - node->str = str; - str_list_push_node_front(list, node); - } -} - -void -str_list_push_front_fmt(mod_arena_t arena, str_list_t *list, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - str_t s = str_push_vfmt(arena, fmt, args); - va_end(args); - str_list_push_front(arena, list, s); -} - -void -str_list_concat_inplace(str_list_t *dst, str_list_t *src) -{ - if (!src->first) { - return; - } - - if (!dst->first) { - *dst = *src; - } else { - dst->last->next = src->first; - dst->last = src->last; - dst->count += src->count; - dst->total_bytes += src->total_bytes; - } - memset(src, 0, sizeof(*src)); -} - -str_list_t -str_split(mod_arena_t arena, str_t str, uint64_t split_count, str_t *splits) -{ - str_list_t list = {0}; - - uint64_t split_start = 0; - for (uint64_t i = 0; i < str.len; ++i) { - bool was_split = false; - for (uint64_t split_idx = 0; split_idx < split_count; ++split_idx) { - bool match = false; - if (i + splits[split_idx].len <= str.len) { - match = true; - for (uint64_t split_i = 0; split_i < splits[split_idx].len && i + split_i < str.len; ++split_i) { - if (splits[split_idx].data[split_i] != str.data[i + split_i]) { - match = false; - break; - } - } - } - - if (match) { - str_t split_string = str_make(str.data + split_start, i - split_start); - str_list_push(arena, &list, split_string); - split_start = i + splits[split_idx].len; - i += splits[split_idx].len - 1; - was_split = true; - break; - } - } - - if (was_split == 0 && i == str.len - 1) { - str_t split_string = str_make(str.data + split_start, i + 1 - split_start); - str_list_push(arena, &list, split_string); - break; - } - } - - return list; -} - -str_list_t -str_split_lines(mod_arena_t arena, str_t str) -{ - str_list_t list = {0}; - - uint64_t start_idx = 0; - for (uint64_t i = 0; i < str.len; ++i) { - bool is_eof = (i == str.len - 1); - char c = str.data[i]; - - bool is_newline = (c == '\r' || c == '\n'); - - if (is_newline || is_eof) { - // for newlines, end before the newline char; for EOF, include the last char - uint64_t end_idx = is_newline ? i : i + 1; - - str_t line = str_slice(str, start_idx, end_idx); - line = str_trim_trailing_space(line); - str_list_push(arena, &list, line); - - // skip \r\n or \n\r pairs - if (is_newline && (i + 1) < str.len) { - char next = str.data[i + 1]; - if ((c == '\r' && next == '\n') || (c == '\n' && next == '\r')) { - i += 1; - } - } - - start_idx = i + 1; - } - } - - return list; -} - -str_t -str_list_join(mod_arena_t arena, str_list_t list, str_t pre, str_t sep, str_t post) -{ - uint64_t seps = (list.count > 1) ? (list.count - 1) : 0; - uint64_t total = (list.total_bytes + pre.len + seps * sep.len + post.len); - - str_t result = { - .data = mod_arena_push(arena, total + 1, 1), - .len = total, - }; - - if (result.data) { - if (result.len > 0) { - uint8_t *ptr = result.data; - memcpy(ptr, pre.data, pre.len); - ptr += pre.len; - - for (str_node_t *node = list.first; node; node = node->next) { - memcpy(ptr, node->str.data, node->str.len); - ptr += node->str.len; - - if (node != list.last) { - memcpy(ptr, sep.data, sep.len); - ptr += sep.len; - } - } - - memcpy(ptr, post.data, post.len); - ptr += post.len; - } - - result.data[result.len] = '\0'; - } - return result; -} - -str_t -str_list_join_lines(mod_arena_t arena, str_list_t list) -{ - return str_list_join(arena, list, STR_NULL, STR_LIT("\n"), STR_NULL); -} - -str_array_t -str_array_make(str_t *items, int count) -{ - return (str_array_t){ - .items = items, - .count = count, - }; -} - -str_array_t -str_array_copy(mod_arena_t arena, str_array_t src) -{ - MOD_ASSERT((!src.items && src.count == 0) || (src.items && src.count > 0)); - - str_array_t dst = { - .count = src.count, - .items = mod_arena_push(arena, src.count * sizeof(str_t), sizeof(str_t)), - }; - - if (dst.items) { - for (uint64_t i = 0; i < src.count; ++i) { - dst.items[i] = str_push_copy(arena, src.items[i]); - } - } - return dst; -} - -str_array_t -str_array_copy_from_list(mod_arena_t arena, str_list_t list) -{ - return str_array_from_list(arena, str_list_copy(arena, list)); -} - -str_array_t -str_array_from_list(mod_arena_t arena, str_list_t list) -{ - str_array_t array = { - .count = list.count, - .items = mod_arena_push(arena, list.count * sizeof(str_t), sizeof(str_t)), - }; - - if (array.items) { - uint64_t i = 0; - for (str_node_t *node = list.first; node != 0; node = node->next, ++i) { - array.items[i] = node->str; - } - } - return array; -} - -bool -str_array_contains(str_array_t array, str_t s, str_cmp_flags_t flags) -{ - for (uint64_t i = 0; i < array.count; ++i) { - if (str_equal(array.items[i], s, flags)) { - return true; - } - } - return false; -} - -bool -str_array_find(str_array_t array, str_t s, str_cmp_flags_t flags, uint64_t *idx) -{ - for (uint64_t i = 0; i < array.count; ++i) { - if (str_equal(array.items[i], s, flags)) { - if (idx) { - *idx = i; - } - return true; - } - } - return false; -} - -bool -str_list_contains(str_list_t list, str_t s, str_cmp_flags_t flags) -{ - for (str_node_t *node = list.first; node; node = node->next) { - if (str_equal(node->str, s, flags)) { - return true; - } - } - return false; -} - -char * -str_push_cstr(mod_arena_t arena, str_t s) -{ - char *cstr = mod_arena_push(arena, s.len + 1, 1); - if (cstr) { - memcpy(cstr, s.data, s.len * sizeof(char)); - cstr[s.len] = '\0'; - } - return cstr; -} - -wchar_t * -str16_push_wstr(mod_arena_t arena, str16_t s) -{ - wchar_t *wstr = mod_arena_push(arena, sizeof(s.data[0]) * (s.len + 1), sizeof(s.data[0])); - if (wstr) { - memcpy(wstr, s.data, s.len * sizeof(wchar_t)); - wstr[s.len] = '\0'; - } - return wstr; -} - -uint64_t -str_write_cstr(str_t s, char *buf, uint64_t cap) -{ - if (!buf || cap == 0 || str_is_empty(s)) { - return 0; - } - - uint64_t len = MIN_VAL(s.len + 1, cap); - memcpy(buf, s.data, len - 1); - buf[len - 1] = '\0'; - return len; -} - -uint64_t -str_write_data(str_t s, char *buf, uint64_t cap) -{ - if (!buf || cap == 0 || str_is_empty(s)) { - return 0; - } - - uint64_t len = MIN_VAL(s.len, cap); - memcpy(buf, s.data, len); - return len; -} - -str_t -str_to_upper(mod_arena_t arena, str_t str) -{ - str_t result = str_push_copy(arena, str); - if (!str_is_empty(result)) { - for (uint64_t i = 0; i < str.len; ++i) { - result.data[i] = ascii_to_upper(str.data[i]); - } - } - return result; -} - -str_t -str_to_lower(mod_arena_t arena, str_t str) -{ - str_t result = str_push_copy(arena, str); - if (!str_is_empty(result)) { - for (uint64_t i = 0; i < str.len; ++i) { - result.data[i] = ascii_to_lower(str.data[i]); - } - } - return result; -} - -str_t -str_trim_leading(str_t str, str_t charset, str_cmp_flags_t flags) -{ - uint64_t start_idx = str.len; - for (uint64_t i = 0; i < str.len; ++i) { - if (!str_has_char(charset, str.data[i], flags)) { - start_idx = i; - break; - } - } - - return str_slice(str, start_idx, str.len); -} - -str_t -str_trim_trailing(str_t str, str_t charset, str_cmp_flags_t flags) -{ - uint64_t end_idx = 0; - for (uint64_t i = 0; i < str.len; ++i) { - uint64_t j = str.len - 1 - i; // reverse order - if (!str_has_char(charset, str.data[j], flags)) { - end_idx = j + 1; - break; - } - } - - return str_slice(str, 0, end_idx); -} - -str_t -str_trim(str_t str, str_t charset, str_cmp_flags_t flags) -{ - return str_trim_trailing(str_trim_leading(str, charset, flags), charset, flags); -} - -str_t -str_trim_leading_space(str_t str) -{ - return str_trim_leading(str, STR_LIT(" \r\t\f\v\n"), 0); -} - -str_t -str_trim_trailing_space(str_t str) -{ - return str_trim_trailing(str, STR_LIT(" \r\t\f\v\n"), 0); -} - -str_t -str_trim_space(str_t str) -{ - return str_trim(str, STR_LIT(" \r\t\f\v\n"), 0); -} - -str_t -str_trim_prefix(str_t str, str_t prefix, str_cmp_flags_t flags) -{ - str_t result = str; - if (str_has_prefix(str, prefix, flags)) { - result = str_slice(str, prefix.len, str.len); - } - return result; -} - -str_t -str_trim_suffix(str_t str, str_t suffix, str_cmp_flags_t flags) -{ - str_t result = str; - if (str_has_suffix(str, suffix, flags)) { - result = str_slice(str, 0, str.len - suffix.len); - } - return result; -} - -/* str_trim_comment(STR_LIT("example # this is a comment"), STR_LIT("#"), 0) --> STR_LIT("example ") */ -str_t -str_trim_comment(str_t str, str_t charset, str_cmp_flags_t flags) -{ - uint64_t end_idx = str.len; - for (uint64_t i = 0; i < str.len; ++i) { - if (str_has_char(charset, str.data[i], flags)) { - end_idx = i; - break; - } - } - - return str_slice(str, 0, end_idx); -} - -bool -str_parse_s64(str_t str, int64_t *value) -{ - if (str_is_empty(str)) { - return false; - } - - uint64_t i = 0; - int sign = 1; - - if (str.data[0] == '-') { - sign = -1; - i = 1; - } else if (str.data[0] == '+') { - i = 1; - } - - if (i == str.len) { - return false; - } - - int64_t result = 0; - for (; i < str.len; ++i) { - uint8_t c = str.data[i]; - if (!ascii_is_num(c)) { - return false; - } - - int digit = c - '0'; - - /* overflow check before multiply + add */ - if (result > (INT64_MAX - digit) / 10) { - return false; - } - result = result * 10 + digit; - } - - result *= sign; - - *value = result; - return true; -} - -bool -str_parse_int(str_t str, int *value) -{ - int64_t int_value = 0; - if (!str_parse_s64(str, &int_value)) { - return false; - } - - if (!IN_RANGE(int_value, INT32_MIN, INT32_MAX)) { - return false; - } - - *value = (int)int_value; - return true; -} - -bool -str_parse_u32(str_t str, uint32_t *value) -{ - int64_t int_value = 0; - if (!str_parse_s64(str, &int_value)) { - return false; - } - - if (!IN_RANGE(int_value, 0, UINT32_MAX)) { - return false; - } - - *value = (uint32_t)int_value; - return true; -} - -bool -str_parse_u16(str_t str, uint16_t *value) -{ - int64_t int_value = 0; - if (!str_parse_s64(str, &int_value)) { - return false; - } - - if (!IN_RANGE(int_value, 0, UINT16_MAX)) { - return false; - } - - *value = (uint16_t)int_value; - return true; -} - -bool -str_parse_u8(str_t str, uint8_t *value) -{ - int64_t int_value = 0; - if (!str_parse_s64(str, &int_value)) { - return false; - } - - if (!IN_RANGE(int_value, 0, UINT8_MAX)) { - return false; - } - - *value = (uint8_t)int_value; - return true; -} - -bool -str_parse_float(str_t str, float *value) -{ - if (str_is_empty(str)) { - return false; - } - - uint64_t i = 0; - double sign = 1.0; - - if (str.data[0] == '-') { - sign = -1.0; - i = 1; - } else if (str.data[0] == '+') { - i = 1; - } - - if (i == str.len) { - return false; - } - - bool has_digit = false; - double result = 0.0; - - /* integer part */ - for (; i < str.len && ascii_is_num(str.data[i]); ++i) { - result = result * 10.0 + (str.data[i] - '0'); - has_digit = true; - } - - /* fractional part */ - if (i < str.len && str.data[i] == '.') { - i += 1; - double frac = 0.1; - for (; i < str.len && ascii_is_num(str.data[i]); ++i) { - result += (str.data[i] - '0') * frac; - frac *= 0.1; - has_digit = true; - } - } - - if (!has_digit) { - return false; - } - - /* exponent part */ - if (i < str.len && (str.data[i] == 'e' || str.data[i] == 'E')) { - i += 1; - - int exp_sign = 1; - if (i < str.len && str.data[i] == '-') { - exp_sign = -1; - i += 1; - } else if (i < str.len && str.data[i] == '+') { - i += 1; - } - - if (i == str.len || !ascii_is_num(str.data[i])) { - return false; - } - - int exp = 0; - for (; i < str.len && ascii_is_num(str.data[i]); ++i) { - if (exp > 300) { - return false; // prevent absurd exponents - } - exp = exp * 10 + (str.data[i] - '0'); - } - - double pow10 = 1.0; - for (int e = 0; e < exp; ++e) { - pow10 *= 10.0; - } - - if (exp_sign > 0) { - result *= pow10; - } else { - result /= pow10; - } - } - - /* trailing junk */ - if (i != str.len) { - return false; - } - - result *= sign; - - /* range check - reject inf */ - float f = (float)result; - if (!IN_RANGE(f, -FLT_MAX, FLT_MAX) || f != f) { - return false; - } - - *value = f; - return true; -} - -bool -str_parse_bool(str_t s, bool default_val) -{ - if (str_equal_icase(s, STR_LIT("true")) || str_equal_icase(s, STR_LIT("yes")) || str_equal_icase(s, STR_LIT("on"))) { - return true; - } - - if (str_equal_icase(s, STR_LIT("false")) || str_equal_icase(s, STR_LIT("no")) || str_equal_icase(s, STR_LIT("off"))) { - return false; - } - - return default_val; -} - -#define BITMASK1 0x01 -#define BITMASK2 0x03 -#define BITMASK3 0x07 -#define BITMASK4 0x0F -#define BITMASK5 0x1F -#define BITMASK6 0x3F -#define BITMASK7 0x7F -#define BITMASK8 0xFF -#define BITMASK9 0x01FF -#define BITMASK10 0x03FF - -typedef struct decoded_codepoint_s decoded_codepoint_t; -struct decoded_codepoint_s { - uint32_t codepoint; - uint32_t advance; -}; - -static uint8_t utf8_class[32] = { - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, 4, 5, -}; - -static decoded_codepoint_t -codepoint_from_utf8(uint8_t *str, uint64_t max) -{ - decoded_codepoint_t result = { - .codepoint = 0xFFFFFFFF, - .advance = 1, - }; - - uint8_t byte = str[0]; - uint8_t byte_class = utf8_class[byte >> 3]; - - switch (byte_class) { - case 1: - result.codepoint = byte; - break; - - case 2: - if (2 <= max) { - uint8_t cont_byte = str[1]; - if (utf8_class[cont_byte >> 3] == 0) { - result.codepoint = (byte & BITMASK5) << 6; - result.codepoint |= (cont_byte & BITMASK6); - result.advance = 2; - } - } - break; - - case 3: - if (3 <= max) { - uint8_t cont_byte[2] = {str[1], str[2]}; - if (utf8_class[cont_byte[0] >> 3] == 0 && utf8_class[cont_byte[1] >> 3] == 0) { - result.codepoint = (byte & BITMASK4) << 12; - result.codepoint |= ((cont_byte[0] & BITMASK6) << 6); - result.codepoint |= (cont_byte[1] & BITMASK6); - result.advance = 3; - } - } - break; - - case 4: - if (4 <= max) { - uint8_t cont_byte[3] = {str[1], str[2], str[3]}; - if (utf8_class[cont_byte[0] >> 3] == 0 && utf8_class[cont_byte[1] >> 3] == 0 && - utf8_class[cont_byte[2] >> 3] == 0) { - result.codepoint = (byte & BITMASK3) << 18; - result.codepoint |= ((cont_byte[0] & BITMASK6) << 12); - result.codepoint |= ((cont_byte[1] & BITMASK6) << 6); - result.codepoint |= (cont_byte[2] & BITMASK6); - result.advance = 4; - } - } - break; - } - - if (result.advance == 2 && result.codepoint < 0x80) { - result.codepoint = 0xFFFFFFFF; - } - - if (result.advance == 3 && result.codepoint < 0x800) { - result.codepoint = 0xFFFFFFFF; - } - - if (result.advance == 4 && (result.codepoint < 0x10000 || result.codepoint > 0x10FFFF)) { - result.codepoint = 0xFFFFFFFF; - } - - if (result.codepoint >= 0xD800 && result.codepoint <= 0xDFFF) { - result.codepoint = 0xFFFFFFFF; - } - - return result; -} - -static decoded_codepoint_t -codepoint_from_utf16(uint16_t *str, uint64_t max) -{ - decoded_codepoint_t result = { - .codepoint = 0xFFFFFFFF, - .advance = 1, - }; - - if (!max) { - return result; - } - - uint16_t w0 = str[0]; - if (w0 >= 0xD800 && w0 <= 0xDBFF) { - if (max >= 2) { - uint16_t w1 = str[1]; - if (w1 >= 0xDC00 && w1 <= 0xDFFF) { - result.codepoint = 0x10000 + (((uint32_t)(w0 - 0xD800) << 10) | ((uint32_t)(w1 - 0xDC00) & 0x3FF)); - result.advance = 2; - return result; - } - } - return result; - } - - if (w0 >= 0xDC00 && w0 <= 0xDFFF) { - return result; - } - - result.codepoint = w0; - return result; -} - -static uint64_t -utf8_len_from_codepoint(uint32_t codepoint) -{ -#define BIT8 0x80 - uint32_t advance = 0; - if (codepoint <= 0x7F) { - advance = 1; - } else if (codepoint <= 0x7FF) { - advance = 2; - } else if (codepoint <= 0xFFFF) { - advance = 3; - } else if (codepoint <= 0x10FFFF) { - advance = 4; - } else { - advance = 1; - } -#undef BIT8 - return advance; -} - -static uint32_t -utf8_from_codepoint(uint8_t *out, uint32_t codepoint) -{ -#define BIT8 0x80 - uint32_t advance = 0; - if (codepoint <= 0x7F) { - out[0] = (uint8_t)codepoint; - advance = 1; - } else if (codepoint <= 0x7FF) { - out[0] = (BITMASK2 << 6) | ((codepoint >> 6) & BITMASK5); - out[1] = BIT8 | (codepoint & BITMASK6); - advance = 2; - } else if (codepoint <= 0xFFFF) { - out[0] = (BITMASK3 << 5) | ((codepoint >> 12) & BITMASK4); - out[1] = BIT8 | ((codepoint >> 6) & BITMASK6); - out[2] = BIT8 | (codepoint & BITMASK6); - advance = 3; - } else if (codepoint <= 0x10FFFF) { - out[0] = (BITMASK4 << 4) | ((codepoint >> 18) & BITMASK3); - out[1] = BIT8 | ((codepoint >> 12) & BITMASK6); - out[2] = BIT8 | ((codepoint >> 6) & BITMASK6); - out[3] = BIT8 | (codepoint & BITMASK6); - advance = 4; - } else { - out[0] = '?'; - advance = 1; - } -#undef BIT8 - return advance; -} - -static uint32_t -utf16_from_codepoint(uint16_t *out, uint32_t codepoint) -{ - uint32_t advance = 1; - if (codepoint == 0xFFFFFFFF) { - out[0] = (uint16_t)'?'; - } else if (codepoint < 0x10000) { - out[0] = (uint16_t)codepoint; - } else { - uint64_t v = codepoint - 0x10000; - out[0] = 0xD800 + (uint16_t)(v >> 10); - out[1] = 0xDC00 + (uint16_t)(v & BITMASK10); - advance = 2; - } - return advance; -} - -#undef BITMASK10 -#undef BITMASK9 -#undef BITMASK8 -#undef BITMASK7 -#undef BITMASK6 -#undef BITMASK5 -#undef BITMASK4 -#undef BITMASK3 -#undef BITMASK2 -#undef BITMASK1 - -str_t -str_from_str16(mod_arena_t arena, str16_t in) -{ - uint64_t cap = in.len * 3; // worst case UTF-8 - uint8_t *buf = mod_arena_push(arena, cap + 1, 1); - uint16_t *ptr = in.data; - uint16_t *opl = ptr + in.len; - uint64_t size = 0; - - if (buf) { - while (ptr < opl) { - decoded_codepoint_t c = codepoint_from_utf16(ptr, (uint64_t)(opl - ptr)); - - ptr += c.advance; - size += utf8_from_codepoint(buf + size, c.codepoint); - } - buf[size] = 0; - mod_arena_pop(arena, cap - size); - } - - return str_make(buf, size); -} - -str16_t -str16_from_str(mod_arena_t arena, str_t in) -{ - uint64_t cap = in.len * 2; // worst case UTF-16 - uint16_t *buf = mod_arena_push(arena, (cap + 1) * 2, 2); - uint8_t *ptr = in.data; - uint8_t *opl = ptr + in.len; - uint64_t size = 0; - - if (buf) { - while (ptr < opl) { - decoded_codepoint_t c = codepoint_from_utf8(ptr, (uint64_t)(opl - ptr)); - - ptr += c.advance; - size += utf16_from_codepoint(buf + size, c.codepoint); - } - buf[size] = 0; - mod_arena_pop(arena, (cap - size) * sizeof(uint16_t)); - } - - return str16_make(buf, size); -} - -uint64_t -str16_utf8_len(str16_t in) -{ - uint16_t *ptr = in.data; - uint16_t *opl = ptr + in.len; - uint64_t len = 0; - - while (ptr < opl) { - decoded_codepoint_t c = codepoint_from_utf16(ptr, (uint64_t)(opl - ptr)); - - ptr += c.advance; - len += utf8_len_from_codepoint(c.codepoint); - } - - return len; -} - -uint64_t -str16_write_utf8(uint8_t *buf, uint64_t max_len, str16_t in) -{ - uint16_t *ptr = in.data; - uint16_t *opl = ptr + in.len; - uint64_t len = 0; - - while (ptr < opl) { - decoded_codepoint_t c = codepoint_from_utf16(ptr, (uint64_t)(opl - ptr)); - uint64_t bytes = utf8_len_from_codepoint(c.codepoint); - - if (len + bytes > max_len) { - break; - } - - ptr += c.advance; - len += utf8_from_codepoint(buf + len, c.codepoint); - } - - return len; -} - -/* ====================================================== PATH ====================================================== */ - -str_t -path_base(str_t path) -{ - uint64_t last_slash_idx = 0; - if (str_rfind(path, STR_LIT("/"), STR_CMP_FLAG_IGNORE_SLASHES, &last_slash_idx)) { - path = str_slice(path, last_slash_idx + 1, path.len); - } - return path; -} - -str_t -path_dir(str_t path) -{ - uint64_t last_slash_idx = 0; - str_rfind(path, STR_LIT("/"), STR_CMP_FLAG_IGNORE_SLASHES, &last_slash_idx); - return str_slice(path, 0, last_slash_idx); -} - -str_t -path_get_ext(str_t path) -{ - uint64_t dot_idx = 0; - - path = path_base(path); - if (str_rfind(path, STR_LIT("."), 0, &dot_idx)) { - path = str_slice(path, dot_idx + 1, path.len); - } else { - path = STR_NULL; - } - return path; -} - -str_t -path_trim_ext(str_t path) -{ - uint64_t idx = 0; - if (str_rfind_any(path, STR_LIT("./"), STR_CMP_FLAG_IGNORE_SLASHES, &idx) && path.data[idx] == '.') { - path = str_slice(path, 0, idx); - } - return path; -} - -static bool -path_is_sep(uint8_t c) -{ - return c == '/' || c == '\\'; -} - -str_t -path_replace_slashes_inplace(str_t path, char ch) -{ - for (uint64_t i = 0; i < path.len; ++i) { - if (path_is_sep(path.data[i])) { - path.data[i] = ch; - } - } - return path; -} - -static str_t -path_trim_trailing_seps(str_t path) -{ - while (path.len > 0) { - uint8_t c = path.data[path.len - 1]; - if (!path_is_sep(c)) { - break; - } - - /* keep "/" intact */ - if (path.len == 1) { - break; - } - - /* keep "C:/" intact */ - if (path.len == 3 && - ascii_is_alpha(path.data[0]) && - path.data[1] == ':' && - path_is_sep(path.data[2])) { - break; - } - - path.len -= 1; - } - - return path; -} - -bool -path_equal(str_t a, str_t b) -{ - a = path_trim_trailing_seps(a); - b = path_trim_trailing_seps(b); - return str_equal(a, b, STR_CMP_FLAG_IGNORE_CASE|STR_CMP_FLAG_IGNORE_SLASHES); -} - -bool -path_has_prefix(str_t path, str_t prefix) -{ - path = path_trim_trailing_seps(path); - prefix = path_trim_trailing_seps(prefix); - - if (str_is_empty(prefix)) { - return true; - } - - if (prefix.len > path.len) { - return false; - } - - if (!str_has_prefix(path, prefix, STR_CMP_FLAG_IGNORE_CASE|STR_CMP_FLAG_IGNORE_SLASHES)) { - return false; - } - - /* exact match */ - if (prefix.len == path.len) { - return true; - } - - /* next char must be a separator, otherwise "C:/Game" matches "C:/GameX" */ - return path_is_sep(path.data[prefix.len]); -} - -bool -path_make_relative(str_t path, str_t base, str_t *out) -{ - if (out) { - *out = STR_NULL; - } - - path = path_trim_trailing_seps(path); - base = path_trim_trailing_seps(base); - - if (!path_has_prefix(path, base)) { - return false; - } - - if (base.len == path.len) { - if (out) { - *out = STR_NULL; - } - return true; - } - - uint64_t start = base.len; - while (start < path.len && path_is_sep(path.data[start])) { - start += 1; - } - - if (out) { - *out = str_slice(path, start, path.len); - } - return true; -} - -str_t -path_push_relative(mod_arena_t arena, str_t path, str_t base) -{ - str_t rel = STR_NULL; - if (!path_make_relative(path, base, &rel)) { - return STR_NULL; - } - - rel = str_push_copy(arena, rel); - return path_replace_slashes_inplace(rel, '/'); -} - -bool -path_is_abs(str_t path) -{ - // /mnt/c/Users/user/AppData - if (str_has_prefix(path, STR_LIT("/"), STR_CMP_FLAG_IGNORE_SLASHES)) { - return true; - } - - // D:\\Users\\user\\AppData - if (path.len >= 3 && ascii_is_alpha(path.data[0]) && path.data[1] == ':' && path_is_sep(path.data[2])) { - return true; - } - - return false; -} - -str_list_t -path_push_parts(mod_arena_t arena, str_t path) -{ - str_t splits[] = { - STR_LIT("/"), - STR_LIT("\\"), - }; - - return str_split(arena, path, COUNTOF(splits), splits); -} - -str_t -path_module_dir(mod_arena_t perm) -{ - wchar_t buf[MAX_PATH + 1] = {0}; - HMODULE h_mod = NULL; - - GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | - GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, - (LPCWSTR)path_module_dir, - &h_mod); - - DWORD len = GetModuleFileNameW(h_mod, buf, COUNTOF(buf)); - if (len == 0 || len >= COUNTOF(buf)) { - return (str_t){0}; - } - - str16_t full_path16 = str16_make((uint16_t *)buf, (uint64_t)len); - str_t full_path = str_from_str16(perm, full_path16); - return path_dir(full_path); -} - -str_t -path_join(mod_arena_t arena, str_t a, str_t b) -{ - str_t result = {0}; - if (str_is_empty(a)) { - result = str_push_copy(arena, b); - } else if (str_is_empty(b)) { - result = str_push_copy(arena, a); - } else { - str_t sep = STR_LIT("/"); - - if (str_has_suffix(a, sep, STR_CMP_FLAG_IGNORE_SLASHES)) { - a = str_slice(a, 0, a.len - 1); - } - - if (str_has_prefix(b, sep, STR_CMP_FLAG_IGNORE_SLASHES)) { - b = str_slice(b, 1, b.len); - } - - uint64_t len = a.len + sep.len + b.len; - uint8_t *buf = mod_arena_push(arena, len, 1); - if (buf) { - memcpy(buf + 0, a.data, a.len); - memcpy(buf + a.len, sep.data, sep.len); - memcpy(buf + a.len + sep.len, b.data, b.len); - result = str_make(buf, len); - } - } - - // normalize - return path_replace_slashes_inplace(result, '/'); -} - -/* ====================================================== FILE ====================================================== */ - -bool -file_exists(str_t path) -{ - if (str_is_empty(path)) { - return false; - } - - tmp_arena_t tmp = mod_scratch_begin(MOD_ARENA_INVALID); - str16_t path16 = str16_from_str(tmp.arena, path); - - DWORD attr = GetFileAttributesW(path16.data); - bool exists = (attr != INVALID_FILE_ATTRIBUTES) && !(attr & FILE_ATTRIBUTE_DIRECTORY); - - mod_scratch_end(tmp); - return exists; -} - -uint64_t -file_size(str_t path) -{ - if (str_is_empty(path)) { - return 0; - } - - tmp_arena_t tmp = mod_scratch_begin(MOD_ARENA_INVALID); - str16_t path16 = str16_from_str(tmp.arena, path); - uint64_t size = 0; - - WIN32_FILE_ATTRIBUTE_DATA data; - if (GetFileAttributesExW(path16.data, GetFileExInfoStandard, &data)) { - size = ((uint64_t)data.nFileSizeHigh << 32) | (uint64_t)data.nFileSizeLow; - } - - mod_scratch_end(tmp); - return size; -} - -str_t -file_read_all(str_t path, mod_arena_t arena) -{ - str_t result = {0}; - if (str_is_empty(path) || !arena) { - return result; - } - - tmp_arena_t tmp = mod_scratch_begin(arena); - str16_t path16 = str16_from_str(tmp.arena, path); - - HANDLE h = CreateFileW(path16.data, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (h != INVALID_HANDLE_VALUE) { - LARGE_INTEGER size_li; - if (GetFileSizeEx(h, &size_li) && size_li.QuadPart > 0) { - uint64_t size = size_li.QuadPart; - uint64_t used = mod_arena_pos(arena); - uint8_t *data = MOD_ARENA_PUSH_ARRAY_ZERO(arena, uint8_t, size + 1); - if (data) { - uint64_t total_read = 0; - while (total_read < size) { - DWORD to_read = (DWORD)MIN_VAL((uint64_t)UINT32_MAX, (size - total_read)); - DWORD just_read = 0; - - if (!ReadFile(h, data + total_read, to_read, &just_read, NULL)) { - break; - } - - if (just_read == 0) { - break; - } - - total_read += just_read; - } - - if (total_read != size) { - mod_arena_pop_to(arena, used); - } else { - result = str_make(data, total_read); - } - } - } - CloseHandle(h); - } - - mod_scratch_end(tmp); - return result; -} - -bool -file_write(str_t s, str_t path) -{ - if (str_is_empty(path)) { - return false; - } - - tmp_arena_t tmp = mod_scratch_begin(MOD_ARENA_INVALID); - str16_t path16 = str16_from_str(tmp.arena, path); - bool result = false; - - HANDLE h = CreateFileW(path16.data, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (h != INVALID_HANDLE_VALUE) { - if (str_is_empty(s)) { - // empty string -> empty file - result = true; - } else { - bool success = true; - uint64_t total_written = 0; - while (total_written < s.len) { - DWORD to_write = (DWORD)MIN_VAL((uint64_t)UINT32_MAX, (s.len - total_written)); - DWORD just_written = 0; - - if (!WriteFile(h, s.data + total_written, to_write, &just_written, NULL)) { - success = false; - break; - } - - if (just_written == 0) { - success = false; - break; - } - - total_written += (uint64_t)just_written; - } - result = success && (total_written == s.len); - } - CloseHandle(h); - } - - mod_scratch_end(tmp); - return result; -} - -bool -file_write_lines(str_list_t lines, str_t path) -{ - if (str_is_empty(path)) { - return false; - } - - tmp_arena_t tmp = mod_scratch_begin(MOD_ARENA_INVALID); - str16_t path16 = str16_from_str(tmp.arena, path); - bool result = false; - - HANDLE h = CreateFileW(path16.data, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (h != INVALID_HANDLE_VALUE) { - bool success = true; - uint64_t total_written = 0; - uint64_t total_size = lines.total_bytes + (lines.count > 1 ? lines.count - 1 : 0); - - for (str_node_t *node = lines.first; node && success; node = node->next) { - str_t chunks[] = { - node->str, - (node != lines.last) ? STR_LIT("\n") : STR_NULL, - }; - - for (uint64_t chunk_idx = 0; chunk_idx < 2; ++chunk_idx) { - str_t chunk = chunks[chunk_idx]; - if (str_is_empty(chunk)) { - continue; - } - - uint64_t chunk_written = 0; - while (chunk_written < chunk.len) { - DWORD to_write = (DWORD)MIN_VAL((uint64_t)UINT32_MAX, (chunk.len - chunk_written)); - DWORD just_written = 0; - - if (!WriteFile(h, chunk.data + chunk_written, to_write, &just_written, NULL)) { - success = false; - break; - } - - if (just_written == 0) { - success = false; - break; - } - - chunk_written += (uint64_t)just_written; - total_written += (uint64_t)just_written; - } - } - } - - result = success && (total_written == total_size); - CloseHandle(h); - } - - mod_scratch_end(tmp); - return result; -} - -bool -file_copy(str_t dst, str_t src) -{ - if (str_is_empty(dst) || str_is_empty(src)) { - return false; - } - - tmp_arena_t tmp = mod_scratch_begin(MOD_ARENA_INVALID); - str16_t src16 = str16_from_str(tmp.arena, src); - str16_t dst16 = str16_from_str(tmp.arena, dst); - - bool result = (CopyFileW(src16.data, dst16.data, FALSE) != 0); - - mod_scratch_end(tmp); - return result; -} - -bool -file_delete(str_t path) -{ - if (str_is_empty(path)) { - return false; - } - - tmp_arena_t tmp = mod_scratch_begin(MOD_ARENA_INVALID); - str16_t path16 = str16_from_str(tmp.arena, path); - - bool result = (DeleteFileW(path16.data) != 0); - - mod_scratch_end(tmp); - return result; -} - -bool -dir_exists(str_t path) -{ - if (str_is_empty(path)) { - return false; - } - - tmp_arena_t tmp = mod_scratch_begin(MOD_ARENA_INVALID); - str16_t path16 = str16_from_str(tmp.arena, path); - - DWORD attr = GetFileAttributesW(path16.data); - bool exists = (attr != INVALID_FILE_ATTRIBUTES) && (attr & FILE_ATTRIBUTE_DIRECTORY); - - mod_scratch_end(tmp); - return exists; -} - -bool -dir_create(str_t path) -{ - if (dir_exists(path)) { - return true; - } - - tmp_arena_t tmp = mod_scratch_begin(MOD_ARENA_INVALID); - str16_t path16 = str16_from_str(tmp.arena, path); - - bool result = CreateDirectoryW(path16.data, NULL) || GetLastError() == ERROR_ALREADY_EXISTS; - - mod_scratch_end(tmp); - return result; -} - -bool -dir_create_recursive(str_t path) -{ - if (str_is_empty(path)) { - return false; - } - - if (dir_exists(path)) { - return true; - } - - /* walk the path and create each segment */ - for (uint64_t i = 0; i < path.len; ++i) { - uint8_t c = path.data[i]; - if (c == '/' || c == '\\') { - str_t segment = str_slice(path, 0, i); - if (!str_is_empty(segment) && !dir_exists(segment)) { - if (!dir_create(segment)) { - return false; - } - } - } - } - - return dir_create(path); -} - -static inline bool -is_current_or_parent_dir(const wchar_t *name) -{ - if (!name || name[0] == L'\0') { - return false; - } - - /* '.' and '..' */ - return (name[0] == L'.' && (name[1] == L'\0' || (name[1] == L'.' && name[2] == L'\0'))); -} - -static dir_entry_list_t -dir_list_internal(str_t path, str_t pattern, mod_arena_t arena) -{ - tmp_arena_t tmp = mod_scratch_begin(arena); - dir_entry_list_t result = {0}; - - path = path_replace_slashes_inplace(str_push_copy(tmp.arena, path), '\\'); - - /* build search pattern: path\* or path\pattern */ - str_t search_pattern; - if (str_is_empty(path)) { - if (str_is_empty(pattern)) { - search_pattern = STR_LIT("*"); - } else { - search_pattern = pattern; - } - } else { - if (str_is_empty(pattern)) { - search_pattern = str_push_fmt(tmp.arena, "%.*s\\*", STR_ARG(path)); - } else { - search_pattern = str_push_fmt(tmp.arena, "%.*s\\%.*s", STR_ARG(path), STR_ARG(pattern)); - } - } - - str16_t pattern16 = str16_from_str(tmp.arena, search_pattern); - - WIN32_FIND_DATAW fd; - HANDLE h = FindFirstFileW(pattern16.data, &fd); - if (h != INVALID_HANDLE_VALUE) { - /* first pass: count entries */ - int count = 0; - do { - if (is_current_or_parent_dir(fd.cFileName)) { - continue; - } - count += 1; - } while (FindNextFileW(h, &fd)); - FindClose(h); - - if (count > 0) { - /* second pass: fill entries */ - result.items = MOD_ARENA_PUSH_ARRAY_ZERO(arena, dir_entry_t, count); - result.count = 0; - - if (result.items) { - h = FindFirstFileW(pattern16.data, &fd); - if (h != INVALID_HANDLE_VALUE) { - do { - if (is_current_or_parent_dir(fd.cFileName)) { - continue; - } - - if (result.count >= count) { - break; - } - - dir_entry_t *entry = &result.items[result.count]; - str16_t name16 = str16_from_wstr(fd.cFileName); - - entry->name = str_from_str16(arena, name16); - entry->path = path_join(arena, path, entry->name); - entry->kind = (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? DIR_ENTRY_DIR : DIR_ENTRY_FILE; - entry->size = ((uint64_t)fd.nFileSizeHigh << 32) | (uint64_t)fd.nFileSizeLow; - - result.count += 1; - } while (FindNextFileW(h, &fd)); - FindClose(h); - } - } - } - } - - mod_scratch_end(tmp); - return result; -} - -dir_entry_list_t -dir_list(str_t path, mod_arena_t arena) -{ - return dir_list_internal(path, (str_t){0}, arena); -} - -dir_entry_list_t -dir_list_filter(str_t path, str_t pattern, mod_arena_t arena) -{ - return dir_list_internal(path, pattern, arena); -} - -bool -dir_delete(str_t path) -{ - if (str_is_empty(path)) { - return false; - } - - tmp_arena_t tmp = mod_scratch_begin(MOD_ARENA_INVALID); - str16_t path16 = str16_from_str(tmp.arena, path); - - bool result = (RemoveDirectoryW(path16.data) != 0); - - mod_scratch_end(tmp); - return result; -} - -bool -dir_delete_recursive(str_t path) -{ - tmp_arena_t tmp = mod_scratch_begin(MOD_ARENA_INVALID); - dir_entry_list_t entries = dir_list(path, tmp.arena); - for (int i = 0; i < entries.count; ++i) { - dir_entry_t *e = &entries.items[i]; - if (e->kind == DIR_ENTRY_DIR) { - dir_delete_recursive(e->path); - } else { - file_delete(e->path); - } - } - - mod_scratch_end(tmp); - return dir_delete(path); -} - -/* =================================================== INI PARSER =================================================== */ - -bool -ini_is_line_section(str_t line) -{ - return (line.len >= 2 && line.data[0] == '[' && line.data[line.len - 1] == ']'); -} - -bool -ini_parse_section_header(str_t line, str_t *out_name, str_t *out_arg) -{ - *out_name = (str_t){0}; - *out_arg = (str_t){0}; - - str_t body = str_trim_space(str_slice(line, 1, line.len - 1)); - uint64_t dot_idx = 0; - if (str_find(body, STR_LIT("."), 0, &dot_idx)) { - *out_name = str_trim_space(str_slice(body, 0, dot_idx)); - *out_arg = str_trim_space(str_slice(body, dot_idx + 1, body.len)); - } else { - *out_name = body; - } - - return !str_is_empty(*out_name); -} - -static void -ini_section_list_push(ini_section_list_t *list, ini_section_t *section) -{ - QUEUE_PUSH(list->first, list->last, section); - list->count += 1; -} - -ini_section_list_t -ini_parse_sections(mod_arena_t arena, str_array_t lines) -{ - ini_section_list_t result = {0}; - ini_section_t *section = NULL; - for (uint64_t i = 0; i < lines.count; ++i) { - str_t line = lines.items[i]; - - if (ini_is_line_section(line)) { - str_t name = {0}; - str_t arg = {0}; - if (ini_parse_section_header(line, &name, &arg)) { - section = MOD_ARENA_PUSH_ZERO(arena, ini_section_t); - if (section) { - section->name = str_push_copy(arena, name); - section->arg = str_push_copy(arena, arg); - - ini_section_list_push(&result, section); - } - } else { - section = NULL; - } - continue; - } - - if (section) { - str_list_push(arena, §ion->lines, str_push_copy(arena, line)); - } - } - - return result; -} - -bool -ini_parse_kv(str_t line, str_t *out_key, str_t *out_value) -{ - if (!out_key || !out_value) { - return false; - } - - if (str_is_empty(line)) { - return false; - } - - *out_key = (str_t){0}; - *out_value = (str_t){0}; - - uint64_t eq_idx = 0; - if (!str_find(line, STR_LIT("="), 0, &eq_idx)) { - return false; - } - - *out_key = str_trim_space(str_slice(line, 0, eq_idx)); - *out_value = str_trim_space(str_slice(line, eq_idx + 1, line.len)); - - return !str_is_empty(*out_key); -} - -str_array_t -ini_split_lines(mod_arena_t arena, str_t text) -{ - if (!arena || str_is_empty(text)) { - return (str_array_t){0}; - } - - tmp_arena_t tmp = mod_scratch_begin(arena); - str_array_t out_array = {0}; - { - str_list_t parts = {0}; - str_list_t raw_lines = str_split_lines(tmp.arena, text); - for (str_node_t *node = raw_lines.first; node; node = node->next) { - str_t line = node->str; - - line = str_trim_comment(line, STR_LIT(";"), 0); - line = str_trim_space(line); - - str_list_push(tmp.arena, &parts, line); - } - out_array = str_array_copy_from_list(arena, parts); - } - mod_scratch_end(tmp); - - return out_array; -} diff --git a/mod/mod_sdk.h b/mod/mod_sdk.h deleted file mode 100644 index 1dcfbc4..0000000 --- a/mod/mod_sdk.h +++ /dev/null @@ -1,1063 +0,0 @@ -#ifndef MOD_SDK_H -#define MOD_SDK_H - -#include "mod_api.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* ====================================================== TYPES ===================================================== */ - -/* -------------------------- feature-test helpers -------------------------- */ - -#ifndef __has_attribute -# define __has_attribute(x) 0 -#endif - -#ifndef __has_builtin -# define __has_builtin(x) 0 -#endif - -#ifndef __has_cpp_attribute -# define __has_cpp_attribute(x) 0 -#endif - -#ifndef __has_include -# define __has_include(x) 0 -#endif - -/* -------------------------------- alignof --------------------------------- */ - -#if defined(_MSC_VER) -# define MOD_ALIGNOF(T) __alignof(T) -#elif defined(__clang__) || defined(__GNUC__) -# define MOD_ALIGNOF(T) __alignof__(T) -#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) -# define MOD_ALIGNOF(T) _Alignof(T) -#elif defined(__cplusplus) -# define MOD_ALIGNOF(T) alignof(T) -#else -# warning "alignof not supported" -#endif - -/* align specifier for type declarations (struct/union/class) */ -/* Usage: ALIGNED_TYPE(struct, 32) Name { ...members... }; */ -#if defined(_MSC_VER) -# define MOD_ALIGNED_TYPE(TYPE_KEYWORD, N) __declspec(align(N)) TYPE_KEYWORD -#elif defined(__clang__) || defined(__GNUC__) -# define MOD_ALIGNED_TYPE(TYPE_KEYWORD, N) TYPE_KEYWORD __attribute__((aligned(N))) -#else -# define MOD_ALIGNED_TYPE(TYPE_KEYWORD, N) TYPE_KEYWORD -#endif - -/* format(printf) for checking printf-like functions */ -#if defined(__clang__) || defined(__GNUC__) || __has_attribute(format) -/* 1-based indices: fmt starts at 'fmt_index', args at 'vararg_index' */ -# define MOD_ATTR_FORMAT(fmt_index, vararg_index) __attribute__((format(printf, fmt_index, vararg_index))) -#else -# define MOD_ATTR_FORMAT(fmt_index, vararg_index) -#endif - -#if !defined MOD_DISABLE_ASSERT -/* - * Shows an assertion dialog with the failed expression and optional message. - * Abort exits the process, Retry breaks into the debugger, and Ignore continues. - */ -void -mod_assert_msg(const char *expr, const char *file, int line, const char *fmt, ...) MOD_ATTR_FORMAT(4, 5); - -# define MOD_ASSERT(COND) \ - do { \ - if (!(COND)) { \ - mod_assert_msg(#COND, __FILE__, __LINE__, NULL); \ - } \ - } while (0) -# define MOD_ASSERT_MSG(COND, ...) \ - do { \ - if (!(COND)) { \ - mod_assert_msg(#COND, __FILE__, __LINE__, __VA_ARGS__); \ - } \ - } while (0) -#else -# define MOD_ASSERT(COND) \ - do { \ - (void)sizeof(COND); \ - } while (0) -# define MOD_ASSERT_MSG(COND, ...) \ - do { \ - (void)sizeof(COND); \ - } while (0) -#endif - -#define AS_BOOL(x) !!(x) -#define FLAG(bit) (1 << (bit)) - -#define IN_RANGE(v, min, max) (((v) >= (min)) && ((v) <= (max))) - -#define MAX_VAL(a, b) (((a) > (b)) ? (a) : (b)) -#define MIN_VAL(a, b) (((a) < (b)) ? (a) : (b)) - -#define CLAMP(v, min, max) (((v) > (max)) ? (max) : (((v) < (min)) ? (min) : (v))) -#define CLAMP_TOP(v, max) MIN_VAL(v, max) -#define CLAMP_BOTTOM(v, min) MAX_VAL(v, min) - -#ifndef COUNTOF -# define COUNTOF(array) (int)(sizeof(array) / sizeof((array)[0])) -#endif - -/* alignment must be a power-of-two */ -#define ALIGN_DOWN(size, alignment) ((size) & ~((alignment) - 1)) -#define ALIGN_UP(size, alignment) ALIGN_DOWN(size + alignment - 1, alignment) - -#define ENSURE_STR_LIT(x) "" x "" -#define BOOL_AS_STR(v) ((v) ? "true" : "false") - -#define KB (1024 * 1ULL) -#define MB (1024 * KB) -#define GB (1024 * MB) -#define TB (1024 * GB) - -/* ======================================================= SDK ===================================================== */ - -typedef struct { - const mod_host_api_t *host; - mod_t mod; -} mod_sdk_t; - -/* Returns the host API saved by mod_sdk_init. Asserts if the SDK is not initialized. */ -const mod_host_api_t * -mod_sdk_host(void); -/* Returns this mod's loader handle. Asserts if the SDK is not initialized. */ -mod_t -mod_sdk_mod_handle(void); - -/* - * Checks the required host API prefix and ABI version, then stores the host API and mod handle. - * This must succeed before any other SDK function is used. Major and minor ABI versions must match; - * optional fields appended in patch releases are checked by the wrappers that use them. - */ -bool -mod_sdk_init(const mod_host_api_t *host, mod_t mod); - -extern mod_sdk_t g_sdk; - -/* True when HOST contains FIELD and it is safe to read that function pointer. */ -#define MOD_HOST_API_HAS_FIELD(HOST, FIELD) \ - ((HOST) != NULL && (HOST)->struct_size >= (offsetof(mod_host_api_t, FIELD) + sizeof((HOST)->FIELD))) - -/* ======================================================= MOD ===================================================== */ - -#define MOD_LOG_ERROR(...) mod_log(LOG_LEVEL_ERROR, __VA_ARGS__) -#define MOD_LOG_WARN(...) mod_log(LOG_LEVEL_WARN, __VA_ARGS__) -#define MOD_LOG_INFO(...) mod_log(LOG_LEVEL_INFO, __VA_ARGS__) -#define MOD_LOG_DEBUG(...) mod_log(LOG_LEVEL_DEBUG, __VA_ARGS__) - -/* Writes a formatted message to the loader log. */ -void -mod_log(log_level_t level, const char *fmt, ...); -/* Writes a formatted message to the loader log using an existing va_list. */ -void -mod_logv(log_level_t level, const char *fmt, va_list args); - -/* Returns a loader-owned string of this mod's directory path. */ -str_t -mod_get_mod_dir(void); -/* Returns a loader-owned string of this mod's config file path. */ -str_t -mod_get_config_path(void); -/* Returns a loader-owned string of this mod's manifest file path. */ -str_t -mod_get_manifest_path(void); -/* Finds a config entry declared by this mod. Returns MOD_CFG_INVALID when it is not found. */ -mod_cfg_t -mod_get_cfg_by_id(str_t id); -/* Registers a console command callback for this mod. Returns false if registration fails. */ -bool -mod_register_cmd(str_t name, str_t description, mod_cmd_fn_t fn, void *user); - -/* ======================================================== UI ====================================================== */ - -/* Returns the loader's Nuklear context. Use it to draw UI (in tick, draw_panel, draw_config). */ -struct nk_context * -mod_get_nk_ctx(void); -/* Writes the current viewport size. Either output pointer may be NULL. */ -void -mod_get_viewport_size(unsigned int *vw, unsigned int *vh); - -/* Returns current value of frame counter. */ -uint64_t -mod_get_frame_counter(void); -/* Returns current FPS value. */ -float -mod_get_fps(void); - -/* ======================================================= CFG ===================================================== */ - -/* Returns a bool config value, or false when the handle cannot provide one. */ -bool -mod_cfg_get_bool(mod_cfg_t cfg); -/* Returns an integer config value, or 0 when the handle cannot provide one. */ -int -mod_cfg_get_int(mod_cfg_t cfg); -/* Returns a float config value, or 0.0f when the handle cannot provide one. */ -float -mod_cfg_get_float(mod_cfg_t cfg); -/* Returns an enum config index, or -1 when the handle cannot provide one. */ -int -mod_cfg_get_enum(mod_cfg_t cfg); -/* Returns the string config length in bytes, not including a null terminator. */ -uint64_t -mod_cfg_get_string_len(mod_cfg_t cfg); -/* Copies up to cap bytes from a string config and returns the number copied. No null terminator is added. */ -uint64_t -mod_cfg_get_string_data(mod_cfg_t cfg, void *buf, uint64_t cap); -/* Copies a string config into an arena and adds a null terminator. Returns STR_NULL for an empty or invalid value. */ -str_t -mod_cfg_push_string(mod_cfg_t cfg, mod_arena_t arena); -/* Returns a keybind config value, or an empty keybind when the handle cannot provide one. */ -keybind_t -mod_cfg_get_keybind(mod_cfg_t cfg); -/* Returns a color config value, or zeroed color data when the handle cannot provide one. */ -mod_color_t -mod_cfg_get_color(mod_cfg_t cfg); -/* Sets a bool config value when the handle refers to a valid and compatible entry. */ -void -mod_cfg_set_bool(mod_cfg_t cfg, bool val); -/* Sets an integer config value when the handle refers to a valid and compatible entry. */ -void -mod_cfg_set_int(mod_cfg_t cfg, int val); -/* Sets a float config value when the handle refers to a valid and compatible entry. */ -void -mod_cfg_set_float(mod_cfg_t cfg, float val); -/* Sets an enum config index when the handle refers to a valid and compatible entry. */ -void -mod_cfg_set_enum(mod_cfg_t cfg, int val); -/* Sets a string config value. The loader copies the supplied bytes. */ -void -mod_cfg_set_string(mod_cfg_t cfg, str_t val); -/* Sets a keybind config value when the handle refers to a valid and compatible entry. */ -void -mod_cfg_set_keybind(mod_cfg_t cfg, keybind_t val); -/* Sets a color config value when the handle refers to a valid and compatible entry. */ -void -mod_cfg_set_color(mod_cfg_t cfg, mod_color_t val); - -/* ====================================================== ARENA ===================================================== */ - -#define MOD_ARENA_PUSH_ARRAY(ARENA, T, N) (T *)mod_arena_push((ARENA), (N) * sizeof(T), MOD_ALIGNOF(T)) -#define MOD_ARENA_PUSH_ARRAY_ZERO(ARENA, T, N) (T *)mod_arena_push_zero((ARENA), (N) * sizeof(T), MOD_ALIGNOF(T)) -#define MOD_ARENA_PUSH(ARENA, T) MOD_ARENA_PUSH_ARRAY(ARENA, T, 1) -#define MOD_ARENA_PUSH_ZERO(ARENA, T) MOD_ARENA_PUSH_ARRAY_ZERO(ARENA, T, 1) - -/* - * Returns this mod's permanent arena. - * Allocations stay valid until the mod is unloaded. - * Destroyed automatically by the loader after mod is deinitialized (i.e. deinit called). - */ -mod_arena_t -mod_get_perm(void); -/* - * Creates a dynamic arena owned by this mod. Returns MOD_ARENA_INVALID on failure. - * Destroyed automatically by the loader after mod is deinitialized (i.e. deinit called). - */ -mod_arena_t -mod_arena_create(uint64_t reserve_size, uint64_t commit_size); -/* - * Destroys an arena created by mod_arena_create. - * Only arenas created by this mod can be destroyed. - * Permanent arena and scratch arena cannot be destroyed. - */ -void -mod_arena_destroy(mod_arena_t arena); -/* Allocates bytes from an arena with the requested alignment. Returns NULL when the allocation cannot fit. */ -void * -mod_arena_push(mod_arena_t arena, uint64_t size, uint64_t alignment); -/* Allocates aligned bytes from an arena and clears the whole allocation. */ -void * -mod_arena_push_zero(mod_arena_t arena, uint64_t size, uint64_t alignment); -/* Returns the current used byte position of an arena. */ -uint64_t -mod_arena_pos(mod_arena_t arena); -/* - * Rewinds an arena to zero. - * Memory is NOT decommitted. - * Use this to quickly clear the arena instead of mod_arena_pop/mod_arena_pop_to (expensive). - */ -void -mod_arena_reset(mod_arena_t arena); -/* - * Rewinds an arena to a previous byte position. - * Later allocations become invalid. Memory is decommitted. - */ -void -mod_arena_pop_to(mod_arena_t arena, uint64_t pos); -/* - * Rewinds an arena by up to size bytes. - * Popping past the start resets it to zero. - * Later allocations become invalid. Memory is decommitted. - */ -void -mod_arena_pop(mod_arena_t arena, uint64_t size); -/* - * Returns a temporary (scratch) arena that is different from the supplied conflicting arena. - * Pass MOD_ARENA_INVALID when there is no conflict. Pair every call with mod_scratch_end. - */ -tmp_arena_t -mod_scratch_begin(mod_arena_t conflict); -/* Ends a scratch arena and invalidates allocations made after that scope began. */ -void -mod_scratch_end(tmp_arena_t tmp); - -/* ====================================================== INPUT ===================================================== */ - -/* Converts a key name to an input key value. Returns INPUT_KEY_NONE when unknown. */ -input_key_kind_t -mod_input_key_from_str(str_t name); -/* Returns a loader-owned name for an input key, or STR_NULL when unknown. */ -str_t -mod_input_key_to_str(input_key_kind_t key); -/* Returns a loader-owned name for an input event kind, or STR_NULL when unknown. */ -str_t -mod_input_event_kind_to_str(input_event_kind_t kind); -/* Parses a keybind string into out. Returns false for an empty or invalid bind. */ -bool -mod_keybind_parse(str_t str, keybind_t *out); -/* Returns the formatted keybind length in bytes, not including a null terminator. */ -uint64_t -mod_keybind_utf8_len(keybind_t bind); -/* Writes a formatted keybind into a buffer and returns the bytes written. No null terminator is added. */ -uint64_t -mod_keybind_utf8_write(keybind_t bind, void *buf, uint64_t cap); -/* Formats a keybind into an arena and adds a null terminator. */ -str_t -mod_keybind_to_str(keybind_t bind, mod_arena_t arena); -/* Returns whether the keybind is down in the current input state. */ -bool -mod_keybind_is_down(keybind_t bind); -/* Returns true on the frame a keybind changes from up to down. */ -bool -mod_keybind_is_pressed(keybind_t bind); -/* Returns true on the frame a keybind changes from down to up. */ -bool -mod_keybind_is_released(keybind_t bind); -/* Parses a keybind string and checks its current state. Invalid strings return false. */ -bool -mod_keybind_str_is_down(str_t keybind_str); -/* Parses a keybind string and checks for an up to down transition. */ -bool -mod_keybind_str_is_pressed(str_t keybind_str); -/* Parses a keybind string and checks for a down to up transition. */ -bool -mod_keybind_str_is_released(str_t keybind_str); -/* Returns whether the event key appears in the bind. It does not check event kind or other key states. */ -bool -mod_keybind_activated_by_event(keybind_t bind, input_event_t *ev); - -/* ========================================== HOOKING / SIGNATURE SCANNING ========================================== */ - -typedef struct sigscan_entry_s sigscan_entry_t; -struct sigscan_entry_s { - const char *name; // for debugging/logging - const char *pattern; // signature pattern, e.g. "40 55 56 ?? ..." - void **pp; // write back pointer, e.g. &ProcessEvent - uint8_t op_off; // offset of the operand inside the matched bytes - uint8_t deref; // 0..2 times *(ptr) - void *addr; // resulting address - uintptr_t first_rvas[8]; // first RVAs to try -}; - -/* using macros for templates because they're constant */ - -#define SIG_ENTRY_DIRECT(PTR, PATTERN, ...) \ - { \ - .name = #PTR, \ - .pattern = (PATTERN), \ - .pp = (void **)&PTR, \ - .op_off = 0, \ - .deref = 0, \ - .addr = NULL, \ - .first_rvas = {__VA_ARGS__}, \ - } - -#define SIG_ENTRY_MOV64_PTR(PTR, PATTERN, ...) \ - { \ - .name = #PTR, \ - .pattern = (PATTERN), \ - .pp = (void **)&PTR, \ - .op_off = 3, \ - .deref = 1, \ - .addr = NULL, \ - .first_rvas = {__VA_ARGS__}, \ - } - -#define SIG_ENTRY_MOV64_ADDR(PTR, PATTERN, ...) \ - { \ - .name = #PTR, \ - .pattern = (PATTERN), \ - .pp = (void **)&PTR, \ - .op_off = 3, \ - .deref = 0, \ - .addr = NULL, \ - .first_rvas = {__VA_ARGS__}, \ - } - -#define SIG_ENTRY_MOV32_PTR(PTR, PATTERN, ...) \ - { \ - .name = #PTR, \ - .pattern = (PATTERN), \ - .pp = (void **)&PTR, \ - .op_off = 2, \ - .deref = 1, \ - .addr = NULL, \ - .first_rvas = {__VA_ARGS__}, \ - } - -#define SIG_ENTRY_LEA_ADDR(PTR, PATTERN, ...) \ - { \ - .name = #PTR, \ - .pattern = (PATTERN), \ - .pp = (void **)&PTR, \ - .op_off = 3, \ - .deref = 0, \ - .addr = NULL, \ - .first_rvas = {__VA_ARGS__}, \ - } - -#define SIG_ENTRY_CALL_ARG(PTR, PATTERN, ...) \ - { \ - .name = #PTR, \ - .pattern = (PATTERN), \ - .pp = (void **)&PTR, \ - .op_off = 1, \ - .deref = 0, \ - .addr = NULL, \ - .first_rvas = {__VA_ARGS__}, \ - } - -/* - * Tries the listed RVAs first, then scans the configured game module ranges for the pattern. - * op_off selects a RIP-relative operand when nonzero, and deref controls how many pointer reads follow. - * The resolved address is written through entry->pp and a SIGSCAN_ERR value is returned. - */ -sigscan_err_t -mod_sigscan(sigscan_entry_t *entry); -/* - * Creates a hook owned by this mod and writes a stable next-call thunk to original. - * Multiple mods may hook the same target. The most recently enabled hook runs first; - * calling original continues with the next enabled hook, then the real function. - * The hook starts disabled. - * Removed automatically by the loader after mod is deinitialized (i.e. deinit called). - */ -bool -mod_hook_create(void *target, void *detour, void **original); -/* Enables a hook previously created for target. */ -bool -mod_hook_enable(void *target); -/* Disables a hook previously created for target. */ -bool -mod_hook_disable(void *target); -/* Removes a hook previously created for target and releases its loader state. */ -bool -mod_hook_remove(void *target); - -/* ===================================================== STRING ===================================================== */ - -#define STR_CLIT(lit) {.data = (uint8_t *)(ENSURE_STR_LIT(lit)), .len = (sizeof(lit) - 1)} - -#ifdef __cplusplus -# define STR_LIT(lit) str_t STR_CLIT(lit) -# define STR_NULL str_t{} -#else -# define STR_LIT(lit) (str_t)STR_CLIT(lit) -# define STR_NULL (str_t){0} -#endif - -#define STR_FMT "%.*s" -#define STR_ARG(str) (int)(str).len, (str).data - -#define STR_BOOL(v) ((v) ? STR_LIT("true") : STR_LIT("false")) - -typedef uint32_t str_cmp_flags_t; -enum { - STR_CMP_FLAG_IGNORE_CASE = (1 << 0), - STR_CMP_FLAG_IGNORE_SLASHES = (1 << 1), -}; - -typedef struct str_node_s str_node_t; -struct str_node_s { - struct str_node_s *next; - str_t str; -}; - -typedef struct str_list_s str_list_t; -struct str_list_s { - str_node_t *first; - str_node_t *last; - uint64_t count; - uint64_t total_bytes; -}; - -typedef struct str_array_s str_array_t; -struct str_array_s { - uint64_t count; - str_t *items; -}; - -static inline bool -str_is_empty(str_t s) -{ - return (!s.data || s.len == 0); -} - -static inline bool -str16_is_empty(str16_t s) -{ - return (!s.data || s.len == 0); -} - -static inline uint8_t -ascii_is_space(uint8_t c) -{ - return c == ' ' || c == '\r' || c == '\t' || c == '\f' || c == '\v' || c == '\n'; -} - -static inline uint8_t -ascii_to_upper(uint8_t c) -{ - return (c >= 'a' && c <= 'z') ? ('A' + (c - 'a')) : c; -} - -static inline uint8_t -ascii_to_lower(uint8_t c) -{ - return (c >= 'A' && c <= 'Z') ? ('a' + (c - 'A')) : c; -} - -static inline uint8_t -ascii_is_num(uint8_t c) -{ - return c >= '0' && c <= '9'; -} - -static inline uint8_t -ascii_is_alpha_lower(uint8_t c) -{ - return c >= 'a' && c <= 'z'; -} - -static inline uint8_t -ascii_is_alpha_upper(uint8_t c) -{ - return c >= 'A' && c <= 'Z'; -} - -static inline uint8_t -ascii_is_alpha(uint8_t c) -{ - return ascii_is_alpha_lower(c) || ascii_is_alpha_upper(c); -} - -static inline uint8_t -ascii_to_forward_slash(uint8_t c) -{ - return (c == '\\' ? '/' : c); -} - -/* Lowercases an ASCII letter stored in a UTF-16 code unit. */ -static inline uint16_t -utf16_ascii_to_lower(uint16_t c) -{ - return (c >= 'A' && c <= 'Z') ? (uint16_t)('a' + (c - 'A')) : c; -} - -/* Converts a value from 0 to 15 to an uppercase hexadecimal byte. */ -static inline uint8_t -nibble_to_hex(uint8_t d) -{ - char c = 0; - - if (d < 10) { - c = d + '0'; - } else { - c = d - 10 + 'A'; - } - - return c; -} - -/* Converts a hexadecimal byte to a value from 0 to 15. Returns -1 when invalid. */ -static inline int -hex_to_nibble(uint8_t c) -{ - if (c >= '0' && c <= '9') { - return c - '0'; - } else if (c >= 'A' && c <= 'F') { - return c - 'A' + 10; - } else if (c >= 'a' && c <= 'f') { - return c - 'a' + 10; - } - return -1; -} - -/* Compares two ASCII bytes using the requested case and slash rules. */ -static inline bool -ascii_equal(uint8_t a, uint8_t b, str_cmp_flags_t flags) -{ - if (flags & STR_CMP_FLAG_IGNORE_SLASHES) { - a = ascii_to_forward_slash(a); - b = ascii_to_forward_slash(b); - } - - if (flags & STR_CMP_FLAG_IGNORE_CASE) { - a = ascii_to_lower(a); - b = ascii_to_lower(b); - } - - return a == b; -} - -/* Length calculation */ - -/* Returns the byte length of a null-terminated string. NULL returns zero. */ -uint64_t -calc_cstr_len(const char *cstr); -/* Returns the byte length up to cap bytes, even when no null terminator is found. */ -uint64_t -calc_cstr_len_with_cap(const char *s, uint64_t cap); -/* Returns the UTF-16 code unit length of a null-terminated wide string. NULL returns zero. */ -uint64_t -calc_wstr_len(const wchar_t *wstr); -/* Returns the wide string length up to cap code units, even when no terminator is found. */ -uint64_t -calc_wstr_len_with_cap(const wchar_t *s, uint64_t cap); - -/* Creation */ - -/* Creates a string view. Invalid data or zero size produces STR_NULL. */ -str_t -str_make(void *data, uint64_t size); -/* Creates a string view of a null-terminated byte string, excluding the terminator. */ -str_t -str_from_cstr(const char *cstr); -/* Creates a string view limited to cap bytes. */ -str_t -str_from_cstr_with_cap(const char *cstr, uint64_t cap); -/* Creates a UTF-16 string view. Invalid data or zero size produces an empty view. */ -str16_t -str16_make(uint16_t *data, uint64_t size); -/* Creates a UTF-16 string view of a null-terminated wide string. */ -str16_t -str16_from_wstr(const wchar_t *wstr); -/* Creates a UTF-16 string view limited to cap code units. */ -str16_t -str16_from_wstr_with_cap(const wchar_t *wstr, uint64_t cap); -/* Returns a clamped string slice. Reversed indexes are swapped. */ -str_t -str_slice(str_t str, uint64_t start_idx, uint64_t end_idx); - -/* Comparison/Search */ - -/* Checks whether a string starts with a prefix using the requested comparison flags. */ -bool -str_has_prefix(str_t s, str_t prefix, str_cmp_flags_t flags); -/* Checks whether a string ends with a suffix using the requested comparison flags. */ -bool -str_has_suffix(str_t s, str_t suffix, str_cmp_flags_t flags); -/* Compares two strings byte by byte and returns a value below, equal to, or above zero. */ -int -str_compare(str_t a, str_t b, str_cmp_flags_t flags); -/* Checks whether two strings contain the same bytes under the requested comparison flags. */ -bool -str_equal(str_t a, str_t b, str_cmp_flags_t flags); -/* Checks whether two strings are equal ignoring the case. */ -bool -str_equal_icase(str_t a, str_t b); -/* Finds the first matching substring and optionally writes its byte index. */ -bool -str_find(str_t s, str_t sub, str_cmp_flags_t flags, uint64_t *idx); -/* Finds the last matching substring and optionally writes its byte index. */ -bool -str_rfind(str_t s, str_t sub, str_cmp_flags_t flags, uint64_t *idx); -/* Finds the first byte present in charset and optionally writes its index. */ -bool -str_find_any(str_t s, str_t charset, str_cmp_flags_t flags, uint64_t *idx); -/* Finds the last byte present in charset and optionally writes its index. */ -bool -str_rfind_any(str_t s, str_t charset, str_cmp_flags_t flags, uint64_t *idx); -/* Checks whether a string contains a byte under the requested comparison flags. */ -bool -str_has_char(str_t s, char c, str_cmp_flags_t flags); - -/* Allocation */ - -/* Copies a string into an arena and adds a null terminator. */ -str_t -str_push_copy(mod_arena_t arena, str_t str); -/* Formats into a buffer and returns the required byte count excluding the terminator. The result may be truncated. */ -uint64_t -str_write_vfmt(void *buf, uint64_t cap, const char *fmt, va_list args); -/* Formats into a buffer and returns the required byte count excluding the terminator. The result may be truncated. */ -uint64_t -str_write_fmt(void *buf, uint64_t cap, const char *fmt, ...) MOD_ATTR_FORMAT(3, 4); -/* Formats a null-terminated string into an arena using an existing va_list. */ -str_t -str_push_vfmt(mod_arena_t arena, const char *fmt, va_list args); -/* Formats a null-terminated string into an arena. */ -str_t -str_push_fmt(mod_arena_t arena, const char *fmt, ...) MOD_ATTR_FORMAT(2, 3); -/* Allocates a string filled with one byte and adds a null terminator. */ -str_t -str_push_fill_byte(mod_arena_t arena, uint64_t size, uint8_t byte); -/* Copies two strings into one arena allocation and adds a null terminator. */ -str_t -str_push_concat(mod_arena_t arena, str_t a, str_t b); -/* Formats raw bytes as uppercase hexadecimal and adds a null terminator. */ -str_t -str_push_hex(mod_arena_t arena, void *data, uint64_t size); - -/* String list/array */ - -/* Deep-copies a string list, including every string, into an arena. */ -str_list_t -str_list_copy(mod_arena_t arena, str_list_t src); -/* Appends an existing node and updates list totals. The node's next pointer is overwritten. */ -void -str_list_push_node(str_list_t *list, str_node_t *n); -/* Prepends an existing node and updates list totals. The node's next pointer is overwritten. */ -void -str_list_push_node_front(str_list_t *list, str_node_t *n); -/* Allocates and appends a node that keeps a view of str. */ -void -str_list_push(mod_arena_t arena, str_list_t *list, str_t str); -/* Copies a string into an arena, then appends it as a new list node. */ -void -str_list_push_copy(mod_arena_t arena, str_list_t *list, str_t str); -/* Formats a string into an arena and appends it as a new list node. */ -void -str_list_push_fmt(mod_arena_t arena, str_list_t *list, const char *fmt, ...) MOD_ATTR_FORMAT(3, 4); -/* Allocates and prepends a node that keeps a view of str. */ -void -str_list_push_front(mod_arena_t arena, str_list_t *list, str_t str); -/* Formats a string into an arena and prepends it as a new list node. */ -void -str_list_push_front_fmt(mod_arena_t arena, str_list_t *list, const char *fmt, ...) MOD_ATTR_FORMAT(3, 4); -/* Checks whether any list item equals a string under the requested comparison flags. */ -bool -str_list_contains(str_list_t list, str_t s, str_cmp_flags_t flags); -/* Moves all nodes from src to the end of dst, then clears src. */ -void -str_list_concat_inplace(str_list_t *dst, str_list_t *src); -/* Splits a string on any supplied separator. Nodes are allocated, but their strings remain views of the input. */ -str_list_t -str_split(mod_arena_t arena, str_t str, uint64_t split_count, str_t *splits); -/* Splits text on CR or LF and trims trailing whitespace. Returned strings remain views of the input. */ -str_list_t -str_split_lines(mod_arena_t arena, str_t str); -/* Joins a list with optional prefix, separator, and suffix into one null-terminated arena string. */ -str_t -str_list_join(mod_arena_t arena, str_list_t list, str_t pre, str_t sep, str_t post); -/* Joins a list with LF separators into one null-terminated arena string. */ -str_t -str_list_join_lines(mod_arena_t arena, str_list_t list); -/* Creates a string array view over existing string items. */ -str_array_t -str_array_make(str_t *items, int count); -/* Deep-copies a string array and all of its strings into an arena. */ -str_array_t -str_array_copy(mod_arena_t arena, str_array_t a); -/* Deep-copies a list into a flat string array. */ -str_array_t -str_array_copy_from_list(mod_arena_t arena, str_list_t list); -/* Copies only the item views from a list into a flat array. String data is not copied. */ -str_array_t -str_array_from_list(mod_arena_t arena, str_list_t list); -/* Checks whether an array contains a string under the requested comparison flags. */ -bool -str_array_contains(str_array_t array, str_t s, str_cmp_flags_t flags); -/* Finds a matching array item and optionally writes its index. */ -bool -str_array_find(str_array_t array, str_t s, str_cmp_flags_t flags, uint64_t *idx); - -/* UTF-8 <-> UTF-16 conversions */ - -/* Converts UTF-16 to a null-terminated UTF-8 arena string. Invalid input units become question marks. */ -str_t -str_from_str16(mod_arena_t arena, str16_t in); -/* Converts UTF-8 to a null-terminated UTF-16 arena string. Invalid input bytes become question marks. */ -str16_t -str16_from_str(mod_arena_t arena, str_t in); - -/* Returns the UTF-8 byte count needed for a UTF-16 string, excluding a terminator. */ -uint64_t -str16_utf8_len(str16_t in); -/* Writes complete UTF-8 codepoints that fit and returns the byte count. No terminator is added. */ -uint64_t -str16_write_utf8(uint8_t *buf, uint64_t max_len, str16_t in); - -/* C-string conversion */ - -/* Copies a byte string into an arena and returns a null-terminated C string. */ -char * -str_push_cstr(mod_arena_t arena, str_t s); -/* Copies a UTF-16 string into an arena and returns a null-terminated wide string. */ -wchar_t * -str16_push_wstr(mod_arena_t arena, str16_t s); - -/* Copies a string with a null terminator. The return value includes the terminator byte. */ -uint64_t -str_write_cstr(str_t s, char *buf, uint64_t cap); -/* Copies up to cap raw string bytes and returns the number copied. No terminator is added. */ -uint64_t -str_write_data(str_t s, char *buf, uint64_t cap); - -/* Mutations */ - -/* Copies a string into an arena and uppercases ASCII letters. */ -str_t -str_to_upper(mod_arena_t arena, str_t str); -/* Copies a string into an arena and lowercases ASCII letters. */ -str_t -str_to_lower(mod_arena_t arena, str_t str); - -/* Trimming */ - -/* Returns a view with leading bytes from charset removed. */ -str_t -str_trim_leading(str_t str, str_t charset, str_cmp_flags_t flags); -/* Returns a view with trailing bytes from charset removed. */ -str_t -str_trim_trailing(str_t str, str_t charset, str_cmp_flags_t flags); -/* Returns a view with matching leading and trailing bytes removed. */ -str_t -str_trim(str_t str, str_t charset, str_cmp_flags_t flags); -/* Returns a view with leading ASCII whitespace removed. */ -str_t -str_trim_leading_space(str_t str); -/* Returns a view with trailing ASCII whitespace removed. */ -str_t -str_trim_trailing_space(str_t str); -/* Returns a view with leading and trailing ASCII whitespace removed. */ -str_t -str_trim_space(str_t str); -/* Returns a view with prefix removed when it matches. */ -str_t -str_trim_prefix(str_t str, str_t prefix, str_cmp_flags_t flags); -/* Returns a view with suffix removed when it matches. */ -str_t -str_trim_suffix(str_t str, str_t suffix, str_cmp_flags_t flags); -/* Returns the part before the first byte found in charset. */ -str_t -str_trim_comment(str_t str, str_t charset, str_cmp_flags_t flags); - -/* Parsing */ - -/* Parses a strict signed decimal integer with no whitespace or trailing bytes. */ -bool -str_parse_s64(str_t str, int64_t *value); -/* Parses a strict signed 32-bit decimal integer. */ -bool -str_parse_int(str_t str, int *value); -/* Parses a strict unsigned 32-bit decimal integer. */ -bool -str_parse_u32(str_t str, uint32_t *value); -/* Parses a strict unsigned 16-bit decimal integer. */ -bool -str_parse_u16(str_t str, uint16_t *value); -/* Parses a strict unsigned 8-bit decimal integer. */ -bool -str_parse_u8(str_t str, uint8_t *value); -/* Parses a strict decimal float with an optional exponent. NaN, infinity, and trailing bytes are rejected. */ -bool -str_parse_float(str_t str, float *value); -/* Parses true, yes, on, false, no, or off without case sensitivity. Other values return default_val. */ -bool -str_parse_bool(str_t s, bool default_val); - -/* ====================================================== PATH ====================================================== */ - -/* - * Returns a view of the final path component. - * Example: /foo/bar.txt --> bar.txt - */ -str_t -path_base(str_t path); -/* - * Returns a view of the path before its final separator. - * A path with no separator returns an empty view. - * Example: /foo/bar.txt --> /foo - */ -str_t -path_dir(str_t path); -/* - * Returns a view of the final component's extension without the dot, or STR_NULL when absent. - * Example: /foo/bar.txt -> txt - */ -str_t -path_get_ext(str_t path); -/* - * Returns a view with the final extension removed. - * Example: /foo/bar.txt -> /foo/bar - */ -str_t -path_trim_ext(str_t path); -/* - * Replaces both slash kinds in writable path data and returns the same view. - * Example (with '\\'): /foo/bar.txt -> \\foo\\bar.txt - */ -str_t -path_replace_slashes_inplace(str_t path, char ch); - -/* Compares Windows paths without case or slash direction differences and ignores trailing separators. */ -bool -path_equal(str_t a, str_t b); -/* Checks whether prefix is a complete leading path, not just a byte prefix. */ -bool -path_has_prefix(str_t path, str_t prefix); -/* - * Returns a view relative to base when path is inside base. Comparison ignores case and slash direction. - * Example: path=/foo/bar.txt base=/foo --> bar.txt - */ -bool -path_make_relative(str_t path, str_t base, str_t *out); -/* Copies a relative path into an arena and normalizes separators to forward slashes. */ -str_t -path_push_relative(mod_arena_t arena, str_t path, str_t base); - -/* Checks for a leading slash or a Windows drive-root path. */ -bool -path_is_abs(str_t path); - -/* - * Splits a path on both slash kinds. - * Returned part strings remain views of path. - * Example: /foo/bar.txt --> [foo, bar.txt] - */ -str_list_t -path_push_parts(mod_arena_t arena, str_t path); - -/* Returns the directory containing the current DLL, allocated in the supplied arena. */ -str_t -path_module_dir(mod_arena_t perm); - -/* - * Joins two path parts into an arena string and normalizes separators. - * The result is not guaranteed to be null-terminated. - * Example: a:/foo/bar, b:baz.txt --> /foo/bar/baz.txt - */ -str_t -path_join(mod_arena_t arena, str_t a, str_t b); - -/* ====================================================== FILE ====================================================== */ - -typedef uint8_t dir_entry_kind_t; -enum { - DIR_ENTRY_FILE, - DIR_ENTRY_DIR, -}; - -typedef struct dir_entry_s dir_entry_t; -struct dir_entry_s { - str_t name; // filename only, no path - str_t path; // full path - dir_entry_kind_t kind; - uint64_t size; // file size in bytes (0 for dirs) -}; - -typedef struct dir_entry_list_s dir_entry_list_t; -struct dir_entry_list_s { - dir_entry_t *items; - int count; -}; - -/* Returns true when path exists and is a regular file. */ -bool -file_exists(str_t path); -/* Returns a file's size in bytes, or zero on failure and for empty files. */ -uint64_t -file_size(str_t path); - -/* Reads a non-empty file into an arena. The result is raw bytes with a null terminator; empty files return STR_NULL. */ -str_t -file_read_all(str_t path, mod_arena_t arena); -/* Creates or truncates a file and writes all supplied bytes. */ -bool -file_write(str_t s, str_t path); -/* Creates or truncates a file and writes list items separated by LF, with no final LF. */ -bool -file_write_lines(str_list_t lines, str_t path); -/* Copies a file and overwrites an existing destination. */ -bool -file_copy(str_t dst, str_t src); -/* Deletes a file and returns whether the OS call succeeded. */ -bool -file_delete(str_t path); - -/* Returns true when path exists and is a directory. */ -bool -dir_exists(str_t path); - -/* Creates one directory level. Existing directories count as success. */ -bool -dir_create(str_t path); - -/* Creates a directory and each missing parent directory. */ -bool -dir_create_recursive(str_t path); - -/* Lists a directory into an arena, excluding the current and parent entries. */ -dir_entry_list_t -dir_list(str_t path, mod_arena_t arena); - -/* Lists entries matching a Windows wildcard pattern such as *.dll. */ -dir_entry_list_t -dir_list_filter(str_t path, str_t pattern, mod_arena_t arena); - -/* Deletes an empty directory. */ -bool -dir_delete(str_t path); - -/* Deletes child files and directories, then deletes the requested directory. */ -bool -dir_delete_recursive(str_t path); - -/* =================================================== INI PARSER =================================================== */ - -typedef struct ini_section_s ini_section_t; -struct ini_section_s { - ini_section_t *next; - str_t name; - str_t arg; - str_list_t lines; -}; - -typedef struct ini_section_list_s ini_section_list_t; -struct ini_section_list_s { - ini_section_t *first; - ini_section_t *last; - int count; -}; - -/* Checks whether a line starts with [ and ends with ]. */ -bool -ini_is_line_section(str_t line); -/* Parses [name] or [name.arg] into trimmed string views. */ -bool -ini_parse_section_header(str_t line, str_t *out_name, str_t *out_arg); - -/* Builds copied section records from an array of lines. Lines before the first valid section are ignored. */ -ini_section_list_t -ini_parse_sections(mod_arena_t arena, str_array_t lines); - -/* Splits the first key=value pair into trimmed string views. The key must not be empty. */ -bool -ini_parse_kv(str_t line, str_t *out_key, str_t *out_value); -/* Splits INI text, removes semicolon comments, trims whitespace, and deep-copies the resulting lines. */ -str_array_t -ini_split_lines(mod_arena_t arena, str_t text); - -#ifdef __cplusplus -} -#endif - -#endif /* MOD_SDK_H */ diff --git a/mod/mod_unreal.c b/mod/mod_unreal.c deleted file mode 100644 index 8acedac..0000000 --- a/mod/mod_unreal.c +++ /dev/null @@ -1,1395 +0,0 @@ -#include "mod_unreal.h" - -#define TMAP_FNAME_UINT8PTR_KEY_EQUAL(A, B) unreal_fname_equal(A, B, false) -#define TMAP_FNAME_UINT8PTR_KEY_HASH(KEY) unreal_fname_hash(KEY) - -TMAP_DEFINE_FUNCS(unreal_tmap_fname_uint8ptr, tmap_fname_uint8ptr_t, fname_t, uint8_t *, TMAP_FNAME_UINT8PTR_KEY_EQUAL, TMAP_FNAME_UINT8PTR_KEY_HASH) - -unreal_cached_objects_t g_cached_objects = {0}; - -void -unreal_cache_objects(void) -{ - for (int i = 0; i < unreal_uobject_array_count(); ++i) { - uobject_t *obj = unreal_uobject_array_get_obj(i); - if (!obj) { - continue; - } - - tmp_arena_t tmp = mod_scratch_begin(MOD_ARENA_INVALID); - str_t full_name = unreal_uobject_push_full_name(obj, tmp.arena); - - if (str_equal(full_name, STR_LIT("/Script/CoreUObject.Object"), 0)) { - g_cached_objects.core_object = (uclass_t *)obj; - } else if (str_equal(full_name, STR_LIT("/Script/CoreUObject.Class"), 0)) { - g_cached_objects.core_class = (uclass_t *)obj; - } else if (str_equal(full_name, STR_LIT("/Script/CoreUObject.ScriptStruct"), 0)) { - g_cached_objects.core_scriptstruct = (uclass_t *)obj; - } else if (str_equal(full_name, STR_LIT("/Script/CoreUObject.Function"), 0)) { - g_cached_objects.core_func = (uclass_t *)obj; - } else if (str_equal(full_name, STR_LIT("/Script/CoreUObject.Enum"), 0)) { - g_cached_objects.core_enum = (uclass_t *)obj; - } else if (str_equal(full_name, STR_LIT("/Script/CoreUObject.Package"), 0)) { - g_cached_objects.core_package = (uclass_t *)obj; - } else if (str_equal(full_name, STR_LIT("/Script/Engine.Actor"), 0)) { - g_cached_objects.actor = (uclass_t *)obj; - } else if (str_equal(full_name, STR_LIT("/Script/Engine.PlayerController"), 0)) { - g_cached_objects.player_ctrl = (uclass_t *)obj; - } else if (str_equal(full_name, STR_LIT("/Script/Engine.LocalPlayer"), 0)) { - g_cached_objects.local_player = (uclass_t *)obj; - } else if (str_equal(full_name, STR_LIT("/Script/Engine.Pawn"), 0)) { - g_cached_objects.pawn = (uclass_t *)obj; - } else if (str_equal(full_name, STR_LIT("/Script/Engine.HUD"), 0)) { - g_cached_objects.hud = (uclass_t *)obj; - } else if (str_equal(full_name, STR_LIT("/Script/Engine.World"), 0)) { - g_cached_objects.world = (uclass_t *)obj; - } else if (str_equal(full_name, STR_LIT("/Script/Engine.GameInstance"), 0)) { - g_cached_objects.game_instance = (uclass_t *)obj; - } else if (str_equal(full_name, STR_LIT("/Script/Engine.Level"), 0)) { - g_cached_objects.level = (uclass_t *)obj; - } else if (str_equal(full_name, STR_LIT("/Script/Engine.ActorComponent"), 0)) { - g_cached_objects.actor_component = (uclass_t *)obj; - } else if (str_equal(full_name, STR_LIT("/Script/UMG.Widget"), 0)) { - g_cached_objects.widget = (uclass_t *)obj; - } else if (str_equal(full_name, STR_LIT("/Script/Engine.Blueprint"), 0)) { - g_cached_objects.blueprint = (uclass_t *)obj; - } else if (str_equal(full_name, STR_LIT("/Script/Engine.DataAsset"), 0)) { - g_cached_objects.data_asset = (uclass_t *)obj; - } else if (str_equal(full_name, STR_LIT("/Script/Engine.DataTable"), 0)) { - g_cached_objects.data_table = (uclass_t *)obj; - } else if (str_equal(full_name, STR_LIT("/Script/Engine.Default__GameplayStatics"), 0)) { - g_cached_objects.gameplay_statics_cdo = obj; - } else if (str_equal(full_name, STR_LIT("/Script/Engine.GameplayStatics.BeginDeferredActorSpawnFromClass"), 0)) { - g_cached_objects.begin_spawn = (ufunc_t *)obj; - } else if (str_equal(full_name, STR_LIT("/Script/Engine.GameplayStatics.FinishSpawningActor"), 0)) { - g_cached_objects.finish_spawn = (ufunc_t *)obj; - } else if (str_equal(full_name, STR_LIT("/Script/Engine.Actor.K2_DestroyActor"), 0)) { - g_cached_objects.destroy_actor = (ufunc_t *)obj; - } - mod_scratch_end(tmp); - } -} - -static inline int -u32_count_digits(uint32_t v) -{ - int count = 1; - while (v >= 10) { - v /= 10; - count += 1; - } - return count; -} - -fname_pool_t * -unreal_get_name_pool(void) -{ - const mod_host_api_t *host = mod_sdk_host(); - return (host) ? host->get_name_pool() : NULL; -} - -bool -unreal_fname_equal(fname_t a, fname_t b, bool ignore_num) -{ - if (ignore_num) { - return a.cmp_idx == b.cmp_idx; - } - return a.cmp_idx == b.cmp_idx && a.num == b.num; -} - -uint32_t -unreal_fname_hash(fname_t name) -{ - uint32_t block = name.cmp_idx >> FNAME_BLOCK_OFFSET_BITS; - uint32_t offset = name.cmp_idx & ((1u << FNAME_BLOCK_OFFSET_BITS) - 1); - - uint32_t hash = (block << (32 - FNAME_MAX_BLOCK_BITS)) + - (block) + - (offset << FNAME_BLOCK_OFFSET_BITS) + - (offset) + - (offset >> 4); - - return hash + name.num; -} - -bool -unreal_fname_is_none(fname_t name) -{ - return name.cmp_idx == 0 && name.num == 0; -} - -fname_entry_t * -unreal_fname_entry_get(uint32_t cmp_idx) -{ - fname_pool_t *name_pool = unreal_get_name_pool(); - if (!name_pool) { - /* should not happen */ - return NULL; - } - - uint32_t block = cmp_idx >> FNAME_BLOCK_OFFSET_BITS; // high bits - uint32_t offset = cmp_idx & ((1u << FNAME_BLOCK_OFFSET_BITS) - 1); // low 16 bits - - if (block >= FNAME_MAX_BLOCKS) { - return NULL; - } - - uint8_t *base = (uint8_t *)name_pool->entries.blocks[block]; - if (!base) { - return NULL; - } - - return (fname_entry_t *)(base + offset * 2); -} - -uint64_t -unreal_fname_utf8_len(fname_t name) -{ - const mod_host_api_t *host = mod_sdk_host(); - return (host) ? host->fname_utf8_len(name) : 0ULL; -} - -uint64_t -unreal_fname_utf8_write(uint8_t *buf, uint64_t max_len, fname_t name) -{ - const mod_host_api_t *host = mod_sdk_host(); - return (host && buf && max_len > 0) ? host->fname_utf8_write(name, buf, max_len) : 0ULL; -} - -str_t -unreal_fname_to_str(fname_t fname, mod_arena_t arena) -{ - str_t result = STR_NULL; - uint64_t len = unreal_fname_utf8_len(fname); - uint8_t *buf = mod_arena_push(arena, len + 1, 1); - if (buf) { - MOD_ASSERT(unreal_fname_utf8_write(buf, len, fname) == len); - buf[len] = '\0'; - result = str_make(buf, len); - } - - return result; -} - -fname_t -unreal_fname_from_str(str_t str, efind_name_t find_type) -{ - const mod_host_api_t *host = mod_sdk_host(); - return (host) ? host->fname_from_str(str, find_type) : (fname_t){0}; -} - -#define FNAME_BLOCK_BYTES ((1u << FNAME_BLOCK_OFFSET_BITS) * 2u) - -static uint32_t -unreal_fname_entry_size_bytes(fname_entry_t *entry) -{ - if (!entry) { - return 0; - } - - uint32_t len = entry->header.len; - uint32_t size = sizeof(fname_entry_header_t); - - if (entry->header.is_wide) { - size += len * sizeof(uint16_t); - } else { - size += len; - } - - return (uint32_t)ALIGN_UP(size, 2); -} - -void -unreal_fname_pool_iterate(fname_pool_iter_cb_t cb, void *user) -{ - if (!cb) { - return; - } - - fname_pool_t *name_pool = unreal_get_name_pool(); - if (!name_pool) { - return; - } - - fname_entry_allocator_t *alloc = &name_pool->entries; - - for (uint32_t block_idx = 0; block_idx <= alloc->current_block && block_idx < FNAME_MAX_BLOCKS; ++block_idx) { - uint8_t *block = alloc->blocks[block_idx]; - if (!block) { - continue; - } - - uint32_t block_limit = FNAME_BLOCK_BYTES; - if (block_idx == alloc->current_block) { - block_limit = alloc->current_byte_cursor; - } - - for (uint32_t byte_offset = 0; byte_offset + sizeof(fname_entry_header_t) <= block_limit;) { - fname_entry_t *entry = (fname_entry_t *)(block + byte_offset); - - uint32_t entry_size = unreal_fname_entry_size_bytes(entry); - if (entry_size == 0 || byte_offset + entry_size > block_limit) { - break; - } - - fname_t name = { - .cmp_idx = (block_idx << FNAME_BLOCK_OFFSET_BITS) | (byte_offset / 2), - .num = 0, - }; - - if (!cb(name, entry, user)) { - return; - } - - byte_offset += entry_size; - } - } -} - -static bool -unreal_fname_entry_match_text_ansi(fname_entry_t *entry, str_t text, bool ignore_case) -{ - uint32_t last = (uint32_t)entry->header.len - (uint32_t)text.len; - for (uint32_t i = 0; i <= last; ++i) { - bool match = true; - - for (uint32_t j = 0; j < text.len; ++j) { - uint8_t a = entry->name.ansi[i + j]; - uint8_t b = text.data[j]; - - if (ignore_case) { - a = ascii_to_lower(a); - b = ascii_to_lower(b); - } - - if (a != b) { - match = false; - break; - } - } - - if (match) { - return true; - } - } - - return false; -} - -static bool -unreal_fname_entry_match_text_wide(fname_entry_t *entry, str_t text, bool ignore_case) -{ - uint32_t last = (uint32_t)entry->header.len - (uint32_t)text.len; - for (uint32_t i = 0; i <= last; ++i) { - bool match = true; - - for (uint32_t j = 0; j < text.len; ++j) { - uint16_t a = entry->name.wide[i + j]; - uint16_t b = text.data[j]; - - if (ignore_case) { - a = utf16_ascii_to_lower(a); - b = utf16_ascii_to_lower(b); - } - - if (a != b) { - match = false; - break; - } - } - - if (match) { - return true; - } - } - - return false; -} - -/* NOTE: text matching is ASCII-oriented. UTF-8 multibyte queries are not decoded when matching wide FName entries */ -bool -unreal_fname_entry_match_text(fname_entry_t *entry, str_t text, bool ignore_case, bool exact_match) -{ - if (!entry || str_is_empty(text) || entry->header.len == 0) { - return false; - } - - if (exact_match && text.len != entry->header.len) { - return false; - } - - if (text.len > entry->header.len) { - return false; - } - - if (entry->header.is_wide) { - return unreal_fname_entry_match_text_wide(entry, text, ignore_case); - } else { - return unreal_fname_entry_match_text_ansi(entry, text, ignore_case); - } -} - -static bool -unreal_fname_entry_match_text16_ansi(fname_entry_t *entry, str16_t text, bool ignore_case) -{ - uint32_t last = (uint32_t)entry->header.len - (uint32_t)text.len; - for (uint32_t i = 0; i <= last; ++i) { - bool match = true; - - for (uint32_t j = 0; j < text.len; ++j) { - uint16_t a = entry->name.ansi[i + j]; - uint16_t b = text.data[j]; - - if (ignore_case) { - a = utf16_ascii_to_lower(a); - b = utf16_ascii_to_lower(b); - } - - if (a != b) { - match = false; - break; - } - } - - if (match) { - return true; - } - } - - return false; -} - -static bool -unreal_fname_entry_match_text16_wide(fname_entry_t *entry, str16_t text, bool ignore_case) -{ - uint32_t last = (uint32_t)entry->header.len - (uint32_t)text.len; - for (uint32_t i = 0; i <= last; ++i) { - bool match = true; - - for (uint32_t j = 0; j < text.len; ++j) { - uint16_t a = entry->name.wide[i + j]; - uint16_t b = text.data[j]; - - if (ignore_case) { - a = utf16_ascii_to_lower(a); - b = utf16_ascii_to_lower(b); - } - - if (a != b) { - match = false; - break; - } - } - - if (match) { - return true; - } - } - - return false; -} - -bool -unreal_fname_entry_match_text16(fname_entry_t *entry, str16_t text, bool ignore_case, bool exact_match) -{ - if (!entry || str16_is_empty(text) || entry->header.len == 0) { - return false; - } - - if (exact_match && text.len != entry->header.len) { - return false; - } - - if (text.len > entry->header.len) { - return false; - } - - if (entry->header.is_wide) { - return unreal_fname_entry_match_text16_wide(entry, text, ignore_case); - } else { - return unreal_fname_entry_match_text16_ansi(entry, text, ignore_case); - } -} - -bool -unreal_fname_match_text(fname_t name, str_t text, bool ignore_case, bool exact_match) -{ - if (str_is_empty(text)) { - return false; - } - - fname_entry_t *entry = unreal_fname_entry_get(name.cmp_idx); - if (!entry || entry->header.len == 0) { - return false; - } - - return unreal_fname_entry_match_text(entry, text, ignore_case, exact_match); -} - -bool -unreal_fname_match_text16(fname_t name, str16_t text, bool ignore_case, bool exact_match) -{ - if (str16_is_empty(text)) { - return false; - } - - fname_entry_t *entry = unreal_fname_entry_get(name.cmp_idx); - if (!entry || entry->header.len == 0) { - return false; - } - - return unreal_fname_entry_match_text16(entry, text, ignore_case, exact_match); -} - -/* ==================================================== FSTRING ===================================================== */ -static uint32_t g_fcrc_table[256] = { - 0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9, 0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005, - 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61, 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD, - 0x4C11DB70, 0x48D0C6C7, 0x4593E01E, 0x4152FDA9, 0x5F15ADAC, 0x5BD4B01B, 0x569796C2, 0x52568B75, - 0x6A1936C8, 0x6ED82B7F, 0x639B0DA6, 0x675A1011, 0x791D4014, 0x7DDC5DA3, 0x709F7B7A, 0x745E66CD, - 0x9823B6E0, 0x9CE2AB57, 0x91A18D8E, 0x95609039, 0x8B27C03C, 0x8FE6DD8B, 0x82A5FB52, 0x8664E6E5, - 0xBE2B5B58, 0xBAEA46EF, 0xB7A96036, 0xB3687D81, 0xAD2F2D84, 0xA9EE3033, 0xA4AD16EA, 0xA06C0B5D, - 0xD4326D90, 0xD0F37027, 0xDDB056FE, 0xD9714B49, 0xC7361B4C, 0xC3F706FB, 0xCEB42022, 0xCA753D95, - 0xF23A8028, 0xF6FB9D9F, 0xFBB8BB46, 0xFF79A6F1, 0xE13EF6F4, 0xE5FFEB43, 0xE8BCCD9A, 0xEC7DD02D, - 0x34867077, 0x30476DC0, 0x3D044B19, 0x39C556AE, 0x278206AB, 0x23431B1C, 0x2E003DC5, 0x2AC12072, - 0x128E9DCF, 0x164F8078, 0x1B0CA6A1, 0x1FCDBB16, 0x018AEB13, 0x054BF6A4, 0x0808D07D, 0x0CC9CDCA, - 0x7897AB07, 0x7C56B6B0, 0x71159069, 0x75D48DDE, 0x6B93DDDB, 0x6F52C06C, 0x6211E6B5, 0x66D0FB02, - 0x5E9F46BF, 0x5A5E5B08, 0x571D7DD1, 0x53DC6066, 0x4D9B3063, 0x495A2DD4, 0x44190B0D, 0x40D816BA, - 0xACA5C697, 0xA864DB20, 0xA527FDF9, 0xA1E6E04E, 0xBFA1B04B, 0xBB60ADFC, 0xB6238B25, 0xB2E29692, - 0x8AAD2B2F, 0x8E6C3698, 0x832F1041, 0x87EE0DF6, 0x99A95DF3, 0x9D684044, 0x902B669D, 0x94EA7B2A, - 0xE0B41DE7, 0xE4750050, 0xE9362689, 0xEDF73B3E, 0xF3B06B3B, 0xF771768C, 0xFA325055, 0xFEF34DE2, - 0xC6BCF05F, 0xC27DEDE8, 0xCF3ECB31, 0xCBFFD686, 0xD5B88683, 0xD1799B34, 0xDC3ABDED, 0xD8FBA05A, - 0x690CE0EE, 0x6DCDFD59, 0x608EDB80, 0x644FC637, 0x7A089632, 0x7EC98B85, 0x738AAD5C, 0x774BB0EB, - 0x4F040D56, 0x4BC510E1, 0x46863638, 0x42472B8F, 0x5C007B8A, 0x58C1663D, 0x558240E4, 0x51435D53, - 0x251D3B9E, 0x21DC2629, 0x2C9F00F0, 0x285E1D47, 0x36194D42, 0x32D850F5, 0x3F9B762C, 0x3B5A6B9B, - 0x0315D626, 0x07D4CB91, 0x0A97ED48, 0x0E56F0FF, 0x1011A0FA, 0x14D0BD4D, 0x19939B94, 0x1D528623, - 0xF12F560E, 0xF5EE4BB9, 0xF8AD6D60, 0xFC6C70D7, 0xE22B20D2, 0xE6EA3D65, 0xEBA91BBC, 0xEF68060B, - 0xD727BBB6, 0xD3E6A601, 0xDEA580D8, 0xDA649D6F, 0xC423CD6A, 0xC0E2D0DD, 0xCDA1F604, 0xC960EBB3, - 0xBD3E8D7E, 0xB9FF90C9, 0xB4BCB610, 0xB07DABA7, 0xAE3AFBA2, 0xAAFBE615, 0xA7B8C0CC, 0xA379DD7B, - 0x9B3660C6, 0x9FF77D71, 0x92B45BA8, 0x9675461F, 0x8832161A, 0x8CF30BAD, 0x81B02D74, 0x857130C3, - 0x5D8A9099, 0x594B8D2E, 0x5408ABF7, 0x50C9B640, 0x4E8EE645, 0x4A4FFBF2, 0x470CDD2B, 0x43CDC09C, - 0x7B827D21, 0x7F436096, 0x7200464F, 0x76C15BF8, 0x68860BFD, 0x6C47164A, 0x61043093, 0x65C52D24, - 0x119B4BE9, 0x155A565E, 0x18197087, 0x1CD86D30, 0x029F3D35, 0x065E2082, 0x0B1D065B, 0x0FDC1BEC, - 0x3793A651, 0x3352BBE6, 0x3E119D3F, 0x3AD08088, 0x2497D08D, 0x2056CD3A, 0x2D15EBE3, 0x29D4F654, - 0xC5A92679, 0xC1683BCE, 0xCC2B1D17, 0xC8EA00A0, 0xD6AD50A5, 0xD26C4D12, 0xDF2F6BCB, 0xDBEE767C, - 0xE3A1CBC1, 0xE760D676, 0xEA23F0AF, 0xEEE2ED18, 0xF0A5BD1D, 0xF464A0AA, 0xF9278673, 0xFDE69BC4, - 0x89B8FD09, 0x8D79E0BE, 0x803AC667, 0x84FBDBD0, 0x9ABC8BD5, 0x9E7D9662, 0x933EB0BB, 0x97FFAD0C, - 0xAFB010B1, 0xAB710D06, 0xA6322BDF, 0xA2F33668, 0xBCB4666D, 0xB8757BDA, 0xB5365D03, 0xB1F740B4, -}; - - -fstring_t -unreal_fstring_from_str(str_t s, mod_arena_t arena) -{ - str16_t s16 = str16_from_str(arena, s); - MOD_ASSERT(s16.data[s16.len] == 0); // must be null-terminated - - return (fstring_t){ - .data = s16.data, - .len = (int32_t)s16.len + 1, - .max = (int32_t)s16.len + 1, - }; -} - -str_t -unreal_fstring_to_str(fstring_t fs, mod_arena_t arena) -{ - return str_from_str16(arena, str16_from_wstr_with_cap(fs.data, fs.len)); -} - -static inline uint32_t -unreal_crc_byte(uint32_t hash, uint8_t byte) -{ - return ((hash >> 8) & 0x00FFFFFF) ^ g_fcrc_table[(hash ^ byte) & 0xFF]; -} - -static inline uint16_t -unreal_tchar_to_upper(uint16_t c) -{ - return (c >= 'a' && c <= 'z') ? (uint16_t)(c - ('a' - 'A')) : c; -} - -uint32_t -unreal_fstring_hash(fstring_t str) -{ - if (!str.data || str.len <= 1) { - return 0; - } - - int32_t len = str.len - 1; - uint32_t hash = 0; - for (int32_t i = 0; i < len; ++i) { - uint16_t ch = unreal_tchar_to_upper(str.data[i]); - - hash = unreal_crc_byte(hash, (uint8_t)(ch >> 0)); - hash = unreal_crc_byte(hash, (uint8_t)(ch >> 8)); - } - - return hash; -} - -/* =================================================== FIOSTATUS ==================================================== */ - -str_t -unreal_fio_status_to_str(fio_status_t status, mod_arena_t arena) -{ - str_t result = STR_NULL; - tmp_arena_t tmp = mod_scratch_begin(arena); - { - str_t err_msg_str = str_from_str16(tmp.arena, str16_from_wstr_with_cap(status.err_msg, COUNTOF(status.err_msg))); - const char *err_code_str = eio_err_code_to_str(status.err_code); - - result = str_push_fmt(arena, "%.*s (%d - %s)", STR_ARG(err_msg_str), status.err_code, err_code_str); - } - mod_scratch_end(tmp); - return result; -} - -/* ==================================================== UOBJECT ===================================================== */ - -fuobject_array_t * -unreal_get_object_array(void) -{ - const mod_host_api_t *host = mod_sdk_host(); - return (host) ? host->get_object_array() : NULL; -} - -uworld_t * -unreal_get_current_world(void) -{ - const mod_host_api_t *host = mod_sdk_host(); - if (host) { - uworld_t **gworld_ptr = host->get_gworld_ptr(); - if (gworld_ptr) { - return *gworld_ptr; - } - } - return NULL; -} - -bool -unreal_register_uobject_listener(uobject_listener_kind_t kind, uobject_notify_cb_t notify_cb, void *user) -{ - const mod_host_api_t *host = mod_sdk_host(); - mod_t mod = mod_sdk_mod_handle(); - return (host) ? host->register_uobject_listener(mod, kind, notify_cb, user) : false; -} - -void -unreal_deregister_uobject_listener(uobject_listener_kind_t kind, uobject_notify_cb_t notify_cb, void *user) -{ - const mod_host_api_t *host = mod_sdk_host(); - mod_t mod = mod_sdk_mod_handle(); - if (host) { - host->deregister_uobject_listener(mod, kind, notify_cb, user); - } -} - -fuobject_item_t * -unreal_uobject_array_get_item(int idx) -{ - fuobject_array_t *uobjects = unreal_get_object_array(); - if (!uobjects) { - return NULL; - } - - fchunked_fixed_uobject_array_t *a = &uobjects->obj_objs; - if (idx < 0 || idx >= a->num_elems) { - return NULL; - } - - int chunk_idx = idx / UOBJECT_ARRAY_NUM_ELEMS_PER_CHUNK; - int within_idx = idx % UOBJECT_ARRAY_NUM_ELEMS_PER_CHUNK; - - if (chunk_idx < 0 || chunk_idx >= a->num_chunks) { - return NULL; - } - - fuobject_item_t *chunk = a->objs[chunk_idx]; - if (!chunk) { - return NULL; - } - - return &chunk[within_idx]; -} - -bool -unreal_uobject_array_item_is_valid(fuobject_item_t *item) -{ - if (!item || !item->obj) { - return false; - } - - if (item->flags & (IOF_UNREACHABLE | IOF_PENDING_KILL)) { - return false; - } - - return true; -} - -uobject_t * -unreal_uobject_array_get_obj(int idx) -{ - fuobject_item_t *item = unreal_uobject_array_get_item(idx); - if (!item || !unreal_uobject_array_item_is_valid(item)) { - return NULL; - } - return item->obj; -} - -bool -unreal_uobject_is_a(uobject_t *obj, uclass_t *cls) -{ - if (obj && cls) { - for (uclass_t *c = obj->cls; c; c = (uclass_t *)c->super_struct) { - if (c == cls) { - return true; - } - } - } - return false; -} - -bool -unreal_uobject_is_default(uobject_t *obj) -{ - return (obj && (obj->obj_flags & (RF_CLASS_DEFAULT_OBJECT | RF_ARCHETYPE_OBJECT))); -} - -bool -unreal_uobject_is_valid(uobject_t *obj) -{ - if (!obj) { - return false; - } - - fuobject_item_t *item = unreal_uobject_array_get_item(obj->internal_idx); - if (!item || !unreal_uobject_array_item_is_valid(item)) { - return false; - } - - /* The item at this index must point back to our object. - * If it points to something else, our object was destroyed - * and the slot was reused. */ - if (item->obj != obj) { - return false; - } - - return true; -} - -uint64_t -unreal_uobject_get_name_len(uobject_t *obj) -{ - uint64_t len = 0; - if (obj) { - len = unreal_fname_utf8_len(obj->name); - } - return len; -} - -uint64_t -unreal_uobject_write_name(uobject_t *obj, uint8_t *buf, uint64_t max_len) -{ - uint64_t len = 0; - if (obj && buf && max_len > 0) { - len = unreal_fname_utf8_write(buf, max_len, obj->name); - } - return len; -} - -str_t -unreal_uobject_push_name(uobject_t *obj, mod_arena_t arena) -{ - str_t result = STR_NULL; - if (obj) { - uint64_t len = unreal_uobject_get_name_len(obj); - uint8_t *buf = mod_arena_push(arena, len + 1, 1); - if (buf) { - MOD_ASSERT(unreal_uobject_write_name(obj, buf, len) == len); - buf[len] = '\0'; - result = str_make(buf, len); - } - } - - return result; -} - -bool -unreal_outer_chain_contains(uobject_t *obj, str_t str, bool ignore_case, bool exact_match) -{ - for (uobject_t *cur = obj; cur; cur = cur->outer) { - if (unreal_fname_match_text(cur->name, str, ignore_case, exact_match)) { - return true; - } - } - return false; -} - -bool -unreal_super_chain_contains(uclass_t *cls, str_t str, bool ignore_case, bool exact_match) -{ - for (ustruct_t *s = cls ? (ustruct_t *)cls : NULL; s; s = s->super_struct) { - if (unreal_fname_match_text(s->name, str, ignore_case, exact_match)) { - return true; - } - } - return false; -} - -uint64_t -unreal_uobject_get_full_name_len(uobject_t *obj) -{ - uint64_t len = 0; - if (obj) { - len += unreal_fname_utf8_len(obj->name); - for (uobject_t *cur = obj->outer; cur; cur = cur->outer) { - len += 1; // '.' - len += unreal_fname_utf8_len(cur->name); - } - } - return len; -} - -uint64_t -unreal_uobject_write_full_name(uobject_t *obj, uint8_t *buf, uint64_t max_len) -{ - uint64_t len = 0; - if (obj && buf && max_len > 0) { - tmp_arena_t tmp = mod_scratch_begin(MOD_ARENA_INVALID); - { - uint64_t depth = 0; - for (uobject_t *cur = obj; cur; cur = cur->outer) { - depth += 1; - } - - uobject_t **chain = mod_arena_push(tmp.arena, depth * sizeof(uobject_t *), sizeof(uobject_t *)); - uint64_t i = depth; - for (uobject_t *cur = obj; cur; cur = cur->outer) { - chain[--i] = cur; - } - - for (i = 0; i < depth && len < max_len; ++i) { - len += unreal_fname_utf8_write(buf + len, max_len - len, chain[i]->name); - if (i + 1 < depth && len + 1 <= max_len) { - buf[len++] = '.'; - } - } - } - mod_scratch_end(tmp); - } - return len; -} - -str_t -unreal_uobject_push_full_name(uobject_t *obj, mod_arena_t arena) -{ - str_t result = STR_NULL; - if (obj) { - uint64_t len = unreal_uobject_get_full_name_len(obj); - if (len > 0) { - uint8_t *buf = mod_arena_push(arena, len + 1, 1); - if (buf) { - unreal_uobject_write_full_name(obj, buf, len); - buf[len] = '\0'; - result = str_make(buf, len); - } - } - } - return result; -} - -int -unreal_uobject_array_count(void) -{ - fuobject_array_t *uobjects = unreal_get_object_array(); - if (!uobjects) { - return 0; - } - return uobjects->obj_objs.num_elems; -} - -int -unreal_uobject_array_capacity(void) -{ - fuobject_array_t *uobjects = unreal_get_object_array(); - if (!uobjects) { - return 0; - } - return uobjects->obj_objs.max_elems; -} - -int -unreal_uobject_array_num_chunks(void) -{ - fuobject_array_t *uobjects = unreal_get_object_array(); - if (!uobjects) { - return 0; - } - return uobjects->obj_objs.num_chunks; -} - -int -unreal_uobject_array_max_chunks(void) -{ - fuobject_array_t *uobjects = unreal_get_object_array(); - if (!uobjects) { - return 0; - } - return uobjects->obj_objs.max_chunks; -} - -int -unreal_uobject_array_first_gc_index(void) -{ - fuobject_array_t *uobjects = unreal_get_object_array(); - if (!uobjects) { - return 0; - } - return uobjects->obj_first_cg_idx; -} - -int -unreal_uobject_array_last_non_gc_index(void) -{ - fuobject_array_t *uobjects = unreal_get_object_array(); - if (!uobjects) { - return 0; - } - return uobjects->obj_last_non_cg_idx; -} - -bool -unreal_uobject_array_is_open_for_disregard_for_gc(void) -{ - fuobject_array_t *uobjects = unreal_get_object_array(); - if (!uobjects) { - return 0; - } - return uobjects->open_for_disregard_for_gc; -} - -uobject_t * -unreal_uobject_find(str_t name, bool ignore_case, bool exact_match) -{ - if (str_is_empty(name)) { - return NULL; - } - - for (int i = 0; i < unreal_uobject_array_count(); ++i) { - uobject_t *obj = unreal_uobject_array_get_obj(i); - if (!obj) { - continue; - } - - if (unreal_fname_match_text(obj->name, name, ignore_case, exact_match)) { - return obj; - } - } - - return NULL; -} - -uclass_t * -unreal_uclass_find(str_t name, bool ignore_case, bool exact_match) -{ - if (str_is_empty(name)) { - return NULL; - } - - MOD_ASSERT_MSG(g_cached_objects.core_class != NULL, "/Script/CoreUObject.Class is not cached, make sure you call unreal_cache_objects()"); - - for (int i = 0; i < unreal_uobject_array_count(); ++i) { - uobject_t *obj = unreal_uobject_array_get_obj(i); - if (!obj) { - continue; - } - - if (!unreal_uobject_is_a(obj, g_cached_objects.core_class)) { - continue; - } - - if (unreal_fname_match_text(obj->name, name, ignore_case, exact_match)) { - return (uclass_t *)obj; - } - } - - return NULL; -} - -uobject_t * -unreal_uobject_find_first_of(uclass_t *cls) -{ - if (!cls) { - return NULL; - } - - for (int i = 0; i < unreal_uobject_array_count(); ++i) { - uobject_t *obj = unreal_uobject_array_get_obj(i); - if (!obj) { - continue; - } - - if (unreal_uobject_is_a(obj, cls) && !unreal_uobject_is_default(obj)) { - return obj; - } - } - - return NULL; -} - -uobject_t * -unreal_uobject_find_first_of_by_name(uclass_t *cls, str_t name, bool ignore_case, bool exact_match) -{ - if (!cls) { - return NULL; - } - - for (int i = 0; i < unreal_uobject_array_count(); ++i) { - uobject_t *obj = unreal_uobject_array_get_obj(i); - if (!obj) { - continue; - } - - - if (!unreal_uobject_is_a(obj, cls) || !unreal_uobject_is_default(obj)) { - continue; - } - - if (unreal_fname_match_text(obj->name, name, ignore_case, exact_match)) { - return obj; - } - } - - return NULL; -} - -uclass_t * -unreal_uobject_find_class_by_full_name(str_t full_name) -{ - MOD_ASSERT_MSG(g_cached_objects.core_class != NULL, "/Script/CoreUObject.Class is not cached, make sure you call unreal_cache_objects()"); - - for (int i = 0; i < unreal_uobject_array_count(); ++i) { - uobject_t *obj = unreal_uobject_array_get_obj(i); - if (!obj) { - continue; - } - - if (!unreal_uobject_is_a(obj, g_cached_objects.core_class)) { - continue; - } - - tmp_arena_t tmp = mod_scratch_begin(MOD_ARENA_INVALID); - - str_t obj_full_name = unreal_uobject_push_full_name(obj, tmp.arena); - bool match = str_equal(obj_full_name, full_name, 0); - - mod_scratch_end(tmp); - - if (match) { - return (uclass_t *)obj; - } - } - - return NULL; -} - -uobject_t * -unreal_uobject_find_by_full_name(uclass_t *cls, str_t full_name) -{ - for (int i = 0; i < unreal_uobject_array_count(); ++i) { - uobject_t *obj = unreal_uobject_array_get_obj(i); - if (!obj) { - continue; - } - - if (cls && !unreal_uobject_is_a(obj, cls)) { - continue; - } - - tmp_arena_t tmp = mod_scratch_begin(MOD_ARENA_INVALID); - - str_t obj_full_name = unreal_uobject_push_full_name(obj, tmp.arena); - bool match = str_equal(obj_full_name, full_name, 0); - - mod_scratch_end(tmp); - - if (match) { - return obj; - } - } - - return NULL; -} - -void -unreal_process_event(uobject_t *self, ufunc_t *func, void *params) -{ - const mod_host_api_t *host = mod_sdk_host(); - if (host) { - host->process_event(self, func, params); - } -} - -uobject_t * -unreal_spawn_actor(uobject_t *world_ctx_obj, uclass_t *cls) -{ - MOD_ASSERT_MSG(g_cached_objects.gameplay_statics_cdo != NULL, "/Script/Engine.Default__GameplayStatics is not cached, make sure you call unreal_cache_objects()"); - MOD_ASSERT_MSG(g_cached_objects.begin_spawn != NULL, "/Script/Engine.GameplayStatics.BeginDeferredActorSpawnFromClass is not cached, make sure you call unreal_cache_objects()"); - MOD_ASSERT_MSG(g_cached_objects.finish_spawn != NULL, "/Script/Engine.GameplayStatics.FinishSpawningActor is not cached, make sure you call unreal_cache_objects()"); - - uobject_t *result = NULL; - tmp_arena_t tmp = mod_scratch_begin(MOD_ARENA_INVALID); - { - begin_actor_spawn_params_t *p1 = mod_arena_push(tmp.arena, sizeof(*p1), 16); - finish_actor_spawn_params_t *p2 = mod_arena_push(tmp.arena, sizeof(*p2), 16); - - MOD_ASSERT_MSG(p1 != NULL, "failed to allocate begin actor spawn params"); - MOD_ASSERT_MSG(p2 != NULL, "failed to allocate finish actor spawn params"); - - if (p1 && p2) { - ftransform_t xf = { - .rotation = {.w = 1.0f}, - .scale3d = {.x = 1.0f, .y = 1.0f, .z = 1.0f}, - }; - - *p1 = (begin_actor_spawn_params_t){ - .world_ctx_obj = (uworld_t *)world_ctx_obj, - .actor_class = cls, - .spawn_transform = xf, - .collision_handling_override = 3, - }; - - uobject_t *gameplay_statics_cdo = g_cached_objects.gameplay_statics_cdo; - ufunc_t *begin_spawn = g_cached_objects.begin_spawn; - ufunc_t *finish_spawn = g_cached_objects.finish_spawn; - - MOD_ASSERT_MSG(gameplay_statics_cdo != NULL, "missing /Script/Engine.Default__GameplayStatics"); - MOD_ASSERT_MSG(begin_spawn != NULL, "missing /Script/Engine.GameplayStatics.BeginDeferredActorSpawnFromClass"); - MOD_ASSERT_MSG(finish_spawn != NULL, "missing /Script/Engine.GameplayStatics.FinishSpawningActor"); - - unreal_process_event(gameplay_statics_cdo, begin_spawn, p1); - if (p1->return_value) { - *p2 = (finish_actor_spawn_params_t){ - .actor = p1->return_value, - .spawn_transform = xf, - }; - - unreal_process_event(gameplay_statics_cdo, finish_spawn, p2); - if (p2->return_value) { - result = (uobject_t *)p2->return_value; - } - } - } - } - mod_scratch_end(tmp); - return result; -} - -void -unreal_despawn_actor(uobject_t *actor) -{ - MOD_ASSERT_MSG(g_cached_objects.destroy_actor != NULL, "/Script/Engine.Actor.K2_DestroyActor is not cached, make sure you call unreal_cache_objects()"); - - ufunc_t *destroy_actor = g_cached_objects.destroy_actor; - if (actor) { - unreal_process_event(actor, destroy_actor, NULL); - } -} - -uobject_t * -unreal_static_construct_object(fstatic_construct_obj_params_t *params) -{ - const mod_host_api_t *host = mod_sdk_host(); - if (!MOD_HOST_API_HAS_FIELD(host, static_construct_object) || !host->static_construct_object) { - return NULL; - } - return host->static_construct_object(params); -} - -uobject_t * -unreal_static_load_object(uclass_t *obj_cls, uobject_t *outer, str_t name, str_t filename, uint32_t load_flags, void *sandbox, bool allow_obj_reconcile, void *instancing_ctx) -{ - const mod_host_api_t *host = mod_sdk_host(); - if (!MOD_HOST_API_HAS_FIELD(host, static_load_object) || !host->static_load_object) { - return NULL; - } - return host->static_load_object(obj_cls, outer, name, filename, load_flags, sandbox, allow_obj_reconcile, instancing_ctx); -} - -uclass_t * -unreal_static_load_class(uclass_t *base_cls, uobject_t *outer, str_t name, str_t filename, uint32_t load_flags) -{ - const mod_host_api_t *host = mod_sdk_host(); - return (host) ? host->static_load_class(base_cls, outer, name, filename, load_flags) : NULL; -} - -bool -unreal_mount_pak(str_t file_path, int order) -{ - const mod_host_api_t *host = mod_sdk_host(); - return (host) ? host->mount_pak(file_path, order) : false; -} - -bool -unreal_mount_iostore(str_t file_path, int order) -{ - const mod_host_api_t *host = mod_sdk_host(); - return (host) ? host->mount_iostore(file_path, order) : false; -} - -fnative_func_ptr_t -unreal_get_native(uint8_t opcode) -{ - const mod_host_api_t *host = mod_sdk_host(); - return (host) ? host->get_native(opcode) : (fnative_func_ptr_t){0}; -} - -bool -unreal_fframe_step(fframe_t *stack, void *result) -{ - MOD_ASSERT(stack != NULL); - MOD_ASSERT(stack->code != NULL); - - uint8_t opcode = *stack->code++; - fnative_func_ptr_t exec = unreal_get_native(opcode); - if (!exec) { - return false; - } - - exec(stack->obj, stack, result); - return true; -} - -/* ================================================ CLASS INTROSPECTION ============================================= */ -fprop_t * -unreal_ustruct_find_prop(ustruct_t *s, str_t name) -{ - for (fprop_t *p = s->prop_link; p; p = p->prop_link_next) { - if (unreal_fname_match_text(p->name, name, false, true)) { - return p; - } - } - - return NULL; -} - -ufunc_t * -unreal_ustruct_find_func(ustruct_t *s, str_t name) -{ - for (ustruct_t *cur = s; cur; cur = cur->super_struct) { - for (ufield_t *f = cur->children; f; f = f->next) { - if (unreal_fname_match_text(f->name, name, false, true)) { - return (ufunc_t *)f; - } - } - } - - return NULL; -} - -ufunc_t * -unreal_ustruct_find_func_fname(ustruct_t *s, fname_t name, bool ignore_num) -{ - for (ustruct_t *cur = s; cur; cur = cur->super_struct) { - for (ufield_t *f = cur->children; f; f = f->next) { - if (unreal_fname_equal(f->name, name, ignore_num)) { - return (ufunc_t *)f; - } - } - } - - return NULL; -} - -void * -unreal_get_mcast_sparse_delegate(uobject_t *delegate_owner, fname_t delegate_name) -{ - const mod_host_api_t *host = mod_sdk_host(); - return (host) ? host->get_mcast_sparse_delegate(delegate_owner, delegate_name) : NULL; -} - -/* =============================================== CONTAINER UTILITIES ============================================== */ - -static uint32_t * -unreal_tbit_array_data(tbit_array_t *bits) -{ - if (!bits) { - return NULL; - } - - if (bits->allocator.secondary_data) { - return (uint32_t *)bits->allocator.secondary_data; - } - - if (bits->num_bits > COUNTOF(bits->allocator.inline_data) * 32) { - MOD_ASSERT_MSG(false, "TBitArray has %d bits but no secondary allocation", bits->num_bits); - return NULL; - } - - return bits->allocator.inline_data; -} - -bool -unreal_tbit_array_is_set(tbit_array_t *bits, int32_t idx) -{ - if (!bits || idx < 0 || idx >= bits->num_bits) { - return false; - } - - uint32_t *data = unreal_tbit_array_data(bits); - if (!data) { - return false; - } - - uint32_t bit_idx = (uint32_t)idx; - return (data[bit_idx >> 5] & (1u << (bit_idx & 31))) != 0; -} - -int32_t -unreal_tbit_array_find_next_set(tbit_array_t *bits, int32_t start_idx) -{ - if (!bits || bits->num_bits <= 0) { - return TSET_INVALID_ID; - } - - if (start_idx < 0) { - start_idx = 0; - } - - uint32_t *data = unreal_tbit_array_data(bits); - if (!data) { - return TSET_INVALID_ID; - } - - for (int32_t idx = start_idx; idx < bits->num_bits; ++idx) { - uint32_t bit_idx = (uint32_t)idx; - if (data[bit_idx >> 5] & (1u << (bit_idx & 31))) { - return idx; - } - } - - return TSET_INVALID_ID; -} - -int32_t -unreal_tset_hash_head(hash_allocator_t *hash, int32_t hash_size, uint32_t key_hash) -{ - if (!hash || hash_size <= 0) { - return TSET_INVALID_ID; - } - - if ((hash_size & (hash_size - 1)) != 0) { - MOD_ASSERT_MSG(false, "TSet hash size must be a power of two: %d", hash_size); - return TSET_INVALID_ID; - } - - int32_t *data = hash->secondary_data ? (int32_t *)hash->secondary_data : hash->inline_data; - if (!hash->secondary_data && hash_size > COUNTOF(hash->inline_data)) { - MOD_ASSERT_MSG(false, "TSet hash has %d buckets but no secondary allocation", hash_size); - return TSET_INVALID_ID; - } - - return data[key_hash & (uint32_t)(hash_size - 1)]; -} - -bool -unreal_map_helpers_available(void) -{ - const mod_host_api_t *host = mod_sdk_host(); - return MOD_HOST_API_HAS_FIELD(host, map_find) && host->map_add && host->map_remove && host->map_find; -} - -void -unreal_map_add(void *map, fprop_map_t *prop, const void *key, const void *val) -{ - const mod_host_api_t *host = mod_sdk_host(); - if (!map || !prop || !key || !val || !MOD_HOST_API_HAS_FIELD(host, map_add) || !host->map_add) { - return; - } - host->map_add(map, prop, key, val); -} - -bool -unreal_map_remove(void *map, fprop_map_t *prop, const void *key) -{ - const mod_host_api_t *host = mod_sdk_host(); - if (!map || !prop || !key || !MOD_HOST_API_HAS_FIELD(host, map_remove) || !host->map_remove) { - return false; - } - return host->map_remove(map, prop, key); -} - -bool -unreal_map_find(void *map, fprop_map_t *prop, const void *key, void *out_val) -{ - const mod_host_api_t *host = mod_sdk_host(); - if (!map || !prop || !key || !out_val || !MOD_HOST_API_HAS_FIELD(host, map_find) || !host->map_find) { - return false; - } - return host->map_find(map, prop, key, out_val); -} - -/* =================================================== DATA TABLE =================================================== */ - -tmap_fname_uint8ptr_t * -unreal_udata_table_get_row_map(udata_table_t *table) -{ - return (table) ? &table->row_map : NULL; -} - -void -unreal_udata_table_add_row(udata_table_t *table, fname_t row_name, const ftable_row_base_t *row_data) -{ - if (table && row_data) { - table->vtable->add_row(table, row_name, row_data); - } -} - -void -unreal_udata_table_remove_row(udata_table_t *table, fname_t row_name) -{ - if (table) { - table->vtable->remove_row(table, row_name); - } -} - -void -unreal_udata_table_empty(udata_table_t *table) -{ - if (table) { - table->vtable->empty_table(table); - } -} - -uint8_t * -unreal_udata_table_find_row(udata_table_t *table, fname_t row_name) -{ - if (table && table->row_struct && !unreal_fname_is_none(row_name)) { - uint8_t **row_data_ptr = unreal_tmap_fname_uint8ptr_find(&table->row_map, row_name); - if (row_data_ptr) { - return *row_data_ptr; - } - } - return NULL; -} - -bool -unreal_add_gameplay_tag(fname_t tag_name) -{ - const mod_host_api_t *host = mod_sdk_host(); - if (!MOD_HOST_API_HAS_FIELD(host, add_gameplay_tag) || !host->add_gameplay_tag) { - return false; - } - return host->add_gameplay_tag(tag_name); -} - -bool -unreal_check_gameplay_tag_exists(fname_t tag_name) -{ - const mod_host_api_t *host = mod_sdk_host(); - if (!MOD_HOST_API_HAS_FIELD(host, check_gameplay_tag_exists) || !host->check_gameplay_tag_exists) { - return false; - } - return host->check_gameplay_tag_exists(tag_name); -} diff --git a/mod/mod_unreal.h b/mod/mod_unreal.h deleted file mode 100644 index e9ce8b1..0000000 --- a/mod/mod_unreal.h +++ /dev/null @@ -1,3115 +0,0 @@ -#ifndef MOD_UNREAL_H -#define MOD_UNREAL_H - -#include "mod_sdk.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define FNAME_MAX_BLOCK_BITS 13 -#define FNAME_BLOCK_OFFSET_BITS 16 -#define FNAME_MAX_BLOCKS (1 << FNAME_MAX_BLOCK_BITS) -#define FNAME_ENTRY_NAME_SIZE 1024 -#define FNAME_POOL_SHARD_BITS 8 -#define FNAME_POOL_MAX_SHARDS (1 << FNAME_POOL_SHARD_BITS) - -#define FNAME_NO_NUMBER_INTERNAL (0) -#define FNAME_INTERNAL_TO_EXTERNAL(NUM) ((NUM) - 1) -#define FNAME_EXTERNAL_TO_INTERNAL(NUM) ((NUM) + 1) - -#define FIO_STATUS_ERR_MSG_LEN 128 - -#define UOBJECT_ARRAY_NUM_ELEMS_PER_CHUNK (64 * 1024) - -#define FUNC_FLAG_NONE 0x00000000 -#define FUNC_FLAG_FINAL 0x00000001 -#define FUNC_FLAG_REQUIRED_API 0x00000002 -#define FUNC_FLAG_BLUEPRINT_AUTHORITY_ONLY 0x00000004 -#define FUNC_FLAG_BLUEPRINT_COSMETIC 0x00000008 -#define FUNC_FLAG_NET 0x00000040 -#define FUNC_FLAG_NET_RELIABLE 0x00000080 -#define FUNC_FLAG_NET_REQUEST 0x00000100 -#define FUNC_FLAG_EXEC 0x00000200 -#define FUNC_FLAG_NATIVE 0x00000400 -#define FUNC_FLAG_EVENT 0x00000800 -#define FUNC_FLAG_NET_RESPONSE 0x00001000 -#define FUNC_FLAG_STATIC 0x00002000 -#define FUNC_FLAG_NET_MULTICAST 0x00004000 -#define FUNC_FLAG_UBERGRAPH_FUNCTION 0x00008000 -#define FUNC_FLAG_MULTICAST_DELEGATE 0x00010000 -#define FUNC_FLAG_PUBLIC 0x00020000 -#define FUNC_FLAG_PRIVATE 0x00040000 -#define FUNC_FLAG_PROTECTED 0x00080000 -#define FUNC_FLAG_DELEGATE 0x00100000 -#define FUNC_FLAG_NET_SERVER 0x00200000 -#define FUNC_FLAG_HAS_OUT_PARMS 0x00400000 -#define FUNC_FLAG_HAS_DEFAULTS 0x00800000 -#define FUNC_FLAG_NET_CLIENT 0x01000000 -#define FUNC_FLAG_DLL_IMPORT 0x02000000 -#define FUNC_FLAG_BLUEPRINT_CALLABLE 0x04000000 -#define FUNC_FLAG_BLUEPRINT_EVENT 0x08000000 -#define FUNC_FLAG_BLUEPRINT_PURE 0x10000000 -#define FUNC_FLAG_EDITOR_ONLY 0x20000000 -#define FUNC_FLAG_CONST 0x40000000 -#define FUNC_FLAG_NET_VALIDATE 0x80000000 -#define FUNC_FLAG_ALL 0xFFFFFFFF - -typedef uint32_t estruct_flags_t; -#define ESF_NO_FLAGS 0x00000000 -#define ESF_NATIVE 0x00000001 -#define ESF_IDENTICAL_NATIVE 0x00000002 -#define ESF_HAS_INSTANCED_REF 0x00000004 -#define ESF_NO_EXPORT 0x00000008 -#define ESF_ATOMIC 0x00000010 -#define ESF_IMMUTABLE 0x00000020 -#define ESF_ADD_STRUCT_REF_OBJS 0x00000040 -#define ESF_REQUIRED_API 0x00000200 -#define ESF_NET_SERIALIZE_NATIVE 0x00000400 -#define ESF_SERIALIZE_NATIVE 0x00000800 -#define ESF_COPY_NATIVE 0x00001000 -#define ESF_IS_POD 0x00002000 -#define ESF_NO_DESTRUCTOR 0x00004000 -#define ESF_ZERO_CONSTRUCTOR 0x00008000 -#define ESF_EXPORT_TEXT_ITEM_NATIVE 0x00010000 -#define ESF_IMPORT_TEXT_ITEM_NATIVE 0x00020000 -#define ESF_POST_SERIALIZE_NATIVE 0x00040000 -#define ESF_SERIALIZE_FROM_MISMATCHED_TAG 0x00080000 -#define ESF_NET_DELTA_SERIALIZE_NATIVE 0x00100000 -#define ESF_POST_SCRIPT_CONSTRUCT 0x00200000 -#define ESF_NET_SHARED_SERIALIZATION 0x00400000 -#define ESF_TRASHED 0x00800000 - -typedef uint64_t eprop_flags_t; -#define CPF_NONE 0 -#define CPF_EDIT 0x0000000000000001 -#define CPF_CONST_PARM 0x0000000000000002 -#define CPF_BLUEPRINT_VISIBLE 0x0000000000000004 -#define CPF_EXPORT_OBJECT 0x0000000000000008 -#define CPF_BLUEPRINT_READ_ONLY 0x0000000000000010 -#define CPF_NET 0x0000000000000020 -#define CPF_EDIT_FIXED_SIZE 0x0000000000000040 -#define CPF_PARM 0x0000000000000080 -#define CPF_OUT_PARM 0x0000000000000100 -#define CPF_ZERO_CONSTRUCTOR 0x0000000000000200 -#define CPF_RETURN_PARM 0x0000000000000400 -#define CPF_DISABLE_EDIT_ON_TEMPLATE 0x0000000000000800 -#define CPF_TRANSIENT 0x0000000000002000 -#define CPF_CONFIG 0x0000000000004000 -#define CPF_DISABLE_EDIT_ON_INSTANCE 0x0000000000010000 -#define CPF_EDIT_CONST 0x0000000000020000 -#define CPF_GLOBAL_CONFIG 0x0000000000040000 -#define CPF_INSTANCED_REFERENCE 0x0000000000080000 -#define CPF_DUPLICATE_TRANSIENT 0x0000000000200000 -#define CPF_SAVE_GAME 0x0000000001000000 -#define CPF_NO_CLEAR 0x0000000002000000 -#define CPF_REFERENCE_PARM 0x0000000008000000 -#define CPF_BLUEPRINT_ASSIGNABLE 0x0000000010000000 -#define CPF_DEPRECATED 0x0000000020000000 -#define CPF_IS_PLAIN_OLD_DATA 0x0000000040000000 -#define CPF_REP_SKIP 0x0000000080000000 -#define CPF_REP_NOTIFY 0x0000000100000000 -#define CPF_INTERP 0x0000000200000000 -#define CPF_NON_TRANSACTIONAL 0x0000000400000000 -#define CPF_EDITOR_ONLY 0x0000000800000000 -#define CPF_NO_DESTRUCTOR 0x0000001000000000 -#define CPF_AUTO_WEAK 0x0000004000000000 -#define CPF_CONTAINS_INSTANCED_REFERENCE 0x0000008000000000 -#define CPF_ASSET_REGISTRY_SEARCHABLE 0x0000010000000000 -#define CPF_SIMPLE_DISPLAY 0x0000020000000000 -#define CPF_ADVANCED_DISPLAY 0x0000040000000000 -#define CPF_PROTECTED 0x0000080000000000 -#define CPF_BLUEPRINT_CALLABLE 0x0000100000000000 -#define CPF_BLUEPRINT_AUTHORITY_ONLY 0x0000200000000000 -#define CPF_TEXT_EXPORT_TRANSIENT 0x0000400000000000 -#define CPF_NON_PIE_DUPLICATE_TRANSIENT 0x0000800000000000 -#define CPF_EXPOSE_ON_SPAWN 0x0001000000000000 -#define CPF_PERSISTENT_INSTANCE 0x0002000000000000 -#define CPF_UOBJECT_WRAPPER 0x0004000000000000 -#define CPF_HAS_GET_VALUE_TYPE_HASH 0x0008000000000000 -#define CPF_NATIVE_ACCESS_SPECIFIER_PUBLIC 0x0010000000000000 -#define CPF_NATIVE_ACCESS_SPECIFIER_PROTECTED 0x0020000000000000 -#define CPF_NATIVE_ACCESS_SPECIFIER_PRIVATE 0x0040000000000000 -#define CPF_SKIP_SERIALIZATION 0x0080000000000000 - -typedef uint32_t eobj_flags_t; -enum { - RF_NO_FLAGS = 0X00000000, - RF_PUBLIC = 0X00000001, - RF_STANDALONE = 0X00000002, - RF_MARK_AS_NATIVE = 0X00000004, - RF_TRANSACTIONAL = 0X00000008, - RF_CLASS_DEFAULT_OBJECT = 0X00000010, - RF_ARCHETYPE_OBJECT = 0X00000020, - RF_TRANSIENT = 0X00000040, - RF_MARK_AS_ROOT_SET = 0X00000080, - RF_TAG_GARBAGE_TEMP = 0X00000100, - RF_NEED_INITIALIZATION = 0X00000200, - RF_NEED_LOAD = 0X00000400, - RF_KEEP_FOR_COOKER = 0X00000800, - RF_NEED_POST_LOAD = 0X00001000, - RF_NEED_POST_LOAD_SUBOBJECTS = 0X00002000, - RF_NEWER_VERSION_EXISTS = 0X00004000, - RF_BEGIN_DESTROYED = 0X00008000, - RF_FINISH_DESTROYED = 0X00010000, - RF_BEING_REGENERATED = 0X00020000, - RF_DEFAULT_SUB_OBJECT = 0X00040000, - RF_WAS_LOADED = 0X00080000, - RF_TEXT_EXPORT_TRANSIENT = 0X00100000, - RF_LOAD_COMPLETED = 0X00200000, - RF_INHERITABLE_COMPONENT_TEMPLATE = 0X00400000, - RF_DUPLICATE_TRANSIENT = 0X00800000, - RF_STRONG_REF_ON_FRAME = 0X01000000, - RF_NON_PIE_DUPLICATE_TRANSIENT = 0X02000000, - RF_DYNAMIC = 0X04000000, - RF_WILL_BE_LOADED = 0X08000000, - RF_HAS_EXTERNAL_PACKAGE = 0X10000000, -}; - -typedef enum { - EX_LOCAL_VARIABLE = 0x00, - EX_INSTANCE_VARIABLE = 0x01, - EX_DEFAULT_VARIABLE = 0x02, - EX_RETURN = 0x04, - EX_JUMP = 0x06, - EX_JUMP_IF_NOT = 0x07, - EX_ASSERT = 0x09, - EX_NOTHING = 0x0B, - EX_LET = 0x0F, - EX_CLASS_CONTEXT = 0x12, - EX_META_CAST = 0x13, - EX_LET_BOOL = 0x14, - EX_END_PARM_VALUE = 0x15, - EX_END_FUNCTION_PARMS = 0x16, - EX_SELF = 0x17, - EX_SKIP = 0x18, - EX_CONTEXT = 0x19, - EX_CONTEXT_FAIL_SILENT = 0x1A, - EX_VIRTUAL_FUNCTION = 0x1B, - EX_FINAL_FUNCTION = 0x1C, - EX_INT_CONST = 0x1D, - EX_FLOAT_CONST = 0x1E, - EX_STRING_CONST = 0x1F, - EX_OBJECT_CONST = 0x20, - EX_NAME_CONST = 0x21, - EX_ROTATION_CONST = 0x22, - EX_VECTOR_CONST = 0x23, - EX_BYTE_CONST = 0x24, - EX_INT_ZERO = 0x25, - EX_INT_ONE = 0x26, - EX_TRUE = 0x27, - EX_FALSE = 0x28, - EX_TEXT_CONST = 0x29, - EX_NO_OBJECT = 0x2A, - EX_TRANSFORM_CONST = 0x2B, - EX_INT_CONST_BYTE = 0x2C, - EX_NO_INTERFACE = 0x2D, - EX_DYNAMIC_CAST = 0x2E, - EX_STRUCT_CONST = 0x2F, - EX_END_STRUCT_CONST = 0x30, - EX_SET_ARRAY = 0x31, - EX_END_ARRAY = 0x32, - EX_PROPERTY_CONST = 0x33, - EX_UNICODE_STRING_CONST = 0x34, - EX_INT64_CONST = 0x35, - EX_UINT64_CONST = 0x36, - EX_PRIMITIVE_CAST = 0x38, - EX_SET_SET = 0x39, - EX_END_SET = 0x3A, - EX_SET_MAP = 0x3B, - EX_END_MAP = 0x3C, - EX_SET_CONST = 0x3D, - EX_END_SET_CONST = 0x3E, - EX_MAP_CONST = 0x3F, - EX_END_MAP_CONST = 0x40, - EX_STRUCT_MEMBER_CONTEXT = 0x42, - EX_LET_MULTICAST_DELEGATE = 0x43, - EX_LET_DELEGATE = 0x44, - EX_LOCAL_VIRTUAL_FUNCTION = 0x45, - EX_LOCAL_FINAL_FUNCTION = 0x46, - EX_LOCAL_OUT_VARIABLE = 0x48, - EX_DEPRECATED_OP_4A = 0x4A, - EX_INSTANCE_DELEGATE = 0x4B, - EX_PUSH_EXECUTION_FLOW = 0x4C, - EX_POP_EXECUTION_FLOW = 0x4D, - EX_COMPUTED_JUMP = 0x4E, - EX_POP_EXECUTION_FLOW_IF_NOT = 0x4F, - EX_BREAKPOINT = 0x50, - EX_INTERFACE_CONTEXT = 0x51, - EX_OBJ_TO_INTERFACE_CAST = 0x52, - EX_END_OF_SCRIPT = 0x53, - EX_CROSS_INTERFACE_CAST = 0x54, - EX_INTERFACE_TO_OBJ_CAST = 0x55, - EX_WIRE_TRACEPOINT = 0x5A, - EX_SKIP_OFFSET_CONST = 0x5B, - EX_ADD_MULTICAST_DELEGATE = 0x5C, - EX_CLEAR_MULTICAST_DELEGATE = 0x5D, - EX_TRACEPOINT = 0x5E, - EX_LET_OBJ = 0x5F, - EX_LET_WEAK_OBJ_PTR = 0x60, - EX_BIND_DELEGATE = 0x61, - EX_REMOVE_MULTICAST_DELEGATE = 0x62, - EX_CALL_MULTICAST_DELEGATE = 0x63, - EX_LET_VALUE_ON_PERSISTENT_FRAME = 0x64, - EX_ARRAY_CONST = 0x65, - EX_END_ARRAY_CONST = 0x66, - EX_SOFT_OBJECT_CONST = 0x67, - EX_CALL_MATH = 0x68, - EX_SWITCH_VALUE = 0x69, - EX_INSTRUMENTATION_EVENT = 0x6A, - EX_ARRAY_GET_BY_REF = 0x6B, - EX_CLASS_SPARSE_DATA_VARIABLE = 0x6C, - EX_FIELD_PATH_CONST = 0x6D, - EX_MAX = 0x100, -} expr_token_t; - -#define FSTRING(WS) \ - { \ - .data = (WS), \ - .len = COUNTOF(WS), \ - .max = COUNTOF(WS), \ - } - -#define TARRAY(T) \ - struct { \ - T *data; \ - int32_t num; \ - int32_t max; \ - } - -#define TARRAY_INLINE(T, N) \ - struct { \ - struct { \ - T inline_data[N]; \ - void *secondary_data; \ - } data; \ - int32_t num; \ - int32_t max; \ - } - -#define TPAIR(KT, VT) \ - struct { \ - KT key; \ - VT value; \ - } - -#define TSHARED_PTR(T) \ - struct { \ - T *obj; \ - void *ref_ctrl; \ - } - -#define TSPARSE_SLOT(T) \ - union { \ - T elem_data; \ - struct { \ - int32_t prev_free_idx; \ - int32_t next_free_idx; \ - }; \ - } - -#define TSPARSE(T) \ - struct { \ - TARRAY(TSPARSE_SLOT(T)) data; \ - tbit_array_t alloc_flags; \ - int32_t first_free_idx; \ - int32_t num_free_idx; \ - } - -#define TSET_ELEM(T) \ - struct { \ - T val; \ - int32_t hash_next_id; \ - int32_t hash_idx; \ - } - -#define TSET(T) \ - struct { \ - TSPARSE(TSET_ELEM(T)) elems; \ - hash_allocator_t hash; \ - int32_t hash_size; \ - } - -#define TMAP(TK, TV) \ - struct { \ - TSET(TPAIR(TK, TV)) pairs; \ - } - -#define TSET_INVALID_ID (-1) - -#define TSPARSE_NUM(SPARSE) ((SPARSE)->data.num - (SPARSE)->num_free_idx) -#define TSPARSE_MAX_INDEX(SPARSE) ((SPARSE)->data.num) -#define TSPARSE_IS_ALLOCATED(SPARSE, IDX) unreal_tbit_array_is_set(&(SPARSE)->alloc_flags, (IDX)) -#define TSPARSE_ELEM_AT(SPARSE, IDX) (&(SPARSE)->data.data[(IDX)].elem_data) -#define TSPARSE_FIRST_INDEX(SPARSE) unreal_tbit_array_find_next_set(&(SPARSE)->alloc_flags, 0) -#define TSPARSE_NEXT_INDEX(SPARSE, IDX) unreal_tbit_array_find_next_set(&(SPARSE)->alloc_flags, (IDX) + 1) -#define TSPARSE_FOR_EACH_INDEX(SPARSE, IDX) for (int32_t IDX = TSPARSE_FIRST_INDEX(SPARSE); IDX != TSET_INVALID_ID; IDX = TSPARSE_NEXT_INDEX((SPARSE), IDX)) - -#define TSET_NUM(SET) TSPARSE_NUM(&(SET)->elems) -#define TSET_MAX_INDEX(SET) TSPARSE_MAX_INDEX(&(SET)->elems) -#define TSET_IS_ALLOCATED(SET, IDX) TSPARSE_IS_ALLOCATED(&(SET)->elems, (IDX)) -#define TSET_ELEM_AT(SET, IDX) TSPARSE_ELEM_AT(&(SET)->elems, (IDX)) -#define TSET_FIRST_INDEX(SET) TSPARSE_FIRST_INDEX(&(SET)->elems) -#define TSET_NEXT_INDEX(SET, IDX) TSPARSE_NEXT_INDEX(&(SET)->elems, (IDX)) -#define TSET_FOR_EACH_INDEX(SET, IDX) for (int32_t IDX = TSET_FIRST_INDEX(SET); IDX != TSET_INVALID_ID; IDX = TSET_NEXT_INDEX((SET), IDX)) - -#define TMAP_NUM(MAP) TSET_NUM(&(MAP)->pairs) -#define TMAP_MAX_INDEX(MAP) TSET_MAX_INDEX(&(MAP)->pairs) -#define TMAP_IS_ALLOCATED(MAP, IDX) TSET_IS_ALLOCATED(&(MAP)->pairs, (IDX)) -#define TMAP_PAIR_AT(MAP, IDX) (&TSET_ELEM_AT(&(MAP)->pairs, (IDX))->val) -#define TMAP_KEY_AT(MAP, IDX) (TMAP_PAIR_AT((MAP), (IDX))->key) -#define TMAP_VALUE_AT(MAP, IDX) (TMAP_PAIR_AT((MAP), (IDX))->value) -#define TMAP_FIRST_INDEX(MAP) TSET_FIRST_INDEX(&(MAP)->pairs) -#define TMAP_NEXT_INDEX(MAP, IDX) TSET_NEXT_INDEX(&(MAP)->pairs, (IDX)) -#define TMAP_FOR_EACH_INDEX(MAP, IDX) for (int32_t IDX = TMAP_FIRST_INDEX(MAP); IDX != TSET_INVALID_ID; IDX = TMAP_NEXT_INDEX((MAP), IDX)) - -#define TMAP_DECLARE_FUNCS(NAME, MAP_TYPE, KEY_TYPE, VALUE_TYPE) \ - VALUE_TYPE * \ - NAME##_find(MAP_TYPE *map, KEY_TYPE key); - -#define TMAP_DEFINE_FUNCS(NAME, MAP_TYPE, KEY_TYPE, VALUE_TYPE, KEY_EQUAL, KEY_HASH) \ - VALUE_TYPE * \ - NAME##_find(MAP_TYPE *map, KEY_TYPE key) \ - { \ - if (!map || TMAP_NUM(map) == 0 || map->pairs.hash_size <= 0) { \ - return NULL; \ - } \ - \ - int32_t elem_idx = unreal_tset_hash_head(&map->pairs.hash, map->pairs.hash_size, (uint32_t)(KEY_HASH(key))); \ - while (elem_idx != TSET_INVALID_ID) { \ - if (elem_idx < 0 || elem_idx >= TMAP_MAX_INDEX(map) || !TMAP_IS_ALLOCATED(map, elem_idx)) { \ - MOD_ASSERT_MSG(false, "invalid TSet hash element index: %d", elem_idx); \ - return NULL; \ - } \ - \ - if (KEY_EQUAL(TMAP_PAIR_AT(map, elem_idx)->key, key)) { \ - return &TMAP_PAIR_AT(map, elem_idx)->value; \ - } \ - \ - int32_t next_idx = TSET_ELEM_AT(&map->pairs, elem_idx)->hash_next_id; \ - if (next_idx == elem_idx) { \ - MOD_ASSERT_MSG(false, "TSet hash chain points to itself at index %d", elem_idx); \ - return NULL; \ - } \ - elem_idx = next_idx; \ - } \ - \ - return NULL; \ - } - -typedef struct tmulticast_delegate_s tmulticast_delegate_t; -struct tmulticast_delegate_s { - TARRAY(void) invocation_list; - int32_t compaction_threshold; - int32_t invocation_list_lock_count; -}; - -typedef struct bit_array_allocator_s bit_array_allocator_t; -struct bit_array_allocator_s { - uint32_t inline_data[4]; - void *secondary_data; -}; -MOD_STATIC_ASSERT(sizeof(bit_array_allocator_t) == 24, "size mismatch"); - -typedef struct tbit_array_s tbit_array_t; -struct tbit_array_s { - bit_array_allocator_t allocator; - int32_t num_bits; - int32_t max_bits; -}; -MOD_STATIC_ASSERT(sizeof(tbit_array_t) == 32, "size mismatch"); - -typedef struct hash_allocator_s hash_allocator_t; -struct hash_allocator_s { - int32_t inline_data[1]; - void *secondary_data; -}; -MOD_STATIC_ASSERT(sizeof(hash_allocator_t) == 16, "size mismatch"); - -typedef uint32_t einput_event_t; -enum { - IE_PRESSED = 0, - IE_RELEASED = 1, - IE_REPEAT = 2, - IE_DOUBLE_CLICK = 3, - IE_AXIS = 4, - IE_MAX, -}; - -typedef struct fstring_s fstring_t; -struct fstring_s { - uint16_t *data; - int32_t len; - int32_t max; -}; -MOD_STATIC_ASSERT(sizeof(fstring_t) == 16, "size mismatch"); - -typedef uint32_t etext_flags_t; -enum { - ETEXT_TRANSIENT = (1 << 0), - ETEXT_CULTURE_INVARIANT = (1 << 1), - ETEXT_IMMUTABLE = (1 << 2), - ETEXT_INITIAL_EXPR_SYNCED = (1 << 3), -}; - -typedef int8_t etext_history_type_t; -enum { - ETEXT_HISTORY_TYPE_NONE = -1, - ETEXT_HISTORY_TYPE_BASE = 0, - ETEXT_HISTORY_TYPE_NAMED_FORMAT, - ETEXT_HISTORY_TYPE_ORDERED_FORMAT, - ETEXT_HISTORY_TYPE_ARGUMENT_FORMAT, - ETEXT_HISTORY_TYPE_AS_NUMBER, - ETEXT_HISTORY_TYPE_AS_PERCENT, - ETEXT_HISTORY_TYPE_AS_CURRENCY, - ETEXT_HISTORY_TYPE_AS_DATE, - ETEXT_HISTORY_TYPE_AS_TIME, - ETEXT_HISTORY_TYPE_AS_DATE_TIME, - ETEXT_HISTORY_TYPE_TRANSFORM, - ETEXT_HISTORY_TYPE_STRING_TABLE_ENTRY, - ETEXT_HISTORY_TYPE_TEXT_GENERATOR, -}; - -typedef uint8_t etext_identical_mode_flags_t; -enum { - ETEXT_IDENTICAL_MODE_NONE = 0, - ETEXT_IDENTICAL_MODE_DEEP_COMPARE = FLAG(0), - ETEXT_IDENTICAL_MODE_LEXICAL_COMPARE_INVARIANTS = FLAG(1), -}; - -typedef TSHARED_PTR(fstring_t) ftext_display_string_ptr_t; - -struct ftext_history_s; -struct ftext_s; - -typedef void (__fastcall *ftest_history_destructor_fn_t) (void); -typedef etext_history_type_t (__fastcall *ftest_history_get_type_fn_t) (void); -typedef bool (__fastcall *ftest_history_identical_to_fn_t) (struct ftext_history_s *other, etext_identical_mode_flags_t compare_mode_flags); -typedef fstring_t (__fastcall *ftest_history_build_localized_display_string_fn_t) (void); -typedef fstring_t (__fastcall *ftest_history_build_invariant_display_string_fn_t) (void); -typedef void (__fastcall *ftest_history_serialize_fn_t) (void *record); -typedef void (__fastcall *ftest_history_serialize_for_display_string_fn_t) (void *record, ftext_display_string_ptr_t *out_display_string); -typedef bool (__fastcall *ftest_history_should_read_from_buffer_fn_t) (const wchar_t *buffer); -typedef const wchar_t *(__fastcall *ftest_history_read_from_buffer_fn_t) (const wchar_t *buffer, const wchar_t *text_namespace, const wchar_t *package_namespace, ftext_display_string_ptr_t *out_display_string); -typedef bool (__fastcall *ftest_history_write_to_buffer_fn_t) (fstring_t *buffer, ftext_display_string_ptr_t display_string, bool strip_package_namespace); -typedef bool (__fastcall *ftest_history_is_out_of_date_fn_t) (void); -typedef fstring_t *(__fastcall *ftest_history_get_source_string_fn_t) (void); -typedef void (__fastcall *ftest_history_get_historic_format_data_fn_t) (struct ftext_s *text, void *out_historic_format_data); -typedef bool (__fastcall *ftest_history_get_historic_numeric_data_fn_t) (struct ftext_s *text, void *out_historic_numeric_data); -typedef bool (__fastcall *ftest_history_can_rebuild_localized_display_string_fn_t)(void); - -typedef struct ftext_history_vtable_s ftext_history_vtable_t; -struct ftext_history_vtable_s { - ftest_history_destructor_fn_t destructor; - ftest_history_get_type_fn_t get_type; - ftest_history_identical_to_fn_t identical_to; - ftest_history_build_localized_display_string_fn_t build_localized_display_string; - ftest_history_build_invariant_display_string_fn_t build_invariant_display_string; - ftest_history_serialize_fn_t serialize; - ftest_history_serialize_for_display_string_fn_t serialize_for_display_string; - ftest_history_should_read_from_buffer_fn_t should_read_from_buffer; - ftest_history_read_from_buffer_fn_t read_from_buffer; - ftest_history_write_to_buffer_fn_t write_to_buffer; - ftest_history_is_out_of_date_fn_t is_out_of_date; - ftest_history_get_source_string_fn_t get_source_string; - ftest_history_get_historic_format_data_fn_t get_historic_format_data; - ftest_history_get_historic_numeric_data_fn_t get_historic_numeric_data; - ftest_history_can_rebuild_localized_display_string_fn_t can_rebuild_localized_display_string; -}; - -typedef struct ftext_history_s ftext_history_t; -struct ftext_history_s { - ftext_history_vtable_t *vtable; - uint64_t revision; -}; - -typedef void (__fastcall *itext_data_destructor_fn_t) (void); -typedef bool (__fastcall *itext_data_owns_localized_string_fn_t) (void); -typedef fstring_t *(__fastcall *itext_data_get_display_string_fn_t) (void); -typedef ftext_display_string_ptr_t (__fastcall *itext_data_get_localized_string_fn_t) (void); -typedef ftext_display_string_ptr_t *(__fastcall *itext_data_get_mutable_localized_string_fn_t)(void); -typedef struct ftext_history_s *(__fastcall *itext_data_get_text_history_fn_t) (void); -typedef struct ftext_history_s *(__fastcall *itext_data_get_mutable_text_history_fn_t) (void); -typedef void (__fastcall *itext_data_persist_text_fn_t) (void); -typedef uint16_t (__fastcall *itext_data_get_global_history_revision_fn_t) (void); -typedef uint16_t (__fastcall *itext_data_get_local_history_revision_fn_t) (void); - -typedef struct itext_data_vtable_s itext_data_vtable_t; -struct itext_data_vtable_s { - itext_data_destructor_fn_t destructor; - itext_data_owns_localized_string_fn_t owns_localized_string; - itext_data_get_display_string_fn_t get_display_string; - itext_data_get_localized_string_fn_t get_localized_string; - itext_data_get_mutable_localized_string_fn_t get_mutable_localized_string; - itext_data_get_text_history_fn_t get_text_history; - itext_data_get_mutable_text_history_fn_t get_mutable_text_history; - itext_data_persist_text_fn_t persist_text; - itext_data_get_global_history_revision_fn_t get_global_history_revision; - itext_data_get_local_history_revision_fn_t get_local_history_revision; -}; - -typedef struct itext_data_s itext_data_t; -struct itext_data_s { - itext_data_vtable_t *vtable; -}; - -typedef struct ftext_data_s ftext_data_t; -struct ftext_data_s { - void *vftable; - fstring_t local_str; - fstring_t display_str; -}; - -typedef struct ftext_s ftext_t; -struct ftext_s { - TSHARED_PTR(itext_data_t) text_data; - etext_flags_t flags; -}; -MOD_STATIC_ASSERT(offsetof(ftext_t, flags) == 0x10, "invalid offset"); -MOD_STATIC_ASSERT(sizeof(ftext_t) == 0x18, "size mismatch"); - -typedef struct fscript_name_s fscript_name_t; -struct fscript_name_s { - uint32_t cmp_idx; - uint32_t display_idx; - uint32_t num; -}; -MOD_STATIC_ASSERT(sizeof(fscript_name_t) == 12, "size mismatch"); - -typedef struct frwlock_s { - void *ptr; -} frwlock_t; -MOD_STATIC_ASSERT(sizeof(frwlock_t) == 8, "size mismatch"); - -typedef struct fcritical_section_s fcritical_section_t; -struct fcritical_section_s { - void *opaque1[1]; - long opaque2[2]; - void *opaque3[3]; -}; -MOD_STATIC_ASSERT(sizeof(fcritical_section_t) == 0x28, "size mismatch"); - -typedef struct fkey_s fkey_t; -struct fkey_s { - fname_t name; - TSHARED_PTR(void) details; -}; -MOD_STATIC_ASSERT(sizeof(fkey_t) == 24, "size mismatch"); - -typedef struct finput_key_event_args_s finput_key_event_args_t; -struct finput_key_event_args_s { - void *viewport; - int32_t controller_id; - fkey_t key; - einput_event_t event; - float amount_depressed; - bool is_touch_event; -}; -MOD_STATIC_ASSERT(offsetof(finput_key_event_args_t, key) == 0x10, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(finput_key_event_args_t, event) == 0x28, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(finput_key_event_args_t, amount_depressed) == 0x2C, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(finput_key_event_args_t, is_touch_event) == 0x30, "invalid offset"); - -typedef struct fvector2d_s fvector2d_t; -struct fvector2d_s { - float x; - float y; -}; -MOD_STATIC_ASSERT(sizeof(fvector2d_t) == 8, "size mismatch"); - -typedef struct fmodifier_keys_state_s fmodifier_keys_state_t; -struct fmodifier_keys_state_s { - uint16_t is_left_shift_down : 1; - uint16_t is_right_shift_down : 1; - uint16_t is_left_control_down : 1; - uint16_t is_right_control_down : 1; - uint16_t is_left_alt_down : 1; - uint16_t is_right_alt_down : 1; - uint16_t is_left_command_down : 1; - uint16_t is_right_command_down : 1; - uint16_t are_caps_locked : 1; -}; -MOD_STATIC_ASSERT(sizeof(fmodifier_keys_state_t) == 2, "size mismatch"); - -typedef uint8_t egesture_event_t; -enum { - GESTURE_NONE = 0, - GESTURE_SCROLL = 1, - GESTURE_MAGNIFY = 2, - GESTURE_SWIPE = 3, - GESTURE_ROTATE = 4, - GESTURE_LONG_PRESS = 5, - GESTURE_COUNT = 6, -}; - -typedef struct finput_event_s finput_event_t; -struct finput_event_s { - void *vftable; - fmodifier_keys_state_t modifier_keys; - bool is_repeat; - uint8_t _pad0[1]; - uint32_t user_idx; - void *event_path; -}; -MOD_STATIC_ASSERT(sizeof(finput_event_t) == 0x18, "size mismatch"); -MOD_STATIC_ASSERT(offsetof(finput_event_t, modifier_keys) == 0x08, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(finput_event_t, is_repeat) == 0x0A, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(finput_event_t, user_idx) == 0x0C, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(finput_event_t, event_path) == 0x10, "invalid offset"); - -typedef struct fkey_event_s fkey_event_t; -struct fkey_event_s { - finput_event_t base; - fkey_t key; - uint32_t character_code; - uint32_t key_code; -}; -MOD_STATIC_ASSERT(sizeof(fkey_event_t) == 0x38, "size mismatch"); -MOD_STATIC_ASSERT(offsetof(fkey_event_t, key) == 0x18, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fkey_event_t, character_code) == 0x30, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fkey_event_t, key_code) == 0x34, "invalid offset"); - -typedef struct fanalog_input_event_s fanalog_input_event_t; -struct fanalog_input_event_s { - fkey_event_t base; - float analog_value; - uint8_t _pad0[4]; -}; -MOD_STATIC_ASSERT(sizeof(fanalog_input_event_t) == 0x40, "size mismatch"); -MOD_STATIC_ASSERT(offsetof(fanalog_input_event_t, analog_value) == 0x38, "invalid offset"); - -typedef struct fcharacter_event_s fcharacter_event_t; -struct fcharacter_event_s { - finput_event_t base; - uint16_t character; - uint8_t _pad0[6]; -}; -MOD_STATIC_ASSERT(sizeof(fcharacter_event_t) == 0x20, "size mismatch"); -MOD_STATIC_ASSERT(offsetof(fcharacter_event_t, character) == 0x18, "invalid offset"); - -typedef struct fpointer_event_s fpointer_event_t; -struct fpointer_event_s { - finput_event_t base; - fvector2d_t screen_space_pos; - fvector2d_t last_screen_space_pos; - fvector2d_t cursor_delta; - void *pressed_buttons; - fkey_t effecting_button; - uint32_t pointer_idx; - uint32_t touchpad_idx; - float force; - bool is_touch_event; - egesture_event_t gesture_type; - uint8_t _pad0[2]; - fvector2d_t wheel_or_gesture_delta; - bool is_direction_inverted_from_device; - bool is_touch_force_changed; - bool is_touch_first_move; - uint8_t _pad1[5]; -}; -MOD_STATIC_ASSERT(sizeof(fpointer_event_t) == 0x70, "size mismatch"); -MOD_STATIC_ASSERT(offsetof(fpointer_event_t, screen_space_pos) == 0x18, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fpointer_event_t, last_screen_space_pos) == 0x20, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fpointer_event_t, cursor_delta) == 0x28, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fpointer_event_t, pressed_buttons) == 0x30, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fpointer_event_t, effecting_button) == 0x38, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fpointer_event_t, pointer_idx) == 0x50, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fpointer_event_t, touchpad_idx) == 0x54, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fpointer_event_t, force) == 0x58, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fpointer_event_t, is_touch_event) == 0x5C, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fpointer_event_t, gesture_type) == 0x5D, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fpointer_event_t, wheel_or_gesture_delta) == 0x60, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fpointer_event_t, is_direction_inverted_from_device) == 0x68, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fpointer_event_t, is_touch_force_changed) == 0x69, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fpointer_event_t, is_touch_first_move) == 0x6A, "invalid offset"); - -typedef struct fname_entry_header_s fname_entry_header_t; -struct fname_entry_header_s { - uint16_t is_wide : 1; - uint16_t lowercase_hash : 5; - uint16_t len : 10; -}; - -typedef struct fname_entry_s fname_entry_t; -struct fname_entry_s { - fname_entry_header_t header; - union { - uint8_t ansi[FNAME_ENTRY_NAME_SIZE]; - uint16_t wide[FNAME_ENTRY_NAME_SIZE]; - } name; -}; - -typedef struct fname_entry_allocator_s fname_entry_allocator_t; -struct fname_entry_allocator_s { - void *rwlock; - uint32_t current_block; - uint32_t current_byte_cursor; - uint8_t *blocks[FNAME_MAX_BLOCKS]; -}; - -typedef struct fname_slot_s fname_slot_t; -struct fname_slot_s { - uint32_t id_and_hash; -}; - -typedef struct fname_pool_shard_s fname_pool_shard_t; -struct fname_pool_shard_s { - void *rwlock; - uint32_t used_slots; - uint32_t cap_mask; - fname_slot_t *slots; - fname_entry_allocator_t *entries; - uint32_t num_created_entries; - uint32_t num_created_wide_entries; -}; - -typedef struct fname_pool_s fname_pool_t; -struct fname_pool_s { - fname_entry_allocator_t entries; - fname_pool_shard_t cmp_shards[FNAME_POOL_MAX_SHARDS]; - // other fields ... -}; - -typedef struct fprimary_asset_type_s { - fname_t name; -} fprimary_asset_type_t; - -typedef struct fprimary_asset_id_s -{ - fprimary_asset_type_t primary_asset_type; - fname_t primary_asset_name; -} fprimary_asset_id_t; - -typedef enum { - ETT_HIDDEN = 0x0, - ETT_ALPHABETICAL = 0x1, - ETT_NUMERICAL = 0x2, - ETT_DIMENSIONAL = 0x3, - ETT_CHRONOLOGICAL = 0x4, -} etag_type_t; - -typedef enum { - EDMT_NORMAL = 0x0, - EDMT_WORLD = 0x1, - EDMT_PIE = 0x2, -} eduplicate_mode_type_t; - -typedef uint32_t erename_flags_t; - -typedef struct fasset_registry_tag_s { - fname_t name; - fstring_t value; - etag_type_t type; - uint32_t display_flags; -} fasset_registry_tag_t; - -struct ustruct_s; -struct uclass_s; -struct ufunc_s; -struct ufield_s; -struct uenum_s; -struct uscript_struct_s; -struct uobject_s; -struct uworld_s; -struct fprop_s; -struct foutput_device_s; -struct fout_parm_rec_s; -struct fframe_s; - -typedef TARRAY(struct uobject_s *) tarray_uobjectptr_t; -typedef TARRAY(void) tarray_void_t; -typedef TMAP(fstring_t, fstring_t) tmap_fstring_fstring_t; -typedef TMAP(struct uobject_s *, struct uobject_s *) tmap_uobjectptr_uobjectptr_t; -typedef TARRAY(fasset_registry_tag_t) tarray_fasset_registry_tag_t; - -typedef void (__fastcall *uobject_destructor_fn_t) (struct uobject_s *); -typedef void (__fastcall *uobject_register_deps_fn_t) (struct uobject_s *); -typedef void (__fastcall *uobject_deferred_register_fn_t) (struct uobject_s *, struct uclass_s *, const wchar_t *, const wchar_t *); -typedef bool (__fastcall *uobject_can_be_cluster_root_fn_t) (struct uobject_s *); -typedef bool (__fastcall *uobject_can_be_in_cluster_fn_t) (struct uobject_s *); -typedef void (__fastcall *uobject_create_cluster_fn_t) (struct uobject_s *); -typedef void (__fastcall *uobject_on_cluster_marked_as_pending_kill_fn_t) (struct uobject_s *); -typedef fstring_t (__fastcall *uobject_get_detailed_info_internal_fn_t) (struct uobject_s *); -typedef void (__fastcall *uobject_post_init_props_fn_t) (struct uobject_s *); -typedef void (__fastcall *uobject_post_cdo_contruct_fn_t) (struct uobject_s *); -typedef bool (__fastcall *uobject_pre_save_root_fn_t) (struct uobject_s *, const wchar_t *); -typedef void (__fastcall *uobject_post_save_root_fn_t) (struct uobject_s *, bool); -typedef void (__fastcall *uobject_pre_save_fn_t) (struct uobject_s *, const void *); -typedef bool (__fastcall *uobject_is_ready_for_async_post_load_fn_t) (struct uobject_s *); -typedef void (__fastcall *uobject_post_load_fn_t) (struct uobject_s *); -typedef void (__fastcall *uobject_post_load_subobjects_fn_t) (struct uobject_s *, void *); -typedef void (__fastcall *uobject_begin_destroy_fn_t) (struct uobject_s *); -typedef bool (__fastcall *uobject_is_ready_for_finish_destroy_fn_t) (struct uobject_s *); -typedef void (__fastcall *uobject_finish_destroy_fn_t) (struct uobject_s *); -typedef void (__fastcall *uobject_serialize_fn_t) (struct uobject_s *, void *); -typedef void (__fastcall *uobject_serialize_farchive_fn_t) (struct uobject_s *, void *); -typedef void (__fastcall *uobject_shutdown_after_error_fn_t) (struct uobject_s *); -typedef void (__fastcall *uobject_post_interp_change_fn_t) (struct uobject_s *, struct fprop_s *); -typedef void (__fastcall *uobject_post_rename_fn_t) (struct uobject_s *, struct uobject_s *, const fname_t); -typedef void (__fastcall *uobject_pre_duplicate_fn_t) (struct uobject_s *, void *); -typedef void (__fastcall *uobject_post_duplicate_from_type_fn_t) (struct uobject_s *, eduplicate_mode_type_t); -typedef void (__fastcall *uobject_post_duplicate_fn_t) (struct uobject_s *, bool); -typedef bool (__fastcall *uobject_needs_load_for_client_fn_t) (struct uobject_s *); -typedef bool (__fastcall *uobject_needs_load_for_server_fn_t) (struct uobject_s *); -typedef bool (__fastcall *uobject_needs_load_for_target_platform_fn_t) (struct uobject_s *, const void *); -typedef bool (__fastcall *uobject_needs_load_for_editor_game_fn_t) (struct uobject_s *); -typedef bool (__fastcall *uobject_is_editor_only_fn_t) (struct uobject_s *); -typedef bool (__fastcall *uobject_has_non_editor_only_references_fn_t) (struct uobject_s *); -typedef bool (__fastcall *uobject_is_post_load_thread_safe_fn_t) (struct uobject_s *); -typedef bool (__fastcall *uobject_is_destruction_thread_safe_fn_t) (struct uobject_s *); -typedef void (__fastcall *uobject_get_preload_deps_fn_t) (struct uobject_s *, tarray_uobjectptr_t *); -typedef void (__fastcall *uobject_get_prestream_packages_fn_t) (struct uobject_s *, tarray_uobjectptr_t *); -typedef void (__fastcall *uobject_export_custom_props_fn_t) (struct uobject_s *, struct foutput_device_s *, uint32_t); -typedef void (__fastcall *uobject_import_custom_props_fn_t) (struct uobject_s *, const wchar_t *, void *); -typedef void (__fastcall *uobject_post_edit_import_fn_t) (struct uobject_s *); -typedef void (__fastcall *uobject_post_reload_config_fn_t) (struct uobject_s *, struct fprop_s *); -typedef bool (__fastcall *uobject_rename_fn_t) (struct uobject_s *, const wchar_t *, struct uobject_s *, erename_flags_t); -typedef fstring_t (__fastcall *uobject_get_desc_fn_t) (struct uobject_s *); -typedef struct uscript_struct_s *(__fastcall *uobject_get_sparse_class_data_struct_fn_t) (struct uobject_s *); -typedef struct uworld_s *(__fastcall *uobject_get_world_fn_t) (struct uobject_s *); -typedef bool (__fastcall *uobject_get_native_prop_vals_fn_t) (struct uobject_s *, tmap_fstring_fstring_t *, uint32_t); -typedef void (__fastcall *uobject_get_resource_size_ex_fn_t) (struct uobject_s *, void *); -typedef fname_t (__fastcall *uobject_get_exporter_name_fn_t) (struct uobject_s *); -typedef void *(__fastcall *uobject_get_restore_for_uobject_overwrite_fn_t) (struct uobject_s *); -typedef bool (__fastcall *uobject_are_native_props_identical_to_fn_t) (struct uobject_s *, struct uobject_s *); -typedef void (__fastcall *uobject_get_asset_registry_tags_fn_t) (struct uobject_s *, tarray_fasset_registry_tag_t *); -typedef bool (__fastcall *uobject_is_asset_fn_t) (struct uobject_s *); -typedef fprimary_asset_id_t *(__fastcall *uobject_get_primary_asset_id_fn_t) (struct uobject_s *, fprimary_asset_id_t *); -typedef bool (__fastcall *uobject_is_localized_resource_fn_t) (struct uobject_s *); -typedef bool (__fastcall *uobject_is_safe_for_root_set_fn_t) (struct uobject_s *); -typedef void (__fastcall *uobject_tag_subobjects_fn_t) (struct uobject_s *, eobj_flags_t); -typedef void (__fastcall *uobject_get_lifetime_replicated_props_fn_t) (struct uobject_s *, tarray_void_t *); -typedef bool (__fastcall *uobject_is_name_stable_for_networking_fn_t) (struct uobject_s *); -typedef bool (__fastcall *uobject_is_full_name_stable_for_networking_fn_t) (struct uobject_s *); -typedef bool (__fastcall *uobject_is_supported_for_networking_fn_t) (struct uobject_s *); -typedef void (__fastcall *uobject_get_subobjects_with_stable_names_for_networking_fn_t)(struct uobject_s *, tarray_uobjectptr_t *); -typedef void (__fastcall *uobject_pre_net_receive_fn_t) (struct uobject_s *); -typedef void (__fastcall *uobject_post_net_receive_fn_t) (struct uobject_s *); -typedef void (__fastcall *uobject_post_rep_notifies_fn_t) (struct uobject_s *); -typedef void (__fastcall *uobject_pre_destroy_from_replication_fn_t) (struct uobject_s *); -typedef void (__fastcall *uobject_build_subobject_mapping_fn_t) (struct uobject_s *, struct uobject_s *, tmap_uobjectptr_uobjectptr_t *); -typedef const wchar_t *(__fastcall *uobject_get_config_override_platform_fn_t) (struct uobject_s *); -typedef void (__fastcall *uobject_override_per_object_config_section_fn_t) (struct uobject_s *, fstring_t *); -typedef void (__fastcall *uobject_process_event_fn_t) (struct uobject_s *, struct ufunc_s *, void *); -typedef int32_t (__fastcall *uobject_get_function_callspace_fn_t) (struct uobject_s *, struct ufunc_s *, struct fframe_s *); -typedef bool (__fastcall *uobject_call_remote_function_fn_t) (struct uobject_s *, struct ufunc_s *, void *, struct fout_parm_rec_s *, struct fframe_s *); -typedef bool (__fastcall *uobject_process_console_exec_fn_t) (struct uobject_s *, const wchar_t *, struct foutput_device_s *, struct uobject_s *); -typedef struct uclass_s *(__fastcall *uobject_regenerate_class_fn_t) (struct uobject_s *, struct uclass_s *, struct uobject_s *); -typedef void (__fastcall *uobject_mark_as_editor_only_subobject_fn_t) (struct uobject_s *); -typedef bool (__fastcall *uobject_check_default_subobjects_internal_fn_t) (struct uobject_s *); -typedef void (__fastcall *uobject_validate_generated_rep_enums_fn_t) (struct uobject_s *, const tarray_void_t *); -typedef void (__fastcall *uobject_set_net_push_id_dynamic_fn_t) (struct uobject_s *, const int32_t); -typedef int32_t (__fastcall *uobject_get_net_push_id_dynamic_fn_t) (struct uobject_s *); - -typedef struct uobject_vtable_s uobject_vtable_t; -struct uobject_vtable_s { - uobject_destructor_fn_t destructor; - uobject_register_deps_fn_t register_deps; - uobject_deferred_register_fn_t deferred_register; - uobject_can_be_cluster_root_fn_t can_be_cluster_root; - uobject_can_be_in_cluster_fn_t can_be_in_cluster; - uobject_create_cluster_fn_t create_cluster; - uobject_on_cluster_marked_as_pending_kill_fn_t on_cluster_marked_as_pending_kill; - uobject_get_detailed_info_internal_fn_t get_detailed_info_internal; - uobject_post_init_props_fn_t post_init_props; - uobject_post_cdo_contruct_fn_t post_cdo_contruct; - uobject_pre_save_root_fn_t pre_save_root; - uobject_post_save_root_fn_t post_save_root; - uobject_pre_save_fn_t pre_save; - uobject_is_ready_for_async_post_load_fn_t is_ready_for_async_post_load; - uobject_post_load_fn_t post_load; - uobject_post_load_subobjects_fn_t post_load_subobjects; - uobject_begin_destroy_fn_t begin_destroy; - uobject_is_ready_for_finish_destroy_fn_t is_ready_for_finish_destroy; - uobject_finish_destroy_fn_t finish_destroy; - uobject_serialize_fn_t serialize; - uobject_serialize_farchive_fn_t serialize_farchive; - uobject_shutdown_after_error_fn_t shutdown_after_error; - uobject_post_interp_change_fn_t post_interp_change; - uobject_post_rename_fn_t post_rename; - uobject_pre_duplicate_fn_t pre_duplicate; - uobject_post_duplicate_from_type_fn_t post_duplicate_from_type; - uobject_post_duplicate_fn_t post_duplicate; - uobject_needs_load_for_client_fn_t needs_load_for_client; - uobject_needs_load_for_server_fn_t needs_load_for_server; - uobject_needs_load_for_target_platform_fn_t needs_load_for_target_platform; - uobject_needs_load_for_editor_game_fn_t needs_load_for_editor_game; - uobject_is_editor_only_fn_t is_editor_only; - uobject_has_non_editor_only_references_fn_t has_non_editor_only_references; - uobject_is_post_load_thread_safe_fn_t is_post_load_thread_safe; - uobject_is_destruction_thread_safe_fn_t is_destruction_thread_safe; - uobject_get_preload_deps_fn_t get_preload_deps; - uobject_get_prestream_packages_fn_t get_prestream_packages; - uobject_export_custom_props_fn_t export_custom_props; - uobject_import_custom_props_fn_t import_custom_props; - uobject_post_edit_import_fn_t post_edit_import; - uobject_post_reload_config_fn_t post_reload_config; - uobject_rename_fn_t rename; - uobject_get_desc_fn_t get_desc; - uobject_get_sparse_class_data_struct_fn_t get_sparse_class_data_struct; - uobject_get_world_fn_t get_world; - uobject_get_native_prop_vals_fn_t get_native_prop_vals; - uobject_get_resource_size_ex_fn_t get_resource_size_ex; - uobject_get_exporter_name_fn_t get_exporter_name; - uobject_get_restore_for_uobject_overwrite_fn_t get_restore_for_uobject_overwrite; - uobject_are_native_props_identical_to_fn_t are_native_props_identical_to; - uobject_get_asset_registry_tags_fn_t get_asset_registry_tags; - uobject_is_asset_fn_t is_asset; - uobject_get_primary_asset_id_fn_t get_primary_asset_id; - uobject_is_localized_resource_fn_t is_localized_resource; - uobject_is_safe_for_root_set_fn_t is_safe_for_root_set; - uobject_tag_subobjects_fn_t tag_subobjects; - uobject_get_lifetime_replicated_props_fn_t get_lifetime_replicated_props; - uobject_is_name_stable_for_networking_fn_t is_name_stable_for_networking; - uobject_is_full_name_stable_for_networking_fn_t is_full_name_stable_for_networking; - uobject_is_supported_for_networking_fn_t is_supported_for_networking; - uobject_get_subobjects_with_stable_names_for_networking_fn_t get_subobjects_with_stable_names_for_networking; - uobject_pre_net_receive_fn_t pre_net_receive; - uobject_post_net_receive_fn_t post_net_receive; - uobject_post_rep_notifies_fn_t post_rep_notifies; - uobject_pre_destroy_from_replication_fn_t pre_destroy_from_replication; - uobject_build_subobject_mapping_fn_t build_subobject_mapping; - uobject_get_config_override_platform_fn_t get_config_override_platform; - uobject_override_per_object_config_section_fn_t override_per_object_config_section; - uobject_process_event_fn_t process_event; - uobject_get_function_callspace_fn_t get_function_callspace; - uobject_call_remote_function_fn_t call_remote_function; - uobject_process_console_exec_fn_t process_console_exec; - uobject_regenerate_class_fn_t regenerate_class; - uobject_mark_as_editor_only_subobject_fn_t mark_as_editor_only_subobject; - uobject_check_default_subobjects_internal_fn_t check_default_subobjects_internal; - uobject_validate_generated_rep_enums_fn_t validate_generated_rep_enums; - uobject_set_net_push_id_dynamic_fn_t set_net_push_id_dynamic; - uobject_get_net_push_id_dynamic_fn_t get_net_push_id_dynamic; -}; -MOD_STATIC_ASSERT(sizeof(uobject_vtable_t) == 0x270, "size mismatch"); - -typedef struct uobject_s uobject_t; -struct uobject_s { - uobject_vtable_t *vtable; - eobj_flags_t obj_flags; - int32_t internal_idx; - struct uclass_s *cls; - fname_t name; - struct uobject_s *outer; -}; -MOD_STATIC_ASSERT(sizeof(uobject_t) == 0x28, "size mismatch"); - -struct ufield_s; - -typedef void (__fastcall *ufield_add_cpp_prop_fn_t)(struct ufield_s *, struct fprop_s *); -typedef void (__fastcall *ufield_bind_fn_t) (struct ufield_s *); - -typedef struct ufield_vtable_s ufield_vtable_t; -struct ufield_vtable_s { - uobject_destructor_fn_t destructor; - uobject_register_deps_fn_t register_deps; - uobject_deferred_register_fn_t deferred_register; - uobject_can_be_cluster_root_fn_t can_be_cluster_root; - uobject_can_be_in_cluster_fn_t can_be_in_cluster; - uobject_create_cluster_fn_t create_cluster; - uobject_on_cluster_marked_as_pending_kill_fn_t on_cluster_marked_as_pending_kill; - uobject_get_detailed_info_internal_fn_t get_detailed_info_internal; - uobject_post_init_props_fn_t post_init_props; - uobject_post_cdo_contruct_fn_t post_cdo_contruct; - uobject_pre_save_root_fn_t pre_save_root; - uobject_post_save_root_fn_t post_save_root; - uobject_pre_save_fn_t pre_save; - uobject_is_ready_for_async_post_load_fn_t is_ready_for_async_post_load; - uobject_post_load_fn_t post_load; - uobject_post_load_subobjects_fn_t post_load_subobjects; - uobject_begin_destroy_fn_t begin_destroy; - uobject_is_ready_for_finish_destroy_fn_t is_ready_for_finish_destroy; - uobject_finish_destroy_fn_t finish_destroy; - uobject_serialize_fn_t serialize; - uobject_serialize_farchive_fn_t serialize_farchive; - uobject_shutdown_after_error_fn_t shutdown_after_error; - uobject_post_interp_change_fn_t post_interp_change; - uobject_post_rename_fn_t post_rename; - uobject_pre_duplicate_fn_t pre_duplicate; - uobject_post_duplicate_from_type_fn_t post_duplicate_from_type; - uobject_post_duplicate_fn_t post_duplicate; - uobject_needs_load_for_client_fn_t needs_load_for_client; - uobject_needs_load_for_server_fn_t needs_load_for_server; - uobject_needs_load_for_target_platform_fn_t needs_load_for_target_platform; - uobject_needs_load_for_editor_game_fn_t needs_load_for_editor_game; - uobject_is_editor_only_fn_t is_editor_only; - uobject_has_non_editor_only_references_fn_t has_non_editor_only_references; - uobject_is_post_load_thread_safe_fn_t is_post_load_thread_safe; - uobject_is_destruction_thread_safe_fn_t is_destruction_thread_safe; - uobject_get_preload_deps_fn_t get_preload_deps; - uobject_get_prestream_packages_fn_t get_prestream_packages; - uobject_export_custom_props_fn_t export_custom_props; - uobject_import_custom_props_fn_t import_custom_props; - uobject_post_edit_import_fn_t post_edit_import; - uobject_post_reload_config_fn_t post_reload_config; - uobject_rename_fn_t rename; - uobject_get_desc_fn_t get_desc; - uobject_get_sparse_class_data_struct_fn_t get_sparse_class_data_struct; - uobject_get_world_fn_t get_world; - uobject_get_native_prop_vals_fn_t get_native_prop_vals; - uobject_get_resource_size_ex_fn_t get_resource_size_ex; - uobject_get_exporter_name_fn_t get_exporter_name; - uobject_get_restore_for_uobject_overwrite_fn_t get_restore_for_uobject_overwrite; - uobject_are_native_props_identical_to_fn_t are_native_props_identical_to; - uobject_get_asset_registry_tags_fn_t get_asset_registry_tags; - uobject_is_asset_fn_t is_asset; - uobject_get_primary_asset_id_fn_t get_primary_asset_id; - uobject_is_localized_resource_fn_t is_localized_resource; - uobject_is_safe_for_root_set_fn_t is_safe_for_root_set; - uobject_tag_subobjects_fn_t tag_subobjects; - uobject_get_lifetime_replicated_props_fn_t get_lifetime_replicated_props; - uobject_is_name_stable_for_networking_fn_t is_name_stable_for_networking; - uobject_is_full_name_stable_for_networking_fn_t is_full_name_stable_for_networking; - uobject_is_supported_for_networking_fn_t is_supported_for_networking; - uobject_get_subobjects_with_stable_names_for_networking_fn_t get_subobjects_with_stable_names_for_networking; - uobject_pre_net_receive_fn_t pre_net_receive; - uobject_post_net_receive_fn_t post_net_receive; - uobject_post_rep_notifies_fn_t post_rep_notifies; - uobject_pre_destroy_from_replication_fn_t pre_destroy_from_replication; - uobject_build_subobject_mapping_fn_t build_subobject_mapping; - uobject_get_config_override_platform_fn_t get_config_override_platform; - uobject_override_per_object_config_section_fn_t override_per_object_config_section; - uobject_process_event_fn_t process_event; - uobject_get_function_callspace_fn_t get_function_callspace; - uobject_call_remote_function_fn_t call_remote_function; - uobject_process_console_exec_fn_t process_console_exec; - uobject_regenerate_class_fn_t regenerate_class; - uobject_mark_as_editor_only_subobject_fn_t mark_as_editor_only_subobject; - uobject_check_default_subobjects_internal_fn_t check_default_subobjects_internal; - uobject_validate_generated_rep_enums_fn_t validate_generated_rep_enums; - uobject_set_net_push_id_dynamic_fn_t set_net_push_id_dynamic; - uobject_get_net_push_id_dynamic_fn_t get_net_push_id_dynamic; - ufield_add_cpp_prop_fn_t add_cpp_prop; - ufield_bind_fn_t bind; -}; -MOD_STATIC_ASSERT(sizeof(ufield_vtable_t) == 0x280, "size mismatch"); - -typedef struct ufield_s ufield_t; -struct ufield_s { - /* uobject_t */ - ufield_vtable_t *vtable; - eobj_flags_t obj_flags; - int32_t internal_idx; - struct uclass_s *cls; - fname_t name; - struct uobject_s *outer; - /* ufield_t */ - struct ufield_s *next; -}; -MOD_STATIC_ASSERT(offsetof(ufield_t, next) == 0x28, "invalid offset"); - -typedef struct fthread_safe_counter_s fthread_safe_counter_t; -struct fthread_safe_counter_s { - volatile int32_t counter; -}; - -typedef struct ffield_variant_s ffield_variant_t; -struct ffield_variant_s { - union { - struct ffield_s *field; - uobject_t *obj; - } container; - uint8_t is_uobject; - uint8_t _pad0[7]; -}; - -typedef struct ffield_class_s ffield_class_t; -struct ffield_class_s { - fname_t name; - uint64_t id; - uint64_t cast_flags; - uint32_t class_flags; - struct ffield_class_s *super_class; - struct ffield_s *default_obj; - struct ffield_s *(*ctor_fn)(ffield_variant_t *, fname_t *, uint32_t); - fthread_safe_counter_t unique_name_idx_counter; -}; - -typedef TARRAY(struct ffield_s *) tarray_ffieldptr_t; - -typedef void (__fastcall *ffield_destructor_fn_t) (struct ffield_s *); -typedef void (__fastcall *ffield_serialize_fn_t) (struct ffield_s *, void *); -typedef void (__fastcall *ffield_post_load_fn_t) (struct ffield_s *); -typedef void (__fastcall *ffield_get_preload_deps_fn_t) (struct ffield_s *, tarray_uobjectptr_t *); -typedef void (__fastcall *ffield_begin_destroy_fn_t) (struct ffield_s *); -typedef void (__fastcall *ffield_add_referenced_objs_fn_t) (struct ffield_s *, void *); -typedef void (__fastcall *ffield_add_cpp_prop_fn_t) (struct ffield_s *, struct fprop_s *); -typedef void (__fastcall *ffield_bind_fn_t) (struct ffield_s *); -typedef void (__fastcall *ffield_post_duplicate_fn_t) (struct ffield_s *, struct ffield_s *); -typedef struct ffield_s *(__fastcall *ffield_get_inner_field_by_name_fn_t) (struct ffield_s *, fname_t *); -typedef void (__fastcall *ffield_get_inner_fields_fn_t) (struct ffield_s *, tarray_ffieldptr_t *); - -typedef struct ffield_vtable_s ffield_vtable_t; -struct ffield_vtable_s { - ffield_destructor_fn_t destructor; - ffield_serialize_fn_t serialize; - ffield_post_load_fn_t post_load; - ffield_get_preload_deps_fn_t get_preload_deps; - ffield_begin_destroy_fn_t begin_destroy; - ffield_add_referenced_objs_fn_t add_referenced_objs; - ffield_add_cpp_prop_fn_t add_cpp_prop; - ffield_bind_fn_t bind; - ffield_post_duplicate_fn_t post_duplicate; - ffield_get_inner_field_by_name_fn_t get_inner_field_by_name; - ffield_get_inner_fields_fn_t get_inner_fields; -}; -MOD_STATIC_ASSERT(sizeof(ffield_vtable_t) == 0x58, "size mismatch"); - -typedef struct ffield_s ffield_t; -struct ffield_s { - ffield_vtable_t *vtable; - ffield_class_t *cls; - ffield_variant_t owner; - struct ffield_s *next; - fname_t name; - uint32_t flags; -}; - -MOD_STATIC_ASSERT(offsetof(ffield_t, cls) == 0x08, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ffield_t, owner) == 0x10, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ffield_t, next) == 0x20, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ffield_t, name) == 0x28, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ffield_t, flags) == 0x30, "invalid offset"); - -typedef struct fguid_s fguid_t; -struct fguid_s { - uint32_t a; - uint32_t b; - uint32_t c; - uint32_t d; -}; -MOD_STATIC_ASSERT(sizeof(fguid_t) == 16, "size mismatch"); - -typedef enum { - ECFTR_USE_SERIALIZE_ITEM = 0x0, - ECFTR_CANNOT_CONVERT = 0x1, - ECFTR_CONVERTED = 0x2, -} econvert_from_type_result_t; - -typedef struct fprop_tag_s { - struct fprop_s *prop; - fname_t type; - uint8_t bool_val; - fname_t name; - fname_t struct_name; - fname_t enum_name; - fname_t inner_type; - fname_t value_jtype; - int32_t size; - int32_t array_index; - int64_t size_offset; - fguid_t struct_guid; - uint8_t has_prop_guid; - fguid_t prop_guid; -} fprop_tag_t; - -typedef struct fstructured_archive_slot_s { - void *ar; -} fstructured_archive_slot_t; - -typedef enum { - EPORT_NONE = 0x0, - EPORT_STRONG = 0x1, - EPORT_WEAK = 0x2, -} eprop_obj_ref_type_t; - -struct fprop_struct_s; - -typedef TARRAY(uint8_t) tarray_uint8_t; -typedef TARRAY(struct fprop_struct_s *) tarray_fprop_structptr_t; - -typedef fstring_t (__fastcall *fprop_get_cpp_macro_type_fn_t) (struct fprop_s *, fstring_t *); -typedef bool (__fastcall *fprop_pass_cpp_args_by_ref_fn_t) (struct fprop_s *); -typedef fstring_t (__fastcall *fprop_get_cpp_type_fn_t) (struct fprop_s *, fstring_t *, uint32_t); -typedef fstring_t (__fastcall *fprop_get_cpp_type_forward_declaration_fn_t) (struct fprop_s *); -typedef void (__fastcall *fprop_link_internal_fn_t) (struct fprop_s *, void *); -typedef econvert_from_type_result_t (__fastcall *fprop_convert_from_type_fn_t) (struct fprop_s *, fprop_tag_t *, fstructured_archive_slot_t, uint8_t *, struct ustruct_s *); -typedef bool (__fastcall *fprop_identical_fn_t) (struct fprop_s *, const void *, const void *, uint32_t); -typedef void (__fastcall *fprop_serialize_item_fn_t) (struct fprop_s *, fstructured_archive_slot_t, void *, const void *); -typedef bool (__fastcall *fprop_netserialize_item_fn_t) (struct fprop_s *, void *, void *, void *, tarray_uint8_t *); -typedef bool (__fastcall *fprop_supports_net_shared_serialization_fn_t) (struct fprop_s *); -typedef void (__fastcall *fprop_export_text_item_fn_t) (struct fprop_s *, fstring_t *, const void *, const void *, struct uobject_s *, int32_t, struct uobject_s *); -typedef const wchar_t *(__fastcall *fprop_import_text_internal_fn_t) (struct fprop_s *, const wchar_t *, void *, int32_t, struct uobject_s *, struct foutput_device_s *); -typedef void (__fastcall *fprop_copy_values_internal_fn_t) (struct fprop_s *, void *, const void *, int32_t); -typedef uint32_t (__fastcall *fprop_get_value_type_hash_internal_fn_t) (struct fprop_s *, const void *); -typedef void (__fastcall *fprop_copy_single_value_to_script_vm_fn_t) (struct fprop_s *, void *, const void *); -typedef void (__fastcall *fprop_copy_complete_value_to_script_vm_fn_t) (struct fprop_s *, void *, const void *); -typedef void (__fastcall *fprop_copy_single_value_from_script_vm_fn_t) (struct fprop_s *, void *, const void *); -typedef void (__fastcall *fprop_copy_complete_value_from_script_vm_fn_t) (struct fprop_s *, void *, const void *); -typedef void (__fastcall *fprop_clear_value_internal_fn_t) (struct fprop_s *, void *); -typedef void (__fastcall *fprop_destroy_value_internal_fn_t) (struct fprop_s *, void *); -typedef void (__fastcall *fprop_initialize_value_internal_fn_t) (struct fprop_s *, void *); -typedef fname_t (__fastcall *fprop_get_id_fn_t) (struct fprop_s *); -typedef void (__fastcall *fprop_instance_subobjects_fn_t) (struct fprop_s *, void *, const void *, struct uobject_s *, void *); -typedef int32_t (__fastcall *fprop_get_min_alignment_fn_t) (struct fprop_s *); -typedef bool (__fastcall *fprop_contains_object_reference_fn_t) (struct fprop_s *, tarray_fprop_structptr_t *, eprop_obj_ref_type_t); -typedef void (__fastcall *fprop_emit_reference_info_fn_t) (struct fprop_s *, struct uclass_s *, int32_t, tarray_fprop_structptr_t *); -typedef bool (__fastcall *fprop_same_type_fn_t) (struct fprop_s *, struct fprop_s *); - -typedef struct fprop_vtable_s fprop_vtable_t; -struct fprop_vtable_s { - ffield_destructor_fn_t destructor; - ffield_serialize_fn_t serialize; - ffield_post_load_fn_t post_load; - ffield_get_preload_deps_fn_t get_preload_deps; - ffield_begin_destroy_fn_t begin_destroy; - ffield_add_referenced_objs_fn_t add_referenced_objs; - ffield_add_cpp_prop_fn_t add_cpp_prop; - ffield_bind_fn_t bind; - ffield_post_duplicate_fn_t post_duplicate; - ffield_get_inner_field_by_name_fn_t get_inner_field_by_name; - ffield_get_inner_fields_fn_t get_inner_fields; - fprop_get_cpp_macro_type_fn_t get_cpp_macro_type; - fprop_pass_cpp_args_by_ref_fn_t pass_cpp_args_by_ref; - fprop_get_cpp_type_fn_t get_cpp_type; - fprop_get_cpp_type_forward_declaration_fn_t get_cpp_type_forward_declaration; - fprop_link_internal_fn_t link_internal; - fprop_convert_from_type_fn_t convert_from_type; - fprop_identical_fn_t identical; - fprop_serialize_item_fn_t serialize_item; - fprop_netserialize_item_fn_t netserialize_item; - fprop_supports_net_shared_serialization_fn_t supports_net_shared_serialization; - fprop_export_text_item_fn_t export_text_item; - fprop_import_text_internal_fn_t import_text_internal; - fprop_copy_values_internal_fn_t copy_values_internal; - fprop_get_value_type_hash_internal_fn_t get_value_type_hash_internal; - fprop_copy_single_value_to_script_vm_fn_t copy_single_value_to_script_vm; - fprop_copy_complete_value_to_script_vm_fn_t copy_complete_value_to_script_vm; - fprop_copy_single_value_from_script_vm_fn_t copy_single_value_from_script_vm; - fprop_copy_complete_value_from_script_vm_fn_t copy_complete_value_from_script_vm; - fprop_clear_value_internal_fn_t clear_value_internal; - fprop_destroy_value_internal_fn_t destroy_value_internal; - fprop_initialize_value_internal_fn_t initialize_value_internal; - fprop_get_id_fn_t get_id; - fprop_instance_subobjects_fn_t instance_subobjects; - fprop_get_min_alignment_fn_t get_min_alignment; - fprop_contains_object_reference_fn_t contains_object_reference; - fprop_emit_reference_info_fn_t emit_reference_info; - fprop_same_type_fn_t same_type; -}; -MOD_STATIC_ASSERT(sizeof(fprop_vtable_t) == 0x130, "size mismatch"); - -typedef struct fprop_s fprop_t; -struct fprop_s { - /* ffield_t */ - fprop_vtable_t *vtable; - ffield_class_t *cls; - ffield_variant_t owner; - struct ffield_s *next; - fname_t name; - uint32_t flags; - uint32_t pad; - - /* fprop_t */ - int32_t array_dim; - int32_t elem_size; - eprop_flags_t prop_flags; - uint16_t rep_idx; - uint8_t bp_rep_cond; - int32_t offset_internal; - fname_t rep_notify_func; - struct fprop_s *prop_link_next; - struct fprop_s *next_ref; - struct fprop_s *dtor_link_next; - struct fprop_s *post_ctor_link_next; -}; - -MOD_STATIC_ASSERT(offsetof(fprop_t, array_dim) == 0x38, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fprop_t, elem_size) == 0x3C, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fprop_t, prop_flags) == 0x40, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fprop_t, rep_idx) == 0x48, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fprop_t, offset_internal) == 0x4C, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fprop_t, rep_notify_func) == 0x50, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fprop_t, prop_link_next) == 0x58, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fprop_t, next_ref) == 0x60, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fprop_t, dtor_link_next) == 0x68, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fprop_t, post_ctor_link_next) == 0x70, "invalid offset"); - -/* ByteProperty */ -typedef struct fprop_byte_s fprop_byte_t; -struct fprop_byte_s { - fprop_t base; - struct uenum_s *uenum; -}; - -MOD_STATIC_ASSERT(offsetof(fprop_byte_t, uenum) == 0x78, "invalid offset"); - -/* UInt16Property */ -typedef struct fprop_uint16_s fprop_uint16_t; -struct fprop_uint16_s { - fprop_t base; -}; - -/* UInt32Property */ -typedef struct fprop_uint32_s fprop_uint32_t; -struct fprop_uint32_s { - fprop_t base; -}; - -/* UInt64Property */ -typedef struct fprop_uint64_s fprop_uint64_t; -struct fprop_uint64_s { - fprop_t base; -}; - -/* Int8Property */ -typedef struct fprop_int8_s fprop_int8_t; -struct fprop_int8_s { - fprop_t base; -}; - -/* Int16Property */ -typedef struct fprop_int16_s fprop_int16_t; -struct fprop_int16_s { - fprop_t base; -}; - -/* IntProperty */ -typedef struct fprop_int_s fprop_int_t; -struct fprop_int_s { - fprop_t base; -}; - -/* Int64Property */ -typedef struct fprop_int64_s fprop_int64_t; -struct fprop_int64_s { - fprop_t base; -}; - -/* FloatProperty */ -typedef struct fprop_float_s fprop_float_t; -struct fprop_float_s { - fprop_t base; -}; - -/* DoubleProperty */ -typedef struct fprop_double_s fprop_double_t; -struct fprop_double_s { - fprop_t base; -}; - -/* BoolProperty */ -typedef struct fprop_bool_s fprop_bool_t; -struct fprop_bool_s { - fprop_t base; - uint8_t field_size; - uint8_t byte_offset; - uint8_t byte_mask; - uint8_t field_mask; -}; -MOD_STATIC_ASSERT(offsetof(fprop_bool_t, field_size) == 0x78, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fprop_bool_t, byte_offset) == 0x79, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fprop_bool_t, byte_mask) == 0x7a, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fprop_bool_t, field_mask) == 0x7b, "invalid offset"); - -/* ObjectPropertyBase */ -typedef struct fprop_obj_base_s fprop_obj_base_t; -struct fprop_obj_base_s { - fprop_t base; - struct uclass_s *prop_class; -}; -MOD_STATIC_ASSERT(offsetof(fprop_obj_base_t, prop_class) == 0x78, "invalid offset"); - -/* ObjectProperty */ -typedef struct fprop_obj_s fprop_obj_t; -struct fprop_obj_s { - fprop_obj_base_t base; -}; - -/* WeakObjectProperty */ -typedef struct fprop_obj_weak_s fprop_obj_weak_t; -struct fprop_obj_weak_s { - fprop_obj_base_t base; -}; - -/* LazyObjectProperty */ -typedef struct fprop_obj_lazy_s fprop_obj_lazy_t; -struct fprop_obj_lazy_s { - fprop_obj_base_t base; -}; - -/* SoftObjectProperty */ -typedef struct fprop_obj_soft_s fprop_obj_soft_t; -struct fprop_obj_soft_s { - fprop_obj_base_t base; -}; - -/* ClassProperty */ -typedef struct fprop_class_s fprop_class_t; -struct fprop_class_s { - fprop_obj_t base; - struct uclass_s *meta_class; -}; -MOD_STATIC_ASSERT(offsetof(fprop_class_t, meta_class) == 0x80, "invalid offset"); - -/* SoftClassProperty */ -typedef struct fprop_class_soft_s fprop_class_soft_t; -struct fprop_class_soft_s { - fprop_obj_soft_t base; - struct uclass_s *meta_class; -}; -MOD_STATIC_ASSERT(offsetof(fprop_class_soft_t, meta_class) == 0x80, "invalid offset"); - -/* InterfaceProperty */ -typedef struct fprop_iface_s fprop_iface_t; -struct fprop_iface_s { - fprop_t base; - struct uclass_s *iface_class; -}; -MOD_STATIC_ASSERT(offsetof(fprop_iface_t, iface_class) == 0x78, "invalid offset"); - -/* NameProperty */ -typedef struct fprop_fname_s fprop_fname_t; -struct fprop_fname_s { - fprop_t base; -}; - -/* StrProperty */ -typedef struct fprop_str_s fprop_str_t; -struct fprop_str_s { - fprop_t base; -}; - -typedef uint32_t earray_prop_flags_t; -enum { - EAPF_NONE, - EAPF_USES_MEM_IMAGE_ALLOCATOR, -}; - -/* ArrayProperty */ -typedef struct fprop_array_s fprop_array_t; -struct fprop_array_s { - fprop_t base; - fprop_t *inner; - earray_prop_flags_t array_flags; -}; -MOD_STATIC_ASSERT(offsetof(fprop_array_t, inner) == 0x78, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fprop_array_t, array_flags) == 0x80, "invalid offset"); - -typedef uint32_t emap_prop_flags_t; -enum { - EMPF_NONE, - EMPF_USES_MEM_IMAGE_ALLOCATOR, -}; - -typedef struct fscript_sparse_array_layout_s fscript_sparse_array_layout_t; -struct fscript_sparse_array_layout_s { - int32_t alignment; - int32_t size; -}; - -typedef struct fscript_set_layout_s fscript_set_layout_t; -struct fscript_set_layout_s { - int32_t hash_next_id_offset; - int32_t hash_idx_offset; - int32_t size; - fscript_sparse_array_layout_t sparse_array_layout; -}; - -typedef struct fscript_map_layout_s fscript_map_layout_t; -struct fscript_map_layout_s { - int32_t value_offset; - fscript_set_layout_t set_layout; -}; - -/* MapProperty */ -typedef struct fprop_map_s fprop_map_t; -struct fprop_map_s { - fprop_t base; - fprop_t *key_prop; - fprop_t *val_prop; - fscript_map_layout_t map_layout; - emap_prop_flags_t map_flags; -}; -MOD_STATIC_ASSERT(offsetof(fprop_map_t, key_prop) == 0x78, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fprop_map_t, val_prop) == 0x80, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fprop_map_t, map_layout) == 0x88, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fprop_map_t, map_flags) == 0xa0, "invalid offset"); - -/* SetProperty */ -typedef struct fprop_set_s fprop_set_t; -struct fprop_set_s { - fprop_t base; - fprop_t *elem_prop; - fscript_set_layout_t set_layout; -}; -MOD_STATIC_ASSERT(offsetof(fprop_set_t, elem_prop) == 0x78, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fprop_set_t, set_layout) == 0x80, "invalid offset"); - -/* StructProperty */ -typedef struct fprop_struct_s fprop_struct_t; -struct fprop_struct_s { - fprop_t base; - struct uscript_struct_s *script_struct; -}; -MOD_STATIC_ASSERT(offsetof(fprop_struct_t, script_struct) == 0x78, "invalid offset"); - -/* DelegateProperty */ -typedef struct fprop_delegate_s fprop_delegate_t; -struct fprop_delegate_s { - fprop_t base; - struct ufunc_s *signature_func; -}; -MOD_STATIC_ASSERT(offsetof(fprop_delegate_t, signature_func) == 0x78, "invalid offset"); - -/* MulticastDelegateProperty */ -typedef struct fprop_mcast_delegate_s fprop_mcast_delegate_t; -struct fprop_mcast_delegate_s { - fprop_t base; - struct ufunc_s *signature_func; -}; -MOD_STATIC_ASSERT(offsetof(fprop_mcast_delegate_t, signature_func) == 0x78, "invalid offset"); - -typedef struct fprop_mcastinline_delegate_inline_s fprop_mcastinline_delegate_inline_t; -struct fprop_mcastinline_delegate_inline_s { - fprop_mcast_delegate_t base; -}; - -typedef struct fprop_mcastinline_delegate_sparse_s fprop_mcastinline_delegate_sparse_t; -struct fprop_mcastinline_delegate_sparse_s { - fprop_mcast_delegate_t base; -}; - -/* TextProperty */ -typedef struct fprop_text_s fprop_text_t; -struct fprop_text_s { - fprop_t base; -}; - -/* NumericProperty */ -typedef struct fprop_numeric_s fprop_numeric_t; -struct fprop_numeric_s { - fprop_t base; -}; - -/* EnumProperty */ -typedef struct fprop_enum_s fprop_enum_t; -struct fprop_enum_s { - fprop_t base; - fprop_numeric_t *underlying_prop; - struct uenum_s *uenum; -}; -MOD_STATIC_ASSERT(offsetof(fprop_enum_t, underlying_prop) == 0x78, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fprop_enum_t, uenum) == 0x80, "invalid offset"); - -/* FieldPathProperty */ -typedef struct fprop_field_path_s fprop_field_path_t; -struct fprop_field_path_s { - fprop_t base; - ffield_class_t *prop_class; -}; -MOD_STATIC_ASSERT(offsetof(fprop_field_path_t, prop_class) == 0x78, "invalid offset"); - -typedef TARRAY(TPAIR(fname_t, int64_t)) tarray_tpair_fname_int64_t; - -typedef struct uenum_s uenum_t; -struct uenum_s { - ufield_t base; - fstring_t cpp_type; - tarray_tpair_fname_int64_t names; - uint32_t cpp_form; - uint32_t enum_flags; - void *enum_display_name_fn; -}; - -MOD_STATIC_ASSERT(offsetof(uenum_t, cpp_type) == 0x30, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uenum_t, names) == 0x40, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uenum_t, cpp_form) == 0x50, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uenum_t, enum_flags) == 0x54, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uenum_t, enum_display_name_fn) == 0x58, "invalid offset"); - -typedef TARRAY(uint8_t) ustruct_script_t; - -typedef struct fstruct_base_chain_s fstruct_base_chain_t; -struct fstruct_base_chain_s { - struct fstruct_base_chain_s **struct_base_chain_array; - int32_t num_struct_bases_in_chain_minus_one; -}; - -typedef struct ustruct_s *(__fastcall *ustruct_get_inheritance_super_fn_t) (struct ustruct_s *); -typedef void (__fastcall *ustruct_link_fn_t) (struct ustruct_s *, void *, bool); -typedef void (__fastcall *ustruct_serialize_bin_fn_t) (struct ustruct_s *, void *, void *); -typedef void (__fastcall *ustruct_serialize_bin2_fn_t) (struct ustruct_s *, fstructured_archive_slot_t, void *); -typedef void (__fastcall *ustruct_serialize_tagged_props_fn_t) (struct ustruct_s *, void *, uint8_t *, struct ustruct_s *, uint8_t *, const struct uobject_s *); -typedef void (__fastcall *ustruct_serialize_tagged_props2_fn_t) (struct ustruct_s *, fstructured_archive_slot_t, uint8_t *, struct ustruct_s *, uint8_t *, const struct uobject_s *); -typedef void (__fastcall *ustruct_init_struct_fn_t) (struct ustruct_s *, void *, int32_t); -typedef void (__fastcall *ustruct_destroy_struct_fn_t) (struct ustruct_s *, void *, int32_t); -typedef struct fprop_s *(__fastcall *ustruct_custom_find_prop_fn_t) (struct ustruct_s *, const fname_t); -typedef expr_token_t (__fastcall *ustruct_serialize_expr_fn_t) (struct ustruct_s *, int32_t *, void *); -typedef const wchar_t *(__fastcall *ustruct_get_prefix_cpp_fn_t) (struct ustruct_s *); -typedef void (__fastcall *ustruct_set_super_struct_fn_t) (struct ustruct_s *, struct ustruct_s *); -typedef fstring_t (__fastcall *ustruct_prop_name_to_display_name_fn_t) (struct ustruct_s *, fname_t); -typedef fstring_t (__fastcall *ustruct_get_authored_name_for_field_fn_t) (struct ustruct_s *, const struct ufield_s *); -typedef fstring_t (__fastcall *ustruct_get_authored_name_for_field2_fn_t) (struct ustruct_s *, const struct ffield_s *); -typedef bool (__fastcall *ustruct_is_struct_trashed_fn_t) (struct ustruct_s *); -typedef fname_t (__fastcall *ustruct_find_prop_name_from_guid_fn_t) (struct ustruct_s *, const fguid_t *); -typedef fguid_t (__fastcall *ustruct_find_prop_guid_from_name_fn_t) (struct ustruct_s *, const fname_t); -typedef bool (__fastcall *ustruct_are_prop_guids_available_fn_t) (struct ustruct_s *); - -typedef struct ustruct_vtable_s ustruct_vtable_t; -struct ustruct_vtable_s { - uobject_destructor_fn_t destructor; - uobject_register_deps_fn_t register_deps; - uobject_deferred_register_fn_t deferred_register; - uobject_can_be_cluster_root_fn_t can_be_cluster_root; - uobject_can_be_in_cluster_fn_t can_be_in_cluster; - uobject_create_cluster_fn_t create_cluster; - uobject_on_cluster_marked_as_pending_kill_fn_t on_cluster_marked_as_pending_kill; - uobject_get_detailed_info_internal_fn_t get_detailed_info_internal; - uobject_post_init_props_fn_t post_init_props; - uobject_post_cdo_contruct_fn_t post_cdo_contruct; - uobject_pre_save_root_fn_t pre_save_root; - uobject_post_save_root_fn_t post_save_root; - uobject_pre_save_fn_t pre_save; - uobject_is_ready_for_async_post_load_fn_t is_ready_for_async_post_load; - uobject_post_load_fn_t post_load; - uobject_post_load_subobjects_fn_t post_load_subobjects; - uobject_begin_destroy_fn_t begin_destroy; - uobject_is_ready_for_finish_destroy_fn_t is_ready_for_finish_destroy; - uobject_finish_destroy_fn_t finish_destroy; - uobject_serialize_fn_t serialize; - uobject_serialize_farchive_fn_t serialize_farchive; - uobject_shutdown_after_error_fn_t shutdown_after_error; - uobject_post_interp_change_fn_t post_interp_change; - uobject_post_rename_fn_t post_rename; - uobject_pre_duplicate_fn_t pre_duplicate; - uobject_post_duplicate_from_type_fn_t post_duplicate_from_type; - uobject_post_duplicate_fn_t post_duplicate; - uobject_needs_load_for_client_fn_t needs_load_for_client; - uobject_needs_load_for_server_fn_t needs_load_for_server; - uobject_needs_load_for_target_platform_fn_t needs_load_for_target_platform; - uobject_needs_load_for_editor_game_fn_t needs_load_for_editor_game; - uobject_is_editor_only_fn_t is_editor_only; - uobject_has_non_editor_only_references_fn_t has_non_editor_only_references; - uobject_is_post_load_thread_safe_fn_t is_post_load_thread_safe; - uobject_is_destruction_thread_safe_fn_t is_destruction_thread_safe; - uobject_get_preload_deps_fn_t get_preload_deps; - uobject_get_prestream_packages_fn_t get_prestream_packages; - uobject_export_custom_props_fn_t export_custom_props; - uobject_import_custom_props_fn_t import_custom_props; - uobject_post_edit_import_fn_t post_edit_import; - uobject_post_reload_config_fn_t post_reload_config; - uobject_rename_fn_t rename; - uobject_get_desc_fn_t get_desc; - uobject_get_sparse_class_data_struct_fn_t get_sparse_class_data_struct; - uobject_get_world_fn_t get_world; - uobject_get_native_prop_vals_fn_t get_native_prop_vals; - uobject_get_resource_size_ex_fn_t get_resource_size_ex; - uobject_get_exporter_name_fn_t get_exporter_name; - uobject_get_restore_for_uobject_overwrite_fn_t get_restore_for_uobject_overwrite; - uobject_are_native_props_identical_to_fn_t are_native_props_identical_to; - uobject_get_asset_registry_tags_fn_t get_asset_registry_tags; - uobject_is_asset_fn_t is_asset; - uobject_get_primary_asset_id_fn_t get_primary_asset_id; - uobject_is_localized_resource_fn_t is_localized_resource; - uobject_is_safe_for_root_set_fn_t is_safe_for_root_set; - uobject_tag_subobjects_fn_t tag_subobjects; - uobject_get_lifetime_replicated_props_fn_t get_lifetime_replicated_props; - uobject_is_name_stable_for_networking_fn_t is_name_stable_for_networking; - uobject_is_full_name_stable_for_networking_fn_t is_full_name_stable_for_networking; - uobject_is_supported_for_networking_fn_t is_supported_for_networking; - uobject_get_subobjects_with_stable_names_for_networking_fn_t get_subobjects_with_stable_names_for_networking; - uobject_pre_net_receive_fn_t pre_net_receive; - uobject_post_net_receive_fn_t post_net_receive; - uobject_post_rep_notifies_fn_t post_rep_notifies; - uobject_pre_destroy_from_replication_fn_t pre_destroy_from_replication; - uobject_build_subobject_mapping_fn_t build_subobject_mapping; - uobject_get_config_override_platform_fn_t get_config_override_platform; - uobject_override_per_object_config_section_fn_t override_per_object_config_section; - uobject_process_event_fn_t process_event; - uobject_get_function_callspace_fn_t get_function_callspace; - uobject_call_remote_function_fn_t call_remote_function; - uobject_process_console_exec_fn_t process_console_exec; - uobject_regenerate_class_fn_t regenerate_class; - uobject_mark_as_editor_only_subobject_fn_t mark_as_editor_only_subobject; - uobject_check_default_subobjects_internal_fn_t check_default_subobjects_internal; - uobject_validate_generated_rep_enums_fn_t validate_generated_rep_enums; - uobject_set_net_push_id_dynamic_fn_t set_net_push_id_dynamic; - uobject_get_net_push_id_dynamic_fn_t get_net_push_id_dynamic; - - ufield_add_cpp_prop_fn_t add_cpp_prop; - ufield_bind_fn_t bind; - - ustruct_get_inheritance_super_fn_t get_inheritance_super; - ustruct_link_fn_t link; - ustruct_serialize_bin_fn_t serialize_bin; - ustruct_serialize_bin2_fn_t serialize_bin2; - ustruct_serialize_tagged_props_fn_t serialize_tagged_props; - ustruct_serialize_tagged_props2_fn_t serialize_tagged_props2; - ustruct_init_struct_fn_t init_struct; - ustruct_destroy_struct_fn_t destroy_struct; - ustruct_custom_find_prop_fn_t custom_find_prop; - ustruct_serialize_expr_fn_t serialize_expr; - ustruct_get_prefix_cpp_fn_t get_prefix_cpp; - ustruct_set_super_struct_fn_t set_super_struct; - ustruct_prop_name_to_display_name_fn_t prop_name_to_display_name; - ustruct_get_authored_name_for_field_fn_t get_authored_name_for_field; - ustruct_get_authored_name_for_field2_fn_t get_authored_name_for_field2; - ustruct_is_struct_trashed_fn_t is_struct_trashed; - ustruct_find_prop_name_from_guid_fn_t find_prop_name_from_guid; - ustruct_find_prop_guid_from_name_fn_t find_prop_guid_from_name; - ustruct_are_prop_guids_available_fn_t are_prop_guids_available; -}; -MOD_STATIC_ASSERT(sizeof(ustruct_vtable_t) == 0x318, "size mismatch"); - -// ustruct_t->children (UObject/UField chain): use for UFunction discovery -// ustruct_t->child_props (FField/FProperty chain): use for fields and params -typedef struct ustruct_s ustruct_t; -struct ustruct_s { - /* uobject_t */ - ustruct_vtable_t *vtable; - eobj_flags_t obj_flags; - int32_t internal_idx; - struct uclass_s *cls; - fname_t name; - struct uobject_s *outer; - /* ufield_t */ - struct ufield_s *next; - /* ustruct_t */ - fstruct_base_chain_t chain; - struct ustruct_s *super_struct; - ufield_t *children; - struct ffield_s *child_props; - int32_t props_size; - int32_t min_alignment; - ustruct_script_t script; - struct fprop_s *prop_link; - struct fprop_s *ref_link; - struct fprop_s *dtor_link; - struct fprop_s *post_ctor_link; - tarray_uobjectptr_t script_and_prop_obj_refs; - void *unresolved_script_props; - void *unversioned_schema; -}; - -MOD_STATIC_ASSERT(offsetof(ustruct_t, super_struct) == 0x40, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ustruct_t, children) == 0x48, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ustruct_t, child_props) == 0x50, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ustruct_t, props_size) == 0x58, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ustruct_t, min_alignment) == 0x5C, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ustruct_t, script) == 0x60, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ustruct_t, prop_link) == 0x70, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ustruct_t, ref_link) == 0x78, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ustruct_t, dtor_link) == 0x80, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ustruct_t, post_ctor_link) == 0x88, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ustruct_t, script_and_prop_obj_refs) == 0x90, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ustruct_t, unresolved_script_props) == 0xA0, "invalid offset"); -MOD_STATIC_ASSERT(sizeof(ustruct_t) == 0xB0, "size mismatch"); - -typedef struct icpp_struct_ops_s icpp_struct_ops_t; -struct icpp_struct_ops_s { - void *vftable; - int32_t size; - int32_t alignment; -}; -MOD_STATIC_ASSERT(offsetof(icpp_struct_ops_t, size) == 0x08, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(icpp_struct_ops_t, alignment) == 0x0c, "invalid offset"); - -typedef struct uscript_struct_s uscript_struct_t; -struct uscript_struct_s { - /* uobject_t */ - ustruct_vtable_t *vtable; - eobj_flags_t obj_flags; - int32_t internal_idx; - struct uclass_s *cls; - fname_t name; - struct uobject_s *outer; - /* ufield_t */ - struct ufield_s *next; - /* ustruct_t */ - fstruct_base_chain_t chain; - struct ustruct_s *super_struct; - ufield_t *children; - struct ffield_s *child_props; - int32_t props_size; - int32_t min_alignment; - ustruct_script_t script; - struct fprop_s *prop_link; - struct fprop_s *ref_link; - struct fprop_s *dtor_link; - struct fprop_s *post_ctor_link; - tarray_uobjectptr_t script_and_prop_obj_refs; - void *unresolved_script_props; - void *unversioned_schema; - /* uscript_struct_t */ - estruct_flags_t struct_flags; - bool prep_cpp_struct_ops_completed; - icpp_struct_ops_t *cpp_struct_ops; -}; -MOD_STATIC_ASSERT(offsetof(uscript_struct_t, struct_flags) == 0xb0, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uscript_struct_t, prep_cpp_struct_ops_completed) == 0xb4, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uscript_struct_t, cpp_struct_ops) == 0xb8, "invalid offset"); - -typedef struct ufunc_s ufunc_t; -struct ufunc_s { - /* uobject_t */ - ustruct_vtable_t *vtable; - eobj_flags_t obj_flags; - int32_t internal_idx; - struct uclass_s *cls; - fname_t name; - struct uobject_s *outer; - /* ufield_t */ - struct ufield_s *next; - /* ustruct_t */ - fstruct_base_chain_t chain; - struct ustruct_s *super_struct; - ufield_t *children; - struct ffield_s *child_props; - int32_t props_size; - int32_t min_alignment; - ustruct_script_t script; - struct fprop_s *prop_link; - struct fprop_s *ref_link; - struct fprop_s *dtor_link; - struct fprop_s *post_ctor_link; - tarray_uobjectptr_t script_and_prop_obj_refs; - void *unresolved_script_props; - void *unversioned_schema; - /* ufunc_t */ - uint32_t func_flags; - uint8_t num_params; - uint16_t params_size; - uint16_t return_val_offset; - uint16_t rpc_id; - uint16_t rpc_rsp_id; - struct fprop_s *first_prop_to_init; - void *event_graph_func; - void *event_graph_call_offset; - void *func; -}; -MOD_STATIC_ASSERT(offsetof(ufunc_t, func_flags) == 0xB0, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ufunc_t, num_params) == 0xB4, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ufunc_t, params_size) == 0xB6, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ufunc_t, return_val_offset) == 0xB8, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ufunc_t, rpc_id) == 0xBA, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ufunc_t, rpc_rsp_id) == 0xBC, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ufunc_t, first_prop_to_init) == 0xC0, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ufunc_t, event_graph_func) == 0xC8, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ufunc_t, event_graph_call_offset) == 0xD0, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(ufunc_t, func) == 0xD8, "invalid offset"); -MOD_STATIC_ASSERT(sizeof(ufunc_t) == 0xE0, "size mismatch"); - -typedef struct foverride_s { - fname_t component_name; - struct uclass_s *component_class; -} foverride_t; - -typedef struct fsubobject_init_s { - struct uobject_s *subobject; - struct uobject_s *templ; -} fsubobject_init_t; - -typedef TARRAY_INLINE(foverride_t, 8) foverrides_t; -typedef TARRAY_INLINE(fsubobject_init_t, 8) fsubobjects_to_init_t; - -typedef struct fobject_initializer_s { - struct uobject_s *obj; - struct uobject_s *object_archetype; - bool copy_transients_from_class_defaults; - bool should_init_props_from_archetype; - bool subobject_class_init_allowed; - void *instance_graph; - foverrides_t component_overrides; - fsubobjects_to_init_t component_inits; - struct uobject_s *last_constructed_object; -} fobject_initializer_t; - -MOD_STATIC_ASSERT(offsetof(fobject_initializer_t, object_archetype) == 0x008, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fobject_initializer_t, copy_transients_from_class_defaults) == 0x010, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fobject_initializer_t, should_init_props_from_archetype) == 0x011, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fobject_initializer_t, subobject_class_init_allowed) == 0x012, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fobject_initializer_t, instance_graph) == 0x018, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fobject_initializer_t, component_overrides) == 0x020, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fobject_initializer_t, component_inits) == 0x0B0, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fobject_initializer_t, last_constructed_object) == 0x140, "invalid offset"); -MOD_STATIC_ASSERT(sizeof(fobject_initializer_t) == 0x148, "size mismatch"); - -typedef struct uclass_s *(__fastcall *uclass_get_authoritative_class_fn_t) (struct uclass_s *); -typedef void (__fastcall *uclass_post_init_instance_fn_t) (struct uclass_s *, struct uobject_s *); -typedef void (__fastcall *uclass_init_props_from_custom_list_fn_t) (struct uclass_s *, uint8_t *, const uint8_t *); -typedef void (__fastcall *uclass_setup_object_initializer_fn_t) (struct uclass_s *, fobject_initializer_t *); -typedef uint8_t *(__fastcall *uclass_get_persistent_uber_graph_frame_fn_t) (struct uclass_s *, struct uobject_s *, struct ufunc_s *); -typedef void (__fastcall *uclass_create_persistent_uber_graph_frame_fn_t) (struct uclass_s *, struct uobject_s *, bool, bool, struct uclass_s *); -typedef void (__fastcall *uclass_destroy_persistent_uber_graph_frame_fn_t) (struct uclass_s *, struct uobject_s *, bool); -typedef void (__fastcall *uclass_serialize_default_object_fn_t) (struct uclass_s *, struct uobject_s *, void *); -typedef void (__fastcall *uclass_serialize_default_object2_fn_t) (struct uclass_s *, struct uobject_s *, fstructured_archive_slot_t); -typedef void (__fastcall *uclass_post_load_default_object_fn_t) (struct uclass_s *, struct uobject_s *); -typedef void (__fastcall *uclass_purge_class_fn_t) (struct uclass_s *, bool); -typedef bool (__fastcall *uclass_is_function_implemented_in_script_fn_t) (struct uclass_s *, fname_t); -typedef bool (__fastcall *uclass_has_prop_fn_t) (struct uclass_s *, struct fprop_s *); -typedef struct uobject_s *(__fastcall *uclass_find_archetype_fn_t) (struct uclass_s *, const struct uclass_s *, const fname_t); -typedef struct uobject_s *(__fastcall *uclass_get_archetype_for_cdo_fn_t) (struct uclass_s *); -typedef void *(__fastcall *uclass_get_archetype_for_sparse_class_data_fn_t) (struct uclass_s *); -typedef void (__fastcall *uclass_get_default_object_preload_deps_fn_t) (struct uclass_s *, tarray_uobjectptr_t *); -typedef struct uobject_s *(__fastcall *uclass_create_default_object_fn_t) (struct uclass_s *); - -typedef struct uclass_vtable_s uclass_vtable_t; -struct uclass_vtable_s { - uobject_destructor_fn_t destructor; - uobject_register_deps_fn_t register_deps; - uobject_deferred_register_fn_t deferred_register; - uobject_can_be_cluster_root_fn_t can_be_cluster_root; - uobject_can_be_in_cluster_fn_t can_be_in_cluster; - uobject_create_cluster_fn_t create_cluster; - uobject_on_cluster_marked_as_pending_kill_fn_t on_cluster_marked_as_pending_kill; - uobject_get_detailed_info_internal_fn_t get_detailed_info_internal; - uobject_post_init_props_fn_t post_init_props; - uobject_post_cdo_contruct_fn_t post_cdo_contruct; - uobject_pre_save_root_fn_t pre_save_root; - uobject_post_save_root_fn_t post_save_root; - uobject_pre_save_fn_t pre_save; - uobject_is_ready_for_async_post_load_fn_t is_ready_for_async_post_load; - uobject_post_load_fn_t post_load; - uobject_post_load_subobjects_fn_t post_load_subobjects; - uobject_begin_destroy_fn_t begin_destroy; - uobject_is_ready_for_finish_destroy_fn_t is_ready_for_finish_destroy; - uobject_finish_destroy_fn_t finish_destroy; - uobject_serialize_fn_t serialize; - uobject_serialize_farchive_fn_t serialize_farchive; - uobject_shutdown_after_error_fn_t shutdown_after_error; - uobject_post_interp_change_fn_t post_interp_change; - uobject_post_rename_fn_t post_rename; - uobject_pre_duplicate_fn_t pre_duplicate; - uobject_post_duplicate_from_type_fn_t post_duplicate_from_type; - uobject_post_duplicate_fn_t post_duplicate; - uobject_needs_load_for_client_fn_t needs_load_for_client; - uobject_needs_load_for_server_fn_t needs_load_for_server; - uobject_needs_load_for_target_platform_fn_t needs_load_for_target_platform; - uobject_needs_load_for_editor_game_fn_t needs_load_for_editor_game; - uobject_is_editor_only_fn_t is_editor_only; - uobject_has_non_editor_only_references_fn_t has_non_editor_only_references; - uobject_is_post_load_thread_safe_fn_t is_post_load_thread_safe; - uobject_is_destruction_thread_safe_fn_t is_destruction_thread_safe; - uobject_get_preload_deps_fn_t get_preload_deps; - uobject_get_prestream_packages_fn_t get_prestream_packages; - uobject_export_custom_props_fn_t export_custom_props; - uobject_import_custom_props_fn_t import_custom_props; - uobject_post_edit_import_fn_t post_edit_import; - uobject_post_reload_config_fn_t post_reload_config; - uobject_rename_fn_t rename; - uobject_get_desc_fn_t get_desc; - uobject_get_sparse_class_data_struct_fn_t get_sparse_class_data_struct; - uobject_get_world_fn_t get_world; - uobject_get_native_prop_vals_fn_t get_native_prop_vals; - uobject_get_resource_size_ex_fn_t get_resource_size_ex; - uobject_get_exporter_name_fn_t get_exporter_name; - uobject_get_restore_for_uobject_overwrite_fn_t get_restore_for_uobject_overwrite; - uobject_are_native_props_identical_to_fn_t are_native_props_identical_to; - uobject_get_asset_registry_tags_fn_t get_asset_registry_tags; - uobject_is_asset_fn_t is_asset; - uobject_get_primary_asset_id_fn_t get_primary_asset_id; - uobject_is_localized_resource_fn_t is_localized_resource; - uobject_is_safe_for_root_set_fn_t is_safe_for_root_set; - uobject_tag_subobjects_fn_t tag_subobjects; - uobject_get_lifetime_replicated_props_fn_t get_lifetime_replicated_props; - uobject_is_name_stable_for_networking_fn_t is_name_stable_for_networking; - uobject_is_full_name_stable_for_networking_fn_t is_full_name_stable_for_networking; - uobject_is_supported_for_networking_fn_t is_supported_for_networking; - uobject_get_subobjects_with_stable_names_for_networking_fn_t get_subobjects_with_stable_names_for_networking; - uobject_pre_net_receive_fn_t pre_net_receive; - uobject_post_net_receive_fn_t post_net_receive; - uobject_post_rep_notifies_fn_t post_rep_notifies; - uobject_pre_destroy_from_replication_fn_t pre_destroy_from_replication; - uobject_build_subobject_mapping_fn_t build_subobject_mapping; - uobject_get_config_override_platform_fn_t get_config_override_platform; - uobject_override_per_object_config_section_fn_t override_per_object_config_section; - uobject_process_event_fn_t process_event; - uobject_get_function_callspace_fn_t get_function_callspace; - uobject_call_remote_function_fn_t call_remote_function; - uobject_process_console_exec_fn_t process_console_exec; - uobject_regenerate_class_fn_t regenerate_class; - uobject_mark_as_editor_only_subobject_fn_t mark_as_editor_only_subobject; - uobject_check_default_subobjects_internal_fn_t check_default_subobjects_internal; - uobject_validate_generated_rep_enums_fn_t validate_generated_rep_enums; - uobject_set_net_push_id_dynamic_fn_t set_net_push_id_dynamic; - uobject_get_net_push_id_dynamic_fn_t get_net_push_id_dynamic; - - ufield_add_cpp_prop_fn_t add_cpp_prop; - ufield_bind_fn_t bind; - - ustruct_get_inheritance_super_fn_t get_inheritance_super; - ustruct_link_fn_t link; - ustruct_serialize_bin_fn_t serialize_bin; - ustruct_serialize_bin2_fn_t serialize_bin2; - ustruct_serialize_tagged_props_fn_t serialize_tagged_props; - ustruct_serialize_tagged_props2_fn_t serialize_tagged_props2; - ustruct_init_struct_fn_t init_struct; - ustruct_destroy_struct_fn_t destroy_struct; - ustruct_custom_find_prop_fn_t custom_find_prop; - ustruct_serialize_expr_fn_t serialize_expr; - ustruct_get_prefix_cpp_fn_t get_prefix_cpp; - ustruct_set_super_struct_fn_t set_super_struct; - ustruct_prop_name_to_display_name_fn_t prop_name_to_display_name; - ustruct_get_authored_name_for_field_fn_t get_authored_name_for_field; - ustruct_get_authored_name_for_field2_fn_t get_authored_name_for_field2; - ustruct_is_struct_trashed_fn_t is_struct_trashed; - ustruct_find_prop_name_from_guid_fn_t find_prop_name_from_guid; - ustruct_find_prop_guid_from_name_fn_t find_prop_guid_from_name; - ustruct_are_prop_guids_available_fn_t are_prop_guids_available; - - uclass_get_authoritative_class_fn_t get_authoritative_class; - uclass_post_init_instance_fn_t post_init_instance; - uclass_init_props_from_custom_list_fn_t init_props_from_custom_list; - uclass_setup_object_initializer_fn_t setup_object_initializer; - uclass_get_persistent_uber_graph_frame_fn_t get_persistent_uber_graph_frame; - uclass_create_persistent_uber_graph_frame_fn_t create_persistent_uber_graph_frame; - uclass_destroy_persistent_uber_graph_frame_fn_t destroy_persistent_uber_graph_frame; - uclass_serialize_default_object_fn_t serialize_default_object; - uclass_serialize_default_object2_fn_t serialize_default_object2; - uclass_post_load_default_object_fn_t post_load_default_object; - uclass_purge_class_fn_t purge_class; - uclass_is_function_implemented_in_script_fn_t is_function_implemented_in_script; - uclass_has_prop_fn_t has_prop; - uclass_find_archetype_fn_t find_archetype; - uclass_get_archetype_for_cdo_fn_t get_archetype_for_cdo; - uclass_get_archetype_for_sparse_class_data_fn_t get_archetype_for_sparse_class_data; - uclass_get_default_object_preload_deps_fn_t get_default_object_preload_deps; - uclass_create_default_object_fn_t create_default_object; -}; -MOD_STATIC_ASSERT(sizeof(uclass_vtable_t) == 0x3A8, "size mismatch"); - -typedef void (*uclass_ctor_fn_t)(const fobject_initializer_t *); -typedef struct uobject_s *(*uclass_class_vtable_helper_ctor_caller_fn_t)(void *); -typedef void (*uclass_class_add_referenced_objects_fn_t)(struct uobject_s *, void *); -typedef void (*fnative_func_ptr_fn_t)(struct uobject_s *ctx, struct fframe_s *stack, void *const z_param_result); - -typedef struct fnative_func_lookup_s fnative_func_lookup_t; -struct fnative_func_lookup_s { - fname_t name; - fnative_func_ptr_fn_t pointer; -}; - -typedef struct fgc_ref_token_stream_s fgc_ref_token_stream_t; -struct fgc_ref_token_stream_s { - TARRAY(uint32_t) tokens; -}; - -typedef TARRAY(struct ufield_s *) tarray_ufieldptr_t; -typedef TARRAY(fnative_func_lookup_t) tarray_fnative_func_lookup_t; -typedef TMAP(fname_t, struct ufunc_s *) tmap_fname_ufuncptr_t; - -typedef struct uclass_s uclass_t; -struct uclass_s { - /* uobject_t */ - uclass_vtable_t *vtable; - eobj_flags_t obj_flags; - int32_t internal_idx; - struct uclass_s *cls; - fname_t name; - struct uobject_s *outer; - /* ufield_t */ - struct ufield_s *next; - /* ustruct_t */ - fstruct_base_chain_t chain; - struct ustruct_s *super_struct; - ufield_t *children; - struct ffield_s *child_props; - int32_t props_size; - int32_t min_alignment; - ustruct_script_t script; - struct fprop_s *prop_link; - struct fprop_s *ref_link; - struct fprop_s *dtor_link; - struct fprop_s *post_ctor_link; - tarray_uobjectptr_t script_and_prop_obj_refs; - void *unresolved_script_props; - void *unversioned_schema; - /* uclass_t */ - uclass_ctor_fn_t class_ctor; - uclass_class_vtable_helper_ctor_caller_fn_t class_vtable_helper_ctor_caller; - uclass_class_add_referenced_objects_fn_t class_add_referenced_objects; - uint32_t class_unique_and_cooked; - uint32_t class_flags; - uint64_t class_cast_flags; - struct uclass_s *class_within; - uobject_t *class_generated_by; - fname_t class_config_name; - tarray_void_t class_reps; - tarray_ufieldptr_t net_fields; - int32_t first_owned_class_rep; - uobject_t *cdo; - void *sparse_class_data; - struct uscript_struct_s *sparse_class_data_struct; - tmap_fname_ufuncptr_t func_map; - tmap_fname_ufuncptr_t super_func_map; - frwlock_t super_func_map_lock; - tarray_void_t interfaces; - fgc_ref_token_stream_t ref_token_stream; - fcritical_section_t ref_token_stream_critical; - tarray_fnative_func_lookup_t native_func_lookup_table; -}; - -MOD_STATIC_ASSERT(offsetof(uclass_t, class_ctor) == 0x0B0, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uclass_t, class_vtable_helper_ctor_caller) == 0x0B8, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uclass_t, class_add_referenced_objects) == 0x0C0, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uclass_t, class_unique_and_cooked) == 0x0C8, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uclass_t, class_flags) == 0x0CC, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uclass_t, class_cast_flags) == 0x0D0, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uclass_t, class_within) == 0x0D8, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uclass_t, class_generated_by) == 0x0E0, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uclass_t, class_config_name) == 0x0E8, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uclass_t, class_reps) == 0x0F0, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uclass_t, net_fields) == 0x100, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uclass_t, first_owned_class_rep) == 0x110, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uclass_t, cdo) == 0x118, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uclass_t, sparse_class_data) == 0x120, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uclass_t, sparse_class_data_struct) == 0x128, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uclass_t, func_map) == 0x130, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uclass_t, super_func_map) == 0x180, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uclass_t, super_func_map_lock) == 0x1D0, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uclass_t, interfaces) == 0x1D8, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uclass_t, ref_token_stream) == 0x1E8, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uclass_t, ref_token_stream_critical) == 0x1F8, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(uclass_t, native_func_lookup_table) == 0x220, "invalid offset"); -MOD_STATIC_ASSERT(sizeof(uclass_t) == 0x230, "size mismatch"); - -struct udata_table_s; -struct ftable_row_base_s; - -typedef TMAP(fname_t, uint8_t *) tmap_fname_uint8ptr_t; -typedef TARRAY(fstring_t) tarray_fstring_t; - -TMAP_DECLARE_FUNCS(unreal_tmap_fname_uint8ptr, tmap_fname_uint8ptr_t, fname_t, uint8_t *) - -typedef void (__fastcall *ftable_row_base_destructor_fn_t) (struct ftable_row_base_s *); -typedef void (__fastcall *ftable_row_base_on_post_data_import_fn_t) (struct ftable_row_base_s *, struct udata_table_s *, fname_t, tarray_fstring_t *); -typedef void (__fastcall *ftable_row_base_on_data_table_changed_fn_t)(struct ftable_row_base_s *, struct udata_table_s *, fname_t); - -typedef struct ftable_row_vtable_s ftable_row_vtable_t; -struct ftable_row_vtable_s { - ftable_row_base_destructor_fn_t destructor; - ftable_row_base_on_post_data_import_fn_t on_post_data_import; - ftable_row_base_on_data_table_changed_fn_t on_data_table_changed; -}; -MOD_STATIC_ASSERT(sizeof(ftable_row_vtable_t) == 0x18, "size mismatch"); - -typedef struct ftable_row_base_s ftable_row_base_t; -struct ftable_row_base_s { - ftable_row_vtable_t *vtable; -}; - -typedef tmap_fname_uint8ptr_t *(__fastcall *udata_table_get_non_const_row_map_fn_t) (struct udata_table_s *); -typedef void (__fastcall *udata_table_add_row_internal_fn_t) (struct udata_table_s *, fname_t, uint8_t *); -typedef const tmap_fname_uint8ptr_t *(__fastcall *udata_table_get_row_map_const_fn_t) (struct udata_table_s *); -typedef const tmap_fname_uint8ptr_t *(__fastcall *udata_table_get_row_map_fn_t) (struct udata_table_s *); -typedef bool (__fastcall *udata_table_allow_duplicate_rows_on_import_fn_t) (struct udata_table_s *); -typedef void (__fastcall *udata_table_empty_table_fn_t) (struct udata_table_s *); -typedef void (__fastcall *udata_table_remove_row_fn_t) (struct udata_table_s *, fname_t); -typedef void (__fastcall *udata_table_add_row_fn_t) (struct udata_table_s *, fname_t, const ftable_row_base_t *); - -typedef struct udata_table_vtable_s udata_table_vtable_t; -struct udata_table_vtable_s { - uobject_destructor_fn_t destructor; - uobject_register_deps_fn_t register_deps; - uobject_deferred_register_fn_t deferred_register; - uobject_can_be_cluster_root_fn_t can_be_cluster_root; - uobject_can_be_in_cluster_fn_t can_be_in_cluster; - uobject_create_cluster_fn_t create_cluster; - uobject_on_cluster_marked_as_pending_kill_fn_t on_cluster_marked_as_pending_kill; - uobject_get_detailed_info_internal_fn_t get_detailed_info_internal; - uobject_post_init_props_fn_t post_init_props; - uobject_post_cdo_contruct_fn_t post_cdo_contruct; - uobject_pre_save_root_fn_t pre_save_root; - uobject_post_save_root_fn_t post_save_root; - uobject_pre_save_fn_t pre_save; - uobject_is_ready_for_async_post_load_fn_t is_ready_for_async_post_load; - uobject_post_load_fn_t post_load; - uobject_post_load_subobjects_fn_t post_load_subobjects; - uobject_begin_destroy_fn_t begin_destroy; - uobject_is_ready_for_finish_destroy_fn_t is_ready_for_finish_destroy; - uobject_finish_destroy_fn_t finish_destroy; - uobject_serialize_fn_t serialize; - uobject_serialize_farchive_fn_t serialize_farchive; - uobject_shutdown_after_error_fn_t shutdown_after_error; - uobject_post_interp_change_fn_t post_interp_change; - uobject_post_rename_fn_t post_rename; - uobject_pre_duplicate_fn_t pre_duplicate; - uobject_post_duplicate_from_type_fn_t post_duplicate_from_type; - uobject_post_duplicate_fn_t post_duplicate; - uobject_needs_load_for_client_fn_t needs_load_for_client; - uobject_needs_load_for_server_fn_t needs_load_for_server; - uobject_needs_load_for_target_platform_fn_t needs_load_for_target_platform; - uobject_needs_load_for_editor_game_fn_t needs_load_for_editor_game; - uobject_is_editor_only_fn_t is_editor_only; - uobject_has_non_editor_only_references_fn_t has_non_editor_only_references; - uobject_is_post_load_thread_safe_fn_t is_post_load_thread_safe; - uobject_is_destruction_thread_safe_fn_t is_destruction_thread_safe; - uobject_get_preload_deps_fn_t get_preload_deps; - uobject_get_prestream_packages_fn_t get_prestream_packages; - uobject_export_custom_props_fn_t export_custom_props; - uobject_import_custom_props_fn_t import_custom_props; - uobject_post_edit_import_fn_t post_edit_import; - uobject_post_reload_config_fn_t post_reload_config; - uobject_rename_fn_t rename; - uobject_get_desc_fn_t get_desc; - uobject_get_sparse_class_data_struct_fn_t get_sparse_class_data_struct; - uobject_get_world_fn_t get_world; - uobject_get_native_prop_vals_fn_t get_native_prop_vals; - uobject_get_resource_size_ex_fn_t get_resource_size_ex; - uobject_get_exporter_name_fn_t get_exporter_name; - uobject_get_restore_for_uobject_overwrite_fn_t get_restore_for_uobject_overwrite; - uobject_are_native_props_identical_to_fn_t are_native_props_identical_to; - uobject_get_asset_registry_tags_fn_t get_asset_registry_tags; - uobject_is_asset_fn_t is_asset; - uobject_get_primary_asset_id_fn_t get_primary_asset_id; - uobject_is_localized_resource_fn_t is_localized_resource; - uobject_is_safe_for_root_set_fn_t is_safe_for_root_set; - uobject_tag_subobjects_fn_t tag_subobjects; - uobject_get_lifetime_replicated_props_fn_t get_lifetime_replicated_props; - uobject_is_name_stable_for_networking_fn_t is_name_stable_for_networking; - uobject_is_full_name_stable_for_networking_fn_t is_full_name_stable_for_networking; - uobject_is_supported_for_networking_fn_t is_supported_for_networking; - uobject_get_subobjects_with_stable_names_for_networking_fn_t get_subobjects_with_stable_names_for_networking; - uobject_pre_net_receive_fn_t pre_net_receive; - uobject_post_net_receive_fn_t post_net_receive; - uobject_post_rep_notifies_fn_t post_rep_notifies; - uobject_pre_destroy_from_replication_fn_t pre_destroy_from_replication; - uobject_build_subobject_mapping_fn_t build_subobject_mapping; - uobject_get_config_override_platform_fn_t get_config_override_platform; - uobject_override_per_object_config_section_fn_t override_per_object_config_section; - uobject_process_event_fn_t process_event; - uobject_get_function_callspace_fn_t get_function_callspace; - uobject_call_remote_function_fn_t call_remote_function; - uobject_process_console_exec_fn_t process_console_exec; - uobject_regenerate_class_fn_t regenerate_class; - uobject_mark_as_editor_only_subobject_fn_t mark_as_editor_only_subobject; - uobject_check_default_subobjects_internal_fn_t check_default_subobjects_internal; - uobject_validate_generated_rep_enums_fn_t validate_generated_rep_enums; - uobject_set_net_push_id_dynamic_fn_t set_net_push_id_dynamic; - uobject_get_net_push_id_dynamic_fn_t get_net_push_id_dynamic; - - udata_table_get_non_const_row_map_fn_t get_non_const_row_map; - udata_table_add_row_internal_fn_t add_row_internal; - udata_table_get_row_map_const_fn_t get_row_map_const; - udata_table_get_row_map_fn_t get_row_map; - udata_table_allow_duplicate_rows_on_import_fn_t allow_duplicate_rows_on_import; - udata_table_empty_table_fn_t empty_table; - udata_table_remove_row_fn_t remove_row; - udata_table_add_row_fn_t add_row; -}; -MOD_STATIC_ASSERT(sizeof(udata_table_vtable_t) == 0x2B0, "size mismatch"); - -typedef tmulticast_delegate_t fon_data_table_changed_t; - -typedef struct udata_table_s udata_table_t; -struct udata_table_s { - /* uobject_t */ - udata_table_vtable_t *vtable; - eobj_flags_t obj_flags; - int32_t internal_idx; - struct uclass_s *cls; - fname_t name; - struct uobject_s *outer; - /* udata_table_t */ - uscript_struct_t *row_struct; - tmap_fname_uint8ptr_t row_map; - uint8_t flags; - fstring_t import_key_field; - fon_data_table_changed_t on_data_table_changed_delegate; -}; - -MOD_STATIC_ASSERT(offsetof(udata_table_t, row_struct) == 0x28, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(udata_table_t, row_map) == 0x30, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(udata_table_t, flags) == 0x80, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(udata_table_t, import_key_field) == 0x88, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(udata_table_t, on_data_table_changed_delegate) == 0x98, "invalid offset"); -MOD_STATIC_ASSERT(sizeof(udata_table_t) == 0xB0, "size mismatch"); - -typedef struct { - int32_t object_idx; - int32_t object_serial; -} fweak_object_ptr_t; - -MOD_STATIC_ASSERT(sizeof(fweak_object_ptr_t) == 0x08, "size mismatch"); - -typedef struct { - fweak_object_ptr_t object; - fname_t function_name; -} fscript_delegate_t; - -MOD_STATIC_ASSERT(sizeof(fscript_delegate_t) == 0x10, "size mismatch"); - -typedef struct { - fscript_delegate_t *data; - int32_t num; - int32_t max; -} fmulticast_script_delegate_t; - -MOD_STATIC_ASSERT(sizeof(fmulticast_script_delegate_t) == 0x10, "size mismatch"); - -typedef struct { - fname_t tag_name; -} fgameplay_tag_t; - -MOD_STATIC_ASSERT(sizeof(fgameplay_tag_t) == 0x08, "size mismatch"); - -typedef uint8_t elog_verbosity_type_t; -#define ELVT_NO_LOGGING 0x0 -#define ELVT_FATAL 0x1 -#define ELVT_ERROR 0x2 -#define ELVT_WARNING 0x3 -#define ELVT_DISPLAY 0x4 -#define ELVT_LOG 0x5 -#define ELVT_VERBOSE 0x6 -#define ELVT_VERY_VERBOSE 0x7 -#define ELVT_ALL 0x7 -#define ELVT_NUM_VERBOSITY 0x8 -#define ELVT_VERBOSITY_MASK 0xF -#define ELVT_SET_COLOR 0x40 -#define ELVT_BREAK_ON_LOG 0x80 - -struct foutput_device_s; - -typedef void (__fastcall *foutput_device_destructor_fn_t) (struct foutput_device_s *); -typedef void (__fastcall *foutput_device_serialize_time_fn_t) (struct foutput_device_s *, const wchar_t *, elog_verbosity_type_t, const fname_t *, const double); -typedef void (__fastcall *foutput_device_serialize_fn_t) (struct foutput_device_s *, const wchar_t *, elog_verbosity_type_t, const fname_t *); -typedef void (__fastcall *foutput_device_flush_fn_t) (struct foutput_device_s *); -typedef void (__fastcall *foutput_device_tear_down_fn_t) (struct foutput_device_s *); -typedef void (__fastcall *foutput_device_dump_fn_t) (struct foutput_device_s *, void *); -typedef bool (__fastcall *foutput_device_is_memory_only_fn_t) (struct foutput_device_s *); -typedef bool (__fastcall *foutput_device_can_be_used_on_any_thread_fn_t) (struct foutput_device_s *); -typedef bool (__fastcall *foutput_device_can_be_used_on_multiple_threads_fn_t)(struct foutput_device_s *); - -typedef struct foutput_device_vtable_s foutput_device_vtable_t; -struct foutput_device_vtable_s { - foutput_device_destructor_fn_t destructor; - foutput_device_serialize_time_fn_t serialize_time; - foutput_device_serialize_fn_t serialize; - foutput_device_flush_fn_t flush; - foutput_device_tear_down_fn_t tear_down; - foutput_device_dump_fn_t dump; - foutput_device_is_memory_only_fn_t is_memory_only; - foutput_device_can_be_used_on_any_thread_fn_t can_be_used_on_any_thread; - foutput_device_can_be_used_on_multiple_threads_fn_t can_be_used_on_multiple_threads; -}; -MOD_STATIC_ASSERT(sizeof(foutput_device_vtable_t) == 0x48, "size mismatch"); - -typedef struct foutput_device_s foutput_device_t; -struct foutput_device_s { - foutput_device_vtable_t *vftable; - uint8_t suppress_event_tag; - uint8_t auto_emit_line_terminator; -}; - -typedef struct fout_parm_rec_s fout_parm_rec_t; -struct fout_parm_rec_s { - fprop_t *prop; - uint8_t *prop_addr; - struct fout_parm_rec_s *next_out_param; -}; - -typedef struct { - uint32_t inline_data[8]; - uint32_t *secondary_data; - int32_t num; - int32_t max; -} fflow_stack_t; - -typedef struct fframe_s fframe_t; -struct fframe_s { - foutput_device_t base; - ufunc_t *node; - uobject_t *obj; - uint8_t *code; - uint8_t *locals; - fprop_t *most_recent_prop; - uint8_t *most_recent_prop_addr; - fflow_stack_t flow_stack; - struct fframe_s *prev_frame; - fout_parm_rec_t *out_params; - ffield_t *prop_chain_for_compiled_in; - ufunc_t *current_native_func; - uint8_t array_ctx_failed; -}; -MOD_STATIC_ASSERT(offsetof(fframe_t, node) == 0x10, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fframe_t, obj) == 0x18, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fframe_t, code) == 0x20, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fframe_t, locals) == 0x28, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fframe_t, most_recent_prop) == 0x30, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fframe_t, most_recent_prop_addr) == 0x38, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fframe_t, flow_stack) == 0x40, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fframe_t, prev_frame) == 0x70, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fframe_t, out_params) == 0x78, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fframe_t, prop_chain_for_compiled_in) == 0x80, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fframe_t, current_native_func) == 0x88, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(fframe_t, array_ctx_failed) == 0x90, "invalid offset"); - -typedef void(__fastcall *fnative_func_ptr_t)(uobject_t *context, fframe_t *stack, void *result); - -typedef struct fuobject_item_s fuobject_item_t; -struct fuobject_item_s { - uobject_t *obj; - int32_t flags; - int32_t cluster_root_idx; - int32_t serial_num; -}; - -typedef struct fchunked_fixed_uobject_array_s fchunked_fixed_uobject_array_t; -struct fchunked_fixed_uobject_array_s { - fuobject_item_t **objs; - fuobject_item_t *preallocated_objs; - int32_t max_elems; - int32_t num_elems; - int32_t max_chunks; - int32_t num_chunks; -}; - -/* NOTE: creation and deletion listeners use the same callback signature */ -typedef struct fuobject_listener_s fuobject_listener_t; - -typedef void (*fuobject_listener_destroy_t)(fuobject_listener_t *self); -typedef void (*fuobject_listener_notify_cb_t)(fuobject_listener_t *self, const uobject_t *obj, int32_t idx); -typedef void (*fuobject_listener_shutdown_cb_t)(fuobject_listener_t *self); - -typedef struct fuobject_listener_vftable_s fuobject_listener_vftable_t; -struct fuobject_listener_vftable_s { - fuobject_listener_destroy_t destroy; - fuobject_listener_notify_cb_t on_notify; - fuobject_listener_shutdown_cb_t on_shutdown; -}; - -struct fuobject_listener_s { - fuobject_listener_vftable_t *vftable; -}; - -typedef TARRAY(fuobject_listener_t *) tarray_fuobject_listener_t; - -typedef struct fuobject_array_s fuobject_array_t; -struct fuobject_array_s { - int32_t obj_first_cg_idx; - int32_t obj_last_non_cg_idx; - int32_t max_objs_not_considered_by_gc; - bool open_for_disregard_for_gc; - fchunked_fixed_uobject_array_t obj_objs; - fcritical_section_t obj_objs_critical; - TARRAY(int32_t) obj_available_list; - tarray_fuobject_listener_t create_listeners; - tarray_fuobject_listener_t delete_listeners; - fcritical_section_t delete_listeners_critical; - fthread_safe_counter_t master_serial_num; -}; -MOD_STATIC_ASSERT(sizeof(fuobject_array_t) == 0xB8, "size mismatch"); - -typedef struct fasset_data_s fasset_data_t; -struct fasset_data_s { - fname_t obj_path; - fname_t package_name; - fname_t package_path; - fname_t asset_name; - fname_t asset_class; -}; - -typedef struct furl_s furl_t; -struct furl_s { - fstring_t protocol; - fstring_t host; - int32_t port; - int32_t valid; - fstring_t map; - fstring_t redirect_url; - TARRAY(fstring_t) op; - fstring_t portal; -}; - -typedef struct uworld_s uworld_t; -struct uworld_s { - /* uobject */ - uobject_vtable_t *vtable; - eobj_flags_t obj_flags; - int32_t internal_idx; - struct uclass_s *cls; - fname_t name; - struct uobject_s *outer; -}; - -typedef struct fio_env_s fio_env_t; -struct fio_env_s { - fstring_t path; - int32_t order; -}; -MOD_STATIC_ASSERT(sizeof(fio_env_t) == 24, "size mismatch"); - -typedef struct faes_key_s faes_key_t; -struct faes_key_s { - uint8_t key[32]; -}; -MOD_STATIC_ASSERT(sizeof(faes_key_t) == 32, "size mismatch"); - -typedef uint32_t eio_err_code_t; -enum { - IO_ERROR_OK, - IO_ERROR_UNKNOWN, - IO_ERROR_INVALID_CODE, - IO_ERROR_CANCELLED, - IO_ERROR_FILE_OPEN_FAILED, - IO_ERROR_FILE_NOT_OPEN, - IO_ERROR_READ_ERROR, - IO_ERROR_WRITE_ERROR, - IO_ERROR_NOT_FOUND, - IO_ERROR_CORRUPT_TOC, - IO_ERROR_UNKNOWN_CHUNK_ID, - IO_ERROR_INVALID_PARAMETER, - IO_ERROR_SIGNATURE_ERROR, - IO_ERROR_INVALID_ENCRYPTION_KEY -}; - -/* Returns a static readable name for an IO error code. */ -static inline const char * -eio_err_code_to_str(eio_err_code_t code) -{ - switch (code) { - case IO_ERROR_OK: - return "ok"; - case IO_ERROR_UNKNOWN: - return "unknown"; - case IO_ERROR_INVALID_CODE: - return "invalid code"; - case IO_ERROR_CANCELLED: - return "cancelled"; - case IO_ERROR_FILE_OPEN_FAILED: - return "file open failed"; - case IO_ERROR_FILE_NOT_OPEN: - return "file not open"; - case IO_ERROR_READ_ERROR: - return "read error"; - case IO_ERROR_WRITE_ERROR: - return "write error"; - case IO_ERROR_NOT_FOUND: - return "not found"; - case IO_ERROR_CORRUPT_TOC: - return "corrupt TOC"; - case IO_ERROR_UNKNOWN_CHUNK_ID: - return "uknown chunk ID"; - case IO_ERROR_INVALID_PARAMETER: - return "invalid parameter"; - case IO_ERROR_SIGNATURE_ERROR: - return "signature error"; - case IO_ERROR_INVALID_ENCRYPTION_KEY: - return "invalid encryption key"; - } - return "-"; -} - -typedef struct fio_status_s fio_status_t; -struct fio_status_s { - eio_err_code_t err_code; - uint16_t err_msg[FIO_STATUS_ERR_MSG_LEN]; -}; -MOD_STATIC_ASSERT(sizeof(fio_status_t) == 260, "size mismatch"); - -typedef struct fio_dispatcher_impl_s fio_dispatcher_impl_t; -struct fio_dispatcher_impl_s { - bool is_multithreaded; - // lots of other fields.. -}; - -typedef void fpak_platform_file_t; - -typedef struct flayer_actor_stats_s flayer_actor_stats_t; -struct flayer_actor_stats_s { - uclass_t *type; - int32_t total; -}; - -typedef struct ulayer_s ulayer_t; -struct ulayer_s { - uobject_t base; - fname_t layer_name; - uint32_t is_visible; - TARRAY(flayer_actor_stats_t) actor_stats; -}; - -typedef int32_t einternal_object_flags_t; -enum { - IOF_NONE = 0, - IOF_REACHABLE_IN_CLUSTER = (1 << 23), - IOF_CLUSTER_ROOT = (1 << 24), - IOF_NATIVE = (1 << 25), - IOF_ASYNC = (1 << 26), - IOF_ASYNC_LOADING = (1 << 27), - IOF_UNREACHABLE = (1 << 28), - IOF_PENDING_KILL = (1 << 29), - IOF_ROOT_SET = (1 << 30), - IOF_PENDING_CONSTRUCTION = (1 << 31), - IOF_GC_KEEP_FLAGS = (IOF_NATIVE | IOF_ASYNC | IOF_ASYNC_LOADING), -}; - -typedef struct fstatic_construct_obj_params_s fstatic_construct_obj_params_t; -struct fstatic_construct_obj_params_s { - uclass_t *cls; - uobject_t *outer; - fname_t name; - eobj_flags_t set_flags; - einternal_object_flags_t internal_set_flags; - bool copy_transients_from_class_defaults; - bool assume_template_is_archetype; - uobject_t *tmpl; - void *instance_graph; - void *external_package; -}; - -typedef struct fvector_s fvector_t; -struct fvector_s { - float x; - float y; - float z; -}; - -typedef struct fquat_s fquat_t; -struct fquat_s { - float x; - float y; - float z; - float w; -}; - -typedef struct ftransform_s ftransform_t; -MOD_ALIGNED_TYPE(struct, 16) ftransform_s -{ - fquat_t rotation; - fvector_t translation; - float _pad0[1]; - fvector_t scale3d; - float _pad1[1]; -}; -MOD_STATIC_ASSERT(sizeof(ftransform_t) == 48, "invalid size"); - -typedef struct begin_actor_spawn_s begin_actor_spawn_params_t; -struct begin_actor_spawn_s { - uworld_t *world_ctx_obj; - uclass_t *actor_class; - ftransform_t spawn_transform; - uint8_t collision_handling_override; - void *owner; - void *return_value; -}; -MOD_STATIC_ASSERT(offsetof(begin_actor_spawn_params_t, actor_class) == 8, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(begin_actor_spawn_params_t, spawn_transform) == 16, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(begin_actor_spawn_params_t, collision_handling_override) == 64, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(begin_actor_spawn_params_t, owner) == 72, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(begin_actor_spawn_params_t, return_value) == 80, "invalid offset"); - -typedef struct finish_actor_spawn_s finish_actor_spawn_params_t; -struct finish_actor_spawn_s { - void *actor; - uint8_t _pad0[8]; - ftransform_t spawn_transform; - void *return_value; -}; -MOD_STATIC_ASSERT(offsetof(finish_actor_spawn_params_t, spawn_transform) == 16, "invalid offset"); -MOD_STATIC_ASSERT(offsetof(finish_actor_spawn_params_t, return_value) == 64, "invalid offset"); - -typedef struct fsoft_object_path_s fsoft_object_path_t; -struct fsoft_object_path_s { - fname_t asset_path_name; - fstring_t sub_path_string; -}; - -typedef struct execute_console_cmd_params_s execute_console_cmd_params_t; -struct execute_console_cmd_params_s { - uobject_t *world_ctx_obj; - fstring_t cmd; - void *specific_player; // APlayerController * -}; - -typedef struct unreal_cached_objects_s unreal_cached_objects_t; -struct unreal_cached_objects_s { - uclass_t *core_object; // Class /Script/CoreUObject.Object - uclass_t *core_class; // Class /Script/CoreUObject.Class - uclass_t *core_scriptstruct; // Class /Script/CoreUObject.ScriptStruct - uclass_t *core_func; // Class /Script/CoreUObject.Function - uclass_t *core_enum; // Class /Script/CoreUObject.Enum - uclass_t *core_package; // Class /Script/CoreUObject.Package - uclass_t *actor; // Class /Script/Engine.Actor - uclass_t *player_ctrl; // Class /Script/Engine.PlayerController - uclass_t *local_player; // Class /Script/Engine.LocalPlayer - uclass_t *pawn; // Class /Script/Engine.Pawn - uclass_t *hud; // Class /Script/Engine.HUD - uclass_t *world; // Class /Script/Engine.World - uclass_t *game_instance; // Class /Script/Engine.GameInstance - uclass_t *level; // Class /Script/Engine.Level - uclass_t *actor_component; // Class /Script/Engine.ActorComponent - uclass_t *widget; // Class /Script/UMG.Widget - uclass_t *blueprint; // Class /Script/Engine.Blueprint - uclass_t *data_asset; // Class /Script/Engine.DataAsset - uclass_t *data_table; // Class /Script/Engine.DataTable - uobject_t *gameplay_statics_cdo; // GameplayStatics /Script/Engine.Default__GameplayStatics - ufunc_t *begin_spawn; // Function /Script/Engine.GameplayStatics.BeginDeferredActorSpawnFromClass - ufunc_t *finish_spawn; // Function /Script/Engine.GameplayStatics.FinishSpawningActor - ufunc_t *destroy_actor; // Function /Script/Engine.Actor.K2_DestroyActor -}; - -extern unreal_cached_objects_t g_cached_objects; - -/* - * Scans the current UObject array and fills g_cached_objects with commonly used classes and functions. - * Call it on initialization. - * Helpers that use the cache assert when required entries are missing. - */ -void -unreal_cache_objects(void); - -/* ===================================================== FNAME ====================================================== */ - -/* Returns the engine's live FName pool. */ -fname_pool_t * -unreal_get_name_pool(void); - -/* Compares FNames by comparison index and, unless ignore_num is set, by number. */ -bool -unreal_fname_equal(fname_t a, fname_t b, bool ignore_num); -/* Compute FName hash. */ -uint32_t -unreal_fname_hash(fname_t name); -/* Check if FName is None. */ -bool -unreal_fname_is_none(fname_t name); -/* Returns the raw pool entry for a comparison index. The engine owns the returned memory. */ -fname_entry_t * -unreal_fname_entry_get(uint32_t cmp_idx); -/* Returns the UTF-8 byte length of an FName, including its numeric suffix when present. */ -uint64_t -unreal_fname_utf8_len(fname_t name); -/* Writes an FName as UTF-8 and returns the bytes written. No null terminator is added. */ -uint64_t -unreal_fname_utf8_write(uint8_t *buf, uint64_t max_len, fname_t name); -/* Converts an FName to a null-terminated UTF-8 string allocated in an arena. */ -str_t -unreal_fname_to_str(fname_t fname, mod_arena_t arena); -/* - * Finds or creates an FName using the requested EFindName mode. - * FNAME_FIND does not add missing names. - * Modes that modify the pool should only be used where Unreal allows it. - */ -fname_t -unreal_fname_from_str(str_t s, efind_name_t find_type); - -typedef bool (*fname_pool_iter_cb_t)(fname_t name, fname_entry_t *entry, void *user); -/* - * Walks the current FName pool and calls cb for each entry. - * Returning false stops the walk. - */ -void -unreal_fname_pool_iterate(fname_pool_iter_cb_t cb, void *user); - -/* - * Matches UTF-8 text against an FName entry by exact match or substring. - * UTF-8 multibyte text is not decoded for wide entries. - * Case insensitive comparison is ASCII-only. - */ -bool -unreal_fname_entry_match_text(fname_entry_t *entry, str_t text, bool ignore_case, bool exact_match); -/* - * Matches UTF-16 text against an FName entry by exact match or substring. - * Case insensitive comparison is ASCII-only. - */ -bool -unreal_fname_entry_match_text16(fname_entry_t *entry, str16_t text, bool ignore_case, bool exact_match); -/* Matches UTF-8 text against an FName's pool entry. The FName number suffix is ignored. */ -bool -unreal_fname_match_text(fname_t name, str_t text, bool ignore_case, bool exact_match); -/* Matches UTF-16 text against an FName's pool entry. The FName number suffix is ignored. */ -bool -unreal_fname_match_text16(fname_t name, str16_t text, bool ignore_case, bool exact_match); - -/* ==================================================== FSTRING ===================================================== */ - -/* - * Converts UTF-8 into arena-backed UTF-16 and wraps it as an FString view. - * The memory is not owned by Unreal and must not be passed to code that frees or resizes the FString. - */ -fstring_t -unreal_fstring_from_str(str_t s, mod_arena_t arena); -/* Copies an FString to a null-terminated UTF-8 arena string. */ -str_t -unreal_fstring_to_str(fstring_t fs, mod_arena_t arena); -/* Compute FString hash. */ -uint32_t -unreal_fstring_hash(fstring_t str); -/* =================================================== FIOSTATUS ==================================================== */ -/* Formats an I/O status as its message, numeric code, and readable code name. */ -str_t -unreal_fio_status_to_str(fio_status_t status, mod_arena_t perm); - -/* ==================================================== UOBJECT ===================================================== */ - -/* Returns the engine's live global UObject array, or NULL when unavailable. */ -fuobject_array_t * -unreal_get_object_array(void); -/* Returns the current GWorld value. It may be NULL during startup, shutdown, or map changes. */ -uworld_t * -unreal_get_current_world(void); - -/* Registers a create or delete callback for this mod. Returns false when registration fails. */ -bool -unreal_register_uobject_listener(uobject_listener_kind_t kind, uobject_notify_cb_t notify_cb, void *user); -/* Removes a listener matching the same kind, callback, and user pointer. */ -void -unreal_deregister_uobject_listener(uobject_listener_kind_t kind, uobject_notify_cb_t notify_cb, void *user); - -/* Returns a raw object array slot by index, even when the slot itself is not valid. */ -fuobject_item_t * -unreal_uobject_array_get_item(int idx); -/* Checks that a slot has an object and is not marked unreachable or pending kill. */ -bool -unreal_uobject_array_item_is_valid(fuobject_item_t *item); -/* Returns the valid UObject at an array index, or NULL. */ -uobject_t * -unreal_uobject_array_get_obj(int idx); -/* Checks an object's class and every superclass against cls. */ -bool -unreal_uobject_is_a(uobject_t *obj, uclass_t *cls); -/* Checks whether an object is a class default object or archetype object. */ -bool -unreal_uobject_is_default(uobject_t *obj); -/* - * Checks the object's array index, slot flags, and that the slot still points to the same object. - * This is only a snapshot and does not keep the object alive after the call. - */ -bool -unreal_uobject_is_valid(uobject_t *obj); - -/* Returns the UTF-8 byte length of an object's FName. */ -uint64_t -unreal_uobject_get_name_len(uobject_t *obj); -/* Writes an object's FName as UTF-8 and returns the bytes written. No terminator is added. */ -uint64_t -unreal_uobject_write_name(uobject_t *obj, uint8_t *dst, uint64_t cap); -/* Copies an object's name into a null-terminated arena string. */ -str_t -unreal_uobject_push_name(uobject_t *obj, mod_arena_t arena); - -/* Checks the object and each outer for a matching FName. */ -bool -unreal_outer_chain_contains(uobject_t *obj, str_t str, bool ignore_case, bool exact_match); -/* Checks the class and each superclass for a matching FName. */ -bool -unreal_super_chain_contains(uclass_t *cls, str_t str, bool ignore_case, bool exact_match); - -/* Returns the byte length of the outer chain and object name joined with dots. */ -uint64_t -unreal_uobject_get_full_name_len(uobject_t *obj); -/* Writes the outer chain from root to object with dot separators. No terminator is added. */ -uint64_t -unreal_uobject_write_full_name(uobject_t *obj, uint8_t *dst, uint64_t cap); -/* Copies the outer chain from root to object into a null-terminated arena string. */ -str_t -unreal_uobject_push_full_name(uobject_t *obj, mod_arena_t arena); - -/* Returns the current number of UObject array elements, including empty or invalid slots. */ -int -unreal_uobject_array_count(void); -/* Returns the maximum element capacity of the current UObject array. */ -int -unreal_uobject_array_capacity(void); -/* Returns the number of currently allocated UObject chunks. */ -int -unreal_uobject_array_num_chunks(void); -/* Returns the maximum UObject chunk count. */ -int -unreal_uobject_array_max_chunks(void); - -/* Returns the first object index considered by garbage collection. */ -int -unreal_uobject_array_first_gc_index(void); -/* Returns the last object index excluded from normal garbage collection. */ -int -unreal_uobject_array_last_non_gc_index(void); -/* Returns whether Unreal is still accepting objects into the disregard-for-GC range. */ -bool -unreal_uobject_array_is_open_for_disregard_for_gc(void); - -/* Scans valid objects and returns the first whose FName matches. The number suffix is ignored. */ -uobject_t * -unreal_uobject_find(str_t name, bool ignore_case, bool exact_match); -/* Scans valid UClass objects and returns the first name match. unreal_cache_objects must have run first. */ -uclass_t * -unreal_uclass_find(str_t name, bool ignore_case, bool exact_match); -/* Returns the first non-default object that is an instance of cls or one of its subclasses. */ -uobject_t * -unreal_uobject_find_first_of(uclass_t *cls); -/* Returns the first non-default object with a specified name that is an instance of cls or one of its subclasses. */ -uobject_t * -unreal_uobject_find_first_of_by_name(uclass_t *cls, str_t name, bool ignore_case, bool exact_match); -/* Finds a UClass by an exact, case-sensitive dotted outer-chain name. */ -uclass_t * -unreal_uobject_find_class_by_full_name(str_t full_name); -/* Finds an object by exact, case-sensitive full name and optional class filter. */ -uobject_t * -unreal_uobject_find_by_full_name(uclass_t *cls, str_t full_name); - -/* - * Calls Unreal's ProcessEvent for self and func. - * params must match the function's parameter memory layout, including return and out fields. - * Call this only from game thread. - */ -void -unreal_process_event(uobject_t *self, ufunc_t *func, void *params); - -/* - * Spawns an actor through GameplayStatics using deferred begin and finish calls. - * It uses an identity transform, always-spawn collision handling, and no owner. - * unreal_cache_objects must have run first. - */ -uobject_t * -unreal_spawn_actor(uobject_t *world_ctx_obj, uclass_t *cls); -/* Calls K2_DestroyActor on an actor. unreal_cache_objects must have run first. */ -void -unreal_despawn_actor(uobject_t *actor); -/* Creates and initializes a new UObject according to the specified parameters. */ -uobject_t * -unreal_static_construct_object(fstatic_construct_obj_params_t *params); -/* Loads a UObject through the host's Unreal loader and returns NULL on failure. */ -uobject_t * -unreal_static_load_object(uclass_t *obj_cls, uobject_t *outer, str_t name, str_t filename, uint32_t load_flags, void *sandbox, bool allow_obj_reconcile, void *instancing_ctx); -/* Loads a UClass through the host's Unreal loader and returns NULL on failure. */ -uclass_t * -unreal_static_load_class(uclass_t *base_cls, uobject_t *outer, str_t name, str_t filename, uint32_t load_flags); - -/* Mounts a pak file using the supplied engine mount order. */ -bool -unreal_mount_pak(str_t file_path, int order); -/* Mounts an IO Store container using the supplied engine mount order. */ -bool -unreal_mount_iostore(str_t file_path, int order); - -/* Returns the native bytecode handler registered for an opcode, or NULL. */ -fnative_func_ptr_t -unreal_get_native(uint8_t opcode); -/* - * Reads one opcode from stack->code, advances the code pointer, and calls its native handler. - * Returns false when no handler exists. - * The opcode byte remains consumed in that case. - */ -bool -unreal_fframe_step(fframe_t *stack, void *result); - -/* ================================================ CLASS INTROSPECTION ============================================= */ -/* Searches s->prop_link for an exact, case-sensitive property name. */ -fprop_t * -unreal_ustruct_find_prop(ustruct_t *s, str_t name); -/* Searches UField children on a struct and its super structs for an exact function name. */ -ufunc_t * -unreal_ustruct_find_func(ustruct_t *s, str_t name); - -/* Searches UField children on a struct and its super structs for an FName. */ -ufunc_t * -unreal_ustruct_find_func_fname(ustruct_t *s, fname_t name, bool ignore_num); - -/* Returns the raw sparse multicast delegate storage for an owner and delegate name. */ -void * -unreal_get_mcast_sparse_delegate(uobject_t *s, fname_t name); - -/* ================================================= PROPERTY ACCESS ================================================ */ -/* Returns a raw property address by adding offset_internal to a container pointer. No checks are made. */ -static inline void * -unreal_uprop_ptr(fprop_t *prop, void *container) -{ - return (uint8_t *)container + prop->offset_internal; -} - -/* Reads a packed Unreal bool property directly from container memory. */ -static inline bool -unreal_uprop_get_bool(fprop_bool_t *prop, void *container) -{ - uint8_t *byte = (uint8_t *)container + prop->base.offset_internal + prop->byte_offset; - return (*byte & prop->field_mask) != 0; -} - -/* Writes a packed Unreal bool property directly without calling engine setters or notifications. */ -static inline void -unreal_uprop_set_bool(fprop_bool_t *prop, void *container, bool val) -{ - uint8_t *byte = (uint8_t *)container + prop->base.offset_internal + prop->byte_offset; - if (val) { - *byte |= prop->field_mask; - } else { - *byte &= ~prop->field_mask; - } -} - -/* Reads an FName property directly from container memory. */ -static inline fname_t -unreal_uprop_get_fname(fprop_t *prop, void *container) -{ - return *(fname_t *)unreal_uprop_ptr(prop, container); -} - -/* Writes an FName property directly without calling engine setters or notifications. */ -static inline void -unreal_uprop_set_fname(fprop_t *prop, void *container, fname_t val) -{ - *(fname_t *)unreal_uprop_ptr(prop, container) = val; -} - -/* Returns a shallow copy of an FString property. Its data remains owned by the engine object. */ -static inline fstring_t -unreal_uprop_get_fstr(fprop_t *prop, void *container) -{ - return *(fstring_t *)unreal_uprop_ptr(prop, container); -} - -/* Reads a UObject property pointer directly from container memory. */ -static inline uobject_t * -unreal_uprop_get_obj(fprop_t *prop, void *container) -{ - return *(uobject_t **)unreal_uprop_ptr(prop, container); -} - -/* Writes a UObject property pointer directly without validation or engine notifications. */ -static inline void -unreal_uprop_set_obj(fprop_t *prop, void *container, uobject_t *val) -{ - *(uobject_t **)unreal_uprop_ptr(prop, container) = val; -} - -/* =============================================== CONTAINER UTILITIES ============================================== */ - -/* Returns true when idx is an allocated/set bit in the bit array. */ -bool -unreal_tbit_array_is_set(tbit_array_t *bits, int32_t idx); -/* Returns the first set bit at or after start_idx, or TSET_INVALID_ID when there is none. */ -int32_t -unreal_tbit_array_find_next_set(tbit_array_t *bits, int32_t start_idx); -/* Returns the first TSet element id in the bucket for key_hash, or TSET_INVALID_ID. */ -int32_t -unreal_tset_hash_head(hash_allocator_t *hash, int32_t hash_size, uint32_t key_hash); - -/* Returns false when the connected host predates the reflected map helpers. */ -bool -unreal_map_helpers_available(void); -void -unreal_map_add(void *map, fprop_map_t *prop, const void *key, const void *val); -bool -unreal_map_remove(void *map, fprop_map_t *prop, const void *key); -bool -unreal_map_find(void *map, fprop_map_t *prop, const void *key, void *out_val); - -/* =================================================== DATA TABLE =================================================== */ - -tmap_fname_uint8ptr_t * -unreal_udata_table_get_row_map(udata_table_t *table); -void -unreal_udata_table_add_row(udata_table_t *table, fname_t row_name, const ftable_row_base_t *row_data); -void -unreal_udata_table_remove_row(udata_table_t *table, fname_t row_name); -void -unreal_udata_table_empty(udata_table_t *table); -uint8_t * -unreal_udata_table_find_row(udata_table_t *table, fname_t row_name); - -/* Adds a new FGameplayTag. - * NOTE: tags are added after tick function. */ -bool -unreal_add_gameplay_tag(fname_t tag_name); -/* Check if given FGameplayTag exists. */ -bool -unreal_check_gameplay_tag_exists(fname_t tag_name); - -#ifdef __cplusplus -} -#endif - -#endif /* UE_TYPES_H */ diff --git a/overdub.vcxproj b/overdub.vcxproj index 807e9d1..9246cfc 100644 --- a/overdub.vcxproj +++ b/overdub.vcxproj @@ -69,7 +69,7 @@ Disabled false false - WIN32_LEAN_AND_MEAN;COBJMACROS;BUILD_DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + WIN32_LEAN_AND_MEAN;COBJMACROS;BUILD_DEBUG;OVERDUB_BUILD_DLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) include;vendor;%(AdditionalIncludeDirectories) ProgramDatabase MultiThreadedDebug @@ -94,7 +94,7 @@ true true true - WIN32_LEAN_AND_MEAN;COBJMACROS;BUILD_RELEASE;NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + WIN32_LEAN_AND_MEAN;COBJMACROS;BUILD_RELEASE;OVERDUB_BUILD_DLL;NDEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) include;vendor;%(AdditionalIncludeDirectories) MultiThreaded @@ -104,7 +104,7 @@ true true UseLinkTimeCodeGeneration - user32.lib;kernel32.lib;advapi32.lib;shlwapi.lib;d3d12.lib;d3d11.lib;dxgi.lib;dxguid.lib;uuid.lib;%(AdditionalDependencies) + user32.lib;kernel32.lib;advapi32.lib;shlwapi.lib;d3d12.lib;d3d11.lib;dxgi.lib;dxguid.lib;uuid.lib;dbghelp.lib;%(AdditionalDependencies) @@ -115,7 +115,7 @@ Disabled false false - WIN32_LEAN_AND_MEAN;COBJMACROS;BUILD_TEST_UI;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + WIN32_LEAN_AND_MEAN;COBJMACROS;BUILD_TEST_UI;OVERDUB_STATIC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) .;include;vendor;%(AdditionalIncludeDirectories) ProgramDatabase /utf-8 %(AdditionalOptions) @@ -136,7 +136,7 @@ false - true + false false @@ -266,6 +266,11 @@ true false + + true + true + false + true true @@ -281,7 +286,7 @@ - + diff --git a/src/builtin/tweaks.c b/src/builtin/tweaks.c index 864c187..ae3c9ae 100644 --- a/src/builtin/tweaks.c +++ b/src/builtin/tweaks.c @@ -4,7 +4,7 @@ #include "file.h" #include "globals.h" #include "log.h" -#include "mod_host.h" +#include "mod.h" #include "path.h" #include "scratch.h" @@ -199,13 +199,13 @@ ufunc_is(ufunc_t *func, str_t func_name) static bool should_disable_tutorials(tweaks_t *tweaks) { - return tweaks && tweaks->inited && mod_cfg_get_bool(&globals.mod_manager, tweaks->cfg.disable_tutorials_h); + return tweaks && tweaks->inited && mod_manager_cfg_get_bool(&globals.mod_manager, tweaks->cfg.disable_tutorials_h); } static bool should_restore_jbox_music(tweaks_t *tweaks) { - return tweaks && tweaks->inited && mod_cfg_get_bool(&globals.mod_manager, tweaks->cfg.restore_jbox_h); + return tweaks && tweaks->inited && mod_manager_cfg_get_bool(&globals.mod_manager, tweaks->cfg.restore_jbox_h); } static bool @@ -325,12 +325,12 @@ tweaks_on_jbox_controller_delete(uobject_t *obj, int32_t idx, void *user) } static bool MOD_CALL -tweaks_init(const mod_host_api_t *host, mod_handle_t h) +tweaks_init(mod_handle_t h) { tweaks_t *tweaks = &g_tweaks; mem_zero(tweaks, sizeof(*tweaks)); - tweaks->perm = mod_arena_handle_resolve(host->get_perm(h)); + tweaks->perm = mod_arena_handle_resolve(mod_get_perm(h)); ASSERT(tweaks->perm != NULL); tweaks->cfg.disable_tutorials_h = mod_cfg_get_by_id(&globals.mod_manager, h, STR_LIT(CFG_DISABLE_TUTORIALS)); @@ -340,16 +340,18 @@ tweaks_init(const mod_host_api_t *host, mod_handle_t h) void *jbox_play_music_addr = NULL; - host->sigscan("JukeboxPlayMusic", "48 89 5C 24 ? 48 89 7C 24 ? 41 56 48 83 EC ? 4C 8B F2 48 8B F9", 0, 0, NULL, &jbox_play_music_addr); + sigscan_entry_t jbox_play_music_sig = SIG_ENTRY_DIRECT(jbox_play_music_addr, + "48 89 5C 24 ? 48 89 7C 24 ? 41 56 48 83 EC ? 4C 8B F2 48 8B F9"); + mod_sigscan(&jbox_play_music_sig); tweaks->jbox.play_music = jbox_play_music_addr; - tweaks->jbox.state_path = path_join(tweaks->perm, host->get_mod_dir(h), STR_LIT("jukebox_state.ini")); + tweaks->jbox.state_path = path_join(tweaks->perm, mod_get_mod_dir(h), STR_LIT("jukebox_state.ini")); tweaks_load_jbox_state(&tweaks->jbox.saved_state, tweaks->jbox.state_path); tweaks->jbox.controller_cls_name = unreal_fname_from_str(STR_LIT("JukeBoxController_BP_C"), FNAME_FIND); - host->register_uobject_listener(h, UOBJECT_LISTENER_KIND_CREATE, tweaks_on_jbox_controller_create, NULL); - host->register_uobject_listener(h, UOBJECT_LISTENER_KIND_DELETE, tweaks_on_jbox_controller_delete, NULL); + mod_register_uobject_listener(h, UOBJECT_LISTENER_KIND_CREATE, tweaks_on_jbox_controller_create, NULL); + mod_register_uobject_listener(h, UOBJECT_LISTENER_KIND_DELETE, tweaks_on_jbox_controller_delete, NULL); uclass_t *jbox_controller_cls = unreal_uclass_find(STR_LIT("JukeBoxController_BP_C"), false, true); if (jbox_controller_cls) { @@ -387,7 +389,7 @@ tweaks_process_event_pre(mod_handle_t h, uobject_t *self, ufunc_t *func, void *p should_consume = true; } - if (mod_cfg_get_bool(&globals.mod_manager, tweaks->cfg.enable_infinite_jumps_h)) { + if (mod_manager_cfg_get_bool(&globals.mod_manager, tweaks->cfg.enable_infinite_jumps_h)) { if (func && unreal_fname_match_text(func->name, STR_LIT("CanJumpInternal"), false, true)) { *((uint8_t *)params) = 1; should_consume = true; @@ -496,7 +498,7 @@ tweaks_tick(mod_handle_t h, float delta) } } - if (keybind_is_pressed(mod_cfg_get_keybind(&globals.mod_manager, tweaks->cfg.debug_widget_keybind_h))) { + if (keybind_is_pressed(mod_manager_cfg_get_keybind(&globals.mod_manager, tweaks->cfg.debug_widget_keybind_h))) { static uclass_t *debug_cls = NULL; static ufunc_t *debug_show = NULL; diff --git a/src/builtin/ufunction_call.c b/src/builtin/ufunction_call.c index 3e431e0..750e9b9 100644 --- a/src/builtin/ufunction_call.c +++ b/src/builtin/ufunction_call.c @@ -3,7 +3,7 @@ #include "arena.h" #include "globals.h" #include "log.h" -#include "mod_host.h" +#include "mod.h" #include "scratch.h" #include "str.h" #include "ui_nuklear.h" @@ -1077,9 +1077,9 @@ call_execute(search_tool_t *tool, ufunc_call_dialog_t *dialog) } bool -ufunc_call_init(search_tool_t *tool, const mod_host_api_t *host, mod_handle_t h) +ufunc_call_init(search_tool_t *tool, mod_handle_t h) { - if (!tool || !host) { + if (!tool) { return false; } @@ -1088,8 +1088,8 @@ ufunc_call_init(search_tool_t *tool, const mod_host_api_t *host, mod_handle_t h) return false; } - dialog->model_arena = mod_arena_handle_resolve(host->arena_create(h, 32 * MB, 64 * KB)); - dialog->result_arena = mod_arena_handle_resolve(host->arena_create(h, 32 * MB, 64 * KB)); + dialog->model_arena = mod_arena_handle_resolve(mod_arena_create(h, 32 * MB, 64 * KB)); + dialog->result_arena = mod_arena_handle_resolve(mod_arena_create(h, 32 * MB, 64 * KB)); dialog->picker.slots = ARENA_PUSH_ARRAY(tool->perm, uint32_t, tool->cache.record_cap); dialog->func_slot = RECORD_SLOT_INVALID; call_object_ref_set_none(&dialog->target); diff --git a/src/builtin/ufunction_tracer.c b/src/builtin/ufunction_tracer.c index 3bf3d61..1d5c1b4 100644 --- a/src/builtin/ufunction_tracer.c +++ b/src/builtin/ufunction_tracer.c @@ -1205,7 +1205,7 @@ trace_draw_window(trace_tool_t *tool, unsigned int vw, unsigned int vh) } uint32_t call_root_count = trace_call_root_count(tool); - uint32_t page_size = (uint32_t)MAX_VAL(1, mod_cfg_get_int(&globals.mod_manager, tool->cfg.page_size_h)); + uint32_t page_size = (uint32_t)MAX_VAL(1, mod_manager_cfg_get_int(&globals.mod_manager, tool->cfg.page_size_h)); uint32_t page_count = trace_page_count(call_root_count, page_size); if (tool->ui.page_idx >= page_count) { tool->ui.page_idx = page_count - 1; @@ -1279,10 +1279,8 @@ trace_draw_window(trace_tool_t *tool, unsigned int vw, unsigned int vh) } static bool MOD_CALL -trace_init(const mod_host_api_t *host, mod_handle_t h) +trace_init(mod_handle_t h) { - UNUSED_VAR(host); - trace_tool_t *tool = &g_trace_tool; mem_zero(tool, sizeof(*tool)); @@ -1291,7 +1289,7 @@ trace_init(const mod_host_api_t *host, mod_handle_t h) tool->cfg.open_window_h = mod_cfg_get_by_id(&globals.mod_manager, h, STR_LIT(CFG_OPEN_WINDOW_ID)); tool->cfg.page_size_h = mod_cfg_get_by_id(&globals.mod_manager, h, STR_LIT(CFG_PAGE_SIZE_ID)); - tool->max_call_count = (uint32_t)MAX_VAL(1, mod_cfg_get_int(&globals.mod_manager, tool->cfg.max_calls_h)); + tool->max_call_count = (uint32_t)MAX_VAL(1, mod_manager_cfg_get_int(&globals.mod_manager, tool->cfg.max_calls_h)); tool->ui.capture_filter_input = ARENA_PUSH_ARRAY_ZERO(tool->perm, char, TRACE_FILTER_TEXT_CAP); tool->ui.capture_filter_input_len = 0; @@ -1379,7 +1377,7 @@ trace_input(mod_handle_t h, input_event_t *ev) return false; } - keybind_t toggle = mod_cfg_get_keybind(&globals.mod_manager, tool->cfg.open_window_h); + keybind_t toggle = mod_manager_cfg_get_keybind(&globals.mod_manager, tool->cfg.open_window_h); if (keybind_activated_by_event(toggle, ev)) { if (keybind_is_pressed(toggle)) { tool->ui.closed = !tool->ui.closed; diff --git a/src/builtin/uobject_search.c b/src/builtin/uobject_search.c index 3c44ceb..dfb45b6 100644 --- a/src/builtin/uobject_search.c +++ b/src/builtin/uobject_search.c @@ -8,7 +8,7 @@ #include "globals.h" #include "input.h" #include "log.h" -#include "mod_host.h" +#include "mod.h" #include "mod_manager.h" #include "nk_d3d12.h" #include "profiler.h" @@ -41,7 +41,7 @@ progress_pct(uint32_t current, uint32_t max) bool work_budget_exhausted(search_tool_t *tool, uint64_t start_us) { - uint64_t work_budget_us = (uint64_t)mod_cfg_get_int(&globals.mod_manager, tool->cfg.work_budget_h); + uint64_t work_budget_us = (uint64_t)mod_manager_cfg_get_int(&globals.mod_manager, tool->cfg.work_budget_h); return time_now_us() - start_us >= work_budget_us; } @@ -58,7 +58,7 @@ get_page_count(slot_list_t *results, uint32_t page_size) static void clamp_page(search_tool_t *tool, slot_list_t *results) { - uint32_t max_results = (uint32_t)mod_cfg_get_int(&globals.mod_manager, tool->cfg.max_results_h); + uint32_t max_results = (uint32_t)mod_manager_cfg_get_int(&globals.mod_manager, tool->cfg.max_results_h); uint32_t page_count = get_page_count(results, max_results); if (tool->ui.page_index >= page_count) { tool->ui.page_index = page_count - 1; @@ -341,7 +341,7 @@ draw_window(search_tool_t *tool, unsigned int vw, unsigned int vh) clamp_page(tool, &tool->search.visible); - uint32_t max_results = (uint32_t)mod_cfg_get_int(&globals.mod_manager, tool->cfg.max_results_h); + uint32_t max_results = (uint32_t)mod_manager_cfg_get_int(&globals.mod_manager, tool->cfg.max_results_h); uint32_t page_size = (uint32_t)NK_MAX(max_results, 1); uint32_t page_count = get_page_count(&tool->search.visible, page_size); uint32_t start_idx = tool->ui.page_index * page_size; @@ -479,7 +479,7 @@ tool_work_tick(search_tool_t *tool) } static bool MOD_CALL -tool_init(const mod_host_api_t *host, mod_handle_t h) +tool_init(mod_handle_t h) { search_tool_t *tool = &g_tool; mem_zero(tool, sizeof(*tool)); @@ -511,7 +511,7 @@ tool_init(const mod_host_api_t *host, mod_handle_t h) tool->cache.build_total = (uint32_t)unreal_uobject_array_count(); tool->cache.world = (globals.gworld_ptr) ? *globals.gworld_ptr : NULL; - arena_t *string_arena = mod_arena_handle_resolve(host->arena_create(h, 128 * MB, 1 * MB)); + arena_t *string_arena = mod_arena_handle_resolve(mod_arena_create(h, 128 * MB, 1 * MB)); if (!string_arena) { LOG_ERROR("UObject Search: failed to create the string arena"); return false; @@ -550,8 +550,8 @@ tool_init(const mod_host_api_t *host, mod_handle_t h) tool->details.preview_tab = NULL; for (int i = 0; i < COUNTOF(tool->details.tabs); ++i) { - tool->details.tabs[i].info_arena = mod_arena_handle_resolve(host->arena_create(h, 64 * MB, 64 * KB)); - tool->details.tabs[i].value_arena = mod_arena_handle_resolve(host->arena_create(h, 64 * MB, 64 * KB)); + tool->details.tabs[i].info_arena = mod_arena_handle_resolve(mod_arena_create(h, 64 * MB, 64 * KB)); + tool->details.tabs[i].value_arena = mod_arena_handle_resolve(mod_arena_create(h, 64 * MB, 64 * KB)); ASSERT(tool->details.tabs[i].info_arena != NULL); ASSERT(tool->details.tabs[i].value_arena != NULL); @@ -562,13 +562,13 @@ tool_init(const mod_host_api_t *host, mod_handle_t h) tool->details.tabs[i].next = &tool->details.tabs[i + 1]; } - if (!ufunc_call_init(tool, host, h)) { + if (!ufunc_call_init(tool, h)) { LOG_ERROR("UObject Search: failed to initialize the UFunction call dialog"); return false; } - ASSERT(host->register_uobject_listener(h, UOBJECT_LISTENER_KIND_CREATE, on_uobject_created, tool)); - ASSERT(host->register_uobject_listener(h, UOBJECT_LISTENER_KIND_DELETE, on_uobject_deleted, tool)); + ASSERT(mod_register_uobject_listener(h, UOBJECT_LISTENER_KIND_CREATE, on_uobject_created, tool)); + ASSERT(mod_register_uobject_listener(h, UOBJECT_LISTENER_KIND_DELETE, on_uobject_deleted, tool)); tool->ctx = globals.ui_manager.ctx; tool->handle = h; @@ -621,7 +621,7 @@ tool_input(mod_handle_t h, input_event_t *ev) return false; } - keybind_t toggle_keybind = mod_cfg_get_keybind(&globals.mod_manager, tool->cfg.open_window_h); + keybind_t toggle_keybind = mod_manager_cfg_get_keybind(&globals.mod_manager, tool->cfg.open_window_h); if (keybind_activated_by_event(toggle_keybind, ev)) { if (keybind_is_pressed(toggle_keybind)) { tool->ui.closed = !tool->ui.closed; diff --git a/src/builtin/uobject_search_internal.h b/src/builtin/uobject_search_internal.h index 81e8c70..80483fc 100644 --- a/src/builtin/uobject_search_internal.h +++ b/src/builtin/uobject_search_internal.h @@ -282,7 +282,7 @@ struct tool_cache_s { typedef struct ufunc_call_dialog_s ufunc_call_dialog_t; bool -ufunc_call_init(search_tool_t *tool, const mod_host_api_t *host, mod_handle_t h); +ufunc_call_init(search_tool_t *tool, mod_handle_t h); void ufunc_call_open(search_tool_t *tool, record_t *func_record, record_t *suggested_target); void diff --git a/src/mod_host.c b/src/mod_host.c index 6747140..5679236 100644 --- a/src/mod_host.c +++ b/src/mod_host.c @@ -1,4 +1,4 @@ -#include "mod_host.h" +#include "mod.h" #include "arena.h" #include "globals.h" @@ -6,618 +6,329 @@ #include "mod_manager.h" #include "scratch.h" #include "sigscan.h" +#include "str.h" #include "unreal.h" -#include "unreal_prop.h" -#include +#include -static inline host_tmp_arena_t -host_tmp_arena_make(tmp_arena_t tmp) +static inline mod_tmp_arena_t +mod_tmp_arena_make(tmp_arena_t tmp) { - return (host_tmp_arena_t){ + return (mod_tmp_arena_t){ .arena = mod_arena_handle_make(tmp.arena), .pos = tmp.pos, }; } static inline tmp_arena_t -host_tmp_arena_resolve(host_tmp_arena_t host_tmp) +mod_tmp_arena_resolve(mod_tmp_arena_t tmp) { return (tmp_arena_t){ - .arena = mod_arena_handle_resolve(host_tmp.arena), - .pos = host_tmp.pos, + .arena = mod_arena_handle_resolve(tmp.arena), + .pos = tmp.pos, }; } -static str_t MOD_CALL -host_get_mod_dir(mod_handle_t h) +str_t MOD_CALL +mod_get_mod_dir(mod_handle_t mod) { - return mod_get_mod_dir(&globals.mod_manager, h); + return mod_manager_get_mod_dir(&globals.mod_manager, mod); } -static str_t MOD_CALL -host_get_config_path(mod_handle_t h) +str_t MOD_CALL +mod_get_config_path(mod_handle_t mod) { - return mod_get_config_path(&globals.mod_manager, h); + return mod_manager_get_config_path(&globals.mod_manager, mod); } -static str_t MOD_CALL -host_get_manifest_path(mod_handle_t h) +str_t MOD_CALL +mod_get_manifest_path(mod_handle_t mod) { - return mod_get_manifest_path(&globals.mod_manager, h); + return mod_manager_get_manifest_path(&globals.mod_manager, mod); } -static void MOD_CALL -host_logv(mod_handle_t h, log_level_t level, const char *fmt, va_list args) +void MOD_CALL +mod_logv(mod_handle_t mod, log_level_t level, const char *fmt, va_list args) { - (void)h; + (void)mod; log_emitv(level, LOG_SINK_DEFAULT, fmt, args); } -static mod_cfg_handle_t MOD_CALL -host_get_cfg_by_id(mod_handle_t h, str_t id) -{ - return mod_cfg_get_by_id(&globals.mod_manager, h, id); -} - -static bool MOD_CALL -host_register_cmd(mod_handle_t h, str_t name, str_t description, mod_cmd_fn_t fn, void *user) -{ - return mod_register_cmd(&globals.mod_manager, h, name, description, fn, user); -} - -static struct nk_context *MOD_CALL -host_get_nk_ctx(void) +void MOD_CALL +mod_log(mod_handle_t mod, log_level_t level, const char *fmt, ...) { - return globals.ui_manager.ctx; + va_list args; + va_start(args, fmt); + mod_logv(mod, level, fmt, args); + va_end(args); } -static void MOD_CALL -host_get_viewport_size(unsigned int *vw, unsigned int *vh) +mod_cfg_handle_t MOD_CALL +mod_get_cfg_by_id(mod_handle_t mod, str_t id) { - if (vw) { - *vw = globals.ui_manager.vw; - } - - if (vh) { - *vh = globals.ui_manager.vh; - } + return mod_cfg_get_by_id(&globals.mod_manager, mod, id); } -static void MOD_CALL -host_cfg_get_bool(mod_cfg_handle_t h, bool *val) +bool MOD_CALL +mod_register_cmd(mod_handle_t mod, str_t name, str_t description, mod_cmd_fn_t fn, void *user) { - if (val) { - *val = mod_cfg_get_bool(&globals.mod_manager, h); - } + return mod_manager_register_cmd(&globals.mod_manager, mod, name, description, fn, user); } -static void MOD_CALL -host_cfg_get_int(mod_cfg_handle_t h, int *val) +struct nk_context *MOD_CALL +mod_get_nk_ctx(void) { - if (val) { - *val = mod_cfg_get_int(&globals.mod_manager, h); - } -} - -static void MOD_CALL -host_cfg_get_float(mod_cfg_handle_t h, float *val) -{ - if (val) { - *val = mod_cfg_get_float(&globals.mod_manager, h); - } -} - -static void MOD_CALL -host_cfg_get_enum(mod_cfg_handle_t h, int *val) -{ - if (val) { - *val = mod_cfg_get_enum(&globals.mod_manager, h); - } -} - -static void MOD_CALL -host_cfg_get_string_len(mod_cfg_handle_t h, uint64_t *len) -{ - if (len) { - *len = mod_cfg_get_string_len(&globals.mod_manager, h); - } -} - -static void MOD_CALL -host_cfg_get_string_data(mod_cfg_handle_t h, void *buf, uint64_t cap, uint64_t *written) -{ - uint64_t len = mod_cfg_get_string_data(&globals.mod_manager, h, buf, cap); - if (written) { - *written = len; - } + return globals.ui_manager.ctx; } -static void MOD_CALL -host_cfg_get_keybind(mod_cfg_handle_t h, keybind_t *val) +void MOD_CALL +mod_get_viewport_size(unsigned int *width, unsigned int *height) { - if (val) { - *val = mod_cfg_get_keybind(&globals.mod_manager, h); + if (width) { + *width = globals.ui_manager.vw; } -} - -static void MOD_CALL -host_cfg_get_color(mod_cfg_handle_t h, mod_color_t *val) -{ - if (val) { - *val = mod_cfg_get_color(&globals.mod_manager, h); + if (height) { + *height = globals.ui_manager.vh; } } -static void MOD_CALL -host_cfg_set_bool(mod_cfg_handle_t h, bool val) -{ - mod_cfg_set_bool(&globals.mod_manager, h, val); -} - -static void MOD_CALL -host_cfg_set_int(mod_cfg_handle_t h, int val) -{ - mod_cfg_set_int(&globals.mod_manager, h, val); -} - -static void MOD_CALL -host_cfg_set_float(mod_cfg_handle_t h, float val) -{ - mod_cfg_set_float(&globals.mod_manager, h, val); -} - -static void MOD_CALL -host_cfg_set_enum(mod_cfg_handle_t h, int val) +uint64_t MOD_CALL +mod_get_frame_counter(void) { - mod_cfg_set_enum(&globals.mod_manager, h, val); + return globals.frame_counter; } -static void MOD_CALL -host_cfg_set_string(mod_cfg_handle_t h, str_t val) +float MOD_CALL +mod_get_fps(void) { - mod_cfg_set_string(&globals.mod_manager, h, val); + return globals.fps; } -static void MOD_CALL -host_cfg_set_keybind(mod_cfg_handle_t h, keybind_t val) +bool MOD_CALL +mod_cfg_get_bool(mod_cfg_handle_t cfg) { - mod_cfg_set_keybind(&globals.mod_manager, h, val); + return mod_manager_cfg_get_bool(&globals.mod_manager, cfg); } -static void MOD_CALL -host_cfg_set_color(mod_cfg_handle_t h, mod_color_t val) +int MOD_CALL +mod_cfg_get_int(mod_cfg_handle_t cfg) { - mod_cfg_set_color(&globals.mod_manager, h, val); + return mod_manager_cfg_get_int(&globals.mod_manager, cfg); } -static mod_arena_handle_t MOD_CALL -host_get_perm(mod_handle_t h) +float MOD_CALL +mod_cfg_get_float(mod_cfg_handle_t cfg) { - return mod_get_perm_arena(&globals.mod_manager, h); + return mod_manager_cfg_get_float(&globals.mod_manager, cfg); } -static mod_arena_handle_t MOD_CALL -host_arena_create(mod_handle_t h, uint64_t reserve_size, uint64_t commit_size) +int MOD_CALL +mod_cfg_get_enum(mod_cfg_handle_t cfg) { - return mod_dll_arena_alloc(&globals.mod_manager, h, reserve_size, commit_size); + return mod_manager_cfg_get_enum(&globals.mod_manager, cfg); } -static void MOD_CALL -host_arena_destroy(mod_handle_t h, mod_arena_handle_t arena_h) +uint64_t MOD_CALL +mod_cfg_get_string_len(mod_cfg_handle_t cfg) { - mod_dll_arena_free(&globals.mod_manager, h, arena_h); + return mod_manager_cfg_get_string_len(&globals.mod_manager, cfg); } -static void *MOD_CALL -host_arena_push(mod_arena_handle_t h, uint64_t size, uint64_t alignment) +uint64_t MOD_CALL +mod_cfg_get_string_data(mod_cfg_handle_t cfg, void *buf, uint64_t cap) { - if (h == MOD_ARENA_HANDLE_INVALID) { - return NULL; - } - - return arena_push_aligned(mod_arena_handle_resolve(h), size, alignment); + return mod_manager_cfg_get_string_data(&globals.mod_manager, cfg, buf, cap); } -static uint64_t MOD_CALL -host_arena_pos(mod_arena_handle_t h) +str_t MOD_CALL +mod_cfg_push_string(mod_cfg_handle_t cfg, mod_arena_handle_t arena) { - if (h == MOD_ARENA_HANDLE_INVALID) { - return 0; + uint64_t len = mod_cfg_get_string_len(cfg); + if (len == 0) { + return STR_NULL; } - return arena_get_used(mod_arena_handle_resolve(h)); -} - -static void MOD_CALL -host_arena_pop_to(mod_arena_handle_t h, uint64_t pos) -{ - if (h == MOD_ARENA_HANDLE_INVALID) { - return; + uint8_t *data = mod_arena_push_zero(arena, len + 1, 1); + if (!data) { + return STR_NULL; } - arena_pop_to(mod_arena_handle_resolve(h), pos); + return str_make(data, mod_cfg_get_string_data(cfg, data, len)); } -static void MOD_CALL -host_arena_reset(mod_arena_handle_t h) +keybind_t MOD_CALL +mod_cfg_get_keybind(mod_cfg_handle_t cfg) { - if (h == MOD_ARENA_HANDLE_INVALID) { - return; - } - - arena_reset(mod_arena_handle_resolve(h)); + return mod_manager_cfg_get_keybind(&globals.mod_manager, cfg); } -static host_tmp_arena_t MOD_CALL -host_scratch_begin(mod_arena_handle_t conflict) +mod_color_t MOD_CALL +mod_cfg_get_color(mod_cfg_handle_t cfg) { - tmp_arena_t tmp = scratch_begin(mod_arena_handle_resolve(conflict)); - return host_tmp_arena_make(tmp); + return mod_manager_cfg_get_color(&globals.mod_manager, cfg); } -static void MOD_CALL -host_scratch_end(host_tmp_arena_t host_tmp) +void MOD_CALL +mod_cfg_set_bool(mod_cfg_handle_t cfg, bool value) { - tmp_arena_t tmp = host_tmp_arena_resolve(host_tmp); - scratch_end(tmp); + mod_manager_cfg_set_bool(&globals.mod_manager, cfg, value); } -static fname_pool_t *MOD_CALL -host_get_name_pool(void) +void MOD_CALL +mod_cfg_set_int(mod_cfg_handle_t cfg, int value) { - return globals.name_pool; + mod_manager_cfg_set_int(&globals.mod_manager, cfg, value); } -static fuobject_array_t *MOD_CALL -host_get_object_array(void) +void MOD_CALL +mod_cfg_set_float(mod_cfg_handle_t cfg, float value) { - return globals.uobjects; + mod_manager_cfg_set_float(&globals.mod_manager, cfg, value); } -static uworld_t **MOD_CALL -host_get_gworld_ptr(void) +void MOD_CALL +mod_cfg_set_enum(mod_cfg_handle_t cfg, int value) { - return globals.gworld_ptr; + mod_manager_cfg_set_enum(&globals.mod_manager, cfg, value); } -static void MOD_CALL -host_process_event(uobject_t *self, ufunc_t *func, void *params) +void MOD_CALL +mod_cfg_set_string(mod_cfg_handle_t cfg, str_t value) { - unreal_process_event(self, func, params); + mod_manager_cfg_set_string(&globals.mod_manager, cfg, value); } -static uclass_t *MOD_CALL -host_static_load_class(uclass_t *base_cls, uobject_t *outer, str_t name, str_t filename, uint32_t load_flags) +void MOD_CALL +mod_cfg_set_keybind(mod_cfg_handle_t cfg, keybind_t value) { - return unreal_static_load_class(base_cls, outer, name, filename, load_flags); + mod_manager_cfg_set_keybind(&globals.mod_manager, cfg, value); } -static bool MOD_CALL -host_mount_pak(str_t file_path, int order) +void MOD_CALL +mod_cfg_set_color(mod_cfg_handle_t cfg, mod_color_t value) { - return unreal_mount_pak(file_path, order); + mod_manager_cfg_set_color(&globals.mod_manager, cfg, value); } -static bool MOD_CALL -host_mount_iostore(str_t file_path, int order) +mod_arena_handle_t MOD_CALL +mod_get_perm(mod_handle_t mod) { - return unreal_mount_iostore(file_path, order); + return mod_get_perm_arena(&globals.mod_manager, mod); } -static fname_t MOD_CALL -host_fname_from_str(str_t str, efind_name_t find_type) +mod_arena_handle_t MOD_CALL +mod_arena_create(mod_handle_t mod, uint64_t reserve_size, uint64_t commit_size) { - return unreal_fname_from_str(str, find_type); + return mod_dll_arena_alloc(&globals.mod_manager, mod, reserve_size, commit_size); } -static uint64_t MOD_CALL -host_fname_utf8_len(fname_t name) +void MOD_CALL +mod_arena_destroy(mod_handle_t mod, mod_arena_handle_t arena) { - return unreal_fname_utf8_len(name); + mod_dll_arena_free(&globals.mod_manager, mod, arena); } -static uint64_t MOD_CALL -host_fname_utf8_write(fname_t name, void *buf, uint64_t cap) +void *MOD_CALL +mod_arena_push(mod_arena_handle_t arena, uint64_t size, uint64_t alignment) { - return unreal_fname_utf8_write(buf, cap, name); + arena_t *resolved = mod_arena_handle_resolve(arena); + return resolved ? arena_push_aligned(resolved, size, alignment) : NULL; } -static void *MOD_CALL -host_get_mcast_sparse_delegate(uobject_t *delegate_owner, fname_t delegate_name) +void *MOD_CALL +mod_arena_push_zero(mod_arena_handle_t arena, uint64_t size, uint64_t alignment) { - return unreal_get_mcast_sparse_delegate(delegate_owner, delegate_name); + arena_t *resolved = mod_arena_handle_resolve(arena); + return resolved ? arena_push_zero_aligned(resolved, size, alignment) : NULL; } -static fnative_func_ptr_t MOD_CALL -host_get_native(uint8_t opcode) +uint64_t MOD_CALL +mod_arena_pos(mod_arena_handle_t arena) { - return unreal_get_native(opcode); + arena_t *resolved = mod_arena_handle_resolve(arena); + return resolved ? arena_get_used(resolved) : 0; } -static input_key_kind_t MOD_CALL -host_input_key_from_str(str_t name) +void MOD_CALL +mod_arena_reset(mod_arena_handle_t arena) { - return input_key_from_str(name); -} - -static str_t MOD_CALL -host_input_key_to_str(input_key_kind_t key) -{ - return input_key_to_str(key); -} - -static str_t MOD_CALL -host_input_event_kind_to_str(input_event_kind_t kind) -{ - return input_event_kind_to_str(kind); -} - -static bool MOD_CALL -host_keybind_parse(str_t str, keybind_t *out) -{ - keybind_t tmp = keybind_parse(str, KEYBIND_NULL); - if (!keybind_is_valid(tmp)) { - return false; + arena_t *resolved = mod_arena_handle_resolve(arena); + if (resolved) { + arena_reset(resolved); } - - if (out) { - *out = tmp; - } - return true; -} - -static uint64_t MOD_CALL -host_keybind_utf8_len(keybind_t bind) -{ - return keybind_utf8_len(bind); -} - -static uint64_t MOD_CALL -host_keybind_utf8_write(keybind_t bind, void *buf, uint64_t cap) -{ - return keybind_utf8_write(bind, buf, cap); -} - -static bool MOD_CALL -host_keybind_is_down(keybind_t bind) -{ - return keybind_is_down(bind); -} - -static bool MOD_CALL -host_keybind_is_pressed(keybind_t bind) -{ - return keybind_is_pressed(bind); -} - -static bool MOD_CALL -host_keybind_is_released(keybind_t bind) -{ - return keybind_is_released(bind); -} - -static bool MOD_CALL -host_register_uobject_listener(mod_handle_t h, uobject_listener_kind_t kind, uobject_on_notify_cb_t notify_cb, void *user) -{ - return mod_dll_uobject_listener_register(&globals.mod_manager, h, kind, notify_cb, user); -} - -static void MOD_CALL -host_deregister_uobject_listener(mod_handle_t h, uobject_listener_kind_t kind, uobject_on_notify_cb_t notify_cb, void *user) -{ - mod_dll_uobject_listener_deregister(&globals.mod_manager, h, kind, notify_cb, user); } -static sigscan_err_t MOD_CALL -host_sigscan(const char *name, const char *pattern, uint8_t op_offset, uint8_t num_deref, uintptr_t first_rvas_to_try[8], void **result) +void MOD_CALL +mod_arena_pop_to(mod_arena_handle_t arena, uint64_t pos) { - sigscan_entry_t entry = { - .name = name, - .pattern = pattern, - .pp = result, - .kind = (op_offset == 0) ? SIG_DIRECT : SIG_RIPREL32_AT, - .op_off = op_offset, - .deref = num_deref, - .addr = NULL, - }; - - if (first_rvas_to_try) { - mem_copy(entry.first_rvas, first_rvas_to_try, sizeof(entry.first_rvas)); + arena_t *resolved = mod_arena_handle_resolve(arena); + if (resolved) { + arena_pop_to(resolved, pos); } - - return sigscan_scan_entry(globals.user_spans, globals.num_user_spans, globals.user_module_base, &entry); -} - -static bool MOD_CALL -host_hook_create(mod_handle_t h, void *target, void *detour, void **original) -{ - return mod_dll_hook_create(&globals.mod_manager, h, target, detour, original); -} - -static bool MOD_CALL -host_hook_enable(mod_handle_t h, void *target) -{ - return mod_dll_hook_enable(&globals.mod_manager, h, target); } -static bool MOD_CALL -host_hook_disable(mod_handle_t h, void *target) +void MOD_CALL +mod_arena_pop(mod_arena_handle_t arena, uint64_t size) { - return mod_dll_hook_disable(&globals.mod_manager, h, target); -} - -static bool MOD_CALL -host_hook_remove(mod_handle_t h, void *target) -{ - return mod_dll_hook_remove(&globals.mod_manager, h, target); -} - -static void MOD_CALL -host_map_add(void *map, void *prop, const void *key, const void *val) -{ - unreal_map_add(map, prop, key, val); + arena_t *resolved = mod_arena_handle_resolve(arena); + if (resolved) { + arena_pop(resolved, size); + } } -static bool MOD_CALL -host_map_remove(void *map, void *prop, const void *key) +mod_tmp_arena_t MOD_CALL +mod_scratch_begin(mod_arena_handle_t conflict) { - return unreal_map_remove(map, prop, key); + return mod_tmp_arena_make(scratch_begin(mod_arena_handle_resolve(conflict))); } -static bool MOD_CALL -host_map_find(void *map, void *prop, const void *key, void *out_val) +void MOD_CALL +mod_scratch_end(mod_tmp_arena_t tmp) { - return unreal_map_find(map, prop, key, out_val); + scratch_end(mod_tmp_arena_resolve(tmp)); } -static uobject_t * MOD_CALL -host_static_load_object(uclass_t *obj_cls, uobject_t *outer, str_t name, str_t filename, uint32_t load_flags, void *sandbox, bool allow_obj_reconcile, void *instancing_ctx) +bool MOD_CALL +mod_register_uobject_listener(mod_handle_t mod, uobject_listener_kind_t kind, uobject_on_notify_cb_t callback, void *user) { - return unreal_static_load_object(obj_cls, outer, name, filename, load_flags, sandbox, allow_obj_reconcile, instancing_ctx); + return mod_dll_uobject_listener_register(&globals.mod_manager, mod, kind, callback, user); } -static uobject_t *MOD_CALL -host_static_construct_object(void *params) +void MOD_CALL +mod_deregister_uobject_listener(mod_handle_t mod, uobject_listener_kind_t kind, uobject_on_notify_cb_t callback, void *user) { - return unreal_static_construct_object(params); + mod_dll_uobject_listener_deregister(&globals.mod_manager, mod, kind, callback, user); } -static bool MOD_CALL -host_add_gameplay_tag(fname_t tag_name) +sigscan_err_t MOD_CALL +mod_sigscan(sigscan_entry_t *entry) { - if (globals.num_custom_tags >= CONFIG_MAX_CUSTOM_GAMEPLAY_TAGS) { - return false; + if (!entry) { + return SIG_ERR_NOT_FOUND; } - - globals.custom_tags[globals.num_custom_tags++].tag_name = tag_name; - return true; + return sigscan_scan_entry(globals.user_spans, globals.num_user_spans, globals.user_module_base, entry); } -static bool MOD_CALL -host_check_gameplay_tag_exists(fname_t tag_name) +bool MOD_CALL +mod_hook_create(mod_handle_t mod, void *target, void *detour, void **original) { - if (unreal_fname_is_none(tag_name)) { - return false; - } - - fgameplay_tag_t tag = unreal_gameplay_tags_manager_request_tag(tag_name); - return !unreal_fname_is_none(tag.tag_name); + return mod_dll_hook_create(&globals.mod_manager, mod, target, detour, original); } -static uint64_t -host_get_frame_counter(void) +bool MOD_CALL +mod_hook_enable(mod_handle_t mod, void *target) { - return globals.frame_counter; + return mod_dll_hook_enable(&globals.mod_manager, mod, target); } -static float -host_get_fps(void) +bool MOD_CALL +mod_hook_disable(mod_handle_t mod, void *target) { - return globals.fps; + return mod_dll_hook_disable(&globals.mod_manager, mod, target); } -static const mod_host_api_t g_host_api = { - .struct_size = sizeof(mod_host_api_t), - .abi_version = MOD_HOST_ABI_VERSION, - - /* MOD */ - - .get_mod_dir = host_get_mod_dir, - .get_config_path = host_get_config_path, - .get_manifest_path = host_get_manifest_path, - .logv = host_logv, - .get_cfg_by_id = host_get_cfg_by_id, - .register_cmd = host_register_cmd, - - /* UI */ - .get_nk_ctx = host_get_nk_ctx, - .get_viewport_size = host_get_viewport_size, - - /* MOD CONFIGURATION */ - - .cfg_get_bool = host_cfg_get_bool, - .cfg_get_int = host_cfg_get_int, - .cfg_get_float = host_cfg_get_float, - .cfg_get_enum = host_cfg_get_enum, - .cfg_get_string_len = host_cfg_get_string_len, - .cfg_get_string_data = host_cfg_get_string_data, - .cfg_get_keybind = host_cfg_get_keybind, - .cfg_get_color = host_cfg_get_color, - .cfg_set_bool = host_cfg_set_bool, - .cfg_set_int = host_cfg_set_int, - .cfg_set_float = host_cfg_set_float, - .cfg_set_enum = host_cfg_set_enum, - .cfg_set_string = host_cfg_set_string, - .cfg_set_keybind = host_cfg_set_keybind, - .cfg_set_color = host_cfg_set_color, - - /* MEMORY ALLOCATION */ - - .get_perm = host_get_perm, - .arena_create = host_arena_create, - .arena_destroy = host_arena_destroy, - .arena_push = host_arena_push, - .arena_pos = host_arena_pos, - .arena_pop_to = host_arena_pop_to, - .arena_reset = host_arena_reset, - .scratch_begin = host_scratch_begin, - .scratch_end = host_scratch_end, - - /* UNREAL ENGINE */ - - .get_name_pool = host_get_name_pool, - .get_object_array = host_get_object_array, - .get_gworld_ptr = host_get_gworld_ptr, - .process_event = host_process_event, - .static_load_class = host_static_load_class, - .mount_pak = host_mount_pak, - .mount_iostore = host_mount_iostore, - .fname_from_str = host_fname_from_str, - .fname_utf8_len = host_fname_utf8_len, - .fname_utf8_write = host_fname_utf8_write, - .get_mcast_sparse_delegate = host_get_mcast_sparse_delegate, - .get_native = host_get_native, - - /* INPUT EVENTS / KEYBINDS */ - - .input_key_from_str = host_input_key_from_str, - .input_key_to_str = host_input_key_to_str, - .input_event_kind_to_str = host_input_event_kind_to_str, - .keybind_parse = host_keybind_parse, - .keybind_utf8_len = host_keybind_utf8_len, - .keybind_utf8_write = host_keybind_utf8_write, - .keybind_is_down = host_keybind_is_down, - .keybind_is_pressed = host_keybind_is_pressed, - .keybind_is_released = host_keybind_is_released, - - /* UOBJECT CREATE/DELETE LISTENERS */ - - .register_uobject_listener = host_register_uobject_listener, - .deregister_uobject_listener = host_deregister_uobject_listener, - - /* HOOKING / SIGNATURE SCANNING */ - .sigscan = host_sigscan, - .hook_create = host_hook_create, - .hook_enable = host_hook_enable, - .hook_disable = host_hook_disable, - .hook_remove = host_hook_remove, - - /* UNREAL ENGINE (CONT.) */ - .map_add = host_map_add, - .map_remove = host_map_remove, - .map_find = host_map_find, - .static_load_object = host_static_load_object, - .static_construct_object = host_static_construct_object, - .add_gameplay_tag = host_add_gameplay_tag, - .check_gameplay_tag_exists = host_check_gameplay_tag_exists, - - .get_frame_counter = host_get_frame_counter, - .get_fps = host_get_fps, -}; - -const mod_host_api_t * -mod_host_api_get(void) -{ - return &g_host_api; +bool MOD_CALL +mod_hook_remove(mod_handle_t mod, void *target) +{ + return mod_dll_hook_remove(&globals.mod_manager, mod, target); } diff --git a/src/mod_manager.c b/src/mod_manager.c index 16aa5ae..c6b2b69 100644 --- a/src/mod_manager.c +++ b/src/mod_manager.c @@ -6,7 +6,7 @@ #include "ini.h" #include "input.h" #include "log.h" -#include "mod_host.h" +#include "mod.h" #include "path.h" #include "scratch.h" #include "sigscan.h" @@ -1451,7 +1451,7 @@ mod_get_options_info(mod_manager_t *manager, mod_handle_t h, mod_option_info_t * } str_t -mod_get_mod_dir(mod_manager_t *manager, mod_handle_t h) +mod_manager_get_mod_dir(mod_manager_t *manager, mod_handle_t h) { if (!manager) { return STR_NULL; @@ -1466,7 +1466,7 @@ mod_get_mod_dir(mod_manager_t *manager, mod_handle_t h) } str_t -mod_get_config_path(mod_manager_t *manager, mod_handle_t h) +mod_manager_get_config_path(mod_manager_t *manager, mod_handle_t h) { if (!manager) { return STR_NULL; @@ -1481,7 +1481,7 @@ mod_get_config_path(mod_manager_t *manager, mod_handle_t h) } str_t -mod_get_manifest_path(mod_manager_t *manager, mod_handle_t h) +mod_manager_get_manifest_path(mod_manager_t *manager, mod_handle_t h) { if (!manager) { return STR_NULL; @@ -1515,7 +1515,7 @@ mod_cfg_get_by_id(mod_manager_t *manager, mod_handle_t h, str_t id) } bool -mod_cfg_get_bool(mod_manager_t *manager, mod_cfg_handle_t h) +mod_manager_cfg_get_bool(mod_manager_t *manager, mod_cfg_handle_t h) { mod_option_runtime_t *opt = mod_cfg_handle_resolve(manager, h); mod_option_info_t *info = mod_option_info_get(manager, h); @@ -1527,7 +1527,7 @@ mod_cfg_get_bool(mod_manager_t *manager, mod_cfg_handle_t h) } int -mod_cfg_get_int(mod_manager_t *manager, mod_cfg_handle_t h) +mod_manager_cfg_get_int(mod_manager_t *manager, mod_cfg_handle_t h) { mod_option_runtime_t *opt = mod_cfg_handle_resolve(manager, h); mod_option_info_t *info = mod_option_info_get(manager, h); @@ -1539,7 +1539,7 @@ mod_cfg_get_int(mod_manager_t *manager, mod_cfg_handle_t h) } float -mod_cfg_get_float(mod_manager_t *manager, mod_cfg_handle_t h) +mod_manager_cfg_get_float(mod_manager_t *manager, mod_cfg_handle_t h) { mod_option_runtime_t *opt = mod_cfg_handle_resolve(manager, h); mod_option_info_t *info = mod_option_info_get(manager, h); @@ -1551,7 +1551,7 @@ mod_cfg_get_float(mod_manager_t *manager, mod_cfg_handle_t h) } int -mod_cfg_get_enum(mod_manager_t *manager, mod_cfg_handle_t h) +mod_manager_cfg_get_enum(mod_manager_t *manager, mod_cfg_handle_t h) { mod_option_runtime_t *opt = mod_cfg_handle_resolve(manager, h); mod_option_info_t *info = mod_option_info_get(manager, h); @@ -1563,7 +1563,7 @@ mod_cfg_get_enum(mod_manager_t *manager, mod_cfg_handle_t h) } uint64_t -mod_cfg_get_string_len(mod_manager_t *manager, mod_cfg_handle_t h) +mod_manager_cfg_get_string_len(mod_manager_t *manager, mod_cfg_handle_t h) { mod_option_runtime_t *opt = mod_cfg_handle_resolve(manager, h); mod_option_info_t *info = mod_option_info_get(manager, h); @@ -1576,7 +1576,7 @@ mod_cfg_get_string_len(mod_manager_t *manager, mod_cfg_handle_t h) } uint64_t -mod_cfg_get_string_data(mod_manager_t *manager, mod_cfg_handle_t h, void *buf, uint64_t cap) +mod_manager_cfg_get_string_data(mod_manager_t *manager, mod_cfg_handle_t h, void *buf, uint64_t cap) { mod_option_runtime_t *opt = mod_cfg_handle_resolve(manager, h); mod_option_info_t *info = mod_option_info_get(manager, h); @@ -1604,7 +1604,7 @@ mod_cfg_get_string(mod_manager_t *manager, mod_cfg_handle_t h, arena_t *arena) } keybind_t -mod_cfg_get_keybind(mod_manager_t *manager, mod_cfg_handle_t h) +mod_manager_cfg_get_keybind(mod_manager_t *manager, mod_cfg_handle_t h) { mod_option_runtime_t *opt = mod_cfg_handle_resolve(manager, h); mod_option_info_t *info = mod_option_info_get(manager, h); @@ -1616,7 +1616,7 @@ mod_cfg_get_keybind(mod_manager_t *manager, mod_cfg_handle_t h) } mod_color_t -mod_cfg_get_color(mod_manager_t *manager, mod_cfg_handle_t h) +mod_manager_cfg_get_color(mod_manager_t *manager, mod_cfg_handle_t h) { mod_option_runtime_t *opt = mod_cfg_handle_resolve(manager, h); mod_option_info_t *info = mod_option_info_get(manager, h); @@ -1628,7 +1628,7 @@ mod_cfg_get_color(mod_manager_t *manager, mod_cfg_handle_t h) } void -mod_cfg_set_bool(mod_manager_t *manager, mod_cfg_handle_t h, bool val) +mod_manager_cfg_set_bool(mod_manager_t *manager, mod_cfg_handle_t h, bool val) { mod_option_runtime_t *opt = mod_cfg_handle_resolve(manager, h); mod_option_info_t *info = mod_option_info_get(manager, h); @@ -1640,7 +1640,7 @@ mod_cfg_set_bool(mod_manager_t *manager, mod_cfg_handle_t h, bool val) } void -mod_cfg_set_int(mod_manager_t *manager, mod_cfg_handle_t h, int val) +mod_manager_cfg_set_int(mod_manager_t *manager, mod_cfg_handle_t h, int val) { mod_option_runtime_t *opt = mod_cfg_handle_resolve(manager, h); mod_option_info_t *info = mod_option_info_get(manager, h); @@ -1653,7 +1653,7 @@ mod_cfg_set_int(mod_manager_t *manager, mod_cfg_handle_t h, int val) } void -mod_cfg_set_float(mod_manager_t *manager, mod_cfg_handle_t h, float val) +mod_manager_cfg_set_float(mod_manager_t *manager, mod_cfg_handle_t h, float val) { mod_option_runtime_t *opt = mod_cfg_handle_resolve(manager, h); mod_option_info_t *info = mod_option_info_get(manager, h); @@ -1665,7 +1665,7 @@ mod_cfg_set_float(mod_manager_t *manager, mod_cfg_handle_t h, float val) } void -mod_cfg_set_enum(mod_manager_t *manager, mod_cfg_handle_t h, int val) +mod_manager_cfg_set_enum(mod_manager_t *manager, mod_cfg_handle_t h, int val) { mod_option_runtime_t *opt = mod_cfg_handle_resolve(manager, h); mod_option_info_t *info = mod_option_info_get(manager, h); @@ -1683,7 +1683,7 @@ mod_cfg_set_enum(mod_manager_t *manager, mod_cfg_handle_t h, int val) } void -mod_cfg_set_string(mod_manager_t *manager, mod_cfg_handle_t h, str_t val) +mod_manager_cfg_set_string(mod_manager_t *manager, mod_cfg_handle_t h, str_t val) { mod_option_runtime_t *opt = mod_cfg_handle_resolve(manager, h); mod_option_info_t *info = mod_option_info_get(manager, h); @@ -1697,7 +1697,7 @@ mod_cfg_set_string(mod_manager_t *manager, mod_cfg_handle_t h, str_t val) } void -mod_cfg_set_keybind(mod_manager_t *manager, mod_cfg_handle_t h, keybind_t bind) +mod_manager_cfg_set_keybind(mod_manager_t *manager, mod_cfg_handle_t h, keybind_t bind) { mod_option_runtime_t *opt = mod_cfg_handle_resolve(manager, h); mod_option_info_t *info = mod_option_info_get(manager, h); @@ -1710,7 +1710,7 @@ mod_cfg_set_keybind(mod_manager_t *manager, mod_cfg_handle_t h, keybind_t bind) } void -mod_cfg_set_color(mod_manager_t *manager, mod_cfg_handle_t h, mod_color_t color) +mod_manager_cfg_set_color(mod_manager_t *manager, mod_cfg_handle_t h, mod_color_t color) { mod_option_runtime_t *opt = mod_cfg_handle_resolve(manager, h); mod_option_info_t *info = mod_option_info_get(manager, h); @@ -2339,6 +2339,344 @@ err_msg_set(err_msg_t *err, str_t msg) mem_copy(err->msg, msg.data, err->len); } +static void +err_msg_append(err_msg_t *err, str_t msg) +{ + if (!err || str_is_empty(msg) || err->len >= (int)sizeof(err->msg)) { + return; + } + + uint64_t available = sizeof(err->msg) - (uint64_t)err->len; + uint64_t written = MIN_VAL(msg.len, available); + mem_copy(err->msg + err->len, msg.data, written); + err->len += (int)written; +} + +static bool +mod_pe_range_is_valid(uint64_t file_size, uint64_t offset, uint64_t size) +{ + return offset <= file_size && size <= file_size - offset; +} + +typedef struct mod_pe_file_s mod_pe_file_t; +struct mod_pe_file_s { + uint8_t *data; + uint64_t size; + IMAGE_FILE_HEADER file_header; + IMAGE_SECTION_HEADER *sections; + uint32_t size_of_headers; + IMAGE_DATA_DIRECTORY import_directory; + bool is_pe64; +}; + +static bool +mod_pe_file_parse(str_t file, mod_pe_file_t *pe) +{ + if (!pe || !file.data || !mod_pe_range_is_valid(file.len, 0, sizeof(IMAGE_DOS_HEADER))) { + return false; + } + + IMAGE_DOS_HEADER dos = {0}; + mem_copy(&dos, file.data, sizeof(dos)); + if (dos.e_magic != IMAGE_DOS_SIGNATURE || dos.e_lfanew < 0) { + return false; + } + + uint64_t nt_offset = (uint64_t)dos.e_lfanew; + if (!mod_pe_range_is_valid(file.len, nt_offset, sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER))) { + return false; + } + + DWORD signature = 0; + mem_copy(&signature, file.data + nt_offset, sizeof(signature)); + if (signature != IMAGE_NT_SIGNATURE) { + return false; + } + + uint64_t file_header_offset = nt_offset + sizeof(signature); + mem_copy(&pe->file_header, file.data + file_header_offset, sizeof(pe->file_header)); + + uint64_t optional_offset = file_header_offset + sizeof(IMAGE_FILE_HEADER); + if (!mod_pe_range_is_valid(file.len, optional_offset, pe->file_header.SizeOfOptionalHeader)) { + return false; + } + + WORD optional_magic = 0; + if (pe->file_header.SizeOfOptionalHeader < sizeof(optional_magic)) { + return false; + } + mem_copy(&optional_magic, file.data + optional_offset, sizeof(optional_magic)); + + if (optional_magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { + IMAGE_OPTIONAL_HEADER64 optional = {0}; + if (pe->file_header.SizeOfOptionalHeader < sizeof(optional)) { + return false; + } + + mem_copy(&optional, file.data + optional_offset, sizeof(optional)); + pe->size_of_headers = optional.SizeOfHeaders; + pe->import_directory = optional.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; + pe->is_pe64 = true; + } else if (optional_magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + IMAGE_OPTIONAL_HEADER32 optional = {0}; + if (pe->file_header.SizeOfOptionalHeader < sizeof(optional)) { + return false; + } + + mem_copy(&optional, file.data + optional_offset, sizeof(optional)); + pe->size_of_headers = optional.SizeOfHeaders; + pe->import_directory = optional.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; + pe->is_pe64 = false; + } else { + return false; + } + + uint64_t sections_offset = optional_offset + pe->file_header.SizeOfOptionalHeader; + uint64_t sections_size = (uint64_t)pe->file_header.NumberOfSections * sizeof(IMAGE_SECTION_HEADER); + if (!mod_pe_range_is_valid(file.len, sections_offset, sections_size)) { + return false; + } + + pe->data = file.data; + pe->size = file.len; + pe->sections = (IMAGE_SECTION_HEADER *)(file.data + sections_offset); + return true; +} + +static uint8_t * +mod_pe_rva_to_ptr(mod_pe_file_t *pe, uint32_t rva, uint64_t required_size, uint64_t *available_out) +{ + if (!pe) { + return NULL; + } + + if (rva < pe->size_of_headers) { + uint64_t available = pe->size - MIN_VAL((uint64_t)rva, pe->size); + if (required_size <= available) { + if (available_out) { + *available_out = available; + } + return pe->data + rva; + } + return NULL; + } + + for (uint16_t i = 0; i < pe->file_header.NumberOfSections; ++i) { + IMAGE_SECTION_HEADER section = {0}; + mem_copy(§ion, &pe->sections[i], sizeof(section)); + + uint64_t section_start = section.VirtualAddress; + uint64_t section_span = MAX_VAL(section.Misc.VirtualSize, section.SizeOfRawData); + uint64_t section_end = section_start + section_span; + if ((uint64_t)rva < section_start || (uint64_t)rva >= section_end) { + continue; + } + + uint64_t delta = (uint64_t)rva - section_start; + if (delta > section.SizeOfRawData) { + return NULL; + } + + uint64_t available = section.SizeOfRawData - delta; + uint64_t offset = (uint64_t)section.PointerToRawData + delta; + if (required_size > available || !mod_pe_range_is_valid(pe->size, offset, available)) { + return NULL; + } + + if (available_out) { + *available_out = available; + } + return pe->data + offset; + } + + return NULL; +} + +static str_t +mod_pe_read_cstr(mod_pe_file_t *pe, uint32_t rva) +{ + uint64_t available = 0; + uint8_t *data = mod_pe_rva_to_ptr(pe, rva, 1, &available); + if (!data) { + return STR_NULL; + } + + uint64_t len = calc_cstr_len_with_cap((const char *)data, available); + if (len == available) { + return STR_NULL; + } + return str_make(data, len); +} + +static bool +mod_pe_check_import(HMODULE overdub, str_t name, err_msg_t *err, bool *header_written) +{ + bool found = false; + tmp_arena_t tmp = scratch_begin(NULL); + { + char *cstr = str_push_cstr(tmp.arena, name); + + found = cstr && GetProcAddress(overdub, cstr) != NULL; + } + scratch_end(tmp); + + if (!found) { + if (!*header_written) { + err_msg_set(err, STR_LIT("Missing Overdub API functions:")); + *header_written = true; + } + err_msg_append(err, STR_LIT("\n ")); + err_msg_append(err, name); + } + return found; +} + +static bool +mod_pe_check_ordinal_import(HMODULE overdub, WORD ordinal, err_msg_t *err, bool *header_written) +{ + if (GetProcAddress(overdub, MAKEINTRESOURCEA(ordinal))) { + return true; + } + + if (!*header_written) { + err_msg_set(err, STR_LIT("Missing Overdub API functions:")); + *header_written = true; + } + + char ordinal_buf[16] = {0}; + str_write_fmt(ordinal_buf, sizeof(ordinal_buf), "\n #%u", ordinal); + err_msg_append(err, str_from_cstr(ordinal_buf)); + return false; +} + +static bool +mod_pe_preflight_overdub_imports(str_t path, err_msg_t *err) +{ + bool ok = false; + bool missing = false; + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t file = file_read_all(path, tmp.arena); + if (!str_is_empty(file)) { + mod_pe_file_t pe = {0}; + if (mod_pe_file_parse(file, &pe)) { + if (pe.import_directory.VirtualAddress != 0 && pe.import_directory.Size != 0) { + HMODULE overdub = NULL; + DWORD flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT; + if (GetModuleHandleExW(flags, (LPCWSTR)(uintptr_t)&mod_pe_preflight_overdub_imports, &overdub)) { + uint64_t descriptor_bytes = 0; + IMAGE_IMPORT_DESCRIPTOR *descriptors = (IMAGE_IMPORT_DESCRIPTOR *)mod_pe_rva_to_ptr(&pe, pe.import_directory.VirtualAddress, sizeof(IMAGE_IMPORT_DESCRIPTOR), &descriptor_bytes); + if (descriptors) { + uint64_t descriptor_count = MIN_VAL(descriptor_bytes, pe.import_directory.Size) / sizeof(IMAGE_IMPORT_DESCRIPTOR); + bool header_written = false; + + ok = true; + for (uint64_t descriptor_idx = 0; descriptor_idx < descriptor_count && ok; ++descriptor_idx) { + IMAGE_IMPORT_DESCRIPTOR descriptor = {0}; + mem_copy(&descriptor, &descriptors[descriptor_idx], sizeof(descriptor)); + + if (descriptor.Name == 0 && descriptor.FirstThunk == 0 && descriptor.OriginalFirstThunk == 0) { + break; + } + + str_t dll_name = mod_pe_read_cstr(&pe, descriptor.Name); + if (str_is_empty(dll_name)) { + err_msg_set(err, STR_LIT("failed to inspect DLL imports: invalid imported DLL name")); + ok = false; + break; + } + + if (!str_equal(dll_name, STR_LIT("overdub.dll"), STR_CMP_FLAG_IGNORE_CASE)) { + continue; + } + + uint32_t thunk_rva = descriptor.OriginalFirstThunk ? descriptor.OriginalFirstThunk : descriptor.FirstThunk; + uint32_t thunk_size = pe.is_pe64 ? sizeof(IMAGE_THUNK_DATA64) : sizeof(IMAGE_THUNK_DATA32); + + for (uint64_t thunk_idx = 0;; ++thunk_idx) { + uint64_t thunk_offset = thunk_idx * thunk_size; + if (thunk_offset > UINT32_MAX || thunk_rva > UINT32_MAX - (uint32_t)thunk_offset) { + err_msg_set(err, STR_LIT("failed to inspect DLL imports: invalid import thunk")); + ok = false; + break; + } + + uint8_t *thunk_ptr = mod_pe_rva_to_ptr(&pe, thunk_rva + (uint32_t)thunk_offset, thunk_size, NULL); + if (!thunk_ptr) { + err_msg_set(err, STR_LIT("failed to inspect DLL imports: invalid import thunk")); + ok = false; + break; + } + + uint64_t thunk_value = 0; + if (pe.is_pe64) { + IMAGE_THUNK_DATA64 thunk = {0}; + mem_copy(&thunk, thunk_ptr, sizeof(thunk)); + thunk_value = thunk.u1.AddressOfData; + } else { + IMAGE_THUNK_DATA32 thunk = {0}; + mem_copy(&thunk, thunk_ptr, sizeof(thunk)); + thunk_value = thunk.u1.AddressOfData; + } + + if (thunk_value == 0) { + break; + } + + bool is_ordinal = pe.is_pe64 ? IMAGE_SNAP_BY_ORDINAL64(thunk_value) : IMAGE_SNAP_BY_ORDINAL32((DWORD)thunk_value); + if (is_ordinal) { + WORD ordinal = pe.is_pe64 ? IMAGE_ORDINAL64(thunk_value) : IMAGE_ORDINAL32((DWORD)thunk_value); + missing |= !mod_pe_check_ordinal_import(overdub, ordinal, err, &header_written); + continue; + } + + if (thunk_value > UINT32_MAX) { + err_msg_set(err, STR_LIT("failed to inspect DLL imports: invalid import name RVA")); + ok = false; + break; + } + + uint32_t name_rva = (uint32_t)thunk_value; + if (name_rva > UINT32_MAX - sizeof(WORD)) { + err_msg_set(err, STR_LIT("failed to inspect DLL imports: invalid import name RVA")); + ok = false; + break; + } + + if (!mod_pe_rva_to_ptr(&pe, name_rva, sizeof(WORD) + 1, NULL)) { + err_msg_set(err, STR_LIT("failed to inspect DLL imports: invalid import name")); + ok = false; + break; + } + + str_t import_name = mod_pe_read_cstr(&pe, name_rva + sizeof(WORD)); + if (str_is_empty(import_name)) { + err_msg_set(err, STR_LIT("failed to inspect DLL imports: invalid import name")); + ok = false; + break; + } + + missing |= !mod_pe_check_import(overdub, import_name, err, &header_written); + } + } + } else { + err_msg_set(err, STR_LIT("failed to inspect DLL imports: invalid import directory")); + } + } else { + err_msg_set(err, STR_LIT("failed to inspect DLL imports: Overdub module not found")); + } + } + } else { + err_msg_set(err, STR_LIT("failed to inspect DLL imports: malformed PE image")); + } + } else { + err_msg_set(err, STR_LIT("failed to inspect DLL imports: could not read file")); + } + } + scratch_end(tmp); + return ok && !missing; +} + bool mod_dll_load(mod_manager_t *manager, mod_handle_t h) { @@ -2378,6 +2716,11 @@ mod_dll_load(mod_manager_t *manager, mod_handle_t h) return false; } + if (!mod_pe_preflight_overdub_imports(m->manifest.dll.path, &m->dll.err_msg)) { + m->dll.err_stage = MOD_DLL_ERROR_LOAD; + return false; + } + HMODULE dll = mod_win32_load_library(m->manifest.dll.path); if (!dll) { m->dll.err_stage = MOD_DLL_ERROR_LOAD; @@ -2385,7 +2728,24 @@ mod_dll_load(mod_manager_t *manager, mod_handle_t h) return false; } - FARPROC entry_proc = mod_win32_get_proc(dll, MOD_DLL_ENTRY_EXPORT); + FARPROC abi_version_proc = mod_win32_get_proc(dll, MOD_ABI_VERSION_EXPORT); + if (!abi_version_proc) { + mod_win32_free_library(dll); + m->dll.err_stage = MOD_DLL_ERROR_LOAD; + err_msg_set(&m->dll.err_msg, STR_LIT("missing mod_abi_version export")); + return false; + } + + mod_abi_version_fn_t mod_abi_version = (mod_abi_version_fn_t)(uintptr_t)abi_version_proc; + mod_version_t abi_version = mod_abi_version(); + if (!mod_abi_compatible(MOD_ABI_VERSION, abi_version)) { + mod_win32_free_library(dll); + m->dll.err_stage = MOD_DLL_ERROR_LOAD; + err_msg_set(&m->dll.err_msg, STR_LIT("incompatible ABI version")); + return false; + } + + FARPROC entry_proc = mod_win32_get_proc(dll, MOD_ENTRY_EXPORT); if (!entry_proc) { mod_win32_free_library(dll); m->dll.err_stage = MOD_DLL_ERROR_LOAD; @@ -2393,9 +2753,8 @@ mod_dll_load(mod_manager_t *manager, mod_handle_t h) return false; } - mod_entry_fn_t mod_entry = (mod_entry_fn_t)(uintptr_t)entry_proc; - - const mod_api_t *mod_api = mod_entry(); + mod_entry_fn_t mod_entry = (mod_entry_fn_t)(uintptr_t)entry_proc; + const mod_api_t *mod_api = mod_entry(); if (!mod_api) { mod_win32_free_library(dll); m->dll.err_stage = MOD_DLL_ERROR_LOAD; @@ -2406,7 +2765,6 @@ mod_dll_load(mod_manager_t *manager, mod_handle_t h) #define API_HAS_FIELD(API, NAME) \ ((API)->struct_size >= (offsetof(mod_api_t, NAME) + sizeof((API)->NAME))) - version_t abi_version = API_HAS_FIELD(mod_api, abi_version) ? mod_api->abi_version : (version_t){0}; mod_init_fn_t init = API_HAS_FIELD(mod_api, init) ? mod_api->init : NULL; mod_deinit_fn_t deinit = API_HAS_FIELD(mod_api, deinit) ? mod_api->deinit : NULL; mod_tick_fn_t tick = API_HAS_FIELD(mod_api, tick) ? mod_api->tick : NULL; @@ -2420,13 +2778,6 @@ mod_dll_load(mod_manager_t *manager, mod_handle_t h) #undef API_HAS_FIELD - if (!mod_abi_compatible((version_t)MOD_HOST_ABI_VERSION, abi_version)) { - mod_win32_free_library(dll); - m->dll.err_stage = MOD_DLL_ERROR_LOAD; - err_msg_set(&m->dll.err_msg, STR_LIT("incompatible ABI version")); - return false; - } - m->dll.dll_handle = dll; m->dll.state = MOD_DLL_STATE_LOADED; m->dll.perm = arena_new_dynamic(CONFIG_MOD_CODE_ARENA_SIZE, 64 * KB); @@ -2536,7 +2887,7 @@ mod_dll_start(mod_manager_t *manager, mod_handle_t h) mod_dll_arenas_init_free_list(&m->dll); - if (!m->dll.funcs.init(mod_host_api_get(), mod_handle_make(m))) { + if (!m->dll.funcs.init(mod_handle_make(m))) { mod_cleanup_dll_runtime(m); m->dll.err_stage = MOD_DLL_ERROR_INIT; @@ -3021,7 +3372,7 @@ mod_manager_dispatch_command(mod_manager_t *manager, str_t name, str_t args) } bool -mod_register_cmd(mod_manager_t *manager, mod_handle_t h, str_t name, str_t description, mod_cmd_fn_t cb, void *user) +mod_manager_register_cmd(mod_manager_t *manager, mod_handle_t h, str_t name, str_t description, mod_cmd_fn_t cb, void *user) { if (!cb || str_is_empty(name)) { return false; diff --git a/src/unreal.c b/src/unreal.c index 0d9b06a..53a65ea 100644 --- a/src/unreal.c +++ b/src/unreal.c @@ -19,6 +19,24 @@ TMAP_DEFINE_FUNCS(unreal_tmap_fname_uint8ptr, tmap_fname_uint8ptr_t, fname_t, ui /* ===================================================== FNAME ====================================================== */ +fname_pool_t * +unreal_get_name_pool(void) +{ + return globals.name_pool; +} + +fuobject_array_t * +unreal_get_object_array(void) +{ + return globals.uobjects; +} + +uworld_t * +unreal_get_current_world(void) +{ + return globals.gworld_ptr ? *globals.gworld_ptr : NULL; +} + static inline int u32_count_digits(uint32_t v) { @@ -463,6 +481,22 @@ static uint32_t g_fcrc_table[256] = { 0xAFB010B1, 0xAB710D06, 0xA6322BDF, 0xA2F33668, 0xBCB4666D, 0xB8757BDA, 0xB5365D03, 0xB1F740B4, }; +fstring_t +unreal_fstring_view_from_str16(str16_t s) +{ + return (fstring_t){ + .data = s.data, + .len = (int32_t)s.len, + .max = (int32_t)s.len, + }; +} + +str16_t +unreal_fstring_view_to_str16(fstring_t fs) +{ + return str16_from_wstr_with_cap(fs.data, fs.len); +} + fstring_t unreal_fstring_from_str(str_t s, arena_t *arena) { @@ -1880,6 +1914,28 @@ unreal_udata_table_find_row(udata_table_t *table, fname_t row_name) /* ================================================= GAMEPLAY TAGS ================================================== */ +bool +unreal_add_gameplay_tag(fname_t tag_name) +{ + if (unreal_fname_is_none(tag_name) || globals.num_custom_tags >= CONFIG_MAX_CUSTOM_GAMEPLAY_TAGS) { + return false; + } + + globals.custom_tags[globals.num_custom_tags++].tag_name = tag_name; + return true; +} + +bool +unreal_check_gameplay_tag_exists(fname_t tag_name) +{ + if (unreal_fname_is_none(tag_name)) { + return false; + } + + fgameplay_tag_t tag = unreal_gameplay_tags_manager_request_tag(tag_name); + return !unreal_fname_is_none(tag.tag_name); +} + bool unreal_gameplay_tags_manager_add(fname_t tag_name) { diff --git a/src/vendor.c b/src/vendor.c index f49a2ec..50193cb 100644 --- a/src/vendor.c +++ b/src/vendor.c @@ -19,6 +19,7 @@ #define NK_PROFILE_SCOPE_BEGIN(NAME, SCOPE) PROF_SCOPE_BEGIN(NAME, SCOPE) #define NK_PROFILE_SCOPE_END(SCOPE) PROF_SCOPE_END(SCOPE) +#define NK_API MOD_API #include "nuklear/src/nuklear.c" #include "nk_font_runtime.h" diff --git a/test/test_ui.c b/test/test_ui.c index 7740ab5..04ac7be 100644 --- a/test/test_ui.c +++ b/test/test_ui.c @@ -594,33 +594,114 @@ ui_input_event_from_win32(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam, inpu return false; } +static void +test_input_key_down(input_key_state_t *key) +{ + if (!key->down) { + key->pressed = true; + } + key->down = true; +} + +static void +test_input_key_up(input_key_state_t *key) +{ + if (key->down) { + key->released = true; + } + key->down = false; +} + +static void +test_input_sync_virtual_modifier(input_key_kind_t key) +{ + input_key_kind_t virt, left, right; + + switch (key) { + case INPUT_KEY_LEFT_CTRL: + case INPUT_KEY_RIGHT_CTRL: + virt = INPUT_KEY_CTRL; + left = INPUT_KEY_LEFT_CTRL; + right = INPUT_KEY_RIGHT_CTRL; + break; + + case INPUT_KEY_LEFT_SHIFT: + case INPUT_KEY_RIGHT_SHIFT: + virt = INPUT_KEY_SHIFT; + left = INPUT_KEY_LEFT_SHIFT; + right = INPUT_KEY_RIGHT_SHIFT; + break; + + case INPUT_KEY_LEFT_ALT: + case INPUT_KEY_RIGHT_ALT: + virt = INPUT_KEY_ALT; + left = INPUT_KEY_LEFT_ALT; + right = INPUT_KEY_RIGHT_ALT; + break; + + default: + return; + } + + input_key_state_t *state = &globals.keys[virt]; + bool down = globals.keys[left].down || globals.keys[right].down; + if (down) { + test_input_key_down(state); + } else { + test_input_key_up(state); + } +} + static bool on_input_event(input_event_t *ev) { - globals.keys_down[INPUT_KEY_MOUSE_WHEEL_UP] = false; - globals.keys_down[INPUT_KEY_MOUSE_WHEEL_DOWN] = false; + ASSERT(ev->key < INPUT_KEY_MAX); switch (ev->kind) { case INPUT_EVENT_KEY_DOWN: case INPUT_EVENT_MOUSE_DOWN: - case INPUT_EVENT_MOUSE_DBLCLICK: - globals.keys_down[ev->key] = true; + case INPUT_EVENT_MOUSE_DBLCLICK: { + if (ev->key != INPUT_KEY_NONE) { + test_input_key_down(&globals.keys[ev->key]); + test_input_sync_virtual_modifier(ev->key); + } break; + } + case INPUT_EVENT_KEY_UP: - case INPUT_EVENT_MOUSE_UP: - globals.keys_down[ev->key] = false; + case INPUT_EVENT_MOUSE_UP: { + if (ev->key != INPUT_KEY_NONE) { + test_input_key_up(&globals.keys[ev->key]); + test_input_sync_virtual_modifier(ev->key); + } break; - case INPUT_EVENT_MOUSE_WHEEL: - /* MOUSE_WHEEL_UP or MOUSE_WHEEL_DOWN */ - globals.keys_down[ev->key] = true; + } + + case INPUT_EVENT_MOUSE_WHEEL: { + if (ev->wheel_delta > 0.0f) { + globals.keys[INPUT_KEY_MOUSE_WHEEL_UP].pressed = true; + } else if (ev->wheel_delta < 0.0f) { + globals.keys[INPUT_KEY_MOUSE_WHEEL_DOWN].pressed = true; + } + globals.wheel_delta += ev->wheel_delta; break; - case INPUT_EVENT_APP_ACTIVATION: + } + + case INPUT_EVENT_APP_ACTIVATION: { if (!ev->app_activated) { /* out of focus, all held keys should be released */ - mem_zero(globals.keys_down, sizeof(globals.keys_down)); + input_key_lost_focus(); } break; } + } + + bool force_consume = false; + if ((ev->kind == INPUT_EVENT_KEY_UP || ev->kind == INPUT_EVENT_MOUSE_UP) && + ev->key != INPUT_KEY_NONE && globals.consumed_down[ev->key]) { + globals.consumed_down[ev->key] = false; + force_consume = true; + } bool consumed = false; const char *consumer = "Engine"; @@ -656,7 +737,14 @@ on_input_event(input_event_t *ev) #else (void)consumer; #endif - return consumed; + + if (consumed && + (ev->kind == INPUT_EVENT_KEY_DOWN || ev->kind == INPUT_EVENT_MOUSE_DOWN) && + ev->key != INPUT_KEY_NONE) { + globals.consumed_down[ev->key] = true; + } + + return consumed || force_consume; } static LRESULT CALLBACK @@ -1409,6 +1497,7 @@ main(int argc, char **argv) } mod_manager_start_dlls(&globals.mod_manager); + globals.engine_inited = true; uint64_t frame_time_prev = time_now_us(); int running = 1; @@ -1472,8 +1561,6 @@ main(int argc, char **argv) } ASSERT(SUCCEEDED(hr)); - mem_copy(globals.prev_keys_down, globals.keys_down, sizeof(globals.prev_keys_down)); - scratch_reset(); if (text_profile && globals.frame_counter == 60) { profiler_reset(); @@ -1482,6 +1569,7 @@ main(int argc, char **argv) running = 0; } globals.frame_counter += 1; + input_key_clear_transient_state(); frame_time_prev = frame_time_now; } diff --git a/test/test_ui_signatures.c b/test/test_ui_signatures.c new file mode 100644 index 0000000..a4554c7 --- /dev/null +++ b/test/test_ui_signatures.c @@ -0,0 +1,10 @@ +#include "signatures.h" + +/* TestUI has no game process to scan, so engine entry points stay unavailable */ +#define UE_FUNC_NORMAL(NAME, RET, ...) \ + NAME##_fn_t NAME = NULL; +#define UE_FUNC_HOOKED(NAME, RET, ...) \ + NAME##_fn_t NAME = NULL; \ + NAME##_fn_t NAME##_real = NULL; + +#include "unreal_funcs.inc" From d13211566ac1015825f7e83e7fa018aaa7da1601 Mon Sep 17 00:00:00 2001 From: akmubi Date: Sat, 29 Aug 2026 04:05:15 +0500 Subject: [PATCH 5/9] add out-of-tree mod project build --- docs/MOD_DEVELOPMENT.md | 18 ++++++++++++++++++ mod/Makefile | 39 +++++++++++++++++++++++++++++++++------ mod/mod.vcxproj | 30 ++++++++++++++++++++++++++---- mod/mod.vcxproj.filters | 2 +- 4 files changed, 78 insertions(+), 11 deletions(-) diff --git a/docs/MOD_DEVELOPMENT.md b/docs/MOD_DEVELOPMENT.md index c727419..522621c 100644 --- a/docs/MOD_DEVELOPMENT.md +++ b/docs/MOD_DEVELOPMENT.md @@ -168,6 +168,24 @@ mod/build//example.dll A mod project should use the matching public headers from `include/` and link `build/overdub.lib`. +### Building a mod outside the Overdub repository + +The Makefile and Visual Studio project accept an Overdub source-tree location (so the mod does not need to be inside this repository). Point both include lookup and import-library lookup at the matching Overdub build with one setting. + +Make: +```sh +make OVERDUB_DIR=/path/to/overdub CONFIG=release MOD_NAME=example +``` + +MSBuild: +```batch +msbuild mod.vcxproj /p:OverdubDir=C:\path\to\overdub /p:Configuration=Release /p:Platform=x64 /p:ModName=example +``` + +For multiple mod projects, set the `OVERDUB_DIR` environment variable once instead. The Makefile reads it directly, and `mod.vcxproj` uses it when `OverdubDir` was not supplied as an MSBuild property. If neither setting is present, the included in-repository templates continue to default to `..`. + +If `build/overdub.lib` is missing, the mod build automatically builds Overdub first with the same Debug or Release configuration. An invalid `OVERDUB_DIR` or a failed Overdub build stops the mod build with an explicit error. + ## 4. Minimal Native Mod ```c diff --git a/mod/Makefile b/mod/Makefile index f406500..bfad42b 100644 --- a/mod/Makefile +++ b/mod/Makefile @@ -6,12 +6,21 @@ # make MOD_NAME=tweaks MOD_SRC=tweaks.c # make MOD_NAME=tweaks MOD_SRC=tweaks.cpp # make CONFIG=release MOD_NAME=tweaks MOD_SRC=tweaks.cpp +# make OVERDUB_DIR=/path/to/overdub MOD_NAME=tweaks MOD_SRC=tweaks.c # make clean MOD_NAME ?= mod MOD_SRC ?= main.c CONFIG ?= debug +# Set this on the command line or in the environment for an out-of-tree mod. +OVERDUB_DIR ?= .. +OVERDUB_INCLUDE_DIR ?= $(OVERDUB_DIR)/include +OVERDUB_VENDOR_DIR ?= $(OVERDUB_DIR)/vendor +OVERDUB_HEADER ?= $(OVERDUB_INCLUDE_DIR)/mod.h +OVERDUB_LIB ?= $(OVERDUB_DIR)/build/overdub.lib +OVERDUB_MAKEFILE ?= $(OVERDUB_DIR)/Makefile + ifeq ($(origin CC), default) ifeq ($(OS),Windows_NT) CC := gcc @@ -36,10 +45,8 @@ OBJS := $(patsubst %.c,$(BUILD_DIR)/%.o,$(filter %.c,$(SRCS))) \ $(patsubst %.cpp,$(BUILD_DIR)/%.o,$(filter %.cpp,$(SRCS))) DEPS := $(OBJS:.o=.d) -OVERDUB_LIB := ../build/overdub.lib - COMMON_WARNINGS := -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -COMMON_FLAGS := $(COMMON_WARNINGS) -I../include -I../vendor -ffunction-sections -fdata-sections -MMD -MP +COMMON_FLAGS := $(COMMON_WARNINGS) -I"$(OVERDUB_INCLUDE_DIR)" -I"$(OVERDUB_VENDOR_DIR)" -ffunction-sections -fdata-sections -MMD -MP CFLAGS := -std=c11 $(COMMON_FLAGS) CXXFLAGS := -std=c++20 $(COMMON_FLAGS) @@ -59,17 +66,37 @@ LDFLAGS := -shared -static -static-libgcc -static-libstdc++ \ -Wl,--exclude-all-symbols \ -Wl,--out-implib,$(BUILD_DIR)/lib$(MOD_NAME).a -LDLIBS := $(OVERDUB_LIB) +LDLIBS := "$(OVERDUB_LIB)" LINKER := $(if $(filter %.cpp,$(SRCS)),$(CXX),$(CC)) -.PHONY: all clean +.PHONY: all check-overdub clean all: $(TARGET) -$(TARGET): $(OBJS) $(OVERDUB_LIB) +check-overdub: + @if [ ! -f "$(OVERDUB_HEADER)" ]; then \ + printf "ERROR\t%s\n" "$(OVERDUB_HEADER) is missing. Set OVERDUB_DIR to the Overdub source directory."; \ + exit 1; \ + fi + @if [ ! -f "$(OVERDUB_LIB)" ]; then \ + if [ ! -f "$(OVERDUB_MAKEFILE)" ]; then \ + printf "ERROR\t%s\n" "$(OVERDUB_LIB) is missing and $(OVERDUB_MAKEFILE) was not found. Cannot build Overdub automatically."; \ + exit 1; \ + fi; \ + printf "BUILD\t%s\n" "$(OVERDUB_LIB) is missing; building Overdub ($(CONFIG))."; \ + $(MAKE) -C "$(OVERDUB_DIR)" "$(CONFIG)" || exit 1; \ + fi + @if [ ! -f "$(OVERDUB_LIB)" ]; then \ + printf "ERROR\t%s\n" "The Overdub build completed without producing $(OVERDUB_LIB)."; \ + exit 1; \ + fi + +$(TARGET): $(OBJS) | check-overdub @mkdir -p $(@D) $(LINKER) $(OBJS) $(LDFLAGS) $(LDLIBS) -o $@ +$(OBJS): | check-overdub + $(BUILD_DIR)/%.o: %.c @mkdir -p $(@D) $(CC) $(CFLAGS) -c $< -o $@ diff --git a/mod/mod.vcxproj b/mod/mod.vcxproj index 685f145..884d7ba 100644 --- a/mod/mod.vcxproj +++ b/mod/mod.vcxproj @@ -57,6 +57,12 @@ mod + $(OVERDUB_DIR) + $(ProjectDir).. + $(OverdubDir)\include + $(OverdubDir)\vendor + $(OverdubDir)\build\overdub.lib + $(OverdubDir)\overdub.vcxproj $(ProjectDir)build\$(Configuration)\ $(ProjectDir)build\obj\$(Configuration)\ $(ModName) @@ -74,13 +80,12 @@ true NotUsing WIN32_LEAN_AND_MEAN;NOMINMAX;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - $(ProjectDir)..\include;$(ProjectDir)..\vendor;%(AdditionalIncludeDirectories) + $(OverdubIncludeDirectory);$(OverdubVendorDirectory);%(AdditionalIncludeDirectories) /utf-8 %(AdditionalOptions) Windows - overdub.lib;%(AdditionalDependencies) - $(ProjectDir)..\build;%(AdditionalLibraryDirectories) + $(OverdubImportLibrary);%(AdditionalDependencies) $(IntDir)$(TargetName).lib true true @@ -125,9 +130,26 @@ - + + + + + + + + + diff --git a/mod/mod.vcxproj.filters b/mod/mod.vcxproj.filters index 60cba7b..8cf2d3e 100644 --- a/mod/mod.vcxproj.filters +++ b/mod/mod.vcxproj.filters @@ -12,7 +12,7 @@ - + Mod From 8c697f4404d2c03e7dd6331e33ad3360ea5d8a1e Mon Sep 17 00:00:00 2001 From: akmubi Date: Sat, 29 Aug 2026 04:48:01 +0500 Subject: [PATCH 6/9] remove mod_tmp_arena_t, mod_arena_t --- include/mod.h | 33 +++---------- include/mod_manager.h | 11 ++--- src/builtin/tweaks.c | 2 +- src/builtin/ufunction_call.c | 4 +- src/builtin/ufunction_tracer.c | 2 +- src/builtin/uobject_search.c | 8 ++-- src/mod_host.c | 88 ++-------------------------------- src/mod_manager.c | 36 +++++--------- 8 files changed, 33 insertions(+), 151 deletions(-) diff --git a/include/mod.h b/include/mod.h index cd9d6ba..5f5d1fa 100644 --- a/include/mod.h +++ b/include/mod.h @@ -13,12 +13,10 @@ MOD_EXTERN_C_BEGIN typedef uint64_t mod_handle_t; typedef uint64_t mod_cfg_handle_t; -typedef uint64_t mod_arena_handle_t; typedef version_t mod_version_t; -#define MOD_HANDLE_INVALID ((mod_handle_t)0) -#define MOD_CFG_HANDLE_INVALID ((mod_cfg_handle_t)0) -#define MOD_ARENA_HANDLE_INVALID ((mod_arena_handle_t)0) +#define MOD_HANDLE_INVALID ((mod_handle_t)0) +#define MOD_CFG_HANDLE_INVALID ((mod_cfg_handle_t)0) #define MOD_ABI_VERSION ((mod_version_t)MAKE_VERSION(2, 0, 0)) @@ -33,22 +31,11 @@ typedef version_t mod_version_t; #define MOD_LOG_INFO(MOD, ...) mod_log((MOD), LOG_LEVEL_INFO, __VA_ARGS__) #define MOD_LOG_DEBUG(MOD, ...) mod_log((MOD), LOG_LEVEL_DEBUG, __VA_ARGS__) -#define MOD_ARENA_PUSH_ARRAY(ARENA, T, N) (T *)mod_arena_push((ARENA), (N) * sizeof(T), ALIGNOF(T)) -#define MOD_ARENA_PUSH_ARRAY_ZERO(ARENA, T, N) (T *)mod_arena_push_zero((ARENA), (N) * sizeof(T), ALIGNOF(T)) -#define MOD_ARENA_PUSH(ARENA, T) MOD_ARENA_PUSH_ARRAY((ARENA), T, 1) -#define MOD_ARENA_PUSH_ZERO(ARENA, T) MOD_ARENA_PUSH_ARRAY_ZERO((ARENA), T, 1) - typedef struct mod_color_s mod_color_t; struct mod_color_s { uint8_t r, g, b, a; }; -typedef struct mod_tmp_arena_s mod_tmp_arena_t; -struct mod_tmp_arena_s { - mod_arena_handle_t arena; - uint64_t pos; -}; - struct nk_context; typedef void (MOD_CALL *mod_tick_fn_t) (mod_handle_t mod, float delta); @@ -107,7 +94,7 @@ MOD_API float mod_cfg_get_float(mod_cfg_handle_t cfg); MOD_API int mod_cfg_get_enum(mod_cfg_handle_t cfg); MOD_API uint64_t mod_cfg_get_string_len(mod_cfg_handle_t cfg); MOD_API uint64_t mod_cfg_get_string_data(mod_cfg_handle_t cfg, void *buf, uint64_t cap); -MOD_API str_t mod_cfg_push_string(mod_cfg_handle_t cfg, mod_arena_handle_t arena); +MOD_API str_t mod_cfg_push_string(mod_cfg_handle_t cfg, arena_t *arena); MOD_API keybind_t mod_cfg_get_keybind(mod_cfg_handle_t cfg); MOD_API mod_color_t mod_cfg_get_color(mod_cfg_handle_t cfg); MOD_API void mod_cfg_set_bool(mod_cfg_handle_t cfg, bool value); @@ -119,17 +106,9 @@ MOD_API void mod_cfg_set_keybind(mod_cfg_handle_t cfg, keybind_t value); MOD_API void mod_cfg_set_color(mod_cfg_handle_t cfg, mod_color_t value); /* Manager-owned arenas */ -MOD_API mod_arena_handle_t mod_get_perm(mod_handle_t mod); -MOD_API mod_arena_handle_t mod_arena_create(mod_handle_t mod, uint64_t reserve_size, uint64_t commit_size); -MOD_API void mod_arena_destroy(mod_handle_t mod, mod_arena_handle_t arena); -MOD_API void *mod_arena_push(mod_arena_handle_t arena, uint64_t size, uint64_t alignment); -MOD_API void *mod_arena_push_zero(mod_arena_handle_t arena, uint64_t size, uint64_t alignment); -MOD_API uint64_t mod_arena_pos(mod_arena_handle_t arena); -MOD_API void mod_arena_reset(mod_arena_handle_t arena); -MOD_API void mod_arena_pop_to(mod_arena_handle_t arena, uint64_t pos); -MOD_API void mod_arena_pop(mod_arena_handle_t arena, uint64_t size); -MOD_API mod_tmp_arena_t mod_scratch_begin(mod_arena_handle_t conflict); -MOD_API void mod_scratch_end(mod_tmp_arena_t tmp); +MOD_API arena_t *mod_get_perm(mod_handle_t mod); +MOD_API arena_t *mod_arena_create(mod_handle_t mod, uint64_t reserve_size, uint64_t commit_size); +MOD_API void mod_arena_destroy(mod_handle_t mod, arena_t *arena); /* Manager-owned engine listeners and native hooks */ MOD_API bool mod_register_uobject_listener(mod_handle_t mod, uobject_listener_kind_t kind, uobject_on_notify_cb_t callback, void *user); diff --git a/include/mod_manager.h b/include/mod_manager.h index 3a3c4ef..bc13bbb 100644 --- a/include/mod_manager.h +++ b/include/mod_manager.h @@ -434,7 +434,7 @@ str_t mod_manager_get_config_path(mod_manager_t *manager, mod_handle_t h); str_t mod_manager_get_manifest_path(mod_manager_t *manager, mod_handle_t h); -mod_arena_handle_t +arena_t * mod_get_perm_arena(mod_manager_t *manager, mod_handle_t h); mod_handle_t @@ -484,10 +484,10 @@ mod_dll_uobject_listener_register(mod_manager_t *manager, mod_handle_t h, uobjec void mod_dll_uobject_listener_deregister(mod_manager_t *manager, mod_handle_t h, uobject_listener_kind_t kind, uobject_on_notify_cb_t notify_cb, void *user); -mod_arena_handle_t +arena_t * mod_dll_arena_alloc(mod_manager_t *manager, mod_handle_t h, uint64_t reserve_size, uint64_t commit_size); bool -mod_dll_arena_free(mod_manager_t *manager, mod_handle_t h, mod_arena_handle_t arena_h); +mod_dll_arena_free(mod_manager_t *manager, mod_handle_t h, arena_t *arena); void mod_manager_dispatch_tick(mod_manager_t *manager, float delta); @@ -569,11 +569,6 @@ mod_cfg_handle_make(mod_option_runtime_t *rt); mod_option_runtime_t * mod_cfg_handle_resolve(mod_manager_t *manager, mod_cfg_handle_t h); -mod_arena_handle_t -mod_arena_handle_make(arena_t *arena); -arena_t * -mod_arena_handle_resolve(mod_arena_handle_t h); - void mod_manager_apply_order_from_config(mod_manager_t *manager, str_array_t mod_order_ids); bool diff --git a/src/builtin/tweaks.c b/src/builtin/tweaks.c index ae3c9ae..01fdbfd 100644 --- a/src/builtin/tweaks.c +++ b/src/builtin/tweaks.c @@ -330,7 +330,7 @@ tweaks_init(mod_handle_t h) tweaks_t *tweaks = &g_tweaks; mem_zero(tweaks, sizeof(*tweaks)); - tweaks->perm = mod_arena_handle_resolve(mod_get_perm(h)); + tweaks->perm = mod_get_perm(h); ASSERT(tweaks->perm != NULL); tweaks->cfg.disable_tutorials_h = mod_cfg_get_by_id(&globals.mod_manager, h, STR_LIT(CFG_DISABLE_TUTORIALS)); diff --git a/src/builtin/ufunction_call.c b/src/builtin/ufunction_call.c index 750e9b9..03aaa8e 100644 --- a/src/builtin/ufunction_call.c +++ b/src/builtin/ufunction_call.c @@ -1088,8 +1088,8 @@ ufunc_call_init(search_tool_t *tool, mod_handle_t h) return false; } - dialog->model_arena = mod_arena_handle_resolve(mod_arena_create(h, 32 * MB, 64 * KB)); - dialog->result_arena = mod_arena_handle_resolve(mod_arena_create(h, 32 * MB, 64 * KB)); + dialog->model_arena = mod_arena_create(h, 32 * MB, 64 * KB); + dialog->result_arena = mod_arena_create(h, 32 * MB, 64 * KB); dialog->picker.slots = ARENA_PUSH_ARRAY(tool->perm, uint32_t, tool->cache.record_cap); dialog->func_slot = RECORD_SLOT_INVALID; call_object_ref_set_none(&dialog->target); diff --git a/src/builtin/ufunction_tracer.c b/src/builtin/ufunction_tracer.c index 1d5c1b4..113fb07 100644 --- a/src/builtin/ufunction_tracer.c +++ b/src/builtin/ufunction_tracer.c @@ -1284,7 +1284,7 @@ trace_init(mod_handle_t h) trace_tool_t *tool = &g_trace_tool; mem_zero(tool, sizeof(*tool)); - tool->perm = mod_arena_handle_resolve(mod_get_perm_arena(&globals.mod_manager, h)); + tool->perm = mod_get_perm_arena(&globals.mod_manager, h); tool->cfg.max_calls_h = mod_cfg_get_by_id(&globals.mod_manager, h, STR_LIT(CFG_MAX_CALLS_ID)); tool->cfg.open_window_h = mod_cfg_get_by_id(&globals.mod_manager, h, STR_LIT(CFG_OPEN_WINDOW_ID)); tool->cfg.page_size_h = mod_cfg_get_by_id(&globals.mod_manager, h, STR_LIT(CFG_PAGE_SIZE_ID)); diff --git a/src/builtin/uobject_search.c b/src/builtin/uobject_search.c index dfb45b6..a18428e 100644 --- a/src/builtin/uobject_search.c +++ b/src/builtin/uobject_search.c @@ -484,7 +484,7 @@ tool_init(mod_handle_t h) search_tool_t *tool = &g_tool; mem_zero(tool, sizeof(*tool)); - tool->perm = mod_arena_handle_resolve(mod_get_perm_arena(&globals.mod_manager, h)); + tool->perm = mod_get_perm_arena(&globals.mod_manager, h); tool->cache.record_cap = (uint32_t)unreal_uobject_array_capacity(); if (tool->cache.record_cap > 0) { tool->cache.records = ARENA_PUSH_ARRAY_ZERO(tool->perm, record_t, tool->cache.record_cap); @@ -511,7 +511,7 @@ tool_init(mod_handle_t h) tool->cache.build_total = (uint32_t)unreal_uobject_array_count(); tool->cache.world = (globals.gworld_ptr) ? *globals.gworld_ptr : NULL; - arena_t *string_arena = mod_arena_handle_resolve(mod_arena_create(h, 128 * MB, 1 * MB)); + arena_t *string_arena = mod_arena_create(h, 128 * MB, 1 * MB); if (!string_arena) { LOG_ERROR("UObject Search: failed to create the string arena"); return false; @@ -550,8 +550,8 @@ tool_init(mod_handle_t h) tool->details.preview_tab = NULL; for (int i = 0; i < COUNTOF(tool->details.tabs); ++i) { - tool->details.tabs[i].info_arena = mod_arena_handle_resolve(mod_arena_create(h, 64 * MB, 64 * KB)); - tool->details.tabs[i].value_arena = mod_arena_handle_resolve(mod_arena_create(h, 64 * MB, 64 * KB)); + tool->details.tabs[i].info_arena = mod_arena_create(h, 64 * MB, 64 * KB); + tool->details.tabs[i].value_arena = mod_arena_create(h, 64 * MB, 64 * KB); ASSERT(tool->details.tabs[i].info_arena != NULL); ASSERT(tool->details.tabs[i].value_arena != NULL); diff --git a/src/mod_host.c b/src/mod_host.c index 5679236..2cd4c5c 100644 --- a/src/mod_host.c +++ b/src/mod_host.c @@ -11,24 +11,6 @@ #include -static inline mod_tmp_arena_t -mod_tmp_arena_make(tmp_arena_t tmp) -{ - return (mod_tmp_arena_t){ - .arena = mod_arena_handle_make(tmp.arena), - .pos = tmp.pos, - }; -} - -static inline tmp_arena_t -mod_tmp_arena_resolve(mod_tmp_arena_t tmp) -{ - return (tmp_arena_t){ - .arena = mod_arena_handle_resolve(tmp.arena), - .pos = tmp.pos, - }; -} - str_t MOD_CALL mod_get_mod_dir(mod_handle_t mod) { @@ -141,14 +123,14 @@ mod_cfg_get_string_data(mod_cfg_handle_t cfg, void *buf, uint64_t cap) } str_t MOD_CALL -mod_cfg_push_string(mod_cfg_handle_t cfg, mod_arena_handle_t arena) +mod_cfg_push_string(mod_cfg_handle_t cfg, arena_t *arena) { uint64_t len = mod_cfg_get_string_len(cfg); if (len == 0) { return STR_NULL; } - uint8_t *data = mod_arena_push_zero(arena, len + 1, 1); + uint8_t *data = ARENA_PUSH_ARRAY_ZERO(arena, uint8_t, len + 1); if (!data) { return STR_NULL; } @@ -210,84 +192,24 @@ mod_cfg_set_color(mod_cfg_handle_t cfg, mod_color_t value) mod_manager_cfg_set_color(&globals.mod_manager, cfg, value); } -mod_arena_handle_t MOD_CALL +arena_t *MOD_CALL mod_get_perm(mod_handle_t mod) { return mod_get_perm_arena(&globals.mod_manager, mod); } -mod_arena_handle_t MOD_CALL +arena_t *MOD_CALL mod_arena_create(mod_handle_t mod, uint64_t reserve_size, uint64_t commit_size) { return mod_dll_arena_alloc(&globals.mod_manager, mod, reserve_size, commit_size); } void MOD_CALL -mod_arena_destroy(mod_handle_t mod, mod_arena_handle_t arena) +mod_arena_destroy(mod_handle_t mod, arena_t *arena) { mod_dll_arena_free(&globals.mod_manager, mod, arena); } -void *MOD_CALL -mod_arena_push(mod_arena_handle_t arena, uint64_t size, uint64_t alignment) -{ - arena_t *resolved = mod_arena_handle_resolve(arena); - return resolved ? arena_push_aligned(resolved, size, alignment) : NULL; -} - -void *MOD_CALL -mod_arena_push_zero(mod_arena_handle_t arena, uint64_t size, uint64_t alignment) -{ - arena_t *resolved = mod_arena_handle_resolve(arena); - return resolved ? arena_push_zero_aligned(resolved, size, alignment) : NULL; -} - -uint64_t MOD_CALL -mod_arena_pos(mod_arena_handle_t arena) -{ - arena_t *resolved = mod_arena_handle_resolve(arena); - return resolved ? arena_get_used(resolved) : 0; -} - -void MOD_CALL -mod_arena_reset(mod_arena_handle_t arena) -{ - arena_t *resolved = mod_arena_handle_resolve(arena); - if (resolved) { - arena_reset(resolved); - } -} - -void MOD_CALL -mod_arena_pop_to(mod_arena_handle_t arena, uint64_t pos) -{ - arena_t *resolved = mod_arena_handle_resolve(arena); - if (resolved) { - arena_pop_to(resolved, pos); - } -} - -void MOD_CALL -mod_arena_pop(mod_arena_handle_t arena, uint64_t size) -{ - arena_t *resolved = mod_arena_handle_resolve(arena); - if (resolved) { - arena_pop(resolved, size); - } -} - -mod_tmp_arena_t MOD_CALL -mod_scratch_begin(mod_arena_handle_t conflict) -{ - return mod_tmp_arena_make(scratch_begin(mod_arena_handle_resolve(conflict))); -} - -void MOD_CALL -mod_scratch_end(mod_tmp_arena_t tmp) -{ - scratch_end(mod_tmp_arena_resolve(tmp)); -} - bool MOD_CALL mod_register_uobject_listener(mod_handle_t mod, uobject_listener_kind_t kind, uobject_on_notify_cb_t callback, void *user) { diff --git a/src/mod_manager.c b/src/mod_manager.c index c6b2b69..8e97376 100644 --- a/src/mod_manager.c +++ b/src/mod_manager.c @@ -45,18 +45,6 @@ mod_alloc_slot(mod_manager_t *manager, str_t id) return new_slot; } -mod_arena_handle_t -mod_arena_handle_make(arena_t *arena) -{ - return (mod_arena_handle_t)arena; -} - -arena_t * -mod_arena_handle_resolve(mod_arena_handle_t h) -{ - return (arena_t *)h; -} - bool mod_handle_is_valid(mod_manager_t *manager, mod_handle_t h) { @@ -2167,28 +2155,28 @@ mod_dll_uobject_listener_deregister(mod_manager_t *manager, mod_handle_t h, uobj } } -mod_arena_handle_t +arena_t * mod_dll_arena_alloc(mod_manager_t *manager, mod_handle_t h, uint64_t reserve_size, uint64_t commit_size) { mod_t *m = mod_handle_resolve(manager, h); if (!m || !m->has_code) { - return MOD_ARENA_HANDLE_INVALID; + return NULL; } mod_dll_runtime_t *rt = &m->dll; if (rt->state != MOD_DLL_STATE_LOADED) { - return MOD_ARENA_HANDLE_INVALID; + return NULL; } mod_dll_arena_t *slot = rt->arena_first_free; if (!slot) { - return MOD_ARENA_HANDLE_INVALID; + return NULL; } arena_t arena = arena_new_dynamic(reserve_size, commit_size); if (!arena.backing) { - return MOD_ARENA_HANDLE_INVALID; + return NULL; } rt->arena_first_free = slot->next; @@ -2197,19 +2185,17 @@ mod_dll_arena_alloc(mod_manager_t *manager, mod_handle_t h, uint64_t reserve_siz slot->occupied = true; slot->next = NULL; - return mod_arena_handle_make(&slot->arena); + return &slot->arena; } bool -mod_dll_arena_free(mod_manager_t *manager, mod_handle_t h, mod_arena_handle_t arena_h) +mod_dll_arena_free(mod_manager_t *manager, mod_handle_t h, arena_t *arena) { mod_t *m = mod_handle_resolve(manager, h); - if (!m || !m->has_code || !arena_h) { + if (!m || !m->has_code || !arena) { return false; } - arena_t *arena = mod_arena_handle_resolve(arena_h); - for (int i = 0; i < CONFIG_MOD_MAX_ARENAS; ++i) { mod_dll_arena_t *slot = &m->dll.arenas[i]; @@ -3407,16 +3393,16 @@ mod_manager_register_cmd(mod_manager_t *manager, mod_handle_t h, str_t name, str return true; } -mod_arena_handle_t +arena_t * mod_get_perm_arena(mod_manager_t *manager, mod_handle_t h) { mod_t *m = mod_handle_resolve(manager, h); if (!m) { - return MOD_ARENA_HANDLE_INVALID; + return NULL; } ASSERT(m->has_code); - return mod_arena_handle_make(&m->dll.perm); + return &m->dll.perm; } void From 43cf59230e1c2632974971aebc97b81a1473e6fe Mon Sep 17 00:00:00 2001 From: akmubi Date: Sat, 29 Aug 2026 05:05:39 +0500 Subject: [PATCH 7/9] update CD, update mod project template --- .github/workflows/release.yml | 52 +++++++++++++++++++++++++++++++++++ .gitignore | 1 + docs/MOD_DEVELOPMENT.md | 2 ++ mod/Makefile | 12 ++++---- mod/README.md | 23 ++++++++++++++++ mod/compile_flags.txt | 11 ++++++++ mod/mod.vcxproj | 1 + 7 files changed, 97 insertions(+), 5 deletions(-) create mode 100644 mod/README.md create mode 100644 mod/compile_flags.txt diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4be8d40..97e2450 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -59,6 +59,18 @@ jobs: New-Item -ItemType Directory -Force package\epic | Out-Null New-Item -ItemType Directory -Force package\xbox | Out-Null + $templateRoot = "package\mod-template" + $templateDirectories = @( + "$templateRoot\build" + "$templateRoot\docs" + "$templateRoot\include" + "$templateRoot\vendor\kb" + "$templateRoot\vendor\minhook\include" + "$templateRoot\vendor\nuklear\include" + "$templateRoot\vendor\stb" + ) + New-Item -ItemType Directory -Force -Path $templateDirectories | Out-Null + Copy-Item build\overdub.dll package\steam\ Copy-Item bootstrap\XAPOFX1_5.dll package\steam\ @@ -68,6 +80,24 @@ jobs: Copy-Item build\overdub.dll package\xbox\ Copy-Item bootstrap\dsound.dll package\xbox\ + Copy-Item LICENSE "$templateRoot\" + Copy-Item build\overdub.lib "$templateRoot\build\" + Copy-Item docs\MOD_DEVELOPMENT.md "$templateRoot\docs\" + Copy-Item include\* "$templateRoot\include\" -Recurse + Copy-Item mod\main.c "$templateRoot\" + Copy-Item mod\Makefile "$templateRoot\" + Copy-Item mod\mod.vcxproj "$templateRoot\" + Copy-Item mod\mod.vcxproj.filters "$templateRoot\" + Copy-Item mod\README.md "$templateRoot\" + Copy-Item mod\compile_flags.txt "$templateRoot\" + Copy-Item vendor\kb\kb_text_shape.h "$templateRoot\vendor\kb\" + Copy-Item vendor\kb\LICENSE "$templateRoot\vendor\kb\" + Copy-Item vendor\minhook\include\MinHook.h "$templateRoot\vendor\minhook\include\" + Copy-Item vendor\nuklear\include\nuklear.h "$templateRoot\vendor\nuklear\include\" + Copy-Item vendor\nuklear\LICENSE "$templateRoot\vendor\nuklear\" + Copy-Item vendor\stb\stb_sprintf.h "$templateRoot\vendor\stb\" + Copy-Item vendor\stb\LICENSE "$templateRoot\vendor\stb\" + Compress-Archive ` -Path package\steam\* ` -DestinationPath "overdub-$env:VERSION.steam.zip" @@ -80,6 +110,26 @@ jobs: -Path package\xbox\* ` -DestinationPath "overdub-$env:VERSION.xbox.zip" + Compress-Archive ` + -Path "$templateRoot\*" ` + -DestinationPath "overdub-$env:VERSION.mod-template.zip" + + - name: Validate mod template + shell: pwsh + run: | + $templateRoot = (Resolve-Path package\mod-template).Path + $validationRoot = Join-Path (Resolve-Path package).Path "mod-template-validation" + + msbuild "$templateRoot\mod.vcxproj" ` + /m ` + /p:Configuration=Release ` + /p:Platform=x64 ` + /p:ModName=example ` + "/p:OutDir=$validationRoot\out\" ` + "/p:IntDir=$validationRoot\obj\" ` + /p:TreatWarningAsError=true ` + /warnAsError + - name: Upload release assets shell: pwsh env: @@ -89,4 +139,6 @@ jobs: "overdub-$env:VERSION.steam.zip" ` "overdub-$env:VERSION.epic.zip" ` "overdub-$env:VERSION.xbox.zip" ` + "overdub-$env:VERSION.mod-template.zip" ` + "build\overdub.lib" ` --clobber diff --git a/.gitignore b/.gitignore index 3a10559..d8ecc0c 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ tmp *.dll *.out *.txt +!mod/compile_flags.txt *.o *.d *.obj diff --git a/docs/MOD_DEVELOPMENT.md b/docs/MOD_DEVELOPMENT.md index 522621c..8338418 100644 --- a/docs/MOD_DEVELOPMENT.md +++ b/docs/MOD_DEVELOPMENT.md @@ -186,6 +186,8 @@ For multiple mod projects, set the `OVERDUB_DIR` environment variable once inste If `build/overdub.lib` is missing, the mod build automatically builds Overdub first with the same Debug or Release configuration. An invalid `OVERDUB_DIR` or a failed Overdub build stops the mod build with an explicit error. +The mod-template archive attached to each Overdub release is self-contained. Its project root already contains `include/`, `vendor/`, and `build/overdub.lib`, so it builds without `OVERDUB_DIR` or an Overdub source checkout. The same `overdub.lib` is also available as a separate release asset for custom project layouts. + ## 4. Minimal Native Mod ```c diff --git a/mod/Makefile b/mod/Makefile index bfad42b..b47d056 100644 --- a/mod/Makefile +++ b/mod/Makefile @@ -13,13 +13,15 @@ MOD_NAME ?= mod MOD_SRC ?= main.c CONFIG ?= debug -# Set this on the command line or in the environment for an out-of-tree mod. -OVERDUB_DIR ?= .. +# A packaged template keeps the SDK in this directory. The in-repository +# template falls back to the parent Overdub source tree. +OVERDUB_DIR ?= $(if $(wildcard include/mod.h),.,..) OVERDUB_INCLUDE_DIR ?= $(OVERDUB_DIR)/include OVERDUB_VENDOR_DIR ?= $(OVERDUB_DIR)/vendor OVERDUB_HEADER ?= $(OVERDUB_INCLUDE_DIR)/mod.h OVERDUB_LIB ?= $(OVERDUB_DIR)/build/overdub.lib OVERDUB_MAKEFILE ?= $(OVERDUB_DIR)/Makefile +OVERDUB_PROJECT ?= $(OVERDUB_DIR)/overdub.vcxproj ifeq ($(origin CC), default) ifeq ($(OS),Windows_NT) @@ -79,8 +81,8 @@ check-overdub: exit 1; \ fi @if [ ! -f "$(OVERDUB_LIB)" ]; then \ - if [ ! -f "$(OVERDUB_MAKEFILE)" ]; then \ - printf "ERROR\t%s\n" "$(OVERDUB_LIB) is missing and $(OVERDUB_MAKEFILE) was not found. Cannot build Overdub automatically."; \ + if [ ! -f "$(OVERDUB_MAKEFILE)" ] || [ ! -f "$(OVERDUB_PROJECT)" ]; then \ + printf "ERROR\t%s\n" "$(OVERDUB_LIB) is missing and $(OVERDUB_DIR) is not an Overdub source tree. Cannot build Overdub automatically."; \ exit 1; \ fi; \ printf "BUILD\t%s\n" "$(OVERDUB_LIB) is missing; building Overdub ($(CONFIG))."; \ @@ -106,6 +108,6 @@ $(BUILD_DIR)/%.o: %.cpp $(CXX) $(CXXFLAGS) -c $< -o $@ clean: - rm -rf build + rm -rf build/debug build/release -include $(DEPS) diff --git a/mod/README.md b/mod/README.md new file mode 100644 index 0000000..f9de829 --- /dev/null +++ b/mod/README.md @@ -0,0 +1,23 @@ +# Overdub Mod Template + +This directory contains a minimal native Overdub mod and its matching SDK. +`include/`, `vendor/`, and `build/overdub.lib` are contained in this project, +so no Overdub source checkout or `OverdubDir` setting is required. + +Build with Visual Studio 2022: + +```batch +msbuild mod.vcxproj /m /p:Configuration=Release /p:Platform=x64 /p:ModName=example +``` + +Or build from an MSYS2 MinGW64 shell: + +```sh +make CONFIG=release MOD_NAME=example +``` + +The DLL is written below `build/`. Copy the DLL into the native mod package +described by `docs/MOD_DEVELOPMENT.md`. + +Keep the headers and `overdub.lib` from the same Overdub release. The mod DLL +imports its SDK functions from `overdub.dll`; it does not contain a static SDK. diff --git a/mod/compile_flags.txt b/mod/compile_flags.txt new file mode 100644 index 0000000..0a0d2d7 --- /dev/null +++ b/mod/compile_flags.txt @@ -0,0 +1,11 @@ +-Iinclude +-Ivendor +-I../include +-I../vendor +-xc +-std=c11 +-fms-extensions +-DWIN32_LEAN_AND_MEAN +-DNOMINMAX +-D_CRT_SECURE_NO_WARNINGS +-DBUILD_DEBUG diff --git a/mod/mod.vcxproj b/mod/mod.vcxproj index 884d7ba..831188c 100644 --- a/mod/mod.vcxproj +++ b/mod/mod.vcxproj @@ -58,6 +58,7 @@ mod $(OVERDUB_DIR) + $(ProjectDir) $(ProjectDir).. $(OverdubDir)\include $(OverdubDir)\vendor From 7ad4657d091e4f4a23f743d150dff64525d582b9 Mon Sep 17 00:00:00 2001 From: akmubi Date: Sat, 29 Aug 2026 05:11:19 +0500 Subject: [PATCH 8/9] fix CI --- include/vendor_nuklear.h | 2 +- src/vendor.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/vendor_nuklear.h b/include/vendor_nuklear.h index c4770ef..e59d15e 100644 --- a/include/vendor_nuklear.h +++ b/include/vendor_nuklear.h @@ -11,7 +11,7 @@ #endif #ifndef NK_API -# define NK_API MOD_API +# define NK_API extern MOD_API #endif #include "nuklear/include/nuklear.h" diff --git a/src/vendor.c b/src/vendor.c index 50193cb..ff2bae1 100644 --- a/src/vendor.c +++ b/src/vendor.c @@ -19,7 +19,7 @@ #define NK_PROFILE_SCOPE_BEGIN(NAME, SCOPE) PROF_SCOPE_BEGIN(NAME, SCOPE) #define NK_PROFILE_SCOPE_END(SCOPE) PROF_SCOPE_END(SCOPE) -#define NK_API MOD_API +#define NK_API extern MOD_API #include "nuklear/src/nuklear.c" #include "nk_font_runtime.h" From 15b03bb656a9082dbeffc4ee2656418f1530abfa Mon Sep 17 00:00:00 2001 From: akmubi Date: Sat, 29 Aug 2026 08:36:04 +0500 Subject: [PATCH 9/9] add lua API and more - add ufunction call dialog - refactor logger - add ufunction tracer params - add custom class creation - remove tests, add documentation - fix issues --- .editorconfig | 10 + .gitattributes | 13 + .github/workflows/release.yml | 2 + Makefile | 88 +- README.md | 223 +- docs/INSTALLATION.md | 46 + docs/MOD_DEVELOPMENT.md | 859 +- docs/TROUBLESHOOTING.md | 47 + docs/USING_OVERDUB.md | 84 + docs/lua/Overdub.lua | 69 + docs/lua/Types.lua | 834 + docs/lua/c-modules.md | 162 + docs/lua/overdub-runtime.md | 181 + docs/lua/overdub/input.lua | 52 + docs/lua/overdub/task.lua | 76 + docs/lua/overdub/ui.lua | 200 + docs/lua/overdub/unreal.lua | 674 + docs/lua/tasks.md | 156 + docs/lua/ue4ss-runtime.md | 73 + docs/lua/ui.md | 134 + docs/lua/unreal.md | 299 + docs/mod-development/architecture.md | 59 + docs/mod-development/building-native-mods.md | 82 + docs/mod-development/caveats.md | 59 + docs/mod-development/native-sdk.md | 264 + docs/mod-development/package-format.md | 138 + docs/mod-development/unreal.md | 231 + include/config.h | 52 +- include/globals.h | 1 + include/input.h | 2 + include/log.h | 17 + include/lua_mod_runtime.h | 48 + include/lua_overdub.h | 42 + include/lua_overdub_input.h | 14 + include/lua_overdub_runtime.h | 48 + include/lua_overdub_task.h | 26 + include/lua_overdub_ui.h | 27 + include/lua_overdub_unreal.h | 44 + include/lua_overdub_worker.h | 41 + include/lua_runtime.h | 21 +- include/lua_serial.h | 21 + include/lua_ue4ss.h | 153 + include/lua_ue4ss_runtime.h | 34 + include/lua_unreal_prop.h | 114 + include/mod.h | 2 + include/mod_manager.h | 54 + include/overdub_lua.h | 40 + include/types.h | 8 +- include/ui_console.h | 25 +- include/ui_mod_manager.h | 4 + include/ui_nuklear.h | 11 +- include/unreal.h | 131 +- include/unreal_funcs.inc | 6 + include/unreal_prop.h | 68 +- include/unreal_reflect.h | 145 + mod/README.md | 26 +- mod/mod.vcxproj.user | 2 +- overdub.sln | 3 - overdub.vcxproj | 220 +- overdub.vcxproj.user | 2 +- src/builtin/details_panel.c | 363 +- src/builtin/ufunction_call.c | 1120 +- src/builtin/ufunction_tracer.c | 510 +- src/builtin/uobject_search_internal.h | 2 + src/input.c | 6 + src/log.c | 903 +- src/lua_mod_runtime.c | 265 + src/lua_overdub.c | 624 + src/lua_overdub_input.c | 219 + src/lua_overdub_runtime.c | 656 + src/lua_overdub_task.c | 994 + src/lua_overdub_ui.c | 1867 ++ src/lua_overdub_unreal.c | 3547 +++ src/lua_overdub_worker.c | 415 + src/lua_runtime.c | 437 +- src/lua_serial.c | 397 + src/lua_ue4ss.c | 2120 ++ src/lua_ue4ss_runtime.c | 619 + src/lua_unreal_prop.c | 6167 ++++ src/main.c | 54 +- src/misc.c | 18 + src/mod_host.c | 12 + src/mod_manager.c | 203 +- src/signatures.c | 81 +- src/ui_console.c | 379 +- src/ui_manager.c | 44 + src/ui_mod_manager.c | 100 +- src/unreal.c | 545 +- src/unreal_prop.c | 985 +- src/unreal_reflect.c | 1798 ++ src/vendor.c | 4 - test/fonts/nk_font_dejavusansmono.h | 27926 ----------------- test/test_ui.c | 1585 - test/test_ui_overview.c | 1522 - test/test_ui_signatures.c | 10 - test/test_ui_style_configurator.c | 947 - vendor/lua/src/luaconf.h | 7 +- vendor/minhook/src/buffer.c | 2 +- vendor/minhook/src/buffer.h | 2 +- vendor/minhook/src/hde/hde32.c | 2 +- vendor/minhook/src/hde/hde32.h | 2 +- vendor/minhook/src/hde/hde64.c | 2 +- vendor/minhook/src/hde/hde64.h | 2 +- vendor/minhook/src/hde/pstdint.h | 2 +- vendor/minhook/src/hde/table32.h | 2 +- vendor/minhook/src/hde/table64.h | 2 +- vendor/minhook/src/hook.c | 2 +- vendor/minhook/src/trampoline.c | 2 +- vendor/minhook/src/trampoline.h | 2 +- 109 files changed, 29485 insertions(+), 34557 deletions(-) create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 docs/INSTALLATION.md create mode 100644 docs/TROUBLESHOOTING.md create mode 100644 docs/USING_OVERDUB.md create mode 100644 docs/lua/Overdub.lua create mode 100644 docs/lua/Types.lua create mode 100644 docs/lua/c-modules.md create mode 100644 docs/lua/overdub-runtime.md create mode 100644 docs/lua/overdub/input.lua create mode 100644 docs/lua/overdub/task.lua create mode 100644 docs/lua/overdub/ui.lua create mode 100644 docs/lua/overdub/unreal.lua create mode 100644 docs/lua/tasks.md create mode 100644 docs/lua/ue4ss-runtime.md create mode 100644 docs/lua/ui.md create mode 100644 docs/lua/unreal.md create mode 100644 docs/mod-development/architecture.md create mode 100644 docs/mod-development/building-native-mods.md create mode 100644 docs/mod-development/caveats.md create mode 100644 docs/mod-development/native-sdk.md create mode 100644 docs/mod-development/package-format.md create mode 100644 docs/mod-development/unreal.md create mode 100644 include/lua_mod_runtime.h create mode 100644 include/lua_overdub.h create mode 100644 include/lua_overdub_input.h create mode 100644 include/lua_overdub_runtime.h create mode 100644 include/lua_overdub_task.h create mode 100644 include/lua_overdub_ui.h create mode 100644 include/lua_overdub_unreal.h create mode 100644 include/lua_overdub_worker.h create mode 100644 include/lua_serial.h create mode 100644 include/lua_ue4ss.h create mode 100644 include/lua_ue4ss_runtime.h create mode 100644 include/lua_unreal_prop.h create mode 100644 include/overdub_lua.h create mode 100644 include/unreal_reflect.h create mode 100644 src/lua_mod_runtime.c create mode 100644 src/lua_overdub.c create mode 100644 src/lua_overdub_input.c create mode 100644 src/lua_overdub_runtime.c create mode 100644 src/lua_overdub_task.c create mode 100644 src/lua_overdub_ui.c create mode 100644 src/lua_overdub_unreal.c create mode 100644 src/lua_overdub_worker.c create mode 100644 src/lua_serial.c create mode 100644 src/lua_ue4ss.c create mode 100644 src/lua_ue4ss_runtime.c create mode 100644 src/lua_unreal_prop.c create mode 100644 src/unreal_reflect.c delete mode 100644 test/fonts/nk_font_dejavusansmono.h delete mode 100644 test/test_ui.c delete mode 100644 test/test_ui_overview.c delete mode 100644 test/test_ui_signatures.c delete mode 100644 test/test_ui_style_configurator.c diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..611b109 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,10 @@ +root = true + +[*] +end_of_line = lf +charset = utf-8 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{bat}] +end_of_line = crlf diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..a228617 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,13 @@ +* text=auto eol=lf +*.c text eol=lf +*.h text eol=lf +Makefile text eol=lf +*.bat text eol=crlf +*.png -text +*.jpg -text +*.jpeg -text +*.gif -text +*.pdf -text +*.zip -text +*.exe -text +*.dll -text diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 97e2450..5887916 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -83,6 +83,8 @@ jobs: Copy-Item LICENSE "$templateRoot\" Copy-Item build\overdub.lib "$templateRoot\build\" Copy-Item docs\MOD_DEVELOPMENT.md "$templateRoot\docs\" + Copy-Item docs\mod-development "$templateRoot\docs\" -Recurse + Copy-Item docs\lua "$templateRoot\docs\" -Recurse Copy-Item include\* "$templateRoot\include\" -Recurse Copy-Item mod\main.c "$templateRoot\" Copy-Item mod\Makefile "$templateRoot\" diff --git a/Makefile b/Makefile index c3263c7..afd2c6d 100644 --- a/Makefile +++ b/Makefile @@ -1,16 +1,13 @@ CC := x86_64-w64-mingw32-gcc BUILD_DIR := build -OBJ_DIR_DEBUG := $(BUILD_DIR)/obj/debug -OBJ_DIR_RELEASE := $(BUILD_DIR)/obj/release -OBJ_DIR_TEST_UI := $(BUILD_DIR)/obj/test_ui -OBJ_DIR_TEST_LUA := $(BUILD_DIR)/obj/test_lua +OBJ_DIR_DEBUG := $(BUILD_DIR)/obj/debug +OBJ_DIR_RELEASE := $(BUILD_DIR)/obj/release INC := -I. -Iinclude -Ivendor -CFLAGS_COMMON := -std=c11 -Wall -Wextra -Wno-unused-function -DWIN32_LEAN_AND_MEAN -DCOBJMACROS $(INC) +CFLAGS_COMMON := -std=c11 -Wall -Wextra -Wno-unused-function -mcx16 -DWIN32_LEAN_AND_MEAN -DCOBJMACROS $(INC) LDFLAGS_COMMON := -shared LIBS_DLL := -luser32 -lkernel32 -ladvapi32 -lshlwapi -ld3d12 -ld3d11 -ldxgi -ldxguid -luuid -ldbghelp -LIBS_TEST_UI := -luser32 -lkernel32 -ladvapi32 -lshlwapi -ld3d11 -ldxguid -ldbghelp CFLAGS_DEBUG := -g3 -O0 LDFLAGS_DEBUG := @@ -21,57 +18,10 @@ LDFLAGS_RELEASE := -Wl,--gc-sections -flto LUA_SRCS := $(filter-out vendor/lua/src/lua.c vendor/lua/src/luac.c,$(wildcard vendor/lua/src/*.c)) SRCS := $(shell find src -name '*.c') $(LUA_SRCS) -SRCS_TEST_UI := \ - src/arena.c \ - src/file.c \ - src/debug.c \ - src/globals.c \ - src/ini.c \ - src/input.c \ - src/log.c \ - src/misc.c \ - src/mod_host.c \ - src/mod_manager.c \ - src/nk_kb_text_shape.c \ - src/nk_font_runtime.c \ - src/path.c \ - src/profiler.c \ - src/scratch.c \ - src/sigscan.c \ - src/str_utf.c \ - src/str.c \ - src/string_pool.c \ - src/ui_console.c \ - src/ui_keybind_capture.c \ - src/ui_manager.c \ - src/ui_mod_manager.c \ - src/ui_nuklear.c \ - src/unreal.c \ - src/unreal_prop.c \ - src/vendor.c \ - src/vendor_kb.c \ - src/builtin/cache.c \ - src/builtin/common.c \ - src/builtin/details_panel.c \ - src/builtin/kismet_disassembler.c \ - src/builtin/search.c \ - src/builtin/uobject_search.c \ - src/builtin/ufunction_call.c \ - src/builtin/ufunction_tracer.c \ - src/builtin/tweaks.c \ - test/test_ui_signatures.c \ - test/test_ui_overview.c \ - test/test_ui_style_configurator.c +OBJS_DEBUG := $(SRCS:%.c=$(OBJ_DIR_DEBUG)/%.o) +OBJS_RELEASE := $(SRCS:%.c=$(OBJ_DIR_RELEASE)/%.o) -SRCS_TEST_UI += $(LUA_SRCS) -SRCS_TEST_LUA := src/lua_runtime.c test/test_lua_runtime.c $(LUA_SRCS) - -OBJS_DEBUG := $(SRCS:%.c=$(OBJ_DIR_DEBUG)/%.o) -OBJS_RELEASE := $(SRCS:%.c=$(OBJ_DIR_RELEASE)/%.o) -OBJS_TEST_UI := $(SRCS_TEST_UI:%.c=$(OBJ_DIR_TEST_UI)/%.o) -OBJS_TEST_LUA := $(SRCS_TEST_LUA:%.c=$(OBJ_DIR_TEST_LUA)/%.o) - -.PHONY: all debug release test_ui test_lua clean +.PHONY: all debug release clean all: debug @@ -83,19 +33,7 @@ release: $(OBJS_RELEASE) | $(BUILD_DIR) @printf "LINK\t$(BUILD_DIR)/overdub.dll\n" @$(CC) -o $(BUILD_DIR)/overdub.dll $(OBJS_RELEASE) $(LDFLAGS_COMMON) $(LDFLAGS_RELEASE) -Wl,--out-implib,$(BUILD_DIR)/overdub.lib $(LIBS_DLL) -test_ui: test/test_ui.c $(OBJS_TEST_UI) | $(BUILD_DIR) - @printf "LINK\t$(BUILD_DIR)/overdub_test_ui.exe\n" - @$(CC) $(CFLAGS_COMMON) -Wno-missing-braces -g3 -O0 -DBUILD_TEST_UI -DOVERDUB_STATIC -o $(BUILD_DIR)/overdub_test_ui.exe test/test_ui.c $(OBJS_TEST_UI) $(LIBS_TEST_UI) - @printf "RUN\t$(BUILD_DIR)/overdub_test_ui.exe\n" - @wine $(BUILD_DIR)/overdub_test_ui.exe - -test_lua: $(OBJS_TEST_LUA) | $(BUILD_DIR) - @printf "LINK\t$(BUILD_DIR)/overdub_test_lua.exe\n" - @$(CC) $(CFLAGS_COMMON) -g3 -O0 -DBUILD_TEST_LUA -o $(BUILD_DIR)/overdub_test_lua.exe $(OBJS_TEST_LUA) - @printf "RUN\t$(BUILD_DIR)/overdub_test_lua.exe\n" - @wine $(BUILD_DIR)/overdub_test_lua.exe - -$(BUILD_DIR) $(OBJ_DIR_DEBUG) $(OBJ_DIR_RELEASE) $(OBJ_DIR_TEST) $(OBJ_DIR_TEST_UI) $(OBJ_DIR_TEST_LUA): +$(BUILD_DIR) $(OBJ_DIR_DEBUG) $(OBJ_DIR_RELEASE): @printf "MKDIR\t$@\n" @mkdir -p $@ @@ -109,21 +47,9 @@ $(OBJ_DIR_RELEASE)/%.o: %.c @printf "CC\t$@\n" @$(CC) $(CFLAGS_COMMON) $(CFLAGS_RELEASE) -DBUILD_RELEASE -DOVERDUB_BUILD_DLL -MMD -MP -c $< -o $@ -$(OBJ_DIR_TEST_UI)/%.o: %.c - @mkdir -p $(dir $@) - @printf "CC\t$@\n" - @$(CC) $(CFLAGS_COMMON) -g3 -O0 -DBUILD_TEST_UI -DOVERDUB_STATIC -MMD -MP -c $< -o $@ - -$(OBJ_DIR_TEST_LUA)/%.o: %.c - @mkdir -p $(dir $@) - @printf "CC\t$@\n" - @$(CC) $(CFLAGS_COMMON) -g3 -O0 -DBUILD_TEST_LUA -MMD -MP -c $< -o $@ - clean: @printf "RM\t$(BUILD_DIR)\n" @rm -rf $(BUILD_DIR) -include $(OBJS_DEBUG:.o=.d) -include $(OBJS_RELEASE:.o=.d) --include $(OBJS_TEST_UI:.o=.d) --include $(OBJS_TEST_LUA:.o=.d) diff --git a/README.md b/README.md index e7c67cc..de18b08 100644 --- a/README.md +++ b/README.md @@ -2,204 +2,77 @@ [![CI](https://github.com/akmubi/overdub/actions/workflows/ci.yml/badge.svg)](https://github.com/akmubi/overdub/actions/workflows/ci.yml) -Overdub is a mod loader and in-game mod manager for Hi-Fi RUSH. It supports native code, Unreal assets, Blueprint actors, etc. - -## Features -- Native C mod API with callbacks, hooks, Unreal helpers, etc. -- Start, stop, and reload DLL mods without restarting the game. -- Combine code, assets, etc. in one mod. -- Shared UI for mod settings and keybinds. -- Built-in UObject Search, UFunction Tracer, and console. -- Windows support, including Linux and Steam Deck through Proton. -Supported stores: Steam, Epic Games, and Xbox/Game Pass. - -## Installation -Download the release made for your game version. It contains `overdub.dll` and a [Hibiki Bootstrap](https://github.com/akmubi/hibiki-bootstrap) DLL. -Copy both files into the game directory. -Steam and Epic Games: +Overdub is a mod loader and in-game mod manager for Hi-Fi RUSH. It can load native DLLs, Lua scripts, cooked Unreal assets, and Blueprint actors from one mod package. + +The loader includes a mod manager, a console, UObject Search, and UFunction Tracer. Native and Lua mods can use Unreal reflection, receive game callbacks, and draw controls in the shared UI. + +Overdub supports the Steam, Epic Games, and Xbox/Game Pass releases. It also runs through Proton on Linux and Steam Deck. + +## Install + +Download the release for your game version. Copy `overdub.dll` and the included bootstrap DLL into the game binary directory. + +For Steam and Epic Games: ``` -/Hibiki/Binaries/Win64/ +Hibiki/Binaries/Win64/ |-- overdub.dll +-- XAPOFX1_5.dll ``` -Xbox and Game Pass: + +For Xbox and Game Pass: ``` -/Hibiki/Binaries/WinGDK/ +Hibiki/Binaries/WinGDK/ |-- overdub.dll +-- dsound.dll ``` -Linux and Steam Deck use the same files. Copy them into the Windows game directory used by Proton. No DLL override or launch option is needed. -Do not keep **UE4SS** or another **proxy DLL loader** in the same directory. -## First Launch -Start the game. Overdub should create: -``` -mods/ -overdub-config.ini -overdub.log -``` +Do not keep UE4SS or another proxy DLL loader in the same directory. Start the game once and Overdub will create its `mods` directory and configuration files. + +See [Installation](docs/INSTALLATION.md) for the complete setup and update instructions. -Default shortcuts: -| Key | Action | -|---------|-----------------------| -| `` ` `` | Open the mod manager | -| `F1` | Open the console | -| `F2` | Open UObject Search | -| `F3` | Open UFunction tracer | +## Use -If the files above are not created, check the installation path and make sure the bootstrap DLL matches your game version. +The default shortcuts are: + +| Key | Window | +| -------- | ---------------- | +| Backtick | Mod manager | +| F1 | Console | +| F2 | UObject Search | +| F3 | UFunction Tracer | + +Each installed mod has its own directory under `mods` and must contain `mod.ini`. -## Installing Mods -Extract each mod into its own directory under `mods`. Every mod needs a `mod.ini` manifest. ``` mods/ +-- example-mod/ |-- mod.ini - |-- main.dll - +-- ... -``` -Asset mods may also contain `.pak`, `.utoc`, and `.ucas` files. -Restart the game after adding or removing a mod. Overdub discovers mod directories only during startup. - -## Using the Mod Manager -The mod list is on the left. Select a mod to see its settings, runtime state, and controls on the right. -The status dot is green when something is active, gray when the mod is inactive, and red when one of its parts failed. -![Selected mod details](docs/images/mod-details.png) - -### Enabling Mods -`Enable` and `Disable` control the whole mod. DLL code and tracked Blueprint actors update immediately. -Assets are different. They are mounted during startup and cannot be safely removed while the game is running. Restart after changing an asset mod, its enabled state, or its order. -Disabling a mod may not undo changes it already made to the game. - -### Mod Options -Options in the `Config` section change immediately in memory. -- `Save` writes them to `config.ini`. -- `Discard` restores the saved values. -- `Restore defaults` resets them until you save again. -Some mods only apply changed options after their DLL or the game is restarted. - -### DLL Controls -The `Code` section separates whether the DLL is loaded from whether its mod code is running. -- `Start` loads and initializes the mod. -- `Stop` shuts it down but keeps the DLL loaded. -- `Restart` stops and starts it. -- `Reload` unloads the DLL, loads it again, and starts it. -Reload is mainly for development. A mod that does not clean up its hooks, callbacks, threads, etc. may crash the game when reloaded. -Reloading DLL code does not rescan manifests, discover new mods, or remount assets. - -### Blueprint Mods -The `Blueprints` section shows each declared actor and its current state. You can spawn or despawn it, enable automatic spawning, or assign a spawn keybind. -Spawning may fail until the required world, player, or custom object exists. - -### Mod Order -Press `Reorder mods`, select a mod, and move it up or down. Apply the change and restart the game. -Order affects DLL startup, callback processing, and asset priority. Callbacks run from top to bottom. For conflicting assets, the lower mod normally takes priority. -![Reorder Mods](docs/images/reorder-mods.png) - -### Settings -Press `Settings` below the mod list to change the mod directory, manager shortcut, console options, etc. -Press `Apply` to save changes to `overdub-config.ini`. Closing the window does not save them. Changing the mod directory also requires a restart. -![Overdub settings](docs/images/settings.png) - -## Configuration Files -Overdub stores loader settings in `overdub-config.ini`. Each mod stores its own values in `mods//config.ini`. -Edit these files only while the game is closed. Invalid values may be ignored, and the running game may overwrite manual changes. - -## Console -Press `F1` to open the console. It shows loader and mod messages and accepts commands registered by mods. -The console contains only the current session. Use `overdub.log` for startup errors or older messages. -![Overdub console](docs/images/console.png) - -## Built-in Tools -Built-in tools appear in the normal mod list and can be configured like other mods. - -### UObject Search -UObject Search inspects Unreal objects currently loaded in memory. Enter a name, adjust the search settings when needed, and select a result to inspect it. -It can search names, type instances, properties, etc. The details panel shows object information, reflected fields, functions, and Kismet bytecode when available. -Selecting results reuses a preview tab. Click the tab to pin it. Useful shortcuts are `Tab`, `Ctrl+Tab`, and `Ctrl+W`. -UFunction details include a `Call...` action. The call dialog validates a target object, provides reflected input fields and searchable typed object/class pickers, automatically supplies conventional WorldContext parameters, and displays return/out values. Unsupported parameter types disable the call. Calls can still change game state, send RPCs, or invoke unsafe game logic, so inspect the function before using it. -Property inspection remains read-only, and broad searches may be slow. -![UObject Search](docs/images/uobject-search.png) - -### UFunction Tracer -UFunction Tracer records Unreal function calls. -1. Add a narrow capture filter. -2. Start capture and perform the action in-game. -3. Stop capture and inspect the calls. -4. Save the trace when needed. -Filters use `+` to include and `-` to exclude: + |-- example.dll + |-- scripts/ + | +-- main.lua + +-- assets/ ``` -+func:OnBeat --func:Tick -``` -Targets include `func`, `self`, `class`, etc., with outer-chain variants. Include rules use OR, while any matching exclude rule rejects the call. -Start narrow. Busy functions can fill the capture quickly and broad tracing can hurt performance. Parameters and return values are not currently saved. -![UFunction Tracer](docs/images/ufunction-tracer.png) - -### Tweaks -The Tweaks tool currently includes tutorial popup control and jukebox state restoration. -Jukebox state is shared across save slots, so restoring it on another slot may restore music that has not been unlocked there. - -## Troubleshooting -### Overdub Does Not Load -Check that `overdub.dll` and the correct bootstrap DLL are in the same game directory. Remove UE4SS and other proxy DLL loaders. -If `overdub.log` and `mods` are not created, the bootstrap did not load Overdub. - -### The Manager Does Not Open -Press the backtick key rather than the apostrophe key. Also check the keyboard layout, the configured shortcut, and whether the game is still loading. - -### A Mod Does Not Appear -Make sure the mod has its own directory, contains `mod.ini`, and uses a unique mod ID. Restart the game and check `overdub.log` for manifest errors. - -### A DLL Mod Does Not Start -Open its `Code` section and read the error. Common causes are a wrong DLL path, unsupported API version, or failed initialization. - -### An Asset Mod Does Not Work -Open its `Assets` section and check the mount error. Make sure every file named in the manifest exists, then restart the game. - -### Fatal Error or Assertion -The error handler **copies the stack trace to the clipboard**. Before launching again, save the complete stack trace and `overdub.log`, then note what happened immediately before the crash. -Testing once without the newest mod can help identify whether the problem belongs to Overdub or the mod. - -## Reporting Problems -Search existing issues first. Problems caused only by a third-party mod should normally be reported to its author. -Include: -- What happened and how to reproduce it. -- Environment details and installed mods. -- Whether the issue remains without third-party mods. -- The complete stack trace and `overdub.log` for crashes. -Screenshots or video are useful when they show something the log cannot. Report one problem per issue, and do not upload game files or another author's full mod package. - -## Known Limitations -- Mod metadata and assets are loaded at startup. -- Mounted assets cannot be freely unloaded. -- DLL reload is safe only when the mod cleans up all of its state. -- The built-in inspection tools are read-only. - -## Mod Development -See the [Mod Development Guide](docs/MOD_DEVELOPMENT.md) for package format, the native API, Unreal helpers, etc. - -## Building From Source -### Windows -Open `overdub.sln` in Visual Studio 2022, select `Release` and `x64`, then build the solution. -Output: -``` -build/overdub.dll -``` -The project has a post-build copy step for a Steam installation path. Change or disable it when the game is installed elsewhere. -### Linux -Install `make` and MinGW-w64, then cross-compile the Windows DLL: +See [Using Overdub](docs/USING_OVERDUB.md) for mod installation, controls, configuration, and built-in tools. See [Troubleshooting](docs/TROUBLESHOOTING.md) when Overdub or a mod does not start. + +## Make mods + +Overdub provides a C SDK and a native Lua 5.4 runtime. It also has a separate compatibility runtime for existing UE4SS Lua mods. + +Start with the [Mod Development](docs/MOD_DEVELOPMENT.md) page. It links to the package format, build guide, native SDK, Lua API, architecture, and caveats. + +## Build Overdub + +Open `overdub.sln` in Visual Studio 2022 and build `Release|x64`, or cross-compile the Windows DLL with MinGW-w64: + ```sh make release ``` -Use `make debug` for a debug build. The output is `build/overdub.dll`. -## Uninstalling -Close the game and remove `overdub.dll` together with `XAPOFX1_5.dll` or `dsound.dll`. -Remove `mods`, `overdub-config.ini`, and `overdub.log` only when you also want to delete installed mods and saved settings. +The output is `build/overdub.dll`. The Debug and Release configurations are described in [Building Native Mods](docs/mod-development/building-native-mods.md). ## License + See [LICENSE](LICENSE). -Overdub is an unofficial project and is not affiliated with the developers or publishers of Hi-Fi RUSH. +Overdub is an unofficial project and is not affiliated with the developers or publishers of Hi-Fi RUSH. diff --git a/docs/INSTALLATION.md b/docs/INSTALLATION.md new file mode 100644 index 0000000..371ad50 --- /dev/null +++ b/docs/INSTALLATION.md @@ -0,0 +1,46 @@ +# Installation + +Overdub releases are tied to a supported game build. Download the archive for the store and game version you use. + +## Windows + +Close the game before changing loader files. + +For Steam and Epic Games, open the game directory and copy these files into `Hibiki/Binaries/Win64`: +``` +overdub.dll +XAPOFX1_5.dll +``` + +For Xbox and Game Pass, copy these files into `Hibiki/Binaries/WinGDK`: +``` +overdub.dll +dsound.dll +``` + +The two DLLs must be in the same directory as the game executable. Do not rename them. + +Remove UE4SS and other proxy DLL loaders from that directory. Two loaders trying to use the same proxy entry point will conflict. + +Start the game. A working installation creates these items beside the game content: +``` +mods/ +overdub-config.ini +overdub.log +``` + +## Linux and Steam Deck + +Use the same Windows release files. Copy them into the Windows game directory inside the Proton prefix. Overdub does not require a Wine DLL override or a launch option. + +## Update + +Close the game, replace `overdub.dll`, and replace the bootstrap DLL when the release includes a new one. Keep `mods`, `overdub-config.ini`, and mod `config.ini` files unless the release notes say otherwise. + +Native mods must use an ABI version compatible with the installed Overdub build. When a native mod stops loading after an update, update that mod as well. + +## Uninstall + +Close the game and remove `overdub.dll` together with `XAPOFX1_5.dll` or `dsound.dll`. + +The `mods` directory and INI files contain installed mods and saved settings. Remove them only if you also want to remove that data. diff --git a/docs/MOD_DEVELOPMENT.md b/docs/MOD_DEVELOPMENT.md index 8338418..1ca78c0 100644 --- a/docs/MOD_DEVELOPMENT.md +++ b/docs/MOD_DEVELOPMENT.md @@ -1,851 +1,20 @@ -# Overdub Mod Development Guide +# Mod Development -This guide covers the parts of Unreal Engine and Overdub that are directly useful when making a mod for Hi-Fi RUSH. It assumes basic C/C++ knowledge. -Hi-Fi RUSH uses a modified Unreal Engine 4.27 build. Public UE 4.27 source is useful for reference, but always verify addresses, layouts, and behavior against the game build you support. +An Overdub mod can contain a native DLL, a Lua entry script, Unreal assets, Blueprint actors, or any combination of them. Every mod is a directory with a `mod.ini` manifest. -The public SDK headers are in [`include/`](../include/). Include [`mod.h`](../include/mod.h) for the lifecycle ABI and mod-owned resources, and include the other public headers for shared utility, Unreal, and Nuklear APIs. Mods link against the small `build/overdub.lib` import library; the implementations live in `overdub.dll`. +If you want to make a Lua mod, begin with [Native Overdub Lua](lua/overdub-runtime.md). Existing UE4SS scripts use the separate [UE4SS Compatibility Runtime](lua/ue4ss-runtime.md). -## 1. Choose a Mod Type +If you want to make a native mod, download the SDK template from the same Overdub release used by the player. Read [Building Native Mods](mod-development/building-native-mods.md), then [Native SDK](mod-development/native-sdk.md). -An Overdub package may contain any combination of these parts. +The rest of the guide is split by subject: -| Type | Use it for | -|------------|----------------------------------------------------------------------| -| Asset | Replacing textures, audio, etc. | -| Blueprint | Gameplay logic made in Unreal Editor that can run as a spawned actor | -| Native DLL | Hooks, custom UI, etc. | +| Document | Subject | +| --------------------------------------------------------------- | ----------------------------------------------------------------- | +| [Package Format](mod-development/package-format.md) | `mod.ini`, assets, Blueprints, and saved options | +| [Building Native Mods](mod-development/building-native-mods.md) | Visual Studio, MinGW-w64, and package output | +| [Native SDK](mod-development/native-sdk.md) | DLL entry points, callbacks, memory, commands, input, and hooks | +| [Unreal API](mod-development/unreal.md) | UObjects, properties, UFunctions, listeners, and custom classes | +| [Architecture](mod-development/architecture.md) | Loader ownership, Lua runtimes, callbacks, and reload behavior | +| [Caveats](mod-development/caveats.md) | Object lifetime, threads, asset lifetime, and unsafe engine calls | -Native DLL mods have the most control and the greatest crash risk. Prefer assets or Blueprints when they can do the job cleanly. - -## 2. Package Layout - -Every mod has its own directory under `mods/`. -``` -mods/ -+-- example-mod/ - +---assets/ - | |-- example.pak - | |-- example.utoc - | +-- example.ucas - |-- mod.ini - |-- config.ini - +-- example.dll -``` - -Only `mod.ini` is required. Include only the files the mod uses. The mod list and asset mount order are created at startup. Restart the game after adding or removing a mod, changing asset files, or changing mod order. - -### Minimal native mod manifest -```ini -[info] -id = author.example -name = Example Mod -author = Author Name -version = 1.0.0 -kind = mod - -[description] -Example native mod. - -[code] -path = example.dll -``` - -Keep `id` stable between releases. It is used for saved order and configuration. - -### Asset files -```ini -[assets] -path_without_ext = example -``` - -Overdub looks for: -``` -example.pak -example.utoc -example.ucas -``` - -The `.utoc` and `.ucas` files are a pair. A package may also contain only a `.pak`. - -### Blueprint actor -```ini -[blueprint] -id = example_actor -mod_actor_class_path = /Game/Mods/Example/BP_ExampleMod.BP_ExampleMod_C -attach_to = world -auto_spawn = true -default_spawn_keybind = F6 -``` - -Accepted `attach_to` values: -- `none` -- `player_controller` -- `local_player` -- `pawn` -- `hud` -- `world` -- `game_instance` -- `custom_class_path` - -For a custom context: -```ini -attach_to = custom_class_path -custom_attach_class_path = Class /Script/GameModule.SomeClass -``` - -The selected context must exist when the actor is spawned. A pawn, HUD, or player controller may be absent on menus and loading screens. - -### Options - -Supported sections: -``` -[option.bool] -[option.int] -[option.float] -[option.enum] -[option.string] -[option.keybind] -[option.color] -``` - -Common keys: -```ini -[option.bool] -id = feature_enabled -label = Enable feature -description = Enables the feature. -default_value = true -``` - -Integer and float options also support `min_value`, `max_value`, and `step`. -```ini -[option.int] -id = count -label = Count -default_value = 3 -min_value = 0 -max_value = 100 -step = 1 -``` - -Enums use `|` separators: -```ini -[option.enum] -id = mode -label = Mode -enum_values = Off|Normal|Aggressive -default_value = Normal -``` - -Colors use decimal RGBA: -```ini -[option.color] -id = display_color -label = Display color -default_value = 255.128.32.255 -``` - -Section names and keys are case-insensitive. A semicolon starts a comment. - -## 3. Building a Native Mod - -The included Visual Studio project targets Visual Studio 2022, x64, C11 or C++20, and the static MSVC runtime. - -Debug build: -```batch -msbuild mod\mod.vcxproj /p:Configuration=Debug /p:Platform=x64 /p:ModName=example -``` - -Release build: -```batch -msbuild mod\mod.vcxproj /p:Configuration=Release /p:Platform=x64 /p:ModName=example -``` - -Output: -``` -mod/build//example.dll -``` - -A mod project should use the matching public headers from `include/` and link `build/overdub.lib`. - -### Building a mod outside the Overdub repository - -The Makefile and Visual Studio project accept an Overdub source-tree location (so the mod does not need to be inside this repository). Point both include lookup and import-library lookup at the matching Overdub build with one setting. - -Make: -```sh -make OVERDUB_DIR=/path/to/overdub CONFIG=release MOD_NAME=example -``` - -MSBuild: -```batch -msbuild mod.vcxproj /p:OverdubDir=C:\path\to\overdub /p:Configuration=Release /p:Platform=x64 /p:ModName=example -``` - -For multiple mod projects, set the `OVERDUB_DIR` environment variable once instead. The Makefile reads it directly, and `mod.vcxproj` uses it when `OverdubDir` was not supplied as an MSBuild property. If neither setting is present, the included in-repository templates continue to default to `..`. - -If `build/overdub.lib` is missing, the mod build automatically builds Overdub first with the same Debug or Release configuration. An invalid `OVERDUB_DIR` or a failed Overdub build stops the mod build with an explicit error. - -The mod-template archive attached to each Overdub release is self-contained. Its project root already contains `include/`, `vendor/`, and `build/overdub.lib`, so it builds without `OVERDUB_DIR` or an Overdub source checkout. The same `overdub.lib` is also available as a separate release asset for custom project layouts. - -## 4. Minimal Native Mod - -```c -#include "mod.h" - -static bool -example_init(mod_handle_t mod) -{ - MOD_LOG_INFO(mod, "Example mod started"); - return true; -} - -static void -example_deinit(mod_handle_t mod) -{ - MOD_LOG_INFO(mod, "Example mod stopped"); -} - -MOD_ABI_VERSION_ENTRY() -{ - return MOD_ABI_VERSION; -} - -MOD_ENTRY() -{ - static const mod_api_t api = { - .struct_size = sizeof(mod_api_t), - .init = example_init, - .deinit = example_deinit, - }; - - return &api; -} -``` - -`mod_entry` only returns the callback table. Do not perform real initialization there. Overdub calls `init` later on the game thread after its engine hooks are ready. - -`init` is required. Other callbacks are optional: -```c -struct mod_api_s { - uint32_t struct_size; - mod_init_fn_t init; - mod_deinit_fn_t deinit; - mod_tick_fn_t tick; - mod_input_fn_t input; - mod_pe_pre_fn_t pe_pre; - mod_pe_post_fn_t pe_post; - mod_func_invoke_pre_fn_t func_invoke_pre; - mod_func_invoke_post_fn_t func_invoke_post; - mod_draw_panel_fn_t draw_panel; - mod_draw_config_fn_t draw_config; -}; -``` - -Always export `mod_abi_version()` and set `struct_size`. Major and minor ABI versions must match the loader; patch differences are ignored. `mod_entry()` remains focused on returning the callback table. - -Before loading a mod, Overdub checks every symbol it imports from `overdub.dll`. If the mod was linked against a newer API, the error lists the exact missing function names. After loading, Overdub calls `mod_abi_version()` and rejects incompatible callback ABIs before resolving `mod_entry()`. - -## 5. Lifecycle and Cleanup - -The useful distinction is between stopping and reloading: -``` -Start: init -Stop: deinit, managed resources removed, DLL stays loaded -Restart: Stop + Start -Reload: Stop + unload DLL + load new DLL + Start -``` - -Static DLL variables survive Stop and Start because the DLL remains loaded. -```c -static int g_counter; -``` - -Reset per-run state in `init`, and clear pointers in `deinit`. - -After `deinit`, Overdub removes manager-owned hooks, UObject listeners, commands, and mod arenas. - -The mod must clean up anything Overdub does not own, such as threads, OS handles, external allocations, hooks, patches , etc. - -A DLL cannot be unloaded while another thread or callback can still execute its code. During `deinit`, stop new work, disable unmanaged callbacks, signal and join every worker thread, restore patches, and only then return. - -## 6. Threads and Hot Paths - -`init`, `deinit`, `tick`, UI callbacks, and most input and reflected-call callbacks normally run on the game thread. - -Most UObject and gameplay work belongs on the game thread. - -A custom hook runs on whichever thread called the hooked function. Before installing one, determine whether it can run concurrently, recurse, execute during shutdown, etc. - -Keep per-frame callbacks, listeners, hooks, etc. fast. Move file IO, parsing, compression, and similar slow work to worker threads, but copy any borrowed game data before sending it to a worker. - -Do not log every frame or every reflected call in normal use. - -## 7. Memory - -### Permanent arena - -```c -mod_arena_handle_t arena = mod_get_perm(mod); -``` - -Use it for state that lives for one active run of the mod. It is destroyed after `deinit`. - -```c -typedef struct { - int counter; -} state_t; - -static state_t *g_state; - -static bool -example_init(mod_handle_t mod) -{ - g_state = MOD_ARENA_PUSH_ZERO(mod_get_perm(mod), state_t); - return g_state != NULL; -} - -static void -example_deinit(mod_handle_t mod) -{ - (void)mod; - g_state = NULL; -} -``` - -### Dynamic arena - -```c -mod_arena_handle_t arena = mod_arena_create(mod, 64 * MB, 64 * KB); -``` - -Use a dynamic arena when a subsystem needs its own reset or destroy point. - -### Scratch arena - -```c -mod_tmp_arena_t tmp = mod_scratch_begin(MOD_ARENA_HANDLE_INVALID); - -/* temporary allocations */ - -mod_scratch_end(tmp); -``` - -Scratch pointers become invalid at `mod_scratch_end`. Never store them. - -Treat `mod_handle_t`, `mod_cfg_handle_t`, and `mod_arena_handle_t` as opaque handles. Do not cast them to pointers or depend on their representation. - -## 8. Unreal Runtime Basics - -The few relationships that matter most are: - -``` -class what type an object is -super class what its class inherits from -outer which UObject contains it -world/level where a runtime actor exists -``` - -The outer chain is not an inheritance chain. - -Every actor is a UObject, but many UObjects are not actors. Classes, functions, assets, etc. are also UObjects. - -A UObject contains a class, name, outer, flags, and an index in the global UObject array. Overdub exposes the current target layouts through `include/unreal.h`. - -### Object lifetime - -Treat every `uobject_t *` as a borrowed pointer. Objects may disappear during travel, level streaming, gameplay destruction, or garbage collection. Slots in the global UObject array can be reused. - -Validate cached pointers before use: - -```c -if (!obj || !unreal_uobject_is_valid(obj)) { - obj = NULL; -} -``` - -Validation only proves that the object is valid at that moment. Clear tracked pointers when objects are deleted and during `deinit`. - -### Names and full names - -Unreal uses `FName` IDs rather than ordinary string pointers for many names. Use `FNAME_FIND` when you only need an existing name. Avoid adding names to the global pool without a reason. - -Short object names can repeat. Prefer full names when identifying a known class or function. - -``` -Class /Script/Engine.Actor -Function /Script/Engine.Actor.K2_DestroyActor -``` - -## 9. Finding UObjects - -Include the Unreal helpers. Overdub initializes the shared runtime state before starting mods: - -```c -#include "unreal.h" -``` - -Find a class by full name: - -```c -uclass_t *actor_class = - unreal_uobject_find_class_by_full_name(STR_LIT("Class /Script/Engine.Actor")); -``` - -Find a live instance: - -```c -uobject_t *actor = unreal_uobject_find_first_of(actor_class); -``` - -The first instance is often not the one you want. Filter by full name, world, outer chain, etc. - -Check inheritance with: - -```c -if (actor && unreal_uobject_is_a(actor, actor_class)) { - /* actor is Actor or derives from Actor */ -} -``` - -Use the built-in UObject Search tool to inspect names, properties, functions, etc. before hard-coding a lookup. - -## 10. UObject Listeners - -Listeners are useful for tracking objects that appear and disappear at runtime. - -```c -static uobject_t *g_tracked; - -static void -on_created(uobject_t *obj, int32_t idx, void *user) -{ - (void)idx; - (void)user; - - /* Match only the objects the mod needs. Keep this callback fast. */ -} - -static void -on_deleted(uobject_t *obj, int32_t idx, void *user) -{ - (void)idx; - (void)user; - - if (obj == g_tracked) { - g_tracked = NULL; - } -} -``` - -Register them during `init`: - -```c -if (!mod_register_uobject_listener(mod, UOBJECT_LISTENER_KIND_CREATE, on_created, NULL)) { - return false; -} - -if (!mod_register_uobject_listener(mod, UOBJECT_LISTENER_KIND_DELETE, on_deleted, NULL)) { - return false; -} -``` - -Managed listeners are removed after `deinit`. - -## 11. Properties and Reflection - -An `FProperty` describes the type and offset of a value. It does not normally contain the value itself. - -```c -fprop_t *prop = unreal_ustruct_find_prop((ustruct_t *)obj->cls, STR_LIT("Health")); -void *ptr = unreal_uprop_ptr(prop, obj); -``` - -Before reading or writing, verify the property exists and has the expected type and size. - -Do not treat all properties as integers or raw byte blocks. For example, bool properties may occupy one bit, strings and containers may require construction and destruction, and object properties follow Unreal lifetime rules. - -Start with plain numeric values, names, and object pointers. Use the SDK helpers for boolean properties instead of overwriting the containing byte. - -## 12. Calling UFunctions - -`ProcessEvent` calls a reflected function on a UObject. Parameters are stored in one buffer whose size and member offsets come from reflection. - -Do not infer offsets from a C declaration. - -```c -/* NOTE: error handling is omitted for brevity */ -static bool -call_set_count(uobject_t *obj, int32_t value) -{ - if (!obj || !unreal_uobject_is_valid(obj)) { - return false; - } - - ufunc_t *func = unreal_ustruct_find_func((ustruct_t *)obj->cls, STR_LIT("SetCount")); - fprop_t *count_prop = unreal_ustruct_find_prop((ustruct_t *)func, STR_LIT("Count")); - - mod_tmp_arena_t tmp = mod_scratch_begin(MOD_ARENA_HANDLE_INVALID); - { - uint8_t *params = MOD_ARENA_PUSH_ARRAY_ZERO(tmp.arena, uint8_t, func->params_size); - int32_t *count = (int32_t *)unreal_uprop_ptr(count_prop, params); - - *count = value; - - unreal_process_event(obj, func, params); - } - mod_scratch_end(tmp); - return true; -} -``` - -This example is only valid when `Count` is really a plain `int32_t`. Complex inputs, outputs, and return values need their proper Unreal initialization and cleanup. - -## 13. ProcessEvent and UFunction::Invoke Callbacks - -A mod can observe or replace game-thread reflected calls: - -```c -bool pe_pre(mod_handle_t mod, uobject_t *obj, ufunc_t *func, void *params); -void pe_post(mod_handle_t mod, uobject_t *obj, ufunc_t *func, void *params, bool consumed); -``` - -Returning `true` from `pe_pre` consumes the call and skips the original `ProcessEvent`. Use this carefully. The original may produce return values, update state, run Blueprint logic, etc. - -All active pre-callbacks run, and Overdub combines their results. Two mods can conflict when both replace the same call. - -`ProcessEvent` can recurse when a callback triggers another reflected call. Use a recursion guard when needed. - -Never keep the `params` pointer after the callback. - -`UFunction::Invoke` callbacks expose an `FFrame` and result pointer. They are lower level and more fragile than `ProcessEvent`. Never save those pointers. Consume an invoke call only when you fully understand the execution path, because skipping it commonly breaks Blueprint execution. - -## 14. Configuration - -Get handles during `init`: - -```c -static mod_cfg_handle_t g_enabled_cfg; - -static bool -example_init(mod_handle_t mod) -{ - g_enabled_cfg = mod_get_cfg_by_id(mod, STR_LIT("feature_enabled")); - return g_enabled_cfg != MOD_CFG_HANDLE_INVALID; -} -``` - -Read the value: - -```c -bool enabled = mod_cfg_get_bool(g_enabled_cfg); -``` - -There is no separate option-changed callback. Compare the current value with the previous value in `tick` when a feature needs transition logic. - -The SDK provides typed getters and setters for bool, int, float, enum, string, keybind, and color options. Do not use a handle with the wrong type. - -## 15. Input and Keybinds - -Direct input callback: - -```c -static bool -example_input(mod_handle_t mod, input_event_t *event) -{ - (void)mod; - - if (event->kind == INPUT_EVENT_KEY_DOWN && - event->key == INPUT_KEY_F8 && - !event->is_repeat) { - MOD_LOG_INFO(mod, "F8 pressed"); - return true; - } - - return false; -} -``` - -Return `true` only when the mod intentionally wants to block later mod callbacks and the game input handler. - -For a configured keybind, polling from `tick` is often simpler: - -```c -keybind_t bind = mod_cfg_get_keybind(g_action_key_cfg); -if (keybind_is_pressed(bind)) { - /* run once */ -} -``` - -Use `is_down` for held state, `is_pressed` for the up-to-down edge, and `is_released` for the down-to-up edge. - -## 16. Console Commands - -Register commands during `init`: - -```c -static void -example_command(mod_handle_t mod, str_t name, str_t args, void *user) -{ - (void)name; - (void)user; - - MOD_LOG_INFO(mod, "args: " STR_FMT, STR_ARG(args)); -} - -static bool -register_commands(mod_handle_t mod) -{ - return mod_register_cmd(mod, STR_LIT("example.run"), STR_LIT("Runs the example command"), example_command, NULL); -} -``` - -Prefix command names to avoid collisions with other mods. - -## 17. Custom UI - -Include Overdub's public Nuklear header: - -```c -#include "vendor_nuklear.h" -``` - -```c -static void -example_draw_panel(mod_handle_t mod, struct nk_context *ctx) -{ - (void)mod; - - nk_layout_row_dynamic(ctx, 24.0f, 1); - nk_label(ctx, "Example panel", NK_TEXT_LEFT); - - if (nk_button_label(ctx, "Run")) { - /* action */ - } -} -``` - -Overdub uses a modified Nuklear version. Compile against the public headers shipped with the target Overdub version and call the implementation exported by `overdub.dll`. - -Nuklear is immediate mode. Rebuild controls every frame, keep persistent UI state in the mod, and never store the context pointer. Do not block or issue D3D12 rendering directly from mod UI callbacks. - -## 18. Signatures and Native Hooks - -Use a native hook only when reflection or a higher-level callback is not enough. - -An RVA is an offset from the game module base. It is exact for one known executable but normally changes after an update. - -A signature is a byte pattern with wildcard bytes: - -``` -48 89 5C 24 ?? 57 48 83 EC ?? -``` - -A useful signature should match one intended location. A signature surviving an update does not prove that parameters, structure layouts, vtable indexes, or behavior are unchanged. - -Example hook shape: - -```c -typedef void (UNREAL_CALL *target_fn_t)(void *self); - -static target_fn_t g_target_real; - -static void UNREAL_CALL -target_hook(void *self) -{ - /* before */ - g_target_real(self); - /* after */ -} -``` - -Resolve and install it: - -```c -static bool -install_target_hook(mod_handle_t mod) -{ - void *target = NULL; - - sigscan_entry_t entry = { - .name = "target", - .pattern = "48 89 5C 24 ?? 57 48 83 EC ??", - .pp = &target, - .kind = SIG_DIRECT, - .op_off = 0, - .deref = 0, - }; - - if (mod_sigscan(&entry) != SIG_ERR_OK || !target) { - return false; - } - - if (!mod_hook_create(mod, target, target_hook, (void **)&g_target_real)) { - return false; - } - - return mod_hook_enable(mod, target); -} -``` - -The pattern above is only an example. - -A detour must match the real ABI, parameters, return type, and calling thread. It must also handle recursion and shutdown correctly. Call the original when the caller depends on its side effects or return value. - -Overdub snapshots the main executable's unpacked executable sections before loading mods, so signature scans are stable if another mod or direct MinHook detour later changes live code. Scan results are translated by RVA and always point into the live module. - -Managed hooks on the same target form a chain. The most recently enabled hook runs first, and the `original` pointer returned to each mod is a stable next-call thunk. Disabling or removing a hook rewires the chain without changing another mod's stored pointer. Hooks installed directly with MinHook do not join this chain and can still conflict with it. - -Hooks created through the mod API are removed after `deinit`. Manual hooks and patches are the mod's responsibility. - -## 19. Assets and Blueprint Actors - -Unreal package paths are not Windows paths. - -``` -/Game/Mods/Example/BP_ExampleMod -``` - -Mounting a package makes its content available. It does not automatically execute a Blueprint or spawn an actor. - -An asset replacement uses the same package path as the original asset. The package with the higher mount priority normally wins. Runtime mod order controls asset priority, so asset conflicts require a restart after reordering. - -A cooked Blueprint usually produces a generated class ending in `_C`: - -``` -Asset: /Game/Mods/Example/BP_ExampleMod -Class: /Game/Mods/Example/BP_ExampleMod.BP_ExampleMod_C -``` - -Overdub can load the generated class and spawn an actor using a context declared in `mod.ini`. - -Blueprint actors may be destroyed during travel or level unloading. Persistent features need to handle `EndPlay`, missing worlds, and respawning when an appropriate context becomes available again. - -Common asset problems include the wrong cooked target, an incorrect package or generated-class path, missing dependencies, etc. - -## 20. Debugging Tools - -### Logging - -```c -MOD_LOG_DEBUG(mod, "value: %d", value); -MOD_LOG_INFO(mod, "mod started"); -MOD_LOG_WARN(mod, "object not found"); -MOD_LOG_ERROR(mod, "failed to install hook"); -``` - -Log initialization stages and failures with enough context to reproduce them. Avoid hot-path spam. - -### UObject Search - -Use UObject Search instead of guessing names and layouts. It shows properties, functions, inheritance, etc. - -Selecting a result opens a reusable preview tab. Click the tab to pin it. The details panel shortcuts are: - -| Shortcut | Action | -|------------|---------------------| -| `Tab` | Select next tab | -| `Ctrl+Tab` | Select previous tab | -| `Ctrl+W` | Close selected tab | - -UFunction details have a `Call...` action. Instance functions require a compatible live target; static functions default to their class default object. Object and class inputs use searchable lists of compatible loaded UObjects, while soft references also accept unloaded paths. Conventional `WorldContext` parameters use the current world automatically. Return and out values are copied into read-only result fields after the synchronous call. - -The caller initializes and destroys reflected parameter values, but it cannot make arbitrary game functions safe. Network, latent, destructive, or internal functions can still have unintended effects. - -### UFunction Tracer - -Start with a narrow filter. Capturing every reflected call can fill the call limit and slow the game. - -Rules use this form: -``` -+target:text --target:text -``` - -`+` includes and `-` excludes. An omitted target means `func`. - -Recommended targets: -``` -self -self_outer -class -class_outer -class_inherit -func -func_outer -``` - -Include rules use OR. Any matching exclusion rejects the call. With only exclusions, all calls start included. - -Example: -``` -+class_inherit:Actor --func:Tick --self:Default__ -``` - -Matching is substring-based by default. `Ignore case` and `Exact match` apply to the whole filter. - -`Capture nested calls` records calls below an already captured call without filtering each nested call. It is useful for call trees but may produce many results. - -The tracer does not currently save parameter or return values. Captured UObject pointers may become invalid later. - -### Native debugger - -Hi-Fi RUSH is protected by VMProtect, so ordinary debugger attachment is blocked. For game builds where a working bypass is available, build the mod with PDB files and debug the first invalid write rather than only the later crash. - -When reporting a crash, keep: -- `overdub.log` -- stack trace -- game and store version -- Overdub version -- mod version -- installed mod list -- exact reproduction steps -- PDB files for native mods - -## 21. Reload-Safe Checklist -### `init` -- reset per-run globals -- acquire required config handles -- allocate state -- resolve required classes and functions -- register managed hooks, listeners, and commands -- start threads only after all shared state is ready -- return `false` on a required initialization failure - -### Runtime -- validate cached UObject pointers -- handle world and level changes -- keep callbacks fast -- avoid hot-path logging -- guard recursive hooks -- copy borrowed data before passing it to workers -- never retain parameter buffers, `FFrame`, result pointers, or scratch pointers - -### `deinit` -- mark the mod as shutting down -- stop producing new jobs -- disable unmanaged callbacks -- signal and join threads -- restore manual patches -- unregister direct engine callbacks and delegates -- release handles, COM objects, and external memory -- clear UObject and arena pointers -- return only after no code can call into the DLL - -## 22. Source Map -When this guide and the implementation disagree, check the code. - -| Area | Source | -|----------------------------------|------------------------------------------| -| Loader entry and main callbacks | `src/main.c` | -| Signatures and core engine hooks | `src/signatures.c` | -| Manifest parser and lifecycle | `src/mod_manager.c` | -| Exported mod operations | `src/mod_host.c`, `include/mod.h` | -| Public mod ABI | `include/mod.h` | -| Shared utility APIs | `include/`, `src/` | -| Unreal helpers | `include/unreal.h`, `src/unreal.c` | -| Nuklear API | `include/vendor_nuklear.h`, `vendor/` | -| D3D12 overlay | `src/nk_d3d12.c` | -| Built-in tool examples | `src/builtin/` | +The public C declarations are in [`include`](../include). The headers are the final reference for function signatures and structure fields. The guides explain how the API is meant to be used. diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md new file mode 100644 index 0000000..4cf73b5 --- /dev/null +++ b/docs/TROUBLESHOOTING.md @@ -0,0 +1,47 @@ +# Troubleshooting + +Start with `overdub.log`. It records loader startup, package parsing, DLL errors, Lua errors, and asset mount failures. + +## Overdub does not load + +Check that `overdub.dll` and the correct bootstrap DLL are beside the game executable. Steam and Epic use `XAPOFX1_5.dll`; Xbox and Game Pass use `dsound.dll`. + +Remove UE4SS and other proxy DLL loaders from the same directory. Make sure the Overdub release supports the installed game build. + +If the game runs but does not create `overdub.log` or `mods`, the bootstrap did not load Overdub. + +## A window does not open + +The mod manager uses the backtick key by default, not the apostrophe key. A keyboard layout or another application may intercept it. Change the shortcut in `overdub-config.ini` while the game is closed if the Settings window cannot be reached. + +Wait until the game has finished its first loading sequence before deciding that the overlay failed. + +## A mod is missing + +Each mod needs its own directory and a valid `mod.ini`. Its ID must be unique. Restart the game after adding the directory because package discovery happens at startup. + +Manifest errors are written to `overdub.log`. + +## A native mod fails + +Open the mod's Code section and read the error. Common causes are a missing DLL, a wrong `path`, an incompatible API version, or a failed `init` callback. + +A reload can fail when the old DLL left a thread or unmanaged callback running. Restart the game before assuming that the newly built DLL is broken. + +## A Lua mod fails + +The log includes the Lua message and stack trace. Confirm that the manifest selects the intended runtime. Native Overdub Lua is the default. Existing UE4SS scripts must set `runtime = ue4ss`. + +Module names use Lua's `require` rules. Check the entry directory, the mod directory, the module filename, and the exported name of any C module. + +## An asset mod fails + +Check the Assets section and the log for mount errors. A `.utoc` file needs its matching `.ucas` file. Package paths and cooked target versions must match the game. + +Asset changes and mod order changes require a restart. + +## The game crashes + +Overdub's error handler copies the stack trace to the clipboard. Save it before launching the game again. Also keep `overdub.log` and note the last action that reproduced the crash. + +Test once without the newest third-party mod. If the crash belongs to a mod, report it to that mod's author. A useful report contains the exact steps, game store and version, Overdub version, installed mod list, stack trace, and log. Native mod authors should keep the matching PDB files. diff --git a/docs/USING_OVERDUB.md b/docs/USING_OVERDUB.md new file mode 100644 index 0000000..6fe9f3c --- /dev/null +++ b/docs/USING_OVERDUB.md @@ -0,0 +1,84 @@ +# Using Overdub + +Overdub opens its windows on top of the game. The default shortcuts are backtick for the mod manager, F1 for the console, F2 for UObject Search, and F3 for UFunction Tracer. The shortcuts can be changed in Settings. + +## Install a mod + +Extract a mod into its own directory under `mods`. The directory must contain `mod.ini`. + +``` +mods/ ++-- author.example/ + |-- mod.ini + |-- config.ini + |-- example.dll + |-- scripts/ + | +-- main.lua + +-- assets/ +``` + +Restart the game after adding or removing a mod. Overdub discovers packages and mounts assets during startup. + +## Mod manager + +Select a mod on the left to see its status and controls. A green status means that at least one part is active. Gray means inactive. Red means that something failed. + +![Selected mod details](images/mod-details.png) + +Enable and Disable control the complete mod. Native DLL and Lua code can be stopped while the game is running. Mounted assets cannot be safely removed, so asset changes still require a restart. + +The Code section can start, stop, restart, or reload a native DLL. Reload is intended for development. It is safe only when the mod releases its hooks, callbacks, threads, and other external state before the DLL is unloaded. + +The Config section edits options declared by a mod. Save writes the values to `config.ini`. Discard restores the last saved values. Restore defaults changes the current values to their defaults; use Save if those values should remain after restart. + +Blueprint entries can be spawned or despawned from their section. A spawn can fail while the required world, pawn, controller, or other context does not exist. + +## Mod order + +Use Reorder mods to change startup order and asset priority, then restart the game. Runtime callbacks are processed in mod order. When asset packages conflict, a package later in the order normally has priority. + +![Reorder mods](images/reorder-mods.png) + +## Settings + +Settings controls the mod directory, window shortcuts, console behavior, and other loader options. Press Apply to save changes. Changing the mod directory requires a restart. + +![Overdub settings](images/settings.png) + +## Console + +The console shows messages from Overdub and mods. Commands registered by Overdub or a mod start with a colon. +``` +:help +``` + +The `unreal` command sends the remaining text to Unreal's console command paths and prints captured text when the engine produces any: +``` +:unreal stat fps +``` + +Some Unreal commands change state without printing output. Commands, console variables, and older `FExec` handlers do not all use the same engine path, so availability depends on the game build. + +The UI console contains only the current session. Use `overdub.log` for startup errors and older messages. + +![Overdub console](images/console.png) + +## UObject Search + +UObject Search inspects objects that are currently loaded. Search by name or type, select a result, and inspect its reflected properties and functions. + +UFunction pages can open a call dialog. The dialog validates the target and input types, initializes reflected parameters, calls the function synchronously, and shows return and output values. This does not make arbitrary game functions safe. A function may change game state, destroy objects, or depend on context that the tool cannot infer. + +![UObject Search](images/uobject-search.png) + +## UFunction Tracer + +UFunction Tracer records reflected calls that match its filters. Start with a narrow filter, begin capture, perform the action in game, and stop capture before inspecting the result. +``` ++func:OnBeat +-func:Tick +``` + +An include rule starts with `+`. An exclude rule starts with `-`. Broad tracing can create a large amount of work and may slow the game. + +![UFunction Tracer](images/ufunction-tracer.png) diff --git a/docs/lua/Overdub.lua b/docs/lua/Overdub.lua new file mode 100644 index 0000000..0b4629d --- /dev/null +++ b/docs/lua/Overdub.lua @@ -0,0 +1,69 @@ +---@meta + +---@class OverdubLog +---@field Debug fun(format: string, ...: any) +---@field Info fun(format: string, ...: any) +---@field Warn fun(format: string, ...: any) +---@field Error fun(format: string, ...: any) + +---@class OverdubCommandHandle +local Command = {} + +---@return boolean removed_now +function Command:Remove() end + +---@return boolean +function Command:IsActive() end + +---@class OverdubDirectoryEntry +---@field Name string +---@field Path string +---@field IsDirectory boolean +---@field Size integer + +---@class OverdubIniSection +---@field Name string +---@field Argument string? +---@field Lines string[] +---@field Values table + +---@class OverdubModule +---@field Id string Stable ID from mod.ini. +---@field Name string Display name from mod.ini. +---@field GameDir string Game installation directory. +---@field RootDir string Root directory containing installed mods. +---@field ModDir string Directory of the current mod. +---@field Log OverdubLog +local overdub = {} + +---@return integer +function overdub.Frame() end + +---@return integer +function overdub.NowUs() end + +---@param name string +---@param callback fun(args: string) +---@return OverdubCommandHandle +function overdub.RegisterCommand(name, callback) end + +---@param path string +---@param pattern? string +---@return OverdubDirectoryEntry[]? entries +---@return string? error +function overdub.ListDirectory(path, pattern) end + +---@param path string +---@return OverdubIniSection[]? sections +---@return string? error +function overdub.ReadIni(path) end + +---@class OverdubLifecycle +---@field Startup? fun() +---@field Tick? fun(delta_seconds: number) +---@field Input? fun(event: OverdubInputEvent): boolean? +---@field DrawPanel? fun(context: OverdubUIContext) +---@field DrawConfig? fun(context: OverdubUIContext) +---@field Shutdown? fun() + +return overdub diff --git a/docs/lua/Types.lua b/docs/lua/Types.lua new file mode 100644 index 0000000..aeea786 --- /dev/null +++ b/docs/lua/Types.lua @@ -0,0 +1,834 @@ +---@meta +---@diagnostic disable: missing-return, duplicate-set-field, lowercase-global + +-- Overdub Lua API declarations. +-- +-- This is a LuaLS/EmmyLua metadata file, modeled after UE4SS's Types.lua. +-- It documents the API implemented by this Overdub revision and must not be +-- required or executed by a mod. This file describes the UE4SS compatibility +-- runtime. Reflected UFunction calls are automatically bridged to the game +-- thread; use ExecuteInGameThread for multi-step game-state operations. + +---@alias UnrealName string|FName +---@alias UnrealClassFilter string|FName|UClass +---@alias UnrealKey integer|string +---@alias ScheduledActionHandle integer +---@alias PropertyType string + +---@class EObjectFlagsTable +---@field RF_NoFlags integer +---@field RF_Public integer +---@field RF_Standalone integer +---@field RF_MarkAsNative integer +---@field RF_Transactional integer +---@field RF_ClassDefaultObject integer +---@field RF_ArchetypeObject integer +---@field RF_Transient integer +---@field RF_MarkAsRootSet integer +---@field RF_TagGarbageTemp integer +---@field RF_NeedInitialization integer +---@field RF_NeedLoad integer +---@field RF_KeepForCooker integer +---@field RF_NeedPostLoad integer +---@field RF_NeedPostLoadSubobjects integer +---@field RF_NewerVersionExists integer +---@field RF_BeginDestroyed integer +---@field RF_FinishDestroyed integer +---@field RF_BeingRegenerated integer +---@field RF_DefaultSubObject integer +---@field RF_WasLoaded integer +---@field RF_TextExportTransient integer +---@field RF_LoadCompleted integer +---@field RF_InheritableComponentTemplate integer +---@field RF_DuplicateTransient integer +---@field RF_StrongRefOnFrame integer +---@field RF_NonPIEDuplicateTransient integer +---@field RF_Dynamic integer +---@field RF_WillBeLoaded integer +---@field RF_HasExternalPackage integer + +---@type EObjectFlagsTable +EObjectFlags = {} + +---@class EInternalObjectFlagsTable +---@field ReachableInCluster integer +---@field ClusterRoot integer +---@field Native integer +---@field Async integer +---@field AsyncLoading integer +---@field Unreachable integer +---@field PendingKill integer +---@field RootSet integer +---@field GarbageCollectionKeepFlags integer +---@field AllFlags integer + +---@type EInternalObjectFlagsTable +EInternalObjectFlags = {} + +---@class EFindNameTable +---@field FNAME_Find integer Do not create a missing name. +---@field FNAME_Add integer Find or add the name. + +---@type EFindNameTable +EFindName = {} + +---@class PropertyTypesTable +---@field ObjectProperty PropertyType +---@field ObjectPtrProperty PropertyType Alias of ObjectProperty on UE 4.27. +---@field Int8Property PropertyType +---@field Int16Property PropertyType +---@field IntProperty PropertyType +---@field Int32Property PropertyType +---@field Int64Property PropertyType +---@field NameProperty PropertyType +---@field FloatProperty PropertyType +---@field DoubleProperty PropertyType +---@field StrProperty PropertyType +---@field ByteProperty PropertyType +---@field UInt16Property PropertyType +---@field UIntProperty PropertyType Alias of UInt32Property. +---@field UInt32Property PropertyType +---@field UInt64Property PropertyType +---@field BoolProperty PropertyType +---@field ArrayProperty PropertyType +---@field SetProperty PropertyType +---@field MapProperty PropertyType +---@field StructProperty PropertyType +---@field ClassProperty PropertyType +---@field SoftObjectProperty PropertyType +---@field SoftClassProperty PropertyType +---@field WeakObjectProperty PropertyType +---@field LazyObjectProperty PropertyType +---@field EnumProperty PropertyType +---@field TextProperty PropertyType +---@field InterfaceProperty PropertyType +---@field DelegateProperty PropertyType +---@field MulticastDelegateProperty PropertyType + +---@type PropertyTypesTable +PropertyTypes = {} + +---@class FName +local FNameType = {} + +---@return string +function FNameType:ToString() end + +---@return integer +function FNameType:GetComparisonIndex() end + +---@param other FName +---@return boolean +function FNameType:Equals(other) end + +---@return 'FName' +function FNameType:type() end + +---@param value string|integer|FName +---@param find_type? integer EFindName.FNAME_Find or EFindName.FNAME_Add. +---@return FName +function FName(value, find_type) end + +---@type FName +NAME_None = nil + +---@class FText +local FTextType = {} + +---@return string +function FTextType:ToString() end + +---@return 'FText' +function FTextType:type() end + +---@param value string +---@return FText +function FText(value) end + +---@class FString +local FString = {} + +---@return string +function FString:ToString() end + +function FString:Empty() end +function FString:Clear() end + +---@return integer +function FString:Len() end + +---@return boolean +function FString:IsEmpty() end + +---@param value string|FString +function FString:Append(value) end + +---@param value string +---@return integer? index One-based byte index, or nil when absent. +function FString:Find(value) end + +---@param prefix string +---@return boolean +function FString:StartsWith(prefix) end + +---@param suffix string +---@return boolean +function FString:EndsWith(suffix) end + +---@return FString +function FString:ToUpper() end + +---@return FString +function FString:ToLower() end + +---@return boolean +function FString:IsValid() end + +---@return 'FString' +function FString:type() end + +---@class RemoteUnrealParam +local RemoteUnrealParam = {} + +---@generic T +---@return T +function RemoteUnrealParam:Get() end + +---@generic T +---@return T +function RemoteUnrealParam:get() end + +---@generic T +---@param value T +function RemoteUnrealParam:Set(value) end + +---@generic T +---@param value T +function RemoteUnrealParam:set(value) end + +---@return boolean +function RemoteUnrealParam:IsValid() end + +---@return 'RemoteUnrealParam'|'LocalUnrealParam' +function RemoteUnrealParam:type() end + +---@class LocalUnrealParam: RemoteUnrealParam + +---@class TArray: { [integer]: T } +local TArray = {} + +---@return integer +function TArray:Num() end + +---@return integer +function TArray:GetArrayNum() end + +---@return integer +function TArray:GetArrayAddress() end + +---@return integer +function TArray:GetArrayMax() end + +---@return integer +function TArray:GetArrayDataAddress() end + +---@generic T +---@param callback fun(index: integer, element: LocalUnrealParam): boolean? +function TArray:ForEach(callback) end + +---@generic T +---@return T[] +function TArray:ToTable() end + +function TArray:Empty() end +function TArray:Clear() end + +---@generic T +---@param value T +---@return integer index One-based index. +function TArray:Add(value) end + +---@generic T +---@param index integer One-based insertion index. +---@param value T +function TArray:Insert(index, value) end + +---@generic T +---@param value T +---@return boolean +function TArray:Contains(value) end + +---@param index integer One-based removal index. +---@return boolean +function TArray:Remove(index) end + +---@return boolean +function TArray:IsValid() end + +---@return 'TArray' +function TArray:type() end + +---@class TSet +local TSet = {} + +---@return integer +function TSet:Num() end + +---@generic T +---@param value T +---@return integer +function TSet:Add(value) end + +---@generic T +---@param value T +---@return boolean +function TSet:Contains(value) end + +---@generic T +---@param value T +---@return boolean +function TSet:Remove(value) end + +function TSet:Empty() end +function TSet:Clear() end + +---@generic T +---@param callback fun(element: T): boolean? +function TSet:ForEach(callback) end + +---@generic T +---@return T[] +function TSet:ToTable() end + +---@return boolean +function TSet:IsValid() end + +---@return 'TSet' +function TSet:type() end + +---@class TMap: { [K]: V } +local TMap = {} + +---@return integer +function TMap:Num() end + +---@generic K, V +---@param key K +---@return V +function TMap:Find(key) end + +---@generic K, V +---@param key K +---@param value V +function TMap:Add(key, value) end + +---@generic K +---@param key K +---@return boolean +function TMap:Contains(key) end + +---@generic K +---@param key K +---@return boolean +function TMap:Remove(key) end + +function TMap:Empty() end +function TMap:Clear() end + +---@generic K, V +---@param callback fun(key: RemoteUnrealParam, value: RemoteUnrealParam): boolean? +function TMap:ForEach(callback) end + +---@generic K, V +---@return table +function TMap:ToTable() end + +---@return boolean +function TMap:IsValid() end + +---@return 'TMap' +function TMap:type() end + +---@class UScriptStructValue +local UScriptStructValue = {} + +---@return boolean +function UScriptStructValue:IsValid() end + +---@return 'UScriptStruct' +function UScriptStructValue:type() end + +---@class UDataTableRow: UScriptStructValue +local UDataTableRow = {} + +---@return string +function UDataTableRow:ToString() end + +---@class FieldClass +local FieldClass = {} + +---@return boolean +function FieldClass:IsValid() end + +---@return FName +function FieldClass:GetFName() end + +---@return 'FieldClass' +function FieldClass:type() end + +---@class Property +local Property = {} + +---@return boolean +function Property:IsValid() end + +---@return string +function Property:GetFullName() end + +---@return FName +function Property:GetFName() end + +---@param property_type PropertyType|FName|FieldClass +---@return boolean +function Property:IsA(property_type) end + +---@return FieldClass +function Property:GetClass() end + +---@return integer +function Property:GetOffset_Internal() end + +---@return integer +function Property:GetArrayDim() end + +---@return integer +function Property:GetElementSize() end + +---@return UClass +function Property:GetPropertyClass() end + +---@return integer +function Property:GetByteMask() end + +---@return integer +function Property:GetByteOffset() end + +---@return integer +function Property:GetFieldMask() end + +---@return integer +function Property:GetFieldSize() end + +---@return UScriptStruct +function Property:GetStruct() end + +---@return Property +function Property:GetInner() end + +---@return Property +function Property:GetElementProperty() end + +---@return Property +function Property:GetKeyProperty() end + +---@return Property +function Property:GetValueProperty() end + +---@return Property +function Property:GetUnderlyingProperty() end + +---@return UEnum? +function Property:GetEnum() end + +---@return 'Property' +function Property:type() end + +---@class UObjectReflection +local UObjectReflection = {} + +---@return boolean +function UObjectReflection:IsValid() end + +---Returns an invalid Property handle, rather than nil, when the property is absent. +---@param property_name UnrealName +---@return Property +function UObjectReflection:GetProperty(property_name) end + +---@return 'UObjectReflection' +function UObjectReflection:type() end + +---@class UObject +local UObject = {} + +---@return boolean +function UObject:IsValid() end + +---@return string +function UObject:GetFullName() end + +---@return FName +function UObject:GetFName() end + +---@return integer +function UObject:GetAddress() end + +---@return UClass +function UObject:GetClass() end + +---@return UObject +function UObject:GetOuter() end + +---@return UWorld? +function UObject:GetWorld() end + +---@return boolean +function UObject:IsAnyClass() end + +---@return boolean +function UObject:IsClass() end + +---@param class UClass|string +---@return boolean +function UObject:IsA(class) end + +---@param flags integer +---@return boolean +function UObject:HasAllFlags(flags) end + +---@param flags integer +---@return boolean +function UObject:HasAnyFlags(flags) end + +---@param flags integer +---@return boolean +function UObject:HasAnyInternalFlags(flags) end + +---@return UObjectReflection +function UObject:Reflection() end + +---@param property_name string +---@return any +function UObject:GetPropertyValue(property_name) end + +---@param property_name string +---@param value any +function UObject:SetPropertyValue(property_name, value) end + +---@param func UFunction +---@param ... any +---@return ... any +function UObject:CallFunction(func, ...) end + +---@return string +function UObject:type() end + +---@class UWorld: UObject + +---@class UStruct: UObject +local UStruct = {} + +---@return UStruct? +function UStruct:GetSuperStruct() end + +---@param callback fun(func: UFunction): boolean? +function UStruct:ForEachFunction(callback) end + +---Iterates only properties declared directly by this struct; walk GetSuperStruct for inherited fields. +---@param callback fun(property: Property): boolean? +function UStruct:ForEachProperty(callback) end + +---@class UScriptStruct: UStruct + +---@class UClass: UStruct +local UClass = {} + +---@return UObject +function UClass:GetCDO() end + +---@param parent UClass +---@return boolean +function UClass:IsChildOf(parent) end + +---@class UFunction: UStruct +local UFunction = {} + +---@return integer +function UFunction:GetFunctionFlags() end + +---@param flags integer +function UFunction:SetFunctionFlags(flags) end + +---@param receiver UObject +---@param ... any +---@return ... any +function UFunction:__call(receiver, ...) end + +---@class UEnum: UObject +local UEnum = {} + +---@param value integer +---@return FName? +function UEnum:GetNameByValue(value) end + +---@param callback fun(name: FName, value: integer): boolean? +function UEnum:ForEachName(callback) end + +---@param index integer Zero-based index. +---@return FName?, integer? +function UEnum:GetEnumNameByIndex(index) end + +---@param index integer Zero-based index. +---@param name string|FName +function UEnum:EditNameAt(index, name) end + +---@param index integer Zero-based index. +---@param value integer +function UEnum:EditValueAt(index, value) end + +---@class UDataTable: UObject +local UDataTable = {} + +---@return UScriptStruct +function UDataTable:GetRowStruct() end + +---@return table +function UDataTable:GetRowMap() end + +---@param row_name UnrealName +---@return UDataTableRow? +function UDataTable:FindRow(row_name) end + +---@param row_name UnrealName +---@param row UDataTableRow|UScriptStructValue|table +function UDataTable:AddRow(row_name, row) end + +---@param row_name UnrealName +function UDataTable:RemoveRow(row_name) end + +function UDataTable:EmptyTable() end + +---@return string[] +function UDataTable:GetRowNames() end + +---@class UDataTableNamedRow +---@field Name string +---@field Data UDataTableRow + +---@return UDataTableNamedRow[] +function UDataTable:GetAllRows() end + +---@param callback fun(name: string, row: UDataTableRow): boolean? +function UDataTable:ForEachRow(callback) end + +---@class UnrealAPI +---@field EObjectFlags EObjectFlagsTable +---@field EInternalObjectFlags EInternalObjectFlagsTable +---@field EFindName EFindNameTable +---@field PropertyTypes PropertyTypesTable +---@field NAME_None FName +local UnrealAPI = {} + +---@overload fun(name: string): UObject +---@overload fun(class: UClass?, outer: UObject?, name: string, exact_class?: boolean): UObject +---@param class_or_name UnrealClassFilter? +---@param object_name UnrealName? +---@param required_flags? integer +---@param banned_flags? integer +---@return UObject An invalid UObject handle is returned when no object matches. +function UnrealAPI.StaticFindObject(class_or_name, object_name, required_flags, banned_flags) end + +---@overload fun(name: string): UObject +---@overload fun(class: UClass?, outer: UObject?, name: string, exact_class?: boolean): UObject +---@param class_or_name UnrealClassFilter? +---@param object_name UnrealName? +---@param required_flags? integer +---@param banned_flags? integer +---@return UObject An invalid UObject handle is returned when no object matches. +function UnrealAPI.FindObject(class_or_name, object_name, required_flags, banned_flags) end + +---@param limit integer Zero means unlimited. +---@param class_or_name UnrealClassFilter? +---@param object_name UnrealName? +---@param required_flags? integer +---@param banned_flags? integer +---@param exact_class? boolean +---@return UObject[] +function UnrealAPI.FindObjects(limit, class_or_name, object_name, required_flags, banned_flags, exact_class) end + +---@param class_name string +---@return UObject An invalid UObject handle is returned when no object matches. +function UnrealAPI.FindFirstOf(class_name) end + +---@param class_name string +---@return UObject[]? +function UnrealAPI.FindAllOf(class_name) end + +---@param path string +---@return UObject? +function UnrealAPI.LoadAsset(path) end + +---@param value string|integer|FName +---@param find_type? integer +---@return FName +function UnrealAPI.FName(value, find_type) end + +---@param value string +---@return FText +function UnrealAPI.FText(value) end + +---@return UObject +function UnrealAPI.CreateInvalidObject() end + +---@type UnrealAPI +Unreal = {} + +---@overload fun(name: string): UObject +---@overload fun(class: UClass?, outer: UObject?, name: string, exact_class?: boolean): UObject +---@param class_or_name UnrealClassFilter? +---@param object_name UnrealName? +---@param required_flags? integer +---@param banned_flags? integer +---@return UObject An invalid UObject handle is returned when no object matches. +function StaticFindObject(class_or_name, object_name, required_flags, banned_flags) end + +---@overload fun(name: string): UObject +---@overload fun(class: UClass?, outer: UObject?, name: string, exact_class?: boolean): UObject +---@param class_or_name UnrealClassFilter? +---@param object_name UnrealName? +---@param required_flags? integer +---@param banned_flags? integer +---@return UObject An invalid UObject handle is returned when no object matches. +function FindObject(class_or_name, object_name, required_flags, banned_flags) end + +---@param limit integer +---@param class_or_name UnrealClassFilter? +---@param object_name UnrealName? +---@param required_flags? integer +---@param banned_flags? integer +---@param exact_class? boolean +---@return UObject[] +function FindObjects(limit, class_or_name, object_name, required_flags, banned_flags, exact_class) end + +---@param class_name string +---@return UObject An invalid UObject handle is returned when no object matches. +function FindFirstOf(class_name) end + +---@param class_name string +---@return UObject[]? +function FindAllOf(class_name) end + +---@param path string +---@return UObject? +function LoadAsset(path) end + +---@return UObject +function CreateInvalidObject() end + +---@class ModRefTable +local ModRefTable = {} + +---@param key any +---@return any +function ModRefTable:GetSharedVariable(key) end + +---@param key any +---@param value any +function ModRefTable:SetSharedVariable(key, value) end + +---@type ModRefTable +ModRef = {} + +---@class GameDirectory: table +---@field __absolute_path string + +---@return GameDirectory +function IterateGameDirectories() end + +---@param name string +---@param callback fun(full_command: string, parameters: string[], output_device: nil): boolean? +function RegisterConsoleCommandHandler(name, callback) end + +---@param name string +---@param callback fun(full_command: string, parameters: string[], output_device: nil): boolean? +function RegisterConsoleCommandGlobalHandler(name, callback) end + +---@overload fun(key: UnrealKey, callback: fun()): boolean +---@param key UnrealKey +---@param modifiers integer[] +---@param callback fun() +---@return boolean +function RegisterKeyBind(key, modifiers, callback) end + +RegisterKeyBindAsync = RegisterKeyBind + +---@param key UnrealKey +---@param modifiers? integer[] +---@return boolean +function IsKeyBindRegistered(key, modifiers) end + +---Runs on the compatibility worker with a deep snapshot of the reflected +---parameters. Setting a RemoteUnrealParam changes only that snapshot and does +---not alter the original Unreal call +---@param target string +---@param pre? fun(self: RemoteUnrealParam, ...: RemoteUnrealParam) +---@param post? fun(self: RemoteUnrealParam, ...: RemoteUnrealParam) +---@return integer pre_id, integer post_id +function RegisterHook(target, pre, post) end + +---@param target string +---@param pre_id integer +---@param post_id integer +function UnregisterHook(target, pre_id, post_id) end + +---Queues the callback to the compatibility worker +---@param class_path string +---@param callback fun(object: UObject) +function NotifyOnNewObject(class_path, callback) end + +---@param callback fun() +function ExecuteInGameThread(callback) end + +---@return boolean +function IsInGameThread() end + +---@overload fun(handle: ScheduledActionHandle, delay_ms: integer, callback: fun()): ScheduledActionHandle +---@param delay_ms integer +---@param callback fun() +---@return ScheduledActionHandle +function ExecuteInGameThreadWithDelay(delay_ms, callback) end + +---@param callback fun() +function ExecuteAsync(callback) end + +---@param delay_ms integer +---@param callback fun() +function ExecuteWithDelay(delay_ms, callback) end + +---@param delay_ms integer +---@param callback fun(): boolean? +function LoopAsync(delay_ms, callback) end + +---@param frame_count integer +---@param callback fun(): boolean? +---@return ScheduledActionHandle +function LoopInGameThreadAfterFrames(frame_count, callback) end + +---@param handle ScheduledActionHandle +---@return boolean +function CancelDelayedAction(handle) end + +---@type table +Key = {} + +---@class ModifierKeyTable +---@field SHIFT integer +---@field CONTROL integer +---@field ALT integer + +---@type ModifierKeyTable +ModifierKey = {} + +-- Intentional compatibility boundaries in this revision: +-- Property:ContainerPtrToValuePtr and Property:ImportText are not exposed; +-- direct UObject/row indexing and assignment provide lifetime-safe access. +-- UEnum insertion/removal and UObject:ProcessConsoleExec are also not exposed. diff --git a/docs/lua/c-modules.md b/docs/lua/c-modules.md new file mode 100644 index 0000000..b3dd34e --- /dev/null +++ b/docs/lua/c-modules.md @@ -0,0 +1,162 @@ +# Lua C Modules + +Overdub uses ordinary Lua 5.4 C modules for native interoperation. There is no separate typed-call or signature-scanning Lua package. A C module can express the real C structures, calling convention, hooks, and cleanup rules without another foreign-function type system. + +Pure Lua dependencies need no special support. Place a vendored file such as `dkjson.lua` in the mod directory and load it with `require("dkjson")`. + +## Small C module + +Include `overdub_lua.h`. It provides the Lua headers and the export macro. + +```c +#include "overdub_lua.h" + +static int +math_add(lua_State *state) +{ + lua_Integer left = luaL_checkinteger(state, 1); + lua_Integer right = luaL_checkinteger(state, 2); + + lua_pushinteger(state, left + right); + return 1; +} + +OVERDUB_LUA_MODULE int +luaopen_example_native(lua_State *state) +{ + static const luaL_Reg functions[] = { + {"Add", math_add}, + {NULL, NULL }, + }; + + luaL_newlib(state, functions); + return 1; +} +``` + +Build it as `example_native.dll`, place it beside `main.lua` or in the mod directory, and require it by the matching export name: + +```lua +local native = require("example_native") +print(native.Add(20, 22)) +``` + +The DLL links against the same `overdub.lib` as a native mod. + +## Expose a C structure + +Use full userdata when Lua should own a C value. The metatable defines its methods and finalizer. + +```c +#include "overdub_lua.h" + +#define COUNTER_META "example.Counter" + +typedef struct counter_s counter_t; +struct counter_s { + int value; +}; + +static counter_t * +counter_check(lua_State *state, int index) +{ + return luaL_checkudata(state, index, COUNTER_META); +} + +static int +counter_new(lua_State *state) +{ + counter_t *counter = lua_newuserdatauv(state, sizeof(*counter), 0); + counter->value = (int)luaL_optinteger(state, 1, 0); + luaL_setmetatable(state, COUNTER_META); + return 1; +} + +static int +counter_add(lua_State *state) +{ + counter_t *counter = counter_check(state, 1); + counter->value += (int)luaL_checkinteger(state, 2); + lua_pushinteger(state, counter->value); + return 1; +} + +OVERDUB_LUA_MODULE int +luaopen_example_counter(lua_State *state) +{ + if (luaL_newmetatable(state, COUNTER_META)) { + static const luaL_Reg methods[] = { + {"Add", counter_add}, + {NULL, NULL }, + }; + + luaL_setfuncs(state, methods, 0); + lua_pushvalue(state, -1); + lua_setfield(state, -2, "__index"); + } + lua_pop(state, 1); + + lua_newtable(state); + lua_pushcfunction(state, counter_new); + lua_setfield(state, -2, "New"); + return 1; +} +``` + +```lua +local counter = require("example_counter").New(10) +print(counter:Add(5)) +``` + +Use `__gc` when userdata owns memory, handles, or library objects. An explicit `Close` method is also useful when cleanup should happen before Lua garbage collection. + +## Existing native libraries + +A C module is the intended bridge for a library such as an Archipelago client DLL. Keep the library's native details inside C and expose a small Lua-facing object. + +```lua +local archipelago = require("hbk_archipelago") + +local client + +return { + Startup = function() + client = assert(archipelago.New({ + host = "archipelago.gg:38281", + slot = "Chai", + password = "", + })) + end, + + Tick = function(delta_seconds) + for _, event in ipairs(client:Poll()) do + handle_archipelago_event(event) + end + end, + + Shutdown = function() + if client then + client:Close() + client = nil + end + end, +} +``` + +`Poll` should return quickly. The C library may do socket work on its own thread, place copied events in a queue, and let Lua drain a bounded number from `Tick`. It must not call the game-thread Lua state from its network thread. + +This pattern does not require Overdub to provide networking or JSON. The mod chooses its native client and can vendor a Lua JSON parser when needed. + +## Game-thread and worker states + +A module loaded by the main mod state runs its Lua functions on the game thread. Keep those functions bounded. A blocking C call cannot be stopped by Lua's execution hook. + +A worker state can require the same module when the DLL supports worker-thread use. Lua values and userdata still cannot cross from that state to the game-thread state. Return serializable values from the worker function. + +Windows loads one DLL image into the process, so C static variables may be shared by several Lua states even though Lua userdata is not. Protect shared native state when a module is used by both the game thread and a worker. + +## Lifetime + +An ordinary C module does not receive the native mod callback table. Its lifecycle comes from the Lua values it creates and the Lua mod's `Startup` and `Shutdown` callbacks. + +Close threads, sockets, hooks, and other external resources explicitly during `Shutdown`. Use userdata finalizers as a fallback, not as the only timely shutdown path. No background thread may call Lua after its state starts closing. diff --git a/docs/lua/overdub-runtime.md b/docs/lua/overdub-runtime.md new file mode 100644 index 0000000..c3f0dd5 --- /dev/null +++ b/docs/lua/overdub-runtime.md @@ -0,0 +1,181 @@ +# Native Overdub Lua + +The native runtime is the default for new Lua mods. It provides a small lifecycle, game-thread Unreal access, cooperative tasks, worker jobs, input, and UI. + +Each mod owns one Lua 5.4 state. That state belongs to the game thread. It does not receive UE4SS globals; import Overdub APIs with `require`. + +## First mod + +Create this package: +``` +example-mod/ +|-- mod.ini ++-- scripts/ + +-- main.lua +``` + +```ini +[info] +id = author.example +name = Example Lua Mod +author = Author Name +version = 1.0.0 +kind = mod + +[lua] +runtime = overdub +``` + +The entry script is an ordinary Lua module. It returns a table of lifecycle callbacks. +```lua +local overdub = require("overdub") + +return { + Startup = function() + overdub.Log.Info("Loaded %s", overdub.Name) + end, + + Tick = function(delta_seconds) + end, + + Input = function(event) + return false + end, + + DrawPanel = function(ctx) + ctx:Text("Running") + end, + + DrawConfig = function(ctx) + end, + + Shutdown = function() + overdub.Log.Info("Stopped") + end, +} +``` + +All fields are optional, but every present field must be a function. The loader executes the chunk, validates the returned table, calls `Startup`, and only then marks the mod active. An entry or startup error closes the state and leaves the mod inactive. + +A failing runtime callback is disabled without stopping unrelated parts of the mod. `Shutdown` runs when a successfully started mod stops. + +## Core module + +`require("overdub")` returns the current mod's identity and common helpers. +```lua +local overdub = require("overdub") + +overdub.Log.Info("id=%s frame=%d", overdub.Id, overdub.Frame()) +overdub.Log.Debug("game=%s", overdub.GameDir) +overdub.Log.Debug("mods=%s", overdub.RootDir) +overdub.Log.Debug("this mod=%s", overdub.ModDir) +``` + +`NowUs` returns the runtime's monotonic microsecond clock. It is useful for local measurements. + +Console commands belong to the mod and are removed at shutdown: +```lua +local command = overdub.RegisterCommand("example.status", function(args) + overdub.Log.Info("status args: %s", args) +end) + +if command:IsActive() then + -- command:Remove() can unregister it early. +end +``` + +## Lua modules + +The runtime opens the normal `package`, `io`, and `os` libraries. It prepends the entry-script directory and `ModDir` to `package.path` and `package.cpath`. +``` +example-mod/ +|-- mod.ini +|-- dkjson.lua ++-- scripts/ + |-- main.lua + +-- state.lua +``` + +```lua +local json = require("dkjson") +local state = require("state") +``` + +This is also how a mod loads its own Lua 5.4 C module. See [Lua C Modules](c-modules.md). + +## Directories and INI files + +`ListDirectory` accepts any path and an optional pattern. It returns file records with `Name`, `Path`, `IsDirectory`, and `Size`. +```lua +local entries, message = overdub.ListDirectory(overdub.ModDir .. "/data", "*.json") +if not entries then + overdub.Log.Error("cannot list data: %s", message) +else + for _, entry in ipairs(entries) do + overdub.Log.Info("%s", entry.Path) + end +end +``` + +`ReadIni` preserves section order and repeated sections. Each result has `Name`, optional `Argument`, original `Lines`, and parsed `Values`. +```lua +local sections = assert(overdub.ReadIni(overdub.ModDir .. "/mod.ini")) + +for _, section in ipairs(sections) do + if section.Name == "archipelago" then + local host = section.Values.host + local slot = section.Values.slot + connect(host, slot) + end +end +``` + +The same helper can read `config.ini` or another INI owned by the mod. Standard Lua file functions remain available when the mod needs another format. + +## Input + +Polling normally belongs in `Tick`. Key names are Unreal `FKey` names such as `F8`, `SpaceBar`, `LeftMouseButton`, and `Gamepad_FaceButton_Bottom`. +```lua +local input = require("overdub.input") + +return { + Tick = function(delta_seconds) + if input.Pressed("F8") then + toggle_feature() + end + + local left_x = input.Analog("Gamepad_LeftX") + local mouse_x, mouse_y = input.MousePosition() + end, + + Input = function(event) + if event.Kind == "KeyDown" and event.Key == "F9" then + return true + end + end, +} +``` + +`Down` reports held state. `Pressed` and `Released` report edges for the current frame. `Analog`, `WheelDelta`, and `MousePosition` expose the remaining polled state. + +An input event is an immutable snapshot. Its common fields include `Kind`, `Key`, `Pressed`, `Released`, `Repeat`, `Shift`, `Ctrl`, `Alt`, `Keyboard`, `Mouse`, and `Gamepad`. Mouse, character, analog, and activation events add fields for their own values. + +Return true from `Input` only when the event should be consumed. + +## Work that spans frames + +Do not perform a long scan, file parse, or blocking library call inside `Tick`. Use a cooperative task for work that must touch Unreal and a worker job for work that uses only copied Lua data. + +The complete examples are in [Tasks and Workers](tasks.md). UI is covered by [Lua UI](ui.md), and reflection is covered by [Lua Unreal](unreal.md). + +## Limits and cleanup + +The entry script has a 2 ms Lua execution limit. Ordinary Lua callbacks have a 250 us hard limit. Cooperative task code can use its 100 us work-budget hint to choose a yield point. Ready deferred work shares a 500 us soft frame budget and a 1 ms scheduler ceiling. + +These limits stop Lua bytecode through an instruction hook. They cannot interrupt code while Lua is inside a blocking C function. + +Tasks, worker futures, commands, hooks, delegate bindings, UI windows, notifications, and root claims are removed or cancelled when the mod stops. Keep a handle only when the mod needs to end one of them early. + +## Declarations + +Use [`Overdub.lua`](Overdub.lua) and the files under [`overdub`](overdub) as LuaLS library files. They describe the native API and should not be executed. diff --git a/docs/lua/overdub/input.lua b/docs/lua/overdub/input.lua new file mode 100644 index 0000000..3db80a7 --- /dev/null +++ b/docs/lua/overdub/input.lua @@ -0,0 +1,52 @@ +---@meta + +---@class OverdubInputEvent +---@field Kind string +---@field Key? string +---@field Pressed boolean +---@field Released boolean +---@field Repeat boolean +---@field Shift boolean +---@field Ctrl boolean +---@field Alt boolean +---@field Keyboard boolean +---@field Mouse boolean +---@field Gamepad boolean +---@field Character? integer Unicode codepoint for Character events. +---@field Activated? boolean Application activation state. +---@field ScreenX? integer +---@field ScreenY? integer +---@field ClientX? integer +---@field ClientY? integer +---@field DeltaX? number +---@field DeltaY? number +---@field WheelDelta? number +---@field AnalogValue? number + +---@class OverdubInputModule +local input = {} + +---@param key string +---@return boolean +function input.Down(key) end + +---@param key string +---@return boolean +function input.Pressed(key) end + +---@param key string +---@return boolean +function input.Released(key) end + +---@param key string +---@return number +function input.Analog(key) end + +---@return number +function input.WheelDelta() end + +---@return integer x +---@return integer y +function input.MousePosition() end + +return input diff --git a/docs/lua/overdub/task.lua b/docs/lua/overdub/task.lua new file mode 100644 index 0000000..2ce795b --- /dev/null +++ b/docs/lua/overdub/task.lua @@ -0,0 +1,76 @@ +---@meta + +---@class OverdubTask +local Task = {} + +---@return boolean cancelled_now +function Task:Cancel() end + +---@return boolean +function Task:IsDone() end + +---@return boolean +function Task:IsCancelled() end + +---@class OverdubFuture +local Future = {} + +---@return boolean +function Future:IsPending() end + +---@return boolean +function Future:IsDone() end + +---@return boolean +function Future:IsCancelled() end + +---@return boolean cancelled_now +function Future:Cancel() end + +---@param callback fun(result: any) +---@return OverdubFuture self +function Future:OnSuccess(callback) end + +---@param callback fun(message: string) +---@return OverdubFuture self +function Future:OnError(callback) end + +---@param callback fun(future: OverdubFuture) +---@return OverdubFuture self +function Future:OnComplete(callback) end + +---Waits cooperatively and must be called from a task created by task.Spawn. +---@return any result +function Future:Await() end + +---Returns the completed result or raises if pending, failed, or cancelled. +---@return any result +function Future:GetResult() end + +---@return string? +function Future:GetError() end + +---@class OverdubTaskModule +local task = {} + +---@overload fun(name: string, callback: fun()): OverdubTask +---@param callback fun() +---@return OverdubTask +function task.Spawn(callback) end + +function task.YieldFrame() end + +---@param seconds number +function task.Sleep(seconds) end + +---@return boolean +function task.ShouldYield() end + +---Runs module[function_name](value) in this mod's serialized worker Lua state. +---@param module_name string +---@param function_name string +---@param value any +---@return OverdubFuture +function task.Offload(module_name, function_name, value) end + +return task diff --git a/docs/lua/overdub/ui.lua b/docs/lua/overdub/ui.lua new file mode 100644 index 0000000..462ccc2 --- /dev/null +++ b/docs/lua/overdub/ui.lua @@ -0,0 +1,200 @@ +---@meta + +---@alias OverdubUIAlignment "Left"|"Center"|"Right" + +---@class OverdubUIColor +---@field R integer +---@field G integer +---@field B integer +---@field A? integer + +---@class OverdubUIWindow +local Window = {} + +---@return boolean removed_now +function Window:Remove() end + +---@return boolean +function Window:IsActive() end + +---@param open boolean +---@return boolean changed +function Window:SetOpen(open) end + +---@return boolean +function Window:IsOpen() end + +---@class OverdubUIContext +local Context = {} + +---@param text string +---@param alignment? OverdubUIAlignment +function Context:Text(text, alignment) end + +---@param text string +---@param color OverdubUIColor +---@param alignment? OverdubUIAlignment +function Context:TextColored(text, color, alignment) end + +---@param text string +---@param height? number +function Context:WrappedText(text, height) end + +---@param text string +---@param color OverdubUIColor +---@param height? number +function Context:WrappedTextColored(text, color, height) end + +---@param label string +---@return boolean pressed +function Context:Button(label) end + +---@param label string +---@param value boolean +---@return boolean value +function Context:Checkbox(label, value) end + +---@param label string +---@param value integer +---@param minimum integer +---@param maximum integer +---@param step? integer +---@return integer value +function Context:SliderInt(label, value, minimum, maximum, step) end + +---@param label string +---@param value number +---@param minimum number +---@param maximum number +---@param step? number +---@return number value +function Context:SliderFloat(label, value, minimum, maximum, step) end + +---@param label string +---@param value integer +---@param minimum integer +---@param maximum integer +---@param step? integer +---@return integer value +---@return boolean changed +function Context:InputInt(label, value, minimum, maximum, step) end + +---@param label string +---@param value number +---@param minimum number +---@param maximum number +---@param step? number +---@return number value +---@return boolean changed +function Context:InputFloat(label, value, minimum, maximum, step) end + +---@param label string +---@param value string +---@param maximum_length? integer +---@return string value +---@return boolean changed +---@return boolean committed +function Context:InputText(label, value, maximum_length) end + +---@param label string +---@param value string +---@param maximum_length? integer +---@return string value +---@return boolean changed +---@return boolean committed +function Context:TextInput(label, value, maximum_length) end + +---@param label string +---@param items string[] +---@param selected_index integer +---@return integer selected_index +function Context:Dropdown(label, items, selected_index) end + +---@param label string +---@param items string[] +---@param selected_index integer +---@return integer selected_index +function Context:Combo(label, items, selected_index) end + +---@param label string +---@param color OverdubUIColor +---@return OverdubUIColor color +function Context:ColorEditor(label, color) end + +---@param label string +---@param value string +---@return string value +function Context:Keybind(label, value) end + +---@param id string +---@param height number +---@param callback fun(context: OverdubUIContext) +---@return integer scroll_x +---@return integer scroll_y +function Context:Group(id, height, callback) end + +---@param id string +---@return integer scroll_x +---@return integer scroll_y +function Context:GroupScroll(id) end + +---@param id string +---@param scroll_x integer +---@param scroll_y integer +function Context:SetGroupScroll(id, scroll_x, scroll_y) end + +---@param title string +---@param expanded boolean +---@param callback fun(context: OverdubUIContext) +---@return boolean expanded +function Context:Tree(title, expanded, callback) end + +---@param text string +function Context:Tooltip(text) end + +function Context:Separator() end + +---@param count? integer +function Context:Spacing(count) end + +---@param columns integer +---@param height? number +function Context:Row(columns, height) end + +---@param columns integer +---@param width number +---@param height? number +function Context:RowStatic(columns, width, height) end + +---@param ratios number[] +---@param height? number +function Context:RowRatios(ratios, height) end + +---@param widths number[] +---@param height? number +function Context:RowWidths(widths, height) end + +---@alias OverdubUIGridColumn number|"Content"|"Flex" + +---@overload fun(self: OverdubUIContext, id: string, columns: OverdubUIGridColumn[], height: number, callback: fun(context: OverdubUIContext)) +---@param id string +---@param columns OverdubUIGridColumn[] +---@param callback fun(context: OverdubUIContext) +function Context:Grid(id, columns, callback) end + +function Context:NextRow() end + +---@return integer width +---@return integer height +function Context:ViewportSize() end + +---@class OverdubUIModule +local ui = {} + +---@overload fun(id: string, title: string, callback: fun(context: OverdubUIContext)): OverdubUIWindow +---@param id string +---@param callback fun(context: OverdubUIContext) +---@return OverdubUIWindow +function ui.RegisterWindow(id, callback) end + +return ui diff --git a/docs/lua/overdub/unreal.lua b/docs/lua/overdub/unreal.lua new file mode 100644 index 0000000..f77c093 --- /dev/null +++ b/docs/lua/overdub/unreal.lua @@ -0,0 +1,674 @@ +---@meta + +---@class UObject +local UObject = {} + +---@return boolean +function UObject:IsValid() end + +---@return string +function UObject:GetName() end + +---@return string +function UObject:GetFullName() end + +---@return string +function UObject:GetPathName() end + +---@return FName +function UObject:GetFName() end + +---@return UObject? +function UObject:GetOuter() end + +---@return UClass +function UObject:GetClass() end + +---@param class UClass|string +---@return boolean +function UObject:IsA(class) end + +---@return integer +function UObject:GetInternalIndex() end + +---@return integer +function UObject:GetAddress() end + +---@return integer +function UObject:GetFlags() end + +---@return integer +function UObject:GetInternalFlags() end + +---@param flags integer +---@return boolean +function UObject:HasAnyFlags(flags) end + +---@param flags integer +---@return boolean +function UObject:HasAllFlags(flags) end + +---@param flags integer +---@return boolean +function UObject:HasAnyInternalFlags(flags) end + +---@return boolean +function UObject:IsRooted() end + +---@return boolean claimed_now +function UObject:AddToRoot() end + +---@return boolean released_now +function UObject:RemoveFromRoot() end + +---@return boolean +function UObject:IsAnyClass() end + +---@return boolean +function UObject:IsClass() end + +---@return UObject? +function UObject:GetWorld() end + +---@param function_object UFunction +---@param ... any +---@return ... any +function UObject:CallFunction(function_object, ...) end + +---@return UObjectReflection +function UObject:Reflection() end + +---@param name string +---@return any +function UObject:GetPropertyValue(name) end + +---@param name string +---@param value any +function UObject:SetPropertyValue(name, value) end + +---@param property_name string +---@param target UObject +---@param function_object UFunction|string +---@return UnrealDelegateHandle +function UObject:BindDelegate(property_name, target, function_object) end + +---@return string +function UObject:Type() end + +---@class UStruct: UObject +local UStruct = {} + +---@return UStruct? +function UStruct:GetSuperStruct() end + +---@param callback fun(property: UnrealProperty): boolean? +function UStruct:ForEachProperty(callback) end + +---@param callback fun(function_object: UFunction): boolean? +function UStruct:ForEachFunction(callback) end + +---@return integer +function UStruct:GetStructureSize() end + +---@return integer +function UStruct:GetMinAlignment() end + +---@class UnrealImplementedInterface +---@field Class UClass? +---@field PointerOffset integer +---@field ImplementedByK2 boolean + +---@class UClass: UStruct +local UClass = {} + +---@return UObject? +function UClass:GetCDO() end + +---@param parent UClass +---@return boolean +function UClass:IsChildOf(parent) end + +---@return integer +function UClass:GetClassFlags() end + +---@param flags integer +---@return boolean +function UClass:HasAnyClassFlags(flags) end + +---@param flags integer +---@return boolean +function UClass:HasAllClassFlags(flags) end + +---@return UClass? +function UClass:GetWithinClass() end + +---@return UObject? +function UClass:GetGeneratedBy() end + +---@return UnrealImplementedInterface[] +function UClass:GetInterfaces() end + +---@param outer? UObject +---@param name? string +---@param flags? integer +---@param template? UObject +---@param copy_transients_from_class_defaults? boolean +---@return UObject? +function UClass:ConstructObject(outer, name, flags, template, copy_transients_from_class_defaults) end + +---@param world_context? UObject +---@return UObject? +function UClass:SpawnActor(world_context) end + +---@class UScriptStruct: UStruct + +---@class UFunction: UStruct +local UFunction = {} + +---@return integer +function UFunction:GetFunctionFlags() end + +---@param flags integer +function UFunction:SetFunctionFlags(flags) end + +---@return integer +function UFunction:GetParameterCount() end + +---@return integer +function UFunction:GetParameterSize() end + +---@return integer? +function UFunction:GetReturnValueOffset() end + +---@class UEnum: UObject +local UEnum = {} + +---@param value integer +---@return FName? +function UEnum:GetNameByValue(value) end + +---@param index integer Zero-based index. +---@return FName? name +---@return integer? value +function UEnum:GetEnumNameByIndex(index) end + +---@param callback fun(name: FName, value: integer): boolean? +function UEnum:ForEachName(callback) end + +---@return integer +function UEnum:NumEnums() end + +---@param index integer Zero-based index. +---@param name FName|string +function UEnum:EditNameAt(index, name) end + +---@param index integer Zero-based index. +---@param value integer +function UEnum:EditValueAt(index, value) end + +---@class UnrealDataTableEntry +---@field Name string +---@field Data UnrealDataTableRow + +---@class UDataTable: UObject +local UDataTable = {} + +---@return UScriptStruct? +function UDataTable:GetRowStruct() end + +---@return table +function UDataTable:GetRowMap() end + +---@param row_name string|FName +---@return UnrealDataTableRow? +function UDataTable:FindRow(row_name) end + +---@param row_name string|FName +---@param value table|UnrealValue|UnrealDataTableRow +function UDataTable:AddRow(row_name, value) end + +---@param row_name string|FName +function UDataTable:RemoveRow(row_name) end + +function UDataTable:EmptyTable() end + +---@return string[] +function UDataTable:GetRowNames() end + +---@return UnrealDataTableEntry[] +function UDataTable:GetAllRows() end + +---@param callback fun(name: string, row: UnrealDataTableRow): boolean? +function UDataTable:ForEachRow(callback) end + +---@class FName +local FName = {} + +---@return string +function FName:ToString() end + +---@return integer +function FName:GetComparisonIndex() end + +---@param other FName|string +---@return boolean +function FName:Equals(other) end + +---@return string +function FName:Type() end + +---@class FText +local FText = {} + +---@return string +function FText:ToString() end + +---@return string +function FText:Type() end + +---@class UnrealValue +local UnrealValue = {} + +---@return boolean +function UnrealValue:IsValid() end + +---@return string +function UnrealValue:Type() end + +---@return integer +function UnrealValue:Num() end + +---@return integer +function UnrealValue:GetArrayNum() end + +---@return integer +function UnrealValue:GetArrayAddress() end + +---@return integer +function UnrealValue:GetArrayMax() end + +---@return integer +function UnrealValue:GetArrayDataAddress() end + +---@param callback fun(key: any, value: any): boolean? +function UnrealValue:ForEach(callback) end + +---@return table +function UnrealValue:ToTable() end + +function UnrealValue:Clear() end + +function UnrealValue:Empty() end + +---@overload fun(self: UnrealValue, key: any, value: any): boolean +---@param value any +---@return integer|boolean +function UnrealValue:Add(value) end + +---@param index integer +---@param value any +function UnrealValue:Insert(index, value) end + +---@param value any +---@return boolean +function UnrealValue:Contains(value) end + +---@param value any +---@return integer|any +function UnrealValue:Find(value) end + +---@param value any +---@return boolean +function UnrealValue:Remove(value) end + +---@return string +function UnrealValue:ToString() end + +---@return integer +function UnrealValue:Len() end + +---@return boolean +function UnrealValue:IsEmpty() end + +---@param value string +function UnrealValue:Append(value) end + +---@param value string +---@return boolean +function UnrealValue:StartsWith(value) end + +---@param value string +---@return boolean +function UnrealValue:EndsWith(value) end + +---@return UnrealValue +function UnrealValue:ToUpper() end + +---@return UnrealValue +function UnrealValue:ToLower() end + +---@class UnrealDataTableRow +local UnrealDataTableRow = {} + +---@return boolean +function UnrealDataTableRow:IsValid() end + +---@param name string +---@return any +function UnrealDataTableRow:GetPropertyValue(name) end + +---@param name string +---@param value any +function UnrealDataTableRow:SetPropertyValue(name, value) end + +---@return string +function UnrealDataTableRow:Type() end + +---@return string +function UnrealDataTableRow:ToString() end + +---@class UnrealProperty +local UnrealProperty = {} + +---@return boolean +function UnrealProperty:IsValid() end + +---@return string +function UnrealProperty:GetFullName() end + +---@return FName +function UnrealProperty:GetFName() end + +---@param class UnrealFieldClass|string|FName +---@return boolean +function UnrealProperty:IsA(class) end + +---@return UnrealFieldClass +function UnrealProperty:GetClass() end + +---@return integer +function UnrealProperty:GetOffset_Internal() end + +---@return integer +function UnrealProperty:GetArrayDim() end + +---@return integer +function UnrealProperty:GetElementSize() end + +---@return UClass +function UnrealProperty:GetPropertyClass() end + +---@return integer +function UnrealProperty:GetByteMask() end + +---@return integer +function UnrealProperty:GetByteOffset() end + +---@return integer +function UnrealProperty:GetFieldMask() end + +---@return integer +function UnrealProperty:GetFieldSize() end + +---@return UScriptStruct? +function UnrealProperty:GetStruct() end + +---@return UnrealProperty? +function UnrealProperty:GetInner() end + +---@return UnrealProperty? +function UnrealProperty:GetElementProperty() end + +---@return UnrealProperty? +function UnrealProperty:GetKeyProperty() end + +---@return UnrealProperty? +function UnrealProperty:GetValueProperty() end + +---@return UnrealProperty? +function UnrealProperty:GetUnderlyingProperty() end + +---@return UEnum? +function UnrealProperty:GetEnum() end + +---@return string +function UnrealProperty:Type() end + +---@class UnrealFieldClass +local UnrealFieldClass = {} + +---@return boolean +function UnrealFieldClass:IsValid() end + +---@return FName +function UnrealFieldClass:GetFName() end + +---@return string +function UnrealFieldClass:Type() end + +---@class UObjectReflection +local UObjectReflection = {} + +---@return boolean +function UObjectReflection:IsValid() end + +---@param name string|FName +---@return UnrealProperty? +function UObjectReflection:GetProperty(name) end + +---@return string +function UObjectReflection:Type() end + +---@class UnrealCall +local UnrealCall = {} + +---@return boolean +function UnrealCall:IsValid() end + +---@return UObject +function UnrealCall:GetObject() end + +---@return UFunction +function UnrealCall:GetFunction() end + +---@return "Before"|"After" +function UnrealCall:GetPhase() end + +---@return boolean +function UnrealCall:IsDeferred() end + +---@return boolean +function UnrealCall:IsSkipped() end + +---@param name string +---@return any +function UnrealCall:Get(name) end + +---@param name string +---@param value any +function UnrealCall:Set(name, value) end + +---@return any +function UnrealCall:GetReturnValue() end + +---@param value any +function UnrealCall:SetReturnValue(value) end + +---@return boolean changed +function UnrealCall:Skip() end + +---@class UnrealHookHandle +local UnrealHookHandle = {} + +---@return boolean removed_now +function UnrealHookHandle:Remove() end + +---@return boolean +function UnrealHookHandle:IsActive() end + +---@class UnrealDelegateHandle +local UnrealDelegateHandle = {} + +---@return boolean removed_now +function UnrealDelegateHandle:Remove() end + +---@return boolean +function UnrealDelegateHandle:IsActive() end + +---@class UnrealNotificationHandle +local UnrealNotificationHandle = {} + +---@return boolean removed_now +function UnrealNotificationHandle:Remove() end + +---@return boolean +function UnrealNotificationHandle:IsActive() end + +---@class UnrealHookCallbacks +---@field Before? fun(call: UnrealCall) +---@field After? fun(call: UnrealCall) + +---@class UnrealPostLoadCallbacks +---@field Before? fun(object: UObject) +---@field After? fun(object: UObject) + +---@alias OverdubUnrealPropertyTypeName "Bool"|"Byte"|"Int8"|"Int16"|"Int32"|"Int64"|"UInt16"|"UInt32"|"UInt64"|"Float"|"Double"|"Name"|"String"|"Text"|"Object"|"Class"|"SoftObject"|"SoftClass"|"WeakObject"|"LazyObject"|"Interface"|"Struct"|"Enum"|"Array"|"Set"|"Map" + +---@class OverdubUnrealPropertyType +---@field Type OverdubUnrealPropertyTypeName +---@field Class? UClass +---@field Struct? UScriptStruct +---@field Enum? UEnum +---@field Underlying? OverdubUnrealPropertyTypeName|OverdubUnrealPropertyType +---@field Inner? OverdubUnrealPropertyTypeName|OverdubUnrealPropertyType +---@field Key? OverdubUnrealPropertyTypeName|OverdubUnrealPropertyType +---@field Value? OverdubUnrealPropertyTypeName|OverdubUnrealPropertyType + +---@class OverdubUnrealPropertyDefinition: OverdubUnrealPropertyType +---@field Name string +---@field Flags? integer +---@field Default? any +---@field Const? boolean + +---@class OverdubUnrealFunctionDefinition +---@field Name string +---@field Flags? integer +---@field Parameters? OverdubUnrealPropertyDefinition[] +---@field Return? OverdubUnrealPropertyTypeName|OverdubUnrealPropertyType +---@field Implementation fun(self: UObject, ...: any): any + +---@class OverdubUnrealClassDefinition +---@field Parent UClass +---@field Properties? OverdubUnrealPropertyDefinition[] +---@field Functions? OverdubUnrealFunctionDefinition[] + +---@class OverdubUnrealModule +local unreal = {} + +---@param value string|integer|FName +---@param find_type? integer +---@return FName +function unreal.FName(value, find_type) end + +---@param value string +---@return FText +function unreal.FText(value) end + +---@type FName +unreal.NAME_None = nil + +---@type table +unreal.EObjectFlags = {} + +---@type table +unreal.EInternalObjectFlags = {} + +---@type table +unreal.EClassFlags = {} + +---@type table +unreal.EPropertyFlags = {} + +---@type table +unreal.EFunctionFlags = {} + +---@type table +unreal.PropertyTypes = {} + +---@type table +unreal.EFindName = {} + +---@param path string +---@param class? UClass +---@return UObject? +function unreal.FindObject(path, class) end + +---@return integer +function unreal.GetObjectCount() end + +---@param index integer Zero-based index. +---@return UObject? +function unreal.GetObjectByIndex(index) end + +---@return fun(): integer?, UObject? +function unreal.Objects() end + +---@param path string +---@param class? UClass +---@param outer? UObject +---@return UObject? +function unreal.LoadObject(path, class, outer) end + +---@param class UClass +---@param outer? UObject +---@param name? string +---@param flags? integer +---@param template? UObject +---@param copy_transients_from_class_defaults? boolean +---@return UObject? +function unreal.ConstructObject(class, outer, name, flags, template, copy_transients_from_class_defaults) end + +---@param class UClass +---@param world_context? UObject +---@return UObject? +function unreal.SpawnActor(class, world_context) end + +---@param name string +---@param definition OverdubUnrealClassDefinition +---@return UClass +function unreal.DefineClass(name, definition) end + +---@param source UObject +---@param property_name string +---@param target UObject +---@param function_object UFunction|string +---@return UnrealDelegateHandle +function unreal.BindDelegate(source, property_name, target, function_object) end + +---@param class UClass|string +---@param callback fun(object: UObject) +---@return UnrealNotificationHandle +function unreal.NotifyOnNewObject(class, callback) end + +---@param object UObject +---@param callback fun() +---@return UnrealNotificationHandle +function unreal.NotifyOnDeleteObject(object, callback) end + +---@param function_object UFunction|string +---@param callbacks UnrealHookCallbacks +---@return UnrealHookHandle +function unreal.Hook(function_object, callbacks) end + +---@param class UClass|string +---@param callbacks UnrealPostLoadCallbacks +---@return UnrealHookHandle +function unreal.HookPostLoad(class, callbacks) end + +---@return UObject? +function unreal.GetCurrentWorld() end + +---@return UObject? +function unreal.GetTransientPackage() end + +return unreal diff --git a/docs/lua/tasks.md b/docs/lua/tasks.md new file mode 100644 index 0000000..ed6f936 --- /dev/null +++ b/docs/lua/tasks.md @@ -0,0 +1,156 @@ +# Tasks and Workers + +`overdub.task` keeps long work out of the per-frame `Tick` callback. It has two different tools because Unreal work and background work have different safety rules. + +A Task is a game-thread Lua coroutine. A Future is a handle to one worker result, similar to a JavaScript Promise. + +## Cooperative tasks + +Use a Task when the work must read or write UObjects. The task still runs on the game thread, but it can pause and continue in another frame. + +```lua +local input = require("overdub.input") +local task = require("overdub.task") +local unreal = require("overdub.unreal") + +local scan_task + +local function scan_objects() + for _, object in unreal.Objects() do + inspect_object(object) + + if task.ShouldYield() then + task.YieldFrame() + end + end +end + +return { + Tick = function(delta_seconds) + if input.Pressed("F8") and (not scan_task or scan_task:IsDone()) then + scan_task = task.Spawn("scan-objects", scan_objects) + end + end, +} +``` + +Every call to `Spawn` creates a new task. The condition in `Tick` prevents a second scan while the first one is active. Overdub does not search for an older task by name. + +The optional name is only for diagnostics. These calls are equivalent apart from that label: + +```lua +task.Spawn(run_scan) +task.Spawn("scan-objects", run_scan) +``` + +`ShouldYield` compares the time used by the current resume with its work-budget hint. It does not yield by itself and it does not accept a budget argument. Call `YieldFrame` at a safe boundary chosen by the algorithm. + +This keeps the decision inside the loop instead of using an arbitrary item count such as `index % 20 == 0`. The amount of work per object can change, while elapsed time still describes the frame cost. + +`Sleep` pauses the task until a later frame after the requested time: + +```lua +task.Spawn(function() + show_message("Connected") + task.Sleep(2.0) + hide_message() +end) +``` + +`Task:Cancel` requests early cancellation. `IsDone` becomes true after success, error, or cancellation. All tasks are cancelled when the mod stops. + +## Worker jobs + +Use `Offload` for CPU work that uses only copied Lua values. The worker cannot access UObjects, the UI context, or closures from the game-thread state. + +```lua +local task = require("overdub.task") + +local parse_future +local parsed_data + +return { + Tick = function(delta_seconds) + if reload_requested() and (not parse_future or parse_future:IsDone()) then + local text = read_text_snapshot() + parse_future = task.Offload("workers.parser", "Parse", text) + + parse_future:OnSuccess(function(result) + parsed_data = result + end) + + parse_future:OnError(function(message) + print("parse failed: " .. message) + end) + end + + if parsed_data then + apply_small_update(parsed_data) + parsed_data = nil + end + end, +} +``` + +`Offload` always submits a new job and returns a new Future. It does not know about `parse_future`. The condition belongs to the mod and prevents `Tick` from submitting the same request every frame. + +The worker entry is a normal Lua module: + +```lua +-- scripts/workers/parser.lua +local parser = {} + +function parser.Parse(text) + local result = expensive_parse(text) + return { + entries = result, + count = #result, + } +end + +return parser +``` + +`OnSuccess` registers a callback for a result. `OnError` registers a callback for an error or cancellation. `OnComplete` always runs and receives the Future. The names describe registration; they are not switch cases. + +The Future marks itself complete. There is no need to assign nil after completion. Keep the handle when `Tick` needs `IsDone` as a resubmission guard, or let Lua collect it when the result is no longer relevant. + +## Await a Future + +`Await` pauses a cooperative Task. It never blocks `Tick`. + +```lua +local rebuild_task + +return { + Tick = function(delta_seconds) + if needs_rebuild() and (not rebuild_task or rebuild_task:IsDone()) then + local input_data = make_plain_snapshot() + + rebuild_task = task.Spawn("rebuild", function() + local future = task.Offload("workers.cache", "Build", input_data) + local result = future:Await() + + -- This code resumes on the game thread. + apply_result_to_unreal(result) + end) + end + end, +} +``` + +Do not call `Await` directly from `Tick`. Tick is a normal callback, not a yieldable coroutine. Await returns the result on success and raises a Lua error after worker failure or cancellation. + +`GetResult` reads an already completed successful result. It raises while pending, after failure, or after cancellation. `GetError` returns the failure message, `"cancelled"`, or nil. + +## Worker boundary + +The boundary supports nil, booleans, integers, numbers, binary-safe strings, arrays, and tables with string or integer keys. Values are serialized and copied. + +Cyclic tables, metatables, userdata, functions, coroutines, Lua states, UObjects, and UI values cannot cross the boundary. Capture the needed Unreal data into a plain table on the game thread, then offload that table. + +Each mod gets a persistent worker Lua state when it first calls `Offload`. Its loaded modules and module-local state survive between jobs. Jobs for one mod run in order rather than concurrently. + +The worker has normal Lua module paths and can load vendored Lua or C modules. It does not provide `overdub`, `overdub.unreal`, or the UI package. + +Cancellation settles the Future and discards a late result. It cannot interrupt a third-party C function that is already blocked inside the worker. Mod shutdown cancels outstanding jobs and waits for the worker to finish. diff --git a/docs/lua/ue4ss-runtime.md b/docs/lua/ue4ss-runtime.md new file mode 100644 index 0000000..3f3d07b --- /dev/null +++ b/docs/lua/ue4ss-runtime.md @@ -0,0 +1,73 @@ +# UE4SS Compatibility Runtime + +The UE4SS runtime exists for older Lua mods that use UE4SS names and globals. It is separate from native Overdub Lua and must be selected in `mod.ini`. +```ini +[lua] +path = scripts/main.lua +runtime = ue4ss +``` + +Do not require `overdub`, `overdub.task`, `overdub.ui`, or `overdub.unreal` from this runtime. It keeps the UE4SS-compatible public names instead. + +## State and modules + +Each compatible mod has its own Lua state and worker thread. Its entry script runs once and the state remains alive until the mod stops. + +The standard `require`, `package`, `io`, and `os` libraries are available. Module lookup includes the entry directory, the mod's `scripts` directory, `mods/shared`, and native module locations used by the compatibility layer. + +## Scheduling + +The compatibility globals include `ExecuteInGameThread`, delayed game-thread work, `ExecuteAsync`, `ExecuteWithDelay`, `LoopAsync`, frame loops, and cancellation. + +```lua +ExecuteInGameThread(function() + local player = FindFirstOf("PlayerController") +end) + +local loop = LoopInGameThreadAfterFrames(1, function() + update_feature() +end) + +CancelDelayedAction(loop) +``` + +Async callbacks run on the mod's worker thread. Use the game-thread helpers for UObject work. + +## Keybinds and commands + +```lua +RegisterKeyBind(Key.ONE, { ModifierKey.CONTROL }, function() + print("Ctrl+1") +end) + +RegisterConsoleCommandHandler("hello", function(full_command, parameters, output_device) + print(parameters[1] or "world") + return true +end) +``` + +Console handlers receive commands entered as `:name arguments` in Overdub's console. `output_device` is nil because the UI console does not use Unreal's `FOutputDevice`. + +## Reflected hooks + +```lua +local pre_id, post_id = RegisterHook( + "/Script/Engine.Actor:K2_DestroyActor", + function(self) + print(self:Get():GetFullName()) + end, + function(self) + print("destroy completed") + end +) + +UnregisterHook("/Script/Engine.Actor:K2_DestroyActor", pre_id, post_id) +``` + +Compatibility hooks receive copied remote parameters. Changing a copy does not alter the original `ProcessEvent` call. Native Overdub hooks are synchronous when possible and have different behavior. + +## Unreal data + +The compatibility layer includes UObject lookup, reflected property values, UFunction calls, new-object notifications, FProperty metadata, and UDataTable helpers. Existing UE4SS function and type names remain unchanged. + +Use [`Types.lua`](Types.lua) as a LuaLS library file for the complete supported surface. It is metadata and must not be executed with `require` or `dofile`. diff --git a/docs/lua/ui.md b/docs/lua/ui.md new file mode 100644 index 0000000..ef0cb9e --- /dev/null +++ b/docs/lua/ui.md @@ -0,0 +1,134 @@ +# Lua UI + +`overdub.ui` wraps the Nuklear UI used by Overdub. It exposes ordinary controls and layout without exposing the raw context pointer. + +Lua UI can be drawn in three places. `DrawPanel` draws the mod's main panel. `DrawConfig` draws its Config section. `RegisterWindow` creates a separate window. All three use the same callback-scoped context. + +## Panel and config callbacks + +```lua +local enabled = true +local speed = 1.0 + +return { + DrawPanel = function(ctx) + ctx:Text("Feature status") + ctx:Text(enabled and "Enabled" or "Disabled") + end, + + DrawConfig = function(ctx) + enabled = ctx:Checkbox("Enabled", enabled) + speed = ctx:SliderFloat("Speed", speed, 0.1, 4.0, 0.1) + end, +} +``` + +When `DrawConfig` exists, it replaces the normal manifest-backed controls in that section. + +## Separate windows + +Register a window during startup and store its state in normal Lua variables. + +```lua +local ui = require("overdub.ui") + +local status_window +local connected = false +local player_name = "Player" + +return { + Startup = function() + status_window = ui.RegisterWindow("status", "Connection", function(ctx) + ctx:Text(connected and "Connected" or "Disconnected") + ctx:Separator() + + connected = ctx:Checkbox("Connected", connected) + player_name = ctx:InputText("Name", player_name, 64) + + ctx:Row(2) + if ctx:Button("Reconnect") then + reconnect() + end + + if ctx:Button("Close") then + status_window:SetOpen(false) + end + end) + end, +} +``` + +Window IDs are scoped to the mod. A handle can use `SetOpen`, `IsOpen`, `Remove`, and `IsActive`. Windows are removed automatically when the mod stops. + +## Rows and grids + +Simple widgets create a one-column row when no layout was selected. Use `Row`, `RowStatic`, `RowRatios`, or `RowWidths` for explicit layout. + +```lua +ctx:Row(2, 28) +ctx:Button("Left") +ctx:Button("Right") + +ctx:RowRatios({ 0.25, 0.75 }, 24) +ctx:Text("Name") +ctx:Text(player_name) + +ctx:RowWidths({ 100, 240 }, 24) +ctx:Text("Status") +ctx:Text("Ready") +``` + +A grid remembers its column layout while the callback runs. Use `NextRow` to advance explicitly. + +```lua +ctx:Grid("stats", { "Content", 90, "Flex" }, function(grid) + grid:Text("Name") + grid:Text("Value") + grid:Text("Notes") + grid:NextRow() + + grid:Text("Score") + grid:Text("1200") + grid:Text("Current run") +end) +``` + +`"Content"` sizes a column to its content. `"Flex"` shares the remaining width. + +## Groups and trees + +A group creates a clipped region with its own scroll position. + +```lua +ctx:Group("items", 180, function(group) + for _, item in ipairs(items) do + group:Text(item.Name) + end +end) +``` + +`Group` returns its current horizontal and vertical scroll offsets. `GroupScroll` reads them without drawing the group. `SetGroupScroll` changes them when the mod needs to scroll to a saved position or jump to a result. + +A clipped group may skip its callback because none of its content is visible. Do not put non-UI game logic inside a group callback. + +Trees keep their expanded state in the value returned to the mod: + +```lua +tree_open = ctx:Tree("Advanced", tree_open, function(tree) + tree:Text("Advanced settings") +end) +``` + +## Inputs and helpers + +Buttons and checkboxes return their new state directly. Sliders return the clamped value. `InputInt`, `InputFloat`, and `InputText` return the value plus change information where applicable. `Dropdown` selects from a string array. `ColorEditor` edits RGBA values, and `Keybind` captures an Overdub keybind. + +Text helpers include `Text`, `TextColored`, `WrappedText`, and `WrappedTextColored`. Alignment strings are `"Left"`, `"Center"`, and `"Right"`. The remaining helpers are `Tooltip`, `Separator`, `Spacing`, `GroupScroll`, and `ViewportSize`. + +See [`ui.lua`](overdub/ui.lua) for exact signatures and return values. + +## Context lifetime + +The context is valid only during its draw callback. Do not store it in a global, task, Future callback, or worker input. + +UI callbacks run on the game thread. They should draw controls and update small pieces of state, not perform searches or file work. A failing separate window removes that window. A failing lifecycle draw callback disables that callback. diff --git a/docs/lua/unreal.md b/docs/lua/unreal.md new file mode 100644 index 0000000..20512d8 --- /dev/null +++ b/docs/lua/unreal.md @@ -0,0 +1,299 @@ +# Lua Unreal + +`overdub.unreal` exposes reflected Unreal objects directly on the game thread. It uses one UObject userdata representation. UClass, UStruct, UFunction, UEnum, and UDataTable add specialized methods while remaining UObjects. + +Unreal property, function, and type names keep their original CamelCase spelling. Overdub module names and ordinary Lua variable names use snake_case. + +## Find and load objects + +`FindObject` searches objects that are already loaded. It accepts the path spelling returned by `GetPathName`. + +```lua +local unreal = require("overdub.unreal") + +local actor_class = assert(unreal.FindObject("/Script/Engine.Actor")) +local actor = unreal.FindObject("/Game/Maps/Test.Test:PersistentLevel.MyActor", actor_class) +``` + +The colon in the actor path is normal Unreal object-path syntax for a subobject. It is not an Overdub-specific format. + +`LoadObject` is separate because it may load an asset and perform file access: + +```lua +local table_class = assert(unreal.FindObject("/Script/Engine.DataTable")) +local item_table = assert(unreal.LoadObject("/Game/Data/Items.Items", table_class)) +``` + +Use `GetObjectCount` and `GetObjectByIndex` for indexed access. `Objects` is the convenient iterator: + +```lua +for index, object in unreal.Objects() do + if object and object:IsA(actor_class) then + inspect_actor(index, object) + end +end +``` + +A complete object-array scan can be expensive. Put it in a cooperative task and call `task.ShouldYield` inside the loop. + +## Common object methods + +Every object supports validity, identity, class, outer, and flag operations. + +```lua +if actor and actor:IsValid() then + print(actor:GetName()) + print(actor:GetFullName()) + print(actor:GetPathName()) + print(actor:GetOuter()) + print(actor:GetClass()) + print(actor:GetFlags()) + print(actor:GetInternalFlags()) +end +``` + +`IsA` accepts a UClass or a supported class identifier. `HasAnyFlags`, `HasAllFlags`, and `HasAnyInternalFlags` test bit masks. + +UClass adds CDO, inheritance, interface, construction, and class-flag methods. UStruct adds property and function iteration plus layout information. UFunction and UEnum add their own metadata methods. See [`unreal.lua`](overdub/unreal.lua) for exact signatures. + +## Properties and UFunctions + +Indexing a UObject by an Unreal property name reads the reflected value. Assignment writes it through the shared property codec. + +```lua +actor.bHidden = true + +local location = actor:K2_GetActorLocation() +location.Z = location.Z + 100.0 +actor:K2_SetActorLocation(location, false, true) +``` + +Indexing a reflected UFunction produces a bound Lua function. Inputs are marshaled from Lua values. Return and output parameters are returned in reflected order. + +```lua +local strings = assert(unreal.FindObject("/Script/Engine.Default__KismetStringLibrary")) +local parts = strings:ParseIntoArray("alpha,beta", ",", true) + +print(parts[1]:ToString()) +print(parts[2]:ToString()) +``` + +Structs and containers are live reflected values. Arrays use Lua's one-based indexing. Sets and maps provide operations such as `Add`, `Contains`, `Find`, `Remove`, `Clear`, `Num`, and `ToTable` where they apply. + +Reflected values retain their owner information and validate it on access. A row or nested value becomes invalid after its owner is destroyed or the row is removed. + +## Data tables + +UDataTable has direct row helpers. Returned rows are live views. + +```lua +local row = item_table:FindRow("Item001") +if row and row:IsValid() then + row.Price = 0 + row.DisplayName = unreal.FText("Free item") +end + +item_table:ForEachRow(function(name, value) + print(name, value.Price) + return false +end) +``` + +The remaining methods include `GetRowStruct`, `GetRowMap`, `AddRow`, `RemoveRow`, `EmptyTable`, `GetRowNames`, and `GetAllRows`. + +Changing a table after another game system has consumed it may be too late. Use a PostLoad hook when the change must happen during the engine's load sequence. + +## Track object creation and deletion + +`NotifyOnNewObject` observes future instances of one class. It does not scan existing objects. Perform one targeted initial search when an instance may already exist. + +```lua +local controller_class = assert(unreal.FindObject("/Script/Engine.PlayerController")) +local current_controller = find_existing_controller() + +local create_handle = unreal.NotifyOnNewObject(controller_class, function(object) + current_controller = object +end) +``` + +`NotifyOnDeleteObject` watches one particular object. Its callback has no object argument because the UObject is already being removed. + +```lua +local delete_handle + +if current_controller then + delete_handle = unreal.NotifyOnDeleteObject(current_controller, function() + current_controller = nil + end) +end +``` + +Notification callbacks are delivered to the owning game-thread Lua state. Their handles support `Remove` and `IsActive`. Delete notifications remove themselves after firing. + +## UFunction hooks + +`Hook` registers optional Before and After callbacks for one UFunction. Both run through one API because they are two phases of the same intercepted call. + +```lua +local set_location = assert(unreal.FindObject("/Script/Engine.Actor:K2_SetActorLocation")) + +local hook = unreal.Hook(set_location, { + Before = function(call) + local location = call:Get("NewLocation") + if location.Z < 0 then + location.Z = 0 + call:Set("NewLocation", location) + end + end, + + After = function(call) + if not call:GetReturnValue() then + print("move failed") + end + end, +}) +``` + +A synchronous Before callback can change parameters, set the return value, or call `Skip` to prevent the original invocation. After sees the final outputs and can replace the return value. + +The call object is borrowed for the callback. `IsValid` becomes false afterward. + +Overdub never recursively enters the same Lua state. If Lua causes another hooked call while it is already running, Overdub copies the values and delivers read-only Before and After snapshots later. `IsDeferred` reports this case. A deferred callback cannot alter a call that already finished. + +There is no separate public deferred-hook type. Deferral is an internal response to nested re-entry, while ordinary calls remain synchronous interceptors. + +## PostLoad hooks + +`HookPostLoad` matches a class and receives real UObject PostLoad calls. Before runs immediately before the engine implementation and After runs immediately after it. + +```lua +local table_class = assert(unreal.FindObject("/Script/Engine.DataTable")) + +local post_load_hook = unreal.HookPostLoad(table_class, { + Before = function(object) + prepare_table(object) + end, + + After = function(object) + apply_table_changes(object) + end, +}) +``` + +This API observes engine timing. It is not the same as calling `PostLoad` from Lua. Use the phase required by the game system that consumes the object. + +## Construct objects and spawn actors + +Construct a non-actor object through the module or its UClass view: + +```lua +local object_class = assert(unreal.FindObject("/Script/CoreUObject.Object")) +local object = assert(object_class:ConstructObject( + unreal.GetTransientPackage(), + nil, + unreal.EObjectFlags.RF_Transient +)) +``` + +Actor classes must use `SpawnActor`: + +```lua +local actor = assert(custom_actor_class:SpawnActor(unreal.GetCurrentWorld())) +``` + +Construction rejects abstract classes, invalid outers, engine-managed flags, and actor classes passed to `ConstructObject`. + +## Root claims + +`AddToRoot` gives the current mod a root claim. Repeating it in the same mod returns false because the claim already exists. `RemoveFromRoot` releases that claim. + +Claims are counted across mods. The last Overdub claim restores the object's original root state. Shutdown releases all claims held by the mod. + +Rooting is not a substitute for validity checks and should not be used to keep world-owned actors alive without understanding their lifecycle. + +## Custom classes + +`DefineClass` creates a process-lifetime UClass scoped to the mod ID. It can inherit an existing class, add properties, change CDO defaults, and add Lua-backed UFunctions. + +```lua +local object_class = assert(unreal.FindObject("/Script/CoreUObject.Object")) +local actor_class = assert(unreal.FindObject("/Script/Engine.Actor")) +local vector_struct = assert(unreal.FindObject("/Script/CoreUObject.Vector")) + +local inventory_class = unreal.DefineClass("InventoryState", { + Parent = object_class, + + Properties = { + { + Name = "Count", + Type = "Int32", + Default = 10, + }, + { + Name = "Owner", + Type = "Object", + Class = actor_class, + }, + { + Name = "Origin", + Type = "Struct", + Struct = vector_struct, + Default = { X = 0, Y = 0, Z = 0 }, + }, + { + Name = "Tags", + Type = "Array", + Inner = "Name", + Default = { "Default", "Inventory" }, + }, + { + Name = "Scores", + Type = "Map", + Key = "Name", + Value = "Int32", + Default = { Default = 4 }, + }, + }, + + Functions = { + { + Name = "Add", + Flags = unreal.EFunctionFlags.FUNC_BlueprintCallable, + Parameters = { + { + Name = "Amount", + Type = "Int32", + }, + }, + Return = "Int32", + Implementation = function(self, amount) + self.Count = self.Count + amount + return self.Count + end, + }, + }, +}) + +local inventory = assert(inventory_class:ConstructObject()) +print(inventory:Add(5)) +``` + +Property descriptions can nest. Array and set use `Inner`. Map uses `Key` and `Value`. Object types use `Class`, structs use `Struct`, and enums use `Enum` plus an integer `Underlying` type. + +Supported declarations are Bool, Byte, Int8, Int16, Int32, Int64, UInt16, UInt32, UInt64, Float, Double, Name, String, Text, Object, Class, SoftObject, SoftClass, WeakObject, LazyObject, Interface, Struct, Enum, Array, Set, and Map. + +Static custom UFunctions are rejected. Classes remain registered until process exit. Stopping the mod makes their Lua implementations inactive but does not remove their layouts. + +## Delegate binding + +A custom UFunction can be bound to a compatible reflected delegate property. + +```lua +local handle = actor:BindDelegate("OnDestroyed", inventory, "HandleDestroyed") + +if handle:IsActive() then + -- handle:Remove() can unbind it early. +end +``` + +`unreal.BindDelegate(actor, "OnDestroyed", inventory, "HandleDestroyed")` is the equivalent module form. The target function must be non-static and match the delegate signature. Bindings are removed when the mod stops. diff --git a/docs/mod-development/architecture.md b/docs/mod-development/architecture.md new file mode 100644 index 0000000..429d6b1 --- /dev/null +++ b/docs/mod-development/architecture.md @@ -0,0 +1,59 @@ +# Architecture + +This page explains the boundaries a mod author needs to understand. It is not a source-level tour of every Overdub subsystem. + +## Loader and mod package + +The loader discovers package manifests at startup and builds one ordered mod list. A package can combine DLL code, Lua code, assets, and Blueprint actor declarations. The mod manager presents those parts as one mod and coordinates their start and stop operations. + +Assets are mounted at startup because Unreal package unloading is not a safe general reload mechanism. DLL and Lua runtimes have explicit lifecycles and can be restarted while the game is running. + +## Native ABI + +A native DLL exports an ABI version and a callback table. The table keeps the entry ABI small and allows optional callbacks to be added through `struct_size` checks. + +Overdub passes an opaque mod handle to each callback. Registrations made through this handle are tagged with the active mod run. This lets the loader remove commands, hooks, listeners, arenas, and custom function implementations without exposing internal generation IDs to mod code. + +The DLL remains loaded during Stop and Start. Reload is the separate operation that unloads it. This distinction lets users temporarily disable a feature without forcing Windows to reload code, while still giving developers a way to replace a DLL. + +## Lua runtimes + +Native Overdub Lua and UE4SS-compatible Lua are different runtimes. They share the Lua VM wrapper and the low-level Unreal property codec, but they do not share lifecycle rules or public globals. + +Each native Overdub Lua mod owns one Lua state. The game thread owns that state and runs its lifecycle, Unreal hooks, task resumes, future completion callbacks, and UI callbacks. Modules are imported with `require("overdub")` and related package names. The entry chunk returns its lifecycle table. + +Each UE4SS-compatible mod has its own state and legacy API. Its scheduling and callback behavior follows the compatibility layer. No `overdub` packages are installed in that state. + +Keeping the runtimes separate prevents a legacy global or worker-thread assumption from silently changing native Overdub behavior. + +## Cooperative tasks and workers + +A cooperative task is a Lua coroutine on the game thread. It can access Unreal objects because it never leaves that thread. It must yield so other frame work can run. + +A worker job runs a named Lua module function in a separate Lua state. Only copied serializable values cross the boundary. Lua closures, UObjects, UI contexts, coroutines, and userdata remain in their owning state. + +This split exists because moving a game-thread Lua closure to a worker would also move its captured state and could expose Unreal pointers on the wrong thread. Named functions and copied values make the boundary visible and testable. + +## Unreal property codec + +The shared property codec owns the rules for constructing, copying, reading, writing, and destroying reflected values. UObject Search, UFunction calls, the tracer, the UE4SS layer, the native Lua layer, and custom reflection all use the same rules. + +This avoids having one subsystem copy an `FString` correctly while another treats it as plain bytes. It also keeps container and object-reference validation consistent. + +## UI + +Native DLL callbacks receive Overdub's Nuklear context. Native Lua receives a restricted userdata wrapper around the same context. Both draw through the normal mod tick and panel routes. + +The context is borrowed for one draw callback. Lua does not see its raw pointer. Persistent UI state belongs to the mod, while widget declarations are rebuilt each frame. + +## Custom reflected classes + +Custom classes are process-lifetime Unreal types. Their layouts cannot be unregistered safely after objects, references, or cached reflection data may exist. Overdub therefore leaves the class registered when a mod stops and disables only the mod-owned function implementations. + +Definitions are scoped by mod ID to prevent name collisions. A later start of the same mod may reuse an identical class definition. A conflicting definition fails instead of changing a live layout. + +## Managed hook chain + +Hooks created through the native mod API join Overdub's chain for that target. The most recently enabled hook runs first, and each saved original pointer remains a stable call to the next entry. Removing one mod's hook rewires the chain without invalidating another mod's original pointer. + +Direct MinHook calls do not join this chain and can still conflict with it. diff --git a/docs/mod-development/building-native-mods.md b/docs/mod-development/building-native-mods.md new file mode 100644 index 0000000..a88f97c --- /dev/null +++ b/docs/mod-development/building-native-mods.md @@ -0,0 +1,82 @@ +# Building Native Mods + +The release SDK template is self-contained. It has the public headers, Nuklear headers, `build/overdub.lib`, a sample source file, and project files for Visual Studio and MinGW-w64. Use the template from the same Overdub release that the player has installed. + +## Visual Studio + +The project uses Visual Studio 2022, x64, C11 or C++20, and the static MSVC runtime. + +Build a debug DLL: + +```batch +msbuild mod.vcxproj /t:Build /m /p:Configuration=Debug /p:Platform=x64 /p:ModName=example +``` + +Build a release DLL: + +```batch +msbuild mod.vcxproj /t:Build /m /p:Configuration=Release /p:Platform=x64 /p:ModName=example +``` + +The DLL is written under `build/Debug` or `build/Release`. + +## MinGW-w64 + +Run the Makefile from an MSYS2 MinGW64 shell on Windows, or install the MinGW-w64 cross compiler on Linux. + +```sh +make CONFIG=debug MOD_NAME=example +make CONFIG=release MOD_NAME=example +``` + +Set `MOD_SRC` when the mod has another source filename or several source files: + +```sh +make CONFIG=release MOD_NAME=example MOD_SRC="main.c feature.c" +``` + +## Use a source checkout + +The in-repository template finds the parent Overdub checkout automatically. A separate project can point to one explicitly: + +```batch +msbuild mod.vcxproj /p:OverdubDir=C:\src\overdub /p:Configuration=Release /p:Platform=x64 /p:ModName=example +``` + +```sh +make OVERDUB_DIR=/src/overdub CONFIG=release MOD_NAME=example +``` + +When `build/overdub.lib` is missing from a source checkout, the template builds Overdub first. A packaged release template already contains the import library and does not need the Overdub source. + +## Package the result + +Copy the DLL into a mod directory and add `mod.ini`: +``` +example-mod/ +|-- mod.ini ++-- example.dll +``` + +```ini +[info] +id = author.example +name = Example Mod +author = Author Name +version = 1.0.0 +kind = mod + +[code] +path = example.dll +``` + +Copy the directory into `mods` and restart the game. During development, Overdub can reload the DLL from the mod manager after it has been discovered. + +## Build Overdub itself + +Open `overdub.sln` and build `Debug|x64` or `Release|x64`. The equivalent MinGW-w64 commands are: + +```sh +make debug +make release +``` diff --git a/docs/mod-development/caveats.md b/docs/mod-development/caveats.md new file mode 100644 index 0000000..fb117cc --- /dev/null +++ b/docs/mod-development/caveats.md @@ -0,0 +1,59 @@ +# Caveats + +Overdub can make engine access easier, but it cannot make every engine operation safe. Keep these boundaries in mind while developing and testing a mod. + +## Game versions + +Signatures, offsets, structure layouts, vtable slots, and native function ABIs can change after a game update. A signature that still matches does not prove that the target function has the same parameters or behavior. + +Use a release built for the exact game version. Recheck every native hook after an update. + +## UObject lifetime + +UObject pointers are borrowed. Objects may be deleted during gameplay, travel, streaming, or garbage collection, and object-array slots can be reused. + +Validate a cached pointer before use. For objects that appear later, combine an initial targeted search with create and delete listeners. Do not repeatedly scan the complete object array from tick. + +Root only objects that the mod owns and deliberately keeps alive. Rooting a world-owned actor can interfere with normal destruction and travel. + +## Callback lifetime + +Do not retain `FFrame`, parameter buffers, return pointers, UI contexts, or scratch allocations after their callback ends. They are borrowed storage. + +A Lua reflected struct, row, or nested container view can also become invalid when its owning object or row is removed. Check `IsValid` when a value survives across frames. + +## Threads + +Loader lifecycle, tick, UI, and normal native Lua callbacks run on the game thread. A native detour runs on the thread that called its target, which may be different. + +Do not access ordinary UObjects from a worker thread. Copy game data into plain worker-owned memory before starting slow parsing, compression, or network work. Send only copied results back to the game thread. + +Lua instruction limits can stop runaway Lua bytecode. They cannot interrupt a blocking C function or operating-system call. + +## Reload + +Overdub removes resources registered through the mod handle, but it cannot discover everything a DLL created. Before `deinit` returns, a native mod must stop and join its threads, remove direct callbacks, restore patches, and release operating-system or library handles. + +No code may execute inside a DLL after Windows unloads it. + +Custom reflected classes are not unloaded. Their native or Lua function implementations become inactive when the owning mod stops. + +## Assets and Blueprints + +Mounted assets remain mounted until process exit. Changing an asset, its enabled state, or mod order requires a game restart. + +Blueprint actors can be destroyed during level travel. A persistent Blueprint feature must handle missing spawn contexts and later respawn. + +Cooked assets must target the game's Unreal build and include their dependencies. Windows paths are not Unreal object paths. + +## Engine calls + +Calling a reflected function is synchronous unless the function itself schedules work. The caller must provide a compatible object and valid engine state. Latent, destructive, network, and internal functions may have requirements that reflection metadata does not describe. + +Hook callbacks that modify parameters, skip a call, or replace a return value run in the original call path. Keep them small and avoid recursion. + +## Diagnostics + +Do not log every tick or every call in a busy hook. Use narrow UFunction Tracer filters and stop capture as soon as the relevant action is recorded. + +Keep PDB files for native releases. A crash report is most useful when it includes the stack trace, log, exact game version, mod version, and reproduction steps. diff --git a/docs/mod-development/native-sdk.md b/docs/mod-development/native-sdk.md new file mode 100644 index 0000000..3f4f014 --- /dev/null +++ b/docs/mod-development/native-sdk.md @@ -0,0 +1,264 @@ +# Native SDK + +Include `mod.h` for the native mod ABI. It also includes the common input, logging, signature scanning, Unreal, reflection, string, and version declarations. + +The mod links to `overdub.lib`. The implementation remains in `overdub.dll`, so the SDK headers and import library must come from a compatible release. + +## Entry points + +Every native mod exports its ABI version and a callback table. `init` is required. The other callbacks may be left null. + +```c +#include "mod.h" + +static bool +example_init(mod_handle_t mod) +{ + MOD_LOG_INFO(mod, "Example mod started"); + return true; +} + +static void +example_deinit(mod_handle_t mod) +{ + MOD_LOG_INFO(mod, "Example mod stopped"); +} + +MOD_ABI_VERSION_ENTRY() +{ + return MOD_ABI_VERSION; +} + +MOD_ENTRY() +{ + static const mod_api_t api = { + .struct_size = sizeof(mod_api_t), + .init = example_init, + .deinit = example_deinit, + }; + + return &api; +} +``` + +`mod_entry` should only return the table. Overdub calls `init` later, after its engine hooks and manager state are ready. Returning false from `init` aborts that start. + +The callback table can also receive `tick`, `input`, `pe_pre`, `pe_post`, `func_invoke_pre`, `func_invoke_post`, `draw_panel`, and `draw_config`. See [`mod_api_t`](../../include/mod.h) for their exact signatures. + +## Lifecycle + +Stop calls `deinit` and removes resources registered through the mod handle, but it leaves the DLL loaded. Restart performs Stop followed by Start. Reload stops the mod, unloads the DLL, loads it again, and starts it. + +Static variables therefore survive Stop and Start. Reset per-run state in `init` and clear borrowed pointers in `deinit`. + +```c +static mod_handle_t g_mod; +static unsigned int g_ticks; + +static bool +example_init(mod_handle_t mod) +{ + g_mod = mod; + g_ticks = 0; + return true; +} + +static void +example_deinit(mod_handle_t mod) +{ + (void)mod; + g_mod = MOD_HANDLE_INVALID; +} +``` + +Overdub owns commands, managed hooks, UObject listeners, custom class implementations, and arenas registered with the mod handle. It removes or disables them after `deinit`. The mod still owns raw OS handles, its own threads, direct patches, and anything registered outside the SDK. + +## State and memory + +`mod_get_perm` returns an arena that lives for the current active run. Use it for ordinary mod state instead of scattering allocations across `malloc` and `free`. + +```c +typedef struct example_state_s example_state_t; +struct example_state_s { + unsigned int updates; + uobject_t *target; +}; + +static example_state_t *g_state; + +static bool +example_init(mod_handle_t mod) +{ + g_state = ARENA_PUSH_ZERO(mod_get_perm(mod), example_state_t); + return g_state != NULL; +} + +static void +example_deinit(mod_handle_t mod) +{ + (void)mod; + g_state = NULL; +} +``` + +`mod_arena_create` creates another manager-owned arena when one subsystem needs a separate lifetime. Destroy it early with `mod_arena_destroy`, or let Overdub remove it after `deinit`. + +Use `scratch_begin` and `scratch_end` for temporary work. Every path after `scratch_begin` must reach `scratch_end`, and no pointer into the scratch arena may survive it. + +```c +tmp_arena_t tmp = scratch_begin(NULL); +str_t text = str_push_fmt(tmp.arena, "frame %llu", mod_get_frame_counter()); + +MOD_LOG_INFO(mod, STR_FMT, STR_ARG(text)); +scratch_end(tmp); +``` + +## Tick and input + +Tick runs once per game frame. Keep it short and avoid file access, long searches, and repeated logging. + +```c +static void +example_tick(mod_handle_t mod, float delta) +{ + (void)delta; + + if ((mod_get_frame_counter() % 300) == 0) { + MOD_LOG_DEBUG(mod, "still active"); + } +} +``` + +Input receives one event. Return true only when the event should not reach later mods or the game. + +```c +static bool +example_input(mod_handle_t mod, input_event_t *event) +{ + bool consume = false; + if (event->kind == INPUT_EVENT_KEY_DOWN && event->key == INPUT_KEY_F8 && !event->is_repeat) { + MOD_LOG_INFO(mod, "F8 pressed"); + consume = true; + } + + return consume; +} +``` + +Manifest keybind options are often easier to poll from tick. Get the option once during `init`, then use `mod_cfg_get_keybind` and the input helpers. + +## Configuration + +`mod_get_cfg_by_id` finds an option declared in `mod.ini`. The handle remains owned by Overdub. + +```c +static mod_cfg_handle_t g_enabled_cfg; + +static bool +example_init(mod_handle_t mod) +{ + g_enabled_cfg = mod_get_cfg_by_id(mod, STR_LIT("enabled")); + return g_enabled_cfg != MOD_CFG_HANDLE_INVALID; +} + +static void +example_tick(mod_handle_t mod, float delta) +{ + (void)mod; + (void)delta; + + if (mod_cfg_get_bool(g_enabled_cfg)) { + run_feature(); + } +} +``` + +Use the getter or setter that matches the declared option type. String getters can report their length, copy into a buffer, or copy into an arena. + +## Console commands + +Register commands during `init`. Prefix the command name with the mod ID or another unique name. + +```c +static void +example_command(mod_handle_t mod, str_t name, str_t args, void *user) +{ + (void)name; + (void)user; + MOD_LOG_INFO(mod, "command args: " STR_FMT, STR_ARG(args)); +} + +static bool +example_init(mod_handle_t mod) +{ + return mod_register_cmd(mod, STR_LIT("example.run"), STR_LIT("Runs the example action"), example_command, NULL); +} +``` + +The registration belongs to the current mod run and is removed automatically at shutdown. + +## UI + +`draw_panel` draws the mod's main panel. `draw_config` draws the Config section and replaces the automatic controls for that section. Both receive Overdub's public Nuklear context. + +```c +#include "vendor_nuklear.h" + +static void +example_draw_panel(mod_handle_t mod, struct nk_context *ctx) +{ + (void)mod; + + nk_layout_row_dynamic(ctx, 24.0f, 1); + nk_label(ctx, "Example panel", NK_TEXT_LEFT); + + if (nk_button_label(ctx, "Run")) { + run_feature(); + } +} +``` + +Nuklear is immediate mode. Store persistent values in mod state and rebuild the controls on every draw. Do not keep the context pointer after the callback. + +## Signature scans and hooks + +Use a native hook only when Unreal reflection or a loader callback cannot provide the event you need. A signature identifies code in one supported executable build; it does not prove that the function ABI or surrounding data layout stayed compatible. + +```c +typedef void (UNREAL_CALL *target_fn_t)(void *self); + +static target_fn_t g_target_real; + +static void UNREAL_CALL +target_hook(void *self) +{ + g_target_real(self); +} + +static bool +install_hook(mod_handle_t mod) +{ + void *target = NULL; + sigscan_entry_t entry = { + .name = "target", + .pattern = "48 89 5C 24 ?? 57 48 83 EC ??", + .pp = &target, + .kind = SIG_DIRECT, + }; + + bool installed = mod_sigscan(&entry) == SIG_ERR_OK && target; + if (installed) { + installed = mod_hook_create(mod, target, target_hook, (void **)&g_target_real); + } + + if (installed) { + installed = mod_hook_enable(mod, target); + } + + return installed; +} +``` + +Managed hooks on the same address form a chain. The most recently enabled hook runs first. Hooks installed directly through another MinHook instance do not join that chain and may conflict. + +A detour runs on whichever thread called its target. Match the exact calling convention, parameters, return value, recursion behavior, and lifetime. Overdub removes managed hooks after `deinit`, but the mod must remove direct hooks and restore direct patches itself. diff --git a/docs/mod-development/package-format.md b/docs/mod-development/package-format.md new file mode 100644 index 0000000..2ffaa89 --- /dev/null +++ b/docs/mod-development/package-format.md @@ -0,0 +1,138 @@ +# Package Format + +Every mod has one directory under the configured `mods` directory. Only `mod.ini` is required. + +``` +mods/ ++-- author.example/ + |-- mod.ini + |-- config.ini + |-- example.dll + |-- scripts/ + | +-- main.lua + +-- assets/ + |-- example.pak + |-- example.utoc + +-- example.ucas +``` + +Overdub discovers mod directories at game startup. Restart the game after adding or removing a package. Asset mounting and mod order also take effect at startup. + +## Basic manifest + +The `info` section identifies the mod. Keep the ID stable because Overdub uses it for saved order and settings. + +```ini +[info] +id = author.example +name = Example Mod +author = Author Name +version = 1.0.0 +kind = mod + +[description] +An example Overdub mod. +``` + +Section names and keys are case-insensitive. A semicolon starts a comment. Unknown sections are left in the file, so a Lua mod can parse its own custom sections with `overdub.ReadIni`. + +## Native DLL + +The DLL path is relative to the mod directory unless it is absolute. + +```ini +[code] +path = example.dll +``` + +## Lua + +Overdub automatically finds `scripts/main.lua` or `main.lua`. Use a `lua` section for another entry path or to select the runtime. + +```ini +[lua] +path = scripts/main.lua +runtime = overdub +``` + +`overdub` is the default runtime. An existing UE4SS script must opt into the compatibility runtime: + +```ini +[lua] +runtime = ue4ss +``` + +The two runtimes have different lifecycle and public APIs. Do not mix them in one Lua state. + +## Assets + +Give the common path without an extension. Overdub looks for the matching `.pak`, `.utoc`, and `.ucas` files. + +```ini +[assets] +path_without_ext = assets/example +``` + +A `.utoc` file needs its matching `.ucas` file. A mod may also use only a `.pak` file. Mounting an asset package makes its content available; it does not execute a Blueprint by itself. + +## Blueprint actors + +A package may have more than one `blueprint` section. Each section describes one generated actor class and the object used as its startup context. + +```ini +[blueprint] +id = example_actor +mod_actor_class_path = /Game/Mods/Example/BP_ExampleMod.BP_ExampleMod_C +attach_to = world +auto_spawn = true +default_spawn_keybind = F6 +``` + +`attach_to` accepts `none`, `player_controller`, `local_player`, `pawn`, `hud`, `world`, `game_instance`, or `custom_class_path`. A custom context also needs its class path: + +```ini +attach_to = custom_class_path +custom_attach_class_path = Class /Script/GameModule.SomeClass +``` + +The selected object may not exist in menus or during travel. In that case the actor cannot be spawned yet. + +## Saved options + +Manifest options appear in the mod manager and are saved to `config.ini`. The supported section arguments are `bool`, `int`, `float`, `enum`, `string`, `keybind`, and `color`. + +```ini +[option.bool] +id = enabled +label = Enable feature +description = Turns the feature on. +default_value = true + +[option.int] +id = count +label = Count +default_value = 3 +min_value = 0 +max_value = 100 +step = 1 + +[option.enum] +id = mode +label = Mode +enum_values = Off|Normal|Aggressive +default_value = Normal + +[option.keybind] +id = action_key +label = Action +default_value = F8 + +[option.color] +id = display_color +label = Display color +default_value = 255.128.32.255 +``` + +Integer and float options use `min_value`, `max_value`, and `step`. Enum choices are separated by `|`. Colors use decimal RGBA components. + +Lua mods may also read `config.ini` directly when they own custom sections. Native mods normally use the typed configuration handles described in [Native SDK](native-sdk.md). diff --git a/docs/mod-development/unreal.md b/docs/mod-development/unreal.md new file mode 100644 index 0000000..cde9413 --- /dev/null +++ b/docs/mod-development/unreal.md @@ -0,0 +1,231 @@ +# Unreal API + +Hi-Fi RUSH uses a modified Unreal Engine 4.27 build. Public UE 4.27 source is useful for understanding types, but Overdub's layouts and addresses are specific to the supported game executable. + +The C API is declared in [`unreal.h`](../../include/unreal.h), [`unreal_prop.h`](../../include/unreal_prop.h), and [`unreal_reflect.h`](../../include/unreal_reflect.h). Lua uses the same low-level property codec through `overdub.unreal`. + +## Objects and names + +A UObject has a class, an outer, a name, flags, and an entry in the global object array. The outer chain describes containment. It is not the class inheritance chain. + +Object paths and full names are different strings: + +``` +/Script/Engine.Actor +Class /Script/Engine.Actor +``` + +Use a path lookup when you already have the expected class. Use a full-name lookup when the type prefix is part of the identifier. + +```c +uclass_t *actor_class = unreal_uobject_find_class_by_full_name(STR_LIT("Class /Script/Engine.Actor")); +uobject_t *actor = unreal_uobject_find_by_path_name(actor_class, STR_LIT("/Game/Maps/Test.Test:PersistentLevel.MyActor")); +``` + +`unreal_uobject_find_by_path_name` follows the path spelling produced by `unreal_uobject_push_ue_path_name`. A colon separates a package object path from subobjects such as a persistent level actor. + +## Object lifetime + +Treat `uobject_t *` as a borrowed pointer. An actor or asset can disappear during destruction, garbage collection, level streaming, or travel. An object-array slot can later hold another object. + +```c +if (target && !unreal_uobject_is_valid(target)) { + target = NULL; +} +``` + +Validation only describes that moment. When a mod needs to keep track of a particular runtime object, search once for existing instances and maintain the pointer with create and delete listeners. + +```c +static uclass_t *g_wanted_class; +static uobject_t *g_current_object; + +static void +on_object_created(uobject_t *object, int32_t index, void *user) +{ + (void)index; + (void)user; + + if (unreal_uobject_is_a(object, g_wanted_class)) { + g_current_object = object; + } +} + +static void +on_object_deleted(uobject_t *object, int32_t index, void *user) +{ + (void)index; + (void)user; + + if (object == g_current_object) { + g_current_object = NULL; + } +} +``` + +Register those callbacks with `mod_register_uobject_listener`. Registrations made through the mod handle are removed automatically after `deinit`. + +## Properties + +Find a property through its owning class or struct, then use the property codec to locate and read its value. + +```c +fprop_t *prop = unreal_ustruct_find_prop((ustruct_t *)object->cls, STR_LIT("Count")); +void *value = unreal_fprop_value_in_container(prop, object, 0); + +unreal_prop_integer_t count = {0}; +if (prop && value && unreal_fprop_read_integer(prop, value, &count)) { + count.value += 1; + unreal_fprop_write_integer(prop, value, count); +} +``` + +Do not assign property storage with `memcpy` unless the property is known to be plain data. Strings, text, structs, object references, arrays, sets, and maps need Unreal's initialization, copy, and destruction rules. `unreal_prop.h` exposes those operations in one place. + +The property codec supports scalar numbers, booleans, names, strings, text, object and class references, soft references, weak and lazy references, interfaces, structs, arrays, sets, maps, enums, and delegate inspection or binding. Custom class definitions currently support all of those except delegate property declarations. + +Array, set, and map element types are recursive descriptions. Their children are not limited to scalar properties. A supported struct, enum, reference, or another supported container can be used when Unreal allows the resulting layout and hashing rules. + +## UFunctions + +Find a function on its owning `UStruct`. Build a parameter buffer using the function's reflected layout, initialize every property, write inputs through the codec, call the function, read outputs, and destroy every initialized value. + +`unreal_process_event_observed` uses the virtual `ProcessEvent` entry so Overdub hooks can observe the call. `unreal_process_event` calls the captured engine implementation directly. Prefer the observed form for ordinary mod behavior. + +Never retain a parameter buffer, `FFrame`, output pointer, or reflected temporary after the call returns. + +## Object construction and actors + +Use `unreal_construct_object` for a non-actor UObject and give it a suitable outer. `unreal_get_transient_package` is useful for temporary objects. + +```c +uobject_t *object = unreal_construct_object(custom_class, unreal_get_transient_package()); +``` + +Actors must be spawned through the world path instead of plain object construction: + +```c +uobject_t *actor = unreal_spawn_actor(world_context, actor_class); +``` + +The world context can be null when Overdub can resolve the current world. An explicit valid context is clearer when the mod already has one. + +## Custom classes from C + +`mod_define_class` creates a process-lifetime class under a name scoped to the mod ID. The class inherits its parent's native constructor and virtual table. It can add reflected properties and native-backed UFunctions. It cannot add new C++ virtual methods. + +```c +static uclass_t *g_inventory_class; + +static void MOD_CALL +inventory_add(unreal_func_call_t *call) +{ + fprop_t *amount_prop = unreal_ustruct_find_prop((ustruct_t *)call->function, STR_LIT("Amount")); + fprop_t *count_prop = unreal_ustruct_find_prop((ustruct_t *)call->object->cls, STR_LIT("Count")); + fprop_t *return_prop = unreal_ustruct_find_prop((ustruct_t *)call->function, STR_LIT("ReturnValue")); + + void *amount_value = unreal_fprop_value_in_container(amount_prop, call->params, 0); + void *count_value = unreal_fprop_value_in_container(count_prop, call->object, 0); + + unreal_prop_integer_t amount = {0}; + unreal_prop_integer_t count = {0}; + + bool ready = unreal_fprop_read_integer(amount_prop, amount_value, &amount); + ready = ready && unreal_fprop_read_integer(count_prop, count_value, &count); + + if (ready) { + count.value += amount.value; + unreal_fprop_write_integer(count_prop, count_value, count); + unreal_fprop_write_integer(return_prop, call->return_value, count); + } +} + +static bool +define_inventory_class(mod_handle_t mod) +{ + uclass_t *object_class = unreal_uobject_find_class_by_full_name(STR_LIT("Class /Script/CoreUObject.Object")); + uclass_t *actor_class = unreal_uobject_find_class_by_full_name(STR_LIT("Class /Script/Engine.Actor")); + + str_t tag_defaults[] = { + STR_LIT("Default"), + STR_LIT("Inventory"), + }; + + unreal_prop_def_t props[] = { + { + .name = STR_LIT("Count"), + .type = UNREAL_PROP_KIND_INT32, + .integer.default_val = 10, + }, + { + .name = STR_LIT("Owner"), + .type = UNREAL_PROP_KIND_OBJECT, + .cls = actor_class, + }, + { + .name = STR_LIT("Tags"), + .type = UNREAL_PROP_KIND_ARRAY, + .inner.type = UNREAL_PROP_KIND_NAME, + .array.default_val.items = tag_defaults, + .array.default_val.count = COUNTOF(tag_defaults), + }, + }; + + unreal_prop_def_t add_params[] = { + { + .name = STR_LIT("Amount"), + .type = UNREAL_PROP_KIND_INT32, + }, + }; + + unreal_func_def_t funcs[] = { + { + .name = STR_LIT("Add"), + .params = add_params, + .num_params = COUNTOF(add_params), + .ret.type = UNREAL_PROP_KIND_INT32, + .impl = inventory_add, + }, + }; + + unreal_class_def_t def = { + .struct_size = sizeof(def), + .parent = object_class, + .props = props, + .num_props = COUNTOF(props), + .funcs = funcs, + .num_funcs = COUNTOF(funcs), + }; + + g_inventory_class = mod_define_class(mod, STR_LIT("InventoryState"), &def); + return g_inventory_class != NULL; +} +``` + +The definition is copied during the call, including property defaults. The class and its layout remain registered until process exit. When a mod stops, Overdub disables its function implementations but does not destroy the class. Starting the same mod again with the same definition reuses the class and enables the new implementations. + +Static UFunctions are rejected. A custom implementation receives the target object, UFunction, parameter storage, return-value storage, and its `user` pointer through `unreal_func_call_t`. + +Class default values are written to the new class default object. New instances receive independent copies, so dynamic containers do not share their backing storage with the CDO. + +The supported custom property definitions are bool, signed and unsigned integers, float, double, name, string, text, object, class, soft object, soft class, weak object, lazy object, interface, struct, enum, array, set, and map. A set element or map key must have a usable Unreal hash function. + +## Rooting + +Rooting prevents Unreal garbage collection from removing an object. Use it only when the mod truly owns a long-lived object. + +Overdub tracks root claims across mods. The first Overdub claim roots the object, and the last claim removes the root unless the object was already rooted outside Overdub. This prevents one mod from undoing another mod's claim. + +Rooting does not make a destroyed actor usable and does not replace validity checks. + +## PostLoad timing + +Calling `PostLoad` yourself is not a general notification mechanism. A mod that must change an object while the engine is processing its load should hook the object's real `PostLoad` call and run before or after it as required. + +This timing matters for data such as a UDataTable that another system consumes immediately after load. Changing the table later may not update the derived state that the game already built from it. + +Native mods can use a version-specific native hook when no higher-level callback exists. Native Overdub Lua provides `HookPostLoad`; see [Lua Unreal](../lua/unreal.md). + +## Debugging reflection + +Use UObject Search to verify names, paths, classes, properties, and functions before hard-coding them. UFunction Tracer can reveal which reflected calls occur during an action. Both tools operate on the live game and are more reliable than guessing from generated names alone. diff --git a/include/config.h b/include/config.h index 830d5da..3edf20e 100644 --- a/include/config.h +++ b/include/config.h @@ -5,8 +5,12 @@ #define CONFIG_PERM_ARENA_SIZE (64 * GB) /* log */ -#define CONFIG_LOG_FILE_NAME "overdub.log" -#define CONFIG_LOG_LEVEL LOG_LEVEL_DEBUG +#define CONFIG_LOG_FILE_NAME "overdub.log" +#define CONFIG_LOG_LEVEL LOG_LEVEL_DEBUG +#define CONFIG_LOG_QUEUE_CAP (4 * KB) +#define CONFIG_LOG_MAX_MESSAGE_LEN (1 * KB) +#define CONFIG_LOG_UI_DRAIN_LIMIT (256) +#define CONFIG_LOG_FILE_BUFFER_SIZE (64 * KB) /* scratch */ #define CONFIG_SCRATCH_RESERVE_SIZE (4 * GB) @@ -37,6 +41,7 @@ #define CONFIG_NK_CONSOLE_MAX_INPUT_LEN (1 * KB) #define CONFIG_NK_CONSOLE_MAX_HISTORY (256) #define CONFIG_NK_CONSOLE_MAX_COMMANDS (256) +#define CONFIG_NK_CONSOLE_TAB_WIDTH (4) #define CONFIG_NK_CONSOLE_MIN_HEIGHT (100.0f) #define CONFIG_NK_CONSOLE_DEFAULT_HEIGHT_RATIO (0.4f) // 40% of viewport @@ -48,9 +53,46 @@ #define CONFIG_UI_CONSOLE_WINDOW_NAME "Console" /* Lua */ -#define CONFIG_LUA_EXECUTION_LIMIT_US (2 * 1000) -#define CONFIG_LUA_HOOK_INSTRUCTION_COUNT (1000) -#define CONFIG_LUA_MEMORY_LIMIT (16 * MB) +#define CONFIG_LUA_EXECUTION_LIMIT_US (2 * 1000) +#define CONFIG_LUA_HOOK_INSTRUCTION_COUNT (1000) +#define CONFIG_LUA_MEMORY_LIMIT (16 * MB) +#define CONFIG_LUA_OVERDUB_STARTUP_LIMIT_US (2 * 1000) +#define CONFIG_LUA_OVERDUB_CALLBACK_LIMIT_US (250) +#define CONFIG_LUA_OVERDUB_TASK_WORK_BUDGET_US (100) +#define CONFIG_LUA_OVERDUB_FRAME_SOFT_BUDGET_US (500) +#define CONFIG_LUA_OVERDUB_SCHEDULER_CEILING_US (1 * 1000) +#define CONFIG_LUA_OVERDUB_ARENA_RESERVE_SIZE (4 * MB) +#define CONFIG_LUA_OVERDUB_ARENA_COMMIT_SIZE (64 * KB) +#define CONFIG_LUA_OVERDUB_PARAM_ARENA_RESERVE_SIZE (4 * MB) +#define CONFIG_LUA_OVERDUB_PARAM_ARENA_COMMIT_SIZE (64 * KB) +#define CONFIG_LUA_OVERDUB_MAX_TASKS (256) +#define CONFIG_LUA_OVERDUB_MAX_PENDING_INPUTS (64) +#define CONFIG_LUA_OVERDUB_MAX_HOOKS (256) +#define CONFIG_LUA_OVERDUB_MAX_DELEGATE_BINDINGS (256) +#define CONFIG_LUA_OVERDUB_MAX_PENDING_FUNC_CALLS (256) +#define CONFIG_LUA_OVERDUB_MAX_PENDING_HOOKS (256) +#define CONFIG_LUA_OVERDUB_MAX_NOTIFICATIONS (64) +#define CONFIG_LUA_OVERDUB_MAX_PENDING_OBJECTS (256) +#define CONFIG_LUA_OVERDUB_MAX_WORKER_JOBS (64) +#define CONFIG_LUA_OVERDUB_MAX_UI_WINDOWS (32) +#define CONFIG_LUA_OVERDUB_MAX_UI_GRIDS (64) +#define CONFIG_LUA_OVERDUB_MAX_COMMANDS (128) +#define CONFIG_LUA_OVERDUB_COMMAND_NAME_CAP (128) +#define CONFIG_LUA_OVERDUB_WORKER_LIMIT_US (30 * 1000 * 1000) +#define CONFIG_LUA_UE4SS_GAME_DISPATCH_BUDGET_US (2 * 1000) +#define CONFIG_LUA_UE4SS_EXECUTION_LIMIT_US (0) +#define CONFIG_LUA_UE4SS_ASYNC_DISPATCH_BUDGET_US (50 * 1000) +#define CONFIG_LUA_UE4SS_ARENA_RESERVE_SIZE (1 * MB) +#define CONFIG_LUA_UE4SS_ARENA_COMMIT_SIZE (64 * KB) +#define CONFIG_LUA_UE4SS_MAX_COMMANDS (128) +#define CONFIG_LUA_UE4SS_MAX_KEYBINDS (128) +#define CONFIG_LUA_UE4SS_MAX_HOOKS (256) +#define CONFIG_LUA_UE4SS_MAX_NOTIFICATIONS (64) +#define CONFIG_LUA_UE4SS_MAX_PENDING_OBJECTS (256) +#define CONFIG_LUA_UE4SS_MAX_PENDING_HOOKS (256) +#define CONFIG_LUA_UE4SS_MAX_PENDING_INPUTS (256) +#define CONFIG_LUA_UE4SS_MAX_PENDING_COMMANDS (64) +#define CONFIG_LUA_UE4SS_MAX_SCHEDULED_JOBS (256) /* manager */ #define CONFIG_MOD_MANAGER_MAX_MODS (128) diff --git a/include/globals.h b/include/globals.h index e43a637..2ec3d33 100644 --- a/include/globals.h +++ b/include/globals.h @@ -47,6 +47,7 @@ struct globals_s { /* input */ input_key_state_t keys[INPUT_KEY_MAX]; bool consumed_down[INPUT_KEY_MAX]; + float analog_values[INPUT_KEY_MAX]; float wheel_delta; /* mod manager */ diff --git a/include/input.h b/include/input.h index 3bbb693..3edf9ea 100644 --- a/include/input.h +++ b/include/input.h @@ -250,6 +250,8 @@ MOD_API bool input_key_is_pressed(input_key_kind_t key); MOD_API bool input_key_is_released(input_key_kind_t key); +MOD_API float +input_key_get_analog_value(input_key_kind_t key); MOD_API bool input_key_is_bindable(input_key_kind_t key); diff --git a/include/log.h b/include/log.h index f501eee..04174da 100644 --- a/include/log.h +++ b/include/log.h @@ -64,6 +64,23 @@ log_emit(log_level_t level, log_sink_flags_t sinks, const char *fmt, ...) ATTR_F void log_emitv(log_level_t level, log_sink_flags_t sinks, const char *fmt, va_list ap); +typedef struct log_message_s log_message_t; +struct log_message_s { + log_level_t level; + uint64_t timestamp; + uint64_t frame; + str_t text; +}; + +void +log_ui_enqueue(log_level_t level, str_t text); +void +log_ui_on_frame_begin(uint64_t frame_counter); + +typedef struct ui_console_s ui_console_t; + +bool +log_ui_flush(ui_console_t *console); void log_flush(void); void diff --git a/include/lua_mod_runtime.h b/include/lua_mod_runtime.h new file mode 100644 index 0000000..6dc203f --- /dev/null +++ b/include/lua_mod_runtime.h @@ -0,0 +1,48 @@ +#ifndef LUA_MOD_RUNTIME_H +#define LUA_MOD_RUNTIME_H + +#include "input.h" +#include "str.h" +#include "unreal.h" + +typedef struct mod_s mod_t; +typedef struct mod_manager_s mod_manager_t; + +struct nk_context; + +void +lua_mod_runtime_system_init(void); +bool +lua_mod_runtime_start(mod_t *mod); +void +lua_mod_runtime_stop(mod_t *mod); +bool +lua_mod_runtime_is_initialized(mod_t *mod); +void +lua_mod_runtime_tick(mod_t *mod, float delta_seconds); +bool +lua_mod_runtime_input(mod_t *mod, input_event_t *event); +bool +lua_mod_runtime_process_event_pre(mod_t *mod, uobject_t *object, ufunc_t *function, void *params); +void +lua_mod_runtime_process_event_post(mod_t *mod, uobject_t *object, ufunc_t *function, void *params, bool consumed); +void +lua_mod_runtime_post_load(mod_t *mod, uobject_t *object, bool after); +bool +lua_mod_runtime_has_post_load_hooks(void); +bool +lua_mod_runtime_command(mod_t *mod, str_t name, str_t args); +void +lua_mod_runtime_notify_uobject_constructed(mod_manager_t *manager, uobject_t *object); +void +lua_mod_runtime_notify_uobject_deleted(mod_manager_t *manager, uobject_t *object, int32_t idx); +int +lua_mod_runtime_snapshot_commands(mod_t *mod, str_t *names, int capacity); +void +lua_mod_runtime_draw_panel(mod_t *mod, struct nk_context *ctx); +bool +lua_mod_runtime_draw_config(mod_t *mod, struct nk_context *ctx); +bool +lua_mod_runtime_has_draw_config(mod_t *mod); + +#endif /* LUA_MOD_RUNTIME_H */ diff --git a/include/lua_overdub.h b/include/lua_overdub.h new file mode 100644 index 0000000..ca8ee31 --- /dev/null +++ b/include/lua_overdub.h @@ -0,0 +1,42 @@ +#ifndef LUA_OVERDUB_H +#define LUA_OVERDUB_H + +#include "str.h" +#include "types.h" + +typedef struct lua_State lua_State; + +typedef struct lua_overdub_command_context_s lua_overdub_command_context_t; +typedef struct lua_overdub_context_s lua_overdub_context_t; +struct lua_overdub_context_s { + arena_t *arena; + str_t mod_id; + str_t mod_name; + str_t game_dir; + str_t root_dir; + str_t mod_dir; + str_t entry_path; + lua_overdub_command_context_t *commands; + uint32_t owner_thread_id; +}; + +bool +lua_overdub_register(lua_State *state, lua_overdub_context_t *context); +lua_overdub_context_t * +lua_overdub_context_get(lua_State *state); +lua_overdub_context_t * +lua_overdub_context_check(lua_State *state); +bool +lua_overdub_preload_module(lua_State *state, const char *name, int (*open_fn)(lua_State *state)); +bool +lua_overdub_configure_package_paths(lua_State *state, str_t entry_path, str_t mod_dir); +void +lua_overdub_context_cleanup(lua_overdub_context_t *context); +bool +lua_overdub_command_find(lua_overdub_context_t *context, str_t name, uint64_t *out_id, int *out_ref); +bool +lua_overdub_command_remove(lua_overdub_context_t *context, uint64_t id); +int +lua_overdub_command_snapshot(lua_overdub_context_t *context, str_t *names, int capacity); + +#endif /* LUA_OVERDUB_H */ diff --git a/include/lua_overdub_input.h b/include/lua_overdub_input.h new file mode 100644 index 0000000..3e8c153 --- /dev/null +++ b/include/lua_overdub_input.h @@ -0,0 +1,14 @@ +#ifndef LUA_OVERDUB_INPUT_H +#define LUA_OVERDUB_INPUT_H + +#include "input.h" +#include "types.h" + +typedef struct lua_State lua_State; + +bool +lua_overdub_input_register(lua_State *state); +bool +lua_overdub_input_push_event(lua_State *state, const input_event_t *event); + +#endif /* LUA_OVERDUB_INPUT_H */ diff --git a/include/lua_overdub_runtime.h b/include/lua_overdub_runtime.h new file mode 100644 index 0000000..e94f75d --- /dev/null +++ b/include/lua_overdub_runtime.h @@ -0,0 +1,48 @@ +#ifndef LUA_OVERDUB_RUNTIME_H +#define LUA_OVERDUB_RUNTIME_H + +#include "input.h" +#include "str.h" +#include "unreal.h" + +typedef struct mod_s mod_t; +typedef struct mod_manager_s mod_manager_t; + +struct nk_context; + +void +lua_overdub_runtime_system_init(void); +bool +lua_overdub_runtime_start(mod_t *mod); +void +lua_overdub_runtime_stop(mod_t *mod); +bool +lua_overdub_runtime_is_initialized(mod_t *mod); +void +lua_overdub_runtime_tick(mod_t *mod, float delta_seconds); +bool +lua_overdub_runtime_input(mod_t *mod, input_event_t *event); +bool +lua_overdub_runtime_process_event_pre(mod_t *mod, uobject_t *object, ufunc_t *function, void *params); +void +lua_overdub_runtime_process_event_post(mod_t *mod, uobject_t *object, ufunc_t *function, void *params, bool consumed); +void +lua_overdub_runtime_post_load(mod_t *mod, uobject_t *object, bool after); +bool +lua_overdub_runtime_has_post_load_hooks(void); +bool +lua_overdub_runtime_command(mod_t *mod, str_t name, str_t args); +void +lua_overdub_runtime_notify_uobject_constructed(mod_manager_t *manager, uobject_t *object); +void +lua_overdub_runtime_notify_uobject_deleted(mod_manager_t *manager, uobject_t *object, int32_t idx); +int +lua_overdub_runtime_snapshot_commands(mod_t *mod, str_t *names, int capacity); +void +lua_overdub_runtime_draw_panel(mod_t *mod, struct nk_context *ctx); +bool +lua_overdub_runtime_draw_config(mod_t *mod, struct nk_context *ctx); +bool +lua_overdub_runtime_has_draw_config(mod_t *mod); + +#endif /* LUA_OVERDUB_RUNTIME_H */ diff --git a/include/lua_overdub_task.h b/include/lua_overdub_task.h new file mode 100644 index 0000000..5849642 --- /dev/null +++ b/include/lua_overdub_task.h @@ -0,0 +1,26 @@ +#ifndef LUA_OVERDUB_TASK_H +#define LUA_OVERDUB_TASK_H + +#include "lua_runtime.h" +#include "str.h" +#include "types.h" + +typedef struct lua_overdub_task_context_s lua_overdub_task_context_t; +typedef struct lua_overdub_worker_context_s lua_overdub_worker_context_t; + +lua_overdub_task_context_t * +lua_overdub_task_context_create(arena_t *arena, lua_runtime_t *runtime, lua_overdub_worker_context_t *worker, str_t mod_id); +void +lua_overdub_task_context_destroy(lua_overdub_task_context_t *context); +bool +lua_overdub_task_register(lua_State *state, lua_overdub_task_context_t *context); +uint64_t +lua_overdub_task_dispatch(lua_overdub_task_context_t *context, uint64_t budget_us); +int +lua_overdub_task_active_count(lua_overdub_task_context_t *context); +uint64_t +lua_overdub_task_dispatch_worker_completions(lua_overdub_task_context_t *context, bool *in_callback, uint64_t budget_us); +int +lua_overdub_task_future_count(lua_overdub_task_context_t *context); + +#endif /* LUA_OVERDUB_TASK_H */ diff --git a/include/lua_overdub_ui.h b/include/lua_overdub_ui.h new file mode 100644 index 0000000..e886767 --- /dev/null +++ b/include/lua_overdub_ui.h @@ -0,0 +1,27 @@ +#ifndef LUA_OVERDUB_UI_H +#define LUA_OVERDUB_UI_H + +#include "lua_runtime.h" +#include "str.h" +#include "types.h" + +typedef struct lua_State lua_State; + +struct nk_context; + +typedef struct lua_overdub_ui_context_s lua_overdub_ui_context_t; + +lua_overdub_ui_context_t * +lua_overdub_ui_context_create(arena_t *arena, lua_runtime_t *runtime, str_t mod_id, uint32_t owner_thread_id); +void +lua_overdub_ui_context_destroy(lua_overdub_ui_context_t *context); +bool +lua_overdub_ui_register(lua_State *state, lua_overdub_ui_context_t *context); +uint64_t +lua_overdub_ui_draw_windows(lua_overdub_ui_context_t *ui, struct nk_context *nk, bool *in_cb, unsigned int vw, unsigned int vh); +bool +lua_overdub_ui_begin_callback(lua_overdub_ui_context_t *ui, struct nk_context *nk, unsigned int vw, unsigned int vh); +void +lua_overdub_ui_end_callback(lua_overdub_ui_context_t *ui); + +#endif /* LUA_OVERDUB_UI_H */ diff --git a/include/lua_overdub_unreal.h b/include/lua_overdub_unreal.h new file mode 100644 index 0000000..73b59d4 --- /dev/null +++ b/include/lua_overdub_unreal.h @@ -0,0 +1,44 @@ +#ifndef LUA_OVERDUB_UNREAL_H +#define LUA_OVERDUB_UNREAL_H + +#include "arena.h" +#include "str.h" +#include "types.h" + +typedef struct lua_State lua_State; +typedef struct lua_runtime_s lua_runtime_t; +typedef struct lua_overdub_unreal_context_s lua_overdub_unreal_context_t; +typedef struct uobject_s uobject_t; +typedef struct ufunc_s ufunc_t; + +lua_overdub_unreal_context_t * +lua_overdub_unreal_context_create(arena_t *arena, lua_runtime_t *runtime, bool *in_callback, str_t mod_id, uint32_t owner_thread_id); +void +lua_overdub_unreal_context_deactivate(lua_overdub_unreal_context_t *context); +void +lua_overdub_unreal_context_destroy(lua_overdub_unreal_context_t *context); +bool +lua_overdub_unreal_register(lua_State *state, lua_overdub_unreal_context_t *context); +void +lua_overdub_unreal_notify_constructed(uobject_t *object); +void +lua_overdub_unreal_notify_deleted(uobject_t *object, int32_t idx); +bool +lua_overdub_unreal_process_event_pre(lua_overdub_unreal_context_t *context, lua_runtime_t *runtime, + bool *in_callback, uobject_t *object, ufunc_t *function, void *params); +void +lua_overdub_unreal_process_event_post(lua_overdub_unreal_context_t *context, lua_runtime_t *runtime, + bool *in_callback, uobject_t *object, ufunc_t *function, void *params, bool consumed); +void +lua_overdub_unreal_post_load(lua_overdub_unreal_context_t *context, lua_runtime_t *runtime, bool *in_callback, uobject_t *object, bool after); +bool +lua_overdub_unreal_has_post_load_hooks(void); +int +lua_overdub_unreal_post_load_hook_count(void); +uint64_t +lua_overdub_unreal_dispatch_pending(lua_overdub_unreal_context_t *context, lua_runtime_t *runtime, + bool *in_callback, uint64_t budget_us); +int +lua_overdub_unreal_pending_count(lua_overdub_unreal_context_t *context); + +#endif /* LUA_OVERDUB_UNREAL_H */ diff --git a/include/lua_overdub_worker.h b/include/lua_overdub_worker.h new file mode 100644 index 0000000..ec22b55 --- /dev/null +++ b/include/lua_overdub_worker.h @@ -0,0 +1,41 @@ +#ifndef LUA_OVERDUB_WORKER_H +#define LUA_OVERDUB_WORKER_H + +#include "lua_serial.h" +#include "str.h" +#include "types.h" + +typedef struct lua_overdub_worker_context_s lua_overdub_worker_context_t; + +typedef uint8_t lua_overdub_worker_result_t; +enum { + LUA_OVERDUB_WORKER_SUCCESS = 0, + LUA_OVERDUB_WORKER_ERROR, + LUA_OVERDUB_WORKER_CANCELLED, +}; + +typedef struct lua_overdub_worker_completion_s lua_overdub_worker_completion_t; +struct lua_overdub_worker_completion_s { + uint64_t id; + lua_overdub_worker_result_t result; + lua_serial_blob_t value; + char error[1024]; +}; + +lua_overdub_worker_context_t * +lua_overdub_worker_context_create(arena_t *arena, str_t mod_id, str_t entry_path, str_t mod_dir, uint32_t owner_thread_id); +void +lua_overdub_worker_context_destroy(lua_overdub_worker_context_t *context); +bool +lua_overdub_worker_submit(lua_overdub_worker_context_t *context, str_t module_name, str_t function_name, + lua_serial_blob_t *input, uint64_t *out_id, char *error, size_t error_cap); +bool +lua_overdub_worker_cancel(lua_overdub_worker_context_t *context, uint64_t id); +bool +lua_overdub_worker_poll(lua_overdub_worker_context_t *context, lua_overdub_worker_completion_t *out_completion); +void +lua_overdub_worker_completion_destroy(lua_overdub_worker_completion_t *completion); +int +lua_overdub_worker_outstanding_count(lua_overdub_worker_context_t *context); + +#endif /* LUA_OVERDUB_WORKER_H */ diff --git a/include/lua_runtime.h b/include/lua_runtime.h index 44fc4c2..acfac0d 100644 --- a/include/lua_runtime.h +++ b/include/lua_runtime.h @@ -4,7 +4,8 @@ #include "str.h" #include "types.h" -typedef struct lua_State lua_State; +typedef struct lua_State lua_State; + typedef struct lua_runtime_s lua_runtime_t; struct lua_runtime_s { lua_State *state; @@ -12,14 +13,32 @@ struct lua_runtime_s { uint64_t execution_limit_us; uint64_t memory_used; uint64_t memory_limit; + bool persistent_output; bool inited; }; bool lua_runtime_init(lua_runtime_t *runtime); +bool +lua_runtime_init_with_execution_limit(lua_runtime_t *runtime, uint64_t execution_limit_us); +bool +lua_runtime_enable_mod_libs(lua_runtime_t *runtime); void lua_runtime_deinit(lua_runtime_t *runtime); bool lua_runtime_execute(lua_runtime_t *runtime, str_t source); +bool +lua_runtime_execute_file(lua_runtime_t *runtime, str_t path); +bool +lua_runtime_execute_file_results(lua_runtime_t *runtime, str_t path, int result_count); +bool +lua_runtime_call_ref(lua_runtime_t *runtime, int callback_ref, int arg_count, int result_count); +bool +lua_runtime_call_ref_ex(lua_runtime_t *runtime, int callback_ref, int arg_count, int result_count, bool log_error, + uint64_t suppressed_error_hash, uint64_t *out_error_hash); +int +lua_runtime_resume(lua_runtime_t *runtime, lua_State *thread, int arg_count, int *result_count); +bool +lua_runtime_pcall(lua_runtime_t *runtime, int arg_count, int result_count, char *error, size_t error_cap); #endif /* LUA_RUNTIME_H */ diff --git a/include/lua_serial.h b/include/lua_serial.h new file mode 100644 index 0000000..394ecbb --- /dev/null +++ b/include/lua_serial.h @@ -0,0 +1,21 @@ +#ifndef LUA_SERIAL_H +#define LUA_SERIAL_H + +#include "types.h" + +typedef struct lua_State lua_State; + +typedef struct lua_serial_blob_s lua_serial_blob_t; +struct lua_serial_blob_s { + uint8_t *data; + uint64_t len; +}; + +bool +lua_serial_encode(lua_State *state, int value_idx, lua_serial_blob_t *out_blob, char *error, size_t error_cap); +bool +lua_serial_decode(lua_State *state, lua_serial_blob_t blob, char *error, size_t error_cap); +void +lua_serial_blob_free(lua_serial_blob_t *blob); + +#endif /* LUA_SERIAL_H */ diff --git a/include/lua_ue4ss.h b/include/lua_ue4ss.h new file mode 100644 index 0000000..bf7cc88 --- /dev/null +++ b/include/lua_ue4ss.h @@ -0,0 +1,153 @@ +#ifndef LUA_UE4SS_H +#define LUA_UE4SS_H + +#include "arena.h" +#include "input.h" +#include "lua_runtime.h" +#include "lua_unreal_prop.h" +#include "str.h" + +typedef struct lua_ue4ss_command_s lua_ue4ss_command_t; +struct lua_ue4ss_command_s { + str_t name; + int callback_ref; +}; + +typedef struct lua_ue4ss_keybind_s lua_ue4ss_keybind_t; +struct lua_ue4ss_keybind_s { + keybind_t bind; + int callback_ref; +}; + +typedef struct lua_ue4ss_hook_s lua_ue4ss_hook_t; +struct lua_ue4ss_hook_s { + str_t target; + fweak_object_ptr_t function; + int64_t pre_id; + int64_t post_id; + int pre_callback_ref; + int post_callback_ref; + bool active; + bool pre_slow_warned; + bool post_slow_warned; +}; + +typedef struct lua_ue4ss_notification_s lua_ue4ss_notification_t; +struct lua_ue4ss_notification_s { + str_t class_path; + fweak_object_ptr_t target_class; + int callback_ref; + bool active; +}; + +typedef struct lua_ue4ss_pending_object_s lua_ue4ss_pending_object_t; +struct lua_ue4ss_pending_object_s { + fweak_object_ptr_t object; +}; + +typedef struct lua_ue4ss_pending_hook_s lua_ue4ss_pending_hook_t; +struct lua_ue4ss_pending_hook_s { + fweak_object_ptr_t object; + fweak_object_ptr_t function; + ufunc_t *function_raw; + void *params; + uint32_t initialized_count; + bool post; +}; + +typedef struct lua_ue4ss_pending_command_s lua_ue4ss_pending_command_t; +struct lua_ue4ss_pending_command_s { + char *data; + uint64_t name_len; + uint64_t args_len; +}; + +typedef struct lua_ue4ss_scheduled_job_s lua_ue4ss_scheduled_job_t; +struct lua_ue4ss_scheduled_job_s { + uint64_t due_us; + uint64_t interval_us; + uint64_t ready_tick; + uint64_t interval_ticks; + int64_t handle; + uint64_t last_error_hash; + int callback_ref; + uint32_t consecutive_errors; + bool loop; + bool frame_based; + bool game_thread; + bool active; + bool slow_warned; +}; + +typedef struct lua_ue4ss_context_s lua_ue4ss_context_t; +struct lua_ue4ss_context_s { + str_t game_dir; + str_t root_mod_dir; + str_t mod_dir; + str_t mod_dir_name; + str_t mod_id; + str_t entry_path; + arena_t *arena; + lua_runtime_t *runtime; + lua_ue4ss_command_t *commands; + int command_count; + lua_ue4ss_keybind_t *keybinds; + int keybind_count; + lua_ue4ss_hook_t *hooks; + int hook_count; + int64_t next_hook_id; + lua_ue4ss_notification_t *notifications; + int notification_count; + lua_ue4ss_pending_object_t *pending_objects; + int pending_object_count; + lua_ue4ss_pending_hook_t *pending_hooks; + int pending_hook_count; + input_event_t *pending_inputs; + int pending_input_count; + lua_ue4ss_pending_command_t *pending_commands; + int pending_command_count; + volatile int32_t pending_lock; + bool pending_overflow; + bool pending_hook_overflow; + bool pending_input_overflow; + bool pending_command_overflow; + bool async_events; + lua_ue4ss_scheduled_job_t *scheduled_jobs; + int scheduled_job_count; + int64_t next_action_handle; + uint64_t scheduler_tick; + uint64_t async_scheduler_tick; + void (*wake_async)(void *user); + void *wake_async_user; +}; + +bool +lua_ue4ss_context_init(lua_ue4ss_context_t *context, arena_t *arena, lua_runtime_t *runtime); +void +lua_ue4ss_context_deinit(lua_ue4ss_context_t *context); + +bool +lua_ue4ss_register(lua_State *state, lua_ue4ss_context_t *context); +void +lua_ue4ss_notify_uobject_constructed(lua_ue4ss_context_t *context, uobject_t *object); + +void +lua_ue4ss_dispatch_game_thread(lua_ue4ss_context_t *context); +void +lua_ue4ss_dispatch_async(lua_ue4ss_context_t *context); +bool +lua_ue4ss_dispatch_command(lua_ue4ss_context_t *context, str_t name, str_t args, bool *handled); +bool +lua_ue4ss_dispatch_process_event_pre(lua_ue4ss_context_t *context, uobject_t *obj, ufunc_t *func, void *params); +void +lua_ue4ss_dispatch_process_event_post(lua_ue4ss_context_t *context, uobject_t *obj, ufunc_t *func, void *params, bool consumed); + +uint32_t +lua_ue4ss_async_wait_ms(lua_ue4ss_context_t *context); + +bool +lua_ue4ss_queue_input(lua_ue4ss_context_t *context, input_event_t *ev); +bool +lua_ue4ss_queue_command(lua_ue4ss_context_t *context, str_t name, str_t args); + +#endif /* LUA_UE4SS_H */ diff --git a/include/lua_ue4ss_runtime.h b/include/lua_ue4ss_runtime.h new file mode 100644 index 0000000..f10153c --- /dev/null +++ b/include/lua_ue4ss_runtime.h @@ -0,0 +1,34 @@ +#ifndef LUA_UE4SS_RUNTIME_H +#define LUA_UE4SS_RUNTIME_H + +#include "input.h" +#include "str.h" +#include "unreal.h" + +typedef struct mod_s mod_t; +typedef struct mod_manager_s mod_manager_t; + +void +lua_ue4ss_runtime_system_init(void); +bool +lua_ue4ss_runtime_start(mod_t *mod); +void +lua_ue4ss_runtime_stop(mod_t *mod); +bool +lua_ue4ss_runtime_is_initialized(mod_t *mod); +void +lua_ue4ss_runtime_tick(mod_t *mod); +void +lua_ue4ss_runtime_queue_input(mod_t *mod, input_event_t *event); +bool +lua_ue4ss_runtime_process_event_pre(mod_t *mod, uobject_t *object, ufunc_t *function, void *params); +void +lua_ue4ss_runtime_process_event_post(mod_t *mod, uobject_t *object, ufunc_t *function, void *params, bool consumed); +bool +lua_ue4ss_runtime_queue_command(mod_t *mod, str_t name, str_t args); +void +lua_ue4ss_runtime_notify_uobject_constructed(mod_manager_t *manager, uobject_t *object); +int +lua_ue4ss_runtime_snapshot_commands(mod_t *mod, str_t *names, int capacity); + +#endif /* LUA_UE4SS_RUNTIME_H */ diff --git a/include/lua_unreal_prop.h b/include/lua_unreal_prop.h new file mode 100644 index 0000000..81614ca --- /dev/null +++ b/include/lua_unreal_prop.h @@ -0,0 +1,114 @@ +#ifndef LUA_UNREAL_PROP_H +#define LUA_UNREAL_PROP_H + +#include "unreal_prop.h" + +typedef struct lua_State lua_State; + +MOD_EXTERN_C_BEGIN + +typedef struct lua_unreal_context_s lua_unreal_context_t; + +typedef bool (*lua_unreal_access_check_fn_t) (void *user); +typedef uobject_t *(*lua_unreal_find_object_fn_t) (void *user, str_t name); +typedef int (*lua_unreal_object_count_fn_t) (void *user); +typedef uobject_t *(*lua_unreal_object_at_fn_t) (void *user, int idx); +typedef bool (*lua_unreal_process_event_fn_t)(void *user, uobject_t *receiver, ufunc_t *function, void *params); + +/* The context and every callback/user pointer must outlive the registered Lua state. + * Lua states using Unreal values must be closed on the game thread. */ +struct lua_unreal_context_s { + void *user; + lua_unreal_access_check_fn_t access_check; + lua_unreal_find_object_fn_t find_object; + lua_unreal_object_count_fn_t object_count; + lua_unreal_object_at_fn_t object_at; + lua_unreal_process_event_fn_t process_event; +}; + +MOD_API void +lua_unreal_context_init(lua_unreal_context_t *context); + +/* Installs the UE4SS-compatible object-discovery globals, FName/FText helpers, + * flag constants, and Unreal table. This smaller entry point is useful to + * verify/embed discovery without registering reflected UObject property behavior. */ +MOD_API bool +lua_unreal_register_static(lua_State *state, lua_unreal_context_t *context); + +/* Registers metatables, the Unreal table, and UE4SS-compatible discovery/FName + * globals (StaticFindObject, FindObject[s], FindFirst/AllOf, and FName) in an arbitrary state. + * UObject reads resolve reflected properties, reflected functions, then metatable methods. + * Unsigned values above LUA_MAXINTEGER are intentionally not marshalled lossily. */ +MOD_API bool +lua_unreal_register(lua_State *state, lua_unreal_context_t *context); + +/* Registers only the internal userdata/metatable layer used by the property + * codec. It does not install Unreal, UE4SS globals, or object-discovery + * functions. A model-specific runtime may layer its own module on top. */ +MOD_API bool +lua_unreal_register_codec(lua_State *state, lua_unreal_context_t *context); + +/* Pushes the shared UObject metatable so a model-specific layer can add its + * own methods. Returns false and leaves the stack unchanged if unavailable. */ +MOD_API bool +lua_unreal_object_metatable_push(lua_State *state); + +/* Replaces the codec's lowercase compatibility aliases (type/get/set) with + * CamelCase names in the current state. The UE4SS registration does not call + * this function. */ +MOD_API void +lua_unreal_use_camel_case_names(lua_State *state); + +/* Model-neutral constructors/constants used by module-specific APIs. */ +MOD_API int +lua_unreal_fname_construct(lua_State *state); +MOD_API int +lua_unreal_ftext_construct(lua_State *state); +MOD_API int +lua_unreal_name_none_push(lua_State *state); +MOD_API void +lua_unreal_object_flags_push(lua_State *state); +MOD_API void +lua_unreal_internal_object_flags_push(lua_State *state); +MOD_API void +lua_unreal_property_types_push(lua_State *state); +MOD_API void +lua_unreal_find_name_modes_push(lua_State *state); + +/* Pushes nil for a null object and one validated UObject userdata otherwise */ +MOD_API int +lua_unreal_object_push(lua_State *state, uobject_t *object); + +/* Pushes a UObject userdata whose weak pointer is intentionally invalid. */ +MOD_API int +lua_unreal_object_push_invalid(lua_State *state); + +/* Returns NULL for a non-UObject value or a stale userdata */ +MOD_API uobject_t * +lua_unreal_object_get(lua_State *state, int idx); + +/* Pushes one scalar/object value or an owned FString/FText/soft-reference/ + * struct/fixed-array/container value. Returns zero for unsupported reflected + * kinds such as delegates. */ +MOD_API int +lua_unreal_prop_push(lua_State *state, fprop_t *prop, void *value, uobject_t *owner); + +/* Transactionally converts and copies a scalar or complete reflected value. */ +MOD_API bool +lua_unreal_prop_write(lua_State *state, int value_idx, fprop_t *prop, void *dst, uobject_t *owner); + +/* A scope keeps borrowed ProcessEvent parameter storage valid only while its + * callback is executing. Retained RemoteUnrealParam values fail cleanly after + * lua_unreal_param_scope_end instead of referring to a reused params block. */ +MOD_API int +lua_unreal_param_scope_begin(lua_State *state); +MOD_API void +lua_unreal_param_scope_end(lua_State *state, int scope_ref); +MOD_API int +lua_unreal_remote_param_push(lua_State *state, int scope_ref, fprop_t *prop, void *value, uobject_t *owner, bool writable); +MOD_API int +lua_unreal_remote_object_param_push(lua_State *state, int scope_ref, uobject_t *object); + +MOD_EXTERN_C_END + +#endif /* LUA_UNREAL_PROP_H */ diff --git a/include/mod.h b/include/mod.h index 5f5d1fa..1aac434 100644 --- a/include/mod.h +++ b/include/mod.h @@ -7,6 +7,7 @@ #include "str.h" #include "types.h" #include "unreal.h" +#include "unreal_reflect.h" #include "version.h" MOD_EXTERN_C_BEGIN @@ -80,6 +81,7 @@ MOD_API void mod_log(mod_handle_t mod, log_level_t level, const char MOD_API void mod_logv(mod_handle_t mod, log_level_t level, const char *fmt, va_list args); MOD_API mod_cfg_handle_t mod_get_cfg_by_id(mod_handle_t mod, str_t id); MOD_API bool mod_register_cmd(mod_handle_t mod, str_t name, str_t description, mod_cmd_fn_t fn, void *user); +MOD_API uclass_t *mod_define_class(mod_handle_t mod, str_t name, const unreal_class_def_t *def); /* UI and timing */ MOD_API struct nk_context *mod_get_nk_ctx(void); diff --git a/include/mod_manager.h b/include/mod_manager.h index bc13bbb..95150c7 100644 --- a/include/mod_manager.h +++ b/include/mod_manager.h @@ -97,6 +97,31 @@ struct mod_dll_info_s { str_t path; }; +typedef struct mod_lua_info_s mod_lua_info_t; + +typedef uint8_t mod_lua_runtime_kind_t; +enum { + MOD_LUA_RUNTIME_OVERDUB = 0, + MOD_LUA_RUNTIME_UE4SS = 1, + MOD_LUA_RUNTIME_MAX, + MOD_LUA_RUNTIME_INVALID = UINT8_MAX, +}; + +static inline str_t +mod_lua_runtime_kind_to_str(mod_lua_runtime_kind_t kind) +{ + switch (kind) { + case MOD_LUA_RUNTIME_UE4SS: return STR_LIT("ue4ss"); + case MOD_LUA_RUNTIME_OVERDUB: return STR_LIT("overdub"); + } + return STR_LIT("invalid"); +} + +struct mod_lua_info_s { + str_t path; + mod_lua_runtime_kind_t runtime_kind; +}; + typedef struct mod_asset_info_s mod_asset_info_t; struct mod_asset_info_s { str_t pak_path; @@ -168,6 +193,7 @@ struct mod_manifest_s { mod_info_t info; mod_dll_info_t dll; + mod_lua_info_t lua; mod_asset_info_t asset; mod_blueprint_info_t *blueprints; int blueprint_count; @@ -292,6 +318,17 @@ struct mod_dll_runtime_s { uobject_listener_t *listeners; }; +typedef struct mod_lua_runtime_s mod_lua_runtime_t; +struct mod_lua_runtime_s { + bool active; + bool start_attempted; + err_msg_t err_msg; + str_t game_dir; + str_t root_mod_dir; + arena_t perm; + void *instance; +}; + typedef struct mod_asset_runtime_s mod_asset_runtime_t; struct mod_asset_runtime_s { mod_asset_state_t state; @@ -354,11 +391,13 @@ struct mod_s { bool enabled; bool has_code; + bool has_lua; bool has_assets; bool has_blueprints; bool has_options; mod_dll_runtime_t dll; + mod_lua_runtime_t lua; mod_asset_runtime_t asset; mod_blueprint_runtime_t *blueprints; int blueprint_count; @@ -405,6 +444,8 @@ mod_manager_mount_assets(mod_manager_t *manager); void mod_manager_start_dlls(mod_manager_t *manager); void +mod_manager_start_lua(mod_manager_t *manager); +void mod_manager_start_blueprints(mod_manager_t *manager); void @@ -457,6 +498,11 @@ mod_dll_restart(mod_manager_t *manager, mod_handle_t h); bool mod_dll_reload(mod_manager_t *manager, mod_handle_t h); +bool +mod_lua_start(mod_manager_t *manager, mod_handle_t h); +void +mod_lua_stop(mod_manager_t *manager, mod_handle_t h); + bool mod_blueprint_spawn(mod_manager_t *manager, mod_handle_t h, int idx); bool @@ -491,12 +537,20 @@ mod_dll_arena_free(mod_manager_t *manager, mod_handle_t h, arena_t *arena); void mod_manager_dispatch_tick(mod_manager_t *manager, float delta); +void +mod_manager_dispatch_uobject_constructed(mod_manager_t *manager, uobject_t *object); +void +mod_manager_dispatch_uobject_deleted(mod_manager_t *manager, uobject_t *object, int32_t idx); bool mod_manager_dispatch_input(mod_manager_t *manager, input_event_t *ev); bool mod_manager_dispatch_process_event_pre(mod_manager_t *manager, uobject_t *obj, ufunc_t *func, void *params); void mod_manager_dispatch_process_event_post(mod_manager_t *manager, uobject_t *obj, ufunc_t *func, void *params, bool consumed); +void +mod_manager_dispatch_post_load(mod_manager_t *manager, uobject_t *obj, bool after); +bool +mod_manager_has_post_load_hooks(mod_manager_t *manager); bool mod_manager_dispatch_ufunction_invoke_pre(mod_manager_t *manager, ufunc_t *func, uobject_t *obj, fframe_t *stack, void *result); void diff --git a/include/overdub_lua.h b/include/overdub_lua.h new file mode 100644 index 0000000..972581e --- /dev/null +++ b/include/overdub_lua.h @@ -0,0 +1,40 @@ +#ifndef OVERDUB_LUA_H +#define OVERDUB_LUA_H + +#if defined(_WIN32) && !defined(OVERDUB_BUILD_DLL) && !defined(LUA_BUILD_AS_DLL) +# define LUA_BUILD_AS_DLL +# define OVERDUB_LUA_UNDEF_BUILD_AS_DLL +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +#include "lua/src/lua.h" +#include "lua/src/lauxlib.h" +#include "lua/src/lualib.h" + +#if defined(__cplusplus) +} +#endif + +#if defined(OVERDUB_LUA_UNDEF_BUILD_AS_DLL) +# undef OVERDUB_LUA_UNDEF_BUILD_AS_DLL +# undef LUA_BUILD_AS_DLL +#endif + +#if defined(_WIN32) +# if defined(__cplusplus) +# define OVERDUB_LUA_MODULE extern "C" __declspec(dllexport) +# else +# define OVERDUB_LUA_MODULE __declspec(dllexport) +# endif +#else +# if defined(__cplusplus) +# define OVERDUB_LUA_MODULE extern "C" +# else +# define OVERDUB_LUA_MODULE +# endif +#endif + +#endif /* OVERDUB_LUA_H */ diff --git a/include/types.h b/include/types.h index 8d7e089..8449dc0 100644 --- a/include/types.h +++ b/include/types.h @@ -213,7 +213,7 @@ my_assert_msg(const char *expr, const char *file, int line, const char *fmt, ... MOD_API void my_assert(const char *expr, const char *file, int line); -#if defined BUILD_DEBUG || defined BUILD_TEST_UI +#if defined BUILD_DEBUG # define ASSERT(COND) \ do { \ if (!(COND)) { \ @@ -373,6 +373,12 @@ mem_move(void *dst, void *src, uint64_t size) MOD_API uint64_t time_now_us(void); +MOD_API uint32_t +thread_current_id(void); +MOD_API int32_t +atomic_i32_increment(volatile int32_t *value); +MOD_API int32_t +atomic_i32_compare_exchange(volatile int32_t *value, int32_t exchange, int32_t comparand); static inline uint64_t time_snap_up(uint64_t t, uint32_t q) diff --git a/include/ui_console.h b/include/ui_console.h index bd0bac8..ca423b5 100644 --- a/include/ui_console.h +++ b/include/ui_console.h @@ -3,6 +3,7 @@ #include "input.h" #include "lua_runtime.h" +#include "lua_unreal_prop.h" #include "log.h" #include "mod_manager.h" #include "str.h" @@ -11,6 +12,8 @@ #include "vendor_nuklear.h" +#define UI_CONSOLE_TIMESTAMP_CAP (48) + typedef int ui_console_log_level_t; enum { UI_CONSOLE_LOG_DEBUG, @@ -53,7 +56,9 @@ ui_console_position_str_array(void); typedef struct ui_console_line_s ui_console_line_t; struct ui_console_line_s { str_t text; + str_t display_text; ui_console_log_level_t level; + char timestamp[UI_CONSOLE_TIMESTAMP_CAP]; float row_w; }; @@ -70,19 +75,23 @@ struct ui_console_cfg_s { keybind_t toggle_bind; bool auto_scroll; bool wrap_lines; + bool show_timestamp; + bool show_log_level; ui_console_position_t position; ui_console_log_level_t min_level; }; typedef struct ui_console_s ui_console_t; struct ui_console_s { - lua_runtime_t lua; + lua_runtime_t lua; + lua_unreal_context_t lua_unreal; ui_console_line_t *lines; uint8_t *line_text_storage; int line_count; int max_lines; int max_line_len; + uint8_t prefix_flags; uint8_t *input_buf; int input_max; @@ -109,13 +118,15 @@ struct ui_console_s { void ui_console_init(ui_console_t *console, arena_t *arena); void -ui_console_logv(ui_console_t *console, ui_console_log_level_t level, const char *fmt, va_list ap); +ui_console_on_frame_begin(ui_console_t *console, uint64_t frame_counter); +void +ui_console_flush_logs(ui_console_t *console); + +void +ui_console_append_log(ui_console_t *console, const log_message_t *message); + void -ui_console_draw(ui_console_t *console, - struct nk_context *ctx, - mod_manager_t *mod_manager, - unsigned int viewport_width, - unsigned int viewport_height); +ui_console_draw(ui_console_t *console, struct nk_context *ctx, mod_manager_t *mod_manager, unsigned int vw, unsigned int vh); void ui_console_toggle(ui_console_t *console); diff --git a/include/ui_mod_manager.h b/include/ui_mod_manager.h index e50cd17..461512e 100644 --- a/include/ui_mod_manager.h +++ b/include/ui_mod_manager.h @@ -41,6 +41,10 @@ struct ui_inspector_state_s { enum nk_collapse_states code_dll_info_open; enum nk_collapse_states code_runtime_open; + enum nk_collapse_states lua_open; + enum nk_collapse_states lua_info_open; + enum nk_collapse_states lua_runtime_open; + enum nk_collapse_states blueprints_open; enum nk_collapse_states blueprints_info_open; enum nk_collapse_states blueprints_runtime_open; diff --git a/include/ui_nuklear.h b/include/ui_nuklear.h index 3ca3a3a..64a497f 100644 --- a/include/ui_nuklear.h +++ b/include/ui_nuklear.h @@ -95,10 +95,13 @@ #define UI_C_BORDER_FOCUS nk_rgba(218, 105, 88, 245) /* Text */ -#define UI_C_TEXT nk_rgba(235, 238, 243, 255) -#define UI_C_TEXT_MUTED nk_rgba(177, 187, 199, 255) -#define UI_C_TEXT_DIM nk_rgba(130, 142, 156, 255) -#define UI_C_TEXT_DISABLED nk_rgba( 89, 99, 111, 255) +#define UI_C_TEXT nk_rgba(235, 238, 243, 255) +#define UI_C_TEXT_MUTED nk_rgba(177, 187, 199, 255) +#define UI_C_TEXT_DIM nk_rgba(130, 142, 156, 255) +#define UI_C_TEXT_DISABLED nk_rgba( 89, 99, 111, 255) +#define UI_C_PROP_TYPE_TEXT nk_rgba(218, 156, 62, 255) +#define UI_C_PROP_VALUE_TEXT nk_rgba(139, 191, 166, 255) +#define UI_C_PROP_LINK_TEXT nk_rgba(122, 184, 232, 255) /* Generic controls */ #define UI_C_CONTROL nk_rgba( 31, 37, 45, 255) diff --git a/include/unreal.h b/include/unreal.h index d7c664e..0f40db1 100644 --- a/include/unreal.h +++ b/include/unreal.h @@ -28,6 +28,8 @@ MOD_EXTERN_C_BEGIN #define UOBJECT_ARRAY_NUM_ELEMS_PER_CHUNK (64 * 1024) +typedef uint32_t efunc_flags_t; + #define FUNC_FLAG_NONE 0x00000000 #define FUNC_FLAG_FINAL 0x00000001 #define FUNC_FLAG_REQUIRED_API 0x00000002 @@ -172,6 +174,58 @@ enum { RF_HAS_EXTERNAL_PACKAGE = 0X10000000, }; +typedef uint32_t eclass_flags_t; +enum { + CLASS_NONE = 0x00000000u, + CLASS_ABSTRACT = 0x00000001u, + CLASS_DEFAULT_CONFIG = 0x00000002u, + CLASS_CONFIG = 0x00000004u, + CLASS_TRANSIENT = 0x00000008u, + CLASS_PARSED = 0x00000010u, + CLASS_MATCHED_SERIALIZERS = 0x00000020u, + CLASS_PROJECT_USER_CONFIG = 0x00000040u, + CLASS_NATIVE = 0x00000080u, + CLASS_NO_EXPORT = 0x00000100u, + CLASS_NOT_PLACEABLE = 0x00000200u, + CLASS_PER_OBJECT_CONFIG = 0x00000400u, + CLASS_REPLICATION_DATA_IS_SET_UP = 0x00000800u, + CLASS_EDIT_INLINE_NEW = 0x00001000u, + CLASS_COLLAPSE_CATEGORIES = 0x00002000u, + CLASS_INTERFACE = 0x00004000u, + CLASS_CUSTOM_CONSTRUCTOR = 0x00008000u, + CLASS_CONST = 0x00010000u, + CLASS_LAYOUT_CHANGING = 0x00020000u, + CLASS_COMPILED_FROM_BLUEPRINT = 0x00040000u, + CLASS_MINIMAL_API = 0x00080000u, + CLASS_REQUIRED_API = 0x00100000u, + CLASS_DEFAULT_TO_INSTANCED = 0x00200000u, + CLASS_TOKEN_STREAM_ASSEMBLED = 0x00400000u, + CLASS_HAS_INSTANCED_REFERENCE = 0x00800000u, + CLASS_HIDDEN = 0x01000000u, + CLASS_DEPRECATED = 0x02000000u, + CLASS_HIDE_DROP_DOWN = 0x04000000u, + CLASS_GLOBAL_USER_CONFIG = 0x08000000u, + CLASS_INTRINSIC = 0x10000000u, + CLASS_CONSTRUCTED = 0x20000000u, + CLASS_CONFIG_DO_NOT_CHECK_DEFAULTS = 0x40000000u, + CLASS_NEWER_VERSION_EXISTS = 0x80000000u, + CLASS_INHERIT = CLASS_TRANSIENT | + CLASS_DEFAULT_CONFIG | + CLASS_CONFIG | + CLASS_PER_OBJECT_CONFIG | + CLASS_CONFIG_DO_NOT_CHECK_DEFAULTS | + CLASS_NOT_PLACEABLE | + CLASS_CONST | + CLASS_HAS_INSTANCED_REFERENCE | + CLASS_DEPRECATED | + CLASS_DEFAULT_TO_INSTANCED | + CLASS_GLOBAL_USER_CONFIG | + CLASS_PROJECT_USER_CONFIG, + CLASS_SCRIPT_INHERIT = CLASS_INHERIT | + CLASS_EDIT_INLINE_NEW | + CLASS_COLLAPSE_CATEGORIES, +}; + typedef enum { EX_LOCAL_VARIABLE = 0x00, EX_INSTANCE_VARIABLE = 0x01, @@ -2040,7 +2094,7 @@ struct ufunc_s { void *unresolved_script_props; void *unversioned_schema; /* ufunc_t */ - uint32_t func_flags; + efunc_flags_t func_flags; uint8_t num_params; uint16_t params_size; uint16_t return_val_offset; @@ -2098,6 +2152,15 @@ STATIC_ASSERT(offsetof(fobject_initializer_t, component_inits) STATIC_ASSERT(offsetof(fobject_initializer_t, last_constructed_object) == 0x140, "invalid offset"); STATIC_ASSERT(sizeof(fobject_initializer_t) == 0x148, "size mismatch"); + + +typedef struct fclass_func_link_info_s fclass_func_link_info_t; +struct fclass_func_link_info_s { + ufunc_t *(*create_func_ptr)(); + const char *func_name; +}; + + typedef struct uclass_s *(__fastcall *uclass_get_authoritative_class_fn_t) (struct uclass_s *); typedef void (__fastcall *uclass_post_init_instance_fn_t) (struct uclass_s *, struct uobject_s *); typedef void (__fastcall *uclass_init_props_from_custom_list_fn_t) (struct uclass_s *, uint8_t *, const uint8_t *); @@ -2262,6 +2325,17 @@ typedef TARRAY(struct ufield_s *) tarray_ufieldptr_t; typedef TARRAY(fnative_func_lookup_t) tarray_fnative_func_lookup_t; typedef TMAP(fname_t, struct ufunc_s *) tmap_fname_ufuncptr_t; +typedef struct fimplemented_interface_s fimplemented_interface_t; +struct fimplemented_interface_s { + struct uclass_s *cls; + int32_t pointer_offset; + bool implemented_by_k2; + uint8_t _pad0[3]; +}; +STATIC_ASSERT(sizeof(fimplemented_interface_t) == 0x10, "size mismatch"); + +typedef TARRAY(fimplemented_interface_t) tarray_fimplemented_interface_t; + typedef struct uclass_s uclass_t; struct uclass_s { /* uobject_t */ @@ -2293,7 +2367,7 @@ struct uclass_s { uclass_class_vtable_helper_ctor_caller_fn_t class_vtable_helper_ctor_caller; uclass_class_add_referenced_objects_fn_t class_add_referenced_objects; uint32_t class_unique_and_cooked; - uint32_t class_flags; + eclass_flags_t class_flags; uint64_t class_cast_flags; struct uclass_s *class_within; uobject_t *class_generated_by; @@ -2307,7 +2381,7 @@ struct uclass_s { tmap_fname_ufuncptr_t func_map; tmap_fname_ufuncptr_t super_func_map; frwlock_t super_func_map_lock; - tarray_void_t interfaces; + tarray_fimplemented_interface_t interfaces; fgc_ref_token_stream_t ref_token_stream; fcritical_section_t ref_token_stream_critical; tarray_fnative_func_lookup_t native_func_lookup_table; @@ -2532,6 +2606,8 @@ typedef uint8_t elog_verbosity_type_t; #define ELVT_SET_COLOR 0x40 #define ELVT_BREAK_ON_LOG 0x80 +typedef void (*unreal_console_output_fn_t)(void *user, str_t text, elog_verbosity_type_t verbosity); + struct foutput_device_s; typedef void (__fastcall *foutput_device_destructor_fn_t) (struct foutput_device_s *); @@ -2565,6 +2641,23 @@ struct foutput_device_s { uint8_t auto_emit_line_terminator; }; +struct uworld_s; +struct fexec_s; + +typedef void (__fastcall *fexec_destructor_fn_t)(struct fexec_s *self); +typedef bool (__fastcall *fexec_exec_fn_t) (struct fexec_s *self, struct uworld_s *world, const wchar_t *command, foutput_device_t *output); + +typedef struct fexec_vtable_s fexec_vtable_t; +struct fexec_vtable_s { + fexec_destructor_fn_t destructor; + fexec_exec_fn_t exec; +}; + +typedef struct fexec_s fexec_t; +struct fexec_s { + fexec_vtable_t *vtable; +}; + typedef struct fout_parm_rec_s fout_parm_rec_t; struct fout_parm_rec_s { fprop_t *prop; @@ -2882,6 +2975,9 @@ struct execute_console_cmd_params_s { fstring_t cmd; void *specific_player; // APlayerController * }; +STATIC_ASSERT(offsetof(execute_console_cmd_params_t, cmd) == 8, "invalid offset"); +STATIC_ASSERT(offsetof(execute_console_cmd_params_t, specific_player) == 24, "invalid offset"); +STATIC_ASSERT(sizeof(execute_console_cmd_params_t) == 32, "size mismatch"); typedef tmulticast_delegate_t fon_gameplay_tag_loaded_t; typedef uint16_t fgameplay_tag_net_idx_t; @@ -3030,6 +3126,9 @@ STATIC_ASSERT(offsetof(ugameplay_tags_manager_t, network_idx_invalidated) STATIC_ASSERT(offsetof(ugameplay_tags_manager_t, gameplay_tag_tables) == 0x230, "invalid offset"); STATIC_ASSERT(sizeof(ugameplay_tags_manager_t) == 0x240, "size mismatch"); +MOD_API bool +unreal_is_in_game_thread(void); + /* ===================================================== FNAME ====================================================== */ MOD_API fname_pool_t * @@ -3114,7 +3213,9 @@ struct unreal_common_s { ufunc_t *finish_spawn; // Function /Script/Engine.GameplayStatics.FinishSpawningActor ufunc_t *destroy_actor; // Function /Script/Engine.Actor.K2_DestroyActor uclass_t *kismet_sys_lib_cls; + uobject_t *kismet_sys_lib_cdo; ufunc_t *exec_console_cmd; + uobject_t *transient_package; // Package /Engine/Transient // fnames fname_t bool_prop; @@ -3221,6 +3322,10 @@ unreal_uobject_is_a(uobject_t *obj, uclass_t *cls); MOD_API bool unreal_uclass_is_child_of(uclass_t *child, uclass_t *parent); MOD_API bool +unreal_uclass_implements_interface(uclass_t *cls, uclass_t *interface_cls); +MOD_API void * +unreal_uobject_get_interface_address(uobject_t *obj, uclass_t *interface_cls); +MOD_API bool unreal_uobject_is_default(uobject_t *obj); MOD_API bool unreal_uobject_is_valid(uobject_t *obj); @@ -3243,6 +3348,8 @@ MOD_API uint64_t unreal_uobject_write_full_name(uobject_t *obj, uint8_t *dst, uint64_t cap); MOD_API str_t unreal_uobject_push_full_name(uobject_t *obj, arena_t *perm); +MOD_API str_t +unreal_uobject_push_ue_path_name(uobject_t *obj, arena_t *perm); MOD_API int unreal_uobject_array_count(void); @@ -3272,12 +3379,26 @@ MOD_API uclass_t * unreal_uobject_find_class_by_full_name(str_t full_name); MOD_API uobject_t * unreal_uobject_find_by_full_name(uclass_t *cls, str_t full_name); +/* finds an already-loaded object by the same path syntax produced by unreal_uobject_push_ue_path_name, including ':' for subobjects */ +MOD_API uobject_t * +unreal_uobject_find_by_path_name(uclass_t *cls, str_t path_name); + +MOD_API uint32_t +unreal_uobject_get_internal_flags(uobject_t *obj); +MOD_API bool +unreal_uobject_is_rooted(uobject_t *obj); +MOD_API bool +unreal_uobject_add_to_root(uobject_t *obj); +MOD_API bool +unreal_uobject_remove_from_root(uobject_t *obj); MOD_API void unreal_process_event(uobject_t *self, ufunc_t *func, void *params); /* Calls the virtual ProcessEvent entry so normal Overdub hooks/listeners observe the call. */ MOD_API void unreal_process_event_observed(uobject_t *self, ufunc_t *func, void *params); +MOD_API bool +unreal_execute_console_command(str_t command, unreal_console_output_fn_t output, void *user); MOD_API uobject_t * unreal_spawn_actor(uobject_t *world_ctx_obj, uclass_t *cls); @@ -3286,6 +3407,10 @@ unreal_despawn_actor(uobject_t *actor); MOD_API uobject_t * unreal_static_construct_object(fstatic_construct_obj_params_t *params); +MOD_API uobject_t * +unreal_get_transient_package(void); +MOD_API uobject_t * +unreal_construct_object(uclass_t *cls, uobject_t *outer); MOD_API uobject_t * unreal_static_load_object(uclass_t *obj_cls, uobject_t *outer, str_t name, str_t filename, uint32_t load_flags, void *sandbox, bool allow_obj_reconcile, void *instancing_ctx); diff --git a/include/unreal_funcs.inc b/include/unreal_funcs.inc index 04df2d1..3cef33d 100644 --- a/include/unreal_funcs.inc +++ b/include/unreal_funcs.inc @@ -27,6 +27,11 @@ UE_FUNC_NORMAL(generic_array_remove, void, void *target, fprop_array_t *prop, UE_FUNC_NORMAL(generic_array_set, void, void *target, fprop_array_t *prop, int32_t idx, const void *new_item, bool size_to_fit); UE_FUNC_NORMAL(fscript_set_add_elem, void, fscript_set_helper_t *helper, const void *item_ptr); UE_FUNC_NORMAL(generic_set_remove, bool, void *target, fprop_set_t *prop, const void *item_ptr); +UE_FUNC_NORMAL(ustruct_static_link, void, ustruct_t *self, bool relink_existing_props); +UE_FUNC_NORMAL(uclass_create_link_and_add_child_funcs_to_map, void, uclass_t *self, fclass_func_link_info_t *funcs, uint32_t num_funcs); +UE_FUNC_NORMAL(uclass_assemble_ref_tok_stream, void, uclass_t *self, bool force); +UE_FUNC_NORMAL(uclass_add_native_func, void, uclass_t *self, const wchar_t *name, fnative_func_ptr_fn_t ptr); +UE_FUNC_NORMAL(ffield_construct, ffield_t *, fname_t *type_name, ffield_variant_t *owner, fname_t *name, eobj_flags_t flags); #undef UE_FUNC_NORMAL @@ -40,6 +45,7 @@ UE_FUNC_HOOKED(io_dispatcher_mount, fio_status_t *, void *self, fio_status_t *st UE_FUNC_HOOKED(game_engine_tick, void, void *self, float delta, bool idle_mode); UE_FUNC_HOOKED(process_event, void, uobject_t *self, ufunc_t *func, void *params) UE_FUNC_HOOKED(ufunction_invoke, void, ufunc_t *func, uobject_t *obj, fframe_t *stack, void *result); +UE_FUNC_HOOKED(conditional_post_load, void, uobject_t *self); UE_FUNC_HOOKED(process_mouse_move_event, bool, void *self, fpointer_event_t mouse_event, bool is_synthetic); UE_FUNC_HOOKED(process_mouse_button_down_event, bool, void *self, void *platform_win, fpointer_event_t mouse_event); UE_FUNC_HOOKED(process_mouse_button_up_event, bool, void *self, fpointer_event_t mouse_event); diff --git a/include/unreal_prop.h b/include/unreal_prop.h index 83eb7e6..05bd09a 100644 --- a/include/unreal_prop.h +++ b/include/unreal_prop.h @@ -40,17 +40,54 @@ typedef enum unreal_prop_kind_e { UNREAL_PROP_KIND_MULTICAST_SPARSE_DELEGATE, } unreal_prop_kind_t; +typedef uint8_t unreal_func_param_role_t; +enum { + UNREAL_FUNC_PARAM_INPUT = 0, + UNREAL_FUNC_PARAM_OUTPUT, + UNREAL_FUNC_PARAM_RETURN, +}; + typedef struct unreal_prop_integer_s unreal_prop_integer_t; struct unreal_prop_integer_s { - uint64_t value; // cast value to int64_t when is_signed is true + uint64_t value; bool is_signed; }; +typedef struct unreal_prop_snapshot_s unreal_prop_snapshot_t; +struct unreal_prop_snapshot_s { + unreal_prop_snapshot_t *next; + unreal_prop_snapshot_t *first_child; + unreal_prop_snapshot_t *last_child; + + str_t name; + str_t type; + str_t value; + str_t tooltip; + eprop_flags_t prop_flags; + bool expanded; + bool truncated; +}; + +typedef struct unreal_prop_snapshot_builder_s unreal_prop_snapshot_builder_t; +struct unreal_prop_snapshot_builder_s { + arena_t *arena; + + uint32_t max_depth; + uint32_t max_container_elements; + uint32_t max_nodes; + uint32_t max_text_length; + + uint32_t node_count; + bool truncated; +}; + MOD_API fprop_t * unreal_ustruct_find_prop(ustruct_t *s, str_t name); MOD_API unreal_prop_kind_t unreal_fprop_get_kind(fprop_t *prop); +MOD_API unreal_func_param_role_t +unreal_fprop_get_param_role(fprop_t *prop); MOD_API bool unreal_fprop_struct_is(fprop_t *prop, fname_t struct_name); MOD_API bool @@ -68,6 +105,10 @@ MOD_API bool unreal_fprop_read_real(fprop_t *prop, const void *value, double *out); MOD_API bool unreal_fprop_read_name(fprop_t *prop, const void *value, fname_t *out); +MOD_API bool +unreal_fprop_read_string(fprop_t *prop, const void *value, arena_t *arena, str_t *out); +MOD_API bool +unreal_fprop_read_soft_path(fprop_t *prop, const void *value, arena_t *arena, str_t *out); MOD_API bool unreal_fprop_write_bool(fprop_t *prop, void *value, bool input); @@ -82,19 +123,44 @@ MOD_API uobject_t * unreal_fprop_get_object(fprop_obj_base_t *prop, const void *value); MOD_API uobject_t * unreal_fprop_get_referenced_object(fprop_t *prop, const void *value); +MOD_API uclass_t * +unreal_fprop_get_reference_class(fprop_t *prop); MOD_API bool unreal_fprop_object_is_compatible(fprop_obj_base_t *prop, uobject_t *object); MOD_API bool unreal_fprop_set_object(fprop_obj_base_t *prop, void *value, uobject_t *object); +MOD_API bool +unreal_fprop_interface_is_compatible(fprop_iface_t *prop, uobject_t *object); +MOD_API bool +unreal_fprop_set_interface(fprop_iface_t *prop, void *value, uobject_t *object); MOD_API uobject_t * unreal_fweak_object_resolve(fweak_object_ptr_t weak); +MOD_API bool +unreal_fweak_object_from_object(uobject_t *object, fweak_object_ptr_t *out); +MOD_API bool +unreal_ufunction_signature_compatible(ufunc_t *signature, ufunc_t *function); +MOD_API ufunc_t * +unreal_fprop_delegate_signature(fprop_t *prop); +MOD_API bool +unreal_fscript_delegate_make(fscript_delegate_t *out, uobject_t *target, ufunc_t *function); +MOD_API bool +unreal_fprop_delegate_contains(uobject_t *owner, fprop_t *prop, const fscript_delegate_t *binding); +MOD_API bool +unreal_fprop_delegate_bind(uobject_t *owner, fprop_t *prop, const fscript_delegate_t *binding); +MOD_API bool +unreal_fprop_delegate_unbind(uobject_t *owner, fprop_t *prop, const fscript_delegate_t *binding); MOD_API str_t unreal_fscript_delegate_push_summary(const fscript_delegate_t *delegate, arena_t *arena); /* NOTE: value_size is the readable size of one property element, not its complete fixed-array size */ MOD_API str_t unreal_fprop_push_value_summary(fprop_t *prop, const void *value, int32_t value_size, arena_t *arena); +MOD_API void +unreal_prop_snapshot_builder_init(unreal_prop_snapshot_builder_t *builder, arena_t *arena); +MOD_API unreal_prop_snapshot_t * +unreal_fprop_snapshot_build(unreal_prop_snapshot_builder_t *builder, fprop_t *prop, str_t name, const void *value); + static inline void * unreal_uprop_ptr(fprop_t *prop, void *container) { diff --git a/include/unreal_reflect.h b/include/unreal_reflect.h new file mode 100644 index 0000000..1ec0eb3 --- /dev/null +++ b/include/unreal_reflect.h @@ -0,0 +1,145 @@ +#ifndef UNREAL_REFLECT_H +#define UNREAL_REFLECT_H + +#include "unreal_prop.h" + +MOD_EXTERN_C_BEGIN + +typedef struct unreal_class_def_s unreal_class_def_t; +typedef struct unreal_func_call_s unreal_func_call_t; +typedef struct unreal_func_def_s unreal_func_def_t; +typedef struct unreal_prop_array_default_s unreal_prop_array_default_t; +typedef struct unreal_prop_map_default_s unreal_prop_map_default_t; +typedef struct unreal_prop_def_s unreal_prop_def_t; +typedef struct unreal_prop_type_s unreal_prop_type_t; +typedef uint64_t unreal_reflect_owner_t; + +#define UNREAL_REFLECT_OWNER_PERSISTENT ((unreal_reflect_owner_t)0) + +typedef void (MOD_CALL *unreal_func_impl_fn_t)(unreal_func_call_t *call); + +/* NOTE: 'kind' comes from the property codec */ +struct unreal_prop_type_s { + unreal_prop_kind_t type; + uclass_t *cls; + uscript_struct_t *struct_type; + uenum_t *enum_type; + const unreal_prop_type_t *inner; + const unreal_prop_type_t *value; +}; + +struct unreal_prop_array_default_s { + const void *items; + uint32_t count; +}; + +struct unreal_prop_map_default_s { + const void *keys; + const void *values; + uint32_t count; +}; + +struct unreal_prop_def_s { + str_t name; + unreal_prop_kind_t type; + eprop_flags_t flags; + uclass_t *cls; + uscript_struct_t *struct_type; + uenum_t *enum_type; + unreal_prop_type_t inner; + unreal_prop_type_t value; + + union { + struct { + bool default_val; + } boolean; + + struct { + int64_t default_val; + } integer; + + struct { + uint64_t default_val; + } unsigned_integer; + + struct { + double default_val; + } real; + + struct { + uobject_t *default_val; + } object; + + struct { + str_t default_val; + } fname; + + struct { + str_t default_val; + } string; + + struct { + str_t default_val; + } soft; + + struct { + str_t default_val; + } structure; + + struct { + int64_t default_val; + } enumeration; + + struct { + unreal_prop_array_default_t default_val; + } array; + + struct { + unreal_prop_array_default_t default_val; + } set; + + struct { + unreal_prop_map_default_t default_val; + } map; + }; +}; + +struct unreal_func_call_s { + uobject_t *object; + ufunc_t *function; + void *params; + void *return_value; + void *user; +}; + +struct unreal_func_def_s { + str_t name; + efunc_flags_t flags; + const unreal_prop_def_t *params; + uint32_t num_params; + unreal_prop_type_t ret; + unreal_func_impl_fn_t impl; + void *user; +}; + +struct unreal_class_def_s { + uint32_t struct_size; + uclass_t *parent; + const unreal_prop_def_t *props; + uint32_t num_props; + const unreal_func_def_t *funcs; + uint32_t num_funcs; +}; + +uclass_t * +unreal_reflect_define_class(str_t scope, str_t name, const unreal_class_def_t *def); + +uclass_t * +unreal_reflect_define_class_owned(unreal_reflect_owner_t owner, str_t scope, str_t name, const unreal_class_def_t *def); + +void +unreal_reflect_disable_owner(unreal_reflect_owner_t owner); + +MOD_EXTERN_C_END + +#endif /* UNREAL_REFLECT_H */ diff --git a/mod/README.md b/mod/README.md index f9de829..5e5ecc4 100644 --- a/mod/README.md +++ b/mod/README.md @@ -1,8 +1,6 @@ -# Overdub Mod Template +# Overdub Native Mod Template -This directory contains a minimal native Overdub mod and its matching SDK. -`include/`, `vendor/`, and `build/overdub.lib` are contained in this project, -so no Overdub source checkout or `OverdubDir` setting is required. +This directory is a small native mod project. A release template already contains the matching SDK headers, Nuklear headers, and `build/overdub.lib`. Keep those files from the same Overdub release. Build with Visual Studio 2022: @@ -10,14 +8,24 @@ Build with Visual Studio 2022: msbuild mod.vcxproj /m /p:Configuration=Release /p:Platform=x64 /p:ModName=example ``` -Or build from an MSYS2 MinGW64 shell: +Or use the Makefile from an MSYS2 MinGW64 shell or Linux with MinGW-w64: ```sh make CONFIG=release MOD_NAME=example ``` -The DLL is written below `build/`. Copy the DLL into the native mod package -described by `docs/MOD_DEVELOPMENT.md`. +The DLL is written below `build`. Copy it into a mod directory with this manifest: -Keep the headers and `overdub.lib` from the same Overdub release. The mod DLL -imports its SDK functions from `overdub.dll`; it does not contain a static SDK. +```ini +[info] +id = author.example +name = Example Mod +author = Author Name +version = 1.0.0 +kind = mod + +[code] +path = example.dll +``` + +The source template is in `main.c`. In a released template, the full guide starts at `docs/MOD_DEVELOPMENT.md`. In the source checkout, it is at `../docs/MOD_DEVELOPMENT.md`. diff --git a/mod/mod.vcxproj.user b/mod/mod.vcxproj.user index 88a5509..824d5a9 100644 --- a/mod/mod.vcxproj.user +++ b/mod/mod.vcxproj.user @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/overdub.sln b/overdub.sln index 555a1c7..3febc18 100644 --- a/overdub.sln +++ b/overdub.sln @@ -8,15 +8,12 @@ Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 Release|x64 = Release|x64 - TestUI|x64 = TestUI|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {0A7A9C9D-6E36-4A0B-9D1A-7F5A6D8E2C41}.Debug|x64.ActiveCfg = Debug|x64 {0A7A9C9D-6E36-4A0B-9D1A-7F5A6D8E2C41}.Debug|x64.Build.0 = Debug|x64 {0A7A9C9D-6E36-4A0B-9D1A-7F5A6D8E2C41}.Release|x64.ActiveCfg = Release|x64 {0A7A9C9D-6E36-4A0B-9D1A-7F5A6D8E2C41}.Release|x64.Build.0 = Release|x64 - {0A7A9C9D-6E36-4A0B-9D1A-7F5A6D8E2C41}.TestUI|x64.ActiveCfg = TestUI|x64 - {0A7A9C9D-6E36-4A0B-9D1A-7F5A6D8E2C41}.TestUI|x64.Build.0 = TestUI|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/overdub.vcxproj b/overdub.vcxproj index 9246cfc..6b2f2b4 100644 --- a/overdub.vcxproj +++ b/overdub.vcxproj @@ -8,10 +8,6 @@ Release x64 - - TestUI - x64 - 17.0 @@ -34,12 +30,6 @@ MultiByte true - - Application - true - v143 - MultiByte - @@ -49,16 +39,11 @@ - - - build\ build\obj\$(Configuration)\ - overdub - overdub - overdub_test_ui + overdub stdc11 @@ -107,210 +92,13 @@ user32.lib;kernel32.lib;advapi32.lib;shlwapi.lib;d3d12.lib;d3d11.lib;dxgi.lib;dxguid.lib;uuid.lib;dbghelp.lib;%(AdditionalDependencies) - - - CompileAsC - Level3 - false - Disabled - false - false - WIN32_LEAN_AND_MEAN;COBJMACROS;BUILD_TEST_UI;OVERDUB_STATIC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - .;include;vendor;%(AdditionalIncludeDirectories) - ProgramDatabase - /utf-8 %(AdditionalOptions) - - - Console - true - user32.lib;kernel32.lib;advapi32.lib;shlwapi.lib;d3d11.lib;dxguid.lib;uuid.lib;dbghelp.lib;%(AdditionalDependencies) - - - - false - - - false - - - false - false - false - - - false - - - false - - - false - - - false - - - false - - - false - - - true - - - false - - - false - - - false - - - false - - - false - - - true - - - false - - - false - - - false - - - true - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - false - - - true - true - false - - - true - true - false - - - true - true - false - - - true - true - false - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/overdub.vcxproj.user b/overdub.vcxproj.user index 88a5509..824d5a9 100644 --- a/overdub.vcxproj.user +++ b/overdub.vcxproj.user @@ -1,4 +1,4 @@ - + \ No newline at end of file diff --git a/src/builtin/details_panel.c b/src/builtin/details_panel.c index 9b3b599..140fe1e 100644 --- a/src/builtin/details_panel.c +++ b/src/builtin/details_panel.c @@ -12,15 +12,13 @@ #include "vendor_stb.h" -#define DETAIL_MAX_CONTAINER_ELEMS (128) - #define DETAIL_C_ROW_COLLAPSIBLE_BG nk_rgba(34, 43, 48, 210) #define DETAIL_C_ROW_COLLAPSIBLE_HOVER nk_rgba(95, 178, 145, 255) #define DETAIL_C_ROW_COLLAPSIBLE_ACTIVE nk_rgba(50, 65, 72, 245) -#define DETAIL_C_PROP_TYPE_TEXT nk_rgba(218, 156, 62, 255) -#define DETAIL_C_PROP_VALUE_TEXT nk_rgba(139, 191, 166, 255) -#define DETAIL_C_PROP_LINK_VALUE_TEXT nk_rgba(122, 184, 232, 255) +#define DETAIL_C_PROP_TYPE_TEXT UI_C_PROP_TYPE_TEXT +#define DETAIL_C_PROP_VALUE_TEXT UI_C_PROP_VALUE_TEXT +#define DETAIL_C_PROP_LINK_VALUE_TEXT UI_C_PROP_LINK_TEXT #define DETAIL_C_PROP_NAME_TEXT UI_C_TEXT #define DETAIL_C_PROP_OFFSET_TEXT UI_C_TEXT #define DETAIL_C_PROP_SIZE_TEXT UI_C_TEXT @@ -694,6 +692,9 @@ detail_tab_build(search_tool_t *tool, detail_tab_t *tab) } if (tab->record->kind == UOBJECT_KIND_PACKAGE) { + uint64_t state_size = ((uint64_t)tool->cache.record_cap + 7) / 8; + tab->package_expanded = ARENA_PUSH_ARRAY_ZERO(tab->info_arena, uint8_t, state_size); + ASSERT(tab->package_expanded != NULL); return; } @@ -1095,11 +1096,7 @@ tarray_children_match(detail_prop_t *node, int32_t num) return false; } - int32_t count = MIN_VAL(num, DETAIL_MAX_CONTAINER_ELEMS); - - return node->children_kind == DETAIL_PROP_CHILDREN_ARRAY_ELEMS && - node->live_child_count == num && - node->live_slot_count == count; + return node->children_kind == DETAIL_PROP_CHILDREN_ARRAY_ELEMS && node->live_child_count == num && node->live_slot_count == num; } static bool @@ -1110,9 +1107,8 @@ tset_children_match(detail_prop_t *node, const void *set, fprop_set_t *prop, int return false; } - detail_prop_t *child = node->first_child; - int32_t emitted = 0; - for (int32_t idx = 0; idx < slot_count && emitted < DETAIL_MAX_CONTAINER_ELEMS; ++idx) { + detail_prop_t *child = node->first_child; + for (int32_t idx = 0; idx < slot_count; ++idx) { if (!unreal_set_is_valid_index(set, prop, idx)) { continue; } @@ -1121,9 +1117,9 @@ tset_children_match(detail_prop_t *node, const void *set, fprop_set_t *prop, int return false; } - child = child->next; - emitted += 1; + child = child->next; } + return child == NULL; } @@ -1135,9 +1131,8 @@ tmap_children_match(detail_prop_t *node, const void *map, fprop_map_t *prop, int return false; } - detail_prop_t *child = node->first_child; - int32_t emitted = 0; - for (int32_t idx = 0; idx < slot_count && emitted < DETAIL_MAX_CONTAINER_ELEMS; ++idx) { + detail_prop_t *child = node->first_child; + for (int32_t idx = 0; idx < slot_count; ++idx) { if (!unreal_map_is_valid_index(map, prop, idx)) { continue; } @@ -1146,9 +1141,9 @@ tmap_children_match(detail_prop_t *node, const void *map, fprop_map_t *prop, int return false; } - child = child->next; - emitted += 1; + child = child->next; } + return child == NULL; } @@ -1159,11 +1154,7 @@ mcast_delegate_children_match(detail_prop_t *node, int32_t num) return false; } - int32_t count = MIN_VAL(num, DETAIL_MAX_CONTAINER_ELEMS); - - return node->children_kind == DETAIL_PROP_CHILDREN_MCAST_DELEGATE && - node->live_child_count == num && - node->live_slot_count == count; + return node->children_kind == DETAIL_PROP_CHILDREN_MCAST_DELEGATE && node->live_child_count == num && node->live_slot_count == num; } static void @@ -1177,13 +1168,11 @@ tarray_rebuild_children(search_tool_t *tool, detail_tab_t *tab, detail_prop_t *n detail_prop_clear_runtime_children(tab, node); - int count = MIN_VAL(num, DETAIL_MAX_CONTAINER_ELEMS); - node->children_kind = DETAIL_PROP_CHILDREN_ARRAY_ELEMS; node->live_child_count = num; - node->live_slot_count = count; + node->live_slot_count = num; - if (count <= 0) { + if (num <= 0) { return; } @@ -1192,7 +1181,7 @@ tarray_rebuild_children(search_tool_t *tool, detail_tab_t *tab, detail_prop_t *n int32_t elem_size = inner->elem_size; ASSERT(elem_size > 0); - for (int i = 0; i < count; ++i) { + for (int32_t i = 0; i < num; ++i) { int32_t elem_offset = i * elem_size; uint8_t *elem_addr = (uint8_t *)unreal_array_get(array, array_prop, i); @@ -1221,16 +1210,11 @@ tset_rebuild_children( int32_t slot_size = set_prop->set_layout.sparse_array_layout.size; ASSERT(slot_size > 0); - int32_t emitted = 0; for (int32_t i = 0; i < slot_count; ++i) { if (!unreal_set_is_valid_index(set, set_prop, i)) { continue; } - if (emitted >= DETAIL_MAX_CONTAINER_ELEMS) { - break; - } - int32_t elem_offset = i * slot_size; uint8_t *elem_addr = (uint8_t *)unreal_set_get(set, set_prop, i); @@ -1238,7 +1222,6 @@ tset_rebuild_children( if (elem) { elem->live_slot_idx = i; QUEUE_PUSH(node->first_child, node->last_child, elem); - emitted += 1; } } } @@ -1259,16 +1242,11 @@ tmap_rebuild_children( int32_t slot_size = map_prop->map_layout.set_layout.sparse_array_layout.size; ASSERT(slot_size > 0); - int32_t emitted = 0; for (int32_t i = 0; i < slot_count; ++i) { if (!unreal_map_is_valid_index(map, map_prop, i)) { continue; } - if (emitted >= DETAIL_MAX_CONTAINER_ELEMS) { - break; - } - int32_t pair_offset = i * slot_size; uint8_t *key_addr = (uint8_t *)unreal_map_get_key(map, map_prop, i); uint8_t *val_addr = (uint8_t *)unreal_map_get_value(map, map_prop, i); @@ -1277,7 +1255,6 @@ tmap_rebuild_children( if (pair) { pair->live_slot_idx = i; QUEUE_PUSH(node->first_child, node->last_child, pair); - emitted += 1; } } } @@ -1292,13 +1269,11 @@ mcast_delegate_rebuild_children(search_tool_t *tool, detail_tab_t *tab, detail_p detail_prop_clear_runtime_children(tab, node); - int32_t count = MIN_VAL(list->num, DETAIL_MAX_CONTAINER_ELEMS); - node->children_kind = DETAIL_PROP_CHILDREN_MCAST_DELEGATE; node->live_child_count = list->num; - node->live_slot_count = count; + node->live_slot_count = list->num; - for (int32_t i = 0; i < count; ++i) { + for (int32_t i = 0; i < list->num; ++i) { detail_prop_t *elem = detail_prop_alloc_runtime(tab); if (!elem) { break; @@ -1449,14 +1424,16 @@ detail_prop_fill_value_tarray_children(search_tool_t *tool, detail_tab_t *tab, d return; } - if (!tarray_children_match(node, num)) { - tarray_rebuild_children(tool, tab, node, array_prop, array, num, depth); - } - if (!node->maximized && !tab->force_expand_values) { + node->children_kind = DETAIL_PROP_CHILDREN_ARRAY_ELEMS; + node->live_child_count = num; return; } + if (!tarray_children_match(node, num)) { + tarray_rebuild_children(tool, tab, node, array_prop, array, num, depth); + } + int elem_size = array_prop->inner->elem_size; ASSERT(elem_size > 0); @@ -1466,7 +1443,7 @@ detail_prop_fill_value_tarray_children(search_tool_t *tool, detail_tab_t *tab, d continue; } - if (elem_idx >= num || elem_idx >= DETAIL_MAX_CONTAINER_ELEMS) { + if (elem_idx >= num) { break; } @@ -1531,14 +1508,16 @@ detail_prop_fill_value_tset_children(search_tool_t *tool, detail_tab_t *tab, det return; } - if (!tset_children_match(node, set, set_prop, live_count, slot_count)) { - tset_rebuild_children(tool, tab, node, set_prop, set, live_count, slot_count, depth); - } - if (!node->maximized && !tab->force_expand_values) { + node->children_kind = DETAIL_PROP_CHILDREN_SET_ELEMS; + node->live_child_count = live_count; return; } + if (!tset_children_match(node, set, set_prop, live_count, slot_count)) { + tset_rebuild_children(tool, tab, node, set_prop, set, live_count, slot_count, depth); + } + int elem_size = set_prop->elem_prop->elem_size; int slot_size = set_prop->set_layout.sparse_array_layout.size; ASSERT(elem_size > 0); @@ -1610,14 +1589,16 @@ detail_prop_fill_value_tmap_children(search_tool_t *tool, detail_tab_t *tab, det return; } - if (!tmap_children_match(node, map, map_prop, live_count, slot_count)) { - tmap_rebuild_children(tool, tab, node, map_prop, map, live_count, slot_count, depth); - } - if (!node->maximized && !tab->force_expand_values) { + node->children_kind = DETAIL_PROP_CHILDREN_MAP_PAIRS; + node->live_child_count = live_count; return; } + if (!tmap_children_match(node, map, map_prop, live_count, slot_count)) { + tmap_rebuild_children(tool, tab, node, map_prop, map, live_count, slot_count, depth); + } + int pair_size = map_prop->map_layout.set_layout.size; int slot_size = map_prop->map_layout.set_layout.sparse_array_layout.size; ASSERT(pair_size > 0); @@ -1718,18 +1699,20 @@ detail_prop_fill_value_mcast_delegate_children(search_tool_t *tool, detail_tab_t return; } - if (!mcast_delegate_children_match(node, num)) { - mcast_delegate_rebuild_children(tool, tab, node, list, depth); - } - if (!node->maximized && !tab->force_expand_values) { + node->children_kind = DETAIL_PROP_CHILDREN_MCAST_DELEGATE; + node->live_child_count = num; return; } + if (!mcast_delegate_children_match(node, num)) { + mcast_delegate_rebuild_children(tool, tab, node, list, depth); + } + for (detail_prop_t *elem = node->first_child; elem; elem = elem->next) { int32_t idx = elem->live_slot_idx; - if (idx < 0 || idx >= num || idx >= DETAIL_MAX_CONTAINER_ELEMS) { + if (idx < 0 || idx >= num) { continue; } @@ -1795,18 +1778,20 @@ detail_prop_fill_value_sparse_mcast_delegate_children(search_tool_t *tool, detai node->summary = ui_text_span_make(tool->ctx, str_push_fmt(arena, "Num=%d Max=%d Data=%p", num, max, list->data)); - if (!mcast_delegate_children_match(node, num)) { - mcast_delegate_rebuild_children(tool, tab, node, list, depth); - } - if (!node->maximized && !tab->force_expand_values) { + node->children_kind = DETAIL_PROP_CHILDREN_MCAST_DELEGATE; + node->live_child_count = num; return; } + if (!mcast_delegate_children_match(node, num)) { + mcast_delegate_rebuild_children(tool, tab, node, list, depth); + } + for (detail_prop_t *elem = node->first_child; elem; elem = elem->next) { int32_t idx = elem->live_slot_idx; - if (idx < 0 || idx >= num || idx >= DETAIL_MAX_CONTAINER_ELEMS) { + if (idx < 0 || idx >= num) { continue; } @@ -1940,6 +1925,15 @@ details_refresh_values(search_tool_t *tool, detail_tab_t *tab) details_fill_owner_values(tool, tab); } +static void +details_refresh_all_values(search_tool_t *tool, detail_tab_t *tab) +{ + bool old_force_expand = tab->force_expand_values; + tab->force_expand_values = true; + details_refresh_values(tool, tab); + tab->force_expand_values = old_force_expand; +} + static void detail_dump_push_line(arena_t *arena, str_list_t *lines, int depth, str_t text) { @@ -2035,10 +2029,7 @@ detail_props_push_dump(search_tool_t *tool, detail_tab_t *tab, arena_t *arena) ASSERT(tab != NULL); ASSERT(arena != NULL); - bool old_force_expand = tab->force_expand_values; - tab->force_expand_values = true; - details_refresh_values(tool, tab); - tab->force_expand_values = old_force_expand; + details_refresh_all_values(tool, tab); str_list_t lines = {0}; @@ -2648,6 +2639,147 @@ ui_detail_row(search_tool_t *tool, struct nk_grid_state *grid_state, ui_detail_r return expanded; } +typedef struct detail_tree_state_s { + bool has_children; + bool has_collapsed; +} detail_tree_state_t; + +static inline bool +detail_prop_has_children(detail_prop_t *prop) +{ + switch (prop->children_kind) { + case DETAIL_PROP_CHILDREN_ARRAY_ELEMS: + case DETAIL_PROP_CHILDREN_SET_ELEMS: + case DETAIL_PROP_CHILDREN_MAP_PAIRS: + case DETAIL_PROP_CHILDREN_MCAST_DELEGATE: { + return prop->live_child_count > 0; + } + + default: { + return prop->first_child != NULL; + } + } +} + +static void +detail_props_collect_tree_state(detail_prop_t *first, detail_tree_state_t *state) +{ + for (detail_prop_t *prop = first; prop; prop = prop->next) { + if (detail_prop_has_children(prop)) { + state->has_children = true; + + if (!prop->maximized) { + state->has_collapsed = true; + } + + detail_props_collect_tree_state(prop->first_child, state); + } + } +} + +static void +detail_props_set_expanded(detail_prop_t *first, bool expanded) +{ + for (detail_prop_t *prop = first; prop; prop = prop->next) { + prop->maximized = expanded && detail_prop_has_children(prop); + detail_props_set_expanded(prop->first_child, expanded); + } +} + +static detail_tree_state_t +detail_funcs_tree_state(detail_tab_t *tab) +{ + detail_tree_state_t state = {0}; + for (detail_owner_t *owner = tab->first_owner; owner; owner = owner->next) { + for (detail_func_t *func = owner->first_func; func; func = func->next) { + state.has_children = true; + + if (!func->maximized) { + state.has_collapsed = true; + } + detail_props_collect_tree_state(func->first_param, &state); + } + } + return state; +} + +static void +detail_funcs_set_expanded(detail_tab_t *tab, bool expanded) +{ + for (detail_owner_t *owner = tab->first_owner; owner; owner = owner->next) { + for (detail_func_t *func = owner->first_func; func; func = func->next) { + func->maximized = expanded; + detail_props_set_expanded(func->first_param, expanded); + } + } +} + +static bool +detail_tree_toggle_button(struct nk_context *ctx, detail_tree_state_t state) +{ + str_t label = STR_LIT("Expand"); + if (state.has_children && !state.has_collapsed) { + label = STR_LIT("Collapse"); + } + + if (!state.has_children) { + nk_widget_disable_begin(ctx); + } + + bool clicked = ui_button_str(ctx, label); + + if (!state.has_children) { + nk_widget_disable_end(ctx); + } + + return clicked; +} + +static inline bool +detail_package_is_expanded(search_tool_t *tool, detail_tab_t *tab, record_t *record) +{ + uint32_t slot = record_to_slot(tool, record); + return (tab->package_expanded[slot / 8] & (1u << (slot % 8))) != 0; +} + +static inline void +detail_package_set_expanded(search_tool_t *tool, detail_tab_t *tab, record_t *record, bool expanded) +{ + uint32_t slot = record_to_slot(tool, record); + uint8_t mask = (uint8_t)(1u << (slot % 8)); + + if (expanded) { + tab->package_expanded[slot / 8] |= mask; + } else { + tab->package_expanded[slot / 8] &= (uint8_t)~mask; + } +} + +static void +detail_package_collect_tree_state(search_tool_t *tool, detail_tab_t *tab, record_t *record, detail_tree_state_t *state) +{ + for (record_t *child = record_from_slot(tool, record->first_child_slot); child; child = record_from_slot(tool, child->next_sibling_slot)) { + if (record_slot_valid(child->first_child_slot)) { + state->has_children = true; + + if (!detail_package_is_expanded(tool, tab, child)) { + state->has_collapsed = true; + } + + detail_package_collect_tree_state(tool, tab, child, state); + } + } +} + +static void +detail_package_set_children_expanded(search_tool_t *tool, detail_tab_t *tab, record_t *record, bool expanded) +{ + for (record_t *child = record_from_slot(tool, record->first_child_slot); child; child = record_from_slot(tool, child->next_sibling_slot)) { + detail_package_set_expanded(tool, tab, child, expanded); + detail_package_set_children_expanded(tool, tab, child, expanded); + } +} + static void package_draw_children(search_tool_t *tool, detail_tab_t *tab, record_t *record, int depth) { @@ -2682,13 +2814,13 @@ package_draw_children(search_tool_t *tool, detail_tab_t *tab, record_t *record, .record_to_open = child_record, }; - bool maximized = record_has_flag(child_record, RECORD_FLAG_MAXIMIZED); + bool maximized = detail_package_is_expanded(tool, tab, child_record); if (ui_detail_row(tool, &tab->package_grid, row, &maximized)) { if (child_record->first_child_slot != RECORD_SLOT_INVALID) { package_draw_children(tool, tab, child_record, depth + 1); } } - record_set_flag(child_record, RECORD_FLAG_MAXIMIZED, maximized); + detail_package_set_expanded(tool, tab, child_record, maximized); } } @@ -2701,12 +2833,19 @@ draw_package_section(search_tool_t *tool, detail_tab_t *tab) tmp_arena_t tmp = scratch_begin(NULL); { if (ui_tree_push(tool->ctx, NK_TREE_TAB, STR_LIT("Package Content"), true)) { - nk_layout_row_dynamic(tool->ctx, 22.0f, 1); + nk_layout_row_dynamic(tool->ctx, 22.0f, 2); if (ui_button_str(tool->ctx, STR_LIT("Copy"))) { str_t dump = detail_push_package_dump(tmp.arena, tool, tab); detail_copy_text(tool->ctx, dump); } + detail_tree_state_t state = {0}; + detail_package_collect_tree_state(tool, tab, tab->record, &state); + + if (detail_tree_toggle_button(tool->ctx, state)) { + detail_package_set_children_expanded(tool, tab, tab->record, state.has_collapsed); + } + if (tab->record->first_child_slot != RECORD_SLOT_INVALID) { package_draw_children(tool, tab, tab->record, 0); } else { @@ -2805,7 +2944,7 @@ draw_detail_enum_section(search_tool_t *tool, detail_tab_t *tab) } static void -draw_detail_prop(search_tool_t *tool, struct nk_grid_state *grid_state, detail_prop_t *prop, int depth) +draw_detail_prop(search_tool_t *tool, detail_tab_t *tab, struct nk_grid_state *grid_state, detail_prop_t *prop, int depth) { ASSERT(tool != NULL); ASSERT(prop != NULL); @@ -2826,22 +2965,7 @@ draw_detail_prop(search_tool_t *tool, struct nk_grid_state *grid_state, detail_p UI_TEXT_CELL(prop->summary, summary_color), }; - bool has_children = false; - switch (prop->children_kind) { - case DETAIL_PROP_CHILDREN_ARRAY_ELEMS: - case DETAIL_PROP_CHILDREN_SET_ELEMS: - case DETAIL_PROP_CHILDREN_MAP_PAIRS: { - has_children = (prop->live_child_count > 0); - break; - } - - case DETAIL_PROP_CHILDREN_SCHEMA: - case DETAIL_PROP_CHILDREN_NONE: - default: { - has_children = (prop->first_child != NULL); - break; - } - } + bool has_children = detail_prop_has_children(prop); ui_detail_row_t row = { .parts = parts, @@ -2852,9 +2976,14 @@ draw_detail_prop(search_tool_t *tool, struct nk_grid_state *grid_state, detail_p .record_to_open = prop->record_to_open, }; - if (ui_detail_row(tool, grid_state, row, has_children ? &prop->maximized : NULL)) { + bool was_maximized = prop->maximized; + if (ui_detail_row(tool, grid_state, row, &prop->maximized)) { + if (!was_maximized && tab->value_base && prop->prop) { + detail_prop_fill_value_direct(tool, tab, prop, depth); + } + for (detail_prop_t *child = prop->first_child; child; child = child->next) { - draw_detail_prop(tool, grid_state, child, depth + 1); + draw_detail_prop(tool, tab, grid_state, child, depth + 1); } } } @@ -2920,12 +3049,15 @@ draw_detail_func_section(search_tool_t *tool, detail_tab_t *tab) ASSERT(tool != NULL); ASSERT(tab != NULL); - ASSERT(tab != NULL); - if (!tab->function) { return; } + nk_layout_row_dynamic(tool->ctx, 22.0f, 1); + if (ui_button_str(tool->ctx, STR_LIT("Call..."))) { + ufunc_call_open(tool, tab->function->record, NULL); + } + tmp_arena_t tmp = scratch_begin(NULL); { detail_func_t *f = tab->function; @@ -2946,8 +3078,11 @@ draw_detail_func_section(search_tool_t *tool, detail_tab_t *tab) detail_copy_text(tool->ctx, dump); } - if (ui_button_str(tool->ctx, STR_LIT("Call..."))) { - ufunc_call_open(tool, f->record, NULL); + detail_tree_state_t state = {0}; + detail_props_collect_tree_state(f->first_param, &state); + + if (detail_tree_toggle_button(tool->ctx, state)) { + detail_props_set_expanded(f->first_param, state.has_collapsed); } ui_text_cell_t header_parts[] = { @@ -2982,7 +3117,7 @@ draw_detail_func_section(search_tool_t *tool, detail_tab_t *tab) ui_detail_row(tool, &tab->single_grid, header_row, NULL); } else { for (detail_prop_t *param = f->first_param; param; param = param->next) { - draw_detail_prop(tool, &tab->param_grid, param, 0); + draw_detail_prop(tool, tab, &tab->param_grid, param, 0); } } @@ -3137,12 +3272,27 @@ draw_detail_layout_section_props(search_tool_t *tool, detail_tab_t *tab) details_refresh_values(tool, tab); - nk_layout_row_dynamic(tool->ctx, 22.0f, 1); + nk_layout_row_dynamic(tool->ctx, 22.0f, 2); if (ui_button_str(tool->ctx, STR_LIT("Copy"))) { str_t dump = detail_props_push_dump(tool, tab, tmp.arena); detail_copy_text(tool->ctx, dump); } + detail_tree_state_t state = {0}; + for (detail_owner_t *owner = tab->first_owner; owner; owner = owner->next) { + detail_props_collect_tree_state(owner->first_prop, &state); + } + + if (detail_tree_toggle_button(tool->ctx, state)) { + if (state.has_collapsed) { + details_refresh_all_values(tool, tab); + } + + for (detail_owner_t *owner = tab->first_owner; owner; owner = owner->next) { + detail_props_set_expanded(owner->first_prop, state.has_collapsed); + } + } + float group_pad_y = tool->ctx->style.window.group_padding.y; float scroll_h = tool->ctx->style.window.scrollbar_size.y; float pad_y = tool->ctx->style.window.spacing.y; @@ -3205,7 +3355,7 @@ draw_detail_layout_section_props(search_tool_t *tool, detail_tab_t *tab) ui_detail_row(tool, &tab->single_grid, row, NULL); } else { for (detail_prop_t *prop = owner->first_prop; prop; prop = prop->next) { - draw_detail_prop(tool, &tab->prop_grid, prop, 1); + draw_detail_prop(tool, tab, &tab->prop_grid, prop, 1); } } } @@ -3238,12 +3388,17 @@ draw_detail_layout_section_funcs(search_tool_t *tool, detail_tab_t *tab) nk_style_push_vec2(tool->ctx, &tool->ctx->style.tab.padding, nk_vec2(2.0f, 2.0f)); nk_style_push_style_item(tool->ctx, &tool->ctx->style.window.fixed_background, UI_ITEM(UI_C_TRANSPARENT)); - nk_layout_row_dynamic(tool->ctx, 22.0f, 1); + nk_layout_row_dynamic(tool->ctx, 22.0f, 2); if (ui_button_str(tool->ctx, STR_LIT("Copy"))) { str_t dump = detail_push_funcs_dump(tmp.arena, tab); detail_copy_text(tool->ctx, dump); } + detail_tree_state_t state = detail_funcs_tree_state(tab); + if (detail_tree_toggle_button(tool->ctx, state)) { + detail_funcs_set_expanded(tab, state.has_collapsed); + } + for (detail_owner_t *owner = tab->first_owner; owner; owner = owner->next) { ui_text_cell_t owner_parts[] = { UI_TEXT_CELL(tab->owner_hbar, UI_C_TEXT), @@ -3325,7 +3480,7 @@ draw_detail_layout_section_funcs(search_tool_t *tool, detail_tab_t *tab) ui_detail_row(tool, &tab->single_grid, row, NULL); } else { for (detail_prop_t *prop = func->first_param; prop; prop = prop->next) { - draw_detail_prop(tool, &tab->param_grid, prop, 2); + draw_detail_prop(tool, tab, &tab->param_grid, prop, 2); } } } diff --git a/src/builtin/ufunction_call.c b/src/builtin/ufunction_call.c index 03aaa8e..4087b19 100644 --- a/src/builtin/ufunction_call.c +++ b/src/builtin/ufunction_call.c @@ -18,23 +18,23 @@ #define CALL_SEARCH_CAP (128) #define CALL_STATUS_CAP (512) #define CALL_MAX_CONTAINER_ELEMS (128) +#define CALL_MAX_PICKER_RESULTS (256) +#define CALL_PICKER_BUDGET_US (500) -#define CALL_C_TYPE_TEXT nk_rgba(218, 156, 62, 255) -#define CALL_C_VALUE_TEXT nk_rgba(139, 191, 166, 255) -#define CALL_C_LINK_TEXT nk_rgba(122, 184, 232, 255) +#define CALL_C_TYPE_TEXT UI_C_PROP_TYPE_TEXT +#define CALL_C_VALUE_TEXT UI_C_PROP_VALUE_TEXT +#define CALL_C_LINK_TEXT UI_C_PROP_LINK_TEXT -typedef uint8_t call_param_role_t; -enum { - CALL_PARAM_INPUT = 0, - CALL_PARAM_OUTPUT, - CALL_PARAM_RETURN, -}; +typedef unreal_func_param_role_t call_param_role_t; typedef uint8_t call_value_kind_t; enum { CALL_VALUE_LEAF = 0, CALL_VALUE_STRUCT, CALL_VALUE_ARRAY, + CALL_VALUE_SET, + CALL_VALUE_MAP, + CALL_VALUE_MAP_PAIR, CALL_VALUE_FIXED_ARRAY, }; @@ -65,40 +65,47 @@ struct call_value_s { bool expanded; bool auto_world; bool class_picker; + bool interface_picker; bool soft_picker; call_object_ref_t object_ref; char input[CALL_TEXT_CAP]; }; -typedef struct call_result_s call_result_t; -struct call_result_s { - call_result_t *next; - call_result_t *first_child; - call_result_t *last_child; - - str_t name; - str_t type; - char value[CALL_TEXT_CAP]; - char tooltip[CALL_TEXT_CAP]; - bool expanded; -}; +typedef unreal_prop_snapshot_t call_result_t; typedef struct call_picker_s call_picker_t; struct call_picker_s { call_object_ref_t *ref; - fprop_t *soft_prop; char *soft_input; uclass_t *required_class; bool class_values; + bool interface_values; bool allow_none; - uint64_t generation; uint32_t count; + uint32_t scan_cursor; + uint32_t scan_total; + uint32_t scan_instance_slot; + bool scan_complete; uint32_t *slots; - char search[CALL_SEARCH_CAP]; + bool active_this_frame; + bool active_last_frame; + + uint32_t match_count; + uint32_t match_slots[CALL_MAX_PICKER_RESULTS]; + uint32_t filter_cursor; + bool filter_complete; + bool matches_truncated; + char search[CALL_SEARCH_CAP]; + char filtered_search[CALL_SEARCH_CAP]; }; +typedef struct call_picker_tooltip_s { + struct nk_rect anchor; + char text[CALL_TEXT_CAP]; +} call_picker_tooltip_t; + struct ufunc_call_dialog_s { arena_t *model_arena; arena_t *result_arena; @@ -127,22 +134,60 @@ struct ufunc_call_dialog_s { bool status_is_error; }; -typedef TARRAY(void) call_tarray_view_t; +static inline bool +call_value_kind_is_dynamic_container(call_value_kind_t kind) +{ + return kind == CALL_VALUE_ARRAY || kind == CALL_VALUE_SET || kind == CALL_VALUE_MAP; +} -typedef struct call_fsoft_object_ptr_s call_fsoft_object_ptr_t; -struct call_fsoft_object_ptr_s { - int32_t object_idx; - int32_t serial_num; - int32_t tag_at_last_test; - int32_t pad0; - fsoft_object_path_t path; -}; +static inline bool +call_prop_kind_uses_object_picker(unreal_prop_kind_t kind) +{ + return kind == UNREAL_PROP_KIND_OBJECT || kind == UNREAL_PROP_KIND_CLASS || + kind == UNREAL_PROP_KIND_WEAK_OBJECT || kind == UNREAL_PROP_KIND_LAZY_OBJECT || + kind == UNREAL_PROP_KIND_INTERFACE; +} + +static inline bool +call_prop_kind_accepts_blank_input(unreal_prop_kind_t kind) +{ + return kind == UNREAL_PROP_KIND_STRUCT || + kind == UNREAL_PROP_KIND_DELEGATE || + kind == UNREAL_PROP_KIND_MULTICAST_DELEGATE || + kind == UNREAL_PROP_KIND_MULTICAST_INLINE_DELEGATE || + kind == UNREAL_PROP_KIND_MULTICAST_SPARSE_DELEGATE; +} + +static inline const char * +call_tree_prefix(bool expanded) +{ + if (expanded) { + return "-"; + } + + return "+"; +} + +static void * +call_prop_value_alloc(arena_t *arena, fprop_t *prop) +{ + int32_t alignment = unreal_fprop_min_alignment(prop); + uint64_t size = unreal_fprop_complete_size(prop); + if (alignment <= 0 || size == 0) { + return NULL; + } + + return arena_push_aligned(arena, size, (uint64_t)alignment); +} static bool call_record_is_live_object(search_tool_t *tool, uint32_t slot, uobject_t *expected) { record_t *record = record_from_slot(tool, slot); - return record && expected && record_has_flag(record, RECORD_FLAG_LIVE) && record->obj == expected && unreal_uobject_is_valid(expected); + return record && expected && + record_has_flag(record, RECORD_FLAG_LIVE) && + record->obj == expected && + unreal_uobject_is_valid(expected); } static void @@ -184,7 +229,11 @@ call_object_ref_set(search_tool_t *tool, call_object_ref_t *ref, uobject_t *obj) return; } - uint32_t slot = (obj->internal_idx >= 0) ? (uint32_t)obj->internal_idx : RECORD_SLOT_INVALID; + uint32_t slot = RECORD_SLOT_INVALID; + if (obj->internal_idx >= 0) { + slot = (uint32_t)obj->internal_idx; + } + record_t *record = record_from_slot(tool, slot); if (!record || !record_has_flag(record, RECORD_FLAG_LIVE) || record->obj != obj) { call_object_ref_set_none(ref); @@ -230,9 +279,18 @@ call_prop_is_supported(fprop_t *prop) case UNREAL_PROP_KIND_CLASS: case UNREAL_PROP_KIND_SOFT_OBJECT: case UNREAL_PROP_KIND_SOFT_CLASS: + case UNREAL_PROP_KIND_WEAK_OBJECT: + case UNREAL_PROP_KIND_LAZY_OBJECT: + case UNREAL_PROP_KIND_INTERFACE: case UNREAL_PROP_KIND_STRUCT: case UNREAL_PROP_KIND_ARRAY: + case UNREAL_PROP_KIND_SET: + case UNREAL_PROP_KIND_MAP: case UNREAL_PROP_KIND_ENUM: + case UNREAL_PROP_KIND_DELEGATE: + case UNREAL_PROP_KIND_MULTICAST_DELEGATE: + case UNREAL_PROP_KIND_MULTICAST_INLINE_DELEGATE: + case UNREAL_PROP_KIND_MULTICAST_SPARSE_DELEGATE: return true; default: return false; @@ -305,13 +363,16 @@ call_value_build_base(ufunc_call_dialog_t *dialog, fprop_t *prop, str_t name, ca .is_none = true, }; - if (unreal_fprop_class_is(prop, globals.unreal.class_prop) || - unreal_fprop_class_is(prop, globals.unreal.soft_class_prop)) { + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + if (kind == UNREAL_PROP_KIND_CLASS || kind == UNREAL_PROP_KIND_SOFT_CLASS) { node->class_picker = true; } - if (unreal_fprop_class_is(prop, globals.unreal.soft_obj_prop) || - unreal_fprop_class_is(prop, globals.unreal.soft_class_prop)) { + if (kind == UNREAL_PROP_KIND_INTERFACE) { + node->interface_picker = true; + } + + if (kind == UNREAL_PROP_KIND_SOFT_OBJECT || kind == UNREAL_PROP_KIND_SOFT_CLASS) { node->soft_picker = true; } @@ -343,14 +404,21 @@ call_value_build(ufunc_call_dialog_t *dialog, fprop_t *prop, str_t name, call_pa return node; } - if (unreal_fprop_class_is(prop, globals.unreal.struct_prop)) { - node->kind = CALL_VALUE_STRUCT; + unreal_prop_kind_t prop_kind = unreal_fprop_get_kind(prop); + if (prop_kind == UNREAL_PROP_KIND_STRUCT) { fprop_struct_t *struct_prop = (fprop_struct_t *)prop; - if (!struct_prop->script_struct || !struct_prop->script_struct->child_props) { + if (!struct_prop->script_struct) { node->supported = false; return node; } + /* NOTE: native structs without reflected fields can still be entered using the engine's ImportText syntax */ + if (!struct_prop->script_struct->child_props) { + node->kind = CALL_VALUE_LEAF; + return node; + } + + node->kind = CALL_VALUE_STRUCT; for (ffield_t *field = struct_prop->script_struct->child_props; field; field = field->next) { fprop_t *child_prop = (fprop_t *)field; str_t child_name = unreal_fname_to_str(child_prop->name, dialog->model_arena); @@ -364,7 +432,7 @@ call_value_build(ufunc_call_dialog_t *dialog, fprop_t *prop, str_t name, call_pa call_value_push_child(node, child); node->supported = node->supported && child->supported; } - } else if (unreal_fprop_class_is(prop, globals.unreal.array_prop)) { + } else if (prop_kind == UNREAL_PROP_KIND_ARRAY) { fprop_array_t *array_prop = (fprop_array_t *)prop; node->kind = CALL_VALUE_ARRAY; @@ -374,6 +442,28 @@ call_value_build(ufunc_call_dialog_t *dialog, fprop_t *prop, str_t name, call_pa if (!array_prop->inner || !call_prop_is_supported(array_prop->inner)) { node->supported = false; } + } else if (prop_kind == UNREAL_PROP_KIND_SET) { + fprop_set_t *set_prop = (fprop_set_t *)prop; + + node->kind = CALL_VALUE_SET; + node->array_count = 0; + str_write_fmt(node->input, sizeof(node->input), "0"); + + if (!set_prop->elem_prop || !call_prop_is_supported(set_prop->elem_prop)) { + node->supported = false; + } + } else if (prop_kind == UNREAL_PROP_KIND_MAP) { + fprop_map_t *map_prop = (fprop_map_t *)prop; + + node->kind = CALL_VALUE_MAP; + node->array_count = 0; + str_write_fmt(node->input, sizeof(node->input), "0"); + + if (!map_prop->key_prop || !map_prop->val_prop || + !call_prop_is_supported(map_prop->key_prop) || + !call_prop_is_supported(map_prop->val_prop)) { + node->supported = false; + } } else { node->kind = CALL_VALUE_LEAF; } @@ -382,9 +472,10 @@ call_value_build(ufunc_call_dialog_t *dialog, fprop_t *prop, str_t name, call_pa } static bool -call_array_parse_count(call_value_t *node, int32_t *out_count) +call_container_parse_count(call_value_t *node, int32_t *out_count) { - if (!node || node->kind != CALL_VALUE_ARRAY || !out_count || node->input[0] == '\0') { + if (!node || !call_value_kind_is_dynamic_container(node->kind) || + !out_count || node->input[0] == '\0') { return false; } @@ -399,19 +490,60 @@ call_array_parse_count(call_value_t *node, int32_t *out_count) return true; } +static call_value_t * +call_map_pair_build(ufunc_call_dialog_t *dialog, call_value_t *map, int32_t idx) +{ + fprop_map_t *map_prop = (fprop_map_t *)map->prop; + call_value_t *pair = ARENA_PUSH_ZERO(dialog->model_arena, call_value_t); + if (!pair) { + return NULL; + } + + str_t key_type = unreal_fprop_push_type_name(map_prop->key_prop, dialog->model_arena); + str_t val_type = unreal_fprop_push_type_name(map_prop->val_prop, dialog->model_arena); + + pair->prop = map->prop; + pair->name = str_push_fmt(dialog->model_arena, "[%d]", idx); + pair->type = str_push_fmt(dialog->model_arena, "TPair<%.*s, %.*s>", STR_ARG(key_type), STR_ARG(val_type)); + pair->role = map->role; + pair->kind = CALL_VALUE_MAP_PAIR; + pair->array_index = idx; + pair->supported = true; + pair->expanded = true; + call_object_ref_set_none(&pair->object_ref); + + call_value_t *key = call_value_build(dialog, map_prop->key_prop, STR_LIT("Key"), map->role, true); + call_value_t *val = call_value_build(dialog, map_prop->val_prop, STR_LIT("Value"), map->role, true); + if (!key || !val) { + return NULL; + } + + call_value_push_child(pair, key); + call_value_push_child(pair, val); + pair->supported = key->supported && val->supported; + return pair; +} + static bool -call_array_sync(ufunc_call_dialog_t *dialog, call_value_t *node) +call_container_sync(ufunc_call_dialog_t *dialog, call_value_t *node) { int32_t count = 0; - if (!call_array_parse_count(node, &count)) { + if (!call_container_parse_count(node, &count)) { return false; } - fprop_array_t *array_prop = (fprop_array_t *)node->prop; while (node->child_count < count) { - int32_t idx = node->child_count; - - call_value_t *child = call_value_build(dialog, array_prop->inner, str_push_fmt(dialog->model_arena, "[%d]", idx), node->role, true); + int32_t idx = node->child_count; + call_value_t *child = NULL; + if (node->kind == CALL_VALUE_ARRAY) { + fprop_array_t *array_prop = (fprop_array_t *)node->prop; + child = call_value_build(dialog, array_prop->inner, str_push_fmt(dialog->model_arena, "[%d]", idx), node->role, true); + } else if (node->kind == CALL_VALUE_SET) { + fprop_set_t *set_prop = (fprop_set_t *)node->prop; + child = call_value_build(dialog, set_prop->elem_prop, str_push_fmt(dialog->model_arena, "[%d]", idx), node->role, true); + } else { + child = call_map_pair_build(dialog, node, idx); + } if (!child) { return false; } @@ -425,23 +557,6 @@ call_array_sync(ufunc_call_dialog_t *dialog, call_value_t *node) return true; } -static call_param_role_t -call_param_role(fprop_t *prop) -{ - if (prop->prop_flags & CPF_RETURN_PARM) { - return CALL_PARAM_RETURN; - } - - /* ReferenceParm describes reference passing, not a second pin direction. - * UHT commonly emits OutParm | ReferenceParm for ordinary output arrays and - * structs, so OutParm must classify the parameter as output-only. */ - if (prop->prop_flags & CPF_OUT_PARM) { - return CALL_PARAM_OUTPUT; - } - - return CALL_PARAM_INPUT; -} - static void call_results_build_placeholders(ufunc_call_dialog_t *dialog); @@ -456,21 +571,26 @@ call_model_build(search_tool_t *tool, ufunc_call_dialog_t *dialog) dialog->first_result = NULL; dialog->last_result = NULL; - ufunc_t *func = dialog->func_expected; - for (ffield_t *field = func ? func->child_props : NULL; field; field = field->next) { + ufunc_t *func = dialog->func_expected; + ffield_t *field = NULL; + if (func) { + field = func->child_props; + } + + for (; field; field = field->next) { fprop_t *prop = (fprop_t *)field; if (!(prop->prop_flags & CPF_PARM)) { continue; } - call_param_role_t role = call_param_role(prop); + call_param_role_t role = unreal_fprop_get_param_role(prop); call_value_t *node = call_value_build(dialog, prop, unreal_fname_to_str(prop->name, dialog->model_arena), role, true); if (!node) { call_status_set(dialog, true, "Failed to allocate the reflected parameter model"); return; } - if (role == CALL_PARAM_INPUT && call_name_is_world_context(prop->name) && + if (role == UNREAL_FUNC_PARAM_INPUT && call_name_is_world_context(prop->name) && unreal_fprop_class_is(prop, globals.unreal.obj_prop)) { node->auto_world = true; } @@ -484,31 +604,18 @@ call_model_build(search_tool_t *tool, ufunc_call_dialog_t *dialog) UNUSED_VAR(tool); } -static uclass_t * -call_node_required_class(call_value_t *node) +static bool +call_candidate_class_matches(uclass_t *candidate, uclass_t *required_class, bool interface_values) { - if (!node || !node->prop) { - return NULL; + if (interface_values) { + return unreal_uclass_implements_interface(candidate, required_class); } - if (unreal_fprop_class_is(node->prop, globals.unreal.class_prop)) { - return ((fprop_class_t *)node->prop)->meta_class; - } - - if (unreal_fprop_class_is(node->prop, globals.unreal.soft_class_prop)) { - return ((fprop_class_soft_t *)node->prop)->meta_class; - } - - if (unreal_fprop_class_is(node->prop, globals.unreal.obj_prop) || - unreal_fprop_class_is(node->prop, globals.unreal.soft_obj_prop)) { - return ((fprop_obj_base_t *)node->prop)->prop_class; - } - - return NULL; + return unreal_uclass_is_child_of(candidate, required_class); } static bool -call_candidate_matches(uobject_t *obj, uclass_t *required_class, bool class_values) +call_candidate_matches(uobject_t *obj, uclass_t *required_class, bool class_values, bool interface_values) { if (!obj || !required_class) { return false; @@ -521,161 +628,60 @@ call_candidate_matches(uobject_t *obj, uclass_t *required_class, bool class_valu return unreal_uclass_is_child_of((uclass_t *)obj, required_class); } - return unreal_uobject_is_a(obj, required_class); + return call_candidate_class_matches(obj->cls, required_class, interface_values); } static void -call_picker_rebuild(search_tool_t *tool, ufunc_call_dialog_t *dialog) +call_picker_rebuild_tick(search_tool_t *tool, ufunc_call_dialog_t *dialog) { call_picker_t *picker = &dialog->picker; - - picker->count = 0; - if (!picker->required_class || !picker->slots) { - picker->generation = tool->cache.generation; + if (picker->scan_complete || !picker->required_class || !picker->slots) { + picker->scan_complete = true; return; } - for (uint32_t i = 0; i < tool->cache.live_slots.count; ++i) { - uint32_t slot = tool->cache.live_slots.slots[i]; - record_t *record = record_from_slot(tool, slot); - if (!record || !record_has_flag(record, RECORD_FLAG_LIVE) || !record->obj) { - continue; - } - - if (call_candidate_matches(record->obj, picker->required_class, picker->class_values)) { - picker->slots[picker->count++] = slot; - } - } - picker->generation = tool->cache.generation; -} + uint64_t start_us = time_now_us(); + uint32_t work = 0; + while (!picker->scan_complete && picker->count < tool->cache.record_cap) { + if (record_slot_valid(picker->scan_instance_slot)) { + uint32_t slot = picker->scan_instance_slot; + record_t *record = record_from_slot(tool, slot); -static bool -call_append_escaped_quoted(arena_t *arena, str_t raw, str_t *out) -{ - uint64_t cap = raw.len * 2 + 3; - uint8_t *buf = ARENA_PUSH_ARRAY(arena, uint8_t, cap); - if (!buf) { - return false; - } + picker->scan_instance_slot = RECORD_SLOT_INVALID; + if (record) { + picker->scan_instance_slot = record->next_instance_slot; + } - uint64_t at = 0; - buf[at++] = '"'; - for (uint64_t i = 0; i < raw.len; ++i) { - uint8_t c = raw.data[i]; - if (c == '\\' || c == '"') { - buf[at++] = '\\'; - buf[at++] = c; - } else if (c == '\n') { - buf[at++] = '\\'; - buf[at++] = 'n'; - } else if (c == '\r') { - buf[at++] = '\\'; - buf[at++] = 'r'; - } else if (c == '\t') { - buf[at++] = '\\'; - buf[at++] = 't'; + if (record && record_has_flag(record, RECORD_FLAG_LIVE) && record->obj) { + picker->slots[picker->count++] = slot; + } } else { - buf[at++] = c; - } - } - buf[at++] = '"'; - buf[at] = '\0'; - - *out = str_make(buf, at); - return true; -} - -static str_t -call_object_literal(search_tool_t *tool, call_object_ref_t ref, arena_t *arena) -{ - if (ref.is_none || !ref.expected) { - return STR_LIT("None"); - } - - if (!call_record_is_live_object(tool, ref.slot, ref.expected)) { - return STR_NULL; - } - - str_t cls_name = unreal_uobject_push_name((uobject_t *)ref.expected->cls, arena); - str_t path = unreal_uobject_push_full_name(ref.expected, arena); - return str_push_fmt(arena, "%.*s'%.*s'", STR_ARG(cls_name), STR_ARG(path)); -} - -static str_t -call_value_literal(search_tool_t *tool, ufunc_call_dialog_t *dialog, call_value_t *node, arena_t *arena) -{ - if (!node || !node->supported) { - return STR_NULL; - } - - if (node->kind == CALL_VALUE_STRUCT) { - str_list_t parts = {0}; - for (call_value_t *child = node->first_child; child; child = child->next) { - str_t value = call_value_literal(tool, dialog, child, arena); - if (str_is_empty(value)) { - return STR_NULL; + if (picker->scan_cursor >= picker->scan_total || picker->scan_cursor >= tool->cache.live_slots.count) { + picker->scan_complete = true; + break; } - str_list_push(arena, &parts, str_push_fmt(arena, "%.*s=%.*s", STR_ARG(child->name), STR_ARG(value))); - } - - return str_list_join(arena, parts, STR_LIT("("), STR_LIT(","), STR_LIT(")")); - } - - if (node->kind == CALL_VALUE_ARRAY || node->kind == CALL_VALUE_FIXED_ARRAY) { - if (node->kind == CALL_VALUE_ARRAY && !call_array_sync(dialog, node)) { - return STR_NULL; - } - - int32_t count = node->kind == CALL_VALUE_ARRAY ? node->array_count : node->child_count; - str_list_t parts = {0}; - int32_t idx = 0; - for (call_value_t *child = node->first_child; child && idx < count; child = child->next, ++idx) { - str_t value = call_value_literal(tool, dialog, child, arena); - if (str_is_empty(value)) { - return STR_NULL; + uint32_t slot = tool->cache.live_slots.slots[picker->scan_cursor++]; + record_t *record = record_from_slot(tool, slot); + if (record && record_has_flag(record, RECORD_FLAG_LIVE) && record->obj && record->kind == UOBJECT_KIND_CLASS && + call_candidate_class_matches((uclass_t *)record->obj, picker->required_class, picker->interface_values)) { + if (picker->class_values) { + picker->slots[picker->count++] = slot; + } else { + picker->scan_instance_slot = record->first_instance_slot; + } } - - str_list_push(arena, &parts, value); } - return str_list_join(arena, parts, STR_LIT("("), STR_LIT(","), STR_LIT(")")); - } - - fprop_t *prop = node->prop; - if (unreal_fprop_class_is(prop, globals.unreal.obj_prop) || - unreal_fprop_class_is(prop, globals.unreal.class_prop)) { - if (node->auto_world) { - uworld_t *world = globals.gworld_ptr ? *globals.gworld_ptr : NULL; - call_object_ref_t world_ref = { - .slot = RECORD_SLOT_INVALID, - .expected = (uobject_t *)world, - .is_none = (world == NULL), - }; - - if (world) { - world_ref.slot = (uint32_t)((uobject_t *)world)->internal_idx; - } - return call_object_literal(tool, world_ref, arena); + work += 1; + if ((work & 63u) == 0 && time_now_us() - start_us >= CALL_PICKER_BUDGET_US) { + break; } - - return call_object_literal(tool, node->object_ref, arena); } - str_t raw = str_from_cstr_with_cap(node->input, sizeof(node->input)); - if (unreal_fprop_class_is(prop, globals.unreal.str_prop) || - unreal_fprop_class_is(prop, globals.unreal.text_prop) || - unreal_fprop_class_is(prop, globals.unreal.name_prop) || - unreal_fprop_class_is(prop, globals.unreal.soft_obj_prop) || - unreal_fprop_class_is(prop, globals.unreal.soft_class_prop)) { - str_t quoted = STR_NULL; - if (!call_append_escaped_quoted(arena, raw, "ed)) { - return STR_NULL; - } - return quoted; + if (picker->count >= tool->cache.record_cap) { + picker->scan_complete = true; } - - return str_push_copy(arena, raw); } static bool @@ -705,234 +711,167 @@ call_apply_value(search_tool_t *tool, ufunc_call_dialog_t *dialog, call_value_t } if (node->kind == CALL_VALUE_ARRAY) { - if (!call_array_sync(dialog, node)) { + if (!call_container_sync(dialog, node) || !unreal_array_clear(value, (fprop_array_t *)node->prop)) { return false; } - } - if (node->kind == CALL_VALUE_LEAF && - (unreal_fprop_class_is(node->prop, globals.unreal.obj_prop) || - unreal_fprop_class_is(node->prop, globals.unreal.class_prop))) { - uobject_t *selected = NULL; - if (node->auto_world) { - selected = globals.gworld_ptr ? (uobject_t *)*globals.gworld_ptr : NULL; - } else if (!node->object_ref.is_none) { - if (!call_record_is_live_object(tool, node->object_ref.slot, node->object_ref.expected)) { + fprop_array_t *array_prop = (fprop_array_t *)node->prop; + int32_t idx = 0; + for (call_value_t *child = node->first_child; child && idx < node->array_count; child = child->next, ++idx) { + void *item = call_prop_value_alloc(arena, array_prop->inner); + if (!item || !unreal_fprop_initialize_value(array_prop->inner, item)) { return false; } - selected = node->object_ref.expected; - } - if (selected && !call_candidate_matches(selected, call_node_required_class(node), node->class_picker)) { - return false; + bool ok = call_apply_value(tool, dialog, child, item, owner, arena) && + unreal_array_add(value, array_prop, item) >= 0; + unreal_fprop_destroy_value(array_prop->inner, item); + if (!ok) { + return false; + } } - return unreal_fprop_set_object((fprop_obj_base_t *)node->prop, value, selected); + return true; } - str_t literal = call_value_literal(tool, dialog, node, arena); - return unreal_fprop_import_text(node->prop, value, owner, literal, arena); -} + if (node->kind == CALL_VALUE_SET) { + if (!call_container_sync(dialog, node) || !unreal_set_clear(value, (fprop_set_t *)node->prop)) { + return false; + } -static void -call_result_format_leaf(call_result_t *result, fprop_t *prop, void *value, arena_t *arena) -{ - unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + fprop_set_t *set_prop = (fprop_set_t *)node->prop; + int32_t idx = 0; + for (call_value_t *child = node->first_child; child && idx < node->array_count; child = child->next, ++idx) { + void *item = call_prop_value_alloc(arena, set_prop->elem_prop); + if (!item || !unreal_fprop_initialize_value(set_prop->elem_prop, item)) { + return false; + } - if (kind == UNREAL_PROP_KIND_BOOL) { - bool boolean = false; - if (unreal_fprop_read_bool(prop, value, &boolean)) { - str_write_fmt(result->value, sizeof(result->value), "%s", boolean ? "true" : "false"); - } - } else if (kind == UNREAL_PROP_KIND_FLOAT) { - double real = 0.0; - if (unreal_fprop_read_real(prop, value, &real)) { - str_write_fmt(result->value, sizeof(result->value), "%.9g", real); - } - } else if (kind == UNREAL_PROP_KIND_DOUBLE) { - double real = 0.0; - if (unreal_fprop_read_real(prop, value, &real)) { - str_write_fmt(result->value, sizeof(result->value), "%.17g", real); - } - } else if (kind == UNREAL_PROP_KIND_BYTE || - kind == UNREAL_PROP_KIND_INT8 || - kind == UNREAL_PROP_KIND_INT16 || - kind == UNREAL_PROP_KIND_INT32 || - kind == UNREAL_PROP_KIND_INT64 || - kind == UNREAL_PROP_KIND_UINT16 || - kind == UNREAL_PROP_KIND_UINT32 || - kind == UNREAL_PROP_KIND_UINT64) { - unreal_prop_integer_t integer = {0}; - if (unreal_fprop_read_integer(prop, value, &integer)) { - if (integer.is_signed) { - str_write_fmt(result->value, sizeof(result->value), "%lld", (long long)(int64_t)integer.value); - } else { - str_write_fmt(result->value, sizeof(result->value), "%llu", (unsigned long long)integer.value); + bool ok = call_apply_value(tool, dialog, child, item, owner, arena); + if (ok) { + unreal_set_add(value, set_prop, item); } - } - } else if (kind == UNREAL_PROP_KIND_ENUM) { - fprop_enum_t *enum_prop = (fprop_enum_t *)prop; - unreal_prop_integer_t integer_value = {0}; - if (!unreal_fprop_read_integer(prop, value, &integer_value)) { - str_write_fmt(result->value, sizeof(result->value), ""); - return; - } - int64_t integer = (int64_t)integer_value.value; - str_t name = STR_NULL; - if (enum_prop->uenum) { - for (int32_t i = 0; i < enum_prop->uenum->names.num; ++i) { - if (enum_prop->uenum->names.data[i].value == integer) { - name = unreal_fname_to_str(enum_prop->uenum->names.data[i].key, arena); - break; - } + + unreal_fprop_destroy_value(set_prop->elem_prop, item); + if (!ok) { + return false; } } - if (!str_is_empty(name)) { - str_write_fmt(result->value, sizeof(result->value), "%.*s", STR_ARG(name)); - } else { - str_write_fmt(result->value, sizeof(result->value), "%lld", (long long)integer); - } - } else if (kind == UNREAL_PROP_KIND_NAME) { - fname_t name = {0}; - if (unreal_fprop_read_name(prop, value, &name)) { - str_t text = unreal_fname_to_str(name, arena); - str_write_fmt(result->value, sizeof(result->value), "%.*s", STR_ARG(text)); - } - } else if (kind == UNREAL_PROP_KIND_STRING) { - str_t text = unreal_fstring_to_str(*(fstring_t *)value, arena); - str_write_fmt(result->value, sizeof(result->value), "%.*s", STR_ARG(text)); - } else if (kind == UNREAL_PROP_KIND_TEXT) { - ftext_t *text = (ftext_t *)value; - fstring_t *display = (text->text_data.obj && text->text_data.obj->vtable && text->text_data.obj->vtable->get_display_string) - ? text->text_data.obj->vtable->get_display_string(text->text_data.obj) - : NULL; - str_t display_text = display ? unreal_fstring_to_str(*display, arena) : STR_NULL; - str_write_fmt(result->value, sizeof(result->value), "%.*s", STR_ARG(display_text)); - } else if (kind == UNREAL_PROP_KIND_OBJECT || kind == UNREAL_PROP_KIND_CLASS) { - uobject_t *obj = unreal_fprop_get_object((fprop_obj_base_t *)prop, value); - if (!obj) { - str_write_fmt(result->value, sizeof(result->value), "None"); - } else if (!unreal_uobject_is_valid(obj)) { - str_write_fmt(result->value, sizeof(result->value), ""); - } else { - str_t name = unreal_uobject_push_name(obj, arena); - str_t full_name = unreal_uobject_push_full_name(obj, arena); - str_write_fmt(result->value, sizeof(result->value), "%.*s", STR_ARG(name)); - str_write_fmt(result->tooltip, sizeof(result->tooltip), "%.*s", STR_ARG(full_name)); - } - } else if (kind == UNREAL_PROP_KIND_SOFT_OBJECT || kind == UNREAL_PROP_KIND_SOFT_CLASS) { - call_fsoft_object_ptr_t *soft = (call_fsoft_object_ptr_t *)value; - str_t asset = unreal_fname_to_str(soft->path.asset_path_name, arena); - str_t sub = unreal_fstring_to_str(soft->path.sub_path_string, arena); - if (!str_is_empty(sub)) { - str_write_fmt(result->value, sizeof(result->value), "%.*s:%.*s", STR_ARG(asset), STR_ARG(sub)); - } else { - str_write_fmt(result->value, sizeof(result->value), "%.*s", STR_ARG(asset)); - } - } else { - str_write_fmt(result->value, sizeof(result->value), ""); + return true; } -} -static call_result_t * -call_result_snapshot(ufunc_call_dialog_t *dialog, fprop_t *prop, str_t name, uint8_t *value, bool allow_fixed_array) -{ - call_result_t *result = ARENA_PUSH_ZERO(dialog->result_arena, call_result_t); - if (!result) { - return NULL; - } + if (node->kind == CALL_VALUE_MAP) { + if (!call_container_sync(dialog, node) || !unreal_map_clear(value, (fprop_map_t *)node->prop)) { + return false; + } - result->name = str_push_copy(dialog->result_arena, name); - result->type = unreal_fprop_push_type_name(prop, dialog->result_arena); - result->expanded = true; + fprop_map_t *map_prop = (fprop_map_t *)node->prop; + int32_t idx = 0; + for (call_value_t *pair = node->first_child; pair && idx < node->array_count; pair = pair->next, ++idx) { + call_value_t *key_node = pair->first_child; + call_value_t *val_node = NULL; + if (key_node) { + val_node = key_node->next; + } - if (allow_fixed_array && prop->array_dim > 1) { - str_write_fmt(result->value, sizeof(result->value), "Num=%d", prop->array_dim); - for (int32_t i = 0; i < prop->array_dim; ++i) { - call_result_t *child = call_result_snapshot(dialog, prop, str_push_fmt(dialog->result_arena, "[%d]", i), value + (uint64_t)i * (uint64_t)prop->elem_size, false); - if (child) { - QUEUE_PUSH(result->first_child, result->last_child, child); + void *key = call_prop_value_alloc(arena, map_prop->key_prop); + void *val = call_prop_value_alloc(arena, map_prop->val_prop); + if (!key_node || !val_node || !key || !val) { + return false; } - } - return result; - } - if (unreal_fprop_class_is(prop, globals.unreal.struct_prop)) { - fprop_struct_t *struct_prop = (fprop_struct_t *)prop; - str_write_fmt(result->value, sizeof(result->value), "{...}"); - if (struct_prop->script_struct) { - for (ffield_t *field = struct_prop->script_struct->child_props; field; field = field->next) { - fprop_t *child_prop = (fprop_t *)field; - call_result_t *child = call_result_snapshot(dialog, child_prop, unreal_fname_to_str(child_prop->name, dialog->result_arena), value + child_prop->offset_internal, true); - if (child) { - QUEUE_PUSH(result->first_child, result->last_child, child); + bool key_initialized = unreal_fprop_initialize_value(map_prop->key_prop, key); + bool val_initialized = unreal_fprop_initialize_value(map_prop->val_prop, val); + if (!key_initialized || !val_initialized) { + if (key_initialized) { + unreal_fprop_destroy_value(map_prop->key_prop, key); + } + + if (val_initialized) { + unreal_fprop_destroy_value(map_prop->val_prop, val); } + return false; + } + + bool ok = call_apply_value(tool, dialog, key_node, key, owner, arena) && + call_apply_value(tool, dialog, val_node, val, owner, arena); + if (ok) { + unreal_map_add(value, map_prop, key, val); + } + + unreal_fprop_destroy_value(map_prop->key_prop, key); + unreal_fprop_destroy_value(map_prop->val_prop, val); + + if (!ok) { + return false; } } - } else if (unreal_fprop_class_is(prop, globals.unreal.array_prop)) { - fprop_array_t *array_prop = (fprop_array_t *)prop; - call_tarray_view_t *array = (call_tarray_view_t *)value; - int32_t count = (array->num >= 0 && array->num <= array->max && array->data) ? array->num : 0; - str_write_fmt(result->value, sizeof(result->value), "Num=%d", count); + return true; + } - int32_t shown = MIN_VAL(count, CALL_MAX_CONTAINER_ELEMS); - for (int32_t i = 0; i < shown; ++i) { - call_result_t *child = call_result_snapshot(dialog, array_prop->inner, str_push_fmt(dialog->result_arena, "[%d]", i), (uint8_t *)array->data + (uint64_t)i * (uint64_t)array_prop->inner->elem_size, true); - if (child) { - QUEUE_PUSH(result->first_child, result->last_child, child); + unreal_prop_kind_t prop_kind = unreal_fprop_get_kind(node->prop); + if (node->kind == CALL_VALUE_LEAF && call_prop_kind_uses_object_picker(prop_kind)) { + uobject_t *selected = NULL; + if (node->auto_world) { + if (globals.gworld_ptr) { + selected = (uobject_t *)*globals.gworld_ptr; + } + } else if (!node->object_ref.is_none) { + if (!call_record_is_live_object(tool, node->object_ref.slot, node->object_ref.expected)) { + return false; } + + selected = node->object_ref.expected; } - } else { - call_result_format_leaf(result, prop, value, dialog->result_arena); + + uclass_t *required_class = unreal_fprop_get_reference_class(node->prop); + if (selected && !call_candidate_matches(selected, required_class, node->class_picker, node->interface_picker)) { + return false; + } + + if (prop_kind == UNREAL_PROP_KIND_INTERFACE) { + return unreal_fprop_set_interface((fprop_iface_t *)node->prop, value, selected); + } + + return unreal_fprop_set_object((fprop_obj_base_t *)node->prop, value, selected); } - return result; + + if (node->kind == CALL_VALUE_LEAF && node->input[0] == '\0' && call_prop_kind_accepts_blank_input(prop_kind)) { + /* NOTE: the initialized value is already the useful blank/default value */ + return true; + } + + str_t input = str_from_cstr_with_cap(node->input, sizeof(node->input)); + return unreal_fprop_import_text(node->prop, value, owner, input, arena); } static call_result_t * -call_result_placeholder(ufunc_call_dialog_t *dialog, fprop_t *prop, str_t name, bool allow_fixed_array) +call_result_snapshot(ufunc_call_dialog_t *dialog, fprop_t *prop, str_t name, uint8_t *value) { - call_result_t *result = ARENA_PUSH_ZERO(dialog->result_arena, call_result_t); - if (!result) { - return NULL; - } + unreal_prop_snapshot_builder_t builder = {0}; + unreal_prop_snapshot_builder_init(&builder, dialog->result_arena); + builder.max_container_elements = CALL_MAX_CONTAINER_ELEMS; - result->name = str_push_copy(dialog->result_arena, name); - result->type = unreal_fprop_push_type_name(prop, dialog->result_arena); - result->expanded = true; + return unreal_fprop_snapshot_build(&builder, prop, name, value); +} - if (allow_fixed_array && prop->array_dim > 1) { - for (int32_t i = 0; i < prop->array_dim; ++i) { - call_result_t *child = call_result_placeholder(dialog, prop, str_push_fmt(dialog->result_arena, "[%d]", i), false); - if (child) { - QUEUE_PUSH(result->first_child, result->last_child, child); - } - } - } else if (unreal_fprop_class_is(prop, globals.unreal.struct_prop)) { - fprop_struct_t *struct_prop = (fprop_struct_t *)prop; - if (struct_prop->script_struct) { - for (ffield_t *field = struct_prop->script_struct->child_props; field; field = field->next) { - fprop_t *child_prop = (fprop_t *)field; - call_result_t *child = call_result_placeholder(dialog, child_prop, unreal_fname_to_str(child_prop->name, dialog->result_arena), true); - if (child) { - QUEUE_PUSH(result->first_child, result->last_child, child); - } - } - } - } - return result; +static call_result_t * +call_result_placeholder(ufunc_call_dialog_t *dialog, fprop_t *prop, str_t name) +{ + return call_result_snapshot(dialog, prop, name, NULL); } static void call_results_build_placeholders(ufunc_call_dialog_t *dialog) { for (call_value_t *node = dialog->first_param; node; node = node->next) { - if (node->role != CALL_PARAM_OUTPUT && node->role != CALL_PARAM_RETURN) { + if (node->role != UNREAL_FUNC_PARAM_OUTPUT && node->role != UNREAL_FUNC_PARAM_RETURN) { continue; } - call_result_t *result = call_result_placeholder(dialog, node->prop, node->name, true); + call_result_t *result = call_result_placeholder(dialog, node->prop, node->name); if (result) { QUEUE_PUSH(dialog->first_result, dialog->last_result, result); } @@ -963,8 +902,8 @@ call_validate_schema(ufunc_call_dialog_t *dialog, ufunc_t *func) return false; } - if (node->kind == CALL_VALUE_ARRAY && !call_array_sync(dialog, node)) { - call_status_set(dialog, true, "Array %.*s Num must be between 0 and %d", STR_ARG(node->name), CALL_MAX_CONTAINER_ELEMS); + if (call_value_kind_is_dynamic_container(node->kind) && !call_container_sync(dialog, node)) { + call_status_set(dialog, true, "Container %.*s Num must be between 0 and %d", STR_ARG(node->name), CALL_MAX_CONTAINER_ELEMS); return false; } } @@ -1002,12 +941,6 @@ call_validate_target(search_tool_t *tool, ufunc_call_dialog_t *dialog, uobject_t static void call_execute(search_tool_t *tool, ufunc_call_dialog_t *dialog) { -#if defined BUILD_TEST_UI - (void)tool; - call_status_set(dialog, true, "Unavailable"); - return; -#else - if (!call_record_is_live_object(tool, dialog->func_slot, (uobject_t *)dialog->func_expected)) { call_status_set(dialog, true, "The function was unloaded or replaced"); return; @@ -1033,35 +966,36 @@ call_execute(search_tool_t *tool, ufunc_call_dialog_t *dialog) } initialized = true; - for (call_value_t *node = dialog->first_param; node; node = node->next) { - if (node->role == CALL_PARAM_OUTPUT || node->role == CALL_PARAM_RETURN) { - continue; - } - - uint8_t *value = params + node->prop->offset_internal; - if (!call_apply_value(tool, dialog, node, value, target, tmp.arena)) { - call_status_set(dialog, true, "Could not parse %.*s (%.*s)", STR_ARG(node->name), STR_ARG(node->type)); - imported = false; - break; + for (call_value_t *node = dialog->first_param; node && imported; node = node->next) { + if (node->role == UNREAL_FUNC_PARAM_INPUT) { + uint8_t *value = params + node->prop->offset_internal; + if (!call_apply_value(tool, dialog, node, value, target, tmp.arena)) { + call_status_set(dialog, true, "Could not parse %.*s (%.*s)", STR_ARG(node->name), STR_ARG(node->type)); + imported = false; + } } } if (imported) { - unreal_process_event_observed(target, func, func->params_size ? params : NULL); + void *params_arg = params; + if (func->params_size == 0) { + params_arg = NULL; + } + + unreal_process_event_observed(target, func, params_arg); arena_reset(dialog->result_arena); dialog->first_result = NULL; dialog->last_result = NULL; for (call_value_t *node = dialog->first_param; node; node = node->next) { - if (node->role != CALL_PARAM_OUTPUT && node->role != CALL_PARAM_RETURN) { - continue; - } - - call_result_t *result = call_result_snapshot(dialog, node->prop, node->name, params + node->prop->offset_internal, true); - if (result) { - QUEUE_PUSH(dialog->first_result, dialog->last_result, result); + if (node->role == UNREAL_FUNC_PARAM_OUTPUT || node->role == UNREAL_FUNC_PARAM_RETURN) { + call_result_t *result = call_result_snapshot(dialog, node->prop, node->name, params + node->prop->offset_internal); + if (result) { + QUEUE_PUSH(dialog->first_result, dialog->last_result, result); + } } } + call_status_set(dialog, false, "Call completed"); } } @@ -1073,7 +1007,6 @@ call_execute(search_tool_t *tool, ufunc_call_dialog_t *dialog) } } scratch_end(tmp); -#endif } bool @@ -1112,7 +1045,11 @@ ufunc_call_open(search_tool_t *tool, record_t *func_record, record_t *suggested_ ufunc_call_dialog_t *dialog = tool->call_dialog; ufunc_t *func = (ufunc_t *)func_record->obj; - uobject_t *outer = func ? func->outer : NULL; + uobject_t *outer = NULL; + if (func) { + outer = func->outer; + } + if (!func || !outer || !unreal_uobject_is_a(outer, globals.unreal.core_class)) { call_status_set(dialog, true, "UFunction has no valid owning UClass"); return; @@ -1124,7 +1061,6 @@ ufunc_call_open(search_tool_t *tool, record_t *func_record, record_t *suggested_ dialog->receiver_class = (uclass_t *)outer; dialog->picker.ref = NULL; dialog->picker.soft_input = NULL; - dialog->picker.generation = UINT64_MAX; nk_grid_state_reset(&dialog->target_grid); nk_grid_state_reset(&dialog->input_grid); @@ -1148,9 +1084,11 @@ ufunc_call_close(search_tool_t *tool) return; } - tool->call_dialog->open = false; - tool->call_dialog->picker.ref = NULL; - tool->call_dialog->picker.soft_input = NULL; + tool->call_dialog->open = false; + tool->call_dialog->picker.ref = NULL; + tool->call_dialog->picker.soft_input = NULL; + tool->call_dialog->picker.active_this_frame = false; + tool->call_dialog->picker.active_last_frame = false; } void @@ -1184,41 +1122,106 @@ static void call_picker_activate(search_tool_t *tool, ufunc_call_dialog_t *dialog, call_object_ref_t *ref, - fprop_t *soft_prop, char *soft_input, uclass_t *required_class, bool class_values, + bool interface_values, bool allow_none) +{ + call_picker_t *picker = &dialog->picker; + bool newly_opened = !picker->active_last_frame; + + picker->active_this_frame = true; + if (newly_opened || + picker->ref != ref || + picker->soft_input != soft_input || + picker->required_class != required_class || + picker->class_values != class_values || + picker->interface_values != interface_values || + picker->allow_none != allow_none) { + picker->ref = ref; + picker->soft_input = soft_input; + picker->required_class = required_class; + picker->class_values = class_values; + picker->interface_values = interface_values; + picker->allow_none = allow_none; + picker->search[0] = '\0'; + picker->filtered_search[0] = '\0'; + picker->count = 0; + picker->scan_cursor = 0; + picker->scan_total = tool->cache.live_slots.count; + picker->scan_instance_slot = RECORD_SLOT_INVALID; + picker->scan_complete = required_class == NULL || picker->scan_total == 0; + picker->match_count = 0; + picker->filter_cursor = 0; + picker->filter_complete = false; + picker->matches_truncated = false; + } +} + +static void +call_picker_filter_tick(search_tool_t *tool, ufunc_call_dialog_t *dialog) { call_picker_t *picker = &dialog->picker; + str_t search = str_from_cstr_with_cap(picker->search, sizeof(picker->search)); + str_t filtered = str_from_cstr_with_cap(picker->filtered_search, sizeof(picker->filtered_search)); + if (!str_equal(search, filtered, 0)) { + str_write_fmt(picker->filtered_search, sizeof(picker->filtered_search), "%.*s", STR_ARG(search)); + picker->match_count = 0; + picker->filter_cursor = 0; + picker->filter_complete = false; + picker->matches_truncated = false; + } - if (picker->ref != ref || - picker->soft_input != soft_input || - picker->required_class != required_class || - picker->class_values != class_values || - picker->allow_none != allow_none) { - picker->ref = ref; - picker->soft_prop = soft_prop; - picker->soft_input = soft_input; - picker->required_class = required_class; - picker->class_values = class_values; - picker->allow_none = allow_none; - picker->search[0] = '\0'; - picker->generation = UINT64_MAX; + if (picker->filter_complete && picker->filter_cursor >= picker->count) { + return; } - if (picker->generation != tool->cache.generation) { - call_picker_rebuild(tool, dialog); + uint64_t start_us = time_now_us(); + uint32_t work = 0; + bool budget_exhausted = false; + tmp_arena_t tmp = scratch_begin(NULL); + while (picker->filter_cursor < picker->count && picker->match_count < CALL_MAX_PICKER_RESULTS && !budget_exhausted) { + uint32_t slot = picker->slots[picker->filter_cursor++]; + record_t *record = record_from_slot(tool, slot); + if (record && record_has_flag(record, RECORD_FLAG_LIVE) && record->obj && + call_candidate_matches(record->obj, picker->required_class, picker->class_values, picker->interface_values)) { + bool matches = str_is_empty(search); + if (!matches) { + str_t full_name = unreal_uobject_push_full_name(record->obj, tmp.arena); + matches = str_find(full_name, search, STR_CMP_FLAG_IGNORE_CASE, NULL); + } + + if (matches) { + picker->match_slots[picker->match_count++] = slot; + } + } + + work += 1; + if ((work & 63u) == 0 && time_now_us() - start_us >= CALL_PICKER_BUDGET_US) { + budget_exhausted = true; + } + } + scratch_end(tmp); + + if (picker->match_count == CALL_MAX_PICKER_RESULTS) { + picker->matches_truncated = true; + picker->filter_complete = true; + } else { + picker->filter_complete = picker->scan_complete && picker->filter_cursor >= picker->count; } } static void -call_draw_popup_tooltip(struct nk_context *ctx, struct nk_rect owner_bounds, struct nk_rect anchor, str_t text) +call_draw_popup_tooltip(struct nk_context *ctx, struct nk_rect owner_bounds, call_picker_tooltip_t *tooltip) { - if (!ctx || str_is_empty(text)) { + if (!ctx || !ctx->current || !ctx->current->popup.active || tooltip->text[0] == '\0') { return; } + str_t text = str_from_cstr_with_cap(tooltip->text, sizeof(tooltip->text)); + struct nk_rect anchor = tooltip->anchor; + struct { int offset; int len; @@ -1246,7 +1249,12 @@ call_draw_popup_tooltip(struct nk_context *ctx, struct nk_rect owner_bounds, str line_width = nk_text_width(ctx, ctx->style.font, ctx->style.font_size, (const char *)text.data + offset, end - offset); if (line_width > max_text_width) { - end = (last_break > offset) ? last_break : NK_MAX(offset + 1, end - 1); + if (last_break > offset) { + end = last_break; + } else { + end = NK_MAX(offset + 1, end - 1); + } + line_width = nk_text_width(ctx, ctx->style.font, ctx->style.font_size, (const char *)text.data + offset, end - offset); break; } @@ -1282,21 +1290,25 @@ call_draw_popup_tooltip(struct nk_context *ctx, struct nk_rect owner_bounds, str nk_draw_text(out, label, (const char *)text.data + lines[i].offset, lines[i].len, ctx->style.font, UI_C_BG_PANEL, UI_C_TEXT); } nk_push_scissor(out, old_clip); + + /* NOTE: keep these commands in the popup range, which Nuklear draws above the parent window */ + nk_finish_popup(ctx, ctx->current); } static bool -call_picker_draw_contents(search_tool_t *tool, ufunc_call_dialog_t *dialog) +call_picker_draw_contents(search_tool_t *tool, ufunc_call_dialog_t *dialog, call_picker_tooltip_t *tooltip) { struct nk_context *ctx = tool->ctx; call_picker_t *picker = &dialog->picker; - bool selected = false; - char hovered_full_name[CALL_TEXT_CAP] = {0}; - struct nk_rect hovered_bounds = {0}; + bool selected = false; nk_layout_row_dynamic(ctx, 24.0f, 1); nk_edit_string_zero_terminated(ctx, NK_EDIT_FIELD, picker->search, sizeof(picker->search), nk_filter_default); + call_picker_rebuild_tick(tool, dialog); + call_picker_filter_tick(tool, dialog); + if (picker->allow_none) { nk_layout_row_dynamic(ctx, 22.0f, 1); if (nk_button_label(ctx, "None")) { @@ -1309,41 +1321,38 @@ call_picker_draw_contents(search_tool_t *tool, ufunc_call_dialog_t *dialog) } } - str_t query = str_from_cstr_with_cap(picker->search, sizeof(picker->search)); - int shown = 0; - - for (uint32_t i = 0; i < picker->count && shown < 256; ++i) { - uint32_t slot = picker->slots[i]; + for (uint32_t i = 0; i < picker->match_count; ++i) { + uint32_t slot = picker->match_slots[i]; record_t *record = record_from_slot(tool, slot); - if (!record || !record_has_flag(record, RECORD_FLAG_LIVE) || !record->obj) { + if (!record || !record_has_flag(record, RECORD_FLAG_LIVE) || !record->obj || + !call_candidate_matches(record->obj, picker->required_class, picker->class_values, picker->interface_values)) { continue; } tmp_arena_t tmp = scratch_begin(NULL); { - str_t full_name = unreal_uobject_push_full_name(record->obj, tmp.arena); - str_t name = unreal_uobject_push_name(record->obj, tmp.arena); - bool matches = str_is_empty(query) || str_find(full_name, query, STR_CMP_FLAG_IGNORE_CASE, NULL); - if (matches) { - struct nk_color object_color = uobject_kind_color(record->kind); + str_t name = unreal_uobject_push_name(record->obj, tmp.arena); + struct nk_color object_color = uobject_kind_color(record->kind); - nk_layout_row_dynamic(ctx, 22.0f, 1); - struct nk_rect item_bounds = nk_widget_bounds(ctx); - bool hovered = nk_widget_is_hovered(ctx); + nk_layout_row_dynamic(ctx, 22.0f, 1); + struct nk_rect item_bounds = nk_widget_bounds(ctx); + bool hovered = nk_widget_is_hovered(ctx); - nk_style_push_color(ctx, &ctx->style.button.text_normal, object_color); - nk_style_push_color(ctx, &ctx->style.button.text_hover, object_color); - nk_style_push_color(ctx, &ctx->style.button.text_active, object_color); + nk_style_push_color(ctx, &ctx->style.button.text_normal, object_color); + nk_style_push_color(ctx, &ctx->style.button.text_hover, object_color); + nk_style_push_color(ctx, &ctx->style.button.text_active, object_color); - bool pressed = nk_button_text(ctx, (const char *)name.data, (int)name.len); + bool pressed = nk_button_text(ctx, (const char *)name.data, (int)name.len); - nk_style_pop_color(ctx); - nk_style_pop_color(ctx); - nk_style_pop_color(ctx); + nk_style_pop_color(ctx); + nk_style_pop_color(ctx); + nk_style_pop_color(ctx); + if (hovered || pressed) { + str_t full_name = unreal_uobject_push_full_name(record->obj, tmp.arena); if (hovered) { - str_write_fmt(hovered_full_name, sizeof(hovered_full_name), "%.*s", STR_ARG(full_name)); - hovered_bounds = item_bounds; + str_write_fmt(tooltip->text, sizeof(tooltip->text), "%.*s", STR_ARG(full_name)); + tooltip->anchor = item_bounds; } if (pressed) { @@ -1354,23 +1363,22 @@ call_picker_draw_contents(search_tool_t *tool, ufunc_call_dialog_t *dialog) } selected = true; } - shown += 1; } } scratch_end(tmp); } - if (shown >= 256) { + if (!picker->scan_complete || !picker->filter_complete) { + nk_layout_row_dynamic(ctx, 20.0f, 1); + nk_labelf_colored(ctx, NK_TEXT_CENTERED, UI_C_TEXT_MUTED, "Searching... %u candidates", picker->count); + } else if (picker->matches_truncated) { nk_layout_row_dynamic(ctx, 20.0f, 1); nk_label_colored(ctx, "More matches exist; narrow the search.", NK_TEXT_CENTERED, UI_C_TEXT_MUTED); - } else if (shown == 0 && !(picker->allow_none && str_is_empty(query))) { + } else if (picker->match_count == 0) { nk_layout_row_dynamic(ctx, 20.0f, 1); nk_label_colored(ctx, "No loaded matches", NK_TEXT_CENTERED, UI_C_TEXT_MUTED); } - if (hovered_full_name[0] != '\0') { - call_draw_popup_tooltip(ctx, dialog->bounds, hovered_bounds, str_from_cstr_with_cap(hovered_full_name, sizeof(hovered_full_name))); - } return selected; } @@ -1380,15 +1388,17 @@ call_draw_object_combo(search_tool_t *tool, call_object_ref_t *ref, uclass_t *required_class, bool class_values, + bool interface_values, bool allow_none) { tmp_arena_t tmp = scratch_begin(NULL); { - str_t label = call_object_ref_label(tool, ref, tmp.arena); - float width = NK_MAX(260.0f, nk_widget_width(tool->ctx)); - struct nk_color label_color = ref && !ref->is_none && call_record_is_live_object(tool, ref->slot, ref->expected) - ? uobject_kind_color(uobject_kind(ref->expected)) - : UI_C_TEXT_DIM; + str_t label = call_object_ref_label(tool, ref, tmp.arena); + float width = NK_MAX(260.0f, nk_widget_width(tool->ctx)); + struct nk_color label_color = UI_C_TEXT_DIM; + if (ref && !ref->is_none && call_record_is_live_object(tool, ref->slot, ref->expected)) { + label_color = uobject_kind_color(uobject_kind(ref->expected)); + } nk_style_push_color(tool->ctx, &tool->ctx->style.combo.label_normal, label_color); nk_style_push_color(tool->ctx, &tool->ctx->style.combo.label_hover, label_color); @@ -1407,11 +1417,14 @@ call_draw_object_combo(search_tool_t *tool, } if (open) { - call_picker_activate(tool, dialog, ref, NULL, NULL, required_class, class_values, allow_none); - if (call_picker_draw_contents(tool, dialog)) { + call_picker_tooltip_t tooltip = {0}; + call_picker_activate(tool, dialog, ref, NULL, required_class, class_values, interface_values, allow_none); + if (call_picker_draw_contents(tool, dialog, &tooltip)) { nk_combo_close(tool->ctx); } + nk_combo_end(tool->ctx); + call_draw_popup_tooltip(tool->ctx, dialog->bounds, &tooltip); } } scratch_end(tmp); @@ -1445,11 +1458,14 @@ call_draw_soft_value(search_tool_t *tool, ufunc_call_dialog_t *dialog, call_valu nk_layout_row_push(ctx, picker_w); if (nk_combo_begin_label(ctx, "...", nk_vec2(440.0f, 360.0f))) { - call_picker_activate(tool, dialog, &node->object_ref, node->prop, node->input, call_node_required_class(node), node->class_picker, true); - if (call_picker_draw_contents(tool, dialog)) { + call_picker_tooltip_t tooltip = {0}; + call_picker_activate(tool, dialog, &node->object_ref, node->input, unreal_fprop_get_reference_class(node->prop), node->class_picker, false, true); + if (call_picker_draw_contents(tool, dialog, &tooltip)) { nk_combo_close(ctx); } + nk_combo_end(ctx); + call_draw_popup_tooltip(ctx, dialog->bounds, &tooltip); } } nk_layout_row_end(ctx); @@ -1461,8 +1477,8 @@ static void call_grid_begin(struct nk_context *ctx, struct nk_grid *grid, struct nk_grid_state *state, float row_height) { static const struct nk_grid_column columns[] = { - {.sizing = NK_GRID_COLUMN_CONTENT, .min_width = 80.0f}, - {.sizing = NK_GRID_COLUMN_CONTENT, .min_width = 72.0f}, + {.sizing = NK_GRID_COLUMN_CONTENT, .min_width = 80.0f }, + {.sizing = NK_GRID_COLUMN_CONTENT, .min_width = 72.0f }, {.sizing = NK_GRID_COLUMN_FLEX, .min_width = 160.0f}, }; @@ -1530,11 +1546,7 @@ call_tree_button(struct nk_context *ctx, str_t title) } static void -call_draw_value_row(search_tool_t *tool, - ufunc_call_dialog_t *dialog, - struct nk_grid_state *grid_state, - call_value_t *node, - int32_t depth) +call_draw_value_row(search_tool_t *tool, ufunc_call_dialog_t *dialog, struct nk_grid_state *grid_state, call_value_t *node, int32_t depth) { struct nk_context *ctx = tool->ctx; @@ -1546,7 +1558,7 @@ call_draw_value_row(search_tool_t *tool, nk_grid_row_begin(&grid); if (node->kind != CALL_VALUE_LEAF) { - str_t title = str_push_fmt(tmp.arena, "%s %.*s", node->expanded ? "-" : "+", STR_ARG(node->type)); + str_t title = str_push_fmt(tmp.arena, "%s %.*s", call_tree_prefix(node->expanded), STR_ARG(node->type)); float width = ui_text_width(ctx, title) + 2.0f * ctx->style.button.padding.x; nk_grid_push(&grid, 0, nk_vec2(width, ctx->style.font_size)); if (call_tree_button(ctx, title)) { @@ -1561,14 +1573,18 @@ call_draw_value_row(search_tool_t *tool, nk_grid_push(&grid, 2, nk_vec2(0.0f, 22.0f)); if (!node->supported) { nk_label_colored(ctx, "", NK_TEXT_LEFT, UI_C_RED); - } else if (node->kind == CALL_VALUE_ARRAY) { + } else if (call_value_kind_is_dynamic_container(node->kind)) { nk_spacer(ctx); } else if (node->kind == CALL_VALUE_FIXED_ARRAY) { nk_labelf_selectable_colored(ctx, NK_TEXT_LEFT, CALL_C_VALUE_TEXT, "Num=%d", node->child_count); - } else if (node->kind == CALL_VALUE_STRUCT) { + } else if (node->kind == CALL_VALUE_STRUCT || node->kind == CALL_VALUE_MAP_PAIR) { nk_label_selectable_colored(ctx, "{...}", NK_TEXT_LEFT, CALL_C_VALUE_TEXT); } else if (node->auto_world) { - uworld_t *world = globals.gworld_ptr ? *globals.gworld_ptr : NULL; + uworld_t *world = NULL; + if (globals.gworld_ptr) { + world = *globals.gworld_ptr; + } + if (world && unreal_uobject_is_valid((uobject_t *)world)) { str_t name = unreal_uobject_push_name((uobject_t *)world, tmp.arena); str_t full_name = unreal_uobject_push_full_name((uobject_t *)world, tmp.arena); @@ -1579,9 +1595,8 @@ call_draw_value_row(search_tool_t *tool, } else { nk_label_colored(ctx, "", NK_TEXT_LEFT, UI_C_RED); } - } else if (unreal_fprop_class_is(node->prop, globals.unreal.obj_prop) || - unreal_fprop_class_is(node->prop, globals.unreal.class_prop)) { - call_draw_object_combo(tool, dialog, &node->object_ref, call_node_required_class(node), node->class_picker, true); + } else if (call_prop_kind_uses_object_picker(unreal_fprop_get_kind(node->prop))) { + call_draw_object_combo(tool, dialog, &node->object_ref, unreal_fprop_get_reference_class(node->prop), node->class_picker, node->interface_picker, true); } else if (node->soft_picker) { call_draw_soft_value(tool, dialog, node); } else { @@ -1597,7 +1612,7 @@ call_draw_value_row(search_tool_t *tool, return; } - if (node->kind == CALL_VALUE_ARRAY) { + if (call_value_kind_is_dynamic_container(node->kind)) { tmp_arena_t label_tmp = scratch_begin(NULL); { struct nk_grid grid; @@ -1614,7 +1629,7 @@ call_draw_value_row(search_tool_t *tool, } scratch_end(label_tmp); - call_array_sync(dialog, node); + call_container_sync(dialog, node); int32_t idx = 0; for (call_value_t *child = node->first_child; child && idx < node->array_count; child = child->next, ++idx) { @@ -1628,22 +1643,25 @@ call_draw_value_row(search_tool_t *tool, } static void -call_draw_result_row(search_tool_t *tool, - struct nk_grid_state *grid_state, - call_result_t *result, - int32_t depth) +call_draw_result_row(search_tool_t *tool, struct nk_grid_state *grid_state, call_result_t *result, int32_t depth) { struct nk_context *ctx = tool->ctx; tmp_arena_t tmp = scratch_begin(NULL); { str_t indented_name = str_push_fmt(tmp.arena, "%*s%.*s", depth * 2, "", STR_ARG(result->name)); + str_t value = result->value; + if (result->truncated) { + const char *suffix = str_is_empty(value) ? "truncated" : " [truncated]"; + value = str_push_fmt(tmp.arena, "%.*s%s", STR_ARG(value), suffix); + } + struct nk_grid grid; call_grid_begin(ctx, &grid, grid_state, 24.0f); nk_grid_row_begin(&grid); if (result->first_child) { - str_t title = str_push_fmt(tmp.arena, "%s %.*s", result->expanded ? "-" : "+", STR_ARG(result->type)); + str_t title = str_push_fmt(tmp.arena, "%s %.*s", call_tree_prefix(result->expanded), STR_ARG(result->type)); float width = ui_text_width(ctx, title) + 2.0f * ctx->style.button.padding.x; nk_grid_push(&grid, 0, nk_vec2(width, ctx->style.font_size)); if (call_tree_button(ctx, title)) { @@ -1655,16 +1673,9 @@ call_draw_result_row(search_tool_t *tool, call_grid_text(&grid, 1, indented_name, UI_C_TEXT); - nk_grid_push(&grid, 2, nk_vec2(0.0f, 22.0f)); - call_edit_colored(ctx, - (nk_flags)NK_EDIT_FIELD | (nk_flags)NK_EDIT_READ_ONLY, - result->value, - sizeof(result->value), - nk_filter_default, - CALL_C_VALUE_TEXT); - if (result->tooltip[0] != '\0' && nk_widget_is_hovered(ctx)) { - str_t tooltip = str_from_cstr_with_cap(result->tooltip, sizeof(result->tooltip)); - nk_tooltip_text(ctx, (const char *)tooltip.data, (int)tooltip.len); + call_grid_text(&grid, 2, value, CALL_C_VALUE_TEXT); + if (!str_is_empty(result->tooltip) && nk_widget_is_hovered(ctx)) { + nk_tooltip_text(ctx, (const char *)result->tooltip.data, (int)result->tooltip.len); } nk_grid_row_end(&grid); nk_grid_end(&grid); @@ -1682,7 +1693,7 @@ static bool call_has_input_params(ufunc_call_dialog_t *dialog) { for (call_value_t *node = dialog->first_param; node; node = node->next) { - if (node->role == CALL_PARAM_INPUT) { + if (node->role == UNREAL_FUNC_PARAM_INPUT) { return true; } } @@ -1693,7 +1704,7 @@ static bool call_has_output_params(ufunc_call_dialog_t *dialog) { for (call_value_t *node = dialog->first_param; node; node = node->next) { - if (node->role == CALL_PARAM_OUTPUT || node->role == CALL_PARAM_RETURN) { + if (node->role == UNREAL_FUNC_PARAM_OUTPUT || node->role == UNREAL_FUNC_PARAM_RETURN) { return true; } } @@ -1761,6 +1772,7 @@ ufunc_call_draw(search_tool_t *tool, unsigned int vw, unsigned int vh) ufunc_call_dialog_t *dialog = tool->call_dialog; struct nk_context *ctx = tool->ctx; const char *window_name = "uobject_search.ufunction_call"; + dialog->picker.active_this_frame = false; if (nk_window_is_active(ctx, "uobject_search")) { nk_window_set_focus(ctx, window_name); @@ -1775,9 +1787,10 @@ ufunc_call_draw(search_tool_t *tool, unsigned int vw, unsigned int vh) } tmp_arena_t title_tmp = scratch_begin(NULL); - str_t func_name = (dialog->func_expected && unreal_uobject_is_valid((uobject_t *)dialog->func_expected)) - ? unreal_uobject_push_full_name((uobject_t *)dialog->func_expected, title_tmp.arena) - : STR_LIT(""); + str_t func_name = STR_LIT(""); + if (dialog->func_expected && unreal_uobject_is_valid((uobject_t *)dialog->func_expected)) { + func_name = unreal_uobject_push_full_name((uobject_t *)dialog->func_expected, title_tmp.arena); + } str_t title = str_push_fmt(title_tmp.arena, "Call %.*s", STR_ARG(func_name)); nk_flags flags = NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE | NK_WINDOW_TITLE | NK_WINDOW_CLOSABLE | NK_WINDOW_NO_SCROLLBAR; @@ -1799,16 +1812,19 @@ ufunc_call_draw(search_tool_t *tool, unsigned int vw, unsigned int vh) tmp_arena_t target_tmp = scratch_begin(NULL); { struct nk_grid grid; - str_t target_type = dialog->receiver_class - ? str_push_fmt(target_tmp.arena, "Object<%.*s>", STR_ARG(unreal_uobject_push_name((uobject_t *)dialog->receiver_class, target_tmp.arena))) - : STR_LIT("Object" ); + str_t target_type = STR_LIT("Object"); + if (dialog->receiver_class) { + str_t receiver_name = unreal_uobject_push_name((uobject_t *)dialog->receiver_class, target_tmp.arena); + target_type = str_push_fmt(target_tmp.arena, "Object<%.*s>", STR_ARG(receiver_name)); + } + call_target_grid_begin(ctx, &grid, &dialog->target_grid, 26.0f); { nk_grid_row_begin(&grid); { call_grid_text(&grid, 0, target_type, CALL_C_TYPE_TEXT); nk_grid_push(&grid, 1, nk_vec2(0.0f, 24.0f)); - call_draw_object_combo(tool, dialog, &dialog->target, dialog->receiver_class, false, false); + call_draw_object_combo(tool, dialog, &dialog->target, dialog->receiver_class, false, false, false); } nk_grid_row_end(&grid); } @@ -1835,7 +1851,7 @@ ufunc_call_draw(search_tool_t *tool, unsigned int vw, unsigned int vh) if (call_has_input_params(dialog)) { for (call_value_t *node = dialog->first_param; node; node = node->next) { - if (node->role == CALL_PARAM_INPUT) { + if (node->role == UNREAL_FUNC_PARAM_INPUT) { call_draw_value_row(tool, dialog, &dialog->input_grid, node, 0); } } @@ -1857,16 +1873,23 @@ ufunc_call_draw(search_tool_t *tool, unsigned int vw, unsigned int vh) } } else { nk_layout_row_dynamic(ctx, 22.0f, 1); - nk_label_colored(ctx, - call_has_output_params(dialog) ? "Call the function to populate output values" : "No return/out parameters", - NK_TEXT_CENTERED, - UI_C_TEXT_MUTED); + const char *placeholder = "No return/out parameters"; + if (call_has_output_params(dialog)) { + placeholder = "Call the function to populate output values"; + } + + nk_label_colored(ctx, placeholder, NK_TEXT_CENTERED, UI_C_TEXT_MUTED); } nk_group_end(ctx); } nk_layout_row_dynamic(ctx, status_h, 1); - nk_label_colored(ctx, dialog->status, NK_TEXT_CENTERED, dialog->status_is_error ? UI_C_RED : CALL_C_VALUE_TEXT); + struct nk_color status_color = CALL_C_VALUE_TEXT; + if (dialog->status_is_error) { + status_color = UI_C_RED; + } + + nk_label_colored(ctx, dialog->status, NK_TEXT_CENTERED, status_color); nk_layout_row_dynamic(ctx, buttons_h, 2); @@ -1903,6 +1926,7 @@ ufunc_call_draw(search_tool_t *tool, unsigned int vw, unsigned int vh) nk_spacer(ctx); } nk_end(ctx); + dialog->picker.active_last_frame = dialog->picker.active_this_frame; scratch_end(title_tmp); if (nk_window_is_closed(ctx, window_name)) { diff --git a/src/builtin/ufunction_tracer.c b/src/builtin/ufunction_tracer.c index 113fb07..66445f7 100644 --- a/src/builtin/ufunction_tracer.c +++ b/src/builtin/ufunction_tracer.c @@ -13,6 +13,7 @@ #include "types.h" #include "ui_nuklear.h" #include "unreal.h" +#include "unreal_prop.h" #include "vendor_nuklear.h" #include "vendor_stb.h" @@ -31,6 +32,12 @@ #define TRACE_FILTER_TEXT_CAP (4 * KB) #define TRACE_FILTER_RULE_MAX (128) +#define TRACE_PARAMETER_MAX_DEPTH (8) +#define TRACE_PARAMETER_MAX_ELEMENTS (64) +#define TRACE_PARAMETER_MAX_NODES (256) +#define TRACE_PARAMETER_MAX_TEXT_LENGTH (512) +#define TRACE_PARAMETER_MEMORY_LIMIT (64 * MB) + #define TRACE_CALL_COL_COUNT (8) #define TRACE_CALL_COL_SEQ "SEQ" #define TRACE_CALL_COL_TIME "TIME" @@ -51,6 +58,15 @@ enum { TRACE_HOOK_INVOKE = 1, }; +typedef uint8_t trace_parameter_state_t; +enum { + TRACE_PARAMETERS_NONE = 0, + TRACE_PARAMETERS_AVAILABLE, + TRACE_PARAMETERS_INVOKE_UNAVAILABLE, + TRACE_PARAMETERS_INVALID, + TRACE_PARAMETERS_MEMORY_LIMIT, +}; + typedef uint8_t trace_filter_sign_t; enum { TRACE_FILTER_SIGN_NONE, @@ -126,10 +142,20 @@ struct trace_call_s { ui_text_span_t self_name; ui_text_span_t func_name; - uint8_t source_flags; - uint8_t consumed_flags; - uobject_kind_t self_kind; - bool maximized; + unreal_prop_snapshot_t *first_input; + unreal_prop_snapshot_t *last_input; + unreal_prop_snapshot_t *first_output; + unreal_prop_snapshot_t *last_output; + unreal_prop_snapshot_t *first_return; + unreal_prop_snapshot_t *last_return; + + uint32_t parameter_node_count; + trace_parameter_state_t parameter_state; + uint8_t source_flags; + uint8_t consumed_flags; + uobject_kind_t self_kind; + bool parameters_truncated; + bool maximized; }; typedef struct trace_frame_s trace_frame_t; @@ -162,18 +188,21 @@ struct trace_ui_s { uint32_t page_idx; arena_t page_arena; - ui_text_span_t seq; - ui_text_span_t time; - ui_text_span_t duration; - ui_text_span_t depth; - ui_text_span_t kind; - ui_text_span_t class_name; - ui_text_span_t self_name; - ui_text_span_t func_name; - ui_text_span_t kind_pe; - ui_text_span_t kind_invoke; - ui_text_span_t kind_pe_and_invoke; - struct nk_grid_state call_grid; + ui_text_span_t seq; + ui_text_span_t time; + ui_text_span_t duration; + ui_text_span_t depth; + ui_text_span_t kind; + ui_text_span_t class_name; + ui_text_span_t self_name; + ui_text_span_t func_name; + ui_text_span_t kind_pe; + ui_text_span_t kind_invoke; + ui_text_span_t kind_pe_and_invoke; + struct nk_grid_state call_grid; + struct nk_grid_state parameter_grid; + ui_nk_splitter_state_t parameter_splitter; + trace_call_t *selected_call; }; typedef struct trace_cfg_s trace_cfg_t; @@ -205,6 +234,7 @@ struct trace_tool_s { uint32_t call_count; uint32_t max_call_count; uint32_t seq_counter; + uint64_t parameter_bytes; bool capture_full; bool clear_pending; @@ -306,6 +336,10 @@ trace_call_alloc(trace_tool_t *tool) tool->last_call = call; tool->call_count += 1; + if (!tool->ui.selected_call) { + tool->ui.selected_call = call; + } + return call; } @@ -556,6 +590,112 @@ trace_call_cache_names(trace_tool_t *tool, trace_call_t *call) } } +static bool +trace_parameter_layout_is_valid(ufunc_t *func, fprop_t *prop) +{ + if (!func || !prop || prop->offset_internal < 0 || prop->elem_size <= 0 || prop->array_dim <= 0) { + return false; + } + + uint64_t end = (uint64_t)prop->offset_internal + unreal_fprop_complete_size(prop); + return end <= func->params_size; +} + +static void +trace_parameter_push(trace_call_t *call, unreal_func_param_role_t role, unreal_prop_snapshot_t *snapshot) +{ + if (role == UNREAL_FUNC_PARAM_INPUT) { + QUEUE_PUSH(call->first_input, call->last_input, snapshot); + } else if (role == UNREAL_FUNC_PARAM_OUTPUT) { + QUEUE_PUSH(call->first_output, call->last_output, snapshot); + } else { + QUEUE_PUSH(call->first_return, call->last_return, snapshot); + } +} + +static bool +trace_parameter_should_capture(unreal_func_param_role_t role, bool capture_inputs) +{ + if (capture_inputs) { + return role == UNREAL_FUNC_PARAM_INPUT; + } + + return role == UNREAL_FUNC_PARAM_OUTPUT || role == UNREAL_FUNC_PARAM_RETURN; +} + +static void +trace_parameters_capture(trace_tool_t *tool, trace_call_t *call, const void *params, bool capture_inputs) +{ + if (!tool || !call || !call->func || call->parameter_state != TRACE_PARAMETERS_AVAILABLE) { + return; + } + + if (call->func->params_size > 0 && !params) { + call->parameter_state = TRACE_PARAMETERS_INVALID; + return; + } + + if (tool->parameter_bytes >= TRACE_PARAMETER_MEMORY_LIMIT) { + if (call->parameter_node_count > 0) { + call->parameters_truncated = true; + } else { + call->parameter_state = TRACE_PARAMETERS_MEMORY_LIMIT; + } + + return; + } + + unreal_prop_snapshot_builder_t builder = {0}; + unreal_prop_snapshot_builder_init(&builder, tool->perm); + builder.max_depth = TRACE_PARAMETER_MAX_DEPTH; + builder.max_container_elements = TRACE_PARAMETER_MAX_ELEMENTS; + builder.max_text_length = TRACE_PARAMETER_MAX_TEXT_LENGTH; + + if (call->parameter_node_count < TRACE_PARAMETER_MAX_NODES) { + builder.max_nodes = TRACE_PARAMETER_MAX_NODES - call->parameter_node_count; + } else { + builder.max_nodes = 0; + } + + uint64_t memory_before = arena_get_used(tool->perm); + for (ffield_t *field = call->func->child_props; field; field = field->next) { + fprop_t *prop = (fprop_t *)field; + if (!(prop->prop_flags & CPF_PARM)) { + continue; + } + + unreal_func_param_role_t role = unreal_fprop_get_param_role(prop); + if (!trace_parameter_should_capture(role, capture_inputs)) { + continue; + } + + if (!trace_parameter_layout_is_valid(call->func, prop)) { + call->parameter_state = TRACE_PARAMETERS_INVALID; + break; + } + + unreal_prop_snapshot_t *snapshot = NULL; + tmp_arena_t tmp = scratch_begin(tool->perm); + { + str_t name = unreal_fname_to_str(prop->name, tmp.arena); + const void *value = (const uint8_t *)params + prop->offset_internal; + snapshot = unreal_fprop_snapshot_build(&builder, prop, name, value); + } + scratch_end(tmp); + + if (!snapshot) { + call->parameters_truncated = true; + break; + } + + trace_parameter_push(call, role, snapshot); + } + + call->parameter_node_count += builder.node_count; + call->parameters_truncated = call->parameters_truncated || builder.truncated; + tool->parameter_bytes += arena_get_used(tool->perm) - memory_before; +} + static trace_call_t * trace_logical_call_begin(trace_tool_t *tool, uobject_t *self, ufunc_t *func, uint8_t source) { @@ -577,16 +717,15 @@ trace_logical_call_begin(trace_tool_t *tool, uobject_t *self, ufunc_t *func, uin return NULL; } - call->start_us = time_now_us(); - call->end_us = call->start_us; - call->depth = depth; - call->self = self; - call->func = func; - call->self_fname = self->name; - call->class_fname = self->cls ? self->cls->name : (fname_t){0}; - call->func_fname = func->name; - call->self_kind = uobject_kind(self); - call->source_flags = source; + call->depth = depth; + call->self = self; + call->func = func; + call->self_fname = self->name; + call->class_fname = self->cls ? self->cls->name : (fname_t){0}; + call->func_fname = func->name; + call->self_kind = uobject_kind(self); + call->source_flags = source; + call->parameter_state = TRACE_PARAMETERS_NONE; trace_call_link(tool, call, tool->active_captured_call); @@ -602,8 +741,6 @@ trace_logical_call_end(trace_tool_t *tool, trace_call_t *call) if (call) { ASSERT(tool->active_captured_call == call); - call->end_us = time_now_us(); - tool->active_captured_call = call->parent; } @@ -622,13 +759,17 @@ trace_clear_now(trace_tool_t *tool) tool->last_root = NULL; tool->active_captured_call = NULL; - tool->frame_free = NULL; - tool->logical_depth = 0; - tool->call_count = 0; - tool->seq_counter = 0; - tool->capture_full = false; - tool->clear_pending = false; - tool->ui.page_idx = 0; + tool->frame_free = NULL; + tool->logical_depth = 0; + tool->call_count = 0; + tool->seq_counter = 0; + tool->parameter_bytes = 0; + tool->capture_full = false; + tool->clear_pending = false; + tool->ui.page_idx = 0; + tool->ui.selected_call = NULL; + + nk_grid_state_reset(&tool->ui.parameter_grid); arena_reset(&tool->ui.page_arena); arena_set_used(tool->perm, tool->perm_size); @@ -656,8 +797,10 @@ struct ui_detail_row_s { ui_text_cell_t *parts; int count; bool has_children; + bool selected; int depth; str_t copy_text; + str_t tooltip; }; static str_t @@ -684,7 +827,7 @@ detail_copy_text(struct nk_context *ctx, str_t text) } static bool -ui_detail_row(trace_tool_t *tool, struct nk_grid_state *grid_state, ui_detail_row_t row, bool *maximized) +ui_detail_row(trace_tool_t *tool, struct nk_grid_state *grid_state, ui_detail_row_t row, bool *maximized, bool *pressed) { struct nk_grid_column columns[NK_GRID_MAX_COLUMNS] = {0}; struct nk_grid_options grid_options = {0}; @@ -709,6 +852,10 @@ ui_detail_row(trace_tool_t *tool, struct nk_grid_state *grid_state, ui_detail_ro ASSERT(maximized != NULL); } + if (pressed) { + *pressed = false; + } + ctx = tool->ctx; if (!ctx->current || !ctx->current->layout) { return false; @@ -756,6 +903,10 @@ ui_detail_row(trace_tool_t *tool, struct nk_grid_state *grid_state, ui_detail_ro struct nk_color bg = row.has_children ? DETAIL_C_ROW_COLLAPSIBLE_BG : UI_C_TRANSPARENT; struct nk_rect sym; + if (row.selected) { + bg = DETAIL_C_ROW_COLLAPSIBLE_ACTIVE; + } + row_bounds = bounds; row_bounds.w = grid.offsets[row.count] + grid.widths[row.count]; @@ -765,20 +916,26 @@ ui_detail_row(trace_tool_t *tool, struct nk_grid_state *grid_state, ui_detail_ro in = &ctx->input; } - if (in && row.has_children) { + if (in && (row.has_children || pressed)) { if (nk_button_behavior(&row_state, row_bounds, in, NK_BUTTON_DEFAULT)) { - *maximized = !*maximized; - expanded = *maximized; - view = *maximized ? DETAIL_TREE_ROW_OPEN : DETAIL_TREE_ROW_CLOSED; + if (pressed) { + *pressed = true; + } + + if (row.has_children) { + *maximized = !*maximized; + expanded = *maximized; + view = *maximized ? DETAIL_TREE_ROW_OPEN : DETAIL_TREE_ROW_CLOSED; + } } ctx->last_widget_state = row_state; } - if (row.has_children && row_state & NK_WIDGET_STATE_HOVER) { + if ((row.has_children || pressed) && row_state & NK_WIDGET_STATE_HOVER) { bg = DETAIL_C_ROW_COLLAPSIBLE_HOVER; } - if (row.has_children && row_state & NK_WIDGET_STATE_ACTIVE) { + if ((row.has_children || pressed) && row_state & NK_WIDGET_STATE_ACTIVE) { bg = DETAIL_C_ROW_COLLAPSIBLE_ACTIVE; } @@ -813,6 +970,11 @@ ui_detail_row(trace_tool_t *tool, struct nk_grid_state *grid_state, ui_detail_ro }; ui_grid_str(&grid, i + 1, row.parts[i].text.str, &options); } + + if (!str_is_empty(row.tooltip) && nk_widget_is_hovered(ctx)) { + nk_tooltip_text(ctx, (const char *)row.tooltip.data, (int)row.tooltip.len); + } + nk_grid_row_end(&grid); nk_grid_end(&grid); nk_layout_reset_min_row_height(ctx); @@ -916,10 +1078,15 @@ draw_detail_call(trace_tool_t *tool, trace_call_t *call, int depth) .count = COUNTOF(parts), .depth = depth, .has_children = (call->first_child != NULL), + .selected = tool->ui.selected_call == call, .copy_text = STR_NULL, }; - maximized = ui_detail_row(tool, &tool->ui.call_grid, row, row.has_children ? &call->maximized : NULL); + bool pressed = false; + maximized = ui_detail_row(tool, &tool->ui.call_grid, row, row.has_children ? &call->maximized : NULL, &pressed); + if (pressed) { + tool->ui.selected_call = call; + } } scratch_end(tmp); @@ -930,6 +1097,134 @@ draw_detail_call(trace_tool_t *tool, trace_call_t *call, int depth) } } +static void +trace_draw_parameter_snapshot(trace_tool_t *tool, unreal_prop_snapshot_t *snapshot, int depth) +{ + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t value = snapshot->value; + if (snapshot->truncated) { + value = str_push_fmt(tmp.arena, "%.*s%s", STR_ARG(value), str_is_empty(value) ? "truncated" : " [truncated]"); + } + + struct nk_color value_color = UI_C_PROP_VALUE_TEXT; + if (!str_is_empty(snapshot->tooltip)) { + value_color = UI_C_PROP_LINK_TEXT; + } + + ui_text_cell_t parts[] = { + UI_TEXT_CELL(ui_text_span_make(tool->ctx, snapshot->type), UI_C_PROP_TYPE_TEXT), + UI_TEXT_CELL(ui_text_span_make(tool->ctx, snapshot->name), UI_C_TEXT), + UI_TEXT_CELL(ui_text_span_make(tool->ctx, value), value_color), + }; + + ui_detail_row_t row = { + .parts = parts, + .count = COUNTOF(parts), + .has_children = snapshot->first_child != NULL, + .selected = false, + .depth = depth, + .copy_text = snapshot->value, + .tooltip = snapshot->tooltip, + }; + + bool expanded = ui_detail_row(tool, &tool->ui.parameter_grid, row, row.has_children ? &snapshot->expanded : NULL, NULL); + if (expanded) { + for (unreal_prop_snapshot_t *child = snapshot->first_child; child; child = child->next) { + trace_draw_parameter_snapshot(tool, child, depth + 1); + } + } + } + scratch_end(tmp); +} + +static void +trace_draw_parameter_list(trace_tool_t *tool, const char *label, unreal_prop_snapshot_t *first) +{ + if (!first) { + return; + } + + nk_layout_row_dynamic(tool->ctx, 20.0f, 1); + nk_label(tool->ctx, label, NK_TEXT_LEFT); + + for (unreal_prop_snapshot_t *snapshot = first; snapshot; snapshot = snapshot->next) { + trace_draw_parameter_snapshot(tool, snapshot, 0); + } +} + +static void +trace_draw_parameter_panel(trace_tool_t *tool) +{ + struct nk_context *ctx = tool->ctx; + trace_call_t *call = tool->ui.selected_call; + + if (!call) { + nk_layout_row_dynamic(ctx, 24.0f, 1); + nk_label_colored(ctx, "Select a call to inspect its parameters", NK_TEXT_CENTERED, UI_C_TEXT_MUTED); + return; + } + + nk_layout_row_dynamic(ctx, 22.0f, 1); + nk_labelf(ctx, NK_TEXT_LEFT, "PARAMETERS - CALL #%u", call->seq); + + if (call->parameter_state == TRACE_PARAMETERS_INVOKE_UNAVAILABLE) { + nk_layout_row_dynamic(ctx, 24.0f, 1); + nk_label_colored(ctx, "Parameters unavailable for Invoke-only calls", NK_TEXT_CENTERED, UI_C_TEXT_MUTED); + return; + } + + if (call->parameter_state == TRACE_PARAMETERS_INVALID) { + nk_layout_row_dynamic(ctx, 24.0f, 1); + nk_label_colored(ctx, "Parameters unavailable because the reflected layout is invalid", NK_TEXT_CENTERED, UI_C_RED); + return; + } + + if (call->parameter_state == TRACE_PARAMETERS_MEMORY_LIMIT) { + nk_layout_row_dynamic(ctx, 24.0f, 1); + nk_label_colored(ctx, "Parameters unavailable because the snapshot memory limit was reached", NK_TEXT_CENTERED, UI_C_ORANGE); + return; + } + + if (call->parameter_state != TRACE_PARAMETERS_AVAILABLE) { + nk_layout_row_dynamic(ctx, 24.0f, 1); + nk_label_colored(ctx, "Parameters unavailable", NK_TEXT_CENTERED, UI_C_TEXT_MUTED); + return; + } + + bool has_parameters = call->first_input || call->first_output || call->first_return; + if (!has_parameters) { + nk_layout_row_dynamic(ctx, 24.0f, 1); + nk_label_colored(ctx, "No parameters", NK_TEXT_CENTERED, UI_C_TEXT_MUTED); + return; + } + + ui_text_cell_t header_parts[] = { + UI_TEXT_CELL(ui_text_span_make(ctx, STR_LIT("TYPE")), UI_C_TEXT), + UI_TEXT_CELL(ui_text_span_make(ctx, STR_LIT("NAME")), UI_C_TEXT), + UI_TEXT_CELL(ui_text_span_make(ctx, STR_LIT("VALUE")), UI_C_TEXT), + }; + + ui_detail_row_t header = { + .parts = header_parts, + .count = COUNTOF(header_parts), + .has_children = false, + .selected = false, + .depth = 0, + .copy_text = STR_NULL, + }; + ui_detail_row(tool, &tool->ui.parameter_grid, header, NULL, NULL); + + trace_draw_parameter_list(tool, "INPUTS", call->first_input); + trace_draw_parameter_list(tool, "OUTPUTS", call->first_output); + trace_draw_parameter_list(tool, "RETURN", call->first_return); + + if (call->parameters_truncated) { + nk_layout_row_dynamic(ctx, 22.0f, 1); + nk_label_colored(ctx, "Some parameter values were truncated by capture limits", NK_TEXT_LEFT, UI_C_ORANGE); + } +} + static uint32_t trace_page_count(uint32_t item_count, uint32_t page_size) { @@ -1024,6 +1319,48 @@ trace_draw_filter_dialog(trace_tool_t *tool, struct nk_context *ctx) } } +static void +trace_save_parameter_snapshot(FILE *file, unreal_prop_snapshot_t *snapshot, const char *role, int depth) +{ + fprintf(file, + " %-6s %*s%.*s %.*s = %.*s%s\n", + role, + depth * 2, + "", + STR_ARG(snapshot->type), + STR_ARG(snapshot->name), + STR_ARG(snapshot->value), + snapshot->truncated ? " [truncated]" : ""); + + for (unreal_prop_snapshot_t *child = snapshot->first_child; child; child = child->next) { + trace_save_parameter_snapshot(file, child, "", depth + 1); + } +} + +static void +trace_save_parameter_list(FILE *file, unreal_prop_snapshot_t *first, const char *role) +{ + for (unreal_prop_snapshot_t *snapshot = first; snapshot; snapshot = snapshot->next) { + trace_save_parameter_snapshot(file, snapshot, role, 0); + } +} + +static void +trace_save_parameters(FILE *file, trace_call_t *call) +{ + if (call->parameter_state == TRACE_PARAMETERS_INVOKE_UNAVAILABLE) { + fprintf(file, " parameters unavailable for Invoke-only calls\n"); + } else if (call->parameter_state == TRACE_PARAMETERS_INVALID) { + fprintf(file, " parameters unavailable because the reflected layout is invalid\n"); + } else if (call->parameter_state == TRACE_PARAMETERS_MEMORY_LIMIT) { + fprintf(file, " parameters unavailable because the snapshot memory limit was reached\n"); + } else if (call->parameter_state == TRACE_PARAMETERS_AVAILABLE) { + trace_save_parameter_list(file, call->first_input, "input"); + trace_save_parameter_list(file, call->first_output, "output"); + trace_save_parameter_list(file, call->first_return, "return"); + } +} + static void trace_save(trace_tool_t *tool) { @@ -1095,6 +1432,8 @@ trace_save(trace_tool_t *tool) max_cls_name_len, STR_ARG(class_name), max_obj_name_len, STR_ARG(self_name), STR_ARG(func_name)); + + trace_save_parameters(file, call); } scratch_end(tmp2); } @@ -1230,9 +1569,27 @@ trace_draw_window(trace_tool_t *tool, unsigned int vw, unsigned int vh) nk_layout_row_end(ctx); } - float results_h = nk_layout_get_remaining_height(ctx); + float gap_y = ctx->style.window.spacing.y; + float splitter_h = 8.0f; + float split_area_h = nk_layout_get_remaining_height(ctx); + float panel_area_h = split_area_h - splitter_h - 2.0f * gap_y; + float min_calls_h = 140.0f; + float min_params_h = 120.0f; + float results_h = 0.0f; + float parameters_h = 0.0f; + + panel_area_h = NK_MAX(panel_area_h, min_calls_h + min_params_h); + results_h = panel_area_h * tool->ui.parameter_splitter.ratio; + results_h = NK_CLAMP(min_calls_h, results_h, panel_area_h - min_params_h); + parameters_h = panel_area_h - results_h; + if (panel_area_h > 0.0f) { + tool->ui.parameter_splitter.ratio = results_h / panel_area_h; + } nk_layout_row_dynamic(ctx, results_h, 1); + struct nk_rect split_track = nk_widget_bounds(ctx); + split_track.h = panel_area_h; + if (nk_group_begin(ctx, "ufunction_trace_calls", NK_WINDOW_BORDER)) { if (call_root_count > 0) { uint32_t first_idx = tool->ui.page_idx * page_size; @@ -1242,14 +1599,14 @@ trace_draw_window(trace_tool_t *tool, unsigned int vw, unsigned int vh) trace_call_t *last_call = trace_call_root_at(tool, last_idx); ui_text_cell_t header_parts[] = { - UI_TEXT_CELL(tool->ui.seq, UI_C_TEXT), - UI_TEXT_CELL(tool->ui.time, UI_C_TEXT), - UI_TEXT_CELL(tool->ui.duration, UI_C_TEXT), - UI_TEXT_CELL(tool->ui.depth, UI_C_TEXT), - UI_TEXT_CELL(tool->ui.kind, UI_C_TEXT), + UI_TEXT_CELL(tool->ui.seq, UI_C_TEXT), + UI_TEXT_CELL(tool->ui.time, UI_C_TEXT), + UI_TEXT_CELL(tool->ui.duration, UI_C_TEXT), + UI_TEXT_CELL(tool->ui.depth, UI_C_TEXT), + UI_TEXT_CELL(tool->ui.kind, UI_C_TEXT), UI_TEXT_CELL(tool->ui.class_name, UI_C_TEXT), - UI_TEXT_CELL(tool->ui.self_name, UI_C_TEXT), - UI_TEXT_CELL(tool->ui.func_name, UI_C_TEXT), + UI_TEXT_CELL(tool->ui.self_name, UI_C_TEXT), + UI_TEXT_CELL(tool->ui.func_name, UI_C_TEXT), }; ui_detail_row_t row = { @@ -1257,9 +1614,10 @@ trace_draw_window(trace_tool_t *tool, unsigned int vw, unsigned int vh) .count = COUNTOF(header_parts), .depth = 0, .has_children = false, + .selected = false, .copy_text = STR_NULL, }; - ui_detail_row(tool, &tool->ui.call_grid, row, NULL); + ui_detail_row(tool, &tool->ui.call_grid, row, NULL, NULL); for (trace_call_t *call = first_call; call != NULL && call != last_call; call = call->next_sibling) { draw_detail_call(tool, call, 0); @@ -1267,6 +1625,23 @@ trace_draw_window(trace_tool_t *tool, unsigned int vw, unsigned int vh) } nk_group_end(ctx); } + + nk_layout_row_dynamic(ctx, splitter_h, 1); + ui_nk_splitter_opts_t split_opts = { + .axis = UI_NK_AXIS_Y, + .track = split_track, + .gap_before = gap_y, + .min_before = min_calls_h, + .min_after = min_params_h, + .line_thickness = 2.0f, + }; + ui_splitter(ctx, &tool->ui.parameter_splitter, &split_opts); + + nk_layout_row_dynamic(ctx, parameters_h, 1); + if (nk_group_begin(ctx, "ufunction_trace_parameters", NK_WINDOW_BORDER)) { + trace_draw_parameter_panel(tool); + nk_group_end(ctx); + } } nk_end(ctx); @@ -1320,6 +1695,9 @@ trace_init(mod_handle_t h) tool->ui.exact_match = false; tool->ui.capture_nested_calls = false; tool->ui.page_idx = 0; + + tool->ui.parameter_splitter.ratio = 0.65f; + tool->ui.seq = ui_text_span_make(globals.ui_manager.ctx, STR_LIT(TRACE_CALL_COL_SEQ)); tool->ui.time = ui_text_span_make(globals.ui_manager.ctx, STR_LIT(TRACE_CALL_COL_TIME)); tool->ui.duration = ui_text_span_make(globals.ui_manager.ctx, STR_LIT(TRACE_CALL_COL_DURATION)); @@ -1392,7 +1770,6 @@ static bool MOD_CALL trace_process_event_pre(mod_handle_t h, uobject_t *self, ufunc_t *func, void *params) { UNUSED_VAR(h); - UNUSED_VAR(params); trace_tool_t *tool = &g_trace_tool; if (!tool->inited) { @@ -1406,6 +1783,13 @@ trace_process_event_pre(mod_handle_t h, uobject_t *self, ufunc_t *func, void *pa frame->owns_logical_call = true; frame->call = trace_logical_call_begin(tool, self, func, FLAG(TRACE_HOOK_PROCESS_EVENT)); + if (frame->call) { + frame->call->parameter_state = TRACE_PARAMETERS_AVAILABLE; + trace_parameters_capture(tool, frame->call, params, true); + frame->call->start_us = time_now_us(); + frame->call->end_us = frame->call->start_us; + } + return false; } @@ -1440,13 +1824,18 @@ trace_ufunction_invoke_pre(mod_handle_t h, ufunc_t *func, uobject_t *self, ffram } else { frame->owns_logical_call = true; frame->call = trace_logical_call_begin(tool, self, func, FLAG(TRACE_HOOK_INVOKE)); + if (frame->call) { + frame->call->parameter_state = TRACE_PARAMETERS_INVOKE_UNAVAILABLE; + frame->call->start_us = time_now_us(); + frame->call->end_us = frame->call->start_us; + } } return false; } static void -trace_hook_post(trace_tool_t *tool, trace_hook_kind_t kind, uobject_t *self, ufunc_t *func, uint8_t consumed_source, bool consumed) +trace_hook_post(trace_tool_t *tool, trace_hook_kind_t kind, uobject_t *self, ufunc_t *func, void *params, uint8_t consumed_source, bool consumed) { if (tool->dropped_frame_depth > 0) { tool->dropped_frame_depth -= 1; @@ -1461,6 +1850,14 @@ trace_hook_post(trace_tool_t *tool, trace_hook_kind_t kind, uobject_t *self, ufu trace_frame_t *frame = trace_frame_pop(tool, kind, self, func); if (frame->owns_logical_call) { + if (frame->call) { + frame->call->end_us = time_now_us(); + + if (kind == TRACE_HOOK_PROCESS_EVENT) { + trace_parameters_capture(tool, frame->call, params, false); + } + } + trace_logical_call_end(tool, frame->call); } @@ -1479,9 +1876,8 @@ static void MOD_CALL trace_process_event_post(mod_handle_t h, uobject_t *self, ufunc_t *func, void *params, bool consumed) { UNUSED_VAR(h); - UNUSED_VAR(params); - trace_hook_post(&g_trace_tool, TRACE_HOOK_PROCESS_EVENT, self, func, FLAG(TRACE_HOOK_PROCESS_EVENT), consumed); + trace_hook_post(&g_trace_tool, TRACE_HOOK_PROCESS_EVENT, self, func, params, FLAG(TRACE_HOOK_PROCESS_EVENT), consumed); } static void MOD_CALL @@ -1491,7 +1887,7 @@ trace_ufunction_invoke_post(mod_handle_t h, ufunc_t *func, uobject_t *self, ffra UNUSED_VAR(stack); UNUSED_VAR(result); - trace_hook_post(&g_trace_tool, TRACE_HOOK_INVOKE, self, func, FLAG(TRACE_HOOK_INVOKE), consumed); + trace_hook_post(&g_trace_tool, TRACE_HOOK_INVOKE, self, func, NULL, FLAG(TRACE_HOOK_INVOKE), consumed); } static void MOD_CALL diff --git a/src/builtin/uobject_search_internal.h b/src/builtin/uobject_search_internal.h index 80483fc..6324d8b 100644 --- a/src/builtin/uobject_search_internal.h +++ b/src/builtin/uobject_search_internal.h @@ -231,6 +231,8 @@ struct detail_tab_s { struct nk_grid_state param_grid; struct nk_grid_state single_grid; + uint8_t *package_expanded; // per-tab bitset indexed by cache record slot + bool layout_prop_maximized; bool layout_func_maximized; bool layout_instances_maximized; diff --git a/src/input.c b/src/input.c index e89d451..b252217 100644 --- a/src/input.c +++ b/src/input.c @@ -231,6 +231,12 @@ input_key_is_released(input_key_kind_t key) return key > INPUT_KEY_NONE && key < INPUT_KEY_MAX && globals.keys[key].released; } +float +input_key_get_analog_value(input_key_kind_t key) +{ + return key > INPUT_KEY_NONE && key < INPUT_KEY_MAX ? globals.analog_values[key] : 0.0f; +} + bool input_key_is_bindable(input_key_kind_t key) { diff --git a/src/log.c b/src/log.c index 2ecb8aa..0c2cf26 100644 --- a/src/log.c +++ b/src/log.c @@ -6,118 +6,405 @@ #include "scratch.h" #include "str.h" #include "ui_console.h" +#include "unreal.h" +#include +#include #include -typedef uint32_t log_color_t; enum { - COLOR_RESET = 0, - COLOR_BLACK = 1, - COLOR_RED = 2, - COLOR_GREEN = 3, - COLOR_YELLOW = 4, - COLOR_BLUE = 5, - COLOR_PURPLE = 6, - COLOR_CYAN = 7, - COLOR_WHITE = 8, + LOG_QUEUE_UI, + LOG_QUEUE_FILE, + LOG_QUEUE_COUNT, +}; + +typedef struct log_atomic_pair_s log_atomic_pair_t; +ALIGNED_TYPE(struct, 16) log_atomic_pair_s +{ + volatile LONG64 values[2]; +}; + +typedef struct log_queue_slot_s log_queue_slot_t; +struct log_queue_slot_s { + volatile LONG64 sequence; + uint64_t timestamp; + uint64_t frame; + uint32_t len; + log_level_t level; + log_sink_flags_t sinks; + HANDLE completion; +}; + +typedef struct log_queue_s log_queue_t; +ALIGNED_TYPE(struct, 64) log_queue_s +{ + volatile LONG64 read_position; + volatile LONG64 dropped; + uint8_t *entries; + log_queue_slot_t *slots; +}; + +typedef struct log_reservation_s log_reservation_t; +struct log_reservation_s { + uint64_t positions[LOG_QUEUE_COUNT]; + bool reserved[LOG_QUEUE_COUNT]; }; typedef struct logger_s logger_t; struct logger_s { - str_t file_path; - log_level_t level; - log_sink_flags_t default_sinks; - HANDLE file; - SRWLOCK rwlock; - arena_t perm; - tmp_arena_t tmp_msg; + arena_t perm; + str_t file_path; + log_queue_t queues[LOG_QUEUE_COUNT]; + log_atomic_pair_t write_positions; + log_atomic_pair_t frame_clock; // second and its first global frame + volatile LONG64 current_frame; + volatile LONG level; + volatile LONG default_sinks; + volatile LONG accepting; + volatile LONG active_calls; + volatile LONG stopping; + volatile LONG file_error; + HANDLE writer; + HANDLE wake; + unsigned int writer_id; + HANDLE file; + uint8_t *file_buffer; + uint64_t file_buffer_len; + bool console_opened; }; static logger_t g_logger = { .level = LOG_LEVEL_INFO, .default_sinks = LOG_SINK_DEFAULT, .file = INVALID_HANDLE_VALUE, - .rwlock = SRWLOCK_INIT, }; -static WORD g_console_attr_default = 0; +STATIC_ASSERT(CONFIG_LOG_QUEUE_CAP > 0 && (CONFIG_LOG_QUEUE_CAP & (CONFIG_LOG_QUEUE_CAP - 1)) == 0, "log queue capacity must be a power of two"); +STATIC_ASSERT(CONFIG_LOG_MAX_MESSAGE_LEN == 1024, "log entries must hold 1 KB of text"); +STATIC_ASSERT(ALIGNOF(log_queue_t) == 64, "log queues must be cache-line aligned"); +STATIC_ASSERT(ALIGNOF(log_atomic_pair_t) == 16, "atomic pairs must be 16-byte aligned"); -static inline const char * -log_level_to_str(log_level_t level) +static uint64_t +log_atomic_read(volatile LONG64 *value) { - switch (level) { - case LOG_LEVEL_DEBUG: - return "DBG"; - case LOG_LEVEL_INFO: - return "INF"; - case LOG_LEVEL_WARN: - return "WRN"; - case LOG_LEVEL_ERROR: - return "ERR"; + return (uint64_t)InterlockedCompareExchange64(value, 0, 0); +} + +static bool +log_pair_compare_exchange(log_atomic_pair_t *pair, LONG64 high, LONG64 low, LONG64 expected[2]) +{ +#if defined(_MSC_VER) + return InterlockedCompareExchange128(pair->values, high, low, expected) != 0; +#else + typedef unsigned __int128 log_pair_value_t; + + log_pair_value_t expected_value = ((log_pair_value_t)(uint64_t)expected[1] << 64) | (uint64_t)expected[0]; + log_pair_value_t desired_value = ((log_pair_value_t)(uint64_t)high << 64) | (uint64_t)low; + log_pair_value_t actual_value = __sync_val_compare_and_swap((volatile log_pair_value_t *)pair->values, expected_value, desired_value); + + expected[0] = (LONG64)(uint64_t)actual_value; + expected[1] = (LONG64)(uint64_t)(actual_value >> 64); + return actual_value == expected_value; +#endif +} + +static void +log_pair_read(log_atomic_pair_t *pair, LONG64 values[2]) +{ + values[0] = 0; + values[1] = 0; + log_pair_compare_exchange(pair, 0, 0, values); +} + +static bool +log_begin(void) +{ + // keep the queue storage alive until this call finishes + InterlockedIncrement(&g_logger.active_calls); + bool accepting = InterlockedCompareExchange(&g_logger.accepting, 0, 0) != 0; + + if (!accepting) { + InterlockedDecrement(&g_logger.active_calls); } - return "UNK"; + + return accepting; } -static inline log_color_t -log_level_color(log_level_t level) +static void +log_end(void) { - switch (level) { - case LOG_LEVEL_DEBUG: - return COLOR_PURPLE; - case LOG_LEVEL_INFO: - return COLOR_WHITE; - case LOG_LEVEL_WARN: - return COLOR_YELLOW; - case LOG_LEVEL_ERROR: - return COLOR_RED; + InterlockedDecrement(&g_logger.active_calls); +} + +static uint64_t +log_timestamp(void) +{ + FILETIME now; + GetSystemTimeAsFileTime(&now); + return ((uint64_t)now.dwHighDateTime << 32) | now.dwLowDateTime; +} + +static bool +log_frame_clock_update(log_atomic_pair_t *clock, LONG64 previous[2], uint64_t second, uint64_t frame_counter, uint64_t *frame) +{ + uint64_t first_frame = (uint64_t)previous[1]; + + if ((uint64_t)previous[0] == second && frame_counter >= first_frame) { + *frame = frame_counter - first_frame; + return true; + } + + if (log_pair_compare_exchange(clock, (LONG64)frame_counter, (LONG64)second, previous)) { + *frame = 0; + return true; } - return COLOR_WHITE; + + return false; } -static WORD -color_to_console_attr(log_color_t color) -{ - WORD attr = 0; - switch (color) { - case COLOR_BLACK: - attr = 0; - break; - case COLOR_RED: - attr = FOREGROUND_RED | FOREGROUND_INTENSITY; - break; - case COLOR_GREEN: - attr = FOREGROUND_GREEN | FOREGROUND_INTENSITY; - break; - case COLOR_YELLOW: - attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; - break; - case COLOR_BLUE: - attr = FOREGROUND_BLUE | FOREGROUND_INTENSITY; - break; - case COLOR_PURPLE: - attr = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY; - break; - case COLOR_CYAN: - attr = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY; - break; - case COLOR_WHITE: - attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY; - break; - default: - attr = g_console_attr_default; - break; - } - return attr; +static void +log_capture_time(log_message_t *message) +{ + ALIGNED_VAR(LONG64 clock[2], 16); + log_pair_read(&g_logger.frame_clock, clock); + bool captured = false; + + while (!captured) { + message->timestamp = log_timestamp(); + + uint64_t second = message->timestamp / 10000000; + uint64_t frame = log_atomic_read(&g_logger.current_frame); + captured = log_frame_clock_update(&g_logger.frame_clock, clock, second, frame, &message->frame); + } +} + +static int +log_queue_index(uint64_t position) +{ + return (int)(position & (CONFIG_LOG_QUEUE_CAP - 1)); +} + +static uint8_t * +log_queue_entry(log_queue_t *queue, uint64_t position) +{ + return queue->entries + (uint64_t)log_queue_index(position) * CONFIG_LOG_MAX_MESSAGE_LEN; +} + +static log_reservation_t +log_reserve(log_sink_flags_t sinks, bool report_drops) +{ + ALIGNED_VAR(LONG64 positions[LOG_QUEUE_COUNT], 16); + log_pair_read(&g_logger.write_positions, positions); + + log_reservation_t result = {0}; + + bool requested[LOG_QUEUE_COUNT] = { + (sinks & LOG_SINK_UI) != 0, + (sinks & (LOG_SINK_FILE | LOG_SINK_WINCON)) != 0, + }; + + bool claimed = false; + while (!claimed) { + LONG64 next[LOG_QUEUE_COUNT]; + + for (int i = 0; i < LOG_QUEUE_COUNT; ++i) { + uint64_t position = (uint64_t)positions[i]; + log_queue_slot_t *slot = &g_logger.queues[i].slots[log_queue_index(position)]; + + result.positions[i] = position; + result.reserved[i] = requested[i] && log_atomic_read(&slot->sequence) == position; + next[i] = (LONG64)(position + result.reserved[i]); + } + + /* reserve both positions together so the sinks agree on message order */ + claimed = log_pair_compare_exchange(&g_logger.write_positions, next[LOG_QUEUE_FILE], next[LOG_QUEUE_UI], positions); + } + + if (report_drops) { + for (int i = 0; i < LOG_QUEUE_COUNT; ++i) { + if (requested[i] && !result.reserved[i]) { + InterlockedIncrement64(&g_logger.queues[i].dropped); + } + } + } + + return result; } static void -console_set_color(log_color_t color) +log_queue_publish(log_queue_t *queue, uint64_t position, const log_message_t *message, log_sink_flags_t sinks, HANDLE completion) { - HANDLE h_out = GetStdHandle(STD_OUTPUT_HANDLE); - if (color == COLOR_RESET) { - SetConsoleTextAttribute(h_out, g_console_attr_default); - } else { - SetConsoleTextAttribute(h_out, color_to_console_attr(color)); + int index = log_queue_index(position); + log_queue_slot_t *slot = &queue->slots[index]; + + slot->timestamp = message->timestamp; + slot->frame = message->frame; + slot->level = message->level; + slot->sinks = sinks; + slot->len = (uint32_t)message->text.len; + slot->completion = completion; + + if (slot->len > 0) { + mem_copy(log_queue_entry(queue, position), message->text.data, slot->len); + } + + /* publish only after the metadata and text are complete */ + InterlockedExchange64(&slot->sequence, (LONG64)(position + 1)); +} + +static bool +log_queue_peek(log_queue_t *queue, uint64_t position, log_message_t *message) +{ + int index = log_queue_index(position); + log_queue_slot_t *slot = &queue->slots[index]; + + if (log_atomic_read(&slot->sequence) != position + 1) { + return false; + } + + *message = (log_message_t){ + .level = slot->level, + .timestamp = slot->timestamp, + .frame = slot->frame, + .text = {.data = log_queue_entry(queue, position), .len = slot->len}, + }; + return true; +} + +static void +log_queue_release(log_queue_t *queue, uint64_t position) +{ + log_queue_slot_t *slot = &queue->slots[log_queue_index(position)]; + InterlockedExchange64(&slot->sequence, (LONG64)(position + CONFIG_LOG_QUEUE_CAP)); + InterlockedExchange64(&queue->read_position, (LONG64)(position + 1)); +} + +static void +log_submit(log_level_t level, log_sink_flags_t sinks, str_t text) +{ + log_message_t message = { + .level = level, + .text = { + .data = text.data, + .len = MIN_VAL(text.len, CONFIG_LOG_MAX_MESSAGE_LEN), + }, + }; + log_capture_time(&message); + log_reservation_t reservation = log_reserve(sinks, true); + + for (int i = 0; i < LOG_QUEUE_COUNT; ++i) { + if (reservation.reserved[i]) { + log_queue_publish(&g_logger.queues[i], reservation.positions[i], &message, sinks, NULL); + } + } + + if (reservation.reserved[LOG_QUEUE_FILE] && reservation.positions[LOG_QUEUE_FILE] == log_atomic_read(&g_logger.queues[LOG_QUEUE_FILE].read_position)) { + SetEvent(g_logger.wake); + } +} + +void +log_ui_enqueue(log_level_t level, str_t text) +{ + if (log_begin()) { + log_submit(level, LOG_SINK_UI, text); + log_end(); + } +} + +void +log_ui_on_frame_begin(uint64_t frame_counter) +{ + if (!unreal_is_in_game_thread()) { + return; + } + + if (log_begin()) { + InterlockedExchange64(&g_logger.current_frame, (LONG64)frame_counter); + log_message_t message = {0}; + log_capture_time(&message); + log_end(); + } +} + +static void +log_ui_drain(ui_console_t *console) +{ + log_queue_t *queue = &g_logger.queues[LOG_QUEUE_UI]; + ALIGNED_VAR(LONG64 positions[LOG_QUEUE_COUNT], 16); + log_pair_read(&g_logger.write_positions, positions); + + uint64_t read_position = log_atomic_read(&queue->read_position); + uint64_t count = MIN_VAL((uint64_t)positions[LOG_QUEUE_UI] - read_position, CONFIG_LOG_UI_DRAIN_LIMIT); + bool ready = true; + + for (uint64_t i = 0; i < count && ready; ++i) { + log_message_t message; + ready = log_queue_peek(queue, read_position, &message); + + if (ready) { + ui_console_append_log(console, &message); + log_queue_release(queue, read_position); + read_position += 1; + } + } + + uint64_t dropped = (uint64_t)InterlockedExchange64(&queue->dropped, 0); + if (dropped > 0) { + char text[128]; + snprintf(text, sizeof(text), "UI console queue overflow: dropped %llu new messages", (unsigned long long)dropped); + + log_message_t message = { + .level = LOG_LEVEL_WARN, + .text = str_from_cstr(text), + }; + log_capture_time(&message); + + ui_console_append_log(console, &message); + } +} + +bool +log_ui_flush(ui_console_t *console) +{ + if (!unreal_is_in_game_thread() || !console || !console->inited) { + return false; + } + + bool drained = false; + + if (log_begin()) { + log_ui_drain(console); + drained = true; + log_end(); + } + + return drained; +} + +static WORD g_console_attr_default = 0; + +static inline const char * +log_level_to_str(log_level_t level) +{ + switch (level) { + case LOG_LEVEL_DEBUG: return "DBG"; + case LOG_LEVEL_INFO: return "INF"; + case LOG_LEVEL_WARN: return "WRN"; + case LOG_LEVEL_ERROR: return "ERR"; + } + return "UNK"; +} + +static WORD +log_level_console_color(log_level_t level) +{ + switch (level) { + case LOG_LEVEL_DEBUG: return FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY; + case LOG_LEVEL_INFO: return FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY; + case LOG_LEVEL_WARN: return FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; + case LOG_LEVEL_ERROR: return FOREGROUND_RED | FOREGROUND_INTENSITY; + default: return g_console_attr_default; } } @@ -133,8 +420,10 @@ console_new_private(const wchar_t *title) // disable QuickEdit to avoid stalls HANDLE h_in = GetStdHandle(STD_INPUT_HANDLE); + if (h_in && h_in != INVALID_HANDLE_VALUE) { DWORD mode = 0; + if (GetConsoleMode(h_in, &mode)) { mode &= ~ENABLE_QUICK_EDIT_MODE; mode |= ENABLE_EXTENDED_FLAGS; @@ -153,126 +442,313 @@ console_new_private(const wchar_t *title) } static void -write_two_digits(char *dst, int v) +log_file_error(DWORD error) { - dst[0] = (char)('0' + (v / 10)); - dst[1] = (char)('0' + (v % 10)); + DWORD previous = (DWORD)InterlockedExchange(&g_logger.file_error, (LONG)error); + + if (previous != error) { + char text[128]; + snprintf(text, sizeof(text), "Log file error: Windows error %lu", error); + OutputDebugStringA(text); + log_ui_enqueue(LOG_LEVEL_ERROR, str_from_cstr(text)); + } } static void -write_three_digits(char *dst, int v) +log_file_write_buffer(void) { - dst[0] = (char)('0' + (v / 100)); - dst[1] = (char)('0' + ((v % 100) / 10)); - dst[2] = (char)('0' + (v % 10)); + uint64_t offset = 0; + bool written = g_logger.file != INVALID_HANDLE_VALUE; + + while (written && offset < g_logger.file_buffer_len) { + DWORD count = 0; + written = WriteFile(g_logger.file, g_logger.file_buffer + offset, (DWORD)(g_logger.file_buffer_len - offset), &count, NULL) != 0; + + if (!written) { + log_file_error(GetLastError()); + } else if (count == 0) { + log_file_error(ERROR_WRITE_FAULT); + written = false; + } else { + offset += count; + } + } + + g_logger.file_buffer_len = 0; } -// returns length (always 23), format: "YYYY-MM-DD HH:MM:SS.MMM" static void -format_time_stamp(char buf[32]) -{ - SYSTEMTIME st; - GetLocalTime(&st); - - int year = (int)st.wYear; - - buf[0] = (char)('0' + (year / 1000) % 10); - buf[1] = (char)('0' + (year / 100) % 10); - buf[2] = (char)('0' + (year / 10) % 10); - buf[3] = (char)('0' + (year % 10)); - buf[4] = '-'; - write_two_digits(buf + 5, (int)st.wMonth); - buf[7] = '-'; - write_two_digits(buf + 8, (int)st.wDay); - buf[10] = ' '; - write_two_digits(buf + 11, (int)st.wHour); - buf[13] = ':'; - write_two_digits(buf + 14, (int)st.wMinute); - buf[16] = ':'; - write_two_digits(buf + 17, (int)st.wSecond); - buf[19] = '.'; - write_three_digits(buf + 20, (int)st.wMilliseconds); - buf[23] = '\0'; +log_file_flush(void) +{ + log_file_write_buffer(); + + if (g_logger.file != INVALID_HANDLE_VALUE && !FlushFileBuffers(g_logger.file)) { + log_file_error(GetLastError()); + } } static void -write_console(str_t msg) +log_file_append(const log_message_t *message, log_sink_flags_t sinks) { - HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); - if (!h || h == INVALID_HANDLE_VALUE || str_is_empty(msg)) { - return; + FILETIME utc = { + .dwLowDateTime = (DWORD)message->timestamp, + .dwHighDateTime = (DWORD)(message->timestamp >> 32), + }; + + FILETIME local; + SYSTEMTIME time = {0}; + FileTimeToLocalFileTime(&utc, &local); + FileTimeToSystemTime(&local, &time); + + char prefix[64]; + int prefix_len = snprintf(prefix, sizeof(prefix), "%04d-%02d-%02d %02d:%02d:%02d.%03d [%s] ", + time.wYear, time.wMonth, time.wDay, + time.wHour, time.wMinute, time.wSecond, time.wMilliseconds, + log_level_to_str(message->level)); + + uint64_t cursor = 0; + HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE); + bool to_console = (sinks & LOG_SINK_WINCON) && console && console != INVALID_HANDLE_VALUE; + bool to_file = (sinks & LOG_SINK_FILE) && g_logger.file != INVALID_HANDLE_VALUE; + + if (to_console) { + SetConsoleTextAttribute(console, log_level_console_color(message->level)); } - DWORD written = 0; - WriteConsoleA(h, msg.data, (DWORD)msg.len, &written, NULL); + do { + uint64_t start = cursor; + while (cursor < message->text.len && message->text.data[cursor] != '\r' && message->text.data[cursor] != '\n') { + cursor += 1; + } + + char line[CONFIG_LOG_MAX_MESSAGE_LEN + 64]; + uint64_t line_len = (uint64_t)prefix_len + cursor - start; + mem_copy(line, prefix, (uint64_t)prefix_len); + + if (cursor > start) { + mem_copy(line + prefix_len, message->text.data + start, cursor - start); + } + + line[line_len++] = '\r'; + line[line_len++] = '\n'; + + if (to_file) { + if (g_logger.file_buffer_len + line_len > CONFIG_LOG_FILE_BUFFER_SIZE) { + log_file_write_buffer(); + } + + mem_copy(g_logger.file_buffer + g_logger.file_buffer_len, line, line_len); + g_logger.file_buffer_len += line_len; + } + + if (to_console) { + DWORD written; + WriteConsoleA(console, line, (DWORD)line_len, &written, NULL); + } + + if (cursor < message->text.len) { + uint8_t newline = message->text.data[cursor]; + cursor += 1; + + if (cursor < message->text.len) { + uint8_t next = message->text.data[cursor]; + bool paired = (newline == '\r' && next == '\n') || (newline == '\n' && next == '\r'); + + if (paired) { + cursor += 1; + } + } + } + } while (cursor < message->text.len); + + if (to_console) { + SetConsoleTextAttribute(console, g_console_attr_default); + } } static void -write_file(str_t msg) +log_file_report_drops(void) { - if (g_logger.file == INVALID_HANDLE_VALUE || str_is_empty(msg)) { - return; - } + uint64_t dropped = (uint64_t)InterlockedExchange64(&g_logger.queues[LOG_QUEUE_FILE].dropped, 0); + + if (dropped > 0) { + char text[128]; + snprintf(text, sizeof(text), "File log queue overflow: dropped %llu new messages", (unsigned long long)dropped); - DWORD written = 0; - WriteFile(g_logger.file, msg.data, (DWORD)msg.len, &written, NULL); + log_message_t overflow = { + .level = LOG_LEVEL_WARN, + .text = str_from_cstr(text), + }; + log_capture_time(&overflow); + + log_file_append(&overflow, LOG_SINK_FILE | LOG_SINK_WINCON); + log_ui_enqueue(LOG_LEVEL_WARN, overflow.text); + } } -static HANDLE -open_log_file(str_t file_path) +static unsigned __stdcall +log_file_writer(void *user) { - if (str_is_empty(file_path)) { - return false; + (void)user; + + DWORD open_error = ERROR_SUCCESS; + tmp_arena_t tmp = scratch_begin(NULL); + { + str16_t path = str16_from_str(tmp.arena, g_logger.file_path); + g_logger.file = CreateFileW(path.data, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + + if (g_logger.file == INVALID_HANDLE_VALUE) { + open_error = GetLastError(); + } } + scratch_end(tmp); - tmp_arena_t tmp = scratch_begin(NULL); - HANDLE result = INVALID_HANDLE_VALUE; - str16_t file_path16 = str16_from_str(tmp.arena, file_path); + if (g_logger.file == INVALID_HANDLE_VALUE) { + log_file_error(open_error); + } - result = CreateFileW(file_path16.data, - GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL); + log_queue_t *queue = &g_logger.queues[LOG_QUEUE_FILE]; + bool stopped = false; - scratch_end(tmp); - return result; + while (!stopped) { + uint64_t position = log_atomic_read(&queue->read_position); + log_message_t message = {0}; + bool ready = log_queue_peek(queue, position, &message); + uint64_t count = 0; + + while (ready && count < CONFIG_LOG_QUEUE_CAP) { + log_queue_slot_t *slot = &queue->slots[log_queue_index(position)]; + + if (slot->completion) { + log_file_report_drops(); + log_file_flush(); + SetEvent(slot->completion); + } else { + log_file_append(&message, slot->sinks); + } + + log_queue_release(queue, position); + position += 1; + count += 1; + ready = log_queue_peek(queue, position, &message); + } + + log_file_report_drops(); + log_file_write_buffer(); + stopped = InterlockedCompareExchange(&g_logger.stopping, 0, 0) != 0 && !ready; + + if (!stopped && !ready) { + WaitForSingleObject(g_logger.wake, 50); + } + } + + log_file_flush(); + + if (g_logger.file != INVALID_HANDLE_VALUE) { + CloseHandle(g_logger.file); + g_logger.file = INVALID_HANDLE_VALUE; + } + + scratch_destroy(); + return 0; } void log_init(str_t file_path, log_level_t level, bool open_console) { - if (open_console) { - console_new_private(L"Log window"); + /* initialize before starting producers, never wait for the writer in DllMain */ + if (InterlockedCompareExchange(&g_logger.accepting, 0, 0)) { + return; } - g_logger.file = INVALID_HANDLE_VALUE; - g_logger.level = level; - g_logger.perm = arena_new_dynamic(64 * KB, 16 * KB); + uint64_t queue_bytes = LOG_QUEUE_COUNT * CONFIG_LOG_QUEUE_CAP * (CONFIG_LOG_MAX_MESSAGE_LEN + sizeof(log_queue_slot_t)); + + g_logger.perm = arena_new_dynamic(queue_bytes + CONFIG_LOG_FILE_BUFFER_SIZE + 64 * KB, 64 * KB); + + bool allocated = g_logger.perm.backing != NULL; + for (int i = 0; i < LOG_QUEUE_COUNT && allocated; ++i) { + log_queue_t *queue = &g_logger.queues[i]; + + queue->entries = arena_push_aligned(&g_logger.perm, CONFIG_LOG_QUEUE_CAP * CONFIG_LOG_MAX_MESSAGE_LEN, 64); + queue->slots = ARENA_PUSH_ARRAY_ZERO(&g_logger.perm, log_queue_slot_t, CONFIG_LOG_QUEUE_CAP); + + allocated = queue->entries && queue->slots; + + if (allocated) { + for (uint64_t slot = 0; slot < CONFIG_LOG_QUEUE_CAP; ++slot) { + queue->slots[slot].sequence = (LONG64)slot; + } + } + + InterlockedExchange64(&queue->read_position, 0); + InterlockedExchange64(&queue->dropped, 0); + } + + g_logger.file_buffer = ARENA_PUSH_ARRAY(&g_logger.perm, uint8_t, CONFIG_LOG_FILE_BUFFER_SIZE); if (path_is_abs(file_path)) { - /* absolute path */ g_logger.file_path = str_push_copy(&g_logger.perm, file_path); } else { - /* relative path */ g_logger.file_path = path_join(&g_logger.perm, globals.game_dir, file_path); } - g_logger.tmp_msg = tmp_arena_begin(&g_logger.perm); + allocated = allocated && g_logger.file_buffer && !str_is_empty(g_logger.file_path); + g_logger.wake = CreateEventA(NULL, FALSE, FALSE, NULL); + + if (!allocated || !g_logger.wake) { + if (g_logger.wake) { + CloseHandle(g_logger.wake); + g_logger.wake = NULL; + } + + arena_destroy(&g_logger.perm); + OutputDebugStringA("Failed to initialize logger"); + return; + } + + g_logger.write_positions = (log_atomic_pair_t){0}; + g_logger.frame_clock = (log_atomic_pair_t){0}; + + InterlockedExchange64(&g_logger.current_frame, 0); + InterlockedExchange(&g_logger.stopping, 0); + InterlockedExchange(&g_logger.file_error, 0); + InterlockedExchange(&g_logger.level, (LONG)level); + + g_logger.file_buffer_len = 0; + g_logger.file = INVALID_HANDLE_VALUE; + g_logger.console_opened = open_console; + + if (open_console) { + console_new_private(L"Log window"); + } + + InterlockedExchange(&g_logger.accepting, 1); + g_logger.writer = (HANDLE)_beginthreadex(NULL, 0, log_file_writer, NULL, 0, &g_logger.writer_id); + + if (!g_logger.writer) { + InterlockedExchange(&g_logger.accepting, 0); + CloseHandle(g_logger.wake); + g_logger.wake = NULL; + arena_destroy(&g_logger.perm); + OutputDebugStringA("Failed to start log writer"); + + if (g_logger.console_opened) { + FreeConsole(); + g_logger.console_opened = false; + } + } } void log_set_level(log_level_t level) { - g_logger.level = level; + InterlockedExchange(&g_logger.level, (LONG)level); } void log_set_default_sinks(log_sink_flags_t sinks) { - g_logger.default_sinks = sinks; + InterlockedExchange(&g_logger.default_sinks, (LONG)sinks); } void @@ -287,99 +763,94 @@ log_emit(log_level_t level, log_sink_flags_t sinks, const char *fmt, ...) void log_emitv(log_level_t level, log_sink_flags_t sinks, const char *fmt, va_list ap) { - if (level < g_logger.level) { + if (level < (log_level_t)InterlockedCompareExchange(&g_logger.level, 0, 0) || !fmt) { return; } if (sinks == LOG_SINK_NONE) { - sinks = g_logger.default_sinks; + sinks = (log_sink_flags_t)InterlockedCompareExchange(&g_logger.default_sinks, 0, 0); } - if (sinks & LOG_SINK_UI) { -#if !defined BUILD_TEST - va_list ap_ui; - va_copy(ap_ui, ap); - ui_console_logv(&globals.ui_manager.console, ui_console_level_from_log(level), fmt, ap_ui); - va_end(ap_ui); -#endif - } - - if ((sinks & (LOG_SINK_FILE | LOG_SINK_WINCON)) == 0) { + if ((sinks & LOG_SINK_DEFAULT) == 0) { return; } - char ts[32]; - format_time_stamp(ts); - str_t ts_str = str_from_cstr_with_cap(ts, sizeof(ts)); - - AcquireSRWLockExclusive(&g_logger.rwlock); - { - tmp_arena_end(g_logger.tmp_msg); + if (log_begin()) { + char text[CONFIG_LOG_MAX_MESSAGE_LEN + 1]; + int len = vsnprintf(text, sizeof(text), fmt, ap); + str_t message = STR_LIT("[log formatting failed]"); - va_list ap_msg; - va_copy(ap_msg, ap); - str_t msg = str_push_vfmt(g_logger.tmp_msg.arena, fmt, ap_msg); - va_end(ap_msg); + if (len >= 0) { + message = (str_t){.data = (uint8_t *)text, .len = MIN_VAL((uint64_t)len, CONFIG_LOG_MAX_MESSAGE_LEN)}; + } - str_t level_name = str_push_fmt(g_logger.tmp_msg.arena, " [%s] ", log_level_to_str(level)); - log_color_t level_color = log_level_color(level); + log_submit(level, sinks, message); + log_end(); + } +} - str_list_t msg_lines = str_split_lines(g_logger.tmp_msg.arena, msg); +static void +log_wait_for_file(void) +{ + HANDLE completion = CreateEventA(NULL, FALSE, FALSE, NULL); - if (sinks & LOG_SINK_WINCON) { - console_set_color(level_color); - for (str_node_t *node = msg_lines.first; node; node = node->next) { - write_console(ts_str); - write_console(level_name); - write_console(node->str); - write_console(STR_LIT("\n")); - } - console_set_color(COLOR_RESET); - } + if (!completion) { + OutputDebugStringA("Failed to create log flush event"); + return; + } - if (sinks & LOG_SINK_FILE) { - if (g_logger.file == INVALID_HANDLE_VALUE) { - g_logger.file = open_log_file(g_logger.file_path); - } + log_reservation_t reservation = log_reserve(LOG_SINK_FILE, false); - if (g_logger.file != INVALID_HANDLE_VALUE) { - for (str_node_t *node = msg_lines.first; node; node = node->next) { - write_file(ts_str); - write_file(level_name); - write_file(node->str); - write_file(STR_LIT("\r\n")); - } - } - } + while (!reservation.reserved[LOG_QUEUE_FILE]) { + SetEvent(g_logger.wake); + Sleep(1); + reservation = log_reserve(LOG_SINK_FILE, false); } - ReleaseSRWLockExclusive(&g_logger.rwlock); + + log_message_t message = {0}; + log_queue_publish(&g_logger.queues[LOG_QUEUE_FILE], reservation.positions[LOG_QUEUE_FILE], &message, 0, completion); + SetEvent(g_logger.wake); + WaitForSingleObject(completion, INFINITE); + CloseHandle(completion); } void log_flush(void) { - AcquireSRWLockExclusive(&g_logger.rwlock); - - if (g_logger.file != INVALID_HANDLE_VALUE) { - FlushFileBuffers(g_logger.file); + if (log_begin()) { + if (thread_current_id() != g_logger.writer_id) { + log_wait_for_file(); + } + log_end(); } - - ReleaseSRWLockExclusive(&g_logger.rwlock); } void log_deinit(void) { - AcquireSRWLockExclusive(&g_logger.rwlock); + /* stop and join the writer outside DllMain */ + if (!InterlockedExchange(&g_logger.accepting, 0)) { + return; + } - if (g_logger.file != INVALID_HANDLE_VALUE) { - FlushFileBuffers(g_logger.file); - CloseHandle(g_logger.file); - g_logger.file = INVALID_HANDLE_VALUE; + while (InterlockedCompareExchange(&g_logger.active_calls, 0, 0) != 0) { + Sleep(1); } + InterlockedExchange(&g_logger.stopping, 1); + SetEvent(g_logger.wake); + WaitForSingleObject(g_logger.writer, INFINITE); + CloseHandle(g_logger.writer); + CloseHandle(g_logger.wake); + + g_logger.writer = NULL; + g_logger.wake = NULL; + g_logger.writer_id = 0; + arena_destroy(&g_logger.perm); - FreeConsole(); - ReleaseSRWLockExclusive(&g_logger.rwlock); + if (g_logger.console_opened) { + FreeConsole(); + g_logger.console_opened = false; + } } diff --git a/src/lua_mod_runtime.c b/src/lua_mod_runtime.c new file mode 100644 index 0000000..422e213 --- /dev/null +++ b/src/lua_mod_runtime.c @@ -0,0 +1,265 @@ +#include "lua_mod_runtime.h" + +#include "lua_overdub_runtime.h" +#include "lua_ue4ss_runtime.h" +#include "mod_manager.h" + +typedef struct lua_mod_runtime_ops_s lua_mod_runtime_ops_t; +struct lua_mod_runtime_ops_s { + void (*system_init) (void); + bool (*start) (mod_t *mod); + void (*stop) (mod_t *mod); + bool (*is_initialized) (mod_t *mod); + void (*tick) (mod_t *mod, float delta_seconds); + bool (*input) (mod_t *mod, input_event_t *event); + bool (*process_event_pre) (mod_t *mod, uobject_t *object, ufunc_t *function, void *params); + void (*process_event_post) (mod_t *mod, uobject_t *object, ufunc_t *function, void *params, bool consumed); + void (*post_load) (mod_t *mod, uobject_t *object, bool after); + bool (*has_post_load_hooks) (void); + bool (*command) (mod_t *mod, str_t name, str_t args); + void (*notify_uobject_constructed)(mod_manager_t *manager, uobject_t *object); + void (*notify_uobject_deleted) (mod_manager_t *manager, uobject_t *object, int32_t idx); + int (*snapshot_commands) (mod_t *mod, str_t *names, int capacity); + void (*draw_panel) (mod_t *mod, struct nk_context *ctx); + bool (*draw_config) (mod_t *mod, struct nk_context *ctx); + bool (*has_draw_config) (mod_t *mod); +}; + +static void +lua_mod_runtime_error_set(err_msg_t *error, str_t message) +{ + error->len = (int)MIN_VAL(message.len, sizeof(error->msg)); + mem_copy(error->msg, message.data, error->len); +} + +static void +lua_mod_ue4ss_tick(mod_t *mod, float delta_seconds) +{ + (void)delta_seconds; + lua_ue4ss_runtime_tick(mod); +} + +static bool +lua_mod_ue4ss_input(mod_t *mod, input_event_t *event) +{ + lua_ue4ss_runtime_queue_input(mod, event); + return false; +} + +static const lua_mod_runtime_ops_t g_lua_ue4ss_runtime_ops = { + .system_init = lua_ue4ss_runtime_system_init, + .start = lua_ue4ss_runtime_start, + .stop = lua_ue4ss_runtime_stop, + .is_initialized = lua_ue4ss_runtime_is_initialized, + .tick = lua_mod_ue4ss_tick, + .input = lua_mod_ue4ss_input, + .process_event_pre = lua_ue4ss_runtime_process_event_pre, + .process_event_post = lua_ue4ss_runtime_process_event_post, + .command = lua_ue4ss_runtime_queue_command, + .notify_uobject_constructed = lua_ue4ss_runtime_notify_uobject_constructed, + .snapshot_commands = lua_ue4ss_runtime_snapshot_commands, +}; + +static const lua_mod_runtime_ops_t g_lua_overdub_runtime_ops = { + .system_init = lua_overdub_runtime_system_init, + .start = lua_overdub_runtime_start, + .stop = lua_overdub_runtime_stop, + .is_initialized = lua_overdub_runtime_is_initialized, + .tick = lua_overdub_runtime_tick, + .input = lua_overdub_runtime_input, + .process_event_pre = lua_overdub_runtime_process_event_pre, + .process_event_post = lua_overdub_runtime_process_event_post, + .post_load = lua_overdub_runtime_post_load, + .has_post_load_hooks = lua_overdub_runtime_has_post_load_hooks, + .command = lua_overdub_runtime_command, + .notify_uobject_constructed = lua_overdub_runtime_notify_uobject_constructed, + .notify_uobject_deleted = lua_overdub_runtime_notify_uobject_deleted, + .snapshot_commands = lua_overdub_runtime_snapshot_commands, + .draw_panel = lua_overdub_runtime_draw_panel, + .draw_config = lua_overdub_runtime_draw_config, + .has_draw_config = lua_overdub_runtime_has_draw_config, +}; + +static const lua_mod_runtime_ops_t *const g_lua_mod_runtime_ops[MOD_LUA_RUNTIME_MAX] = { + [MOD_LUA_RUNTIME_OVERDUB] = &g_lua_overdub_runtime_ops, + [MOD_LUA_RUNTIME_UE4SS] = &g_lua_ue4ss_runtime_ops, +}; + +static const lua_mod_runtime_ops_t * +lua_mod_runtime_ops_from_kind(mod_lua_runtime_kind_t kind) +{ + if (kind >= MOD_LUA_RUNTIME_MAX) { + return NULL; + } + return g_lua_mod_runtime_ops[kind]; +} + +static const lua_mod_runtime_ops_t * +lua_mod_runtime_ops_from_mod(mod_t *mod) +{ + return mod ? lua_mod_runtime_ops_from_kind(mod->manifest.lua.runtime_kind) : NULL; +} + +void +lua_mod_runtime_system_init(void) +{ + for (int i = 0; i < MOD_LUA_RUNTIME_MAX; ++i) { + const lua_mod_runtime_ops_t *ops = g_lua_mod_runtime_ops[i]; + if (ops && ops->system_init) { + ops->system_init(); + } + } +} + +bool +lua_mod_runtime_start(mod_t *mod) +{ + if (!mod || !mod->has_lua) { + return mod != NULL; + } + + const lua_mod_runtime_ops_t *ops = lua_mod_runtime_ops_from_mod(mod); + if (ops && ops->start) { + return ops->start(mod); + } + + mod->lua.start_attempted = true; + lua_mod_runtime_error_set(&mod->lua.err_msg, STR_LIT("invalid Lua runtime in mod.ini")); + return false; +} + +void +lua_mod_runtime_stop(mod_t *mod) +{ + if (!mod || !mod->has_lua) { + return; + } + + const lua_mod_runtime_ops_t *ops = lua_mod_runtime_ops_from_mod(mod); + if (ops && ops->stop) { + ops->stop(mod); + return; + } + + mod->lua.active = false; + mod->lua.start_attempted = false; +} + +bool +lua_mod_runtime_is_initialized(mod_t *mod) +{ + const lua_mod_runtime_ops_t *ops = lua_mod_runtime_ops_from_mod(mod); + return ops && ops->is_initialized && ops->is_initialized(mod); +} + +void +lua_mod_runtime_tick(mod_t *mod, float delta_seconds) +{ + const lua_mod_runtime_ops_t *ops = lua_mod_runtime_ops_from_mod(mod); + if (ops && ops->tick) { + ops->tick(mod, delta_seconds); + } +} + +bool +lua_mod_runtime_input(mod_t *mod, input_event_t *event) +{ + const lua_mod_runtime_ops_t *ops = lua_mod_runtime_ops_from_mod(mod); + return ops && ops->input && ops->input(mod, event); +} + +bool +lua_mod_runtime_process_event_pre(mod_t *mod, uobject_t *object, ufunc_t *function, void *params) +{ + const lua_mod_runtime_ops_t *ops = lua_mod_runtime_ops_from_mod(mod); + return ops && ops->process_event_pre && ops->process_event_pre(mod, object, function, params); +} + +void +lua_mod_runtime_process_event_post(mod_t *mod, uobject_t *object, ufunc_t *function, void *params, bool consumed) +{ + const lua_mod_runtime_ops_t *ops = lua_mod_runtime_ops_from_mod(mod); + if (ops && ops->process_event_post) { + ops->process_event_post(mod, object, function, params, consumed); + } +} + +void +lua_mod_runtime_post_load(mod_t *mod, uobject_t *object, bool after) +{ + const lua_mod_runtime_ops_t *ops = lua_mod_runtime_ops_from_mod(mod); + if (ops && ops->post_load) { + ops->post_load(mod, object, after); + } +} + +bool +lua_mod_runtime_has_post_load_hooks(void) +{ + bool found = false; + for (int i = 0; i < MOD_LUA_RUNTIME_MAX && !found; ++i) { + const lua_mod_runtime_ops_t *ops = g_lua_mod_runtime_ops[i]; + found = ops && ops->has_post_load_hooks && ops->has_post_load_hooks(); + } + + return found; +} + +bool +lua_mod_runtime_command(mod_t *mod, str_t name, str_t args) +{ + const lua_mod_runtime_ops_t *ops = lua_mod_runtime_ops_from_mod(mod); + return ops && ops->command && ops->command(mod, name, args); +} + +void +lua_mod_runtime_notify_uobject_constructed(mod_manager_t *manager, uobject_t *object) +{ + for (int i = 0; i < MOD_LUA_RUNTIME_MAX; ++i) { + const lua_mod_runtime_ops_t *ops = g_lua_mod_runtime_ops[i]; + if (ops && ops->notify_uobject_constructed) { + ops->notify_uobject_constructed(manager, object); + } + } +} + +void +lua_mod_runtime_notify_uobject_deleted(mod_manager_t *manager, uobject_t *object, int32_t idx) +{ + for (int i = 0; i < MOD_LUA_RUNTIME_MAX; ++i) { + const lua_mod_runtime_ops_t *ops = g_lua_mod_runtime_ops[i]; + if (ops && ops->notify_uobject_deleted) { + ops->notify_uobject_deleted(manager, object, idx); + } + } +} + +int +lua_mod_runtime_snapshot_commands(mod_t *mod, str_t *names, int capacity) +{ + const lua_mod_runtime_ops_t *ops = lua_mod_runtime_ops_from_mod(mod); + return ops && ops->snapshot_commands ? ops->snapshot_commands(mod, names, capacity) : 0; +} + +void +lua_mod_runtime_draw_panel(mod_t *mod, struct nk_context *ctx) +{ + const lua_mod_runtime_ops_t *ops = lua_mod_runtime_ops_from_mod(mod); + if (ops && ops->draw_panel) { + ops->draw_panel(mod, ctx); + } +} + +bool +lua_mod_runtime_draw_config(mod_t *mod, struct nk_context *ctx) +{ + const lua_mod_runtime_ops_t *ops = lua_mod_runtime_ops_from_mod(mod); + return ops && ops->draw_config && ops->draw_config(mod, ctx); +} + +bool +lua_mod_runtime_has_draw_config(mod_t *mod) +{ + const lua_mod_runtime_ops_t *ops = lua_mod_runtime_ops_from_mod(mod); + return ops && ops->has_draw_config && ops->has_draw_config(mod); +} diff --git a/src/lua_overdub.c b/src/lua_overdub.c new file mode 100644 index 0000000..cdb0dee --- /dev/null +++ b/src/lua_overdub.c @@ -0,0 +1,624 @@ +#include "lua_overdub.h" + +#include "config.h" +#include "file.h" +#include "globals.h" +#include "ini.h" +#include "log.h" +#include "path.h" +#include "scratch.h" + +#include "lua/src/lauxlib.h" +#include "lua/src/lua.h" +#include "lua/src/lualib.h" + +#include +#include + +#define LUA_OVERDUB_COMMAND_META "overdub.Command" + +typedef struct lua_overdub_command_s lua_overdub_command_t; +struct lua_overdub_command_s { + uint64_t id; + size_t name_len; + int callback_ref; + char name[CONFIG_LUA_OVERDUB_COMMAND_NAME_CAP]; + bool active; +}; + +struct lua_overdub_command_context_s { + lua_State *state; + lua_overdub_command_t commands[CONFIG_LUA_OVERDUB_MAX_COMMANDS]; + uint64_t next_id; +}; + +typedef struct lua_overdub_command_handle_s lua_overdub_command_handle_t; +struct lua_overdub_command_handle_s { + lua_overdub_context_t *context; + uint64_t id; +}; + +static char g_lua_overdub_context_key; + +lua_overdub_context_t * +lua_overdub_context_get(lua_State *state) +{ + lua_pushlightuserdata(state, &g_lua_overdub_context_key); + lua_rawget(state, LUA_REGISTRYINDEX); + lua_overdub_context_t *context = (lua_overdub_context_t *)lua_touserdata(state, -1); + lua_pop(state, 1); + return context; +} + +lua_overdub_context_t * +lua_overdub_context_check(lua_State *state) +{ + lua_overdub_context_t *context = lua_overdub_context_get(state); + if (!context) { + luaL_error(state, "Overdub runtime context is unavailable"); + } + + if (context->owner_thread_id == 0 || context->owner_thread_id != thread_current_id()) { + luaL_error(state, "Overdub Lua state accessed outside its owning game thread"); + } + return context; +} + +static void +lua_overdub_push_str(lua_State *state, str_t value) +{ + lua_pushlstring(state, (const char *)(value.data ? value.data : (uint8_t *)""), (size_t)value.len); +} + +static lua_overdub_command_t * +lua_overdub_command_find_id(lua_overdub_context_t *context, uint64_t id) +{ + if (!context || !context->commands || id == 0) { + return NULL; + } + + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_COMMANDS; ++i) { + lua_overdub_command_t *command = &context->commands->commands[i]; + if (command->active && command->id == id) { + return command; + } + } + + return NULL; +} + +static lua_overdub_command_t * +lua_overdub_command_find_name(lua_overdub_context_t *context, str_t name) +{ + if (!context || !context->commands || str_is_empty(name)) { + return NULL; + } + + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_COMMANDS; ++i) { + lua_overdub_command_t *command = &context->commands->commands[i]; + if (!command->active) { + continue; + } + + str_t registered_name = str_make(command->name, command->name_len); + if (str_equal(registered_name, name, STR_CMP_FLAG_IGNORE_CASE)) { + return command; + } + } + + return NULL; +} + +static bool +lua_overdub_command_name_valid(const char *name, size_t len) +{ + if (!name || len == 0 || len >= CONFIG_LUA_OVERDUB_COMMAND_NAME_CAP || memchr(name, 0, len)) { + return false; + } + + for (size_t i = 0; i < len; ++i) { + uint8_t c = (uint8_t)name[i]; + if (c <= ' ' || c == ':') { + return false; + } + } + + return true; +} + +bool +lua_overdub_command_find(lua_overdub_context_t *context, str_t name, uint64_t *out_id, int *out_ref) +{ + lua_overdub_command_t *command = lua_overdub_command_find_name(context, name); + if (!command) { + return false; + } + + if (out_id) { + *out_id = command->id; + } + + if (out_ref) { + *out_ref = command->callback_ref; + } + + return true; +} + +bool +lua_overdub_command_remove(lua_overdub_context_t *context, uint64_t id) +{ + lua_overdub_command_t *command = lua_overdub_command_find_id(context, id); + if (!command) { + return false; + } + + luaL_unref(context->commands->state, LUA_REGISTRYINDEX, command->callback_ref); + mem_zero(command, sizeof(*command)); + return true; +} + +int +lua_overdub_command_snapshot(lua_overdub_context_t *context, str_t *names, int capacity) +{ + if (!context || !context->commands || !names || capacity <= 0) { + return 0; + } + + int count = 0; + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_COMMANDS && count < capacity; ++i) { + lua_overdub_command_t *command = &context->commands->commands[i]; + if (!command->active) { + continue; + } + + names[count] = str_make(command->name, command->name_len); + count += 1; + } + + return count; +} + +void +lua_overdub_context_cleanup(lua_overdub_context_t *context) +{ + if (!context || !context->commands) { + return; + } + + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_COMMANDS; ++i) { + lua_overdub_command_t *command = &context->commands->commands[i]; + if (command->active) { + luaL_unref(context->commands->state, LUA_REGISTRYINDEX, command->callback_ref); + } + } + + context->commands = NULL; +} + +static lua_overdub_command_handle_t * +lua_overdub_command_handle_check(lua_State *state) +{ + lua_overdub_command_handle_t *handle = luaL_checkudata(state, 1, LUA_OVERDUB_COMMAND_META); + lua_overdub_context_t *context = lua_overdub_context_check(state); + if (!handle->context || handle->context != context) { + luaL_error(state, "Overdub command handle is invalid"); + } + + return handle; +} + +static int +lua_overdub_command_handle_remove(lua_State *state) +{ + lua_overdub_command_handle_t *handle = lua_overdub_command_handle_check(state); + lua_pushboolean(state, lua_overdub_command_remove(handle->context, handle->id)); + return 1; +} + +static int +lua_overdub_command_handle_is_active(lua_State *state) +{ + lua_overdub_command_handle_t *handle = lua_overdub_command_handle_check(state); + lua_pushboolean(state, lua_overdub_command_find_id(handle->context, handle->id) != NULL); + return 1; +} + +static int +lua_overdub_command_handle_gc(lua_State *state) +{ + lua_overdub_command_handle_t *handle = luaL_checkudata(state, 1, LUA_OVERDUB_COMMAND_META); + handle->context = NULL; + handle->id = 0; + return 0; +} + +static int +lua_overdub_register_command(lua_State *state) +{ + lua_overdub_context_t *context = lua_overdub_context_check(state); + if (!context->commands) { + return luaL_error(state, "Overdub console command context is unavailable"); + } + + size_t name_len = 0; + const char *name = luaL_checklstring(state, 1, &name_len); + if (!lua_overdub_command_name_valid(name, name_len)) { + return luaL_argerror(state, 1, "command name must be non-empty, shorter than 128 bytes, and contain no spaces or ':'"); + } + + luaL_checktype(state, 2, LUA_TFUNCTION); + str_t command_name = str_make((void *)name, name_len); + if (lua_overdub_command_find_name(context, command_name)) { + return luaL_error(state, "console command '%s' is already registered by this mod", name); + } + + lua_overdub_command_t *command = NULL; + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_COMMANDS; ++i) { + if (!context->commands->commands[i].active) { + command = &context->commands->commands[i]; + break; + } + } + + if (!command) { + return luaL_error(state, "Overdub console command limit reached"); + } + + uint64_t id = context->commands->next_id; + context->commands->next_id += 1; + if (id == 0) { + id = context->commands->next_id; + context->commands->next_id += 1; + } + + lua_pushvalue(state, 2); + command->callback_ref = luaL_ref(state, LUA_REGISTRYINDEX); + command->id = id; + command->name_len = name_len; + command->active = true; + memcpy(command->name, name, name_len); + command->name[name_len] = 0; + + lua_overdub_command_handle_t *handle = lua_newuserdatauv(state, sizeof(*handle), 0); + *handle = (lua_overdub_command_handle_t){ + .context = context, + .id = id, + }; + luaL_setmetatable(state, LUA_OVERDUB_COMMAND_META); + return 1; +} + +static str_t +lua_overdub_check_path(lua_State *state, int index) +{ + size_t len = 0; + const char *data = luaL_checklstring(state, index, &len); + if (len == 0 || memchr(data, 0, len)) { + luaL_argerror(state, index, "path must be non-empty and contain no null bytes"); + return STR_NULL; + } + + return str_make((void *)data, len); +} + +static int +lua_overdub_list_directory(lua_State *state) +{ + lua_overdub_context_check(state); + str_t path = lua_overdub_check_path(state, 1); + + str_t pattern = STR_NULL; + if (!lua_isnoneornil(state, 2)) { + pattern = lua_overdub_check_path(state, 2); + } + + if (!dir_exists(path)) { + lua_pushnil(state); + lua_pushliteral(state, "directory does not exist"); + return 2; + } + + tmp_arena_t tmp = scratch_begin(NULL); + dir_entry_list_t entries; + if (str_is_empty(pattern)) { + entries = dir_list(path, tmp.arena); + } else { + entries = dir_list_filter(path, pattern, tmp.arena); + } + + lua_createtable(state, entries.count, 0); + for (int i = 0; i < entries.count; ++i) { + dir_entry_t *entry = &entries.items[i]; + lua_createtable(state, 0, 4); + lua_overdub_push_str(state, entry->name); + lua_setfield(state, -2, "Name"); + lua_overdub_push_str(state, entry->path); + lua_setfield(state, -2, "Path"); + lua_pushboolean(state, entry->kind == DIR_ENTRY_DIR); + lua_setfield(state, -2, "IsDirectory"); + lua_pushinteger(state, (lua_Integer)entry->size); + lua_setfield(state, -2, "Size"); + lua_rawseti(state, -2, (lua_Integer)i + 1); + } + + scratch_end(tmp); + return 1; +} + +static int +lua_overdub_read_ini(lua_State *state) +{ + lua_overdub_context_check(state); + str_t path = lua_overdub_check_path(state, 1); + if (!file_exists(path)) { + lua_pushnil(state); + lua_pushliteral(state, "INI file does not exist"); + return 2; + } + + int result = 1; + tmp_arena_t tmp = scratch_begin(NULL); + { + uint64_t file_len = file_size(path); + str_t text = file_read_all(path, tmp.arena); + if (file_len == 0 || !str_is_empty(text)) { + str_array_t lines = ini_split_lines(tmp.arena, text); + ini_section_list_t sections = ini_parse_sections(tmp.arena, lines); + lua_createtable(state, sections.count, 0); + + int section_index = 1; + for (ini_section_t *section = sections.first; section; section = section->next) { + lua_createtable(state, 0, 4); + lua_overdub_push_str(state, section->name); + lua_setfield(state, -2, "Name"); + + if (str_is_empty(section->arg)) { + lua_pushnil(state); + } else { + lua_overdub_push_str(state, section->arg); + } + lua_setfield(state, -2, "Argument"); + + int line_capacity = (int)MIN_VAL(section->lines.count, (uint64_t)INT32_MAX); + lua_createtable(state, line_capacity, 0); + int line_index = 1; + for (str_node_t *node = section->lines.first; node; node = node->next) { + lua_overdub_push_str(state, node->str); + lua_rawseti(state, -2, line_index); + line_index += 1; + } + lua_setfield(state, -2, "Lines"); + + lua_newtable(state); + for (str_node_t *node = section->lines.first; node; node = node->next) { + str_t key = STR_NULL; + str_t value = STR_NULL; + if (!ini_parse_kv(node->str, &key, &value)) { + continue; + } + + lua_overdub_push_str(state, key); + lua_overdub_push_str(state, value); + lua_rawset(state, -3); + } + lua_setfield(state, -2, "Values"); + + lua_rawseti(state, -2, section_index); + section_index += 1; + } + } else { + lua_pushnil(state); + lua_pushliteral(state, "could not read INI file"); + result = 2; + } + } + scratch_end(tmp); + return result; +} + +static int +lua_overdub_frame(lua_State *state) +{ + lua_overdub_context_check(state); + lua_pushinteger(state, (lua_Integer)globals.frame_counter); + return 1; +} + +static int +lua_overdub_now_us(lua_State *state) +{ + lua_overdub_context_check(state); + lua_pushinteger(state, (lua_Integer)time_now_us()); + return 1; +} + +static int +lua_overdub_log(lua_State *state) +{ + lua_overdub_context_t *context = lua_overdub_context_check(state); + int level = (int)lua_tointeger(state, lua_upvalueindex(1)); + int count = lua_gettop(state); + luaL_argcheck(state, count > 0, 1, "message or format string expected"); + + lua_getglobal(state, LUA_STRLIBNAME); + lua_getfield(state, -1, "format"); + lua_remove(state, -2); + lua_insert(state, 1); + lua_call(state, count, 1); + + size_t message_len = 0; + const char *message = luaL_checklstring(state, -1, &message_len); + int log_len = (int)MIN_VAL(message_len, (size_t)INT32_MAX); + + level = CLAMP(level, LOG_LEVEL_DEBUG, LOG_LEVEL_ERROR); + log_emit((log_level_t)level, LOG_SINK_DEFAULT, "[%.*s] %.*s", STR_ARG(context->mod_id), log_len, message); + return 0; +} + +static void +lua_overdub_set_string_field(lua_State *state, const char *name, str_t value) +{ + lua_overdub_push_str(state, value); + lua_setfield(state, -2, name); +} + +static void +lua_overdub_set_log_function(lua_State *state, const char *name, log_level_t level) +{ + lua_pushinteger(state, (lua_Integer)level); + lua_pushcclosure(state, lua_overdub_log, 1); + lua_setfield(state, -2, name); +} + +static int +luaopen_overdub(lua_State *state) +{ + lua_overdub_context_t *context = lua_overdub_context_check(state); + + lua_newtable(state); + lua_overdub_set_string_field(state, "Id", context->mod_id); + lua_overdub_set_string_field(state, "Name", context->mod_name); + lua_overdub_set_string_field(state, "GameDir", context->game_dir); + lua_overdub_set_string_field(state, "RootDir", context->root_dir); + lua_overdub_set_string_field(state, "ModDir", context->mod_dir); + + lua_pushcfunction(state, lua_overdub_frame); + lua_setfield(state, -2, "Frame"); + lua_pushcfunction(state, lua_overdub_now_us); + lua_setfield(state, -2, "NowUs"); + lua_pushcfunction(state, lua_overdub_register_command); + lua_setfield(state, -2, "RegisterCommand"); + lua_pushcfunction(state, lua_overdub_list_directory); + lua_setfield(state, -2, "ListDirectory"); + lua_pushcfunction(state, lua_overdub_read_ini); + lua_setfield(state, -2, "ReadIni"); + + lua_newtable(state); + lua_overdub_set_log_function(state, "Debug", LOG_LEVEL_DEBUG); + lua_overdub_set_log_function(state, "Info", LOG_LEVEL_INFO); + lua_overdub_set_log_function(state, "Warn", LOG_LEVEL_WARN); + lua_overdub_set_log_function(state, "Error", LOG_LEVEL_ERROR); + lua_setfield(state, -2, "Log"); + return 1; +} + +static bool +lua_overdub_prepend_package_field(lua_State *state, const char *field, str_t first_dir, str_t second_dir, + const char *first_suffix, const char *second_suffix) +{ + lua_getglobal(state, LUA_LOADLIBNAME); + if (!lua_istable(state, -1)) { + lua_pop(state, 1); + return false; + } + + lua_getfield(state, -1, field); + size_t old_len = 0; + const char *old_path = lua_tolstring(state, -1, &old_len); + + luaL_Buffer buffer; + luaL_buffinit(state, &buffer); + if (!str_is_empty(first_dir)) { + luaL_addlstring(&buffer, (const char *)first_dir.data, (size_t)first_dir.len); + luaL_addstring(&buffer, first_suffix); + + if (second_suffix) { + luaL_addlstring(&buffer, (const char *)first_dir.data, (size_t)first_dir.len); + luaL_addstring(&buffer, second_suffix); + } + } + + if (!str_is_empty(second_dir) && !path_equal(first_dir, second_dir)) { + luaL_addlstring(&buffer, (const char *)second_dir.data, (size_t)second_dir.len); + luaL_addstring(&buffer, first_suffix); + + if (second_suffix) { + luaL_addlstring(&buffer, (const char *)second_dir.data, (size_t)second_dir.len); + luaL_addstring(&buffer, second_suffix); + } + } + + if (old_path && old_len > 0) { + luaL_addlstring(&buffer, old_path, old_len); + } + luaL_pushresult(&buffer); + + lua_setfield(state, -3, field); + lua_pop(state, 2); // previous value and package table + return true; +} + +bool +lua_overdub_preload_module(lua_State *state, const char *name, int (*open_fn)(lua_State *state)) +{ + if (!state || !name || !open_fn) { + return false; + } + + luaL_getsubtable(state, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); + lua_pushcfunction(state, open_fn); + lua_setfield(state, -2, name); + lua_pop(state, 1); + return true; +} + +bool +lua_overdub_configure_package_paths(lua_State *state, str_t entry_path, str_t mod_dir) +{ + if (!state) { + return false; + } + + str_t entry_dir = path_dir(entry_path); + return lua_overdub_prepend_package_field(state, "path", entry_dir, mod_dir, "/?.lua;", "/?/init.lua;") && + lua_overdub_prepend_package_field(state, "cpath", entry_dir, mod_dir, "/?.dll;", NULL); +} + +bool +lua_overdub_register(lua_State *state, lua_overdub_context_t *context) +{ + if (!state || !context || !context->arena || !context->arena->backing || context->owner_thread_id == 0 || context->owner_thread_id != thread_current_id()) { + return false; + } + + lua_pushlightuserdata(state, &g_lua_overdub_context_key); + lua_pushlightuserdata(state, context); + lua_rawset(state, LUA_REGISTRYINDEX); + + context->commands = ARENA_PUSH_ZERO(context->arena, lua_overdub_command_context_t); + if (!context->commands) { + return false; + } + context->commands->state = state; + context->commands->next_id = 1; + + if (luaL_newmetatable(state, LUA_OVERDUB_COMMAND_META)) { + static const luaL_Reg methods[] = { + {"Remove", lua_overdub_command_handle_remove }, + {"IsActive", lua_overdub_command_handle_is_active}, + {NULL, NULL }, + }; + + luaL_setfuncs(state, methods, 0); + lua_pushvalue(state, -1); + lua_setfield(state, -2, "__index"); + lua_pushcfunction(state, lua_overdub_command_handle_gc); + lua_setfield(state, -2, "__gc"); + lua_pushliteral(state, "Overdub console command"); + lua_setfield(state, -2, "__metatable"); + } + lua_pop(state, 1); + + if (!lua_overdub_configure_package_paths(state, context->entry_path, context->mod_dir)) { + lua_overdub_context_cleanup(context); + return false; + } + + bool registered = lua_overdub_preload_module(state, "overdub", luaopen_overdub); + if (!registered) { + lua_overdub_context_cleanup(context); + } + + return registered; +} diff --git a/src/lua_overdub_input.c b/src/lua_overdub_input.c new file mode 100644 index 0000000..87be7f6 --- /dev/null +++ b/src/lua_overdub_input.c @@ -0,0 +1,219 @@ +#include "lua_overdub_input.h" + +#include "globals.h" +#include "lua_overdub.h" +#include "str.h" + +#include "lua/src/lauxlib.h" +#include "lua/src/lua.h" + +#include +#include + +#define LUA_OVERDUB_INPUT_EVENT_META "overdub.input.Event" + +typedef struct lua_overdub_input_event_s lua_overdub_input_event_t; +struct lua_overdub_input_event_s { + input_event_t value; +}; + +static input_key_kind_t +lua_overdub_input_check_key(lua_State *state, int idx) +{ + size_t name_len = 0; + const char *name_data = luaL_checklstring(state, idx, &name_len); + str_t name = str_make((void *)name_data, (uint64_t)name_len); + input_key_kind_t key = input_key_from_str(name); + + if (key == INPUT_KEY_NONE) { + keybind_t bind = keybind_parse(name, KEYBIND_NULL); + if (bind.count == 1) { + key = bind.keys[0]; + } + } + + if (key == INPUT_KEY_NONE) { + luaL_error(state, "unknown input key '%.*s'", (int)name.len, name.data); + } + return key; +} + +static int +lua_overdub_input_down(lua_State *state) +{ + lua_overdub_context_check(state); + lua_pushboolean(state, input_key_is_down(lua_overdub_input_check_key(state, 1))); + return 1; +} + +static int +lua_overdub_input_pressed(lua_State *state) +{ + lua_overdub_context_check(state); + lua_pushboolean(state, input_key_is_pressed(lua_overdub_input_check_key(state, 1))); + return 1; +} + +static int +lua_overdub_input_released(lua_State *state) +{ + lua_overdub_context_check(state); + lua_pushboolean(state, input_key_is_released(lua_overdub_input_check_key(state, 1))); + return 1; +} + +static int +lua_overdub_input_analog(lua_State *state) +{ + lua_overdub_context_check(state); + lua_pushnumber(state, (lua_Number)input_key_get_analog_value(lua_overdub_input_check_key(state, 1))); + return 1; +} + +static int +lua_overdub_input_wheel_delta(lua_State *state) +{ + lua_overdub_context_check(state); + lua_pushnumber(state, (lua_Number)globals.wheel_delta); + return 1; +} + +static int +lua_overdub_input_mouse_position(lua_State *state) +{ + lua_overdub_context_check(state); + POINT position = {0}; + GetCursorPos(&position); + if (globals.hwnd) { + ScreenToClient((HWND)globals.hwnd, &position); + } + lua_pushinteger(state, (lua_Integer)position.x); + lua_pushinteger(state, (lua_Integer)position.y); + return 2; +} + +static const char * +lua_overdub_input_event_kind(input_event_kind_t kind) +{ + switch (kind) { + case INPUT_EVENT_KEY_DOWN: return "KeyDown"; + case INPUT_EVENT_KEY_UP: return "KeyUp"; + case INPUT_EVENT_KEY_CHAR: return "Character"; + case INPUT_EVENT_MOUSE_DOWN: return "MouseDown"; + case INPUT_EVENT_MOUSE_UP: return "MouseUp"; + case INPUT_EVENT_MOUSE_DBLCLICK: return "MouseDoubleClick"; + case INPUT_EVENT_MOUSE_MOVE: return "MouseMove"; + case INPUT_EVENT_MOUSE_WHEEL: return "MouseWheel"; + case INPUT_EVENT_ANALOG: return "Analog"; + case INPUT_EVENT_APP_ACTIVATION: return "AppActivation"; + } + return "Unknown"; +} + +static int +lua_overdub_input_event_index(lua_State *state) +{ + lua_overdub_input_event_t *event = luaL_checkudata(state, 1, LUA_OVERDUB_INPUT_EVENT_META); + const char *field = luaL_checkstring(state, 2); + input_event_t *value = &event->value; + + if (strcmp(field, "Kind") == 0) { + lua_pushstring(state, lua_overdub_input_event_kind(value->kind)); + } else if (strcmp(field, "Key") == 0) { + str_t key = input_key_to_str(value->key); + if (str_is_empty(key)) { + lua_pushnil(state); + } else { + lua_pushlstring(state, (const char *)key.data, (size_t)key.len); + } + } else if (strcmp(field, "Pressed") == 0) { + lua_pushboolean(state, value->kind == INPUT_EVENT_KEY_DOWN || value->kind == INPUT_EVENT_MOUSE_DOWN || value->kind == INPUT_EVENT_MOUSE_DBLCLICK); + } else if (strcmp(field, "Released") == 0) { + lua_pushboolean(state, value->kind == INPUT_EVENT_KEY_UP || value->kind == INPUT_EVENT_MOUSE_UP); + } else if (strcmp(field, "Repeat") == 0) { + lua_pushboolean(state, value->is_repeat); + } else if (strcmp(field, "Shift") == 0) { + lua_pushboolean(state, (value->modifiers & INPUT_MOD_SHIFT) != 0); + } else if (strcmp(field, "Ctrl") == 0) { + lua_pushboolean(state, (value->modifiers & INPUT_MOD_CTRL) != 0); + } else if (strcmp(field, "Alt") == 0) { + lua_pushboolean(state, (value->modifiers & INPUT_MOD_ALT) != 0); + } else if (strcmp(field, "Keyboard") == 0) { + lua_pushboolean(state, input_event_is_keyboard(value)); + } else if (strcmp(field, "Mouse") == 0) { + lua_pushboolean(state, input_event_is_mouse(value)); + } else if (strcmp(field, "Gamepad") == 0) { + lua_pushboolean(state, input_event_is_gamepad(value)); + } else if (strcmp(field, "Character") == 0 && value->kind == INPUT_EVENT_KEY_CHAR) { + lua_pushinteger(state, (lua_Integer)value->character); + } else if (strcmp(field, "Activated") == 0 && value->kind == INPUT_EVENT_APP_ACTIVATION) { + lua_pushboolean(state, value->app_activated); + } else if (strcmp(field, "ScreenX") == 0 && input_event_is_mouse(value)) { + lua_pushinteger(state, (lua_Integer)value->screen_x); + } else if (strcmp(field, "ScreenY") == 0 && input_event_is_mouse(value)) { + lua_pushinteger(state, (lua_Integer)value->screen_y); + } else if (strcmp(field, "ClientX") == 0 && input_event_is_mouse(value)) { + lua_pushinteger(state, (lua_Integer)value->client_x); + } else if (strcmp(field, "ClientY") == 0 && input_event_is_mouse(value)) { + lua_pushinteger(state, (lua_Integer)value->client_y); + } else if (strcmp(field, "DeltaX") == 0 && value->kind == INPUT_EVENT_MOUSE_MOVE) { + lua_pushnumber(state, (lua_Number)value->delta_x); + } else if (strcmp(field, "DeltaY") == 0 && value->kind == INPUT_EVENT_MOUSE_MOVE) { + lua_pushnumber(state, (lua_Number)value->delta_y); + } else if (strcmp(field, "WheelDelta") == 0 && value->kind == INPUT_EVENT_MOUSE_WHEEL) { + lua_pushnumber(state, (lua_Number)value->wheel_delta); + } else if (strcmp(field, "AnalogValue") == 0 && value->kind == INPUT_EVENT_ANALOG) { + lua_pushnumber(state, (lua_Number)value->analog_value); + } else { + lua_pushnil(state); + } + return 1; +} + +static int +luaopen_overdub_input(lua_State *state) +{ + lua_overdub_context_check(state); + static const luaL_Reg functions[] = { + {"Down", lua_overdub_input_down }, + {"Pressed", lua_overdub_input_pressed }, + {"Released", lua_overdub_input_released }, + {"Analog", lua_overdub_input_analog }, + {"WheelDelta", lua_overdub_input_wheel_delta }, + {"MousePosition", lua_overdub_input_mouse_position}, + {NULL, NULL }, + }; + luaL_newlib(state, functions); + return 1; +} + +bool +lua_overdub_input_register(lua_State *state) +{ + if (!state) { + return false; + } + + if (luaL_newmetatable(state, LUA_OVERDUB_INPUT_EVENT_META)) { + lua_pushcfunction(state, lua_overdub_input_event_index); + lua_setfield(state, -2, "__index"); + lua_pushliteral(state, "immutable Overdub input event"); + lua_setfield(state, -2, "__metatable"); + } + + lua_pop(state, 1); + return lua_overdub_preload_module(state, "overdub.input", luaopen_overdub_input); +} + +bool +lua_overdub_input_push_event(lua_State *state, const input_event_t *event) +{ + if (!state || !event) { + return false; + } + + lua_overdub_input_event_t *value = lua_newuserdatauv(state, sizeof(*value), 0); + value->value = *event; + luaL_setmetatable(state, LUA_OVERDUB_INPUT_EVENT_META); + return true; +} diff --git a/src/lua_overdub_runtime.c b/src/lua_overdub_runtime.c new file mode 100644 index 0000000..37572a0 --- /dev/null +++ b/src/lua_overdub_runtime.c @@ -0,0 +1,656 @@ +#include "lua_overdub_runtime.h" + +#include "config.h" +#include "file.h" +#include "globals.h" +#include "log.h" +#include "lua_overdub.h" +#include "lua_overdub_input.h" +#include "lua_overdub_task.h" +#include "lua_overdub_ui.h" +#include "lua_overdub_unreal.h" +#include "lua_overdub_worker.h" +#include "lua_runtime.h" +#include "mod_manager.h" + +#include "lua/src/lauxlib.h" +#include "lua/src/lua.h" + +#include + +typedef struct lua_overdub_runtime_s lua_overdub_runtime_t; +struct lua_overdub_runtime_s { + lua_runtime_t lua; + lua_overdub_context_t api; + lua_overdub_task_context_t *tasks; + lua_overdub_ui_context_t *ui; + lua_overdub_unreal_context_t *unreal; + lua_overdub_worker_context_t *worker; + uint32_t owner_thread_id; + int startup_ref; + int tick_ref; + int input_ref; + int draw_panel_ref; + int draw_config_ref; + int shutdown_ref; + input_event_t pending_inputs[CONFIG_LUA_OVERDUB_MAX_PENDING_INPUTS]; + int pending_input_count; + bool startup_completed; + bool in_callback; +}; + +typedef struct lua_overdub_frame_budget_s lua_overdub_frame_budget_t; +struct lua_overdub_frame_budget_s { + uint64_t frame; + uint64_t lua_us; + uint64_t scheduler_us; +}; + +static lua_overdub_frame_budget_t g_lua_overdub_frame_budget = { + .frame = UINT64_MAX, +}; + +static void +lua_overdub_frame_budget_sync(void) +{ + if (g_lua_overdub_frame_budget.frame != globals.frame_counter) { + g_lua_overdub_frame_budget = (lua_overdub_frame_budget_t){ + .frame = globals.frame_counter, + }; + } +} + +static void +lua_overdub_frame_budget_add_lua(uint64_t elapsed_us) +{ + lua_overdub_frame_budget_sync(); + g_lua_overdub_frame_budget.lua_us += elapsed_us; +} + +static lua_overdub_runtime_t * +lua_overdub_runtime_from_mod(mod_t *mod) +{ + return mod ? (lua_overdub_runtime_t *)mod->lua.instance : NULL; +} + +static bool +lua_overdub_ref_valid(int ref) +{ + return ref != LUA_NOREF && ref != LUA_REFNIL; +} + +static void +lua_overdub_error_set(err_msg_t *error, str_t message) +{ + if (!error) { + return; + } + + error->len = (int)MIN_VAL(message.len, sizeof(error->msg)); + if (error->len > 0) { + mem_copy(error->msg, message.data, (uint64_t)error->len); + } +} + +static bool +lua_overdub_on_owner_thread(lua_overdub_runtime_t *runtime) +{ + return runtime && runtime->owner_thread_id != 0 && runtime->owner_thread_id == thread_current_id(); +} + +static void +lua_overdub_unref(lua_overdub_runtime_t *runtime, int *ref) +{ + if (!runtime || !runtime->lua.state || !ref || !lua_overdub_ref_valid(*ref)) { + return; + } + + luaL_unref(runtime->lua.state, LUA_REGISTRYINDEX, *ref); + *ref = LUA_NOREF; +} + +static void +lua_overdub_cleanup(mod_t *mod) +{ + lua_overdub_runtime_t *runtime = lua_overdub_runtime_from_mod(mod); + if (!runtime) { + if (mod) { + mod->lua.active = false; + } + return; + } + + lua_overdub_unref(runtime, &runtime->startup_ref); + lua_overdub_unref(runtime, &runtime->tick_ref); + lua_overdub_unref(runtime, &runtime->input_ref); + lua_overdub_unref(runtime, &runtime->draw_panel_ref); + lua_overdub_unref(runtime, &runtime->draw_config_ref); + lua_overdub_unref(runtime, &runtime->shutdown_ref); + + lua_overdub_ui_context_destroy(runtime->ui); + runtime->ui = NULL; + + lua_overdub_task_context_destroy(runtime->tasks); + runtime->tasks = NULL; + + lua_overdub_worker_context_destroy(runtime->worker); + runtime->worker = NULL; + + lua_overdub_context_cleanup(&runtime->api); + lua_overdub_unreal_context_deactivate(runtime->unreal); + lua_runtime_deinit(&runtime->lua); + lua_overdub_unreal_context_destroy(runtime->unreal); + runtime->unreal = NULL; + + mod->lua.instance = NULL; + mod->lua.active = false; + arena_destroy(&mod->lua.perm); +} + +static bool +lua_overdub_lifecycle_ref(lua_State *state, int table_idx, const char *name, int *out_ref) +{ + table_idx = lua_absindex(state, table_idx); + lua_getfield(state, table_idx, name); + if (lua_isnil(state, -1)) { + lua_pop(state, 1); + *out_ref = LUA_NOREF; + return true; + } + + if (!lua_isfunction(state, -1)) { + LOG_ERROR("Overdub lifecycle field '%s' must be a function or nil", name); + lua_pop(state, 1); + return false; + } + + *out_ref = luaL_ref(state, LUA_REGISTRYINDEX); + return true; +} + +static bool +lua_overdub_load_lifecycle(mod_t *mod, lua_overdub_runtime_t *runtime) +{ + if (!lua_runtime_execute_file_results(&runtime->lua, mod->manifest.lua.path, 1)) { + lua_overdub_error_set(&mod->lua.err_msg, STR_LIT("Lua entry script failed")); + return false; + } + + lua_State *state = runtime->lua.state; + if (!lua_istable(state, -1)) { + LOG_ERROR("Overdub Lua mod '%.*s' entry script must return a lifecycle table", STR_ARG(mod->manifest.info.id)); + lua_overdub_error_set(&mod->lua.err_msg, STR_LIT("Lua entry script must return a lifecycle table")); + lua_settop(state, 0); + return false; + } + + struct { + const char *name; + int *ref; + } callbacks[] = { + {"Startup", &runtime->startup_ref }, + {"Tick", &runtime->tick_ref }, + {"Input", &runtime->input_ref }, + {"DrawPanel", &runtime->draw_panel_ref }, + {"DrawConfig", &runtime->draw_config_ref}, + {"Shutdown", &runtime->shutdown_ref }, + }; + + bool valid = true; + for (int i = 0; i < COUNTOF(callbacks); ++i) { + if (!lua_overdub_lifecycle_ref(state, -1, callbacks[i].name, callbacks[i].ref)) { + valid = false; + break; + } + } + + lua_settop(state, 0); + if (!valid) { + lua_overdub_error_set(&mod->lua.err_msg, STR_LIT("Lua entry script contains an invalid lifecycle callback")); + } + + return valid; +} + +static bool +lua_overdub_call(lua_overdub_runtime_t *runtime, int callback_ref, int arg_count, int result_count, const char *name) +{ + if (!runtime || callback_ref == LUA_NOREF || callback_ref == LUA_REFNIL) { + return true; + } + + if (!lua_overdub_on_owner_thread(runtime)) { + LOG_ERROR("Overdub lifecycle callback '%s' was invoked outside its owning game thread", name); + if (runtime->lua.state) { + lua_pop(runtime->lua.state, arg_count); + } + return false; + } + + if (runtime->in_callback) { + LOG_WARN("Overdub lifecycle callback '%s' was not invoked recursively", name); + lua_pop(runtime->lua.state, arg_count); + return false; + } + + runtime->in_callback = true; + bool called = lua_runtime_call_ref(&runtime->lua, callback_ref, arg_count, result_count); + runtime->in_callback = false; + return called; +} + +static bool +lua_overdub_dispatch_input(lua_overdub_runtime_t *runtime, mod_t *mod, const input_event_t *event) +{ + if (!runtime || !event || !lua_overdub_ref_valid(runtime->input_ref)) { + return false; + } + + if (!lua_overdub_input_push_event(runtime->lua.state, event)) { + return false; + } + + uint64_t start_us = time_now_us(); + bool called = lua_overdub_call(runtime, runtime->input_ref, 1, 1, "Input"); + lua_overdub_frame_budget_add_lua(time_now_us() - start_us); + if (!called) { + LOG_ERROR("Overdub Lua mod '%.*s': disabling failed Input callback", STR_ARG(mod->manifest.info.id)); + lua_overdub_unref(runtime, &runtime->input_ref); + return false; + } + + bool consumed = lua_toboolean(runtime->lua.state, -1); + lua_pop(runtime->lua.state, 1); + return consumed; +} + +static void +lua_overdub_dispatch_pending_inputs(lua_overdub_runtime_t *runtime, mod_t *mod) +{ + if (!runtime || runtime->pending_input_count <= 0) { + return; + } + + input_event_t pending[CONFIG_LUA_OVERDUB_MAX_PENDING_INPUTS]; + int count = runtime->pending_input_count; + mem_copy(pending, runtime->pending_inputs, sizeof(*pending) * (uint64_t)count); + + runtime->pending_input_count = 0; + for (int i = 0; i < count; ++i) { + if (!lua_overdub_ref_valid(runtime->input_ref)) { + break; + } + + lua_overdub_dispatch_input(runtime, mod, &pending[i]); + } +} + +void +lua_overdub_runtime_system_init(void) +{ + g_lua_overdub_frame_budget.frame = UINT64_MAX; +} + +bool +lua_overdub_runtime_start(mod_t *mod) +{ + if (!mod || !mod->has_lua || mod->manifest.lua.runtime_kind != MOD_LUA_RUNTIME_OVERDUB) { + return false; + } + + if (!unreal_is_in_game_thread()) { + lua_overdub_error_set(&mod->lua.err_msg, STR_LIT("Overdub Lua runtime can only be started from the game thread")); + return false; + } + + lua_overdub_runtime_t *runtime = lua_overdub_runtime_from_mod(mod); + if (mod->lua.active || runtime) { + return true; + } + + mod->lua.start_attempted = true; + lua_overdub_error_set(&mod->lua.err_msg, STR_NULL); + if (!file_exists(mod->manifest.lua.path)) { + lua_overdub_error_set(&mod->lua.err_msg, STR_LIT("Lua entry file does not exist")); + return false; + } + + mod->lua.perm = arena_new_dynamic(CONFIG_LUA_OVERDUB_ARENA_RESERVE_SIZE, CONFIG_LUA_OVERDUB_ARENA_COMMIT_SIZE); + runtime = ARENA_PUSH_ZERO(&mod->lua.perm, lua_overdub_runtime_t); + if (!runtime) { + lua_overdub_error_set(&mod->lua.err_msg, STR_LIT("failed to allocate Overdub Lua runtime")); + arena_destroy(&mod->lua.perm); + return false; + } + + runtime->owner_thread_id = globals.game_thread_id; + runtime->startup_ref = LUA_NOREF; + runtime->tick_ref = LUA_NOREF; + runtime->input_ref = LUA_NOREF; + runtime->draw_panel_ref = LUA_NOREF; + runtime->draw_config_ref = LUA_NOREF; + runtime->shutdown_ref = LUA_NOREF; + runtime->api = (lua_overdub_context_t){ + .arena = &mod->lua.perm, + .mod_id = mod->manifest.info.id, + .mod_name = mod->manifest.info.name, + .game_dir = mod->lua.game_dir, + .root_dir = mod->lua.root_mod_dir, + .mod_dir = mod->manifest.mod_dir, + .entry_path = mod->manifest.lua.path, + .owner_thread_id = globals.game_thread_id, + }; + mod->lua.instance = runtime; + + bool lua_ready = lua_runtime_init_with_execution_limit(&runtime->lua, CONFIG_LUA_OVERDUB_STARTUP_LIMIT_US); + if (!lua_ready || !lua_runtime_enable_mod_libs(&runtime->lua)) { + lua_overdub_error_set(&mod->lua.err_msg, STR_LIT("failed to initialize Overdub Lua runtime")); + lua_overdub_cleanup(mod); + return false; + } + + runtime->lua.persistent_output = true; + str_t mod_id = mod->manifest.info.id; + str_t entry_path = mod->manifest.lua.path; + str_t mod_dir = mod->manifest.mod_dir; + uint32_t owner_thread_id = globals.game_thread_id; + + runtime->worker = lua_overdub_worker_context_create(&mod->lua.perm, mod_id, entry_path, mod_dir, owner_thread_id); + runtime->tasks = lua_overdub_task_context_create(&mod->lua.perm, &runtime->lua, runtime->worker, mod_id); + runtime->ui = lua_overdub_ui_context_create(&mod->lua.perm, &runtime->lua, mod_id, owner_thread_id); + runtime->unreal = lua_overdub_unreal_context_create(&mod->lua.perm, &runtime->lua, &runtime->in_callback, mod_id, owner_thread_id); + + bool contexts_ready = runtime->worker && runtime->tasks && runtime->ui && runtime->unreal; + bool packages_ready = contexts_ready && lua_overdub_register(runtime->lua.state, &runtime->api); + packages_ready = packages_ready && lua_overdub_input_register(runtime->lua.state); + packages_ready = packages_ready && lua_overdub_task_register(runtime->lua.state, runtime->tasks); + packages_ready = packages_ready && lua_overdub_ui_register(runtime->lua.state, runtime->ui); + packages_ready = packages_ready && lua_overdub_unreal_register(runtime->lua.state, runtime->unreal); + if (!packages_ready) { + lua_overdub_error_set(&mod->lua.err_msg, STR_LIT("failed to register Overdub Lua packages")); + lua_overdub_cleanup(mod); + return false; + } + + if (!lua_overdub_load_lifecycle(mod, runtime)) { + lua_overdub_cleanup(mod); + return false; + } + + if (!lua_overdub_call(runtime, runtime->startup_ref, 0, 0, "Startup")) { + lua_overdub_error_set(&mod->lua.err_msg, STR_LIT("Lua Startup callback failed")); + lua_overdub_cleanup(mod); + return false; + } + + runtime->startup_completed = true; + runtime->lua.execution_limit_us = CONFIG_LUA_OVERDUB_CALLBACK_LIMIT_US; + mod->lua.active = true; + LOG_INFO("Lua mod '%.*s' started on the game thread with the native Overdub runtime", STR_ARG(mod->manifest.info.id)); + return true; +} + +void +lua_overdub_runtime_stop(mod_t *mod) +{ + if (!mod || !mod->has_lua) { + return; + } + + lua_overdub_runtime_t *runtime = lua_overdub_runtime_from_mod(mod); + if (runtime && lua_overdub_on_owner_thread(runtime) && runtime->startup_completed) { + lua_overdub_call(runtime, runtime->shutdown_ref, 0, 0, "Shutdown"); + } else if (runtime && !lua_overdub_on_owner_thread(runtime)) { + LOG_ERROR("Overdub Lua mod '%.*s' cannot be stopped outside its owning game thread", STR_ARG(mod->manifest.info.id)); + return; + } + + lua_overdub_cleanup(mod); + mod->lua.start_attempted = false; +} + +bool +lua_overdub_runtime_is_initialized(mod_t *mod) +{ + lua_overdub_runtime_t *runtime = lua_overdub_runtime_from_mod(mod); + return runtime && runtime->lua.inited; +} + +void +lua_overdub_runtime_tick(mod_t *mod, float delta_seconds) +{ + lua_overdub_runtime_t *runtime = lua_overdub_runtime_from_mod(mod); + if (!runtime || !mod->lua.active) { + return; + } + + if (!lua_overdub_on_owner_thread(runtime)) { + LOG_ERROR("Overdub Lua mod '%.*s' Tick was dispatched outside its owning game thread", STR_ARG(mod->manifest.info.id)); + return; + } + + if (lua_overdub_ref_valid(runtime->tick_ref)) { + lua_pushnumber(runtime->lua.state, (lua_Number)delta_seconds); + uint64_t callback_start_us = time_now_us(); + if (!lua_overdub_call(runtime, runtime->tick_ref, 1, 0, "Tick")) { + LOG_ERROR("Overdub Lua mod '%.*s': disabling failed Tick callback", STR_ARG(mod->manifest.info.id)); + lua_overdub_unref(runtime, &runtime->tick_ref); + } + lua_overdub_frame_budget_add_lua(time_now_us() - callback_start_us); + } + + lua_overdub_dispatch_pending_inputs(runtime, mod); + + lua_overdub_frame_budget_sync(); + if (lua_overdub_unreal_pending_count(runtime->unreal) > 0 && g_lua_overdub_frame_budget.lua_us < CONFIG_LUA_OVERDUB_FRAME_SOFT_BUDGET_US) { + uint64_t dispatch_budget = CONFIG_LUA_OVERDUB_FRAME_SOFT_BUDGET_US - g_lua_overdub_frame_budget.lua_us; + uint64_t elapsed_us = lua_overdub_unreal_dispatch_pending(runtime->unreal, &runtime->lua, &runtime->in_callback, dispatch_budget); + g_lua_overdub_frame_budget.lua_us += elapsed_us; + } + + if (lua_overdub_task_future_count(runtime->tasks) > 0 && g_lua_overdub_frame_budget.lua_us < CONFIG_LUA_OVERDUB_FRAME_SOFT_BUDGET_US) { + uint64_t dispatch_budget = CONFIG_LUA_OVERDUB_FRAME_SOFT_BUDGET_US - g_lua_overdub_frame_budget.lua_us; + uint64_t elapsed_us = lua_overdub_task_dispatch_worker_completions(runtime->tasks, &runtime->in_callback, dispatch_budget); + g_lua_overdub_frame_budget.lua_us += elapsed_us; + } + + bool has_tasks = lua_overdub_task_active_count(runtime->tasks) > 0; + bool has_lua_budget = g_lua_overdub_frame_budget.lua_us < CONFIG_LUA_OVERDUB_FRAME_SOFT_BUDGET_US; + bool has_sched_budget = g_lua_overdub_frame_budget.scheduler_us < CONFIG_LUA_OVERDUB_SCHEDULER_CEILING_US; + if (has_tasks && has_lua_budget && has_sched_budget) { + uint64_t aggregate_remaining = CONFIG_LUA_OVERDUB_FRAME_SOFT_BUDGET_US - g_lua_overdub_frame_budget.lua_us; + uint64_t scheduler_remaining = CONFIG_LUA_OVERDUB_SCHEDULER_CEILING_US - g_lua_overdub_frame_budget.scheduler_us; + uint64_t dispatch_budget = MIN_VAL(aggregate_remaining, scheduler_remaining); + runtime->in_callback = true; + uint64_t elapsed_us = lua_overdub_task_dispatch(runtime->tasks, dispatch_budget); + runtime->in_callback = false; + g_lua_overdub_frame_budget.lua_us += elapsed_us; + g_lua_overdub_frame_budget.scheduler_us += elapsed_us; + } + + struct nk_context *nk = globals.ui_manager.ctx; + if (nk) { + uint64_t elapsed_us = lua_overdub_ui_draw_windows(runtime->ui, nk, &runtime->in_callback, globals.ui_manager.vw, globals.ui_manager.vh); + lua_overdub_frame_budget_add_lua(elapsed_us); + } +} + +bool +lua_overdub_runtime_input(mod_t *mod, input_event_t *event) +{ + lua_overdub_runtime_t *runtime = lua_overdub_runtime_from_mod(mod); + if (!runtime || !mod->lua.active || !event || !lua_overdub_on_owner_thread(runtime)) { + return false; + } + + if (!lua_overdub_ref_valid(runtime->input_ref)) { + return false; + } + + if (runtime->in_callback) { + if (runtime->pending_input_count < CONFIG_LUA_OVERDUB_MAX_PENDING_INPUTS) { + runtime->pending_inputs[runtime->pending_input_count++] = *event; + } else { + LOG_WARN_LIMITED(1, "Overdub Lua mod '%.*s': nested input queue is full; dropping events", STR_ARG(mod->manifest.info.id)); + } + return false; + } + return lua_overdub_dispatch_input(runtime, mod, event); +} + +bool +lua_overdub_runtime_process_event_pre(mod_t *mod, uobject_t *object, ufunc_t *function, void *params) +{ + lua_overdub_runtime_t *runtime = lua_overdub_runtime_from_mod(mod); + if (!runtime || !mod->lua.active || !lua_overdub_on_owner_thread(runtime)) { + return false; + } + + uint64_t start_us = time_now_us(); + bool consumed = lua_overdub_unreal_process_event_pre(runtime->unreal, &runtime->lua, &runtime->in_callback, object, function, params); + lua_overdub_frame_budget_add_lua(time_now_us() - start_us); + return consumed; +} + +void +lua_overdub_runtime_process_event_post(mod_t *mod, uobject_t *object, ufunc_t *function, void *params, bool consumed) +{ + lua_overdub_runtime_t *runtime = lua_overdub_runtime_from_mod(mod); + if (!runtime || !mod->lua.active || !lua_overdub_on_owner_thread(runtime)) { + return; + } + + uint64_t start_us = time_now_us(); + lua_overdub_unreal_process_event_post(runtime->unreal, &runtime->lua, &runtime->in_callback, object, function, params, consumed); + lua_overdub_frame_budget_add_lua(time_now_us() - start_us); +} + +void +lua_overdub_runtime_post_load(mod_t *mod, uobject_t *object, bool after) +{ + lua_overdub_runtime_t *runtime = lua_overdub_runtime_from_mod(mod); + if (!runtime || !mod->lua.active || !lua_overdub_on_owner_thread(runtime)) { + return; + } + + uint64_t start_us = time_now_us(); + lua_overdub_unreal_post_load(runtime->unreal, &runtime->lua, &runtime->in_callback, object, after); + lua_overdub_frame_budget_add_lua(time_now_us() - start_us); +} + +bool +lua_overdub_runtime_has_post_load_hooks(void) +{ + return lua_overdub_unreal_has_post_load_hooks(); +} + +bool +lua_overdub_runtime_command(mod_t *mod, str_t name, str_t args) +{ + lua_overdub_runtime_t *runtime = lua_overdub_runtime_from_mod(mod); + if (!runtime || !mod->lua.active || !lua_overdub_on_owner_thread(runtime)) { + return false; + } + + uint64_t command_id = 0; + int callback_ref = LUA_NOREF; + if (!lua_overdub_command_find(&runtime->api, name, &command_id, &callback_ref)) { + return false; + } + + const char *arg_data = ""; + if (args.data) { + arg_data = (const char *)args.data; + } + + lua_pushlstring(runtime->lua.state, arg_data, (size_t)args.len); + uint64_t start_us = time_now_us(); + bool called = lua_overdub_call(runtime, callback_ref, 1, 0, "console command"); + lua_overdub_frame_budget_add_lua(time_now_us() - start_us); + + if (!called) { + LOG_ERROR("Overdub Lua mod '%.*s': removing failed console command '%.*s'", STR_ARG(mod->manifest.info.id), STR_ARG(name)); + lua_overdub_command_remove(&runtime->api, command_id); + } + + return true; +} + +void +lua_overdub_runtime_notify_uobject_constructed(mod_manager_t *manager, uobject_t *object) +{ + (void)manager; + lua_overdub_unreal_notify_constructed(object); +} + +void +lua_overdub_runtime_notify_uobject_deleted(mod_manager_t *manager, uobject_t *object, int32_t idx) +{ + (void)manager; + lua_overdub_unreal_notify_deleted(object, idx); +} + +int +lua_overdub_runtime_snapshot_commands(mod_t *mod, str_t *names, int capacity) +{ + lua_overdub_runtime_t *runtime = lua_overdub_runtime_from_mod(mod); + if (!runtime || !mod->lua.active || !lua_overdub_on_owner_thread(runtime)) { + return 0; + } + + return lua_overdub_command_snapshot(&runtime->api, names, capacity); +} + +static bool +lua_overdub_runtime_draw_lifecycle(mod_t *mod, struct nk_context *nk, int *ref, const char *name) +{ + lua_overdub_runtime_t *runtime = lua_overdub_runtime_from_mod(mod); + if (!runtime || !mod->lua.active || !lua_overdub_ref_valid(*ref)) { + return false; + } + + if (!lua_overdub_on_owner_thread(runtime)) { + LOG_ERROR("Overdub Lua mod '%.*s' %s was dispatched outside its owning game thread", STR_ARG(mod->manifest.info.id), name); + return true; + } + + if (!lua_overdub_ui_begin_callback(runtime->ui, nk, globals.ui_manager.vw, globals.ui_manager.vh)) { + LOG_ERROR("Overdub Lua mod '%.*s' could not begin %s", STR_ARG(mod->manifest.info.id), name); + return true; + } + + uint64_t start_us = time_now_us(); + bool called = lua_overdub_call(runtime, *ref, 1, 0, name); + lua_overdub_ui_end_callback(runtime->ui); + lua_overdub_frame_budget_add_lua(time_now_us() - start_us); + + if (!called) { + LOG_ERROR("Overdub Lua mod '%.*s': disabling failed %s callback", STR_ARG(mod->manifest.info.id), name); + lua_overdub_unref(runtime, ref); + } + + return true; +} + +void +lua_overdub_runtime_draw_panel(mod_t *mod, struct nk_context *ctx) +{ + lua_overdub_runtime_t *runtime = lua_overdub_runtime_from_mod(mod); + if (runtime) { + lua_overdub_runtime_draw_lifecycle(mod, ctx, &runtime->draw_panel_ref, "DrawPanel"); + } +} + +bool +lua_overdub_runtime_draw_config(mod_t *mod, struct nk_context *ctx) +{ + lua_overdub_runtime_t *runtime = lua_overdub_runtime_from_mod(mod); + return runtime && lua_overdub_runtime_draw_lifecycle(mod, ctx, &runtime->draw_config_ref, "DrawConfig"); +} + +bool +lua_overdub_runtime_has_draw_config(mod_t *mod) +{ + lua_overdub_runtime_t *runtime = lua_overdub_runtime_from_mod(mod); + return runtime && mod->lua.active && lua_overdub_ref_valid(runtime->draw_config_ref); +} diff --git a/src/lua_overdub_task.c b/src/lua_overdub_task.c new file mode 100644 index 0000000..bab59dd --- /dev/null +++ b/src/lua_overdub_task.c @@ -0,0 +1,994 @@ +#include "lua_overdub_task.h" + +#include "config.h" +#include "globals.h" +#include "log.h" +#include "lua_overdub.h" +#include "lua_overdub_worker.h" +#include "lua_serial.h" + +#include "lua/src/lauxlib.h" +#include "lua/src/lua.h" + +#include +#include +#include + +#define LUA_OVERDUB_TASK_HANDLE_META "overdub.task.Task" +#define LUA_OVERDUB_FUTURE_META "overdub.task.Future" +#define LUA_OVERDUB_TASK_NAME_CAP (64) +#define LUA_OVERDUB_WORKER_NAME_CAP (512) + +typedef uint8_t lua_overdub_task_state_t; +enum { + LUA_OVERDUB_TASK_PENDING = 0, + LUA_OVERDUB_TASK_RUNNING, + LUA_OVERDUB_TASK_WAIT_FRAME, + LUA_OVERDUB_TASK_WAIT_TIME, + LUA_OVERDUB_TASK_DONE, + LUA_OVERDUB_TASK_CANCELLED, + LUA_OVERDUB_TASK_FAILED, +}; + +typedef struct lua_overdub_task_s lua_overdub_task_t; +struct lua_overdub_task_s { + lua_State *thread; + uint64_t id; + uint64_t ready_frame; + uint64_t due_us; + int thread_ref; + int handle_ref; + lua_overdub_task_state_t state; + bool active; + bool cancel_requested; + char name[LUA_OVERDUB_TASK_NAME_CAP]; +}; + +typedef struct lua_overdub_task_handle_s lua_overdub_task_handle_t; +struct lua_overdub_task_handle_s { + lua_overdub_task_context_t *context; + uint64_t id; + lua_overdub_task_state_t terminal_state; +}; + +typedef uint8_t lua_overdub_future_state_t; +enum { + LUA_OVERDUB_FUTURE_PENDING = 0, + LUA_OVERDUB_FUTURE_SUCCESS, + LUA_OVERDUB_FUTURE_ERROR, + LUA_OVERDUB_FUTURE_CANCELLED, +}; + +typedef struct lua_overdub_future_handle_s lua_overdub_future_handle_t; +struct lua_overdub_future_handle_s { + lua_overdub_task_context_t *context; + uint64_t id; + lua_overdub_future_state_t state; + int success_ref; + int error_ref; + int complete_ref; + lua_serial_blob_t result; + char error[1024]; +}; + +typedef struct lua_overdub_future_s lua_overdub_future_t; +struct lua_overdub_future_s { + uint64_t id; + int handle_ref; + bool active; +}; + +struct lua_overdub_task_context_s { + lua_runtime_t *runtime; + lua_overdub_worker_context_t *worker; + str_t mod_id; + lua_overdub_task_t tasks[CONFIG_LUA_OVERDUB_MAX_TASKS]; + lua_overdub_future_t futures[CONFIG_LUA_OVERDUB_MAX_WORKER_JOBS]; + lua_overdub_task_t *current; + uint64_t current_resume_start_us; + uint64_t next_id; + int next_slot; + int active_count; + int future_count; + bool dispatching; +}; + +static char g_lua_overdub_task_context_key; + +static uint64_t +lua_overdub_task_next_frame(void) +{ + return globals.frame_counter == UINT64_MAX ? UINT64_MAX : globals.frame_counter + 1; +} + +static lua_overdub_task_context_t * +lua_overdub_task_context_get(lua_State *state) +{ + lua_pushlightuserdata(state, &g_lua_overdub_task_context_key); + lua_rawget(state, LUA_REGISTRYINDEX); + lua_overdub_task_context_t *context = lua_touserdata(state, -1); + lua_pop(state, 1); + return context; +} + +static lua_overdub_task_context_t * +lua_overdub_task_context_check(lua_State *state) +{ + lua_overdub_context_check(state); + lua_overdub_task_context_t *context = lua_overdub_task_context_get(state); + if (!context || !context->runtime || !context->runtime->state) { + luaL_error(state, "Overdub task context is unavailable"); + } + return context; +} + +static lua_overdub_task_t * +lua_overdub_task_find(lua_overdub_task_context_t *context, uint64_t id) +{ + if (!context || id == 0) { + return NULL; + } + + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_TASKS; ++i) { + lua_overdub_task_t *task = &context->tasks[i]; + if (task->active && task->id == id) { + return task; + } + } + return NULL; +} + +static lua_overdub_task_t * +lua_overdub_task_from_thread(lua_overdub_task_context_t *context, lua_State *thread) +{ + if (context && context->current && context->current->thread == thread) { + return context->current; + } + return NULL; +} + +static void +lua_overdub_task_finish(lua_overdub_task_context_t *context, lua_overdub_task_t *task, lua_overdub_task_state_t state) +{ + if (!context || !task || !task->active) { + return; + } + + lua_State *main_state = context->runtime->state; + if (task->handle_ref != LUA_NOREF && task->handle_ref != LUA_REFNIL) { + lua_rawgeti(main_state, LUA_REGISTRYINDEX, task->handle_ref); + lua_overdub_task_handle_t *handle = luaL_testudata(main_state, -1, LUA_OVERDUB_TASK_HANDLE_META); + if (handle && handle->id == task->id) { + handle->terminal_state = state; + } + + lua_pop(main_state, 1); + luaL_unref(main_state, LUA_REGISTRYINDEX, task->handle_ref); + } + + if (task->thread_ref != LUA_NOREF && task->thread_ref != LUA_REFNIL) { + luaL_unref(main_state, LUA_REGISTRYINDEX, task->thread_ref); + } + + *task = (lua_overdub_task_t){ + .thread_ref = LUA_NOREF, + .handle_ref = LUA_NOREF, + }; + context->active_count = MAX_VAL(context->active_count - 1, 0); +} + +static lua_overdub_task_handle_t * +lua_overdub_task_check_handle(lua_State *state) +{ + lua_overdub_task_handle_t *handle = luaL_checkudata(state, 1, LUA_OVERDUB_TASK_HANDLE_META); + lua_overdub_task_context_t *context = lua_overdub_task_context_check(state); + if (!handle->context || handle->context != context || handle->id == 0) { + luaL_error(state, "Task handle is invalid"); + } + return handle; +} + +static int +lua_overdub_task_handle_cancel(lua_State *state) +{ + lua_overdub_task_handle_t *handle = lua_overdub_task_check_handle(state); + lua_overdub_task_t *task = lua_overdub_task_find(handle->context, handle->id); + if (!task || task->cancel_requested) { + lua_pushboolean(state, false); + return 1; + } + + task->cancel_requested = true; + if (task->state != LUA_OVERDUB_TASK_RUNNING) { + lua_overdub_task_finish(handle->context, task, LUA_OVERDUB_TASK_CANCELLED); + } + lua_pushboolean(state, true); + return 1; +} + +static int +lua_overdub_task_handle_is_done(lua_State *state) +{ + lua_overdub_task_handle_t *handle = lua_overdub_task_check_handle(state); + bool active = lua_overdub_task_find(handle->context, handle->id) != NULL; + lua_pushboolean(state, !active && (handle->terminal_state == LUA_OVERDUB_TASK_DONE || + handle->terminal_state == LUA_OVERDUB_TASK_CANCELLED || + handle->terminal_state == LUA_OVERDUB_TASK_FAILED)); + return 1; +} + +static int +lua_overdub_task_handle_is_cancelled(lua_State *state) +{ + lua_overdub_task_handle_t *handle = lua_overdub_task_check_handle(state); + lua_overdub_task_t *task = lua_overdub_task_find(handle->context, handle->id); + lua_pushboolean(state, (task && task->cancel_requested) || (!task && handle->terminal_state == LUA_OVERDUB_TASK_CANCELLED)); + return 1; +} + +static int +lua_overdub_task_spawn(lua_State *state) +{ + lua_overdub_task_context_t *context = lua_overdub_task_context_check(state); + int count = lua_gettop(state); + int function_idx = 1; + const char *name_data = NULL; + size_t name_len = 0; + + if (count == 1) { + function_idx = 1; + } else if (count == 2) { + name_data = luaL_checklstring(state, 1, &name_len); + function_idx = 2; + } else { + return luaL_error(state, "expected Spawn(function) or Spawn(name, function)"); + } + luaL_checktype(state, function_idx, LUA_TFUNCTION); + + lua_overdub_task_t *task = NULL; + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_TASKS; ++i) { + if (!context->tasks[i].active) { + task = &context->tasks[i]; + break; + } + } + + if (!task) { + return luaL_error(state, "Overdub task limit reached"); + } + + uint64_t id = context->next_id++; + if (id == 0) { + id = context->next_id++; + } + + lua_State *thread = lua_newthread(state); + int thread_ref = luaL_ref(state, LUA_REGISTRYINDEX); + lua_pushvalue(state, function_idx); + lua_xmove(state, thread, 1); + + lua_overdub_task_handle_t *handle = lua_newuserdatauv(state, sizeof(*handle), 0); + *handle = (lua_overdub_task_handle_t){ + .context = context, + .id = id, + .terminal_state = LUA_OVERDUB_TASK_PENDING, + }; + luaL_setmetatable(state, LUA_OVERDUB_TASK_HANDLE_META); + lua_pushvalue(state, -1); + + int handle_ref = luaL_ref(state, LUA_REGISTRYINDEX); + + *task = (lua_overdub_task_t){ + .thread = thread, + .id = id, + .ready_frame = context->dispatching ? lua_overdub_task_next_frame() : globals.frame_counter, + .thread_ref = thread_ref, + .handle_ref = handle_ref, + .state = LUA_OVERDUB_TASK_PENDING, + .active = true, + }; + + if (name_data && name_len > 0) { + size_t copy_len = MIN_VAL(name_len, sizeof(task->name) - 1); + memcpy(task->name, name_data, copy_len); + task->name[copy_len] = 0; + } else { + snprintf(task->name, sizeof(task->name), "task-%llu", (unsigned long long)id); + } + + context->active_count += 1; + return 1; +} + +static lua_overdub_task_t * +lua_overdub_task_check_current(lua_State *state, lua_overdub_task_context_t **out_context) +{ + lua_overdub_task_context_t *context = lua_overdub_task_context_check(state); + lua_overdub_task_t *task = lua_overdub_task_from_thread(context, state); + if (!task || task->state != LUA_OVERDUB_TASK_RUNNING) { + luaL_error(state, "this function can only be called from a task spawned by task.Spawn"); + } + + if (out_context) { + *out_context = context; + } + return task; +} + +static int +lua_overdub_task_yield_frame(lua_State *state) +{ + lua_overdub_task_t *task = lua_overdub_task_check_current(state, NULL); + task->state = LUA_OVERDUB_TASK_WAIT_FRAME; + task->ready_frame = lua_overdub_task_next_frame(); + task->due_us = 0; + return lua_yield(state, 0); +} + +static int +lua_overdub_task_sleep(lua_State *state) +{ + lua_overdub_task_t *task = lua_overdub_task_check_current(state, NULL); + lua_Number seconds = luaL_checknumber(state, 1); + if (!(seconds >= 0.0) || seconds > (lua_Number)(UINT64_MAX / 1000000ULL)) { + return luaL_argerror(state, 1, "seconds must be finite and non-negative"); + } + + uint64_t now = time_now_us(); + uint64_t delay_us = (uint64_t)(seconds * 1000000.0); + task->state = LUA_OVERDUB_TASK_WAIT_TIME; + task->ready_frame = lua_overdub_task_next_frame(); + task->due_us = delay_us > UINT64_MAX - now ? UINT64_MAX : now + delay_us; + return lua_yield(state, 0); +} + +static int +lua_overdub_task_should_yield(lua_State *state) +{ + lua_overdub_task_context_t *context = NULL; + lua_overdub_task_check_current(state, &context); + + uint64_t elapsed = time_now_us() - context->current_resume_start_us; + lua_pushboolean(state, elapsed >= CONFIG_LUA_OVERDUB_TASK_WORK_BUDGET_US); + return 1; +} + +static lua_overdub_future_t * +lua_overdub_future_find(lua_overdub_task_context_t *context, uint64_t id) +{ + if (!context || id == 0) { + return NULL; + } + + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_WORKER_JOBS; ++i) { + if (context->futures[i].active && context->futures[i].id == id) { + return &context->futures[i]; + } + } + return NULL; +} + +static lua_overdub_future_handle_t * +lua_overdub_future_check(lua_State *state) +{ + lua_overdub_future_handle_t *handle = luaL_checkudata(state, 1, LUA_OVERDUB_FUTURE_META); + lua_overdub_task_context_t *context = lua_overdub_task_context_check(state); + if (!handle->context || handle->context != context || handle->id == 0) { + luaL_error(state, "Future handle is invalid"); + } + return handle; +} + +static void +lua_overdub_future_unref(lua_State *state, int *ref) +{ + if (ref && *ref != LUA_NOREF && *ref != LUA_REFNIL) { + luaL_unref(state, LUA_REGISTRYINDEX, *ref); + *ref = LUA_NOREF; + } +} + +static void +lua_overdub_future_clear_callbacks(lua_State *state, lua_overdub_future_handle_t *handle) +{ + lua_overdub_future_unref(state, &handle->success_ref); + lua_overdub_future_unref(state, &handle->error_ref); + lua_overdub_future_unref(state, &handle->complete_ref); +} + +static void +lua_overdub_future_release_record(lua_overdub_task_context_t *context, lua_overdub_future_t *future) +{ + if (!context || !future || !future->active) { + return; + } + + if (future->handle_ref != LUA_NOREF && future->handle_ref != LUA_REFNIL) { + luaL_unref(context->runtime->state, LUA_REGISTRYINDEX, future->handle_ref); + } + + *future = (lua_overdub_future_t){.handle_ref = LUA_NOREF}; + context->future_count = MAX_VAL(context->future_count - 1, 0); +} + +static int +lua_overdub_future_push_result(lua_State *state, lua_overdub_future_handle_t *handle) +{ + if (handle->state == LUA_OVERDUB_FUTURE_PENDING) { + return luaL_error(state, "Future is still pending"); + } + + if (handle->state == LUA_OVERDUB_FUTURE_CANCELLED) { + return luaL_error(state, "Future was cancelled"); + } + + if (handle->state == LUA_OVERDUB_FUTURE_ERROR) { + return luaL_error(state, "%s", handle->error[0] ? handle->error : "worker job failed"); + } + + char error[256] = {0}; + if (!lua_serial_decode(state, handle->result, error, sizeof(error))) { + return luaL_error(state, "could not decode worker result: %s", error); + } + return 1; +} + +static int +lua_overdub_future_is_pending_lua(lua_State *state) +{ + lua_pushboolean(state, lua_overdub_future_check(state)->state == LUA_OVERDUB_FUTURE_PENDING); + return 1; +} + +static int +lua_overdub_future_is_done_lua(lua_State *state) +{ + lua_pushboolean(state, lua_overdub_future_check(state)->state != LUA_OVERDUB_FUTURE_PENDING); + return 1; +} + +static int +lua_overdub_future_is_cancelled_lua(lua_State *state) +{ + lua_pushboolean(state, lua_overdub_future_check(state)->state == LUA_OVERDUB_FUTURE_CANCELLED); + return 1; +} + +static int +lua_overdub_future_get_result_lua(lua_State *state) +{ + return lua_overdub_future_push_result(state, lua_overdub_future_check(state)); +} + +static int +lua_overdub_future_get_error_lua(lua_State *state) +{ + lua_overdub_future_handle_t *handle = lua_overdub_future_check(state); + if (handle->state == LUA_OVERDUB_FUTURE_ERROR) { + lua_pushstring(state, handle->error[0] ? handle->error : "worker job failed"); + } else if (handle->state == LUA_OVERDUB_FUTURE_CANCELLED) { + lua_pushliteral(state, "cancelled"); + } else { + lua_pushnil(state); + } + return 1; +} + +static int +lua_overdub_future_set_callback(lua_State *state, int *ref_slot, lua_overdub_future_state_t matching_state, bool complete) +{ + lua_overdub_future_handle_t *handle = lua_overdub_future_check(state); + luaL_checktype(state, 2, LUA_TFUNCTION); + + if (handle->state == LUA_OVERDUB_FUTURE_PENDING) { + lua_overdub_future_unref(state, ref_slot); + lua_pushvalue(state, 2); + *ref_slot = luaL_ref(state, LUA_REGISTRYINDEX); + } else if (complete || handle->state == matching_state || (matching_state == LUA_OVERDUB_FUTURE_ERROR && handle->state == LUA_OVERDUB_FUTURE_CANCELLED)) { + lua_pushvalue(state, 2); + if (complete) { + lua_pushvalue(state, 1); + } else if (matching_state == LUA_OVERDUB_FUTURE_SUCCESS) { + lua_overdub_future_push_result(state, handle); + } else { + lua_pushstring(state, handle->state == LUA_OVERDUB_FUTURE_CANCELLED ? "cancelled" : (handle->error[0] ? handle->error : "worker job failed")); + } + lua_call(state, 1, 0); + } + + lua_pushvalue(state, 1); + return 1; +} + +static int +lua_overdub_future_on_success_lua(lua_State *state) +{ + lua_overdub_future_handle_t *handle = lua_overdub_future_check(state); + return lua_overdub_future_set_callback(state, &handle->success_ref, LUA_OVERDUB_FUTURE_SUCCESS, false); +} + +static int +lua_overdub_future_on_error_lua(lua_State *state) +{ + lua_overdub_future_handle_t *handle = lua_overdub_future_check(state); + return lua_overdub_future_set_callback(state, &handle->error_ref, LUA_OVERDUB_FUTURE_ERROR, false); +} + +static int +lua_overdub_future_on_complete_lua(lua_State *state) +{ + lua_overdub_future_handle_t *handle = lua_overdub_future_check(state); + return lua_overdub_future_set_callback(state, &handle->complete_ref, LUA_OVERDUB_FUTURE_PENDING, true); +} + +static int +lua_overdub_future_cancel_lua(lua_State *state) +{ + lua_overdub_future_handle_t *handle = lua_overdub_future_check(state); + if (handle->state != LUA_OVERDUB_FUTURE_PENDING) { + lua_pushboolean(state, false); + return 1; + } + + lua_overdub_future_t *future = lua_overdub_future_find(handle->context, handle->id); + if (!future || !lua_overdub_worker_cancel(handle->context->worker, handle->id)) { + lua_pushboolean(state, false); + return 1; + } + + handle->state = LUA_OVERDUB_FUTURE_CANCELLED; + snprintf(handle->error, sizeof(handle->error), "cancelled"); + + int error_ref = handle->error_ref; + int complete_ref = handle->complete_ref; + + handle->error_ref = LUA_NOREF; + handle->complete_ref = LUA_NOREF; + lua_overdub_future_unref(state, &handle->success_ref); + + if (error_ref != LUA_NOREF && error_ref != LUA_REFNIL) { + lua_pushliteral(state, "cancelled"); + lua_runtime_call_ref(handle->context->runtime, error_ref, 1, 0); + luaL_unref(state, LUA_REGISTRYINDEX, error_ref); + } + + if (complete_ref != LUA_NOREF && complete_ref != LUA_REFNIL) { + lua_pushvalue(state, 1); + lua_runtime_call_ref(handle->context->runtime, complete_ref, 1, 0); + luaL_unref(state, LUA_REGISTRYINDEX, complete_ref); + } + + lua_overdub_future_release_record(handle->context, future); + lua_pushboolean(state, true); + return 1; +} + +static int lua_overdub_future_await_continue(lua_State *state, int status, lua_KContext continuation); + +static int +lua_overdub_future_await_continue(lua_State *state, int status, lua_KContext continuation) +{ + (void)status; + + lua_overdub_future_handle_t *handle = (lua_overdub_future_handle_t *)(uintptr_t)continuation; + lua_overdub_task_context_t *context = lua_overdub_task_context_check(state); + + if (!handle || handle->context != context) { + return luaL_error(state, "Future handle is invalid"); + } + + if (handle->state == LUA_OVERDUB_FUTURE_PENDING) { + lua_overdub_task_t *task = lua_overdub_task_check_current(state, NULL); + task->state = LUA_OVERDUB_TASK_WAIT_FRAME; + task->ready_frame = lua_overdub_task_next_frame(); + task->due_us = 0; + return lua_yieldk(state, 0, continuation, lua_overdub_future_await_continue); + } + return lua_overdub_future_push_result(state, handle); +} + +static int +lua_overdub_future_await_lua(lua_State *state) +{ + lua_overdub_future_handle_t *handle = lua_overdub_future_check(state); + lua_overdub_task_check_current(state, NULL); + return lua_overdub_future_await_continue(state, LUA_OK, (lua_KContext)(uintptr_t)handle); +} + +static int +lua_overdub_future_gc_lua(lua_State *state) +{ + lua_overdub_future_handle_t *handle = luaL_checkudata(state, 1, LUA_OVERDUB_FUTURE_META); + lua_serial_blob_free(&handle->result); + lua_overdub_future_clear_callbacks(state, handle); + handle->context = NULL; + return 0; +} + +static int +lua_overdub_task_offload(lua_State *state) +{ + lua_overdub_task_context_t *context = lua_overdub_task_context_check(state); + + size_t module_len = 0; + size_t function_len = 0; + + const char *module_name = luaL_checklstring(state, 1, &module_len); + const char *function_name = luaL_checklstring(state, 2, &function_len); + + if (module_len == 0 || function_len == 0 || module_len >= LUA_OVERDUB_WORKER_NAME_CAP || + function_len >= LUA_OVERDUB_WORKER_NAME_CAP || memchr(module_name, 0, module_len) || + memchr(function_name, 0, function_len)) { + return luaL_error(state, "worker module and function names must be non-empty, shorter than %d bytes, and contain no null bytes", LUA_OVERDUB_WORKER_NAME_CAP); + } + + if (lua_gettop(state) != 3) { + return luaL_error(state, "expected Offload(module_name, function_name, value)"); + } + + lua_overdub_future_t *future = NULL; + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_WORKER_JOBS; ++i) { + if (!context->futures[i].active) { + future = &context->futures[i]; + break; + } + } + + if (!future) { + return luaL_error(state, "Overdub Future limit reached"); + } + + lua_serial_blob_t input = {0}; + char error[256] = {0}; + if (!lua_serial_encode(state, 3, &input, error, sizeof(error))) { + return luaL_argerror(state, 3, error[0] ? error : "value cannot cross a worker boundary"); + } + + uint64_t id = 0; + if (!lua_overdub_worker_submit(context->worker, str_make((void *)module_name, (uint64_t)module_len), str_make((void *)function_name, (uint64_t)function_len), &input, &id, error, sizeof(error))) { + lua_serial_blob_free(&input); + return luaL_error(state, "%s", error[0] ? error : "could not submit worker job"); + } + + lua_overdub_future_handle_t *handle = lua_newuserdatauv(state, sizeof(*handle), 0); + *handle = (lua_overdub_future_handle_t){ + .context = context, + .id = id, + .state = LUA_OVERDUB_FUTURE_PENDING, + .success_ref = LUA_NOREF, + .error_ref = LUA_NOREF, + .complete_ref = LUA_NOREF, + }; + + luaL_setmetatable(state, LUA_OVERDUB_FUTURE_META); + lua_pushvalue(state, -1); + int handle_ref = luaL_ref(state, LUA_REGISTRYINDEX); + + *future = (lua_overdub_future_t){ + .id = id, + .handle_ref = handle_ref, + .active = true, + }; + context->future_count += 1; + return 1; +} + +static int +luaopen_overdub_task(lua_State *state) +{ + lua_overdub_task_context_check(state); + static const luaL_Reg functions[] = { + {"Spawn", lua_overdub_task_spawn }, + {"YieldFrame", lua_overdub_task_yield_frame }, + {"Sleep", lua_overdub_task_sleep }, + {"ShouldYield", lua_overdub_task_should_yield}, + {"Offload", lua_overdub_task_offload }, + {NULL, NULL }, + }; + luaL_newlib(state, functions); + return 1; +} + +lua_overdub_task_context_t * +lua_overdub_task_context_create(arena_t *arena, lua_runtime_t *runtime, lua_overdub_worker_context_t *worker, str_t mod_id) +{ + if (!arena || !arena->backing || !runtime || !runtime->state || !worker) { + return NULL; + } + + lua_overdub_task_context_t *context = ARENA_PUSH_ZERO(arena, lua_overdub_task_context_t); + if (!context) { + return NULL; + } + + context->runtime = runtime; + context->worker = worker; + context->mod_id = mod_id; + context->next_id = 1; + + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_TASKS; ++i) { + context->tasks[i].thread_ref = LUA_NOREF; + context->tasks[i].handle_ref = LUA_NOREF; + } + + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_WORKER_JOBS; ++i) { + context->futures[i].handle_ref = LUA_NOREF; + } + + return context; +} + +void +lua_overdub_task_context_destroy(lua_overdub_task_context_t *context) +{ + if (!context) { + return; + } + + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_TASKS; ++i) { + lua_overdub_task_t *task = &context->tasks[i]; + if (task->active) { + lua_overdub_task_finish(context, task, LUA_OVERDUB_TASK_CANCELLED); + } + } + + lua_State *state = context->runtime ? context->runtime->state : NULL; + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_WORKER_JOBS; ++i) { + lua_overdub_future_t *future = &context->futures[i]; + if (!future->active) { + continue; + } + + if (state && future->handle_ref != LUA_NOREF && future->handle_ref != LUA_REFNIL) { + lua_rawgeti(state, LUA_REGISTRYINDEX, future->handle_ref); + + lua_overdub_future_handle_t *handle = luaL_testudata(state, -1, LUA_OVERDUB_FUTURE_META); + if (handle && handle->id == future->id) { + handle->state = LUA_OVERDUB_FUTURE_CANCELLED; + handle->context = NULL; + snprintf(handle->error, sizeof(handle->error), "cancelled"); + lua_overdub_future_clear_callbacks(state, handle); + } + lua_pop(state, 1); + } + + lua_overdub_worker_cancel(context->worker, future->id); + lua_overdub_future_release_record(context, future); + } +} + +bool +lua_overdub_task_register(lua_State *state, lua_overdub_task_context_t *context) +{ + if (!state || !context) { + return false; + } + + lua_pushlightuserdata(state, &g_lua_overdub_task_context_key); + lua_pushlightuserdata(state, context); + lua_rawset(state, LUA_REGISTRYINDEX); + + if (luaL_newmetatable(state, LUA_OVERDUB_TASK_HANDLE_META)) { + static const luaL_Reg methods[] = { + {"Cancel", lua_overdub_task_handle_cancel }, + {"IsDone", lua_overdub_task_handle_is_done }, + {"IsCancelled", lua_overdub_task_handle_is_cancelled}, + {NULL, NULL }, + }; + + luaL_setfuncs(state, methods, 0); + lua_pushvalue(state, -1); + lua_setfield(state, -2, "__index"); + lua_pushliteral(state, "Overdub Task"); + lua_setfield(state, -2, "__metatable"); + } + lua_pop(state, 1); + + if (luaL_newmetatable(state, LUA_OVERDUB_FUTURE_META)) { + static const luaL_Reg methods[] = { + {"IsPending", lua_overdub_future_is_pending_lua }, + {"IsDone", lua_overdub_future_is_done_lua }, + {"IsCancelled",lua_overdub_future_is_cancelled_lua}, + {"Cancel", lua_overdub_future_cancel_lua }, + {"OnSuccess", lua_overdub_future_on_success_lua }, + {"OnError", lua_overdub_future_on_error_lua }, + {"OnComplete", lua_overdub_future_on_complete_lua }, + {"Await", lua_overdub_future_await_lua }, + {"GetResult", lua_overdub_future_get_result_lua }, + {"GetError", lua_overdub_future_get_error_lua }, + {NULL, NULL }, + }; + + luaL_setfuncs(state, methods, 0); + lua_pushvalue(state, -1); + lua_setfield(state, -2, "__index"); + lua_pushcfunction(state, lua_overdub_future_gc_lua); + lua_setfield(state, -2, "__gc"); + lua_pushliteral(state, "Overdub Future"); + lua_setfield(state, -2, "__metatable"); + } + lua_pop(state, 1); + return lua_overdub_preload_module(state, "overdub.task", luaopen_overdub_task); +} + +uint64_t +lua_overdub_task_dispatch(lua_overdub_task_context_t *context, uint64_t budget_us) +{ + if (!context || !context->runtime || !context->runtime->state || context->dispatching || budget_us == 0) { + return 0; + } + + uint64_t dispatch_start = time_now_us(); + context->dispatching = true; + int scan_start = context->next_slot; + for (int offset = 0; offset < CONFIG_LUA_OVERDUB_MAX_TASKS; ++offset) { + if (time_now_us() - dispatch_start >= budget_us) { + break; + } + + int idx = (scan_start + offset) % CONFIG_LUA_OVERDUB_MAX_TASKS; + lua_overdub_task_t *task = &context->tasks[idx]; + if (!task->active || task->cancel_requested || task->ready_frame > globals.frame_counter) { + continue; + } + + uint64_t now = time_now_us(); + if (task->state == LUA_OVERDUB_TASK_WAIT_TIME && task->due_us > now) { + continue; + } + + if (task->state != LUA_OVERDUB_TASK_PENDING && task->state != LUA_OVERDUB_TASK_WAIT_FRAME && task->state != LUA_OVERDUB_TASK_WAIT_TIME) { + continue; + } + + context->next_slot = (idx + 1) % CONFIG_LUA_OVERDUB_MAX_TASKS; + context->current = task; + context->current_resume_start_us = now; + task->state = LUA_OVERDUB_TASK_RUNNING; + + uint64_t previous_limit = context->runtime->execution_limit_us; + context->runtime->execution_limit_us = CONFIG_LUA_OVERDUB_CALLBACK_LIMIT_US; + + int result_count = 0; + int status = lua_runtime_resume(context->runtime, task->thread, 0, &result_count); + + context->runtime->execution_limit_us = previous_limit; + context->current = NULL; + + if ((status == LUA_OK || status == LUA_YIELD) && result_count > 0) { + lua_pop(task->thread, result_count); + } + + if (task->cancel_requested) { + lua_overdub_task_finish(context, task, LUA_OVERDUB_TASK_CANCELLED); + } else if (status == LUA_OK) { + lua_overdub_task_finish(context, task, LUA_OVERDUB_TASK_DONE); + } else if (status == LUA_YIELD) { + if (task->state == LUA_OVERDUB_TASK_RUNNING) { + task->state = LUA_OVERDUB_TASK_WAIT_FRAME; + task->ready_frame = lua_overdub_task_next_frame(); + task->due_us = 0; + } + } else { + LOG_ERROR("Overdub Lua mod '%.*s': task '%s' failed and was stopped", STR_ARG(context->mod_id), task->name); + lua_overdub_task_finish(context, task, LUA_OVERDUB_TASK_FAILED); + } + } + + context->dispatching = false; + return time_now_us() - dispatch_start; +} + +static void +lua_overdub_future_call_ref(lua_overdub_task_context_t *context, bool *in_callback, int callback_ref, int arg_count) +{ + if (!context || !context->runtime || !in_callback || callback_ref == LUA_NOREF || callback_ref == LUA_REFNIL) { + if (context && context->runtime && context->runtime->state && arg_count > 0) { + lua_pop(context->runtime->state, arg_count); + } + return; + } + + bool previous = *in_callback; + *in_callback = true; + lua_runtime_call_ref(context->runtime, callback_ref, arg_count, 0); + *in_callback = previous; + luaL_unref(context->runtime->state, LUA_REGISTRYINDEX, callback_ref); +} + +uint64_t +lua_overdub_task_dispatch_worker_completions(lua_overdub_task_context_t *context, bool *in_callback, uint64_t budget_us) +{ + if (!context || !context->runtime || !context->runtime->state || !context->worker || !in_callback || *in_callback || budget_us == 0) { + return 0; + } + + lua_State *state = context->runtime->state; + uint64_t start_us = time_now_us(); + while (time_now_us() - start_us < budget_us) { + lua_overdub_worker_completion_t completion = {0}; + if (!lua_overdub_worker_poll(context->worker, &completion)) { + break; + } + + lua_overdub_future_t *future = lua_overdub_future_find(context, completion.id); + if (!future || future->handle_ref == LUA_NOREF || future->handle_ref == LUA_REFNIL) { + lua_overdub_worker_completion_destroy(&completion); + continue; + } + + int stack_base = lua_gettop(state); + lua_rawgeti(state, LUA_REGISTRYINDEX, future->handle_ref); + + int handle_idx = lua_absindex(state, -1); + lua_overdub_future_handle_t *handle = luaL_testudata(state, handle_idx, LUA_OVERDUB_FUTURE_META); + if (!handle || handle->id != completion.id || handle->state != LUA_OVERDUB_FUTURE_PENDING) { + lua_settop(state, stack_base); + lua_overdub_future_release_record(context, future); + lua_overdub_worker_completion_destroy(&completion); + continue; + } + + if (completion.result == LUA_OVERDUB_WORKER_SUCCESS) { + handle->state = LUA_OVERDUB_FUTURE_SUCCESS; + handle->result = completion.value; + completion.value = (lua_serial_blob_t){0}; + } else if (completion.result == LUA_OVERDUB_WORKER_CANCELLED) { + handle->state = LUA_OVERDUB_FUTURE_CANCELLED; + snprintf(handle->error, sizeof(handle->error), "cancelled"); + } else { + handle->state = LUA_OVERDUB_FUTURE_ERROR; + snprintf(handle->error, sizeof(handle->error), "%s", completion.error[0] ? completion.error : "worker job failed"); + } + + int success_ref = handle->success_ref; + int error_ref = handle->error_ref; + int complete_ref = handle->complete_ref; + + handle->success_ref = LUA_NOREF; + handle->error_ref = LUA_NOREF; + handle->complete_ref = LUA_NOREF; + + if (handle->state == LUA_OVERDUB_FUTURE_SUCCESS && success_ref != LUA_NOREF && success_ref != LUA_REFNIL) { + char decode_error[256] = {0}; + if (lua_serial_decode(state, handle->result, decode_error, sizeof(decode_error))) { + lua_overdub_future_call_ref(context, in_callback, success_ref, 1); + } else { + luaL_unref(state, LUA_REGISTRYINDEX, success_ref); + LOG_ERROR("Overdub Lua mod '%.*s': could not decode worker result: %s", STR_ARG(context->mod_id), decode_error); + } + } else { + lua_overdub_future_unref(state, &success_ref); + } + + if ((handle->state == LUA_OVERDUB_FUTURE_ERROR || handle->state == LUA_OVERDUB_FUTURE_CANCELLED) && + error_ref != LUA_NOREF && error_ref != LUA_REFNIL) { + lua_pushstring(state, handle->state == LUA_OVERDUB_FUTURE_CANCELLED ? "cancelled" : (handle->error[0] ? handle->error : "worker job failed")); + lua_overdub_future_call_ref(context, in_callback, error_ref, 1); + } else { + lua_overdub_future_unref(state, &error_ref); + } + + if (complete_ref != LUA_NOREF && complete_ref != LUA_REFNIL) { + lua_pushvalue(state, handle_idx); + lua_overdub_future_call_ref(context, in_callback, complete_ref, 1); + } + + lua_settop(state, stack_base); + lua_overdub_future_release_record(context, future); + lua_overdub_worker_completion_destroy(&completion); + } + return time_now_us() - start_us; +} + +int +lua_overdub_task_active_count(lua_overdub_task_context_t *context) +{ + return context ? context->active_count : 0; +} + +int +lua_overdub_task_future_count(lua_overdub_task_context_t *context) +{ + return context && context->worker ? lua_overdub_worker_outstanding_count(context->worker) : 0; +} diff --git a/src/lua_overdub_ui.c b/src/lua_overdub_ui.c new file mode 100644 index 0000000..a12dcfc --- /dev/null +++ b/src/lua_overdub_ui.c @@ -0,0 +1,1867 @@ +#include "lua_overdub_ui.h" + +#include "config.h" +#include "globals.h" +#include "log.h" +#include "lua_overdub.h" +#include "scratch.h" +#include "ui_keybind_capture.h" +#include "ui_nuklear.h" + +#include "lua/src/lauxlib.h" +#include "lua/src/lua.h" + +#include +#include +#include +#include +#include + +#define LUA_OVERDUB_UI_WINDOW_META "overdub.ui.Window" +#define LUA_OVERDUB_UI_CONTEXT_META "overdub.ui.Context" +#define LUA_OVERDUB_UI_ID_CAP (128) +#define LUA_OVERDUB_UI_TITLE_CAP (256) +#define LUA_OVERDUB_UI_NAME_CAP (384) +#define LUA_OVERDUB_UI_TEXT_CAP (4096) +#define LUA_OVERDUB_UI_COMBO_CAP (256) +#define LUA_OVERDUB_UI_KEYBIND_CAP (256) +#define LUA_OVERDUB_UI_WIDGET_ID_CAP (768) + +typedef struct lua_overdub_ui_grid_state_s lua_overdub_ui_grid_state_t; +struct lua_overdub_ui_grid_state_s { + struct nk_grid_state state; + nk_hash scope; + size_t key_len; + char key[LUA_OVERDUB_UI_ID_CAP]; +}; + +typedef struct lua_overdub_ui_window_s lua_overdub_ui_window_t; +struct lua_overdub_ui_window_s { + uint64_t id; + int callback_ref; + int handle_ref; + struct nk_rect bounds; + size_t public_id_len; + char public_id[LUA_OVERDUB_UI_ID_CAP]; + char name[LUA_OVERDUB_UI_NAME_CAP]; + char title[LUA_OVERDUB_UI_TITLE_CAP]; + bool active; + bool open; + bool created; + bool show_requested; + bool drawing; + bool remove_requested; +}; + +typedef struct lua_overdub_ui_window_handle_s lua_overdub_ui_window_handle_t; +struct lua_overdub_ui_window_handle_s { + lua_overdub_ui_context_t *context; + uint64_t id; +}; + +typedef struct lua_overdub_ui_draw_context_s lua_overdub_ui_draw_context_t; +struct lua_overdub_ui_draw_context_s { + lua_overdub_ui_context_t *context; + struct nk_context *nk; + struct nk_grid *grid; + uint64_t token; + int grid_column; + int row_remaining; + float row_values[NK_GRID_MAX_COLUMNS]; + bool grid_row_active; + bool valid; +}; + +struct lua_overdub_ui_context_s { + lua_runtime_t *runtime; + str_t mod_id; + uint32_t owner_thread_id; + uint64_t next_window_id; + uint64_t draw_token; + unsigned int viewport_width; + unsigned int viewport_height; + struct nk_context *nk; + lua_overdub_ui_window_t windows[CONFIG_LUA_OVERDUB_MAX_UI_WINDOWS]; + lua_overdub_ui_grid_state_t grids[CONFIG_LUA_OVERDUB_MAX_UI_GRIDS]; + bool drawing; +}; + +static char g_lua_overdub_ui_context_key; + +static bool +lua_overdub_ui_name_valid(const char *value, size_t len, size_t cap); + +static bool +lua_overdub_ui_ref_valid(int ref) +{ + return ref != LUA_NOREF && ref != LUA_REFNIL; +} + +static bool +lua_overdub_ui_on_owner_thread(lua_overdub_ui_context_t *context) +{ + if (!context) { + return false; + } + + if (context->owner_thread_id == 0) { + return false; + } + + return context->owner_thread_id == thread_current_id(); +} + +static bool +lua_overdub_ui_draw_begin(lua_overdub_ui_context_t *ui, struct nk_context *nk, unsigned int vw, unsigned int vh) +{ + if (!ui || !nk || ui->drawing || !lua_overdub_ui_on_owner_thread(ui)) { + return false; + } + + ui->nk = nk; + ui->viewport_width = vw; + ui->viewport_height = vh; + ui->drawing = true; + return true; +} + +static void +lua_overdub_ui_draw_end(lua_overdub_ui_context_t *ui) +{ + if (!ui) { + return; + } + + ui->draw_token += 1; + ui->drawing = false; + ui->nk = NULL; +} + +static void +lua_overdub_ui_push_draw_context(lua_overdub_ui_context_t *ui) +{ + lua_State *state = ui->runtime->state; + ui->draw_token += 1; + + lua_overdub_ui_draw_context_t *draw = lua_newuserdatauv(state, sizeof(*draw), 0); + *draw = (lua_overdub_ui_draw_context_t){ + .context = ui, + .nk = ui->nk, + .token = ui->draw_token, + .valid = true, + }; + luaL_setmetatable(state, LUA_OVERDUB_UI_CONTEXT_META); +} + +static lua_overdub_ui_context_t * +lua_overdub_ui_context_get(lua_State *state) +{ + lua_pushlightuserdata(state, &g_lua_overdub_ui_context_key); + lua_rawget(state, LUA_REGISTRYINDEX); + lua_overdub_ui_context_t *context = lua_touserdata(state, -1); + lua_pop(state, 1); + return context; +} + +static lua_overdub_ui_context_t * +lua_overdub_ui_context_check(lua_State *state) +{ + lua_overdub_context_check(state); + + lua_overdub_ui_context_t *context = lua_overdub_ui_context_get(state); + if (!context) { + luaL_error(state, "Overdub UI context is unavailable"); + } + + return context; +} + +static lua_overdub_ui_window_t * +lua_overdub_ui_window_find(lua_overdub_ui_context_t *context, uint64_t id) +{ + if (!context || id == 0) { + return NULL; + } + + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_UI_WINDOWS; ++i) { + lua_overdub_ui_window_t *window = &context->windows[i]; + if (window->active && window->id == id) { + return window; + } + } + + return NULL; +} + +static lua_overdub_ui_window_t * +lua_overdub_ui_window_find_public_id(lua_overdub_ui_context_t *context, const char *id, size_t id_len) +{ + if (!context || !id || id_len == 0) { + return NULL; + } + + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_UI_WINDOWS; ++i) { + lua_overdub_ui_window_t *window = &context->windows[i]; + if (!window->active || window->public_id_len != id_len) { + continue; + } + + if (memcmp(window->public_id, id, id_len) == 0) { + return window; + } + } + + return NULL; +} + +static lua_overdub_ui_window_t * +lua_overdub_ui_window_find_free(lua_overdub_ui_context_t *context, int *out_index) +{ + if (!context) { + return NULL; + } + + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_UI_WINDOWS; ++i) { + if (context->windows[i].active) { + continue; + } + + if (out_index) { + *out_index = i; + } + return &context->windows[i]; + } + + return NULL; +} + +static void +lua_overdub_ui_window_release(lua_overdub_ui_context_t *context, lua_overdub_ui_window_t *window) +{ + if (!context || !window || !window->active) { + return; + } + + lua_State *state = context->runtime->state; + if (lua_overdub_ui_ref_valid(window->handle_ref)) { + luaL_unref(state, LUA_REGISTRYINDEX, window->handle_ref); + } + + if (lua_overdub_ui_ref_valid(window->callback_ref)) { + luaL_unref(state, LUA_REGISTRYINDEX, window->callback_ref); + } + + *window = (lua_overdub_ui_window_t){ + .callback_ref = LUA_NOREF, + .handle_ref = LUA_NOREF, + }; +} + +static void +lua_overdub_ui_window_invalidate_handle(lua_overdub_ui_context_t *context, lua_overdub_ui_window_t *window) +{ + if (!context || !window) { + return; + } + + if (!lua_overdub_ui_ref_valid(window->handle_ref)) { + return; + } + + lua_State *state = context->runtime->state; + lua_rawgeti(state, LUA_REGISTRYINDEX, window->handle_ref); + + lua_overdub_ui_window_handle_t *handle = luaL_testudata(state, -1, LUA_OVERDUB_UI_WINDOW_META); + if (handle && handle->id == window->id) { + handle->context = NULL; + } + + lua_pop(state, 1); +} + +static lua_overdub_ui_window_handle_t * +lua_overdub_ui_window_handle_check(lua_State *state) +{ + lua_overdub_ui_window_handle_t *handle = luaL_checkudata(state, 1, LUA_OVERDUB_UI_WINDOW_META); + + lua_overdub_ui_context_t *context = lua_overdub_ui_context_check(state); + if (!handle->context || handle->context != context) { + luaL_error(state, "UI Window handle is invalid"); + } + + return handle; +} + +static bool +lua_overdub_ui_window_handle_active(lua_overdub_ui_window_handle_t *handle) +{ + lua_overdub_ui_window_t *window = lua_overdub_ui_window_find(handle->context, handle->id); + return window && !window->remove_requested; +} + +static int +lua_overdub_ui_window_remove_lua(lua_State *state) +{ + lua_overdub_ui_window_handle_t *handle = lua_overdub_ui_window_handle_check(state); + lua_overdub_ui_window_t *window = lua_overdub_ui_window_find(handle->context, handle->id); + if (!window || window->remove_requested) { + lua_pushboolean(state, false); + return 1; + } + + if (window->drawing) { + window->remove_requested = true; + } else { + lua_overdub_ui_window_release(handle->context, window); + } + + lua_pushboolean(state, true); + return 1; +} + +static int +lua_overdub_ui_window_is_active_lua(lua_State *state) +{ + lua_overdub_ui_window_handle_t *handle = lua_overdub_ui_window_handle_check(state); + lua_pushboolean(state, lua_overdub_ui_window_handle_active(handle)); + return 1; +} + +static int +lua_overdub_ui_window_set_open_lua(lua_State *state) +{ + lua_overdub_ui_window_handle_t *handle = lua_overdub_ui_window_handle_check(state); + lua_overdub_ui_window_t *window = lua_overdub_ui_window_find(handle->context, handle->id); + if (!window || window->remove_requested) { + lua_pushboolean(state, false); + return 1; + } + + bool open = lua_toboolean(state, 2); + if (open && !window->open) { + window->show_requested = true; + } + window->open = open; + + lua_pushboolean(state, true); + return 1; +} + +static int +lua_overdub_ui_window_is_open_lua(lua_State *state) +{ + lua_overdub_ui_window_handle_t *handle = lua_overdub_ui_window_handle_check(state); + lua_overdub_ui_window_t *window = lua_overdub_ui_window_find(handle->context, handle->id); + + bool open = false; + if (window && !window->remove_requested) { + open = window->open; + } + + lua_pushboolean(state, open); + return 1; +} + +static int +lua_overdub_ui_window_gc_lua(lua_State *state) +{ + lua_overdub_ui_window_handle_t *handle = luaL_checkudata(state, 1, LUA_OVERDUB_UI_WINDOW_META); + handle->context = NULL; + handle->id = 0; + return 0; +} + +static lua_overdub_ui_draw_context_t * +lua_overdub_ui_draw_context_check(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = luaL_checkudata(state, 1, LUA_OVERDUB_UI_CONTEXT_META); + lua_overdub_ui_context_t *context = lua_overdub_ui_context_check(state); + + if (!draw->valid || draw->context != context) { + luaL_error(state, "UI context is only valid during its draw callback"); + } + + if (!context->drawing || context->draw_token != draw->token) { + luaL_error(state, "UI context is only valid during its draw callback"); + } + + if (!draw->nk || draw->nk != context->nk) { + luaL_error(state, "UI context is only valid during its draw callback"); + } + + return draw; +} + +static void +lua_overdub_ui_grid_end_row(lua_overdub_ui_draw_context_t *draw) +{ + if (draw->grid && draw->grid_row_active) { + nk_grid_row_end(draw->grid); + draw->grid_row_active = false; + draw->grid_column = 0; + } +} + +static void +lua_overdub_ui_grid_begin_row(lua_overdub_ui_draw_context_t *draw) +{ + if (draw->grid && !draw->grid_row_active) { + nk_grid_row_begin(draw->grid); + draw->grid_row_active = true; + draw->grid_column = 0; + } +} + +static void +lua_overdub_ui_prepare_widget_size(lua_overdub_ui_draw_context_t *draw, float width, float height) +{ + if (draw->grid) { + if (draw->grid_row_active && draw->grid_column >= draw->grid->column_count) { + lua_overdub_ui_grid_end_row(draw); + } + + lua_overdub_ui_grid_begin_row(draw); + nk_grid_push(draw->grid, draw->grid_column, nk_vec2(width, height)); + draw->grid_column += 1; + return; + } + + if (draw->row_remaining > 0) { + draw->row_remaining -= 1; + return; + } + + nk_layout_row_dynamic(draw->nk, height, 1); +} + +static void +lua_overdub_ui_prepare_widget(lua_overdub_ui_draw_context_t *draw, float height) +{ + lua_overdub_ui_prepare_widget_size(draw, 0.0f, height); +} + +static float +lua_overdub_ui_text_width(lua_overdub_ui_draw_context_t *draw, const char *text, size_t text_len) +{ + return nk_text_width(draw->nk, draw->nk->style.font, draw->nk->style.font_size, text, (int)text_len); +} + +static bool +lua_overdub_ui_scoped_name(lua_overdub_ui_draw_context_t *draw, const char *kind, const char *id, size_t id_len, char *name, size_t name_cap) +{ + nk_hash scope = draw->nk->current->layout->text_selection_scope; + str_t mod_id = draw->context->mod_id; + int name_len = snprintf(name, name_cap, "%.*s::%08X::%s::%.*s", STR_ARG(mod_id), (unsigned int)scope, kind, (int)id_len, id); + return name_len >= 0 && (size_t)name_len < name_cap; +} + +static void +lua_overdub_ui_prepare_labeled_control(lua_overdub_ui_draw_context_t *draw, const char *label, size_t label_len) +{ + if (draw->grid) { + float label_width = lua_overdub_ui_text_width(draw, label, label_len); + lua_overdub_ui_prepare_widget_size(draw, label_width, draw->nk->style.font_size); + nk_text(draw->nk, label, (int)label_len, NK_TEXT_LEFT); + lua_overdub_ui_prepare_widget_size(draw, 120.0f, 24.0f); + return; + } + + draw->row_remaining = 0; + nk_layout_row_dynamic(draw->nk, 24.0f, 2); + nk_text(draw->nk, label, (int)label_len, NK_TEXT_LEFT); +} + +static nk_flags +lua_overdub_ui_text_alignment(lua_State *state, int arg) +{ + if (lua_isnoneornil(state, arg)) { + return NK_TEXT_LEFT; + } + + size_t alignment_len = 0; + const char *alignment = luaL_checklstring(state, arg, &alignment_len); + if (alignment_len == sizeof("Left") - 1 && memcmp(alignment, "Left", alignment_len) == 0) { + return NK_TEXT_LEFT; + } + + if (alignment_len == sizeof("Center") - 1 && memcmp(alignment, "Center", alignment_len) == 0) { + return NK_TEXT_CENTERED; + } + + if (alignment_len == sizeof("Right") - 1 && memcmp(alignment, "Right", alignment_len) == 0) { + return NK_TEXT_RIGHT; + } + + luaL_argerror(state, arg, "alignment must be 'Left', 'Center', or 'Right'"); + return NK_TEXT_LEFT; +} + +static int +lua_overdub_ui_text_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + + size_t text_len = 0; + const char *text = luaL_checklstring(state, 2, &text_len); + if (text_len > INT_MAX) { + return luaL_argerror(state, 2, "text is too long"); + } + + nk_flags alignment = lua_overdub_ui_text_alignment(state, 3); + float width = lua_overdub_ui_text_width(draw, text, text_len); + lua_overdub_ui_prepare_widget_size(draw, width, 22.0f); + nk_text(draw->nk, text, (int)text_len, alignment); + return 0; +} + +static int +lua_overdub_ui_wrapped_text_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + + size_t text_len = 0; + const char *text = luaL_checklstring(state, 2, &text_len); + if (text_len > INT_MAX) { + return luaL_argerror(state, 2, "text is too long"); + } + + lua_Number requested_height = luaL_optnumber(state, 3, 48.0); + if (!isfinite((double)requested_height) || requested_height <= 0.0 || requested_height > 4000.0) { + return luaL_argerror(state, 3, "height must be finite and between 0 and 4000"); + } + + lua_overdub_ui_prepare_widget(draw, (float)requested_height); + nk_text_wrap(draw->nk, text, (int)text_len); + return 0; +} + +static int +lua_overdub_ui_button_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + + size_t label_len = 0; + const char *label = luaL_checklstring(state, 2, &label_len); + if (label_len > INT_MAX) { + return luaL_argerror(state, 2, "button label is too long"); + } + + float width = lua_overdub_ui_text_width(draw, label, label_len) + draw->nk->style.button.padding.x * 2.0f; + lua_overdub_ui_prepare_widget_size(draw, width, 24.0f); + bool pressed = nk_button_text(draw->nk, label, (int)label_len); + lua_pushboolean(state, pressed); + return 1; +} + +static int +lua_overdub_ui_checkbox_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + + size_t label_len = 0; + const char *label = luaL_checklstring(state, 2, &label_len); + if (label_len > INT_MAX) { + return luaL_argerror(state, 2, "checkbox label is too long"); + } + + int value = lua_toboolean(state, 3); + float width = lua_overdub_ui_text_width(draw, label, label_len) + draw->nk->style.font_size + draw->nk->style.checkbox.spacing; + lua_overdub_ui_prepare_widget_size(draw, width, 24.0f); + nk_checkbox_text(draw->nk, label, (int)label_len, &value); + lua_pushboolean(state, value); + return 1; +} + +static bool +lua_overdub_ui_integer_fits_int(lua_Integer value) +{ + return value >= INT_MIN && value <= INT_MAX; +} + +static int +lua_overdub_ui_slider_int_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + + size_t label_len = 0; + const char *label = luaL_checklstring(state, 2, &label_len); + if (label_len > INT_MAX) { + return luaL_argerror(state, 2, "slider label is too long"); + } + + lua_Integer value_arg = luaL_checkinteger(state, 3); + lua_Integer min_arg = luaL_checkinteger(state, 4); + lua_Integer max_arg = luaL_checkinteger(state, 5); + lua_Integer step_arg = luaL_optinteger(state, 6, 1); + + if (!lua_overdub_ui_integer_fits_int(value_arg)) { + return luaL_argerror(state, 3, "value is outside the supported integer range"); + } + + if (!lua_overdub_ui_integer_fits_int(min_arg)) { + return luaL_argerror(state, 4, "minimum is outside the supported integer range"); + } + + if (!lua_overdub_ui_integer_fits_int(max_arg)) { + return luaL_argerror(state, 5, "maximum is outside the supported integer range"); + } + + if (!lua_overdub_ui_integer_fits_int(step_arg) || step_arg <= 0) { + return luaL_argerror(state, 6, "step must be a positive supported integer"); + } + + if (min_arg > max_arg) { + return luaL_error(state, "slider minimum cannot exceed its maximum"); + } + + int value = (int)value_arg; + if (value < (int)min_arg) { + value = (int)min_arg; + } + + if (value > (int)max_arg) { + value = (int)max_arg; + } + + lua_overdub_ui_prepare_labeled_control(draw, label, label_len); + nk_slider_int(draw->nk, (int)min_arg, &value, (int)max_arg, (int)step_arg); + lua_pushinteger(state, value); + return 1; +} + +static bool +lua_overdub_ui_number_valid(lua_Number value) +{ + float converted = (float)value; + return isfinite((double)value) && isfinite(converted); +} + +static int +lua_overdub_ui_slider_float_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + + size_t label_len = 0; + const char *label = luaL_checklstring(state, 2, &label_len); + if (label_len > INT_MAX) { + return luaL_argerror(state, 2, "slider label is too long"); + } + + lua_Number value_arg = luaL_checknumber(state, 3); + lua_Number min_arg = luaL_checknumber(state, 4); + lua_Number max_arg = luaL_checknumber(state, 5); + lua_Number step_arg = luaL_optnumber(state, 6, 0.1); + + if (!lua_overdub_ui_number_valid(value_arg)) { + return luaL_argerror(state, 3, "value must be finite"); + } + + if (!lua_overdub_ui_number_valid(min_arg)) { + return luaL_argerror(state, 4, "minimum must be finite"); + } + + if (!lua_overdub_ui_number_valid(max_arg)) { + return luaL_argerror(state, 5, "maximum must be finite"); + } + + if (!lua_overdub_ui_number_valid(step_arg) || step_arg <= 0.0) { + return luaL_argerror(state, 6, "step must be finite and positive"); + } + + if (min_arg > max_arg) { + return luaL_error(state, "slider minimum cannot exceed its maximum"); + } + + float value = (float)value_arg; + if (value < (float)min_arg) { + value = (float)min_arg; + } + + if (value > (float)max_arg) { + value = (float)max_arg; + } + + lua_overdub_ui_prepare_labeled_control(draw, label, label_len); + nk_slider_float(draw->nk, (float)min_arg, &value, (float)max_arg, (float)step_arg); + lua_pushnumber(state, value); + return 1; +} + +static int +lua_overdub_ui_input_int_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + + size_t label_len = 0; + const char *label = luaL_checklstring(state, 2, &label_len); + if (!lua_overdub_ui_name_valid(label, label_len, LUA_OVERDUB_UI_TITLE_CAP)) { + return luaL_argerror(state, 2, "integer input label must be non-empty, short, and contain no null bytes"); + } + + lua_Integer value_arg = luaL_checkinteger(state, 3); + lua_Integer min_arg = luaL_checkinteger(state, 4); + lua_Integer max_arg = luaL_checkinteger(state, 5); + lua_Integer step_arg = luaL_optinteger(state, 6, 1); + bool value_fits = lua_overdub_ui_integer_fits_int(value_arg); + bool min_fits = lua_overdub_ui_integer_fits_int(min_arg); + bool max_fits = lua_overdub_ui_integer_fits_int(max_arg); + + bool values_fit = value_fits && min_fits && max_fits; + if (!values_fit) { + return luaL_error(state, "integer input values are outside the supported integer range"); + } + + if (!lua_overdub_ui_integer_fits_int(step_arg) || step_arg <= 0) { + return luaL_argerror(state, 6, "step must be a positive supported integer"); + } + + if (min_arg > max_arg) { + return luaL_error(state, "integer input minimum cannot exceed its maximum"); + } + + int value = (int)value_arg; + value = MAX_VAL(value, (int)min_arg); + value = MIN_VAL(value, (int)max_arg); + + float width = lua_overdub_ui_text_width(draw, label, label_len) + 120.0f; + lua_overdub_ui_prepare_widget_size(draw, width, 24.0f); + bool changed = nk_property_int(draw->nk, label, (int)min_arg, &value, (int)max_arg, (int)step_arg, 1.0f); + lua_pushinteger(state, value); + lua_pushboolean(state, changed); + return 2; +} + +static int +lua_overdub_ui_input_float_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + + size_t label_len = 0; + const char *label = luaL_checklstring(state, 2, &label_len); + if (!lua_overdub_ui_name_valid(label, label_len, LUA_OVERDUB_UI_TITLE_CAP)) { + return luaL_argerror(state, 2, "float input label must be non-empty, short, and contain no null bytes"); + } + + lua_Number value_arg = luaL_checknumber(state, 3); + lua_Number min_arg = luaL_checknumber(state, 4); + lua_Number max_arg = luaL_checknumber(state, 5); + lua_Number step_arg = luaL_optnumber(state, 6, 0.1); + bool value_valid = lua_overdub_ui_number_valid(value_arg); + bool min_valid = lua_overdub_ui_number_valid(min_arg); + bool max_valid = lua_overdub_ui_number_valid(max_arg); + + bool values_valid = value_valid && min_valid && max_valid; + if (!values_valid) { + return luaL_error(state, "float input values must be finite"); + } + + if (!lua_overdub_ui_number_valid(step_arg) || step_arg <= 0.0) { + return luaL_argerror(state, 6, "step must be finite and positive"); + } + + if (min_arg > max_arg) { + return luaL_error(state, "float input minimum cannot exceed its maximum"); + } + + float value = (float)value_arg; + value = MAX_VAL(value, (float)min_arg); + value = MIN_VAL(value, (float)max_arg); + + float width = lua_overdub_ui_text_width(draw, label, label_len) + 120.0f; + lua_overdub_ui_prepare_widget_size(draw, width, 24.0f); + + bool changed = nk_property_float(draw->nk, label, (float)min_arg, &value, (float)max_arg, (float)step_arg, 1.0f); + lua_pushnumber(state, value); + lua_pushboolean(state, changed); + return 2; +} + +static int +lua_overdub_ui_text_input_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + + size_t label_len = 0; + const char *label = luaL_checklstring(state, 2, &label_len); + if (label_len > INT_MAX) { + return luaL_argerror(state, 2, "text input label is too long"); + } + + size_t value_len = 0; + const char *value = luaL_checklstring(state, 3, &value_len); + lua_Integer max_length = luaL_optinteger(state, 4, 1024); + if (max_length < 1 || max_length >= LUA_OVERDUB_UI_TEXT_CAP) { + return luaL_argerror(state, 4, "maximum length must be between 1 and 4095"); + } + + if (value_len > (size_t)max_length) { + return luaL_argerror(state, 3, "text exceeds the configured maximum length"); + } + + char buffer[LUA_OVERDUB_UI_TEXT_CAP]; + memcpy(buffer, value, value_len); + buffer[value_len] = 0; + + int edit_len = (int)value_len; + int buffer_cap = (int)max_length + 1; + lua_overdub_ui_prepare_labeled_control(draw, label, label_len); + + nk_flags events = nk_edit_string(draw->nk, (nk_flags)NK_EDIT_FIELD | (nk_flags)NK_EDIT_SIG_ENTER, buffer, &edit_len, buffer_cap, nk_filter_default); + bool changed = edit_len != (int)value_len || memcmp(buffer, value, value_len) != 0; + + lua_pushlstring(state, buffer, (size_t)edit_len); + lua_pushboolean(state, changed); + lua_pushboolean(state, (events & NK_EDIT_COMMITED) != 0); + return 3; +} + +static bool +lua_overdub_ui_combo_items_valid(lua_State *state, int table_index, size_t count) +{ + table_index = lua_absindex(state, table_index); + + for (size_t i = 1; i <= count; ++i) { + lua_rawgeti(state, table_index, (lua_Integer)i); + + size_t item_len = 0; + bool valid = lua_type(state, -1) == LUA_TSTRING; + if (valid) { + lua_tolstring(state, -1, &item_len); + valid = item_len <= INT_MAX; + } + + lua_pop(state, 1); + if (!valid) { + return false; + } + } + + return true; +} + +static int +lua_overdub_ui_combo_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + + size_t label_len = 0; + const char *label = luaL_checklstring(state, 2, &label_len); + if (label_len > INT_MAX) { + return luaL_argerror(state, 2, "combo label is too long"); + } + + luaL_checktype(state, 3, LUA_TTABLE); + int items_index = lua_absindex(state, 3); + size_t item_count = lua_rawlen(state, items_index); + if (item_count == 0 || item_count > LUA_OVERDUB_UI_COMBO_CAP) { + return luaL_argerror(state, 3, "combo must contain between 1 and 256 items"); + } + + if (!lua_overdub_ui_combo_items_valid(state, items_index, item_count)) { + return luaL_argerror(state, 3, "combo items must be strings"); + } + + lua_Integer selected_arg = luaL_checkinteger(state, 4); + if (selected_arg < 1 || (size_t)selected_arg > item_count) { + return luaL_argerror(state, 4, "selected index is outside the combo item range"); + } + + lua_overdub_ui_prepare_labeled_control(draw, label, label_len); + + lua_rawgeti(state, items_index, selected_arg); + size_t selected_len = 0; + const char *selected_text = lua_tolstring(state, -1, &selected_len); + + float popup_height = 24.0f * (float)item_count; + if (popup_height > 240.0f) { + popup_height = 240.0f; + } + + int selected = (int)selected_arg; + struct nk_vec2 popup_size = nk_vec2(240.0f, popup_height); + bool open = nk_combo_begin_text(draw->nk, selected_text, (int)selected_len, popup_size); + lua_pop(state, 1); + + if (open) { + nk_layout_row_dynamic(draw->nk, 22.0f, 1); + for (size_t i = 1; i <= item_count; ++i) { + lua_rawgeti(state, items_index, (lua_Integer)i); + + size_t item_len = 0; + const char *item = lua_tolstring(state, -1, &item_len); + bool chosen = nk_combo_item_text(draw->nk, item, (int)item_len, NK_TEXT_LEFT); + lua_pop(state, 1); + + if (chosen) { + selected = (int)i; + nk_combo_close(draw->nk); + } + } + nk_combo_end(draw->nk); + } + + lua_pushinteger(state, selected); + return 1; +} + +static uint8_t +lua_overdub_ui_check_color_component(lua_State *state, int table_idx, const char *name, uint8_t default_value, bool required) +{ + lua_getfield(state, table_idx, name); + if (lua_isnil(state, -1) && !required) { + lua_pop(state, 1); + return default_value; + } + + lua_Integer value = luaL_checkinteger(state, -1); + lua_pop(state, 1); + if (value < 0 || value > 255) { + luaL_error(state, "color component %s must be between 0 and 255", name); + } + + return (uint8_t)value; +} + +static void +lua_overdub_ui_push_color(lua_State *state, struct nk_color color) +{ + lua_createtable(state, 0, 4); + lua_pushinteger(state, color.r); + lua_setfield(state, -2, "R"); + lua_pushinteger(state, color.g); + lua_setfield(state, -2, "G"); + lua_pushinteger(state, color.b); + lua_setfield(state, -2, "B"); + lua_pushinteger(state, color.a); + lua_setfield(state, -2, "A"); +} + +static struct nk_color +lua_overdub_ui_check_color(lua_State *state, int table_idx) +{ + luaL_checktype(state, table_idx, LUA_TTABLE); + table_idx = lua_absindex(state, table_idx); + return (struct nk_color){ + .r = lua_overdub_ui_check_color_component(state, table_idx, "R", 0, true), + .g = lua_overdub_ui_check_color_component(state, table_idx, "G", 0, true), + .b = lua_overdub_ui_check_color_component(state, table_idx, "B", 0, true), + .a = lua_overdub_ui_check_color_component(state, table_idx, "A", 255, false), + }; +} + +static int +lua_overdub_ui_text_colored_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + + size_t text_len = 0; + const char *text = luaL_checklstring(state, 2, &text_len); + if (text_len > INT_MAX) { + return luaL_argerror(state, 2, "text is too long"); + } + + struct nk_color color = lua_overdub_ui_check_color(state, 3); + nk_flags alignment = lua_overdub_ui_text_alignment(state, 4); + float width = lua_overdub_ui_text_width(draw, text, text_len); + lua_overdub_ui_prepare_widget_size(draw, width, 22.0f); + nk_text_colored(draw->nk, text, (int)text_len, alignment, color); + return 0; +} + +static int +lua_overdub_ui_wrapped_text_colored_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + + size_t text_len = 0; + const char *text = luaL_checklstring(state, 2, &text_len); + if (text_len > INT_MAX) { + return luaL_argerror(state, 2, "text is too long"); + } + + lua_Number height = luaL_optnumber(state, 4, 48.0); + if (!isfinite((double)height) || height <= 0.0 || height > 4000.0) { + return luaL_argerror(state, 4, "height must be finite and between 0 and 4000"); + } + + struct nk_color color = lua_overdub_ui_check_color(state, 3); + lua_overdub_ui_prepare_widget(draw, (float)height); + nk_text_wrap_colored(draw->nk, text, (int)text_len, color); + return 0; +} + +static int +lua_overdub_ui_color_editor_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + + size_t label_len = 0; + const char *label = luaL_checklstring(state, 2, &label_len); + if (label_len > INT_MAX) { + return luaL_argerror(state, 2, "color editor label is too long"); + } + + struct nk_color color = lua_overdub_ui_check_color(state, 3); + + lua_overdub_ui_prepare_labeled_control(draw, label, label_len); + if (nk_combo_begin_color(draw->nk, color, nk_vec2(nk_widget_width(draw->nk), 320.0f))) { + nk_layout_row_dynamic(draw->nk, 120.0f, 1); + struct nk_colorf picked = nk_color_picker(draw->nk, nk_color_cf(color), NK_RGBA); + color = nk_rgba_cf(picked); + + nk_layout_row_dynamic(draw->nk, 24.0f, 1); + int red = color.r; + int green = color.g; + int blue = color.b; + int alpha = color.a; + nk_property_int(draw->nk, "#R", 0, &red, 255, 1, 1); + nk_property_int(draw->nk, "#G", 0, &green, 255, 1, 1); + nk_property_int(draw->nk, "#B", 0, &blue, 255, 1, 1); + nk_property_int(draw->nk, "#A", 0, &alpha, 255, 1, 1); + + color = nk_rgba((nk_byte)red, (nk_byte)green, (nk_byte)blue, (nk_byte)alpha); + nk_combo_end(draw->nk); + } + + lua_overdub_ui_push_color(state, color); + return 1; +} + +static int +lua_overdub_ui_keybind_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + + size_t label_len = 0; + const char *label = luaL_checklstring(state, 2, &label_len); + if (label_len == 0 || label_len >= LUA_OVERDUB_UI_KEYBIND_CAP) { + return luaL_argerror(state, 2, "keybind label must be between 1 and 255 bytes"); + } + + size_t value_len = 0; + const char *value = luaL_checklstring(state, 3, &value_len); + keybind_t bind = KEYBIND_NULL; + if (value_len > 0) { + bind = keybind_parse(str_make((void *)value, value_len), KEYBIND_NULL); + if (!keybind_is_valid(bind)) { + return luaL_argerror(state, 3, "keybind is invalid"); + } + } + + char name[LUA_OVERDUB_UI_WIDGET_ID_CAP]; + if (!lua_overdub_ui_scoped_name(draw, "Keybind", label, label_len, name, sizeof(name))) { + return luaL_error(state, "keybind widget id is too long"); + } + + lua_overdub_ui_prepare_labeled_control(draw, label, label_len); + ui_keybind_capture(&globals.ui_manager.keybind_capture, draw->nk, str_make(name, strlen(name)), &bind); + + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t text = keybind_to_str(bind, tmp.arena); + lua_pushlstring(state, (const char *)text.data, (size_t)text.len); + } + scratch_end(tmp); + return 1; +} + +static int +lua_overdub_ui_group_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + + size_t id_len = 0; + const char *id = luaL_checklstring(state, 2, &id_len); + if (!lua_overdub_ui_name_valid(id, id_len, LUA_OVERDUB_UI_ID_CAP)) { + return luaL_argerror(state, 2, "group id must be non-empty, short, and contain no null bytes"); + } + + lua_Number height = luaL_checknumber(state, 3); + if (!isfinite((double)height) || height <= 0.0 || height > 4000.0) { + return luaL_argerror(state, 3, "group height must be finite and between 0 and 4000"); + } + + luaL_checktype(state, 4, LUA_TFUNCTION); + char name[LUA_OVERDUB_UI_WIDGET_ID_CAP]; + if (!lua_overdub_ui_scoped_name(draw, "Group", id, id_len, name, sizeof(name))) { + return luaL_error(state, "namespaced group id is too long"); + } + + lua_overdub_ui_prepare_widget(draw, (float)height); + struct nk_grid *outer_grid = draw->grid; + int outer_column = draw->grid_column; + int outer_remaining = draw->row_remaining; + bool outer_row_active = draw->grid_row_active; + if (nk_group_begin(draw->nk, name, NK_WINDOW_BORDER)) { + draw->grid = NULL; + draw->grid_column = 0; + draw->grid_row_active = false; + draw->row_remaining = 0; + + lua_pushvalue(state, 4); + lua_pushvalue(state, 1); + + int status = lua_pcall(state, 1, 0, 0); + nk_group_end(draw->nk); + draw->grid = outer_grid; + draw->grid_column = outer_column; + draw->grid_row_active = outer_row_active; + draw->row_remaining = outer_remaining; + + if (status != LUA_OK) { + return lua_error(state); + } + } + + nk_uint scroll_x = 0; + nk_uint scroll_y = 0; + nk_group_get_scroll(draw->nk, name, &scroll_x, &scroll_y, NULL, NULL, NULL); + lua_pushinteger(state, scroll_x); + lua_pushinteger(state, scroll_y); + return 2; +} + +static int +lua_overdub_ui_group_scroll_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + + size_t id_len = 0; + const char *id = luaL_checklstring(state, 2, &id_len); + if (!lua_overdub_ui_name_valid(id, id_len, LUA_OVERDUB_UI_ID_CAP)) { + return luaL_argerror(state, 2, "group id must be non-empty, short, and contain no null bytes"); + } + + char name[LUA_OVERDUB_UI_WIDGET_ID_CAP]; + if (!lua_overdub_ui_scoped_name(draw, "Group", id, id_len, name, sizeof(name))) { + return luaL_error(state, "namespaced group id is too long"); + } + + nk_uint scroll_x = 0; + nk_uint scroll_y = 0; + nk_group_get_scroll(draw->nk, name, &scroll_x, &scroll_y, NULL, NULL, NULL); + lua_pushinteger(state, scroll_x); + lua_pushinteger(state, scroll_y); + return 2; +} + +static int +lua_overdub_ui_set_group_scroll_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + + size_t id_len = 0; + const char *id = luaL_checklstring(state, 2, &id_len); + if (!lua_overdub_ui_name_valid(id, id_len, LUA_OVERDUB_UI_ID_CAP)) { + return luaL_argerror(state, 2, "group id must be non-empty, short, and contain no null bytes"); + } + + lua_Integer scroll_x = luaL_checkinteger(state, 3); + lua_Integer scroll_y = luaL_checkinteger(state, 4); + if (scroll_x < 0 || (uint64_t)scroll_x > UINT_MAX) { + return luaL_argerror(state, 3, "horizontal scroll must fit an unsigned 32-bit integer"); + } + + if (scroll_y < 0 || (uint64_t)scroll_y > UINT_MAX) { + return luaL_argerror(state, 4, "vertical scroll must fit an unsigned 32-bit integer"); + } + + char name[LUA_OVERDUB_UI_WIDGET_ID_CAP]; + if (!lua_overdub_ui_scoped_name(draw, "Group", id, id_len, name, sizeof(name))) { + return luaL_error(state, "namespaced group id is too long"); + } + nk_group_set_scroll(draw->nk, name, (nk_uint)scroll_x, (nk_uint)scroll_y); + return 0; +} + +static int +lua_overdub_ui_tree_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + if (draw->grid) { + return luaL_error(state, "Tree cannot be used directly inside Grid; place it inside a Group"); + } + + size_t title_len = 0; + const char *title = luaL_checklstring(state, 2, &title_len); + if (title_len > INT_MAX) { + return luaL_argerror(state, 2, "tree title is too long"); + } + + enum nk_collapse_states expanded = NK_MINIMIZED; + if (lua_toboolean(state, 3)) { + expanded = NK_MAXIMIZED; + } + luaL_checktype(state, 4, LUA_TFUNCTION); + draw->row_remaining = 0; + + int status = LUA_OK; + if (nk_tree_state_push_text(draw->nk, NK_TREE_NODE, title, (int)title_len, &expanded)) { + lua_pushvalue(state, 4); + lua_pushvalue(state, 1); + status = lua_pcall(state, 1, 0, 0); + nk_tree_pop(draw->nk); + } + + draw->row_remaining = 0; + if (status != LUA_OK) { + return lua_error(state); + } + + lua_pushboolean(state, expanded == NK_MAXIMIZED); + return 1; +} + +static int +lua_overdub_ui_tooltip_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + + size_t text_len = 0; + const char *text = luaL_checklstring(state, 2, &text_len); + if (text_len > INT_MAX) { + return luaL_argerror(state, 2, "tooltip text is too long"); + } + + if (nk_widget_is_hovered(draw->nk)) { + nk_tooltip_text(draw->nk, text, (int)text_len); + } + return 0; +} + +static int +lua_overdub_ui_separator_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + + lua_overdub_ui_prepare_widget(draw, 8.0f); + nk_rule_horizontal(draw->nk, draw->nk->style.window.border_color, true); + return 0; +} + +static int +lua_overdub_ui_row_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + if (draw->grid) { + return luaL_error(state, "Row cannot be used inside Grid"); + } + + lua_Integer columns = luaL_checkinteger(state, 2); + if (columns < 1 || columns > 16) { + return luaL_argerror(state, 2, "column count must be between 1 and 16"); + } + + lua_Number height = luaL_optnumber(state, 3, 24.0); + if (!isfinite((double)height) || height <= 0.0 || height > 1000.0) { + return luaL_argerror(state, 3, "row height must be finite and between 0 and 1000"); + } + + nk_layout_row_dynamic(draw->nk, (float)height, (int)columns); + draw->row_remaining = (int)columns; + return 0; +} + +static int +lua_overdub_ui_row_static_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + if (draw->grid) { + return luaL_error(state, "RowStatic cannot be used inside Grid"); + } + + lua_Integer columns = luaL_checkinteger(state, 2); + lua_Number width = luaL_checknumber(state, 3); + lua_Number height = luaL_optnumber(state, 4, 24.0); + if (columns < 1 || columns > NK_GRID_MAX_COLUMNS) { + return luaL_argerror(state, 2, "column count must be between 1 and 16"); + } + + if (!isfinite((double)width) || width <= 0.0 || width > 4000.0) { + return luaL_argerror(state, 3, "column width must be finite and between 0 and 4000"); + } + + if (!isfinite((double)height) || height <= 0.0 || height > 1000.0) { + return luaL_argerror(state, 4, "row height must be finite and between 0 and 1000"); + } + + nk_layout_row_static(draw->nk, (float)height, (int)width, (int)columns); + draw->row_remaining = (int)columns; + return 0; +} + +static int +lua_overdub_ui_row_values_lua(lua_State *state, enum nk_layout_format format) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + if (draw->grid) { + const char *name = "RowWidths"; + if (format == NK_DYNAMIC) { + name = "RowRatios"; + } + + return luaL_error(state, "%s cannot be used inside Grid", name); + } + + luaL_checktype(state, 2, LUA_TTABLE); + int table_idx = lua_absindex(state, 2); + size_t count = lua_rawlen(state, table_idx); + if (count < 1 || count > NK_GRID_MAX_COLUMNS) { + return luaL_argerror(state, 2, "row must contain between 1 and 16 columns"); + } + + lua_Number height = luaL_optnumber(state, 3, 24.0); + if (!isfinite((double)height) || height <= 0.0 || height > 1000.0) { + return luaL_argerror(state, 3, "row height must be finite and between 0 and 1000"); + } + + float sum = 0.0f; + for (size_t i = 0; i < count; ++i) { + lua_rawgeti(state, table_idx, (lua_Integer)i + 1); + lua_Number value = luaL_checknumber(state, -1); + lua_pop(state, 1); + + if (!isfinite((double)value) || value <= 0.0 || value > 4000.0) { + return luaL_argerror(state, 2, "row column values must be finite and between 0 and 4000"); + } + + draw->row_values[i] = (float)value; + sum += (float)value; + } + + if (format == NK_DYNAMIC) { + for (size_t i = 0; i < count; ++i) { + draw->row_values[i] /= sum; + } + } + + nk_layout_row(draw->nk, format, (float)height, (int)count, draw->row_values); + draw->row_remaining = (int)count; + return 0; +} + +static int +lua_overdub_ui_row_ratios_lua(lua_State *state) +{ + return lua_overdub_ui_row_values_lua(state, NK_DYNAMIC); +} + +static int +lua_overdub_ui_row_widths_lua(lua_State *state) +{ + return lua_overdub_ui_row_values_lua(state, NK_STATIC); +} + +static int +lua_overdub_ui_spacing_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + lua_Integer count = luaL_optinteger(state, 2, 1); + if (count < 1 || count > NK_GRID_MAX_COLUMNS) { + return luaL_argerror(state, 2, "spacing count must be between 1 and 16"); + } + + for (lua_Integer i = 0; i < count; ++i) { + lua_overdub_ui_prepare_widget(draw, 1.0f); + nk_spacing(draw->nk, 1); + } + + return 0; +} + +static uint32_t +lua_overdub_ui_hash_u32(uint32_t hash, uint32_t value) +{ + for (int i = 0; i < 4; ++i) { + hash ^= (uint8_t)(value >> (i * 8)); + hash *= 16777619u; + } + + return hash; +} + +static bool +lua_overdub_ui_grid_columns(lua_State *state, int table_idx, struct nk_grid_column *columns, int count, uint32_t *out_signature) +{ + uint32_t signature = lua_overdub_ui_hash_u32(2166136261u, (uint32_t)count); + for (int i = 0; i < count; ++i) { + lua_rawgeti(state, table_idx, i + 1); + int type = lua_type(state, -1); + + struct nk_grid_column column = {0}; + bool valid = false; + if (type == LUA_TNUMBER) { + lua_Number width = lua_tonumber(state, -1); + if (isfinite((double)width) && width > 0.0 && width <= 4000.0) { + column.sizing = NK_GRID_COLUMN_FIXED; + column.width = (float)width; + valid = true; + } + } else if (type == LUA_TSTRING) { + size_t sizing_len = 0; + const char *sizing = lua_tolstring(state, -1, &sizing_len); + if (sizing_len == sizeof("Content") - 1 && memcmp(sizing, "Content", sizing_len) == 0) { + column.sizing = NK_GRID_COLUMN_CONTENT; + column.min_width = 8.0f; + valid = true; + } else if (sizing_len == sizeof("Flex") - 1 && memcmp(sizing, "Flex", sizing_len) == 0) { + column.sizing = NK_GRID_COLUMN_FLEX; + column.width = 1.0f; + column.min_width = 20.0f; + valid = true; + } + } + lua_pop(state, 1); + + if (!valid) { + return false; + } + + uint32_t width_bits = 0; + mem_copy(&width_bits, &column.width, sizeof(width_bits)); + signature = lua_overdub_ui_hash_u32(signature, (uint32_t)column.sizing); + signature = lua_overdub_ui_hash_u32(signature, width_bits); + columns[i] = column; + } + + if (signature == 0) { + signature = 1; + } + *out_signature = signature; + return true; +} + +static lua_overdub_ui_grid_state_t * +lua_overdub_ui_grid_state(lua_overdub_ui_context_t *context, nk_hash scope, const char *id, size_t id_len) +{ + lua_overdub_ui_grid_state_t *free_slot = NULL; + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_UI_GRIDS; ++i) { + lua_overdub_ui_grid_state_t *slot = &context->grids[i]; + if (slot->scope == scope && slot->key_len == id_len && memcmp(slot->key, id, id_len) == 0) { + return slot; + } + + if (!free_slot && slot->key_len == 0) { + free_slot = slot; + } + } + + if (free_slot) { + memcpy(free_slot->key, id, id_len); + free_slot->key[id_len] = 0; + free_slot->key_len = id_len; + free_slot->scope = scope; + } + + return free_slot; +} + +static int +lua_overdub_ui_grid_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + if (draw->grid) { + return luaL_error(state, "Grid cannot be nested inside Grid"); + } + + size_t id_len = 0; + const char *id = luaL_checklstring(state, 2, &id_len); + if (!lua_overdub_ui_name_valid(id, id_len, LUA_OVERDUB_UI_ID_CAP)) { + return luaL_argerror(state, 2, "grid id must be non-empty, short, and contain no null bytes"); + } + + luaL_checktype(state, 3, LUA_TTABLE); + int columns_idx = lua_absindex(state, 3); + size_t column_count = lua_rawlen(state, columns_idx); + if (column_count < 1 || column_count > NK_GRID_MAX_COLUMNS) { + return luaL_argerror(state, 3, "grid must contain between 1 and 16 columns"); + } + + int callback_idx = 4; + lua_Number row_height = 24.0; + if (lua_gettop(state) == 5) { + row_height = luaL_checknumber(state, 4); + callback_idx = 5; + } else if (lua_gettop(state) != 4) { + return luaL_error(state, "expected Grid(id, columns, callback) or Grid(id, columns, height, callback)"); + } + + if (!isfinite((double)row_height) || row_height <= 0.0 || row_height > 1000.0) { + return luaL_argerror(state, 4, "grid row height must be finite and between 0 and 1000"); + } + luaL_checktype(state, callback_idx, LUA_TFUNCTION); + + struct nk_grid_column columns[NK_GRID_MAX_COLUMNS] = {0}; + uint32_t signature = 0; + if (!lua_overdub_ui_grid_columns(state, columns_idx, columns, (int)column_count, &signature)) { + return luaL_argerror(state, 3, "grid columns must be positive pixel widths, 'Content', or 'Flex'"); + } + + nk_hash scope = draw->nk->current->layout->text_selection_scope; + lua_overdub_ui_grid_state_t *slot = lua_overdub_ui_grid_state(draw->context, scope, id, id_len); + if (!slot) { + return luaL_error(state, "Overdub UI grid limit reached or grid id is too long"); + } + + struct nk_grid_options options = { + .row_height = (float)row_height, + .column_gap = draw->nk->style.window.spacing.x, + .generation = signature, + }; + struct nk_grid grid; + draw->row_remaining = 0; + nk_grid_begin(draw->nk, &grid, &slot->state, columns, (int)column_count, &options); + draw->grid = &grid; + + lua_pushvalue(state, callback_idx); + lua_pushvalue(state, 1); + int status = lua_pcall(state, 1, 0, 0); + + lua_overdub_ui_grid_end_row(draw); + nk_grid_end(&grid); + draw->grid = NULL; + + if (status != LUA_OK) { + return lua_error(state); + } + + return 0; +} + +static int +lua_overdub_ui_next_row_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + if (!draw->grid) { + return luaL_error(state, "NextRow is only valid inside Grid"); + } + + lua_overdub_ui_grid_end_row(draw); + return 0; +} + +static int +lua_overdub_ui_viewport_size_lua(lua_State *state) +{ + lua_overdub_ui_draw_context_t *draw = lua_overdub_ui_draw_context_check(state); + + lua_pushinteger(state, draw->context->viewport_width); + lua_pushinteger(state, draw->context->viewport_height); + return 2; +} + +static bool +lua_overdub_ui_name_valid(const char *value, size_t len, size_t cap) +{ + if (!value || len == 0 || len >= cap) { + return false; + } + + return memchr(value, 0, len) == NULL; +} + +static int +lua_overdub_ui_register_window_lua(lua_State *state) +{ + lua_overdub_ui_context_t *context = lua_overdub_ui_context_check(state); + + int argument_count = lua_gettop(state); + int callback_index = 2; + if (argument_count == 3) { + callback_index = 3; + } else if (argument_count != 2) { + return luaL_error(state, "expected RegisterWindow(id, callback) or RegisterWindow(id, title, callback)"); + } + + size_t id_len = 0; + const char *id = luaL_checklstring(state, 1, &id_len); + if (!lua_overdub_ui_name_valid(id, id_len, LUA_OVERDUB_UI_ID_CAP)) { + return luaL_argerror(state, 1, "window id must be non-empty, short, and contain no null bytes"); + } + + size_t title_len = id_len; + const char *title = id; + if (argument_count == 3) { + title = luaL_checklstring(state, 2, &title_len); + } + + if (!lua_overdub_ui_name_valid(title, title_len, LUA_OVERDUB_UI_TITLE_CAP)) { + return luaL_argerror(state, 2, "window title must be non-empty, short, and contain no null bytes"); + } + + luaL_checktype(state, callback_index, LUA_TFUNCTION); + if (lua_overdub_ui_window_find_public_id(context, id, id_len)) { + return luaL_error(state, "UI window '%s' is already registered", id); + } + + int slot_index = 0; + lua_overdub_ui_window_t *window = lua_overdub_ui_window_find_free(context, &slot_index); + if (!window) { + return luaL_error(state, "Overdub UI window limit reached"); + } + + int name_len = snprintf(window->name, sizeof(window->name), "%.*s::%.*s", (int)context->mod_id.len, (const char *)context->mod_id.data, (int)id_len, id); + if (name_len < 0 || name_len >= (int)sizeof(window->name)) { + mem_zero(window, sizeof(*window)); + return luaL_error(state, "namespaced UI window name is too long"); + } + + memcpy(window->public_id, id, id_len); + window->public_id[id_len] = 0; + window->public_id_len = id_len; + + memcpy(window->title, title, title_len); + window->title[title_len] = 0; + + lua_pushvalue(state, callback_index); + int callback_ref = luaL_ref(state, LUA_REGISTRYINDEX); + + uint64_t id_number = context->next_window_id; + context->next_window_id += 1; + if (id_number == 0) { + id_number = context->next_window_id; + context->next_window_id += 1; + } + + lua_overdub_ui_window_handle_t *handle = lua_newuserdatauv(state, sizeof(*handle), 0); + *handle = (lua_overdub_ui_window_handle_t){ + .context = context, + .id = id_number, + }; + luaL_setmetatable(state, LUA_OVERDUB_UI_WINDOW_META); + + lua_pushvalue(state, -1); + int handle_ref = luaL_ref(state, LUA_REGISTRYINDEX); + + float offset = (float)(slot_index % 8) * 24.0f; + window->id = id_number; + window->callback_ref = callback_ref; + window->handle_ref = handle_ref; + window->bounds = nk_rect(40.0f + offset, 40.0f + offset, 420.0f, 300.0f); + window->active = true; + window->open = true; + window->show_requested = true; + return 1; +} + +static int +luaopen_overdub_ui(lua_State *state) +{ + static const luaL_Reg functions[] = { + {"RegisterWindow", lua_overdub_ui_register_window_lua}, + {NULL, NULL}, + }; + + luaL_newlib(state, functions); + return 1; +} + +lua_overdub_ui_context_t * +lua_overdub_ui_context_create(arena_t *arena, lua_runtime_t *runtime, str_t mod_id, uint32_t owner_thread_id) +{ + if (!arena || !arena->backing || !runtime || !runtime->state) { + return NULL; + } + + if (str_is_empty(mod_id) || owner_thread_id == 0) { + return NULL; + } + + lua_overdub_ui_context_t *context = ARENA_PUSH_ZERO(arena, lua_overdub_ui_context_t); + if (!context) { + return NULL; + } + + context->runtime = runtime; + context->mod_id = mod_id; + context->owner_thread_id = owner_thread_id; + context->next_window_id = 1; + + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_UI_WINDOWS; ++i) { + context->windows[i].callback_ref = LUA_NOREF; + context->windows[i].handle_ref = LUA_NOREF; + } + + return context; +} + +void +lua_overdub_ui_context_destroy(lua_overdub_ui_context_t *context) +{ + if (!context) { + return; + } + + lua_State *state = context->runtime->state; + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_UI_WINDOWS; ++i) { + lua_overdub_ui_window_invalidate_handle(context, &context->windows[i]); + lua_overdub_ui_window_release(context, &context->windows[i]); + } + + if (state) { + lua_pushlightuserdata(state, &g_lua_overdub_ui_context_key); + lua_pushnil(state); + lua_rawset(state, LUA_REGISTRYINDEX); + } + +} + +bool +lua_overdub_ui_register(lua_State *state, lua_overdub_ui_context_t *context) +{ + if (!state || !context || context->runtime->state != state) { + return false; + } + + lua_pushlightuserdata(state, &g_lua_overdub_ui_context_key); + lua_pushlightuserdata(state, context); + lua_rawset(state, LUA_REGISTRYINDEX); + + if (luaL_newmetatable(state, LUA_OVERDUB_UI_WINDOW_META)) { + static const luaL_Reg methods[] = { + {"Remove", lua_overdub_ui_window_remove_lua}, + {"IsActive", lua_overdub_ui_window_is_active_lua}, + {"SetOpen", lua_overdub_ui_window_set_open_lua}, + {"IsOpen", lua_overdub_ui_window_is_open_lua}, + {NULL, NULL}, + }; + + luaL_setfuncs(state, methods, 0); + lua_pushvalue(state, -1); + lua_setfield(state, -2, "__index"); + lua_pushcfunction(state, lua_overdub_ui_window_gc_lua); + lua_setfield(state, -2, "__gc"); + lua_pushliteral(state, "Overdub UI Window"); + lua_setfield(state, -2, "__metatable"); + } + lua_pop(state, 1); + + if (luaL_newmetatable(state, LUA_OVERDUB_UI_CONTEXT_META)) { + static const luaL_Reg methods[] = { + {"Text", lua_overdub_ui_text_lua }, + {"TextColored", lua_overdub_ui_text_colored_lua }, + {"WrappedText", lua_overdub_ui_wrapped_text_lua }, + {"WrappedTextColored", lua_overdub_ui_wrapped_text_colored_lua}, + {"Button", lua_overdub_ui_button_lua }, + {"Checkbox", lua_overdub_ui_checkbox_lua }, + {"SliderInt", lua_overdub_ui_slider_int_lua }, + {"SliderFloat", lua_overdub_ui_slider_float_lua }, + {"InputInt", lua_overdub_ui_input_int_lua }, + {"InputFloat", lua_overdub_ui_input_float_lua }, + {"InputText", lua_overdub_ui_text_input_lua }, + {"TextInput", lua_overdub_ui_text_input_lua }, + {"Dropdown", lua_overdub_ui_combo_lua }, + {"Combo", lua_overdub_ui_combo_lua }, + {"ColorEditor", lua_overdub_ui_color_editor_lua }, + {"Keybind", lua_overdub_ui_keybind_lua }, + {"Group", lua_overdub_ui_group_lua }, + {"GroupScroll", lua_overdub_ui_group_scroll_lua }, + {"SetGroupScroll", lua_overdub_ui_set_group_scroll_lua }, + {"Tree", lua_overdub_ui_tree_lua }, + {"Tooltip", lua_overdub_ui_tooltip_lua }, + {"Separator", lua_overdub_ui_separator_lua }, + {"Spacing", lua_overdub_ui_spacing_lua }, + {"Row", lua_overdub_ui_row_lua }, + {"RowStatic", lua_overdub_ui_row_static_lua }, + {"RowRatios", lua_overdub_ui_row_ratios_lua }, + {"RowWidths", lua_overdub_ui_row_widths_lua }, + {"Grid", lua_overdub_ui_grid_lua }, + {"NextRow", lua_overdub_ui_next_row_lua }, + {"ViewportSize", lua_overdub_ui_viewport_size_lua }, + {NULL, NULL }, + }; + + luaL_setfuncs(state, methods, 0); + lua_pushvalue(state, -1); + lua_setfield(state, -2, "__index"); + lua_pushliteral(state, "Overdub UI Context"); + lua_setfield(state, -2, "__metatable"); + } + lua_pop(state, 1); + + return lua_overdub_preload_module(state, "overdub.ui", luaopen_overdub_ui); +} + +static void +lua_overdub_ui_draw_window(lua_overdub_ui_context_t *context, lua_overdub_ui_window_t *window, bool *in_callback) +{ + if (!window->active || !window->open || window->remove_requested) { + return; + } + + if (window->created && window->show_requested) { + nk_window_show(context->nk, window->name, NK_SHOWN); + } + window->show_requested = false; + + nk_flags flags = NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE; + flags |= NK_WINDOW_TITLE | NK_WINDOW_CLOSABLE | NK_WINDOW_MINIMIZABLE; + flags |= (nk_flags)NK_WINDOW_CLOSE_BUTTON_HIDES; + + bool visible = nk_begin_titled(context->nk, window->name, window->title, window->bounds, flags); + window->created = true; + window->drawing = true; + + bool called = true; + if (visible) { + lua_overdub_ui_push_draw_context(context); + + *in_callback = true; + called = lua_runtime_call_ref(context->runtime, window->callback_ref, 1, 0); + *in_callback = false; + context->draw_token += 1; + } + + nk_end(context->nk); + window->drawing = false; + + if (nk_window_is_hidden(context->nk, window->name)) { + window->open = false; + } + + if (!called) { + LOG_ERROR("Overdub Lua mod '%.*s': removing failed UI window '%s'", STR_ARG(context->mod_id), window->public_id); + window->remove_requested = true; + } + + if (window->remove_requested) { + lua_overdub_ui_window_release(context, window); + } +} + +uint64_t +lua_overdub_ui_draw_windows(lua_overdub_ui_context_t *ui, struct nk_context *nk, bool *in_cb, unsigned int vw, unsigned int vh) +{ + if (!ui || !nk || !in_cb || *in_cb) { + return 0; + } + + if (!lua_overdub_ui_draw_begin(ui, nk, vw, vh)) { + return 0; + } + + uint64_t start_us = time_now_us(); + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_UI_WINDOWS; ++i) { + lua_overdub_ui_draw_window(ui, &ui->windows[i], in_cb); + } + + lua_overdub_ui_draw_end(ui); + return time_now_us() - start_us; +} + +bool +lua_overdub_ui_begin_callback(lua_overdub_ui_context_t *ui, struct nk_context *nk, unsigned int vw, unsigned int vh) +{ + if (!lua_overdub_ui_draw_begin(ui, nk, vw, vh)) { + return false; + } + + lua_overdub_ui_push_draw_context(ui); + return true; +} + +void +lua_overdub_ui_end_callback(lua_overdub_ui_context_t *ui) +{ + lua_overdub_ui_draw_end(ui); +} diff --git a/src/lua_overdub_unreal.c b/src/lua_overdub_unreal.c new file mode 100644 index 0000000..38c4b47 --- /dev/null +++ b/src/lua_overdub_unreal.c @@ -0,0 +1,3547 @@ +#include "lua_overdub_unreal.h" + +#include "config.h" +#include "globals.h" +#include "log.h" +#include "lua_overdub.h" +#include "lua_unreal_prop.h" +#include "lua_runtime.h" +#include "scratch.h" +#include "unreal.h" +#include "unreal_prop.h" +#include "unreal_reflect.h" + +#include "lua/src/lauxlib.h" +#include "lua/src/lua.h" + +#include +#include +#include + +#define LUA_OVERDUB_HOOK_HANDLE_META "overdub.unreal.HookHandle" +#define LUA_OVERDUB_DELEGATE_HANDLE_META "overdub.unreal.DelegateHandle" +#define LUA_OVERDUB_CALL_META "overdub.unreal.Call" +#define LUA_OVERDUB_NOTIFY_HANDLE_META "overdub.unreal.NotificationHandle" + +typedef struct lua_overdub_reflected_class_s lua_overdub_reflected_class_t; +typedef struct lua_overdub_reflected_func_s lua_overdub_reflected_func_t; +typedef struct lua_overdub_pending_func_s lua_overdub_pending_func_t; + +struct lua_overdub_reflected_func_s { + struct lua_overdub_unreal_context_s *context; + int callback_ref; + bool active; + bool reentry_reported; +}; + +struct lua_overdub_reflected_class_s { + lua_overdub_reflected_class_t *next; + lua_overdub_reflected_func_t *funcs; + str_t name; + uint32_t num_funcs; +}; + +struct lua_overdub_pending_func_s { + fweak_object_ptr_t object; + fweak_object_ptr_t function; + ufunc_t *function_raw; + lua_overdub_reflected_func_t *impl; + void *params; + uint32_t initialized_count; +}; + +static void MOD_CALL +lua_overdub_unreal_reflected_func_call(unreal_func_call_t *call); +static bool +lua_overdub_unreal_queue_reflected_func(lua_overdub_reflected_func_t *func, unreal_func_call_t *call); +static int +lua_overdub_unreal_bind_delegate_lua(lua_State *state); + +typedef struct lua_overdub_root_claim_s lua_overdub_root_claim_t; +struct lua_overdub_root_claim_s { + fweak_object_ptr_t object; + lua_overdub_root_claim_t *next; +}; + +typedef struct lua_overdub_global_root_s lua_overdub_global_root_t; +struct lua_overdub_global_root_s { + fweak_object_ptr_t object; + uint32_t claim_count; + bool externally_rooted; + lua_overdub_global_root_t *next; +}; + +typedef uint8_t lua_overdub_hook_kind_t; +enum { + LUA_OVERDUB_HOOK_FUNCTION, + LUA_OVERDUB_HOOK_POST_LOAD, +}; + +typedef struct lua_overdub_hook_s lua_overdub_hook_t; +struct lua_overdub_hook_s { + fweak_object_ptr_t target; + uint64_t id; + int before_ref; + int after_ref; + lua_overdub_hook_kind_t kind; + bool active; +}; + +typedef struct lua_overdub_pending_hook_s lua_overdub_pending_hook_t; +struct lua_overdub_pending_hook_s { + fweak_object_ptr_t object; + fweak_object_ptr_t function; + ufunc_t *function_raw; + void *params; + uint32_t initialized_count; + bool after; + bool consumed; +}; + +typedef struct lua_overdub_hook_handle_s lua_overdub_hook_handle_t; +struct lua_overdub_hook_handle_s { + lua_overdub_unreal_context_t *context; + uint64_t id; + int slot; +}; + +typedef struct lua_overdub_delegate_binding_s lua_overdub_delegate_binding_t; +struct lua_overdub_delegate_binding_s { + fweak_object_ptr_t source; + fscript_delegate_t delegate; + fprop_t *property; + uint64_t id; + bool active; +}; + +typedef struct lua_overdub_delegate_handle_s lua_overdub_delegate_handle_t; +struct lua_overdub_delegate_handle_s { + lua_overdub_unreal_context_t *context; + uint64_t id; + int slot; +}; + +typedef struct lua_overdub_call_s lua_overdub_call_t; +struct lua_overdub_call_s { + lua_overdub_unreal_context_t *context; + fweak_object_ptr_t object; + fweak_object_ptr_t function; + ufunc_t *function_raw; + void *params; + bool valid; + bool before; + bool deferred; + bool consumed; + bool skip_requested; +}; + +typedef struct lua_overdub_notification_s lua_overdub_notification_t; +typedef uint8_t lua_overdub_notification_kind_t; +enum { + LUA_OVERDUB_NOTIFICATION_CREATED, + LUA_OVERDUB_NOTIFICATION_DELETED, +}; + +struct lua_overdub_notification_s { + fweak_object_ptr_t target; + uobject_t *target_object; + uint64_t id; + int callback_ref; + lua_overdub_notification_kind_t kind; + bool active; + bool delete_queued; +}; + +typedef struct lua_overdub_pending_object_s lua_overdub_pending_object_t; +struct lua_overdub_pending_object_s { + fweak_object_ptr_t object; + int next_notification; +}; + +typedef struct lua_overdub_notification_handle_s lua_overdub_notification_handle_t; +struct lua_overdub_notification_handle_s { + lua_overdub_unreal_context_t *context; + uint64_t id; + int slot; +}; + +struct lua_overdub_unreal_context_s { + arena_t *arena; + arena_t param_arena; + lua_runtime_t *runtime; + bool *in_callback; + lua_unreal_context_t codec; + str_t mod_id; + uint32_t owner_thread_id; + lua_overdub_reflected_class_t *reflected_classes; + lua_overdub_root_claim_t *root_claims; + lua_overdub_root_claim_t *root_claim_free; + lua_overdub_hook_t hooks[CONFIG_LUA_OVERDUB_MAX_HOOKS]; + lua_overdub_delegate_binding_t delegate_bindings[CONFIG_LUA_OVERDUB_MAX_DELEGATE_BINDINGS]; + lua_overdub_pending_func_t pending_funcs[CONFIG_LUA_OVERDUB_MAX_PENDING_FUNC_CALLS]; + lua_overdub_pending_hook_t pending_hooks[CONFIG_LUA_OVERDUB_MAX_PENDING_HOOKS]; + lua_overdub_notification_t notifications[CONFIG_LUA_OVERDUB_MAX_NOTIFICATIONS]; + lua_overdub_pending_object_t pending_objects[CONFIG_LUA_OVERDUB_MAX_PENDING_OBJECTS]; + lua_overdub_unreal_context_t *notification_next; + CRITICAL_SECTION notification_lock; + uint64_t next_hook_id; + uint64_t next_delegate_id; + uint64_t next_notification_id; + int pending_func_count; + int pending_hook_count; + int pending_object_head; + int pending_object_count; + int pending_delete_count; + int notification_count; + bool pending_func_overflow; + bool pending_hook_overflow; + bool pending_object_overflow; + bool notifications_attached; + bool reflected_active; +}; + +static char g_lua_overdub_unreal_context_key; +static lua_overdub_global_root_t *g_lua_overdub_global_roots; +static lua_overdub_global_root_t *g_lua_overdub_global_root_free; +static int g_lua_overdub_post_load_hook_count; +static SRWLOCK g_lua_overdub_notification_lock = SRWLOCK_INIT; +static volatile LONG g_lua_overdub_notification_context_count; +static lua_overdub_unreal_context_t *g_lua_overdub_notification_first; + +static void +lua_overdub_unreal_notifications_detach(lua_overdub_unreal_context_t *context) +{ + if (!context || !context->notifications_attached) { + return; + } + + AcquireSRWLockExclusive(&g_lua_overdub_notification_lock); + lua_overdub_unreal_context_t **at = &g_lua_overdub_notification_first; + while (*at && *at != context) { + at = &(*at)->notification_next; + } + + if (*at == context) { + *at = context->notification_next; + InterlockedDecrement(&g_lua_overdub_notification_context_count); + } + + context->notification_next = NULL; + context->notifications_attached = false; + ReleaseSRWLockExclusive(&g_lua_overdub_notification_lock); +} + +static bool +lua_overdub_weak_equal(fweak_object_ptr_t left, fweak_object_ptr_t right) +{ + return left.object_idx == right.object_idx && left.object_serial == right.object_serial; +} + +static bool +lua_overdub_unreal_access_check(void *user) +{ + lua_overdub_unreal_context_t *context = user; + return context && context->owner_thread_id != 0 && context->owner_thread_id == thread_current_id(); +} + +static uobject_t * +lua_overdub_unreal_find_object(void *user, str_t path) +{ + (void)user; + return unreal_uobject_find_by_path_name(NULL, path); +} + +static bool +lua_overdub_unreal_process_event(void *user, uobject_t *receiver, ufunc_t *function, void *params) +{ + if (!lua_overdub_unreal_access_check(user) || !receiver || !function) { + return false; + } + unreal_process_event_observed(receiver, function, params); + return true; +} + +static lua_overdub_unreal_context_t * +lua_overdub_unreal_context_get(lua_State *state) +{ + lua_pushlightuserdata(state, &g_lua_overdub_unreal_context_key); + lua_rawget(state, LUA_REGISTRYINDEX); + lua_overdub_unreal_context_t *context = lua_touserdata(state, -1); + lua_pop(state, 1); + return context; +} + +static lua_overdub_unreal_context_t * +lua_overdub_unreal_context_check(lua_State *state) +{ + lua_overdub_context_check(state); + lua_overdub_unreal_context_t *context = lua_overdub_unreal_context_get(state); + if (!lua_overdub_unreal_access_check(context)) { + luaL_error(state, "Unreal access is only available on the owning game thread"); + } + return context; +} + +static uobject_t * +lua_overdub_unreal_object_check(lua_State *state, int idx) +{ + lua_overdub_unreal_context_check(state); + uobject_t *object = lua_unreal_object_get(state, idx); + if (!object) { + luaL_argerror(state, idx, "expected a live UObject"); + } + return object; +} + +static uclass_t * +lua_overdub_unreal_class_check(lua_State *state, int idx) +{ + uobject_t *object = lua_overdub_unreal_object_check(state, idx); + if (!globals.unreal.core_class || !unreal_uobject_is_a(object, globals.unreal.core_class)) { + luaL_argerror(state, idx, "expected a live UClass"); + } + return (uclass_t *)object; +} + +static ustruct_t * +lua_overdub_unreal_struct_check(lua_State *state, int idx) +{ + uobject_t *object = lua_overdub_unreal_object_check(state, idx); + bool is_struct = (globals.unreal.core_class && unreal_uobject_is_a(object, globals.unreal.core_class)) || + (globals.unreal.core_scriptstruct && unreal_uobject_is_a(object, globals.unreal.core_scriptstruct)) || + (globals.unreal.core_func && unreal_uobject_is_a(object, globals.unreal.core_func)); + if (!is_struct) { + luaL_argerror(state, idx, "expected a live UStruct, UClass, UScriptStruct, or UFunction"); + } + return (ustruct_t *)object; +} + +static ufunc_t * +lua_overdub_unreal_function_check(lua_State *state, int idx) +{ + uobject_t *object = lua_overdub_unreal_object_check(state, idx); + if (!globals.unreal.core_func || !unreal_uobject_is_a(object, globals.unreal.core_func)) { + luaL_argerror(state, idx, "expected a live UFunction"); + } + return (ufunc_t *)object; +} + +static uenum_t * +lua_overdub_unreal_enum_check(lua_State *state, int idx) +{ + uobject_t *object = lua_overdub_unreal_object_check(state, idx); + if (!globals.unreal.core_enum || !unreal_uobject_is_a(object, globals.unreal.core_enum)) { + luaL_argerror(state, idx, "expected a live UEnum"); + } + + uenum_t *uenum = (uenum_t *)object; + if (uenum->names.num < 0 || uenum->names.max < uenum->names.num || (uenum->names.num > 0 && !uenum->names.data)) { + luaL_error(state, "the UEnum name table is invalid"); + } + return uenum; +} + +static uint32_t +lua_overdub_unreal_u32_check(lua_State *state, int idx, const char *message) +{ + lua_Integer value = luaL_checkinteger(state, idx); + if (value < 0 || (lua_Unsigned)value > UINT32_MAX) { + luaL_argerror(state, idx, message); + } + return (uint32_t)value; +} + +static uint64_t +lua_overdub_unreal_next_hook_id(lua_overdub_unreal_context_t *context) +{ + uint64_t id = context->next_hook_id++; + if (id == 0) { + id = context->next_hook_id++; + } + return id; +} + +static uint64_t +lua_overdub_unreal_next_id(uint64_t *next_id) +{ + uint64_t id = (*next_id)++; + if (id == 0) { + id = (*next_id)++; + } + return id; +} + +static fweak_object_ptr_t +lua_overdub_unreal_invalid_weak(void) +{ + fweak_object_ptr_t weak = {.object_idx = -1}; + return weak; +} + +static uclass_t * +lua_overdub_unreal_class_arg(lua_State *state, int idx) +{ + if (lua_type(state, idx) != LUA_TSTRING) { + return lua_overdub_unreal_class_check(state, idx); + } + + size_t path_len = 0; + const char *path_data = lua_tolstring(state, idx, &path_len); + if (path_len == 0 || memchr(path_data, 0, path_len)) { + luaL_argerror(state, idx, "UClass path cannot be empty or contain null bytes"); + } + + str_t path = str_make((void *)path_data, (uint64_t)path_len); + uobject_t *object = unreal_uobject_find_by_path_name(globals.unreal.core_class, path); + if (!object) { + luaL_argerror(state, idx, "UClass was not found"); + } + return (uclass_t *)object; +} + +static bool +lua_overdub_unreal_notification_matches(lua_overdub_notification_t *notification, uobject_t *object) +{ + if (!notification || !notification->active || !object) { + return false; + } + + if (notification->kind != LUA_OVERDUB_NOTIFICATION_CREATED) { + return false; + } + + uclass_t *target = (uclass_t *)unreal_fweak_object_resolve(notification->target); + return target && unreal_uobject_is_a(object, target); +} + +static bool +lua_overdub_unreal_delete_notification_matches(lua_overdub_notification_t *notification, uobject_t *object, int32_t idx) +{ + if (!notification || !notification->active || notification->kind != LUA_OVERDUB_NOTIFICATION_DELETED) { + return false; + } + + bool same_object = notification->target_object == object; + bool same_index = notification->target.object_idx == idx; + return !notification->delete_queued && same_object && same_index; +} + +static lua_overdub_notification_t * +lua_overdub_unreal_notification_from_handle(lua_overdub_notification_handle_t *handle) +{ + if (!handle || !handle->context || handle->slot < 0 || handle->slot >= CONFIG_LUA_OVERDUB_MAX_NOTIFICATIONS) { + return NULL; + } + + lua_overdub_notification_t *notification = &handle->context->notifications[handle->slot]; + if (!notification->active || notification->id != handle->id) { + return NULL; + } + return notification; +} + +static lua_overdub_notification_handle_t * +lua_overdub_unreal_notification_handle_check(lua_State *state) +{ + lua_overdub_notification_handle_t *handle = luaL_checkudata(state, 1, LUA_OVERDUB_NOTIFY_HANDLE_META); + lua_overdub_unreal_context_t *context = lua_overdub_unreal_context_check(state); + if (!handle->context || handle->context != context || handle->id == 0) { + luaL_error(state, "Unreal notification handle is invalid"); + } + return handle; +} + +static int +lua_overdub_unreal_notification_remove_lua(lua_State *state) +{ + lua_overdub_notification_handle_t *handle = lua_overdub_unreal_notification_handle_check(state); + lua_overdub_unreal_context_t *context = handle->context; + lua_overdub_notification_t *notification; + int callback_ref = LUA_NOREF; + bool detach = false; + + EnterCriticalSection(&context->notification_lock); + notification = lua_overdub_unreal_notification_from_handle(handle); + if (notification) { + if (notification->delete_queued) { + context->pending_delete_count -= 1; + } + + callback_ref = notification->callback_ref; + notification->callback_ref = LUA_NOREF; + notification->active = false; + notification->delete_queued = false; + context->notification_count -= 1; + detach = context->notification_count == 0; + } + LeaveCriticalSection(&context->notification_lock); + + if (detach) { + lua_overdub_unreal_notifications_detach(context); + } + + if (callback_ref != LUA_NOREF && callback_ref != LUA_REFNIL) { + luaL_unref(state, LUA_REGISTRYINDEX, callback_ref); + } + + lua_pushboolean(state, notification != NULL); + return 1; +} + +static int +lua_overdub_unreal_notification_is_active_lua(lua_State *state) +{ + lua_overdub_notification_handle_t *handle = lua_overdub_unreal_notification_handle_check(state); + lua_overdub_unreal_context_t *context = handle->context; + + EnterCriticalSection(&context->notification_lock); + bool active = lua_overdub_unreal_notification_from_handle(handle) != NULL; + LeaveCriticalSection(&context->notification_lock); + + lua_pushboolean(state, active); + return 1; +} + +static int +lua_overdub_unreal_notification_handle_gc_lua(lua_State *state) +{ + lua_overdub_notification_handle_t *handle = luaL_checkudata(state, 1, LUA_OVERDUB_NOTIFY_HANDLE_META); + handle->context = NULL; + handle->id = 0; + handle->slot = -1; + return 0; +} + +static void +lua_overdub_unreal_hook_deactivate(lua_State *state, lua_overdub_hook_t *hook) +{ + if (!hook || !hook->active) { + return; + } + + if (state && hook->before_ref != LUA_NOREF && hook->before_ref != LUA_REFNIL) { + luaL_unref(state, LUA_REGISTRYINDEX, hook->before_ref); + } + + if (state && hook->after_ref != LUA_NOREF && hook->after_ref != LUA_REFNIL) { + luaL_unref(state, LUA_REGISTRYINDEX, hook->after_ref); + } + + if (hook->kind == LUA_OVERDUB_HOOK_POST_LOAD) { + ASSERT(g_lua_overdub_post_load_hook_count > 0); + g_lua_overdub_post_load_hook_count -= 1; + } + + hook->before_ref = LUA_NOREF; + hook->after_ref = LUA_NOREF; + hook->active = false; +} + +static lua_overdub_hook_t * +lua_overdub_unreal_hook_from_handle(lua_overdub_hook_handle_t *handle) +{ + if (!handle || !handle->context || handle->slot < 0 || handle->slot >= CONFIG_LUA_OVERDUB_MAX_HOOKS) { + return NULL; + } + + lua_overdub_hook_t *hook = &handle->context->hooks[handle->slot]; + return hook->active && hook->id == handle->id ? hook : NULL; +} + +static lua_overdub_hook_handle_t * +lua_overdub_unreal_hook_handle_check(lua_State *state) +{ + lua_overdub_hook_handle_t *handle = luaL_checkudata(state, 1, LUA_OVERDUB_HOOK_HANDLE_META); + lua_overdub_unreal_context_t *context = lua_overdub_unreal_context_check(state); + if (!handle->context || handle->context != context || handle->id == 0) { + luaL_error(state, "Hook handle is invalid"); + } + return handle; +} + +static int +lua_overdub_unreal_hook_handle_remove_lua(lua_State *state) +{ + lua_overdub_hook_handle_t *handle = lua_overdub_unreal_hook_handle_check(state); + lua_overdub_hook_t *hook = lua_overdub_unreal_hook_from_handle(handle); + if (!hook) { + lua_pushboolean(state, false); + return 1; + } + + lua_overdub_unreal_hook_deactivate(state, hook); + lua_pushboolean(state, true); + return 1; +} + +static int +lua_overdub_unreal_hook_handle_is_active_lua(lua_State *state) +{ + lua_overdub_hook_handle_t *handle = lua_overdub_unreal_hook_handle_check(state); + lua_pushboolean(state, lua_overdub_unreal_hook_from_handle(handle) != NULL); + return 1; +} + +static lua_overdub_delegate_binding_t * +lua_overdub_unreal_delegate_from_handle(lua_overdub_delegate_handle_t *handle) +{ + if (!handle || !handle->context || handle->slot < 0 || handle->slot >= CONFIG_LUA_OVERDUB_MAX_DELEGATE_BINDINGS) { + return NULL; + } + + lua_overdub_delegate_binding_t *binding = &handle->context->delegate_bindings[handle->slot]; + if (!binding->active || binding->id != handle->id) { + return NULL; + } + return binding; +} + +static lua_overdub_delegate_handle_t * +lua_overdub_unreal_delegate_handle_check(lua_State *state) +{ + lua_overdub_delegate_handle_t *handle = luaL_checkudata(state, 1, LUA_OVERDUB_DELEGATE_HANDLE_META); + lua_overdub_unreal_context_t *context = lua_overdub_unreal_context_check(state); + if (!handle->context || handle->context != context || handle->id == 0) { + luaL_error(state, "Unreal delegate handle is invalid"); + } + return handle; +} + +static bool +lua_overdub_unreal_delegate_is_installed(lua_overdub_delegate_binding_t *binding) +{ + if (!binding || !binding->active || !unreal_fweak_object_resolve(binding->delegate.object)) { + return false; + } + + uobject_t *source = unreal_fweak_object_resolve(binding->source); + return source && unreal_fprop_delegate_contains(source, binding->property, &binding->delegate); +} + +static bool +lua_overdub_unreal_delegate_deactivate(lua_overdub_delegate_binding_t *binding) +{ + bool removed = false; + if (binding && binding->active) { + uobject_t *source = unreal_fweak_object_resolve(binding->source); + if (source) { + removed = unreal_fprop_delegate_unbind(source, binding->property, &binding->delegate); + } + + binding->active = false; + } + return removed; +} + +static int +lua_overdub_unreal_delegate_handle_remove_lua(lua_State *state) +{ + lua_overdub_delegate_handle_t *handle = lua_overdub_unreal_delegate_handle_check(state); + lua_overdub_delegate_binding_t *binding = lua_overdub_unreal_delegate_from_handle(handle); + lua_pushboolean(state, lua_overdub_unreal_delegate_deactivate(binding)); + return 1; +} + +static int +lua_overdub_unreal_delegate_handle_is_active_lua(lua_State *state) +{ + lua_overdub_delegate_handle_t *handle = lua_overdub_unreal_delegate_handle_check(state); + lua_overdub_delegate_binding_t *binding = lua_overdub_unreal_delegate_from_handle(handle); + bool active = lua_overdub_unreal_delegate_is_installed(binding); + if (binding && !active) { + lua_overdub_unreal_delegate_deactivate(binding); + } + + lua_pushboolean(state, active); + return 1; +} + +static ufunc_t * +lua_overdub_unreal_delegate_function_arg(lua_State *state, uobject_t *target, int idx) +{ + ufunc_t *function = NULL; + if (lua_type(state, idx) == LUA_TSTRING) { + size_t name_len = 0; + const char *name_data = lua_tolstring(state, idx, &name_len); + if (name_len == 0 || memchr(name_data, 0, name_len)) { + luaL_argerror(state, idx, "function name cannot be empty or contain null bytes"); + } + + function = unreal_ustruct_find_func((ustruct_t *)target->cls, str_make((void *)name_data, (uint64_t)name_len)); + if (!function) { + luaL_argerror(state, idx, "function was not found on the target object"); + } + } else { + function = lua_overdub_unreal_function_check(state, idx); + } + return function; +} + +static int +lua_overdub_unreal_bind_delegate_lua(lua_State *state) +{ + lua_overdub_unreal_context_t *context = lua_overdub_unreal_context_check(state); + uobject_t *source = lua_overdub_unreal_object_check(state, 1); + uobject_t *target = lua_overdub_unreal_object_check(state, 3); + + size_t property_len = 0; + const char *property_data = luaL_checklstring(state, 2, &property_len); + if (property_len == 0 || memchr(property_data, 0, property_len)) { + return luaL_argerror(state, 2, "delegate property name cannot be empty or contain null bytes"); + } + + str_t property_name = str_make((void *)property_data, (uint64_t)property_len); + fprop_t *property = unreal_ustruct_find_prop((ustruct_t *)source->cls, property_name); + ufunc_t *signature = unreal_fprop_delegate_signature(property); + if (!property || !signature) { + return luaL_argerror(state, 2, "expected a single-cast, inline multicast, or sparse multicast delegate property"); + } + + ufunc_t *function = lua_overdub_unreal_delegate_function_arg(state, target, 4); + if (function->func_flags & FUNC_FLAG_STATIC) { + return luaL_argerror(state, 4, "a delegate cannot be bound to a static function"); + } + + if (!unreal_ufunction_signature_compatible(signature, function)) { + return luaL_argerror(state, 4, "function signature is incompatible with the delegate property"); + } + + int slot = -1; + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_DELEGATE_BINDINGS && slot < 0; ++i) { + if (context->delegate_bindings[i].active && !lua_overdub_unreal_delegate_is_installed(&context->delegate_bindings[i])) { + lua_overdub_unreal_delegate_deactivate(&context->delegate_bindings[i]); + } + + if (!context->delegate_bindings[i].active) { + slot = i; + } + } + + if (slot < 0) { + return luaL_error(state, "Overdub Unreal delegate-binding limit reached"); + } + + fweak_object_ptr_t source_weak = lua_overdub_unreal_invalid_weak(); + fscript_delegate_t delegate = {0}; + bool ready = unreal_fweak_object_from_object(source, &source_weak) && unreal_fscript_delegate_make(&delegate, target, function); + if (!ready || !unreal_fprop_delegate_bind(source, property, &delegate)) { + return luaL_error(state, "delegate property is already bound or rejected the binding"); + } + + uint64_t id = lua_overdub_unreal_next_id(&context->next_delegate_id); + context->delegate_bindings[slot] = (lua_overdub_delegate_binding_t){ + .source = source_weak, + .delegate = delegate, + .property = property, + .id = id, + .active = true, + }; + + lua_overdub_delegate_handle_t *handle = lua_newuserdatauv(state, sizeof(*handle), 0); + *handle = (lua_overdub_delegate_handle_t){ + .context = context, + .id = id, + .slot = slot, + }; + luaL_setmetatable(state, LUA_OVERDUB_DELEGATE_HANDLE_META); + return 1; +} + +static bool +lua_overdub_unreal_call_is_live(lua_overdub_call_t *call) +{ + return call && call->valid && call->context && call->function_raw && + unreal_fweak_object_resolve(call->function) == (uobject_t *)call->function_raw && + unreal_fweak_object_resolve(call->object) != NULL; +} + +static lua_overdub_call_t * +lua_overdub_unreal_call_check(lua_State *state) +{ + lua_overdub_call_t *call = luaL_checkudata(state, 1, LUA_OVERDUB_CALL_META); + lua_overdub_unreal_context_t *context = lua_overdub_unreal_context_check(state); + if (!call->context || call->context != context || !lua_overdub_unreal_call_is_live(call)) { + luaL_error(state, "UnrealCall is no longer valid"); + } + return call; +} + +static fprop_t * +lua_overdub_unreal_call_find_parameter(lua_State *state, lua_overdub_call_t *call, int name_idx) +{ + size_t name_len = 0; + const char *name_data = luaL_checklstring(state, name_idx, &name_len); + if (name_len == 0 || memchr(name_data, 0, name_len)) { + luaL_argerror(state, name_idx, "parameter name cannot be empty or contain null bytes"); + } + + str_t name = str_make((void *)name_data, (uint64_t)name_len); + for (ffield_t *field = call->function_raw->child_props; field; field = field->next) { + fprop_t *prop = (fprop_t *)field; + if ((prop->prop_flags & CPF_PARM) && unreal_fname_match_text(prop->name, name, false, true)) { + uint64_t size = unreal_fprop_complete_size(prop); + bool fits = call->params && prop->offset_internal >= 0 && size > 0 && + (uint64_t)prop->offset_internal <= call->function_raw->params_size && + size <= (uint64_t)call->function_raw->params_size - (uint64_t)prop->offset_internal; + if (!fits) { + luaL_error(state, "parameter '%.*s' has an invalid reflected layout", (int)name.len, name.data); + } + return prop; + } + } + + luaL_error(state, "UFunction has no parameter named '%.*s'", (int)name.len, name.data); + return NULL; +} + +static fprop_t * +lua_overdub_unreal_call_find_return(lua_State *state, lua_overdub_call_t *call) +{ + for (ffield_t *field = call->function_raw->child_props; field; field = field->next) { + fprop_t *prop = (fprop_t *)field; + if (prop->prop_flags & CPF_RETURN_PARM) { + uint64_t size = unreal_fprop_complete_size(prop); + bool fits = call->params && prop->offset_internal >= 0 && size > 0 && + (uint64_t)prop->offset_internal <= call->function_raw->params_size && + size <= (uint64_t)call->function_raw->params_size - (uint64_t)prop->offset_internal; + if (!fits) { + luaL_error(state, "the UFunction return property has an invalid reflected layout"); + } + return prop; + } + } + + luaL_error(state, "the UFunction has no return value"); + return NULL; +} + +static int +lua_overdub_unreal_call_is_valid_lua(lua_State *state) +{ + lua_overdub_call_t *call = luaL_checkudata(state, 1, LUA_OVERDUB_CALL_META); + lua_overdub_unreal_context_check(state); + lua_pushboolean(state, lua_overdub_unreal_call_is_live(call)); + return 1; +} + +static int +lua_overdub_unreal_call_get_object_lua(lua_State *state) +{ + lua_overdub_call_t *call = lua_overdub_unreal_call_check(state); + return lua_unreal_object_push(state, unreal_fweak_object_resolve(call->object)); +} + +static int +lua_overdub_unreal_call_get_function_lua(lua_State *state) +{ + lua_overdub_call_t *call = lua_overdub_unreal_call_check(state); + return lua_unreal_object_push(state, unreal_fweak_object_resolve(call->function)); +} + +static int +lua_overdub_unreal_call_get_phase_lua(lua_State *state) +{ + lua_pushstring(state, lua_overdub_unreal_call_check(state)->before ? "Before" : "After"); + return 1; +} + +static int +lua_overdub_unreal_call_is_deferred_lua(lua_State *state) +{ + lua_pushboolean(state, lua_overdub_unreal_call_check(state)->deferred); + return 1; +} + +static int +lua_overdub_unreal_call_is_skipped_lua(lua_State *state) +{ + lua_overdub_call_t *call = lua_overdub_unreal_call_check(state); + lua_pushboolean(state, call->consumed || call->skip_requested); + return 1; +} + +static int +lua_overdub_unreal_call_get_lua(lua_State *state) +{ + lua_overdub_call_t *call = lua_overdub_unreal_call_check(state); + fprop_t *prop = lua_overdub_unreal_call_find_parameter(state, call, 2); + void *value = unreal_fprop_value_in_container(prop, call->params, 0); + uobject_t *owner = unreal_fweak_object_resolve(call->object); + if (!value || !lua_unreal_prop_push(state, prop, value, owner)) { + return luaL_error(state, "parameter has an unsupported reflected type"); + } + return 1; +} + +static int +lua_overdub_unreal_call_set_lua(lua_State *state) +{ + lua_overdub_call_t *call = lua_overdub_unreal_call_check(state); + if (call->deferred) { + return luaL_error(state, "a deferred nested UnrealCall is read-only"); + } + + fprop_t *prop = lua_overdub_unreal_call_find_parameter(state, call, 2); + void *value = unreal_fprop_value_in_container(prop, call->params, 0); + uobject_t *owner = unreal_fweak_object_resolve(call->object); + if (!value || !lua_unreal_prop_write(state, 3, prop, value, owner)) { + return luaL_error(state, "could not marshal the parameter value"); + } + return 0; +} + +static int +lua_overdub_unreal_call_get_return_lua(lua_State *state) +{ + lua_overdub_call_t *call = lua_overdub_unreal_call_check(state); + fprop_t *prop = lua_overdub_unreal_call_find_return(state, call); + void *value = unreal_fprop_value_in_container(prop, call->params, 0); + uobject_t *owner = unreal_fweak_object_resolve(call->object); + if (!value || !lua_unreal_prop_push(state, prop, value, owner)) { + return luaL_error(state, "return value has an unsupported reflected type"); + } + return 1; +} + +static int +lua_overdub_unreal_call_set_return_lua(lua_State *state) +{ + lua_overdub_call_t *call = lua_overdub_unreal_call_check(state); + if (call->deferred) { + return luaL_error(state, "a deferred nested UnrealCall is read-only"); + } + + fprop_t *prop = lua_overdub_unreal_call_find_return(state, call); + void *value = unreal_fprop_value_in_container(prop, call->params, 0); + uobject_t *owner = unreal_fweak_object_resolve(call->object); + if (!value || !lua_unreal_prop_write(state, 2, prop, value, owner)) { + return luaL_error(state, "could not marshal the return value"); + } + return 0; +} + +static int +lua_overdub_unreal_call_skip_lua(lua_State *state) +{ + lua_overdub_call_t *call = lua_overdub_unreal_call_check(state); + if (!call->before) { + return luaL_error(state, "Skip is only valid in a Before hook"); + } + + if (call->deferred) { + return luaL_error(state, "a deferred nested UnrealCall cannot skip an invocation that has already run"); + } + + bool changed = !call->skip_requested; + call->skip_requested = true; + lua_pushboolean(state, changed); + return 1; +} + +static lua_overdub_root_claim_t * +lua_overdub_unreal_mod_claim_find(lua_overdub_unreal_context_t *context, fweak_object_ptr_t weak) +{ + for (lua_overdub_root_claim_t *claim = context ? context->root_claims : NULL; claim; claim = claim->next) { + if (lua_overdub_weak_equal(claim->object, weak)) { + return claim; + } + } + return NULL; +} + +static lua_overdub_global_root_t * +lua_overdub_unreal_global_root_find(fweak_object_ptr_t weak) +{ + for (lua_overdub_global_root_t *root = g_lua_overdub_global_roots; root; root = root->next) { + if (lua_overdub_weak_equal(root->object, weak)) { + return root; + } + } + return NULL; +} + +static lua_overdub_root_claim_t * +lua_overdub_unreal_mod_claim_alloc(lua_overdub_unreal_context_t *context) +{ + lua_overdub_root_claim_t *claim = context->root_claim_free; + if (claim) { + context->root_claim_free = claim->next; + *claim = (lua_overdub_root_claim_t){0}; + } else { + claim = ARENA_PUSH_ZERO(context->arena, lua_overdub_root_claim_t); + } + + return claim; +} + +static void +lua_overdub_unreal_mod_claim_free(lua_overdub_unreal_context_t *context, lua_overdub_root_claim_t *claim) +{ + if (context && claim) { + *claim = (lua_overdub_root_claim_t){0}; + claim->next = context->root_claim_free; + context->root_claim_free = claim; + } +} + +static lua_overdub_global_root_t * +lua_overdub_unreal_global_root_alloc(void) +{ + lua_overdub_global_root_t *root = g_lua_overdub_global_root_free; + if (root) { + g_lua_overdub_global_root_free = root->next; + *root = (lua_overdub_global_root_t){0}; + } else { + root = ARENA_PUSH_ZERO(&globals.perm, lua_overdub_global_root_t); + } + + return root; +} + +static void +lua_overdub_unreal_global_root_free(lua_overdub_global_root_t *root) +{ + if (root) { + *root = (lua_overdub_global_root_t){0}; + root->next = g_lua_overdub_global_root_free; + g_lua_overdub_global_root_free = root; + } +} + +static bool +lua_overdub_unreal_claim_root(lua_overdub_unreal_context_t *context, uobject_t *object) +{ + fweak_object_ptr_t weak = {0}; + if (!context || !unreal_fweak_object_from_object(object, &weak)) { + return false; + } + + if (lua_overdub_unreal_mod_claim_find(context, weak)) { + return false; + } + + lua_overdub_root_claim_t *claim = lua_overdub_unreal_mod_claim_alloc(context); + if (!claim) { + return false; + } + + lua_overdub_global_root_t *root = lua_overdub_unreal_global_root_find(weak); + if (!root) { + root = lua_overdub_unreal_global_root_alloc(); + if (!root) { + lua_overdub_unreal_mod_claim_free(context, claim); + return false; + } + + root->object = weak; + root->externally_rooted = unreal_uobject_is_rooted(object); + root->next = g_lua_overdub_global_roots; + g_lua_overdub_global_roots = root; + if (!root->externally_rooted && !unreal_uobject_add_to_root(object)) { + g_lua_overdub_global_roots = root->next; + lua_overdub_unreal_global_root_free(root); + lua_overdub_unreal_mod_claim_free(context, claim); + return false; + } + } + + root->claim_count += 1; + claim->object = weak; + claim->next = context->root_claims; + context->root_claims = claim; + return true; +} + +static void +lua_overdub_unreal_global_root_release(fweak_object_ptr_t weak) +{ + lua_overdub_global_root_t **at = &g_lua_overdub_global_roots; + while (*at && !lua_overdub_weak_equal((*at)->object, weak)) { + at = &(*at)->next; + } + + lua_overdub_global_root_t *root = *at; + if (!root) { + return; + } + + if (root->claim_count > 0) { + root->claim_count -= 1; + } + + if (root->claim_count != 0) { + return; + } + + uobject_t *object = unreal_fweak_object_resolve(root->object); + if (object && !root->externally_rooted) { + unreal_uobject_remove_from_root(object); + } + + *at = root->next; + lua_overdub_unreal_global_root_free(root); +} + +static bool +lua_overdub_unreal_release_root(lua_overdub_unreal_context_t *context, uobject_t *object) +{ + fweak_object_ptr_t weak = {0}; + if (!context || !unreal_fweak_object_from_object(object, &weak)) { + return false; + } + + lua_overdub_root_claim_t **at = &context->root_claims; + while (*at && !lua_overdub_weak_equal((*at)->object, weak)) { + at = &(*at)->next; + } + + lua_overdub_root_claim_t *claim = *at; + if (!claim) { + return false; + } + + *at = claim->next; + lua_overdub_unreal_global_root_release(claim->object); + lua_overdub_unreal_mod_claim_free(context, claim); + return true; +} + +static int +lua_overdub_unreal_find_object_lua(lua_State *state) +{ + lua_overdub_unreal_context_check(state); + size_t path_len = 0; + const char *path_data = luaL_checklstring(state, 1, &path_len); + if (path_len == 0 || memchr(path_data, 0, path_len)) { + return luaL_argerror(state, 1, "object path cannot be empty or contain null bytes"); + } + + uclass_t *cls = NULL; + if (!lua_isnoneornil(state, 2)) { + cls = lua_overdub_unreal_class_check(state, 2); + } + + uobject_t *object = unreal_uobject_find_by_path_name(cls, str_make((void *)path_data, (uint64_t)path_len)); + return lua_unreal_object_push(state, object); +} + +static int +lua_overdub_unreal_get_object_count_lua(lua_State *state) +{ + lua_overdub_unreal_context_check(state); + lua_pushinteger(state, unreal_uobject_array_count()); + return 1; +} + +static int +lua_overdub_unreal_get_object_by_index_lua(lua_State *state) +{ + lua_overdub_unreal_context_check(state); + lua_Integer idx = luaL_checkinteger(state, 1); + if (idx < 0 || idx > INT_MAX) { + return luaL_argerror(state, 1, "object index is out of range"); + } + + return lua_unreal_object_push(state, unreal_uobject_array_get_obj((int)idx)); +} + +static int +lua_overdub_unreal_object_iterator_lua(lua_State *state) +{ + lua_overdub_unreal_context_check(state); + lua_Integer idx = lua_tointeger(state, lua_upvalueindex(1)); + lua_Integer count = lua_tointeger(state, lua_upvalueindex(2)); + if (idx >= count) { + return 0; + } + + lua_pushinteger(state, idx + 1); + lua_replace(state, lua_upvalueindex(1)); + lua_pushinteger(state, idx); + lua_unreal_object_push(state, unreal_uobject_array_get_obj((int)idx)); + return 2; +} + +static int +lua_overdub_unreal_objects_lua(lua_State *state) +{ + lua_overdub_unreal_context_check(state); + lua_pushinteger(state, 0); + lua_pushinteger(state, unreal_uobject_array_count()); + lua_pushcclosure(state, lua_overdub_unreal_object_iterator_lua, 2); + return 1; +} + +static int +lua_overdub_unreal_load_object_lua(lua_State *state) +{ + lua_overdub_unreal_context_check(state); + size_t path_len = 0; + const char *path_data = luaL_checklstring(state, 1, &path_len); + if (path_len == 0 || memchr(path_data, 0, path_len)) { + return luaL_argerror(state, 1, "object path cannot be empty or contain null bytes"); + } + + uclass_t *cls = globals.unreal.core_object; + if (!lua_isnoneornil(state, 2)) { + cls = lua_overdub_unreal_class_check(state, 2); + } + + uobject_t *outer = NULL; + if (!lua_isnoneornil(state, 3)) { + outer = lua_overdub_unreal_object_check(state, 3); + } + + if (!cls) { + return luaL_error(state, "the UObject class is unavailable"); + } + + str_t path = str_make((void *)path_data, (uint64_t)path_len); + return lua_unreal_object_push(state, unreal_static_load_object(cls, outer, path, STR_NULL, 0, NULL, true, NULL)); +} + +static int +lua_overdub_unreal_get_current_world_lua(lua_State *state) +{ + lua_overdub_unreal_context_check(state); + return lua_unreal_object_push(state, (uobject_t *)unreal_get_current_world()); +} + +static int +lua_overdub_unreal_get_transient_package_lua(lua_State *state) +{ + lua_overdub_unreal_context_check(state); + return lua_unreal_object_push(state, globals.unreal.transient_package); +} + +static int +lua_overdub_unreal_construct_object_lua(lua_State *state) +{ + lua_overdub_unreal_context_check(state); + uclass_t *cls = lua_overdub_unreal_class_check(state, 1); + uobject_t *outer = globals.unreal.transient_package; + if (!lua_isnoneornil(state, 2)) { + outer = lua_overdub_unreal_object_check(state, 2); + } + + if (!outer) { + return luaL_error(state, "the transient package is unavailable; provide an Outer explicitly"); + } + + if (globals.unreal.actor && unreal_uclass_is_child_of(cls, globals.unreal.actor)) { + return luaL_argerror(state, 1, "actor classes must be created with SpawnActor"); + } + + if (cls->class_flags & CLASS_ABSTRACT) { + return luaL_argerror(state, 1, "cannot construct an instance of an abstract UClass"); + } + + if (cls->class_within && !unreal_uobject_is_a(outer, cls->class_within)) { + return luaL_argerror(state, 2, "Outer does not satisfy the UClass ClassWithin requirement"); + } + + fname_t name = {0}; + if (!lua_isnoneornil(state, 3)) { + size_t name_len = 0; + const char *name_data = luaL_checklstring(state, 3, &name_len); + if (memchr(name_data, 0, name_len)) { + return luaL_argerror(state, 3, "object name cannot contain null bytes"); + } + + if (name_len > 0) { + name = unreal_fname_from_str(str_make((void *)name_data, (uint64_t)name_len), FNAME_FIND_OR_ADD); + } + } + + eobj_flags_t flags = RF_NO_FLAGS; + if (!lua_isnoneornil(state, 4)) { + flags = (eobj_flags_t)lua_overdub_unreal_u32_check(state, 4, "object flags must fit in an unsigned 32-bit integer"); + } + + const eobj_flags_t engine_managed_flags = RF_CLASS_DEFAULT_OBJECT | RF_NEED_INITIALIZATION | RF_NEED_LOAD | + RF_NEED_POST_LOAD | RF_NEED_POST_LOAD_SUBOBJECTS | + RF_BEGIN_DESTROYED | RF_FINISH_DESTROYED; + if (flags & engine_managed_flags) { + return luaL_argerror(state, 4, "object flags contain engine-managed construction, loading, or destruction state"); + } + + uobject_t *tmpl = NULL; + if (!lua_isnoneornil(state, 5)) { + tmpl = lua_overdub_unreal_object_check(state, 5); + if (!unreal_uobject_is_a(tmpl, cls)) { + return luaL_argerror(state, 5, "Template must be an instance of the constructed UClass"); + } + } + + fstatic_construct_obj_params_t params = { + .cls = cls, + .outer = outer, + .name = name, + .set_flags = flags, + .copy_transients_from_class_defaults = lua_toboolean(state, 6) != 0, + .tmpl = tmpl, + }; + return lua_unreal_object_push(state, unreal_static_construct_object(¶ms)); +} + +static int +lua_overdub_unreal_spawn_actor_lua(lua_State *state) +{ + lua_overdub_unreal_context_check(state); + uclass_t *cls = lua_overdub_unreal_class_check(state, 1); + if (!globals.unreal.actor || !unreal_uclass_is_child_of(cls, globals.unreal.actor)) { + return luaL_argerror(state, 1, "expected an AActor-derived UClass"); + } + + if (cls->class_flags & CLASS_ABSTRACT) { + return luaL_argerror(state, 1, "cannot spawn an instance of an abstract UClass"); + } + + uobject_t *world_context = (uobject_t *)unreal_get_current_world(); + if (!lua_isnoneornil(state, 2)) { + world_context = lua_overdub_unreal_object_check(state, 2); + } + + if (!world_context) { + return luaL_error(state, "the current world is unavailable; provide a WorldContextObject explicitly"); + } + + return lua_unreal_object_push(state, unreal_spawn_actor(world_context, cls)); +} + +static bool +lua_overdub_unreal_prop_kind_from_name(str_t name, unreal_prop_kind_t *out) +{ + static const struct { + const char *name; + unreal_prop_kind_t kind; + } names[] = { + {"Bool", UNREAL_PROP_KIND_BOOL }, + {"BoolProperty", UNREAL_PROP_KIND_BOOL }, + {"Byte", UNREAL_PROP_KIND_BYTE }, + {"ByteProperty", UNREAL_PROP_KIND_BYTE }, + {"Int8", UNREAL_PROP_KIND_INT8 }, + {"Int8Property", UNREAL_PROP_KIND_INT8 }, + {"Int16", UNREAL_PROP_KIND_INT16 }, + {"Int16Property", UNREAL_PROP_KIND_INT16 }, + {"Int", UNREAL_PROP_KIND_INT32 }, + {"Int32", UNREAL_PROP_KIND_INT32 }, + {"IntProperty", UNREAL_PROP_KIND_INT32 }, + {"Int32Property", UNREAL_PROP_KIND_INT32 }, + {"Int64", UNREAL_PROP_KIND_INT64 }, + {"Int64Property", UNREAL_PROP_KIND_INT64 }, + {"UInt16", UNREAL_PROP_KIND_UINT16 }, + {"UInt16Property", UNREAL_PROP_KIND_UINT16 }, + {"UInt", UNREAL_PROP_KIND_UINT32 }, + {"UInt32", UNREAL_PROP_KIND_UINT32 }, + {"UIntProperty", UNREAL_PROP_KIND_UINT32 }, + {"UInt32Property", UNREAL_PROP_KIND_UINT32 }, + {"UInt64", UNREAL_PROP_KIND_UINT64 }, + {"UInt64Property", UNREAL_PROP_KIND_UINT64 }, + {"Float", UNREAL_PROP_KIND_FLOAT }, + {"FloatProperty", UNREAL_PROP_KIND_FLOAT }, + {"Double", UNREAL_PROP_KIND_DOUBLE }, + {"DoubleProperty", UNREAL_PROP_KIND_DOUBLE }, + {"Name", UNREAL_PROP_KIND_NAME }, + {"NameProperty", UNREAL_PROP_KIND_NAME }, + {"String", UNREAL_PROP_KIND_STRING }, + {"StrProperty", UNREAL_PROP_KIND_STRING }, + {"Text", UNREAL_PROP_KIND_TEXT }, + {"TextProperty", UNREAL_PROP_KIND_TEXT }, + {"Object", UNREAL_PROP_KIND_OBJECT }, + {"ObjectProperty", UNREAL_PROP_KIND_OBJECT }, + {"ObjectPtrProperty", UNREAL_PROP_KIND_OBJECT }, + {"Class", UNREAL_PROP_KIND_CLASS }, + {"ClassProperty", UNREAL_PROP_KIND_CLASS }, + {"SoftObject", UNREAL_PROP_KIND_SOFT_OBJECT}, + {"SoftObjectProperty", UNREAL_PROP_KIND_SOFT_OBJECT}, + {"SoftClass", UNREAL_PROP_KIND_SOFT_CLASS }, + {"SoftClassProperty", UNREAL_PROP_KIND_SOFT_CLASS }, + {"WeakObject", UNREAL_PROP_KIND_WEAK_OBJECT}, + {"WeakObjectProperty", UNREAL_PROP_KIND_WEAK_OBJECT}, + {"LazyObject", UNREAL_PROP_KIND_LAZY_OBJECT}, + {"LazyObjectProperty", UNREAL_PROP_KIND_LAZY_OBJECT}, + {"Interface", UNREAL_PROP_KIND_INTERFACE }, + {"InterfaceProperty", UNREAL_PROP_KIND_INTERFACE }, + {"Struct", UNREAL_PROP_KIND_STRUCT }, + {"StructProperty", UNREAL_PROP_KIND_STRUCT }, + {"Array", UNREAL_PROP_KIND_ARRAY }, + {"ArrayProperty", UNREAL_PROP_KIND_ARRAY }, + {"Set", UNREAL_PROP_KIND_SET }, + {"SetProperty", UNREAL_PROP_KIND_SET }, + {"Map", UNREAL_PROP_KIND_MAP }, + {"MapProperty", UNREAL_PROP_KIND_MAP }, + {"Enum", UNREAL_PROP_KIND_ENUM }, + {"EnumProperty", UNREAL_PROP_KIND_ENUM }, + }; + + bool found = false; + for (size_t i = 0; i < COUNTOF(names) && !found; ++i) { + str_t candidate = str_from_cstr(names[i].name); + if (str_equal(name, candidate, 0)) { + *out = names[i].kind; + found = true; + } + } + return found; +} + +static bool +lua_overdub_unreal_prop_kind_uses_class(unreal_prop_kind_t kind) +{ + switch (kind) { + case UNREAL_PROP_KIND_OBJECT: + case UNREAL_PROP_KIND_CLASS: + case UNREAL_PROP_KIND_SOFT_OBJECT: + case UNREAL_PROP_KIND_SOFT_CLASS: + case UNREAL_PROP_KIND_WEAK_OBJECT: + case UNREAL_PROP_KIND_LAZY_OBJECT: + case UNREAL_PROP_KIND_INTERFACE: return true; + default: return false; + } +} + +static str_t +lua_overdub_unreal_required_string_field(lua_State *state, int table_idx, const char *field) +{ + table_idx = lua_absindex(state, table_idx); + lua_getfield(state, table_idx, field); + + size_t len = 0; + const char *data = lua_tolstring(state, -1, &len); + if (!data || len == 0 || memchr(data, 0, len)) { + luaL_error(state, "%s must be a non-empty string without null bytes", field); + } + + str_t result = str_make((void *)data, (uint64_t)len); + lua_pop(state, 1); + return result; +} + +static uint64_t +lua_overdub_unreal_optional_flags(lua_State *state, int table_idx) +{ + table_idx = lua_absindex(state, table_idx); + lua_getfield(state, table_idx, "Flags"); + + uint64_t flags = 0; + if (!lua_isnil(state, -1)) { + if (!lua_isinteger(state, -1)) { + luaL_error(state, "Flags must be an integer"); + } + flags = (uint64_t)(lua_Unsigned)lua_tointeger(state, -1); + } + + lua_pop(state, 1); + return flags; +} + +static unreal_prop_type_t +lua_overdub_unreal_prop_type_parse(lua_State *state, lua_overdub_unreal_context_t *context, int idx, int depth) +{ + if (depth >= 16) { + luaL_error(state, "property type nesting is too deep"); + } + + idx = lua_absindex(state, idx); + int table_idx = 0; + const char *type_data = NULL; + size_t type_len = 0; + if (lua_type(state, idx) == LUA_TSTRING) { + type_data = lua_tolstring(state, idx, &type_len); + } else if (lua_istable(state, idx)) { + table_idx = idx; + lua_getfield(state, table_idx, "Type"); + type_data = lua_tolstring(state, -1, &type_len); + lua_pop(state, 1); + } else { + luaL_error(state, "a property type must be a string or table"); + } + + unreal_prop_type_t type = {0}; + str_t name = str_make((void *)type_data, (uint64_t)type_len); + if (!type_data || type_len == 0 || memchr(type_data, 0, type_len) || !lua_overdub_unreal_prop_kind_from_name(name, &type.type)) { + luaL_error(state, "unknown or missing reflected property Type"); + } + + if (lua_overdub_unreal_prop_kind_uses_class(type.type)) { + type.cls = globals.unreal.core_object; + if (table_idx) { + lua_getfield(state, table_idx, "Class"); + if (!lua_isnil(state, -1)) { + type.cls = lua_overdub_unreal_class_check(state, -1); + } + lua_pop(state, 1); + } + + if (type.type == UNREAL_PROP_KIND_INTERFACE && (!type.cls || !(type.cls->class_flags & CLASS_INTERFACE))) { + luaL_error(state, "an Interface property requires an interface UClass in Class"); + } + } + + if (type.type == UNREAL_PROP_KIND_STRUCT) { + if (!table_idx) { + luaL_error(state, "a Struct property requires a type table with Struct"); + } + + lua_getfield(state, table_idx, "Struct"); + uobject_t *object = lua_overdub_unreal_object_check(state, -1); + if (!globals.unreal.core_scriptstruct || !unreal_uobject_is_a(object, globals.unreal.core_scriptstruct)) { + luaL_error(state, "Struct must be a live UScriptStruct"); + } + type.struct_type = (uscript_struct_t *)object; + lua_pop(state, 1); + } + + if (type.type == UNREAL_PROP_KIND_ENUM) { + if (!table_idx) { + luaL_error(state, "an Enum property requires a type table with Enum"); + } + + lua_getfield(state, table_idx, "Enum"); + type.enum_type = lua_overdub_unreal_enum_check(state, -1); + lua_pop(state, 1); + + unreal_prop_type_t *underlying = ARENA_PUSH_ZERO(context->arena, unreal_prop_type_t); + if (!underlying) { + luaL_error(state, "could not allocate the enum underlying type"); + } + + lua_getfield(state, table_idx, "Underlying"); + if (lua_isnil(state, -1)) { + underlying->type = UNREAL_PROP_KIND_BYTE; + } else { + *underlying = lua_overdub_unreal_prop_type_parse(state, context, -1, depth + 1); + } + lua_pop(state, 1); + type.inner = underlying; + } + + bool has_inner = type.type == UNREAL_PROP_KIND_ARRAY || type.type == UNREAL_PROP_KIND_SET; + if (has_inner) { + if (!table_idx) { + luaL_error(state, "an Array or Set property requires a type table with Inner"); + } + + unreal_prop_type_t *inner = ARENA_PUSH_ZERO(context->arena, unreal_prop_type_t); + if (!inner) { + luaL_error(state, "could not allocate the container element type"); + } + + lua_getfield(state, table_idx, "Inner"); + *inner = lua_overdub_unreal_prop_type_parse(state, context, -1, depth + 1); + lua_pop(state, 1); + type.inner = inner; + } + + if (type.type == UNREAL_PROP_KIND_MAP) { + if (!table_idx) { + luaL_error(state, "a Map property requires a type table with Key and Value"); + } + + unreal_prop_type_t *key = ARENA_PUSH_ZERO(context->arena, unreal_prop_type_t); + unreal_prop_type_t *val = ARENA_PUSH_ZERO(context->arena, unreal_prop_type_t); + if (!key || !val) { + luaL_error(state, "could not allocate the map key/value types"); + } + + lua_getfield(state, table_idx, "Key"); + *key = lua_overdub_unreal_prop_type_parse(state, context, -1, depth + 1); + lua_pop(state, 1); + + lua_getfield(state, table_idx, "Value"); + *val = lua_overdub_unreal_prop_type_parse(state, context, -1, depth + 1); + lua_pop(state, 1); + + type.inner = key; + type.value = val; + } + return type; +} + +static void +lua_overdub_unreal_prop_def_parse(lua_State *state, lua_overdub_unreal_context_t *context, int idx, unreal_prop_def_t *def, bool parameter) +{ + idx = lua_absindex(state, idx); + if (!lua_istable(state, idx)) { + luaL_error(state, "each reflected property or parameter declaration must be a table"); + } + + unreal_prop_type_t type = lua_overdub_unreal_prop_type_parse(state, context, idx, 0); + def->name = lua_overdub_unreal_required_string_field(state, idx, "Name"); + def->type = type.type; + def->flags = (eprop_flags_t)lua_overdub_unreal_optional_flags(state, idx); + def->cls = type.cls; + def->struct_type = type.struct_type; + def->enum_type = type.enum_type; + if (type.inner) { + def->inner = *type.inner; + } + + if (type.value) { + def->value = *type.value; + } + + if (parameter) { + lua_getfield(state, idx, "Const"); + if (lua_toboolean(state, -1)) { + def->flags |= CPF_CONST_PARM; + } + lua_pop(state, 1); + } +} + +static uint32_t +lua_overdub_unreal_list_count(lua_State *state, int idx, const char *name, uint32_t max_count) +{ + lua_Integer count = luaL_len(state, idx); + if (count < 0 || (lua_Unsigned)count > max_count) { + luaL_error(state, "%s has too many entries", name); + } + return (uint32_t)count; +} + +static unreal_prop_def_t * +lua_overdub_unreal_props_parse(lua_State *state, lua_overdub_unreal_context_t *context, int class_idx, uint32_t *out_count) +{ + class_idx = lua_absindex(state, class_idx); + lua_getfield(state, class_idx, "Properties"); + if (lua_isnil(state, -1)) { + lua_pop(state, 1); + *out_count = 0; + return NULL; + } + + if (!lua_istable(state, -1)) { + luaL_error(state, "Properties must be an ordered array"); + } + + int list_idx = lua_gettop(state); + uint32_t count = lua_overdub_unreal_list_count(state, list_idx, "Properties", UINT16_MAX); + unreal_prop_def_t *props = count > 0 ? ARENA_PUSH_ARRAY_ZERO(context->arena, unreal_prop_def_t, count) : NULL; + if (count > 0 && !props) { + luaL_error(state, "could not allocate reflected property declarations"); + } + + for (uint32_t i = 0; i < count; ++i) { + lua_rawgeti(state, list_idx, (lua_Integer)i + 1); + lua_overdub_unreal_prop_def_parse(state, context, -1, &props[i], false); + lua_pop(state, 1); + } + + lua_pop(state, 1); + *out_count = count; + return props; +} + +static unreal_prop_def_t * +lua_overdub_unreal_func_params_parse(lua_State *state, lua_overdub_unreal_context_t *context, int func_idx, uint32_t *out_count) +{ + func_idx = lua_absindex(state, func_idx); + lua_getfield(state, func_idx, "Parameters"); + if (lua_isnil(state, -1)) { + lua_pop(state, 1); + *out_count = 0; + return NULL; + } + + if (!lua_istable(state, -1)) { + luaL_error(state, "Function Parameters must be an ordered array"); + } + + int list_idx = lua_gettop(state); + uint32_t count = lua_overdub_unreal_list_count(state, list_idx, "Function Parameters", UINT8_MAX - 1); + unreal_prop_def_t *params = count > 0 ? ARENA_PUSH_ARRAY_ZERO(context->arena, unreal_prop_def_t, count) : NULL; + if (count > 0 && !params) { + luaL_error(state, "could not allocate reflected function parameters"); + } + + for (uint32_t i = 0; i < count; ++i) { + lua_rawgeti(state, list_idx, (lua_Integer)i + 1); + lua_overdub_unreal_prop_def_parse(state, context, -1, ¶ms[i], true); + lua_pop(state, 1); + } + + lua_pop(state, 1); + *out_count = count; + return params; +} + +static unreal_func_def_t * +lua_overdub_unreal_funcs_parse(lua_State *state, lua_overdub_unreal_context_t *context, int class_idx, + lua_overdub_reflected_func_t **out_records, uint32_t *out_count) +{ + class_idx = lua_absindex(state, class_idx); + lua_getfield(state, class_idx, "Functions"); + if (lua_isnil(state, -1)) { + lua_pop(state, 1); + *out_records = NULL; + *out_count = 0; + return NULL; + } + + if (!lua_istable(state, -1)) { + luaL_error(state, "Functions must be an ordered array"); + } + + int list_idx = lua_gettop(state); + uint32_t count = lua_overdub_unreal_list_count(state, list_idx, "Functions", UINT16_MAX); + + unreal_func_def_t *funcs = count > 0 ? ARENA_PUSH_ARRAY_ZERO(context->arena, unreal_func_def_t, count) : NULL; + lua_overdub_reflected_func_t *records = count > 0 ? ARENA_PUSH_ARRAY_ZERO(context->arena, lua_overdub_reflected_func_t, count) : NULL; + + if (count > 0 && (!funcs || !records)) { + luaL_error(state, "could not allocate reflected function declarations"); + } + + for (uint32_t i = 0; i < count; ++i) { + lua_rawgeti(state, list_idx, (lua_Integer)i + 1); + if (!lua_istable(state, -1)) { + luaL_error(state, "each reflected function declaration must be a table"); + } + + int func_idx = lua_gettop(state); + + funcs[i].name = lua_overdub_unreal_required_string_field(state, func_idx, "Name"); + funcs[i].flags = (efunc_flags_t)lua_overdub_unreal_optional_flags(state, func_idx); + funcs[i].params = lua_overdub_unreal_func_params_parse(state, context, func_idx, &funcs[i].num_params); + funcs[i].impl = lua_overdub_unreal_reflected_func_call; + funcs[i].user = &records[i]; + + records[i].context = context; + records[i].callback_ref = LUA_NOREF; + + lua_getfield(state, func_idx, "Return"); + if (!lua_isnil(state, -1)) { + funcs[i].ret = lua_overdub_unreal_prop_type_parse(state, context, -1, 0); + } + lua_pop(state, 1); + + lua_getfield(state, func_idx, "Implementation"); + if (!lua_isfunction(state, -1)) { + luaL_error(state, "Function Implementation must be a Lua function"); + } + lua_pop(state, 1); + lua_pop(state, 1); + } + + for (uint32_t i = 0; i < count; ++i) { + lua_rawgeti(state, list_idx, (lua_Integer)i + 1); + lua_getfield(state, -1, "Implementation"); + records[i].callback_ref = luaL_ref(state, LUA_REGISTRYINDEX); + lua_pop(state, 1); + } + + lua_pop(state, 1); + *out_records = records; + *out_count = count; + return funcs; +} + +static fprop_t * +lua_overdub_unreal_func_return_prop(ufunc_t *function) +{ + fprop_t *result = NULL; + for (ffield_t *field = function ? function->child_props : NULL; field && !result; field = field->next) { + fprop_t *prop = (fprop_t *)field; + if (unreal_fprop_get_param_role(prop) == UNREAL_FUNC_PARAM_RETURN) { + result = prop; + } + } + return result; +} + +static void +lua_overdub_unreal_reflected_func_disable(lua_overdub_reflected_func_t *func) +{ + lua_overdub_unreal_context_t *context = func ? func->context : NULL; + lua_State *state = context && context->runtime ? context->runtime->state : NULL; + if (state && func->callback_ref != LUA_NOREF && func->callback_ref != LUA_REFNIL) { + luaL_unref(state, LUA_REGISTRYINDEX, func->callback_ref); + } + + if (func) { + func->callback_ref = LUA_NOREF; + func->active = false; + } +} + +static bool +lua_overdub_unreal_reflected_func_can_defer(ufunc_t *function) +{ + if (!function) { + return false; + } + + bool can_defer = true; + for (ffield_t *field = function->child_props; field && can_defer; field = field->next) { + fprop_t *prop = (fprop_t *)field; + if ((prop->prop_flags & CPF_PARM) && unreal_fprop_get_param_role(prop) != UNREAL_FUNC_PARAM_INPUT) { + can_defer = false; + } + } + return can_defer; +} + +static bool +lua_overdub_unreal_reflected_func_ready(lua_overdub_reflected_func_t *func, unreal_func_call_t *call) +{ + if (!func || !call) { + return false; + } + + lua_overdub_unreal_context_t *context = func->context; + if (!context) { + return false; + } + + lua_runtime_t *runtime = context->runtime; + return call && call->object && call->function && func && func->active && runtime && runtime->state && context->in_callback && lua_overdub_unreal_access_check(context); +} + +static void +lua_overdub_unreal_reflected_func_invoke(lua_overdub_reflected_func_t *func, unreal_func_call_t *call) +{ + lua_overdub_unreal_context_t *context = func->context; + lua_runtime_t *runtime = context->runtime; + bool *in_callback = context->in_callback; + lua_State *state = runtime->state; + + int stack_base = lua_gettop(state); + int arg_count = lua_unreal_object_push(state, call->object); + bool converted = arg_count == 1; + for (ffield_t *field = call->function->child_props; field && converted; field = field->next) { + fprop_t *prop = (fprop_t *)field; + if (unreal_fprop_get_param_role(prop) == UNREAL_FUNC_PARAM_INPUT) { + void *value = unreal_fprop_value_in_container(prop, call->params, 0); + converted = value && lua_unreal_prop_push(state, prop, value, call->object) == 1; + arg_count += converted; + } + } + + fprop_t *ret_prop = lua_overdub_unreal_func_return_prop(call->function); + bool called = false; + if (converted) { + *in_callback = true; + called = lua_runtime_call_ref(runtime, func->callback_ref, arg_count, ret_prop ? 1 : 0); + *in_callback = false; + } + + bool returned = called; + if (called && ret_prop) { + returned = call->return_value && lua_unreal_prop_write(state, -1, ret_prop, call->return_value, call->object); + } + + lua_settop(state, stack_base); + if (!converted || !called || !returned) { + lua_overdub_unreal_reflected_func_disable(func); + LOG_ERROR("Overdub Lua mod '%.*s': disabling failed Lua-backed UFunction implementation", STR_ARG(context->mod_id)); + } +} + +static void MOD_CALL +lua_overdub_unreal_reflected_func_call(unreal_func_call_t *call) +{ + lua_overdub_reflected_func_t *func = call ? call->user : NULL; + if (!lua_overdub_unreal_reflected_func_ready(func, call)) { + return; + } + + lua_overdub_unreal_context_t *context = func->context; + if (*context->in_callback) { + if (lua_overdub_unreal_reflected_func_can_defer(call->function)) { + lua_overdub_unreal_queue_reflected_func(func, call); + } else if (!func->reentry_reported) { + LOG_ERROR("Overdub Lua mod '%.*s' cannot defer a recursive Lua-backed UFunction with return or output parameters", STR_ARG(context->mod_id)); + func->reentry_reported = true; + } + return; + } + + lua_overdub_unreal_reflected_func_invoke(func, call); +} + +static lua_overdub_reflected_class_t * +lua_overdub_unreal_reflected_class_find(lua_overdub_unreal_context_t *context, str_t name) +{ + lua_overdub_reflected_class_t *found = NULL; + for (lua_overdub_reflected_class_t *entry = context->reflected_classes; entry && !found; entry = entry->next) { + if (str_equal(entry->name, name, STR_CMP_FLAG_IGNORE_CASE)) { + found = entry; + } + } + return found; +} + +static void +lua_overdub_unreal_exclude_native_time(lua_runtime_t *runtime, uint64_t start_us) +{ + if (runtime && runtime->execution_deadline_us > 0) { + uint64_t elapsed_us = time_now_us() - start_us; + if (runtime->execution_deadline_us <= UINT64_MAX - elapsed_us) { + runtime->execution_deadline_us += elapsed_us; + } else { + runtime->execution_deadline_us = UINT64_MAX; + } + } +} + +static bool +lua_overdub_unreal_apply_lua_defaults(lua_State *state, int class_idx, uclass_t *cls) +{ + bool applied = cls && cls->cdo; + class_idx = lua_absindex(state, class_idx); + lua_getfield(state, class_idx, "Properties"); + if (lua_isnil(state, -1)) { + lua_pop(state, 1); + return applied; + } + + int list_idx = lua_gettop(state); + uint32_t count = (uint32_t)luaL_len(state, list_idx); + for (uint32_t i = 0; i < count && applied; ++i) { + lua_rawgeti(state, list_idx, (lua_Integer)i + 1); + int prop_idx = lua_gettop(state); + str_t name = lua_overdub_unreal_required_string_field(state, prop_idx, "Name"); + + lua_getfield(state, prop_idx, "Default"); + if (!lua_isnil(state, -1)) { + fprop_t *prop = unreal_ustruct_find_prop((ustruct_t *)cls, name); + void *value = prop ? unreal_fprop_value_in_container(prop, cls->cdo, 0) : NULL; + applied = value && lua_unreal_prop_write(state, -1, prop, value, cls->cdo); + } + lua_pop(state, 1); + lua_pop(state, 1); + } + + lua_pop(state, 1); + return applied; +} + +static int +lua_overdub_unreal_define_class_lua(lua_State *state) +{ + lua_overdub_unreal_context_t *context = lua_overdub_unreal_context_check(state); + uint64_t start_us = time_now_us(); + size_t name_len = 0; + const char *name_data = luaL_checklstring(state, 1, &name_len); + if (name_len == 0 || memchr(name_data, 0, name_len)) { + return luaL_argerror(state, 1, "class name cannot be empty or contain null bytes"); + } + + luaL_checktype(state, 2, LUA_TTABLE); + str_t name = str_make((void *)name_data, (uint64_t)name_len); + if (lua_overdub_unreal_reflected_class_find(context, name)) { + return luaL_error(state, "Unreal class '%.*s' was already defined by this Lua runtime", (int)name.len, name.data); + } + + lua_overdub_reflected_class_t *entry = ARENA_PUSH_ZERO(context->arena, lua_overdub_reflected_class_t); + str_t name_copy = str_push_copy(context->arena, name); + if (!entry || !name_copy.data) { + return luaL_error(state, "could not retain Unreal class '%.*s'", (int)name.len, name.data); + } + + lua_getfield(state, 2, "Parent"); + uclass_t *parent = lua_overdub_unreal_class_check(state, -1); + lua_pop(state, 1); + + uint32_t num_props = 0; + unreal_prop_def_t *props = lua_overdub_unreal_props_parse(state, context, 2, &num_props); + + uint32_t num_funcs = 0; + lua_overdub_reflected_func_t *records = NULL; + unreal_func_def_t *funcs = lua_overdub_unreal_funcs_parse(state, context, 2, &records, &num_funcs); + + unreal_class_def_t def = { + .struct_size = sizeof(def), + .parent = parent, + .props = props, + .num_props = num_props, + .funcs = funcs, + .num_funcs = num_funcs, + }; + + unreal_reflect_owner_t owner = (unreal_reflect_owner_t)(uintptr_t)context; + uclass_t *cls = unreal_reflect_define_class_owned(owner, context->mod_id, name, &def); + bool defaults_applied = false; + if (cls) { + entry->name = name_copy; + entry->funcs = records; + entry->num_funcs = num_funcs; + entry->next = context->reflected_classes; + context->reflected_classes = entry; + + for (uint32_t i = 0; i < num_funcs; ++i) { + records[i].active = true; + } + + context->reflected_active = true; + defaults_applied = lua_overdub_unreal_apply_lua_defaults(state, 2, cls); + } + lua_overdub_unreal_exclude_native_time(context->runtime, start_us); + + if (!cls) { + for (uint32_t i = 0; i < num_funcs; ++i) { + lua_overdub_unreal_reflected_func_disable(&records[i]); + } + return luaL_error(state, "could not define Unreal class '%.*s'", (int)name.len, name.data); + } + + if (!defaults_applied) { + return luaL_error(state, "could not apply Lua defaults to Unreal class '%.*s'", (int)name.len, name.data); + } + return lua_unreal_object_push(state, (uobject_t *)cls); +} + +static int +lua_overdub_unreal_notification_add_lua(lua_State *state, lua_overdub_unreal_context_t *context, fweak_object_ptr_t target, + uobject_t *target_object, lua_overdub_notification_kind_t kind) +{ + luaL_checktype(state, 2, LUA_TFUNCTION); + lua_pushvalue(state, 2); + int callback_ref = luaL_ref(state, LUA_REGISTRYINDEX); + + int slot = -1; + uint64_t id = 0; + + AcquireSRWLockExclusive(&g_lua_overdub_notification_lock); + EnterCriticalSection(&context->notification_lock); + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_NOTIFICATIONS && slot < 0; ++i) { + if (!context->notifications[i].active) { + slot = i; + } + } + + if (slot >= 0) { + id = lua_overdub_unreal_next_id(&context->next_notification_id); + context->notifications[slot] = (lua_overdub_notification_t){ + .target = target, + .target_object = target_object, + .id = id, + .callback_ref = callback_ref, + .kind = kind, + .active = true, + }; + context->notification_count += 1; + + if (!context->notifications_attached) { + context->notification_next = g_lua_overdub_notification_first; + context->notifications_attached = true; + g_lua_overdub_notification_first = context; + InterlockedIncrement(&g_lua_overdub_notification_context_count); + } + } + LeaveCriticalSection(&context->notification_lock); + ReleaseSRWLockExclusive(&g_lua_overdub_notification_lock); + + if (slot < 0) { + luaL_unref(state, LUA_REGISTRYINDEX, callback_ref); + return luaL_error(state, "Overdub Unreal notification limit reached"); + } + + lua_overdub_notification_handle_t *handle = lua_newuserdatauv(state, sizeof(*handle), 0); + *handle = (lua_overdub_notification_handle_t){ + .context = context, + .id = id, + .slot = slot, + }; + luaL_setmetatable(state, LUA_OVERDUB_NOTIFY_HANDLE_META); + return 1; +} + +static int +lua_overdub_unreal_notify_on_new_object_lua(lua_State *state) +{ + lua_overdub_unreal_context_t *context = lua_overdub_unreal_context_check(state); + uclass_t *target = lua_overdub_unreal_class_arg(state, 1); + fweak_object_ptr_t weak = lua_overdub_unreal_invalid_weak(); + if (!unreal_fweak_object_from_object((uobject_t *)target, &weak)) { + return luaL_argerror(state, 1, "expected a live UClass"); + } + + return lua_overdub_unreal_notification_add_lua(state, context, weak, NULL, LUA_OVERDUB_NOTIFICATION_CREATED); +} + +static int +lua_overdub_unreal_notify_on_delete_object_lua(lua_State *state) +{ + lua_overdub_unreal_context_t *context = lua_overdub_unreal_context_check(state); + uobject_t *target = lua_overdub_unreal_object_check(state, 1); + fweak_object_ptr_t weak = lua_overdub_unreal_invalid_weak(); + if (!unreal_fweak_object_from_object(target, &weak)) { + return luaL_argerror(state, 1, "expected a live UObject"); + } + + return lua_overdub_unreal_notification_add_lua(state, context, weak, target, LUA_OVERDUB_NOTIFICATION_DELETED); +} + +static int +lua_overdub_unreal_hook_add_lua(lua_State *state, lua_overdub_unreal_context_t *context, uobject_t *target, lua_overdub_hook_kind_t kind) +{ + luaL_checktype(state, 2, LUA_TTABLE); + lua_getfield(state, 2, "Before"); + lua_getfield(state, 2, "After"); + + bool has_before = lua_type(state, -2) == LUA_TFUNCTION; + bool has_after = lua_type(state, -1) == LUA_TFUNCTION; + if (!lua_isnoneornil(state, -2) && !has_before) { + return luaL_argerror(state, 2, "Before must be a function or nil"); + } + + if (!lua_isnoneornil(state, -1) && !has_after) { + return luaL_argerror(state, 2, "After must be a function or nil"); + } + + if (!has_before && !has_after) { + return luaL_argerror(state, 2, "expected a Before or After callback"); + } + + int slot = -1; + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_HOOKS; ++i) { + if (!context->hooks[i].active) { + slot = i; + break; + } + } + + if (slot < 0) { + return luaL_error(state, "Overdub Unreal hook limit reached"); + } + + fweak_object_ptr_t target_weak = lua_overdub_unreal_invalid_weak(); + if (!unreal_fweak_object_from_object(target, &target_weak)) { + return luaL_argerror(state, 1, "expected a live hook target"); + } + + int before_ref = LUA_NOREF; + int after_ref = LUA_NOREF; + if (has_before) { + lua_pushvalue(state, -2); + before_ref = luaL_ref(state, LUA_REGISTRYINDEX); + } + + if (has_after) { + lua_pushvalue(state, -1); + after_ref = luaL_ref(state, LUA_REGISTRYINDEX); + } + lua_pop(state, 2); + + uint64_t id = lua_overdub_unreal_next_hook_id(context); + context->hooks[slot] = (lua_overdub_hook_t){ + .target = target_weak, + .id = id, + .before_ref = before_ref, + .after_ref = after_ref, + .kind = kind, + .active = true, + }; + + if (kind == LUA_OVERDUB_HOOK_POST_LOAD) { + g_lua_overdub_post_load_hook_count += 1; + } + + lua_overdub_hook_handle_t *handle = lua_newuserdatauv(state, sizeof(*handle), 0); + *handle = (lua_overdub_hook_handle_t){ + .context = context, + .id = id, + .slot = slot, + }; + luaL_setmetatable(state, LUA_OVERDUB_HOOK_HANDLE_META); + return 1; +} + +static int +lua_overdub_unreal_hook_lua(lua_State *state) +{ + lua_overdub_unreal_context_t *context = lua_overdub_unreal_context_check(state); + ufunc_t *function = NULL; + if (lua_type(state, 1) == LUA_TSTRING) { + size_t path_len = 0; + const char *path_data = lua_tolstring(state, 1, &path_len); + if (path_len == 0 || memchr(path_data, 0, path_len)) { + return luaL_argerror(state, 1, "UFunction path cannot be empty or contain null bytes"); + } + + uobject_t *object = unreal_uobject_find_by_path_name(globals.unreal.core_func, str_make((void *)path_data, (uint64_t)path_len)); + if (!object) { + return luaL_error(state, "UFunction '%.*s' was not found", (int)path_len, path_data); + } + + function = (ufunc_t *)object; + } else { + function = lua_overdub_unreal_function_check(state, 1); + } + + return lua_overdub_unreal_hook_add_lua(state, context, (uobject_t *)function, LUA_OVERDUB_HOOK_FUNCTION); +} + +static int +lua_overdub_unreal_hook_post_load_lua(lua_State *state) +{ + lua_overdub_unreal_context_t *context = lua_overdub_unreal_context_check(state); + uclass_t *target = lua_overdub_unreal_class_arg(state, 1); + return lua_overdub_unreal_hook_add_lua(state, context, (uobject_t *)target, LUA_OVERDUB_HOOK_POST_LOAD); +} + +static int +lua_overdub_unreal_struct_get_size_lua(lua_State *state) +{ + lua_pushinteger(state, lua_overdub_unreal_struct_check(state, 1)->props_size); + return 1; +} + +static int +lua_overdub_unreal_struct_get_min_alignment_lua(lua_State *state) +{ + lua_pushinteger(state, lua_overdub_unreal_struct_check(state, 1)->min_alignment); + return 1; +} + +static int +lua_overdub_unreal_class_get_flags_lua(lua_State *state) +{ + lua_pushinteger(state, (lua_Integer)lua_overdub_unreal_class_check(state, 1)->class_flags); + return 1; +} + +static int +lua_overdub_unreal_class_has_any_flags_lua(lua_State *state) +{ + uclass_t *cls = lua_overdub_unreal_class_check(state, 1); + eclass_flags_t flags = lua_overdub_unreal_u32_check(state, 2, "class flags must fit in an unsigned 32-bit integer"); + lua_pushboolean(state, (cls->class_flags & flags) != 0); + return 1; +} + +static int +lua_overdub_unreal_class_has_all_flags_lua(lua_State *state) +{ + uclass_t *cls = lua_overdub_unreal_class_check(state, 1); + eclass_flags_t flags = lua_overdub_unreal_u32_check(state, 2, "class flags must fit in an unsigned 32-bit integer"); + lua_pushboolean(state, (cls->class_flags & flags) == flags); + return 1; +} + +static int +lua_overdub_unreal_class_get_within_lua(lua_State *state) +{ + return lua_unreal_object_push(state, (uobject_t *)lua_overdub_unreal_class_check(state, 1)->class_within); +} + +static int +lua_overdub_unreal_class_get_generated_by_lua(lua_State *state) +{ + return lua_unreal_object_push(state, lua_overdub_unreal_class_check(state, 1)->class_generated_by); +} + +static int +lua_overdub_unreal_class_get_interfaces_lua(lua_State *state) +{ + uclass_t *cls = lua_overdub_unreal_class_check(state, 1); + tarray_fimplemented_interface_t *interfaces = &cls->interfaces; + if (interfaces->num < 0 || interfaces->max < interfaces->num || interfaces->num > 4096 || (interfaces->num > 0 && !interfaces->data)) { + return luaL_error(state, "the UClass interface table is invalid"); + } + + lua_createtable(state, interfaces->num, 0); + for (int32_t i = 0; i < interfaces->num; ++i) { + fimplemented_interface_t *interface = &interfaces->data[i]; + lua_createtable(state, 0, 3); + lua_unreal_object_push(state, (uobject_t *)interface->cls); + lua_setfield(state, -2, "Class"); + lua_pushinteger(state, interface->pointer_offset); + lua_setfield(state, -2, "PointerOffset"); + lua_pushboolean(state, interface->implemented_by_k2); + lua_setfield(state, -2, "ImplementedByK2"); + lua_rawseti(state, -2, i + 1); + } + return 1; +} + +static int +lua_overdub_unreal_function_get_parameter_count_lua(lua_State *state) +{ + lua_pushinteger(state, lua_overdub_unreal_function_check(state, 1)->num_params); + return 1; +} + +static int +lua_overdub_unreal_function_get_parameter_size_lua(lua_State *state) +{ + lua_pushinteger(state, lua_overdub_unreal_function_check(state, 1)->params_size); + return 1; +} + +static int +lua_overdub_unreal_function_get_return_offset_lua(lua_State *state) +{ + uint16_t offset = lua_overdub_unreal_function_check(state, 1)->return_val_offset; + if (offset == UINT16_MAX) { + lua_pushnil(state); + } else { + lua_pushinteger(state, offset); + } + return 1; +} + +static int +lua_overdub_unreal_enum_num_lua(lua_State *state) +{ + lua_pushinteger(state, lua_overdub_unreal_enum_check(state, 1)->names.num); + return 1; +} + +static bool +lua_overdub_unreal_method_push(lua_State *state, uobject_t *object, str_t name) +{ + if (!state || !object) { + return false; + } + + lua_CFunction function = NULL; + if (str_equal(name, STR_LIT("BindDelegate"), 0)) { + function = lua_overdub_unreal_bind_delegate_lua; + } + + if (globals.unreal.core_class && unreal_uobject_is_a(object, globals.unreal.core_class)) { + if (str_equal(name, STR_LIT("GetClassFlags"), 0)) { + function = lua_overdub_unreal_class_get_flags_lua; + } else if (str_equal(name, STR_LIT("HasAnyClassFlags"), 0)) { + function = lua_overdub_unreal_class_has_any_flags_lua; + } else if (str_equal(name, STR_LIT("HasAllClassFlags"), 0)) { + function = lua_overdub_unreal_class_has_all_flags_lua; + } else if (str_equal(name, STR_LIT("GetWithinClass"), 0)) { + function = lua_overdub_unreal_class_get_within_lua; + } else if (str_equal(name, STR_LIT("GetGeneratedBy"), 0)) { + function = lua_overdub_unreal_class_get_generated_by_lua; + } else if (str_equal(name, STR_LIT("GetInterfaces"), 0)) { + function = lua_overdub_unreal_class_get_interfaces_lua; + } else if (str_equal(name, STR_LIT("ConstructObject"), 0)) { + function = lua_overdub_unreal_construct_object_lua; + } else if (str_equal(name, STR_LIT("SpawnActor"), 0)) { + function = lua_overdub_unreal_spawn_actor_lua; + } + } + + if (!function && globals.unreal.core_func && unreal_uobject_is_a(object, globals.unreal.core_func)) { + if (str_equal(name, STR_LIT("GetParameterCount"), 0)) { + function = lua_overdub_unreal_function_get_parameter_count_lua; + } else if (str_equal(name, STR_LIT("GetParameterSize"), 0)) { + function = lua_overdub_unreal_function_get_parameter_size_lua; + } else if (str_equal(name, STR_LIT("GetReturnValueOffset"), 0)) { + function = lua_overdub_unreal_function_get_return_offset_lua; + } + } + + if (!function && globals.unreal.core_enum && unreal_uobject_is_a(object, globals.unreal.core_enum) && + str_equal(name, STR_LIT("NumEnums"), 0)) { + function = lua_overdub_unreal_enum_num_lua; + } + + bool is_struct = (globals.unreal.core_class && unreal_uobject_is_a(object, globals.unreal.core_class)) || + (globals.unreal.core_scriptstruct && unreal_uobject_is_a(object, globals.unreal.core_scriptstruct)) || + (globals.unreal.core_func && unreal_uobject_is_a(object, globals.unreal.core_func)); + if (!function && is_struct) { + if (str_equal(name, STR_LIT("GetStructureSize"), 0)) { + function = lua_overdub_unreal_struct_get_size_lua; + } else if (str_equal(name, STR_LIT("GetMinAlignment"), 0)) { + function = lua_overdub_unreal_struct_get_min_alignment_lua; + } + } + + if (!function) { + return false; + } + + lua_pushcfunction(state, function); + return true; +} + +static int +lua_overdub_unreal_object_index_lua(lua_State *state) +{ + lua_overdub_unreal_context_check(state); + uobject_t *object = lua_unreal_object_get(state, 1); + if (object && lua_type(state, 2) == LUA_TSTRING) { + size_t name_len = 0; + const char *name_data = lua_tolstring(state, 2, &name_len); + str_t name = str_make((void *)name_data, (uint64_t)name_len); + fprop_t *property = object->cls ? unreal_ustruct_find_prop((ustruct_t *)object->cls, name) : NULL; + if (!property && lua_overdub_unreal_method_push(state, object, name)) { + return 1; + } + } + + lua_pushvalue(state, lua_upvalueindex(1)); + lua_pushvalue(state, 1); + lua_pushvalue(state, 2); + lua_call(state, 2, 1); + return 1; +} + +static void +lua_overdub_unreal_class_flags_push(lua_State *state) +{ + static const struct { + const char *name; + eclass_flags_t value; + } flags[] = { + {"CLASS_None", CLASS_NONE }, + {"CLASS_Abstract", CLASS_ABSTRACT }, + {"CLASS_DefaultConfig", CLASS_DEFAULT_CONFIG }, + {"CLASS_Config", CLASS_CONFIG }, + {"CLASS_Transient", CLASS_TRANSIENT }, + {"CLASS_Parsed", CLASS_PARSED }, + {"CLASS_MatchedSerializers", CLASS_MATCHED_SERIALIZERS }, + {"CLASS_ProjectUserConfig", CLASS_PROJECT_USER_CONFIG }, + {"CLASS_Native", CLASS_NATIVE }, + {"CLASS_NoExport", CLASS_NO_EXPORT }, + {"CLASS_NotPlaceable", CLASS_NOT_PLACEABLE }, + {"CLASS_PerObjectConfig", CLASS_PER_OBJECT_CONFIG }, + {"CLASS_ReplicationDataIsSetUp", CLASS_REPLICATION_DATA_IS_SET_UP }, + {"CLASS_EditInlineNew", CLASS_EDIT_INLINE_NEW }, + {"CLASS_CollapseCategories", CLASS_COLLAPSE_CATEGORIES }, + {"CLASS_Interface", CLASS_INTERFACE }, + {"CLASS_CustomConstructor", CLASS_CUSTOM_CONSTRUCTOR }, + {"CLASS_Const", CLASS_CONST }, + {"CLASS_LayoutChanging", CLASS_LAYOUT_CHANGING }, + {"CLASS_CompiledFromBlueprint", CLASS_COMPILED_FROM_BLUEPRINT }, + {"CLASS_MinimalAPI", CLASS_MINIMAL_API }, + {"CLASS_RequiredAPI", CLASS_REQUIRED_API }, + {"CLASS_DefaultToInstanced", CLASS_DEFAULT_TO_INSTANCED }, + {"CLASS_TokenStreamAssembled", CLASS_TOKEN_STREAM_ASSEMBLED }, + {"CLASS_HasInstancedReference", CLASS_HAS_INSTANCED_REFERENCE }, + {"CLASS_Hidden", CLASS_HIDDEN }, + {"CLASS_Deprecated", CLASS_DEPRECATED }, + {"CLASS_HideDropDown", CLASS_HIDE_DROP_DOWN }, + {"CLASS_GlobalUserConfig", CLASS_GLOBAL_USER_CONFIG }, + {"CLASS_Intrinsic", CLASS_INTRINSIC }, + {"CLASS_Constructed", CLASS_CONSTRUCTED }, + {"CLASS_ConfigDoNotCheckDefaults", CLASS_CONFIG_DO_NOT_CHECK_DEFAULTS}, + {"CLASS_NewerVersionExists", CLASS_NEWER_VERSION_EXISTS }, + }; + + lua_createtable(state, 0, (int)(sizeof(flags) / sizeof(flags[0]))); + for (size_t i = 0; i < sizeof(flags) / sizeof(flags[0]); ++i) { + lua_pushinteger(state, (lua_Integer)flags[i].value); + lua_setfield(state, -2, flags[i].name); + } +} + +static void +lua_overdub_unreal_property_flags_push(lua_State *state) +{ + static const struct { + const char *name; + eprop_flags_t value; + } flags[] = { + {"CPF_None", CPF_NONE }, + {"CPF_Edit", CPF_EDIT }, + {"CPF_ConstParm", CPF_CONST_PARM }, + {"CPF_BlueprintVisible", CPF_BLUEPRINT_VISIBLE }, + {"CPF_BlueprintReadOnly", CPF_BLUEPRINT_READ_ONLY }, + {"CPF_EditFixedSize", CPF_EDIT_FIXED_SIZE }, + {"CPF_Transient", CPF_TRANSIENT }, + {"CPF_Config", CPF_CONFIG }, + {"CPF_DisableEditOnTemplate", CPF_DISABLE_EDIT_ON_TEMPLATE }, + {"CPF_DisableEditOnInstance", CPF_DISABLE_EDIT_ON_INSTANCE }, + {"CPF_EditConst", CPF_EDIT_CONST }, + {"CPF_GlobalConfig", CPF_GLOBAL_CONFIG }, + {"CPF_InstancedReference", CPF_INSTANCED_REFERENCE }, + {"CPF_DuplicateTransient", CPF_DUPLICATE_TRANSIENT }, + {"CPF_SaveGame", CPF_SAVE_GAME }, + {"CPF_NoClear", CPF_NO_CLEAR }, + {"CPF_Deprecated", CPF_DEPRECATED }, + {"CPF_Interp", CPF_INTERP }, + {"CPF_NonTransactional", CPF_NON_TRANSACTIONAL }, + {"CPF_EditorOnly", CPF_EDITOR_ONLY }, + {"CPF_AssetRegistrySearchable", CPF_ASSET_REGISTRY_SEARCHABLE }, + {"CPF_SimpleDisplay", CPF_SIMPLE_DISPLAY }, + {"CPF_AdvancedDisplay", CPF_ADVANCED_DISPLAY }, + {"CPF_Protected", CPF_PROTECTED }, + {"CPF_ExposeOnSpawn", CPF_EXPOSE_ON_SPAWN }, + {"CPF_TextExportTransient", CPF_TEXT_EXPORT_TRANSIENT }, + {"CPF_NonPIEDuplicateTransient", CPF_NON_PIE_DUPLICATE_TRANSIENT}, + {"CPF_SkipSerialization", CPF_SKIP_SERIALIZATION }, + }; + + lua_createtable(state, 0, (int)COUNTOF(flags)); + for (size_t i = 0; i < COUNTOF(flags); ++i) { + lua_pushinteger(state, (lua_Integer)flags[i].value); + lua_setfield(state, -2, flags[i].name); + } +} + +static void +lua_overdub_unreal_function_flags_push(lua_State *state) +{ + static const struct { + const char *name; + efunc_flags_t value; + } flags[] = { + {"FUNC_None", FUNC_FLAG_NONE }, + {"FUNC_Final", FUNC_FLAG_FINAL }, + {"FUNC_Public", FUNC_FLAG_PUBLIC }, + {"FUNC_Private", FUNC_FLAG_PRIVATE }, + {"FUNC_Protected", FUNC_FLAG_PROTECTED }, + {"FUNC_BlueprintCallable", FUNC_FLAG_BLUEPRINT_CALLABLE}, + {"FUNC_BlueprintPure", FUNC_FLAG_BLUEPRINT_PURE }, + {"FUNC_Const", FUNC_FLAG_CONST }, + }; + + lua_createtable(state, 0, (int)COUNTOF(flags)); + for (size_t i = 0; i < COUNTOF(flags); ++i) { + lua_pushinteger(state, (lua_Integer)flags[i].value); + lua_setfield(state, -2, flags[i].name); + } +} + +static int +lua_overdub_unreal_object_get_name_lua(lua_State *state) +{ + uobject_t *object = lua_overdub_unreal_object_check(state, 1); + tmp_arena_t tmp = scratch_begin(NULL); + str_t name = unreal_uobject_push_name(object, tmp.arena); + lua_pushlstring(state, (const char *)name.data, (size_t)name.len); + scratch_end(tmp); + return 1; +} + +static int +lua_overdub_unreal_object_get_internal_index_lua(lua_State *state) +{ + lua_pushinteger(state, lua_overdub_unreal_object_check(state, 1)->internal_idx); + return 1; +} + +static int +lua_overdub_unreal_object_get_path_name_lua(lua_State *state) +{ + uobject_t *object = lua_overdub_unreal_object_check(state, 1); + tmp_arena_t tmp = scratch_begin(NULL); + str_t path = unreal_uobject_push_ue_path_name(object, tmp.arena); + lua_pushlstring(state, (const char *)path.data, (size_t)path.len); + scratch_end(tmp); + return 1; +} + +static int +lua_overdub_unreal_object_get_flags_lua(lua_State *state) +{ + lua_pushinteger(state, (lua_Integer)lua_overdub_unreal_object_check(state, 1)->obj_flags); + return 1; +} + +static int +lua_overdub_unreal_object_get_internal_flags_lua(lua_State *state) +{ + lua_pushinteger(state, (lua_Integer)unreal_uobject_get_internal_flags(lua_overdub_unreal_object_check(state, 1))); + return 1; +} + +static int +lua_overdub_unreal_object_is_rooted_lua(lua_State *state) +{ + lua_pushboolean(state, unreal_uobject_is_rooted(lua_overdub_unreal_object_check(state, 1))); + return 1; +} + +static int +lua_overdub_unreal_object_add_to_root_lua(lua_State *state) +{ + lua_overdub_unreal_context_t *context = lua_overdub_unreal_context_check(state); + lua_pushboolean(state, lua_overdub_unreal_claim_root(context, lua_overdub_unreal_object_check(state, 1))); + return 1; +} + +static int +lua_overdub_unreal_object_remove_from_root_lua(lua_State *state) +{ + lua_overdub_unreal_context_t *context = lua_overdub_unreal_context_check(state); + lua_pushboolean(state, lua_overdub_unreal_release_root(context, lua_overdub_unreal_object_check(state, 1))); + return 1; +} + +static void +lua_overdub_unreal_pending_params_destroy(ufunc_t *function, void *params, uint32_t initialized_count) +{ + if (params && function) { + uint32_t destroyed = 0; + for (ffield_t *field = function->child_props; field && destroyed < initialized_count; field = field->next) { + fprop_t *prop = (fprop_t *)field; + if (prop->prop_flags & CPF_PARM) { + unreal_fprop_destroy_in_container(prop, params); + destroyed += 1; + } + } + } +} + +static bool +lua_overdub_unreal_pending_params_snapshot(lua_overdub_unreal_context_t *context, ufunc_t *function, void *params, void **out_params, uint32_t *out_initialized_count) +{ + if (!context || !function || !out_params || !out_initialized_count) { + return false; + } + + *out_params = NULL; + *out_initialized_count = 0; + if (function->params_size == 0) { + return true; + } + + if (!params) { + return false; + } + + uint64_t alignment = MAX_VAL((uint64_t)function->min_alignment, 1ULL); + void *copy = arena_push_zero_aligned(&context->param_arena, function->params_size, alignment); + if (!copy) { + return false; + } + + bool copied = true; + for (ffield_t *field = function->child_props; field && copied; field = field->next) { + fprop_t *prop = (fprop_t *)field; + if (prop->prop_flags & CPF_PARM) { + uint64_t size = unreal_fprop_complete_size(prop); + bool fits = prop->offset_internal >= 0 && size > 0 && (uint64_t)prop->offset_internal <= function->params_size && + size <= (uint64_t)function->params_size - (uint64_t)prop->offset_internal; + + void *dst = NULL; + void *src = NULL; + if (fits) { + dst = unreal_fprop_value_in_container(prop, copy, 0); + src = unreal_fprop_value_in_container(prop, params, 0); + } + + copied = dst && src && unreal_fprop_initialize_value(prop, dst); + if (copied) { + *out_initialized_count += 1; + copied = unreal_fprop_copy_complete_value(prop, dst, src); + } + } + } + + if (!copied) { + lua_overdub_unreal_pending_params_destroy(function, copy, *out_initialized_count); + *out_initialized_count = 0; + copy = NULL; + } + + *out_params = copy; + return copied; +} + +static void +lua_overdub_unreal_param_arena_reset_if_empty(lua_overdub_unreal_context_t *context) +{ + if (context && context->pending_func_count == 0 && context->pending_hook_count == 0) { + arena_reset(&context->param_arena); + } +} + +static void +lua_overdub_unreal_pending_hook_destroy(lua_overdub_pending_hook_t *pending) +{ + if (!pending) { + return; + } + + lua_overdub_unreal_pending_params_destroy(pending->function_raw, pending->params, pending->initialized_count); + *pending = (lua_overdub_pending_hook_t){0}; +} + +static bool +lua_overdub_unreal_pending_hook_snapshot(lua_overdub_unreal_context_t *context, lua_overdub_pending_hook_t *pending, uobject_t *object, + ufunc_t *function, void *params, bool after, bool consumed) +{ + if (!context || !pending || !object || !function) { + return false; + } + + bool object_saved = unreal_fweak_object_from_object(object, &pending->object); + bool function_saved = unreal_fweak_object_from_object((uobject_t *)function, &pending->function); + if (!object_saved || !function_saved) { + return false; + } + + pending->function_raw = function; + pending->after = after; + pending->consumed = consumed; + return lua_overdub_unreal_pending_params_snapshot(context, function, params, &pending->params, &pending->initialized_count); +} + +static void +lua_overdub_unreal_pending_func_destroy(lua_overdub_pending_func_t *pending) +{ + if (!pending) { + return; + } + + lua_overdub_unreal_pending_params_destroy(pending->function_raw, pending->params, pending->initialized_count); + *pending = (lua_overdub_pending_func_t){0}; +} + +static bool +lua_overdub_unreal_queue_reflected_func(lua_overdub_reflected_func_t *func, unreal_func_call_t *call) +{ + if (!func || !call) { + return false; + } + + lua_overdub_unreal_context_t *context = func->context; + if (!context || !call->object || !call->function) { + return false; + } + + if (context->pending_func_count >= CONFIG_LUA_OVERDUB_MAX_PENDING_FUNC_CALLS) { + context->pending_func_overflow = true; + return false; + } + + lua_overdub_pending_func_t pending = { + .function_raw = call->function, + .impl = func, + }; + bool saved = unreal_fweak_object_from_object(call->object, &pending.object) && unreal_fweak_object_from_object((uobject_t *)call->function, &pending.function); + if (saved) { + saved = lua_overdub_unreal_pending_params_snapshot(context, call->function, call->params, &pending.params, &pending.initialized_count); + } + + if (!saved) { + lua_overdub_unreal_pending_func_destroy(&pending); + lua_overdub_unreal_param_arena_reset_if_empty(context); + LOG_ERROR("Overdub Lua mod '%.*s' could not snapshot a nested Lua-backed UFunction call", STR_ARG(context->mod_id)); + return false; + } + + context->pending_funcs[context->pending_func_count++] = pending; + return true; +} + +static bool +lua_overdub_unreal_hook_matches(lua_overdub_hook_t *hook, ufunc_t *function, bool after) +{ + int callback_ref = after ? hook->after_ref : hook->before_ref; + return hook->active && hook->kind == LUA_OVERDUB_HOOK_FUNCTION && callback_ref != LUA_NOREF && callback_ref != LUA_REFNIL && + unreal_fweak_object_resolve(hook->target) == (uobject_t *)function; +} + +static bool +lua_overdub_unreal_has_matching_hook(lua_overdub_unreal_context_t *context, ufunc_t *function, bool after) +{ + if (!context || !function) { + return false; + } + + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_HOOKS; ++i) { + if (lua_overdub_unreal_hook_matches(&context->hooks[i], function, after)) { + return true; + } + } + return false; +} + +static bool +lua_overdub_unreal_queue_hook(lua_overdub_unreal_context_t *context, uobject_t *object, + ufunc_t *function, void *params, bool after, bool consumed) +{ + if (!lua_overdub_unreal_has_matching_hook(context, function, after)) { + return false; + } + + if (context->pending_hook_count >= CONFIG_LUA_OVERDUB_MAX_PENDING_HOOKS) { + context->pending_hook_overflow = true; + return false; + } + + lua_overdub_pending_hook_t pending = {0}; + if (!lua_overdub_unreal_pending_hook_snapshot(context, &pending, object, function, params, after, consumed)) { + lua_overdub_unreal_param_arena_reset_if_empty(context); + LOG_ERROR("Overdub Lua mod '%.*s' could not snapshot nested UFunction hook parameters", STR_ARG(context->mod_id)); + return false; + } + + context->pending_hooks[context->pending_hook_count++] = pending; + return true; +} + +static bool +lua_overdub_unreal_hook_call(lua_overdub_unreal_context_t *context, lua_runtime_t *runtime, + bool *in_callback, lua_overdub_hook_t *hook, uobject_t *object, + ufunc_t *function, void *params, bool after, bool consumed, bool deferred) +{ + int *callback_ref_slot = after ? &hook->after_ref : &hook->before_ref; + int callback_ref = *callback_ref_slot; + if (!runtime || !runtime->state || !in_callback || + !lua_overdub_unreal_hook_matches(hook, function, after)) { + return false; + } + + fweak_object_ptr_t object_weak = {.object_idx = -1}; + fweak_object_ptr_t function_weak = {.object_idx = -1}; + if (!unreal_fweak_object_from_object(object, &object_weak) || !unreal_fweak_object_from_object((uobject_t *)function, &function_weak)) { + return false; + } + + lua_State *state = runtime->state; + int stack_base = lua_gettop(state); + lua_overdub_call_t *call = lua_newuserdatauv(state, sizeof(*call), 0); + *call = (lua_overdub_call_t){ + .context = context, + .object = object_weak, + .function = function_weak, + .function_raw = function, + .params = params, + .valid = true, + .before = !after, + .deferred = deferred, + .consumed = consumed, + }; + luaL_setmetatable(state, LUA_OVERDUB_CALL_META); + + *in_callback = true; + bool called = lua_runtime_call_ref(runtime, callback_ref, 1, 0); + *in_callback = false; + + bool skip_requested = call->skip_requested; + call->valid = false; + lua_settop(state, stack_base); + + if (!called && hook->active && *callback_ref_slot == callback_ref) { + luaL_unref(state, LUA_REGISTRYINDEX, callback_ref); + + *callback_ref_slot = LUA_NOREF; + if (hook->before_ref == LUA_NOREF && hook->after_ref == LUA_NOREF) { + lua_overdub_unreal_hook_deactivate(NULL, hook); + } + + LOG_ERROR("Overdub Lua mod '%.*s': disabling failed %s hook callback", STR_ARG(context->mod_id), after ? "After" : "Before"); + } + return called && skip_requested; +} + +static bool +lua_overdub_unreal_dispatch_hook(lua_overdub_unreal_context_t *context, lua_runtime_t *runtime, + bool *in_callback, uobject_t *object, ufunc_t *function, + void *params, bool after, bool consumed, bool deferred) +{ + bool skip_requested = false; + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_HOOKS; ++i) { + lua_overdub_hook_t *hook = &context->hooks[i]; + if (lua_overdub_unreal_hook_matches(hook, function, after) && + lua_overdub_unreal_hook_call(context, runtime, in_callback, hook, object, function, params, after, consumed, deferred)) { + skip_requested = true; + } + } + return skip_requested; +} + +bool +lua_overdub_unreal_process_event_pre(lua_overdub_unreal_context_t *context, lua_runtime_t *runtime, + bool *in_callback, uobject_t *object, ufunc_t *function, void *params) +{ + if (!context || !runtime || !in_callback || !object || !function || + !lua_overdub_unreal_access_check(context)) { + return false; + } + + if (*in_callback) { + lua_overdub_unreal_queue_hook(context, object, function, params, false, false); + return false; + } + return lua_overdub_unreal_dispatch_hook(context, runtime, in_callback, object, function, + params, false, false, false); +} + +void +lua_overdub_unreal_process_event_post(lua_overdub_unreal_context_t *context, lua_runtime_t *runtime, + bool *in_callback, uobject_t *object, ufunc_t *function, + void *params, bool consumed) +{ + if (!context || !runtime || !in_callback || !object || !function || + !lua_overdub_unreal_access_check(context)) { + return; + } + + if (*in_callback) { + lua_overdub_unreal_queue_hook(context, object, function, params, true, consumed); + return; + } + lua_overdub_unreal_dispatch_hook(context, runtime, in_callback, object, function, params, true, consumed, false); +} + +static bool +lua_overdub_unreal_post_load_matches(lua_overdub_hook_t *hook, uobject_t *object, bool after) +{ + if (!hook || !hook->active || hook->kind != LUA_OVERDUB_HOOK_POST_LOAD || !object) { + return false; + } + + int callback_ref = after ? hook->after_ref : hook->before_ref; + if (callback_ref == LUA_NOREF || callback_ref == LUA_REFNIL) { + return false; + } + + uclass_t *target = (uclass_t *)unreal_fweak_object_resolve(hook->target); + return target && unreal_uobject_is_a(object, target); +} + +static void +lua_overdub_unreal_post_load_call(lua_overdub_unreal_context_t *context, lua_runtime_t *runtime, bool *in_callback, lua_overdub_hook_t *hook, uobject_t *object, bool after) +{ + if (!runtime || !runtime->state || !in_callback || *in_callback) { + return; + } + + if (!lua_overdub_unreal_post_load_matches(hook, object, after)) { + return; + } + + int *ref_slot = after ? &hook->after_ref : &hook->before_ref; + int ref = *ref_slot; + lua_unreal_object_push(runtime->state, object); + + *in_callback = true; + bool called = lua_runtime_call_ref(runtime, ref, 1, 0); + *in_callback = false; + + if (!called && hook->active && *ref_slot == ref) { + luaL_unref(runtime->state, LUA_REGISTRYINDEX, ref); + *ref_slot = LUA_NOREF; + + if (hook->before_ref == LUA_NOREF && hook->after_ref == LUA_NOREF) { + lua_overdub_unreal_hook_deactivate(NULL, hook); + } + + const char *phase = after ? "After" : "Before"; + LOG_ERROR("Overdub Lua mod '%.*s': disabling failed %s PostLoad callback", STR_ARG(context->mod_id), phase); + } +} + +void +lua_overdub_unreal_post_load(lua_overdub_unreal_context_t *context, lua_runtime_t *runtime, bool *in_callback, uobject_t *object, bool after) +{ + if (!context || !runtime || !in_callback || !object || *in_callback || !lua_overdub_unreal_access_check(context)) { + return; + } + + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_HOOKS; ++i) { + lua_overdub_hook_t *hook = &context->hooks[i]; + if (lua_overdub_unreal_post_load_matches(hook, object, after)) { + lua_overdub_unreal_post_load_call(context, runtime, in_callback, hook, object, after); + } + } +} + +bool +lua_overdub_unreal_has_post_load_hooks(void) +{ + return g_lua_overdub_post_load_hook_count > 0; +} + +int +lua_overdub_unreal_post_load_hook_count(void) +{ + return g_lua_overdub_post_load_hook_count; +} + +static void +lua_overdub_unreal_queue_constructed(lua_overdub_unreal_context_t *context, uobject_t *object) +{ + if (!context || !object) { + return; + } + + EnterCriticalSection(&context->notification_lock); + bool notify = false; + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_NOTIFICATIONS && !notify; ++i) { + if (lua_overdub_unreal_notification_matches(&context->notifications[i], object)) { + notify = true; + } + } + + bool has_space = context->pending_object_count < CONFIG_LUA_OVERDUB_MAX_PENDING_OBJECTS; + if (notify && !has_space) { + context->pending_object_overflow = true; + } + + fweak_object_ptr_t weak = lua_overdub_unreal_invalid_weak(); + if (notify && has_space && unreal_fweak_object_from_object(object, &weak)) { + int tail = (context->pending_object_head + context->pending_object_count) % CONFIG_LUA_OVERDUB_MAX_PENDING_OBJECTS; + context->pending_objects[tail] = (lua_overdub_pending_object_t){.object = weak}; + context->pending_object_count += 1; + } + + LeaveCriticalSection(&context->notification_lock); +} + +void +lua_overdub_unreal_notify_constructed(uobject_t *object) +{ + if (!object || InterlockedCompareExchange(&g_lua_overdub_notification_context_count, 0, 0) <= 0) { + return; + } + + AcquireSRWLockShared(&g_lua_overdub_notification_lock); + for (lua_overdub_unreal_context_t *context = g_lua_overdub_notification_first; context; context = context->notification_next) { + lua_overdub_unreal_queue_constructed(context, object); + } + ReleaseSRWLockShared(&g_lua_overdub_notification_lock); +} + +static void +lua_overdub_unreal_queue_deleted(lua_overdub_unreal_context_t *context, uobject_t *object, int32_t idx) +{ + if (!context || !object || idx < 0) { + return; + } + + EnterCriticalSection(&context->notification_lock); + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_NOTIFICATIONS; ++i) { + lua_overdub_notification_t *notification = &context->notifications[i]; + if (lua_overdub_unreal_delete_notification_matches(notification, object, idx)) { + notification->delete_queued = true; + context->pending_delete_count += 1; + } + } + LeaveCriticalSection(&context->notification_lock); +} + +void +lua_overdub_unreal_notify_deleted(uobject_t *object, int32_t idx) +{ + LONG context_count = InterlockedCompareExchange(&g_lua_overdub_notification_context_count, 0, 0); + if (!object || idx < 0 || context_count <= 0) { + return; + } + + AcquireSRWLockShared(&g_lua_overdub_notification_lock); + for (lua_overdub_unreal_context_t *context = g_lua_overdub_notification_first; context; context = context->notification_next) { + lua_overdub_unreal_queue_deleted(context, object, idx); + } + ReleaseSRWLockShared(&g_lua_overdub_notification_lock); +} + +typedef enum { + LUA_OVERDUB_NOTIFICATION_NONE, + LUA_OVERDUB_NOTIFICATION_OBJECT_DONE, + LUA_OVERDUB_NOTIFICATION_CALLBACK, +} lua_overdub_notification_dispatch_t; + +static lua_overdub_notification_dispatch_t +lua_overdub_unreal_next_notification(lua_overdub_unreal_context_t *context, uobject_t **out_object, uint64_t *out_id, int *out_callback_ref) +{ + lua_overdub_notification_dispatch_t result = LUA_OVERDUB_NOTIFICATION_NONE; + EnterCriticalSection(&context->notification_lock); + if (context->pending_object_count > 0) { + lua_overdub_pending_object_t *pending = &context->pending_objects[context->pending_object_head]; + uobject_t *object = unreal_fweak_object_resolve(pending->object); + int index = pending->next_notification; + while (object && index < CONFIG_LUA_OVERDUB_MAX_NOTIFICATIONS && result != LUA_OVERDUB_NOTIFICATION_CALLBACK) { + int i = index++; + pending->next_notification = i + 1; + lua_overdub_notification_t *notification = &context->notifications[i]; + if (lua_overdub_unreal_notification_matches(notification, object)) { + *out_object = object; + *out_id = notification->id; + *out_callback_ref = notification->callback_ref; + result = LUA_OVERDUB_NOTIFICATION_CALLBACK; + } + } + + if (result != LUA_OVERDUB_NOTIFICATION_CALLBACK) { + *pending = (lua_overdub_pending_object_t){0}; + context->pending_object_head = (context->pending_object_head + 1) % CONFIG_LUA_OVERDUB_MAX_PENDING_OBJECTS; + context->pending_object_count -= 1; + result = LUA_OVERDUB_NOTIFICATION_OBJECT_DONE; + } + } + + LeaveCriticalSection(&context->notification_lock); + return result; +} + +static bool +lua_overdub_unreal_take_delete(lua_overdub_unreal_context_t *context, int *out_callback_ref) +{ + bool found = false; + bool detach = false; + + EnterCriticalSection(&context->notification_lock); + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_NOTIFICATIONS && !found; ++i) { + lua_overdub_notification_t *notification = &context->notifications[i]; + bool queued = notification->active && notification->kind == LUA_OVERDUB_NOTIFICATION_DELETED && notification->delete_queued; + if (queued) { + *out_callback_ref = notification->callback_ref; + notification->callback_ref = LUA_NOREF; + notification->active = false; + notification->delete_queued = false; + context->pending_delete_count -= 1; + context->notification_count -= 1; + detach = context->notification_count == 0; + found = true; + } + } + LeaveCriticalSection(&context->notification_lock); + + if (detach) { + lua_overdub_unreal_notifications_detach(context); + } + + return found; +} + +static void +lua_overdub_unreal_disable_notification(lua_overdub_unreal_context_t *context, uint64_t id, int callback_ref) +{ + bool detach = false; + bool found = false; + EnterCriticalSection(&context->notification_lock); + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_NOTIFICATIONS && !found; ++i) { + lua_overdub_notification_t *notification = &context->notifications[i]; + if (notification->active && notification->id == id && notification->callback_ref == callback_ref) { + notification->active = false; + notification->callback_ref = LUA_NOREF; + context->notification_count -= 1; + detach = context->notification_count == 0; + found = true; + } + } + LeaveCriticalSection(&context->notification_lock); + + if (detach) { + lua_overdub_unreal_notifications_detach(context); + } +} + +static uint64_t +lua_overdub_unreal_dispatch_notifications(lua_overdub_unreal_context_t *context, lua_runtime_t *runtime, bool *in_callback, uint64_t budget_us) +{ + uint64_t start_us = time_now_us(); + + EnterCriticalSection(&context->notification_lock); + int objects_left = context->pending_object_count; + bool overflow = context->pending_object_overflow; + context->pending_object_overflow = false; + LeaveCriticalSection(&context->notification_lock); + + if (overflow) { + LOG_WARN("Overdub Lua mod '%.*s' new-object notification queue overflowed; some callbacks were dropped", STR_ARG(context->mod_id)); + } + + while (objects_left > 0 && time_now_us() - start_us < budget_us) { + uobject_t *object = NULL; + uint64_t id = 0; + int callback_ref = LUA_NOREF; + lua_overdub_notification_dispatch_t next = lua_overdub_unreal_next_notification(context, &object, &id, &callback_ref); + if (next == LUA_OVERDUB_NOTIFICATION_NONE) { + break; + } + + if (next == LUA_OVERDUB_NOTIFICATION_OBJECT_DONE) { + objects_left -= 1; + continue; + } + + int stack_base = lua_gettop(runtime->state); + lua_unreal_object_push(runtime->state, object); + *in_callback = true; + bool called = lua_runtime_call_ref(runtime, callback_ref, 1, 0); + *in_callback = false; + lua_settop(runtime->state, stack_base); + + if (!called) { + lua_overdub_unreal_disable_notification(context, id, callback_ref); + luaL_unref(runtime->state, LUA_REGISTRYINDEX, callback_ref); + LOG_ERROR("Overdub Lua mod '%.*s': disabling failed new-object notification", STR_ARG(context->mod_id)); + } + } + return time_now_us() - start_us; +} + +static uint64_t +lua_overdub_unreal_dispatch_deletes(lua_overdub_unreal_context_t *context, lua_runtime_t *runtime, bool *in_callback, uint64_t budget_us) +{ + uint64_t start_us = time_now_us(); + + EnterCriticalSection(&context->notification_lock); + int deletes_left = context->pending_delete_count; + LeaveCriticalSection(&context->notification_lock); + + while (deletes_left > 0 && time_now_us() - start_us < budget_us) { + int callback_ref = LUA_NOREF; + bool found = lua_overdub_unreal_take_delete(context, &callback_ref); + if (found) { + *in_callback = true; + bool called = lua_runtime_call_ref(runtime, callback_ref, 0, 0); + *in_callback = false; + luaL_unref(runtime->state, LUA_REGISTRYINDEX, callback_ref); + deletes_left -= 1; + + if (!called) { + LOG_ERROR("Overdub Lua mod '%.*s': delete notification callback failed", STR_ARG(context->mod_id)); + } + } else { + deletes_left = 0; + } + } + + return time_now_us() - start_us; +} + +static uint64_t +lua_overdub_unreal_dispatch_reflected_funcs(lua_overdub_unreal_context_t *context, uint64_t budget_us) +{ + uint64_t start_us = time_now_us(); + int dispatch_count = context->pending_func_count; + for (int i = 0; i < dispatch_count && context->pending_func_count > 0; ++i) { + if (time_now_us() - start_us >= budget_us) { + break; + } + + lua_overdub_pending_func_t pending = context->pending_funcs[0]; + context->pending_func_count -= 1; + if (context->pending_func_count > 0) { + mem_move(context->pending_funcs, context->pending_funcs + 1, sizeof(*context->pending_funcs) * (uint64_t)context->pending_func_count); + } + context->pending_funcs[context->pending_func_count] = (lua_overdub_pending_func_t){0}; + + uobject_t *object = unreal_fweak_object_resolve(pending.object); + ufunc_t *function = (ufunc_t *)unreal_fweak_object_resolve(pending.function); + + unreal_func_call_t call = { + .object = object, + .function = function, + .params = pending.params, + .user = pending.impl, + }; + + if (function == pending.function_raw && lua_overdub_unreal_reflected_func_ready(pending.impl, &call)) { + lua_overdub_unreal_reflected_func_invoke(pending.impl, &call); + } + + lua_overdub_unreal_pending_func_destroy(&pending); + } + return time_now_us() - start_us; +} + +uint64_t +lua_overdub_unreal_dispatch_pending(lua_overdub_unreal_context_t *context, lua_runtime_t *runtime, bool *in_callback, uint64_t budget_us) +{ + if (!context || !runtime || !in_callback || *in_callback || budget_us == 0 || !lua_overdub_unreal_access_check(context)) { + return 0; + } + + if (context->pending_func_overflow) { + LOG_WARN("Overdub Lua mod '%.*s' nested Lua-backed UFunction queue overflowed; some calls were dropped", STR_ARG(context->mod_id)); + context->pending_func_overflow = false; + } + + if (context->pending_hook_overflow) { + LOG_WARN("Overdub Lua mod '%.*s' nested UFunction hook queue overflowed; some callbacks were dropped", STR_ARG(context->mod_id)); + context->pending_hook_overflow = false; + } + + uint64_t start_us = time_now_us(); + lua_overdub_unreal_dispatch_reflected_funcs(context, budget_us); + + uint64_t elapsed_us = time_now_us() - start_us; + if (elapsed_us < budget_us) { + lua_overdub_unreal_dispatch_notifications(context, runtime, in_callback, budget_us - elapsed_us); + } + + elapsed_us = time_now_us() - start_us; + if (elapsed_us < budget_us) { + lua_overdub_unreal_dispatch_deletes(context, runtime, in_callback, budget_us - elapsed_us); + } + + int dispatch_count = context->pending_hook_count; + for (int i = 0; i < dispatch_count && context->pending_hook_count > 0; ++i) { + if (time_now_us() - start_us >= budget_us) { + break; + } + + lua_overdub_pending_hook_t pending = context->pending_hooks[0]; + context->pending_hook_count -= 1; + if (context->pending_hook_count > 0) { + mem_move(context->pending_hooks, context->pending_hooks + 1, sizeof(*context->pending_hooks) * (uint64_t)context->pending_hook_count); + } + context->pending_hooks[context->pending_hook_count] = (lua_overdub_pending_hook_t){0}; + + uobject_t *object = unreal_fweak_object_resolve(pending.object); + ufunc_t *function = (ufunc_t *)unreal_fweak_object_resolve(pending.function); + if (object && function == pending.function_raw) { + lua_overdub_unreal_dispatch_hook(context, runtime, in_callback, object, function, pending.params, pending.after, pending.consumed, true); + } + lua_overdub_unreal_pending_hook_destroy(&pending); + } + + lua_overdub_unreal_param_arena_reset_if_empty(context); + return time_now_us() - start_us; +} + +int +lua_overdub_unreal_pending_count(lua_overdub_unreal_context_t *context) +{ + if (!context) { + return 0; + } + + int count = context->pending_func_count + context->pending_hook_count; + EnterCriticalSection(&context->notification_lock); + count += context->pending_object_count + context->pending_delete_count; + LeaveCriticalSection(&context->notification_lock); + return count; +} + +static int +luaopen_overdub_unreal(lua_State *state) +{ + lua_overdub_unreal_context_check(state); + static const luaL_Reg functions[] = { + {"FindObject", lua_overdub_unreal_find_object_lua }, + {"GetObjectCount", lua_overdub_unreal_get_object_count_lua }, + {"GetObjectByIndex", lua_overdub_unreal_get_object_by_index_lua }, + {"Objects", lua_overdub_unreal_objects_lua }, + {"LoadObject", lua_overdub_unreal_load_object_lua }, + {"ConstructObject", lua_overdub_unreal_construct_object_lua }, + {"SpawnActor", lua_overdub_unreal_spawn_actor_lua }, + {"DefineClass", lua_overdub_unreal_define_class_lua }, + {"BindDelegate", lua_overdub_unreal_bind_delegate_lua }, + {"NotifyOnNewObject", lua_overdub_unreal_notify_on_new_object_lua }, + {"NotifyOnDeleteObject", lua_overdub_unreal_notify_on_delete_object_lua }, + {"Hook", lua_overdub_unreal_hook_lua }, + {"HookPostLoad", lua_overdub_unreal_hook_post_load_lua }, + {"GetCurrentWorld", lua_overdub_unreal_get_current_world_lua }, + {"GetTransientPackage", lua_overdub_unreal_get_transient_package_lua }, + {"FName", lua_unreal_fname_construct }, + {"FText", lua_unreal_ftext_construct }, + {NULL, NULL }, + }; + + luaL_newlib(state, functions); + lua_unreal_object_flags_push(state); + lua_setfield(state, -2, "EObjectFlags"); + lua_unreal_internal_object_flags_push(state); + lua_setfield(state, -2, "EInternalObjectFlags"); + lua_overdub_unreal_class_flags_push(state); + lua_setfield(state, -2, "EClassFlags"); + lua_overdub_unreal_property_flags_push(state); + lua_setfield(state, -2, "EPropertyFlags"); + lua_overdub_unreal_function_flags_push(state); + lua_setfield(state, -2, "EFunctionFlags"); + lua_unreal_property_types_push(state); + lua_setfield(state, -2, "PropertyTypes"); + lua_unreal_find_name_modes_push(state); + lua_setfield(state, -2, "EFindName"); + lua_unreal_name_none_push(state); + lua_setfield(state, -2, "NAME_None"); + return 1; +} + +lua_overdub_unreal_context_t * +lua_overdub_unreal_context_create(arena_t *arena, lua_runtime_t *runtime, bool *in_callback, str_t mod_id, uint32_t owner_thread_id) +{ + if (!arena || !arena->backing || !runtime || !in_callback || str_is_empty(mod_id) || owner_thread_id == 0) { + return NULL; + } + + lua_overdub_unreal_context_t *context = ARENA_PUSH_ZERO(arena, lua_overdub_unreal_context_t); + if (!context) { + return NULL; + } + + context->param_arena = arena_new_dynamic(CONFIG_LUA_OVERDUB_PARAM_ARENA_RESERVE_SIZE, CONFIG_LUA_OVERDUB_PARAM_ARENA_COMMIT_SIZE); + if (!context->param_arena.backing) { + return NULL; + } + + context->arena = arena; + context->runtime = runtime; + context->in_callback = in_callback; + context->mod_id = mod_id; + context->owner_thread_id = owner_thread_id; + context->next_hook_id = 1; + context->next_delegate_id = 1; + context->next_notification_id = 1; + InitializeCriticalSection(&context->notification_lock); + + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_HOOKS; ++i) { + context->hooks[i].before_ref = LUA_NOREF; + context->hooks[i].after_ref = LUA_NOREF; + } + + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_NOTIFICATIONS; ++i) { + context->notifications[i].target = lua_overdub_unreal_invalid_weak(); + context->notifications[i].callback_ref = LUA_NOREF; + } + + lua_unreal_context_init(&context->codec); + context->codec.user = context; + context->codec.access_check = lua_overdub_unreal_access_check; + context->codec.find_object = lua_overdub_unreal_find_object; + context->codec.process_event = lua_overdub_unreal_process_event; + return context; +} + +void +lua_overdub_unreal_context_deactivate(lua_overdub_unreal_context_t *context) +{ + if (context) { + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_DELEGATE_BINDINGS; ++i) { + lua_overdub_unreal_delegate_deactivate(&context->delegate_bindings[i]); + } + + if (context->reflected_active) { + unreal_reflect_disable_owner((unreal_reflect_owner_t)(uintptr_t)context); + context->reflected_active = false; + } + } +} + +void +lua_overdub_unreal_context_destroy(lua_overdub_unreal_context_t *context) +{ + if (!context) { + return; + } + + lua_overdub_unreal_context_deactivate(context); + lua_overdub_unreal_notifications_detach(context); + + while (context->root_claims) { + lua_overdub_root_claim_t *claim = context->root_claims; + context->root_claims = claim->next; + lua_overdub_unreal_global_root_release(claim->object); + lua_overdub_unreal_mod_claim_free(context, claim); + } + + for (int i = 0; i < context->pending_hook_count; ++i) { + lua_overdub_unreal_pending_hook_destroy(&context->pending_hooks[i]); + } + + for (int i = 0; i < context->pending_func_count; ++i) { + lua_overdub_unreal_pending_func_destroy(&context->pending_funcs[i]); + } + + for (int i = 0; i < CONFIG_LUA_OVERDUB_MAX_HOOKS; ++i) { + lua_overdub_unreal_hook_deactivate(NULL, &context->hooks[i]); + } + + DeleteCriticalSection(&context->notification_lock); + arena_destroy(&context->param_arena); +} + +bool +lua_overdub_unreal_register(lua_State *state, lua_overdub_unreal_context_t *context) +{ + if (!state || !context || !lua_unreal_register_codec(state, &context->codec)) { + return false; + } + + lua_pushlightuserdata(state, &g_lua_overdub_unreal_context_key); + lua_pushlightuserdata(state, context); + lua_rawset(state, LUA_REGISTRYINDEX); + + if (!lua_unreal_object_metatable_push(state)) { + return false; + } + + static const luaL_Reg methods[] = { + {"GetName", lua_overdub_unreal_object_get_name_lua }, + {"GetPathName", lua_overdub_unreal_object_get_path_name_lua }, + {"GetInternalIndex", lua_overdub_unreal_object_get_internal_index_lua}, + {"GetFlags", lua_overdub_unreal_object_get_flags_lua }, + {"GetInternalFlags", lua_overdub_unreal_object_get_internal_flags_lua}, + {"IsRooted", lua_overdub_unreal_object_is_rooted_lua }, + {"AddToRoot", lua_overdub_unreal_object_add_to_root_lua }, + {"RemoveFromRoot", lua_overdub_unreal_object_remove_from_root_lua }, + {NULL, NULL }, + }; + + luaL_setfuncs(state, methods, 0); + lua_getfield(state, -1, "__index"); + if (!lua_isfunction(state, -1)) { + lua_pop(state, 2); + return false; + } + + lua_pushcclosure(state, lua_overdub_unreal_object_index_lua, 1); + lua_setfield(state, -2, "__index"); + lua_pop(state, 1); + lua_unreal_use_camel_case_names(state); + + if (luaL_newmetatable(state, LUA_OVERDUB_HOOK_HANDLE_META)) { + static const luaL_Reg methods[] = { + {"Remove", lua_overdub_unreal_hook_handle_remove_lua }, + {"IsActive", lua_overdub_unreal_hook_handle_is_active_lua}, + {NULL, NULL }, + }; + + luaL_setfuncs(state, methods, 0); + lua_pushvalue(state, -1); + lua_setfield(state, -2, "__index"); + lua_pushliteral(state, "Overdub Unreal Hook"); + lua_setfield(state, -2, "__metatable"); + } + lua_pop(state, 1); + + if (luaL_newmetatable(state, LUA_OVERDUB_DELEGATE_HANDLE_META)) { + static const luaL_Reg methods[] = { + {"Remove", lua_overdub_unreal_delegate_handle_remove_lua }, + {"IsActive", lua_overdub_unreal_delegate_handle_is_active_lua}, + {NULL, NULL }, + }; + + luaL_setfuncs(state, methods, 0); + lua_pushvalue(state, -1); + lua_setfield(state, -2, "__index"); + lua_pushliteral(state, "Overdub Unreal delegate binding"); + lua_setfield(state, -2, "__metatable"); + } + lua_pop(state, 1); + + if (luaL_newmetatable(state, LUA_OVERDUB_NOTIFY_HANDLE_META)) { + static const luaL_Reg methods[] = { + {"Remove", lua_overdub_unreal_notification_remove_lua }, + {"IsActive", lua_overdub_unreal_notification_is_active_lua}, + {NULL, NULL }, + }; + + luaL_setfuncs(state, methods, 0); + lua_pushvalue(state, -1); + lua_setfield(state, -2, "__index"); + lua_pushcfunction(state, lua_overdub_unreal_notification_handle_gc_lua); + lua_setfield(state, -2, "__gc"); + lua_pushliteral(state, "Overdub Unreal notification"); + lua_setfield(state, -2, "__metatable"); + } + lua_pop(state, 1); + + if (luaL_newmetatable(state, LUA_OVERDUB_CALL_META)) { + static const luaL_Reg methods[] = { + {"IsValid", lua_overdub_unreal_call_is_valid_lua }, + {"GetObject", lua_overdub_unreal_call_get_object_lua }, + {"GetFunction", lua_overdub_unreal_call_get_function_lua }, + {"GetPhase", lua_overdub_unreal_call_get_phase_lua }, + {"IsDeferred", lua_overdub_unreal_call_is_deferred_lua }, + {"IsSkipped", lua_overdub_unreal_call_is_skipped_lua }, + {"Get", lua_overdub_unreal_call_get_lua }, + {"Set", lua_overdub_unreal_call_set_lua }, + {"GetReturnValue",lua_overdub_unreal_call_get_return_lua }, + {"SetReturnValue",lua_overdub_unreal_call_set_return_lua }, + {"Skip", lua_overdub_unreal_call_skip_lua }, + {NULL, NULL }, + }; + luaL_setfuncs(state, methods, 0); + lua_pushvalue(state, -1); + lua_setfield(state, -2, "__index"); + lua_pushliteral(state, "Overdub Unreal Call"); + lua_setfield(state, -2, "__metatable"); + } + lua_pop(state, 1); + + return lua_overdub_preload_module(state, "overdub.unreal", luaopen_overdub_unreal); +} diff --git a/src/lua_overdub_worker.c b/src/lua_overdub_worker.c new file mode 100644 index 0000000..42fde94 --- /dev/null +++ b/src/lua_overdub_worker.c @@ -0,0 +1,415 @@ +#include "lua_overdub_worker.h" + +#include "config.h" +#include "log.h" +#include "lua_overdub.h" +#include "lua_runtime.h" +#include "scratch.h" + +#include "lua/src/lauxlib.h" +#include "lua/src/lua.h" + +#include +#include +#include +#include +#include + +typedef struct lua_overdub_worker_job_s lua_overdub_worker_job_t; +#define LUA_OVERDUB_WORKER_NAME_CAP (512) +struct lua_overdub_worker_job_s { + uint64_t id; + char module_name[LUA_OVERDUB_WORKER_NAME_CAP]; + char function_name[LUA_OVERDUB_WORKER_NAME_CAP]; + lua_serial_blob_t input; +}; + +struct lua_overdub_worker_context_s { + str_t mod_id; + str_t entry_path; + str_t mod_dir; + uint32_t owner_thread_id; + HANDLE thread; + HANDLE wake_event; + CRITICAL_SECTION lock; + lua_overdub_worker_job_t jobs[CONFIG_LUA_OVERDUB_MAX_WORKER_JOBS]; + lua_overdub_worker_completion_t completions[CONFIG_LUA_OVERDUB_MAX_WORKER_JOBS]; + int job_count; + int completion_count; + int outstanding_count; + uint64_t next_id; + uint64_t running_id; + bool running_cancelled; + volatile LONG stop_requested; +}; + +static void +lua_overdub_worker_error(char *error, size_t error_cap, const char *fmt, ...) +{ + if (!error || error_cap == 0) { + return; + } + + va_list args; + va_start(args, fmt); + vsnprintf(error, error_cap, fmt, args); + va_end(args); + + error[error_cap - 1] = 0; +} + +static bool +lua_overdub_worker_name_valid(str_t name) +{ + return !str_is_empty(name) && name.len < LUA_OVERDUB_WORKER_NAME_CAP && !memchr(name.data, 0, (size_t)name.len); +} + +static void +lua_overdub_worker_job_destroy(lua_overdub_worker_job_t *job) +{ + if (!job) { + return; + } + + lua_serial_blob_free(&job->input); + *job = (lua_overdub_worker_job_t){0}; +} + +void +lua_overdub_worker_completion_destroy(lua_overdub_worker_completion_t *completion) +{ + if (!completion) { + return; + } + + lua_serial_blob_free(&completion->value); + *completion = (lua_overdub_worker_completion_t){0}; +} + +static void +lua_overdub_worker_completion_error(lua_overdub_worker_completion_t *completion, const char *message) +{ + completion->result = LUA_OVERDUB_WORKER_ERROR; + snprintf(completion->error, sizeof(completion->error), "%s", message ? message : "worker job failed"); +} + +static bool +lua_overdub_worker_execute(lua_runtime_t *runtime, lua_overdub_worker_job_t *job, lua_overdub_worker_completion_t *completion) +{ + lua_State *state = runtime ? runtime->state : NULL; + if (!state) { + lua_overdub_worker_completion_error(completion, "worker Lua state is unavailable"); + return false; + } + + lua_settop(state, 0); + lua_getglobal(state, "require"); + lua_pushstring(state, job->module_name); + + char call_error[1024] = {0}; + if (!lua_runtime_pcall(runtime, 1, 1, call_error, sizeof(call_error))) { + lua_overdub_worker_completion_error(completion, call_error); + lua_settop(state, 0); + return false; + } + + if (!lua_istable(state, -1)) { + lua_overdub_worker_completion_error(completion, "worker module must return a table"); + lua_settop(state, 0); + return false; + } + + lua_getfield(state, -1, job->function_name); + if (!lua_isfunction(state, -1)) { + lua_overdub_worker_completion_error(completion, "named worker function was not found"); + lua_settop(state, 0); + return false; + } + lua_remove(state, -2); + + char codec_error[256] = {0}; + if (!lua_serial_decode(state, job->input, codec_error, sizeof(codec_error))) { + lua_overdub_worker_completion_error(completion, codec_error); + lua_settop(state, 0); + return false; + } + + if (!lua_runtime_pcall(runtime, 1, 1, call_error, sizeof(call_error))) { + lua_overdub_worker_completion_error(completion, call_error); + lua_settop(state, 0); + return false; + } + + if (!lua_serial_encode(state, -1, &completion->value, codec_error, sizeof(codec_error))) { + lua_overdub_worker_completion_error(completion, codec_error); + lua_settop(state, 0); + return false; + } + + completion->result = LUA_OVERDUB_WORKER_SUCCESS; + lua_settop(state, 0); + return true; +} + +static unsigned __stdcall +lua_overdub_worker_main(void *user) +{ + lua_overdub_worker_context_t *context = user; + lua_runtime_t runtime = {0}; + + bool runtime_ready = lua_runtime_init_with_execution_limit(&runtime, CONFIG_LUA_OVERDUB_WORKER_LIMIT_US) && + lua_runtime_enable_mod_libs(&runtime) && + lua_overdub_configure_package_paths(runtime.state, context->entry_path, context->mod_dir); + + while (!InterlockedCompareExchange(&context->stop_requested, 0, 0)) { + lua_overdub_worker_job_t job = {0}; + EnterCriticalSection(&context->lock); + if (context->job_count > 0) { + job = context->jobs[0]; + context->job_count -= 1; + if (context->job_count > 0) { + mem_move(context->jobs, context->jobs + 1, sizeof(*context->jobs) * (uint64_t)context->job_count); + } + + context->jobs[context->job_count] = (lua_overdub_worker_job_t){0}; + context->running_id = job.id; + context->running_cancelled = false; + } + LeaveCriticalSection(&context->lock); + + if (!job.id) { + WaitForSingleObject(context->wake_event, INFINITE); + continue; + } + + lua_overdub_worker_completion_t completion = {.id = job.id}; + if (runtime_ready) { + lua_overdub_worker_execute(&runtime, &job, &completion); + } else { + lua_overdub_worker_completion_error(&completion, "worker Lua state failed to initialize"); + } + + EnterCriticalSection(&context->lock); + if (context->running_cancelled) { + lua_overdub_worker_completion_destroy(&completion); + completion.id = job.id; + completion.result = LUA_OVERDUB_WORKER_CANCELLED; + } + + context->running_id = 0; + context->running_cancelled = false; + + if (!InterlockedCompareExchange(&context->stop_requested, 0, 0) && context->completion_count < CONFIG_LUA_OVERDUB_MAX_WORKER_JOBS) { + context->completions[context->completion_count++] = completion; + completion = (lua_overdub_worker_completion_t){0}; + } + LeaveCriticalSection(&context->lock); + + lua_overdub_worker_completion_destroy(&completion); + lua_overdub_worker_job_destroy(&job); + } + + lua_runtime_deinit(&runtime); + scratch_destroy(); + return 0; +} + +lua_overdub_worker_context_t * +lua_overdub_worker_context_create(arena_t *arena, str_t mod_id, str_t entry_path, str_t mod_dir, uint32_t owner_thread_id) +{ + if (!arena || !arena->backing || str_is_empty(mod_id) || str_is_empty(entry_path) || str_is_empty(mod_dir) || owner_thread_id == 0) { + return NULL; + } + + lua_overdub_worker_context_t *context = ARENA_PUSH_ZERO(arena, lua_overdub_worker_context_t); + if (!context) { + return NULL; + } + + context->mod_id = str_push_copy(arena, mod_id); + context->entry_path = str_push_copy(arena, entry_path); + context->mod_dir = str_push_copy(arena, mod_dir); + context->owner_thread_id = owner_thread_id; + context->next_id = 1; + + InitializeCriticalSection(&context->lock); + context->wake_event = CreateEventA(NULL, FALSE, FALSE, NULL); + if (str_is_empty(context->mod_id) || str_is_empty(context->entry_path) || str_is_empty(context->mod_dir) || !context->wake_event) { + lua_overdub_worker_context_destroy(context); + return NULL; + } + + return context; +} + +void +lua_overdub_worker_context_destroy(lua_overdub_worker_context_t *context) +{ + if (!context) { + return; + } + + InterlockedExchange(&context->stop_requested, 1); + if (context->wake_event) { + SetEvent(context->wake_event); + } + + if (context->thread) { + WaitForSingleObject(context->thread, INFINITE); + CloseHandle(context->thread); + } + + for (int i = 0; i < context->job_count; ++i) { + lua_overdub_worker_job_destroy(&context->jobs[i]); + } + + for (int i = 0; i < context->completion_count; ++i) { + lua_overdub_worker_completion_destroy(&context->completions[i]); + } + + if (context->wake_event) { + CloseHandle(context->wake_event); + } + + DeleteCriticalSection(&context->lock); +} + +bool +lua_overdub_worker_submit(lua_overdub_worker_context_t *context, str_t module_name, str_t function_name, + lua_serial_blob_t *input, uint64_t *out_id, char *error, size_t error_cap) +{ + if (error && error_cap > 0) { + error[0] = 0; + } + + bool valid_context = context && context->owner_thread_id == thread_current_id(); + bool valid_input = input && input->data && input->len > 0; + if (!valid_context || !valid_input || !lua_overdub_worker_name_valid(module_name) || !lua_overdub_worker_name_valid(function_name)) { + lua_overdub_worker_error(error, error_cap, "invalid worker job"); + return false; + } + + if (!context->thread) { + context->thread = (HANDLE)_beginthreadex(NULL, 0, lua_overdub_worker_main, context, 0, NULL); + if (!context->thread) { + lua_overdub_worker_error(error, error_cap, "could not start the worker thread"); + return false; + } + } + + uint64_t id = 0; + bool accepted = false; + EnterCriticalSection(&context->lock); + bool stopping = InterlockedCompareExchange(&context->stop_requested, 0, 0) != 0; + bool full = context->outstanding_count >= CONFIG_LUA_OVERDUB_MAX_WORKER_JOBS || context->job_count >= CONFIG_LUA_OVERDUB_MAX_WORKER_JOBS; + if (!stopping && !full) { + id = context->next_id++; + if (id == 0) { + id = context->next_id++; + } + + lua_overdub_worker_job_t *job = &context->jobs[context->job_count++]; + job->id = id; + job->input = *input; + mem_copy(job->module_name, module_name.data, module_name.len); + mem_copy(job->function_name, function_name.data, function_name.len); + job->module_name[module_name.len] = 0; + job->function_name[function_name.len] = 0; + + *input = (lua_serial_blob_t){0}; + context->outstanding_count += 1; + accepted = true; + } + LeaveCriticalSection(&context->lock); + + if (!accepted) { + lua_overdub_worker_error(error, error_cap, "worker job limit reached or worker is stopping"); + return false; + } + + if (out_id) { + *out_id = id; + } + + SetEvent(context->wake_event); + return true; +} + +bool +lua_overdub_worker_cancel(lua_overdub_worker_context_t *context, uint64_t id) +{ + if (!context || id == 0 || context->owner_thread_id != thread_current_id()) { + return false; + } + + bool cancelled = false; + int job_idx = -1; + lua_overdub_worker_job_t job = {0}; + + EnterCriticalSection(&context->lock); + for (int i = 0; i < context->job_count && job_idx < 0; ++i) { + if (context->jobs[i].id == id) { + job_idx = i; + } + } + + if (job_idx >= 0) { + job = context->jobs[job_idx]; + context->job_count -= 1; + if (job_idx < context->job_count) { + mem_move(&context->jobs[job_idx], &context->jobs[job_idx + 1], sizeof(*context->jobs) * (uint64_t)(context->job_count - job_idx)); + } + + context->jobs[context->job_count] = (lua_overdub_worker_job_t){0}; + context->outstanding_count = MAX_VAL(context->outstanding_count - 1, 0); + cancelled = true; + } + + if (!cancelled && context->running_id == id) { + context->running_cancelled = true; + cancelled = true; + } + + LeaveCriticalSection(&context->lock); + lua_overdub_worker_job_destroy(&job); + return cancelled; +} + +bool +lua_overdub_worker_poll(lua_overdub_worker_context_t *context, lua_overdub_worker_completion_t *out_completion) +{ + if (!context || !out_completion || context->owner_thread_id != thread_current_id()) { + return false; + } + + bool found = false; + EnterCriticalSection(&context->lock); + if (context->completion_count > 0) { + *out_completion = context->completions[0]; + + context->completion_count -= 1; + if (context->completion_count > 0) { + mem_move(context->completions, context->completions + 1, sizeof(*context->completions) * (uint64_t)context->completion_count); + } + + context->completions[context->completion_count] = (lua_overdub_worker_completion_t){0}; + context->outstanding_count = MAX_VAL(context->outstanding_count - 1, 0); + found = true; + } + + LeaveCriticalSection(&context->lock); + return found; +} + +int +lua_overdub_worker_outstanding_count(lua_overdub_worker_context_t *context) +{ + if (!context) { + return 0; + } + + EnterCriticalSection(&context->lock); + int count = context->outstanding_count; + LeaveCriticalSection(&context->lock); + return count; +} diff --git a/src/lua_runtime.c b/src/lua_runtime.c index 755acbd..bca9efe 100644 --- a/src/lua_runtime.c +++ b/src/lua_runtime.c @@ -1,13 +1,16 @@ #include "lua_runtime.h" #include "config.h" +#include "file.h" #include "log.h" +#include "scratch.h" #include "lua/src/lauxlib.h" #include "lua/src/lua.h" #include "lua/src/lualib.h" #include +#include #include static void * @@ -48,6 +51,17 @@ lua_runtime_from_state(lua_State *state) return *(lua_runtime_t **)lua_getextraspace(state); } +static uint64_t +lua_runtime_error_hash(const char *error) +{ + uint64_t hash = 14695981039346656037ULL; + for (const uint8_t *at = (const uint8_t *)(error ? error : "unknown error"); *at; ++at) { + hash ^= *at; + hash *= 1099511628211ULL; + } + return hash ? hash : 1; +} + static void lua_runtime_limit_hook(lua_State *state, lua_Debug *debug) { @@ -91,10 +105,15 @@ lua_runtime_print(lua_State *state) luaL_pushresult(&buffer); - size_t len = 0; - const char *text = lua_tolstring(state, -1, &len); - int print_len = (int)MIN_VAL(len, (size_t)INT_MAX); - CONSOLE_INFO("%.*s", print_len, text ? text : ""); + size_t len = 0; + const char *text = lua_tolstring(state, -1, &len); + int print_len = (int)MIN_VAL(len, (size_t)INT_MAX); + lua_runtime_t *runtime = lua_runtime_from_state(state); + if (runtime && runtime->persistent_output) { + LOG_INFO("%.*s", print_len, text ? text : ""); + } else { + CONSOLE_INFO("%.*s", print_len, text ? text : ""); + } return 0; } @@ -106,19 +125,19 @@ lua_runtime_set_global_nil(lua_State *state, const char *name) } static int -lua_runtime_open_libraries(lua_State *state) +lua_runtime_open_libs(lua_State *state) { - static const luaL_Reg libraries[] = { - {LUA_GNAME, luaopen_base}, - {LUA_COLIBNAME, luaopen_coroutine}, - {LUA_TABLIBNAME, luaopen_table}, - {LUA_STRLIBNAME, luaopen_string}, - {LUA_MATHLIBNAME, luaopen_math}, - {LUA_UTF8LIBNAME, luaopen_utf8}, - {NULL, NULL}, + static const luaL_Reg libs[] = { + {LUA_GNAME, luaopen_base }, + {LUA_COLIBNAME, luaopen_coroutine}, + {LUA_TABLIBNAME, luaopen_table }, + {LUA_STRLIBNAME, luaopen_string }, + {LUA_MATHLIBNAME, luaopen_math }, + {LUA_UTF8LIBNAME, luaopen_utf8 }, + {NULL, NULL }, }; - for (const luaL_Reg *lib = libraries; lib->func; ++lib) { + for (const luaL_Reg *lib = libs; lib->func; ++lib) { luaL_requiref(state, lib->name, lib->func, 1); lua_pop(state, 1); } @@ -131,8 +150,25 @@ lua_runtime_open_libraries(lua_State *state) return 0; } +static int +lua_runtime_open_mod_libs(lua_State *state) +{ + static const luaL_Reg libraries[] = { + {LUA_LOADLIBNAME, luaopen_package}, + {LUA_IOLIBNAME, luaopen_io }, + {LUA_OSLIBNAME, luaopen_os }, + {NULL, NULL }, + }; + + for (const luaL_Reg *lib = libraries; lib->func; ++lib) { + luaL_requiref(state, lib->name, lib->func, 1); + lua_pop(state, 1); + } + return 0; +} + bool -lua_runtime_init(lua_runtime_t *runtime) +lua_runtime_init_with_execution_limit(lua_runtime_t *runtime, uint64_t execution_limit_us) { if (!runtime) { return false; @@ -142,7 +178,7 @@ lua_runtime_init(lua_runtime_t *runtime) return true; } - runtime->execution_limit_us = CONFIG_LUA_EXECUTION_LIMIT_US; + runtime->execution_limit_us = execution_limit_us; runtime->memory_limit = CONFIG_LUA_MEMORY_LIMIT; runtime->state = lua_newstate(lua_runtime_alloc, runtime); if (!runtime->state) { @@ -152,7 +188,7 @@ lua_runtime_init(lua_runtime_t *runtime) *(lua_runtime_t **)lua_getextraspace(runtime->state) = runtime; - lua_pushcfunction(runtime->state, lua_runtime_open_libraries); + lua_pushcfunction(runtime->state, lua_runtime_open_libs); int status = lua_pcall(runtime->state, 0, 0, 0); if (status != LUA_OK) { const char *error = lua_tostring(runtime->state, -1); @@ -164,10 +200,40 @@ lua_runtime_init(lua_runtime_t *runtime) } runtime->inited = true; - LOG_INFO("Lua %s initialized (execution limit: %llu us, memory limit: %llu bytes)", - LUA_VERSION, - (unsigned long long)runtime->execution_limit_us, - (unsigned long long)runtime->memory_limit); + if (runtime->execution_limit_us > 0) { + LOG_INFO("Lua %s initialized (execution limit: %llu us, memory limit: %llu bytes)", + LUA_VERSION, + (unsigned long long)runtime->execution_limit_us, + (unsigned long long)runtime->memory_limit); + } else { + LOG_INFO("Lua %s initialized (execution limit: disabled, memory limit: %llu bytes)", + LUA_VERSION, + (unsigned long long)runtime->memory_limit); + } + return true; +} + +bool +lua_runtime_init(lua_runtime_t *runtime) +{ + return lua_runtime_init_with_execution_limit(runtime, CONFIG_LUA_EXECUTION_LIMIT_US); +} + +bool +lua_runtime_enable_mod_libs(lua_runtime_t *runtime) +{ + if (!runtime || !runtime->inited || !runtime->state) { + return false; + } + + lua_pushcfunction(runtime->state, lua_runtime_open_mod_libs); + int status = lua_pcall(runtime->state, 0, 0, 0); + if (status != LUA_OK) { + const char *error = lua_tostring(runtime->state, -1); + LOG_ERROR("Failed to enable Lua mod libraries: %s", error ? error : "unknown error"); + lua_pop(runtime->state, 1); + return false; + } return true; } @@ -185,7 +251,7 @@ lua_runtime_deinit(lua_runtime_t *runtime) } static int -lua_runtime_load(lua_State *state, str_t source) +lua_runtime_load_console(lua_State *state, str_t source) { static const char expression_prefix[] = "return "; @@ -207,6 +273,93 @@ lua_runtime_load(lua_State *state, str_t source) return luaL_loadbufferx(state, (const char *)source.data, source.len, "=console", "t"); } +static bool +lua_runtime_call_loaded(lua_runtime_t *runtime, bool print_results, bool persistent_errors) +{ + lua_State *state = runtime->state; + int function_idx = lua_gettop(state); + + lua_pushcfunction(state, lua_runtime_traceback); + lua_insert(state, function_idx); + + if (runtime->execution_limit_us > 0) { + runtime->execution_deadline_us = time_now_us() + runtime->execution_limit_us; + lua_sethook(state, lua_runtime_limit_hook, LUA_MASKCOUNT, CONFIG_LUA_HOOK_INSTRUCTION_COUNT); + } else { + lua_sethook(state, NULL, 0, 0); + } + + int status = lua_pcall(state, 0, LUA_MULTRET, function_idx); + if (status == LUA_OK) { + int result_count = lua_gettop(state) - function_idx; + lua_remove(state, function_idx); + + if (print_results && result_count > 0) { + lua_pushcfunction(state, lua_runtime_print); + lua_insert(state, 1); + status = lua_pcall(state, result_count, 0, 0); + } + } + + lua_sethook(state, NULL, 0, 0); + + if (status != LUA_OK) { + const char *error = lua_tostring(state, -1); + if (persistent_errors) { + LOG_ERROR("Lua error: %s", error ? error : "unknown error"); + } else { + CONSOLE_ERROR("Lua error: %s", error ? error : "unknown error"); + } + lua_settop(state, 0); + return false; + } + + lua_settop(state, 0); + return true; +} + +static bool +lua_runtime_call_loaded_results(lua_runtime_t *runtime, int result_count, bool persistent_errors) +{ + if (!runtime || !runtime->state || result_count < 0) { + return false; + } + + lua_State *state = runtime->state; + int function_idx = lua_gettop(state); + if (!lua_isfunction(state, function_idx)) { + lua_settop(state, 0); + return false; + } + + lua_pushcfunction(state, lua_runtime_traceback); + lua_insert(state, function_idx); + + if (runtime->execution_limit_us > 0) { + runtime->execution_deadline_us = time_now_us() + runtime->execution_limit_us; + lua_sethook(state, lua_runtime_limit_hook, LUA_MASKCOUNT, CONFIG_LUA_HOOK_INSTRUCTION_COUNT); + } else { + lua_sethook(state, NULL, 0, 0); + } + + int status = lua_pcall(state, 0, result_count, function_idx); + lua_sethook(state, NULL, 0, 0); + + if (status != LUA_OK) { + const char *error = lua_tostring(state, -1); + if (persistent_errors) { + LOG_ERROR("Lua error: %s", error ? error : "unknown error"); + } else { + CONSOLE_ERROR("Lua error: %s", error ? error : "unknown error"); + } + lua_settop(state, 0); + return false; + } + + lua_remove(state, function_idx); // traceback function + return true; +} + bool lua_runtime_execute(lua_runtime_t *runtime, str_t source) { @@ -218,7 +371,7 @@ lua_runtime_execute(lua_runtime_t *runtime, str_t source) lua_State *state = runtime->state; lua_settop(state, 0); - int status = lua_runtime_load(state, source); + int status = lua_runtime_load_console(state, source); if (status != LUA_OK) { const char *error = lua_tostring(state, -1); CONSOLE_ERROR("Lua syntax error: %s", error ? error : "unknown error"); @@ -226,33 +379,239 @@ lua_runtime_execute(lua_runtime_t *runtime, str_t source) return false; } - lua_pushcfunction(state, lua_runtime_traceback); - lua_insert(state, 1); + return lua_runtime_call_loaded(runtime, true, false); +} + +bool +lua_runtime_execute_file(lua_runtime_t *runtime, str_t path) +{ + if (!runtime || !runtime->inited || !runtime->state || !file_exists(path)) { + return false; + } - runtime->execution_deadline_us = time_now_us() + runtime->execution_limit_us; - lua_sethook(state, lua_runtime_limit_hook, LUA_MASKCOUNT, CONFIG_LUA_HOOK_INSTRUCTION_COUNT); + lua_State *state = runtime->state; + int status = 0; + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t source = file_read_all(path, tmp.arena); + lua_settop(state, 0); - status = lua_pcall(state, 0, LUA_MULTRET, 1); - if (status == LUA_OK) { - int result_count = lua_gettop(state) - 1; // exclude traceback handler - lua_remove(state, 1); + lua_pushliteral(state, "@"); + lua_pushlstring(state, (const char *)path.data, (size_t)path.len); + lua_concat(state, 2); - if (result_count > 0) { - lua_pushcfunction(state, lua_runtime_print); - lua_insert(state, 1); - status = lua_pcall(state, result_count, 0, 0); - } + const char *chunk_name = lua_tostring(state, -1); + const char *source_data = source.data ? (const char *)source.data : ""; + + status = luaL_loadbufferx(state, source_data, (size_t)source.len, chunk_name, "t"); + lua_remove(state, -2); // chunk name } + scratch_end(tmp); - lua_sethook(state, NULL, 0, 0); + if (status != LUA_OK) { + const char *error = lua_tostring(state, -1); + LOG_ERROR("Lua syntax error: %s", error ? error : "unknown error"); + lua_settop(state, 0); + return false; + } + + return lua_runtime_call_loaded(runtime, false, true); +} + +bool +lua_runtime_execute_file_results(lua_runtime_t *runtime, str_t path, int result_count) +{ + if (!runtime || !runtime->inited || !runtime->state || result_count < 0 || !file_exists(path)) { + return false; + } + + lua_State *state = runtime->state; + int status = 0; + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t source = file_read_all(path, tmp.arena); + lua_settop(state, 0); + + lua_pushliteral(state, "@"); + lua_pushlstring(state, (const char *)path.data, (size_t)path.len); + lua_concat(state, 2); + + const char *chunk_name = lua_tostring(state, -1); + const char *source_data = source.data ? (const char *)source.data : ""; + + status = luaL_loadbufferx(state, source_data, (size_t)source.len, chunk_name, "t"); + lua_remove(state, -2); // chunk name + } + scratch_end(tmp); if (status != LUA_OK) { const char *error = lua_tostring(state, -1); - CONSOLE_ERROR("Lua error: %s", error ? error : "unknown error"); + LOG_ERROR("Lua syntax error: %s", error ? error : "unknown error"); lua_settop(state, 0); return false; } - lua_settop(state, 0); + return lua_runtime_call_loaded_results(runtime, result_count, true); +} + +bool +lua_runtime_call_ref(lua_runtime_t *runtime, int callback_ref, int arg_count, int result_count) +{ + return lua_runtime_call_ref_ex(runtime, callback_ref, arg_count, result_count, true, 0, NULL); +} + +bool +lua_runtime_pcall(lua_runtime_t *runtime, int arg_count, int result_count, char *error, size_t error_cap) +{ + if (error && error_cap > 0) { + error[0] = 0; + } + + if (!runtime || !runtime->inited || !runtime->state || arg_count < 0 || result_count < 0) { + return false; + } + + lua_State *state = runtime->state; + int top = lua_gettop(state); + int function_idx = top - arg_count; + if (function_idx < 1 || !lua_isfunction(state, function_idx)) { + return false; + } + + lua_pushcfunction(state, lua_runtime_traceback); + lua_insert(state, function_idx); + + lua_Hook previous_hook = lua_gethook(state); + int previous_hook_mask = lua_gethookmask(state); + int previous_hook_count = lua_gethookcount(state); + uint64_t previous_deadline = runtime->execution_deadline_us; + + if (runtime->execution_limit_us > 0) { + runtime->execution_deadline_us = time_now_us() + runtime->execution_limit_us; + lua_sethook(state, lua_runtime_limit_hook, LUA_MASKCOUNT, CONFIG_LUA_HOOK_INSTRUCTION_COUNT); + } else { + lua_sethook(state, NULL, 0, 0); + } + + int status = lua_pcall(state, arg_count, result_count, function_idx); + runtime->execution_deadline_us = previous_deadline; + lua_sethook(state, previous_hook, previous_hook_mask, previous_hook_count); + + if (status != LUA_OK) { + const char *message = lua_tostring(state, -1); + if (error && error_cap > 0) { + snprintf(error, error_cap, "%s", message ? message : "unknown Lua error"); + error[error_cap - 1] = 0; + } + + lua_settop(state, function_idx - 1); + return false; + } + + lua_remove(state, function_idx); /* traceback function */ + return true; +} + +bool +lua_runtime_call_ref_ex(lua_runtime_t *runtime, int callback_ref, int arg_count, int result_count, bool log_error, + uint64_t suppressed_error_hash, uint64_t *out_error_hash) +{ + if (out_error_hash) { + *out_error_hash = 0; + } + + if (!runtime || !runtime->inited || !runtime->state || callback_ref == LUA_NOREF || callback_ref == LUA_REFNIL || arg_count < 0) { + return false; + } + + lua_State *state = runtime->state; + int top = lua_gettop(state); + if (arg_count > top) { + return false; + } + + int base = top - arg_count + 1; + lua_pushcfunction(state, lua_runtime_traceback); + lua_insert(state, base); + lua_rawgeti(state, LUA_REGISTRYINDEX, callback_ref); + lua_insert(state, base + 1); + + lua_Hook previous_hook = lua_gethook(state); + int previous_hook_mask = lua_gethookmask(state); + int previous_hook_count = lua_gethookcount(state); + uint64_t previous_deadline = runtime->execution_deadline_us; + + if (runtime->execution_limit_us > 0) { + runtime->execution_deadline_us = time_now_us() + runtime->execution_limit_us; + lua_sethook(state, lua_runtime_limit_hook, LUA_MASKCOUNT, CONFIG_LUA_HOOK_INSTRUCTION_COUNT); + } else { + lua_sethook(state, NULL, 0, 0); + } + + int status = lua_pcall(state, arg_count, result_count, base); + runtime->execution_deadline_us = previous_deadline; + lua_sethook(state, previous_hook, previous_hook_mask, previous_hook_count); + + if (status != LUA_OK) { + const char *error = lua_tostring(state, -1); + uint64_t error_hash = lua_runtime_error_hash(error); + if (out_error_hash) { + *out_error_hash = error_hash; + } + + if (log_error && error_hash != suppressed_error_hash) { + LOG_ERROR("Lua error: %s", error ? error : "unknown error"); + } + + lua_settop(state, base - 1); + return false; + } + + lua_remove(state, base); // traceback function return true; } + +int +lua_runtime_resume(lua_runtime_t *runtime, lua_State *thread, int arg_count, int *result_count) +{ + if (result_count) { + *result_count = 0; + } + + if (!runtime || !runtime->inited || !runtime->state || !thread || arg_count < 0) { + return LUA_ERRRUN; + } + + lua_Hook previous_hook = lua_gethook(thread); + int previous_hook_mask = lua_gethookmask(thread); + int previous_hook_count = lua_gethookcount(thread); + uint64_t previous_deadline = runtime->execution_deadline_us; + + if (runtime->execution_limit_us > 0) { + runtime->execution_deadline_us = time_now_us() + runtime->execution_limit_us; + lua_sethook(thread, lua_runtime_limit_hook, LUA_MASKCOUNT, CONFIG_LUA_HOOK_INSTRUCTION_COUNT); + } else { + lua_sethook(thread, NULL, 0, 0); + } + + int yielded_results = 0; + int status = lua_resume(thread, runtime->state, arg_count, &yielded_results); + + runtime->execution_deadline_us = previous_deadline; + lua_sethook(thread, previous_hook, previous_hook_mask, previous_hook_count); + + if (result_count) { + *result_count = yielded_results; + } + + if (status != LUA_OK && status != LUA_YIELD) { + const char *error = lua_tostring(thread, -1); + luaL_traceback(runtime->state, thread, error ? error : "unknown coroutine error", 1); + + const char *traceback = lua_tostring(runtime->state, -1); + LOG_ERROR("Lua task error: %s", traceback ? traceback : (error ? error : "unknown error")); + lua_pop(runtime->state, 1); + lua_settop(thread, 0); + } + return status; +} diff --git a/src/lua_serial.c b/src/lua_serial.c new file mode 100644 index 0000000..1da9eaa --- /dev/null +++ b/src/lua_serial.c @@ -0,0 +1,397 @@ +#include "lua_serial.h" + +#include "lua/src/lauxlib.h" +#include "lua/src/lua.h" + +#include +#include +#include +#include + +#define LUA_SERIAL_MAX_BYTES (4 * MB) +#define LUA_SERIAL_MAX_DEPTH (32) +#define LUA_SERIAL_MAX_ENTRIES (64 * 1024) + +typedef uint8_t lua_serial_tag_t; +enum { + LUA_SERIAL_NIL = 0, + LUA_SERIAL_FALSE, + LUA_SERIAL_TRUE, + LUA_SERIAL_INTEGER, + LUA_SERIAL_NUMBER, + LUA_SERIAL_STRING, + LUA_SERIAL_TABLE, +}; + +typedef struct lua_serial_writer_s lua_serial_writer_t; +struct lua_serial_writer_s { + lua_serial_blob_t blob; + uint64_t cap; + const void *tables[LUA_SERIAL_MAX_DEPTH]; + int table_count; + char *error; + size_t error_cap; +}; + +typedef struct lua_serial_reader_s lua_serial_reader_t; +struct lua_serial_reader_s { + lua_serial_blob_t blob; + uint64_t offset; + char *error; + size_t error_cap; +}; + +static void +lua_serial_error(char *error, size_t error_cap, const char *fmt, ...) +{ + if (!error || error_cap == 0 || error[0]) { + return; + } + + va_list args; + va_start(args, fmt); + vsnprintf(error, error_cap, fmt, args); + va_end(args); + + error[error_cap - 1] = 0; +} + +void +lua_serial_blob_free(lua_serial_blob_t *blob) +{ + if (!blob) { + return; + } + + if (blob->data) { + HeapFree(GetProcessHeap(), 0, blob->data); + } + *blob = (lua_serial_blob_t){0}; +} + +static bool +lua_serial_writer_reserve(lua_serial_writer_t *writer, uint64_t additional) +{ + if (!writer || additional > LUA_SERIAL_MAX_BYTES || writer->blob.len > LUA_SERIAL_MAX_BYTES - additional) { + lua_serial_error(writer ? writer->error : NULL, writer ? writer->error_cap : 0, + "serialized value exceeds the %llu-byte limit", (unsigned long long)LUA_SERIAL_MAX_BYTES); + return false; + } + + uint64_t required = writer->blob.len + additional; + if (required <= writer->cap) { + return true; + } + + uint64_t new_cap = writer->cap ? writer->cap : 256; + while (new_cap < required) { + new_cap = MIN_VAL(new_cap * 2, (uint64_t)LUA_SERIAL_MAX_BYTES); + if (new_cap < required && new_cap == LUA_SERIAL_MAX_BYTES) { + return false; + } + } + + void *data = writer->blob.data ? HeapReAlloc(GetProcessHeap(), 0, writer->blob.data, (SIZE_T)new_cap) : HeapAlloc(GetProcessHeap(), 0, (SIZE_T)new_cap); + if (!data) { + lua_serial_error(writer->error, writer->error_cap, "could not allocate serialized value storage"); + return false; + } + + writer->blob.data = data; + writer->cap = new_cap; + return true; +} + +static bool +lua_serial_writer_write(lua_serial_writer_t *writer, const void *data, uint64_t size) +{ + if (!lua_serial_writer_reserve(writer, size)) { + return false; + } + + if (size > 0) { + memcpy(writer->blob.data + writer->blob.len, data, (size_t)size); + } + + writer->blob.len += size; + return true; +} + +static bool +lua_serial_writer_tag(lua_serial_writer_t *writer, lua_serial_tag_t tag) +{ + return lua_serial_writer_write(writer, &tag, sizeof(tag)); +} + +static bool lua_serial_encode_value(lua_State *state, int idx, lua_serial_writer_t *writer, int depth); + +static bool +lua_serial_encode_table(lua_State *state, int idx, lua_serial_writer_t *writer, int depth) +{ + if (depth >= LUA_SERIAL_MAX_DEPTH) { + lua_serial_error(writer->error, writer->error_cap, "table nesting exceeds the %d-level limit", LUA_SERIAL_MAX_DEPTH); + return false; + } + + if (lua_getmetatable(state, idx)) { + lua_pop(state, 1); + lua_serial_error(writer->error, writer->error_cap, "tables with metatables cannot cross a worker boundary"); + return false; + } + + const void *identity = lua_topointer(state, idx); + for (int i = 0; i < writer->table_count; ++i) { + if (writer->tables[i] == identity) { + lua_serial_error(writer->error, writer->error_cap, "cyclic tables cannot cross a worker boundary"); + return false; + } + } + + uint32_t count = 0; + idx = lua_absindex(state, idx); + lua_pushnil(state); + while (lua_next(state, idx)) { + lua_pop(state, 1); + if (count == LUA_SERIAL_MAX_ENTRIES) { + lua_pop(state, 1); + lua_serial_error(writer->error, writer->error_cap, "table exceeds the %u-entry limit", LUA_SERIAL_MAX_ENTRIES); + return false; + } + count += 1; + } + + if (!lua_serial_writer_tag(writer, LUA_SERIAL_TABLE) || !lua_serial_writer_write(writer, &count, sizeof(count))) { + return false; + } + + writer->tables[writer->table_count++] = identity; + bool encoded = true; + lua_pushnil(state); + while (encoded && lua_next(state, idx)) { + int key_type = lua_type(state, -2); + if (!((key_type == LUA_TNUMBER && lua_isinteger(state, -2)) || key_type == LUA_TSTRING)) { + lua_serial_error(writer->error, writer->error_cap, "worker table keys must be strings or integers"); + encoded = false; + } else { + encoded = lua_serial_encode_value(state, -2, writer, depth + 1) && lua_serial_encode_value(state, -1, writer, depth + 1); + } + lua_pop(state, 1); + } + + if (!encoded && lua_gettop(state) >= idx + 1) { + lua_pop(state, 1); + } + + writer->table_count -= 1; + return encoded; +} + +static bool +lua_serial_encode_value(lua_State *state, int idx, lua_serial_writer_t *writer, int depth) +{ + switch (lua_type(state, idx)) { + case LUA_TNIL: { + return lua_serial_writer_tag(writer, LUA_SERIAL_NIL); + } + + case LUA_TBOOLEAN: { + return lua_serial_writer_tag(writer, lua_toboolean(state, idx) ? LUA_SERIAL_TRUE : LUA_SERIAL_FALSE); + } + + case LUA_TNUMBER: { + if (lua_isinteger(state, idx)) { + lua_Integer value = lua_tointeger(state, idx); + return lua_serial_writer_tag(writer, LUA_SERIAL_INTEGER) && lua_serial_writer_write(writer, &value, sizeof(value)); + } else { + lua_Number value = lua_tonumber(state, idx); + return lua_serial_writer_tag(writer, LUA_SERIAL_NUMBER) && lua_serial_writer_write(writer, &value, sizeof(value)); + } + } + + case LUA_TSTRING: { + size_t len = 0; + const char *data = lua_tolstring(state, idx, &len); + if (len > UINT32_MAX) { + lua_serial_error(writer->error, writer->error_cap, "string is too large for a worker value"); + return false; + } + + uint32_t encoded_len = (uint32_t)len; + return lua_serial_writer_tag(writer, LUA_SERIAL_STRING) && lua_serial_writer_write(writer, &encoded_len, sizeof(encoded_len)) && lua_serial_writer_write(writer, data, encoded_len); + } + + case LUA_TTABLE: { + return lua_serial_encode_table(state, idx, writer, depth); + } + + default: { + lua_serial_error(writer->error, writer->error_cap, "%s values cannot cross a worker boundary", lua_typename(state, lua_type(state, idx))); + return false; + } + } +} + +bool +lua_serial_encode(lua_State *state, int value_idx, lua_serial_blob_t *out_blob, char *error, size_t error_cap) +{ + if (error && error_cap > 0) { + error[0] = 0; + } + + if (!state || !out_blob) { + lua_serial_error(error, error_cap, "invalid serializer arguments"); + return false; + } + + *out_blob = (lua_serial_blob_t){0}; + lua_serial_writer_t writer = { + .error = error, + .error_cap = error_cap, + }; + + if (!lua_serial_encode_value(state, value_idx, &writer, 0)) { + lua_serial_blob_free(&writer.blob); + return false; + } + + *out_blob = writer.blob; + return true; +} + +static bool +lua_serial_reader_read(lua_serial_reader_t *reader, void *out, uint64_t size) +{ + if (!reader || size > reader->blob.len || reader->offset > reader->blob.len - size) { + lua_serial_error(reader ? reader->error : NULL, reader ? reader->error_cap : 0, "serialized worker value is truncated"); + return false; + } + + if (size > 0 && out) { + mem_copy(out, reader->blob.data + reader->offset, size); + } + + reader->offset += size; + return true; +} + +static bool +lua_serial_decode_value(lua_State *state, lua_serial_reader_t *reader, int depth) +{ + lua_serial_tag_t tag = 0; + if (!lua_serial_reader_read(reader, &tag, sizeof(tag))) { + return false; + } + + switch (tag) { + case LUA_SERIAL_NIL: { + lua_pushnil(state); + return true; + } + + case LUA_SERIAL_FALSE: { + lua_pushboolean(state, false); + return true; + } + + case LUA_SERIAL_TRUE: { + lua_pushboolean(state, true); + return true; + } + + case LUA_SERIAL_INTEGER: { + lua_Integer value = 0; + if (!lua_serial_reader_read(reader, &value, sizeof(value))) { + return false; + } + + lua_pushinteger(state, value); + return true; + } + + case LUA_SERIAL_NUMBER: { + lua_Number value = 0; + if (!lua_serial_reader_read(reader, &value, sizeof(value))) { + return false; + } + + lua_pushnumber(state, value); + return true; + } + + case LUA_SERIAL_STRING: { + uint32_t len = 0; + if (!lua_serial_reader_read(reader, &len, sizeof(len)) || (uint64_t)len > reader->blob.len || reader->offset > reader->blob.len - (uint64_t)len) { + lua_serial_error(reader->error, reader->error_cap, "serialized worker string is truncated"); + return false; + } + + lua_pushlstring(state, (const char *)reader->blob.data + reader->offset, len); + reader->offset += len; + return true; + } + + case LUA_SERIAL_TABLE: { + if (depth >= LUA_SERIAL_MAX_DEPTH) { + lua_serial_error(reader->error, reader->error_cap, "serialized worker table is nested too deeply"); + return false; + } + + uint32_t count = 0; + if (!lua_serial_reader_read(reader, &count, sizeof(count)) || count > LUA_SERIAL_MAX_ENTRIES) { + lua_serial_error(reader->error, reader->error_cap, "serialized worker table has an invalid entry count"); + return false; + } + + lua_createtable(state, 0, (int)MIN_VAL(count, (uint32_t)INT32_MAX)); + for (uint32_t i = 0; i < count; ++i) { + if (!lua_serial_decode_value(state, reader, depth + 1) || !lua_serial_decode_value(state, reader, depth + 1)) { + lua_pop(state, 1); + return false; + } + + if (!((lua_type(state, -2) == LUA_TNUMBER && lua_isinteger(state, -2)) || lua_type(state, -2) == LUA_TSTRING)) { + lua_pop(state, 3); + lua_serial_error(reader->error, reader->error_cap, "serialized worker table contains an invalid key"); + return false; + } + + lua_rawset(state, -3); + } + return true; + } + + default: { + lua_serial_error(reader->error, reader->error_cap, "serialized worker value has an unknown type tag"); + return false; + } + } +} + +bool +lua_serial_decode(lua_State *state, lua_serial_blob_t blob, char *error, size_t error_cap) +{ + if (error && error_cap > 0) { + error[0] = 0; + } + + if (!state || !blob.data || blob.len == 0) { + lua_serial_error(error, error_cap, "serialized worker value is empty"); + return false; + } + + int stack_base = lua_gettop(state); + lua_serial_reader_t reader = { + .blob = blob, + .error = error, + .error_cap = error_cap, + }; + + if (!lua_serial_decode_value(state, &reader, 0) || reader.offset != blob.len) { + lua_settop(state, stack_base); + if (reader.offset != blob.len) { + lua_serial_error(error, error_cap, "serialized worker value contains trailing data"); + } + return false; + } + return true; +} diff --git a/src/lua_ue4ss.c b/src/lua_ue4ss.c new file mode 100644 index 0000000..4fa3182 --- /dev/null +++ b/src/lua_ue4ss.c @@ -0,0 +1,2120 @@ +#include "lua_ue4ss.h" + +#include "config.h" +#include "file.h" +#include "globals.h" +#include "log.h" +#include "path.h" +#include "scratch.h" + +#include "lua/src/lauxlib.h" +#include "lua/src/lua.h" + +#include +#include + +#define LUA_UE4SS_DIRECTORY_MAX_DEPTH (6) +#define LUA_UE4SS_DIRECTORY_MAX_NODES (2048) + +static const char g_lua_ue4ss_context_registry_key = 0; +static const char g_lua_ue4ss_shared_registry_key = 0; + +static bool lua_ue4ss_pending_lock (lua_ue4ss_context_t *context); +static void lua_ue4ss_pending_unlock (lua_ue4ss_context_t *context); +static void lua_ue4ss_pending_hook_destroy (lua_ue4ss_pending_hook_t *pending); +static void lua_ue4ss_dispatch_pending_hooks (lua_ue4ss_context_t *context); +static void lua_ue4ss_dispatch_pending_inputs (lua_ue4ss_context_t *context); +static void lua_ue4ss_dispatch_pending_commands(lua_ue4ss_context_t *context); +static void lua_ue4ss_dispatch_keybinds (lua_ue4ss_context_t *context, input_event_t *ev); +static void lua_ue4ss_dispatch_process_event (lua_ue4ss_context_t *context, uobject_t *obj, ufunc_t *func, void *params, bool post); + +static const char *g_lua_ue4ss_key_constants[256] = { + [0x01] = "LEFT_MOUSE_BUTTON", + [0x02] = "RIGHT_MOUSE_BUTTON", + [0x04] = "MIDDLE_MOUSE_BUTTON", + [0x05] = "XBUTTON_ONE", + [0x06] = "XBUTTON_TWO", + [0x08] = "BACKSPACE", + [0x09] = "TAB", + [0x0D] = "RETURN", + [0x13] = "PAUSE", + [0x14] = "CAPS_LOCK", + [0x1B] = "ESCAPE", + [0x20] = "SPACE", + [0x21] = "PAGE_UP", + [0x22] = "PAGE_DOWN", + [0x23] = "END", + [0x24] = "HOME", + [0x25] = "LEFT_ARROW", + [0x26] = "UP_ARROW", + [0x27] = "RIGHT_ARROW", + [0x28] = "DOWN_ARROW", + [0x2C] = "PRINT_SCREEN", + [0x2D] = "INS", + [0x2E] = "DEL", + [0x30] = "ZERO", + [0x31] = "ONE", + [0x32] = "TWO", + [0x33] = "THREE", + [0x34] = "FOUR", + [0x35] = "FIVE", + [0x36] = "SIX", + [0x37] = "SEVEN", + [0x38] = "EIGHT", + [0x39] = "NINE", + [0x41] = "A", + [0x42] = "B", + [0x43] = "C", + [0x44] = "D", + [0x45] = "E", + [0x46] = "F", + [0x47] = "G", + [0x48] = "H", + [0x49] = "I", + [0x4A] = "J", + [0x4B] = "K", + [0x4C] = "L", + [0x4D] = "M", + [0x4E] = "N", + [0x4F] = "O", + [0x50] = "P", + [0x51] = "Q", + [0x52] = "R", + [0x53] = "S", + [0x54] = "T", + [0x55] = "U", + [0x56] = "V", + [0x57] = "W", + [0x58] = "X", + [0x59] = "Y", + [0x5A] = "Z", + [0x60] = "NUM_ZERO", + [0x61] = "NUM_ONE", + [0x62] = "NUM_TWO", + [0x63] = "NUM_THREE", + [0x64] = "NUM_FOUR", + [0x65] = "NUM_FIVE", + [0x66] = "NUM_SIX", + [0x67] = "NUM_SEVEN", + [0x68] = "NUM_EIGHT", + [0x69] = "NUM_NINE", + [0x6A] = "MULTIPLY", + [0x6B] = "ADD", + [0x6D] = "SUBTRACT", + [0x6E] = "DECIMAL", + [0x6F] = "DIVIDE", + [0x70] = "F1", + [0x71] = "F2", + [0x72] = "F3", + [0x73] = "F4", + [0x74] = "F5", + [0x75] = "F6", + [0x76] = "F7", + [0x77] = "F8", + [0x78] = "F9", + [0x79] = "F10", + [0x7A] = "F11", + [0x7B] = "F12", + [0x90] = "NUM_LOCK", + [0x91] = "SCROLL_LOCK", + [0xBA] = "OEM_ONE", + [0xBB] = "OEM_PLUS", + [0xBC] = "OEM_COMMA", + [0xBD] = "OEM_MINUS", + [0xBE] = "OEM_PERIOD", + [0xBF] = "OEM_TWO", + [0xC0] = "OEM_THREE", + [0xDB] = "OEM_FOUR", + [0xDC] = "OEM_FIVE", + [0xDD] = "OEM_SIX", + [0xDE] = "OEM_SEVEN", +}; + +static lua_ue4ss_context_t * +lua_ue4ss_context_from_state(lua_State *state) +{ + lua_rawgetp(state, LUA_REGISTRYINDEX, &g_lua_ue4ss_context_registry_key); + lua_ue4ss_context_t *context = (lua_ue4ss_context_t *)lua_touserdata(state, -1); + lua_pop(state, 1); + return context; +} + +bool +lua_ue4ss_context_init(lua_ue4ss_context_t *context, arena_t *arena, lua_runtime_t *runtime) +{ + if (!context || !arena || !runtime) { + return false; + } + + context->arena = arena; + context->runtime = runtime; + context->commands = ARENA_PUSH_ARRAY_ZERO(arena, lua_ue4ss_command_t, CONFIG_LUA_UE4SS_MAX_COMMANDS); + context->command_count = 0; + context->keybinds = ARENA_PUSH_ARRAY_ZERO(arena, lua_ue4ss_keybind_t, CONFIG_LUA_UE4SS_MAX_KEYBINDS); + context->keybind_count = 0; + context->hooks = ARENA_PUSH_ARRAY_ZERO(arena, lua_ue4ss_hook_t, CONFIG_LUA_UE4SS_MAX_HOOKS); + context->hook_count = 0; + context->next_hook_id = 1; + context->notifications = ARENA_PUSH_ARRAY_ZERO(arena, lua_ue4ss_notification_t, CONFIG_LUA_UE4SS_MAX_NOTIFICATIONS); + context->notification_count = 0; + context->pending_objects = ARENA_PUSH_ARRAY_ZERO(arena, lua_ue4ss_pending_object_t, CONFIG_LUA_UE4SS_MAX_PENDING_OBJECTS); + context->pending_object_count = 0; + context->pending_hooks = ARENA_PUSH_ARRAY_ZERO(arena, lua_ue4ss_pending_hook_t, CONFIG_LUA_UE4SS_MAX_PENDING_HOOKS); + context->pending_hook_count = 0; + context->pending_inputs = ARENA_PUSH_ARRAY_ZERO(arena, input_event_t, CONFIG_LUA_UE4SS_MAX_PENDING_INPUTS); + context->pending_input_count = 0; + context->pending_commands = ARENA_PUSH_ARRAY_ZERO(arena, lua_ue4ss_pending_command_t, CONFIG_LUA_UE4SS_MAX_PENDING_COMMANDS); + context->pending_command_count = 0; + context->pending_lock = 0; + context->pending_overflow = false; + context->pending_hook_overflow = false; + context->pending_input_overflow = false; + context->pending_command_overflow = false; + context->async_events = false; + context->scheduled_jobs = ARENA_PUSH_ARRAY_ZERO(arena, lua_ue4ss_scheduled_job_t, CONFIG_LUA_UE4SS_MAX_SCHEDULED_JOBS); + context->scheduled_job_count = 0; + context->next_action_handle = 1; + context->scheduler_tick = 0; + context->async_scheduler_tick = 0; + context->wake_async = NULL; + context->wake_async_user = NULL; + + return context->commands && + context->keybinds && + context->hooks && + context->notifications && + context->pending_objects && + context->pending_hooks && + context->pending_inputs && + context->pending_commands && + context->scheduled_jobs; +} + +void +lua_ue4ss_context_deinit(lua_ue4ss_context_t *context) +{ + if (!context) { + return; + } + + lua_State *state = context->runtime && context->runtime->inited ? context->runtime->state : NULL; + if (state) { + for (int i = 0; i < context->command_count; ++i) { + int callback_ref = context->commands[i].callback_ref; + if (callback_ref != LUA_NOREF && callback_ref != LUA_REFNIL) { + luaL_unref(state, LUA_REGISTRYINDEX, callback_ref); + } + } + + for (int i = 0; i < context->keybind_count; ++i) { + int callback_ref = context->keybinds[i].callback_ref; + if (callback_ref != LUA_NOREF && callback_ref != LUA_REFNIL) { + luaL_unref(state, LUA_REGISTRYINDEX, callback_ref); + } + } + + for (int i = 0; i < context->hook_count; ++i) { + lua_ue4ss_hook_t *hook = &context->hooks[i]; + if (hook->pre_callback_ref != LUA_NOREF && hook->pre_callback_ref != LUA_REFNIL) { + luaL_unref(state, LUA_REGISTRYINDEX, hook->pre_callback_ref); + } + + if (hook->post_callback_ref != LUA_NOREF && hook->post_callback_ref != LUA_REFNIL) { + luaL_unref(state, LUA_REGISTRYINDEX, hook->post_callback_ref); + } + } + + for (int i = 0; i < context->notification_count; ++i) { + int callback_ref = context->notifications[i].callback_ref; + if (callback_ref != LUA_NOREF && callback_ref != LUA_REFNIL) { + luaL_unref(state, LUA_REGISTRYINDEX, callback_ref); + } + } + + if (context->scheduled_jobs) { + for (int i = 0; i < CONFIG_LUA_UE4SS_MAX_SCHEDULED_JOBS; ++i) { + lua_ue4ss_scheduled_job_t *job = &context->scheduled_jobs[i]; + if (job->active && job->callback_ref != LUA_NOREF && job->callback_ref != LUA_REFNIL) { + luaL_unref(state, LUA_REGISTRYINDEX, job->callback_ref); + } + } + } + } + + context->command_count = 0; + context->keybind_count = 0; + context->hook_count = 0; + context->notification_count = 0; + context->pending_object_count = 0; + + for (int i = 0; i < context->pending_hook_count; ++i) { + lua_ue4ss_pending_hook_destroy(&context->pending_hooks[i]); + } + + context->pending_hook_count = 0; + context->pending_input_count = 0; + + for (int i = 0; i < context->pending_command_count; ++i) { + free(context->pending_commands[i].data); + context->pending_commands[i] = (lua_ue4ss_pending_command_t){0}; + } + + context->pending_command_count = 0; + context->scheduled_job_count = 0; +} + +static input_key_kind_t +lua_ue4ss_key_from_vk(lua_Integer value) +{ + if (value >= 0x41 && value <= 0x5A) { + return (input_key_kind_t)(INPUT_KEY_A + value - 0x41); + } + + if (value >= 0x31 && value <= 0x39) { + return (input_key_kind_t)(INPUT_KEY_1 + value - 0x31); + } + + if (value == 0x30) { + return INPUT_KEY_0; + } + + if (value >= 0x70 && value <= 0x7B) { + return (input_key_kind_t)(INPUT_KEY_F1 + value - 0x70); + } + + if (value >= 0x60 && value <= 0x69) { + return (input_key_kind_t)(INPUT_KEY_NUM_0 + value - 0x60); + } + + switch (value) { + case 0x01: return INPUT_KEY_MOUSE_LEFT; + case 0x02: return INPUT_KEY_MOUSE_RIGHT; + case 0x04: return INPUT_KEY_MOUSE_MIDDLE; + case 0x05: return INPUT_KEY_MOUSE_THUMB_1; + case 0x06: return INPUT_KEY_MOUSE_THUMB_2; + case 0x08: return INPUT_KEY_BACKSPACE; + case 0x09: return INPUT_KEY_TAB; + case 0x0D: return INPUT_KEY_ENTER; + case 0x10: return INPUT_KEY_SHIFT; + case 0x11: return INPUT_KEY_CTRL; + case 0x12: return INPUT_KEY_ALT; + case 0x13: return INPUT_KEY_PAUSE; + case 0x14: return INPUT_KEY_CAPS_LOCK; + case 0x1B: return INPUT_KEY_ESCAPE; + case 0x20: return INPUT_KEY_SPACE; + case 0x21: return INPUT_KEY_PAGE_UP; + case 0x22: return INPUT_KEY_PAGE_DOWN; + case 0x23: return INPUT_KEY_END; + case 0x24: return INPUT_KEY_HOME; + case 0x25: return INPUT_KEY_LEFT; + case 0x26: return INPUT_KEY_UP; + case 0x27: return INPUT_KEY_RIGHT; + case 0x28: return INPUT_KEY_DOWN; + case 0x2C: return INPUT_KEY_PRINT_SCREEN; + case 0x2D: return INPUT_KEY_INSERT; + case 0x2E: return INPUT_KEY_DELETE; + case 0x6A: return INPUT_KEY_NUM_MULTIPLY; + case 0x6B: return INPUT_KEY_NUM_ADD; + case 0x6D: return INPUT_KEY_NUM_SUBTRACT; + case 0x6E: return INPUT_KEY_NUM_DECIMAL; + case 0x6F: return INPUT_KEY_NUM_DIVIDE; + case 0x90: return INPUT_KEY_NUM_LOCK; + case 0x91: return INPUT_KEY_SCROLL_LOCK; + case 0xBA: return INPUT_KEY_SEMICOLON; + case 0xBB: return INPUT_KEY_EQUALS; + case 0xBC: return INPUT_KEY_COMMA; + case 0xBD: return INPUT_KEY_HYPHEN; + case 0xBE: return INPUT_KEY_PERIOD; + case 0xBF: return INPUT_KEY_SLASH; + case 0xC0: return INPUT_KEY_BACKTICK; + case 0xDB: return INPUT_KEY_LEFT_BRACKET; + case 0xDC: return INPUT_KEY_BACKSLASH; + case 0xDD: return INPUT_KEY_RIGHT_BRACKET; + case 0xDE: return INPUT_KEY_APOSTROPHE; + default: return INPUT_KEY_NONE; + } +} + +static bool +lua_ue4ss_bind_add_key(keybind_t *bind, input_key_kind_t key) +{ + if (!bind || key == INPUT_KEY_NONE || key >= INPUT_KEY_MAX || bind->count >= KEYBIND_MAX_KEYS) { + return false; + } + + for (int i = 0; i < bind->count; ++i) { + if (bind->keys[i] == key) { + return false; + } + } + + bind->keys[bind->count++] = key; + return true; +} + +static bool +lua_ue4ss_bind_add_value(lua_State *state, int idx, keybind_t *bind) +{ + idx = lua_absindex(state, idx); + if (lua_isinteger(state, idx)) { + return lua_ue4ss_bind_add_key(bind, lua_ue4ss_key_from_vk(lua_tointeger(state, idx))); + } + + if (lua_type(state, idx) == LUA_TSTRING) { + size_t len = 0; + const char *data = lua_tolstring(state, idx, &len); + keybind_t parsed = keybind_parse(str_make((void *)data, (uint64_t)len), KEYBIND_NULL); + if (!keybind_is_valid(parsed)) { + return false; + } + + for (int i = 0; i < parsed.count; ++i) { + if (!lua_ue4ss_bind_add_key(bind, parsed.keys[i])) { + return false; + } + } + return true; + } + return false; +} + +static bool +lua_ue4ss_bind_from_args(lua_State *state, int key_idx, int modifiers_idx, keybind_t *out) +{ + keybind_t bind = KEYBIND_NULL; + if (!lua_ue4ss_bind_add_value(state, key_idx, &bind)) { + return false; + } + + if (modifiers_idx > 0 && !lua_isnoneornil(state, modifiers_idx)) { + if (!lua_istable(state, modifiers_idx)) { + return false; + } + + lua_Integer count = (lua_Integer)lua_rawlen(state, modifiers_idx); + for (lua_Integer i = 1; i <= count; ++i) { + lua_rawgeti(state, modifiers_idx, i); + bool added = lua_ue4ss_bind_add_value(state, -1, &bind); + lua_pop(state, 1); + if (!added) { + return false; + } + } + } + + if (!keybind_is_valid(bind)) { + return false; + } + + *out = bind; + return true; +} + +static int +lua_ue4ss_register_console_command(lua_State *state) +{ + lua_ue4ss_context_t *context = lua_ue4ss_context_from_state(state); + size_t name_len = 0; + const char *name_data = luaL_checklstring(state, 1, &name_len); + + luaL_checktype(state, 2, LUA_TFUNCTION); + if (!context || !context->arena || !context->commands) { + return luaL_error(state, "Lua mod context is unavailable"); + } + + if (name_len == 0) { + return luaL_error(state, "console command name cannot be empty"); + } + + str_t name = str_make((void *)name_data, (uint64_t)name_len); + str_t saved_name = str_push_copy(context->arena, name); + if (str_is_empty(saved_name)) { + return luaL_error(state, "failed to allocate console command name"); + } + + if (!lua_ue4ss_pending_lock(context)) { + return luaL_error(state, "failed to lock Lua console commands"); + } + + for (int i = 0; i < context->command_count; ++i) { + if (str_equal(context->commands[i].name, name, STR_CMP_FLAG_IGNORE_CASE)) { + lua_ue4ss_pending_unlock(context); + return luaL_error(state, "console command '%.*s' is already registered by this mod", (int)name.len, name.data); + } + } + + if (context->command_count >= CONFIG_LUA_UE4SS_MAX_COMMANDS) { + lua_ue4ss_pending_unlock(context); + return luaL_error(state, "Lua console command limit reached"); + } + + lua_ue4ss_command_t *command = &context->commands[context->command_count++]; + + command->name = saved_name; + lua_pushvalue(state, 2); + + command->callback_ref = luaL_ref(state, LUA_REGISTRYINDEX); + lua_ue4ss_pending_unlock(context); + return 0; +} + +static int64_t +lua_ue4ss_next_hook_id(lua_ue4ss_context_t *context) +{ + int64_t result = context->next_hook_id++; + if (context->next_hook_id <= 0 || context->next_hook_id > (int64_t)LUA_MAXINTEGER) { + context->next_hook_id = 1; + } + return result; +} + +static ufunc_t * +lua_ue4ss_find_hook_function(str_t target) +{ + ufunc_t *function = (ufunc_t *)unreal_uobject_find_by_full_name(globals.unreal.core_func, target); + if (function) { + return function; + } + + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t lookup = str_push_copy(tmp.arena, target); + for (uint64_t i = lookup.len; i > 0; --i) { + if (lookup.data[i - 1] == ':') { + lookup.data[i - 1] = '.'; + break; + } + } + + function = (ufunc_t *)unreal_uobject_find_by_full_name(globals.unreal.core_func, lookup); + } + scratch_end(tmp); + + return function; +} + +static int +lua_ue4ss_register_hook(lua_State *state) +{ + lua_ue4ss_context_t *context = lua_ue4ss_context_from_state(state); + size_t target_len = 0; + const char *target_data = luaL_checklstring(state, 1, &target_len); + bool has_pre = lua_type(state, 2) == LUA_TFUNCTION; + bool has_post = lua_type(state, 3) == LUA_TFUNCTION; + + if (!context || !context->arena || !context->hooks) { + return luaL_error(state, "Lua mod context is unavailable"); + } + + if (target_len == 0) { + return luaL_error(state, "UFunction name cannot be empty"); + } + + if (!lua_isnoneornil(state, 2) && !has_pre) { + return luaL_argerror(state, 2, "expected a function or nil"); + } + + if (!lua_isnoneornil(state, 3) && !has_post) { + return luaL_argerror(state, 3, "expected a function or nil"); + } + + if (!has_pre && !has_post) { + return luaL_error(state, "RegisterHook requires a pre or post callback"); + } + + if (context->hook_count >= CONFIG_LUA_UE4SS_MAX_HOOKS) { + return luaL_error(state, "Lua UFunction hook limit reached"); + } + + str_t target = str_make((void *)target_data, (uint64_t)target_len); + ufunc_t *function = lua_ue4ss_find_hook_function(target); + if (!function) { + return luaL_error(state, "UFunction '%.*s' was not found", (int)target.len, target.data); + } + + fweak_object_ptr_t function_weak = {.object_idx = -1}; + if (!unreal_fweak_object_from_object((uobject_t *)function, &function_weak)) { + return luaL_error(state, "UFunction '%.*s' is not a valid UObject", (int)target.len, target.data); + } + + str_t saved_target = str_push_copy(context->arena, target); + if (str_is_empty(saved_target)) { + return luaL_error(state, "failed to allocate UFunction hook name"); + } + + if (!lua_ue4ss_pending_lock(context)) { + return luaL_error(state, "failed to lock Lua UFunction hooks"); + } + + if (context->hook_count >= CONFIG_LUA_UE4SS_MAX_HOOKS) { + lua_ue4ss_pending_unlock(context); + return luaL_error(state, "Lua UFunction hook limit reached"); + } + + lua_ue4ss_hook_t *hook = &context->hooks[context->hook_count++]; + *hook = (lua_ue4ss_hook_t){ + .target = saved_target, + .function = function_weak, + .pre_id = lua_ue4ss_next_hook_id(context), + .post_id = lua_ue4ss_next_hook_id(context), + .pre_callback_ref = LUA_NOREF, + .post_callback_ref = LUA_NOREF, + .active = true, + }; + + if (has_pre) { + lua_pushvalue(state, 2); + hook->pre_callback_ref = luaL_ref(state, LUA_REGISTRYINDEX); + } + + if (has_post) { + lua_pushvalue(state, 3); + hook->post_callback_ref = luaL_ref(state, LUA_REGISTRYINDEX); + } + + lua_ue4ss_pending_unlock(context); + + lua_pushinteger(state, (lua_Integer)hook->pre_id); + lua_pushinteger(state, (lua_Integer)hook->post_id); + return 2; +} + +static int +lua_ue4ss_unregister_hook(lua_State *state) +{ + lua_ue4ss_context_t *context = lua_ue4ss_context_from_state(state); + size_t target_len = 0; + const char *target_data = luaL_checklstring(state, 1, &target_len); + lua_Integer pre_id = luaL_checkinteger(state, 2); + lua_Integer post_id = luaL_checkinteger(state, 3); + + if (!context || !context->hooks) { + return luaL_error(state, "Lua mod context is unavailable"); + } + + str_t target = str_make((void *)target_data, (uint64_t)target_len); + if (!lua_ue4ss_pending_lock(context)) { + return luaL_error(state, "failed to lock Lua UFunction hooks"); + } + + for (int i = 0; i < context->hook_count; ++i) { + lua_ue4ss_hook_t *hook = &context->hooks[i]; + if (!hook->active || hook->pre_id != (int64_t)pre_id || hook->post_id != (int64_t)post_id || !str_equal(hook->target, target, 0)) { + continue; + } + + if (hook->pre_callback_ref != LUA_NOREF && hook->pre_callback_ref != LUA_REFNIL) { + luaL_unref(state, LUA_REGISTRYINDEX, hook->pre_callback_ref); + } + + if (hook->post_callback_ref != LUA_NOREF && hook->post_callback_ref != LUA_REFNIL) { + luaL_unref(state, LUA_REGISTRYINDEX, hook->post_callback_ref); + } + + hook->pre_callback_ref = LUA_NOREF; + hook->post_callback_ref = LUA_NOREF; + hook->active = false; + lua_ue4ss_pending_unlock(context); + return 0; + } + + lua_ue4ss_pending_unlock(context); + return 0; +} + +static int +lua_ue4ss_notify_on_new_object(lua_State *state) +{ + lua_ue4ss_context_t *context = lua_ue4ss_context_from_state(state); + size_t class_path_len = 0; + const char *class_path_data = luaL_checklstring(state, 1, &class_path_len); + + luaL_checktype(state, 2, LUA_TFUNCTION); + if (!context || !context->arena || !context->notifications) { + return luaL_error(state, "Lua mod context is unavailable"); + } + + if (class_path_len == 0) { + return luaL_error(state, "UClass name cannot be empty"); + } + + str_t class_path = str_make((void *)class_path_data, (uint64_t)class_path_len); + uclass_t *target = unreal_uobject_find_class_by_full_name(class_path); + if (!target) { + return luaL_error(state, "UClass '%.*s' was not found", (int)class_path.len, class_path.data); + } + + fweak_object_ptr_t target_weak = {.object_idx = -1}; + if (!unreal_fweak_object_from_object((uobject_t *)target, &target_weak)) { + return luaL_error(state, "UClass '%.*s' is not a valid UObject", (int)class_path.len, class_path.data); + } + + str_t saved_path = str_push_copy(context->arena, class_path); + if (str_is_empty(saved_path)) { + return luaL_error(state, "failed to allocate UClass notification name"); + } + + lua_pushvalue(state, 2); + int callback_ref = luaL_ref(state, LUA_REGISTRYINDEX); + if (!lua_ue4ss_pending_lock(context)) { + luaL_unref(state, LUA_REGISTRYINDEX, callback_ref); + return luaL_error(state, "failed to lock Lua new-object notifications"); + } + + if (context->notification_count >= CONFIG_LUA_UE4SS_MAX_NOTIFICATIONS) { + lua_ue4ss_pending_unlock(context); + luaL_unref(state, LUA_REGISTRYINDEX, callback_ref); + return luaL_error(state, "Lua new-object notification limit reached"); + } + + lua_ue4ss_notification_t *notification = &context->notifications[context->notification_count++]; + *notification = (lua_ue4ss_notification_t){ + .class_path = saved_path, + .target_class = target_weak, + .callback_ref = callback_ref, + .active = true, + }; + lua_ue4ss_pending_unlock(context); + + return 0; +} + +static lua_ue4ss_scheduled_job_t * +lua_ue4ss_find_scheduled_job(lua_ue4ss_context_t *context, int64_t handle) +{ + if (!context || !context->scheduled_jobs || handle <= 0) { + return NULL; + } + + for (int i = 0; i < CONFIG_LUA_UE4SS_MAX_SCHEDULED_JOBS; ++i) { + lua_ue4ss_scheduled_job_t *job = &context->scheduled_jobs[i]; + if (job->active && job->handle == handle) { + return job; + } + } + return NULL; +} + +static void +lua_ue4ss_disable_scheduled_job(lua_ue4ss_context_t *context, lua_ue4ss_scheduled_job_t *job); + +static int64_t +lua_ue4ss_next_action_handle(lua_ue4ss_context_t *context) +{ + for (int attempt = 0; attempt <= CONFIG_LUA_UE4SS_MAX_SCHEDULED_JOBS; ++attempt) { + int64_t handle = context->next_action_handle++; + if (context->next_action_handle <= 0 || context->next_action_handle > (int64_t)LUA_MAXINTEGER) { + context->next_action_handle = 1; + } + + if (!lua_ue4ss_find_scheduled_job(context, handle)) { + return handle; + } + } + return 0; +} + +static uint64_t +lua_ue4ss_check_delay_ms(lua_State *state, int idx) +{ + lua_Integer delay_ms = luaL_checkinteger(state, idx); + if (delay_ms < 0) { + luaL_argerror(state, idx, "delay cannot be negative"); + } + + if ((uint64_t)delay_ms > UINT64_MAX / 1000ULL) { + luaL_argerror(state, idx, "delay is too large"); + } + return (uint64_t)delay_ms; +} + +static int +lua_ue4ss_schedule_job(lua_State *state, uint64_t delay_ms, int callback_idx, bool loop, bool game_thread, int64_t requested_handle, bool return_handle) +{ + lua_ue4ss_context_t *context = lua_ue4ss_context_from_state(state); + luaL_checktype(state, callback_idx, LUA_TFUNCTION); + if (!context || !context->scheduled_jobs) { + return luaL_error(state, "Lua mod context is unavailable"); + } + + if (requested_handle > 0 && lua_ue4ss_find_scheduled_job(context, requested_handle)) { + if (return_handle) { + lua_pushinteger(state, (lua_Integer)requested_handle); + return 1; + } + return 0; + } + + lua_ue4ss_scheduled_job_t *job = NULL; + for (int i = 0; i < CONFIG_LUA_UE4SS_MAX_SCHEDULED_JOBS; ++i) { + if (!context->scheduled_jobs[i].active) { + job = &context->scheduled_jobs[i]; + break; + } + } + + if (!job) { + return luaL_error(state, "Lua scheduled-job limit reached"); + } + + int64_t handle = requested_handle > 0 ? requested_handle : lua_ue4ss_next_action_handle(context); + if (handle <= 0) { + return luaL_error(state, "failed to allocate a scheduled-job handle"); + } + + uint64_t now = time_now_us(); + uint64_t delay_us = delay_ms * 1000ULL; + uint64_t due_us = delay_us > UINT64_MAX - now ? UINT64_MAX : now + delay_us; + uint64_t current_tick = game_thread ? context->scheduler_tick : context->async_scheduler_tick; + uint64_t ready_tick = current_tick == UINT64_MAX ? UINT64_MAX : current_tick + 1; + + lua_pushvalue(state, callback_idx); + int callback_ref = luaL_ref(state, LUA_REGISTRYINDEX); + *job = (lua_ue4ss_scheduled_job_t){ + .due_us = due_us, + .interval_us = delay_us, + .ready_tick = ready_tick, + .handle = handle, + .callback_ref = callback_ref, + .loop = loop, + .game_thread = game_thread, + .active = true, + }; + context->scheduled_job_count += 1; + + if (!game_thread && context->wake_async) { + context->wake_async(context->wake_async_user); + } + + if (return_handle) { + lua_pushinteger(state, (lua_Integer)handle); + return 1; + } + return 0; +} + +static int +lua_ue4ss_execute_in_game_thread(lua_State *state) +{ + return lua_ue4ss_schedule_job(state, 0, 1, false, true, 0, false); +} + +static int +lua_ue4ss_is_in_game_thread(lua_State *state) +{ + bool in_game_thread = unreal_is_in_game_thread(); + lua_pushboolean(state, in_game_thread); + return 1; +} + +static int +lua_ue4ss_execute_in_game_thread_with_delay(lua_State *state) +{ + int arg_count = lua_gettop(state); + if (arg_count == 2) { + uint64_t delay_ms = lua_ue4ss_check_delay_ms(state, 1); + return lua_ue4ss_schedule_job(state, delay_ms, 2, false, true, 0, true); + } + + if (arg_count == 3) { + lua_Integer handle = luaL_checkinteger(state, 1); + if (handle <= 0) { + return luaL_argerror(state, 1, "handle must be positive"); + } + + uint64_t delay_ms = lua_ue4ss_check_delay_ms(state, 2); + return lua_ue4ss_schedule_job(state, delay_ms, 3, false, true, (int64_t)handle, true); + } + return luaL_error(state, "expected (delay_ms, callback) or (handle, delay_ms, callback)"); +} + +static int +lua_ue4ss_execute_async(lua_State *state) +{ + return lua_ue4ss_schedule_job(state, 0, 1, false, false, 0, false); +} + +static int +lua_ue4ss_execute_with_delay(lua_State *state) +{ + uint64_t delay_ms = lua_ue4ss_check_delay_ms(state, 1); + return lua_ue4ss_schedule_job(state, delay_ms, 2, false, false, 0, false); +} + +static int +lua_ue4ss_loop_async(lua_State *state) +{ + uint64_t delay_ms = lua_ue4ss_check_delay_ms(state, 1); + return lua_ue4ss_schedule_job(state, delay_ms, 2, true, false, 0, false); +} + +static int +lua_ue4ss_loop_in_game_thread_after_frames(lua_State *state) +{ + lua_Integer frames = luaL_checkinteger(state, 1); + if (frames < 0) { + return luaL_argerror(state, 1, "frame count cannot be negative"); + } + + uint64_t interval_ticks = MAX_VAL((uint64_t)frames, 1ULL); + int result = lua_ue4ss_schedule_job(state, 0, 2, true, true, 0, true); + if (result == 1) { + lua_ue4ss_context_t *context = lua_ue4ss_context_from_state(state); + int64_t handle = (int64_t)lua_tointeger(state, -1); + lua_ue4ss_scheduled_job_t *job = lua_ue4ss_find_scheduled_job(context, handle); + if (job) { + job->frame_based = true; + job->interval_ticks = interval_ticks; + job->ready_tick = interval_ticks > UINT64_MAX - context->scheduler_tick ? UINT64_MAX : context->scheduler_tick + interval_ticks; + } + } + return result; +} + +static int +lua_ue4ss_cancel_delayed_action(lua_State *state) +{ + lua_ue4ss_context_t *context = lua_ue4ss_context_from_state(state); + lua_Integer handle = luaL_checkinteger(state, 1); + if (handle <= 0) { + return luaL_argerror(state, 1, "handle must be positive"); + } + + lua_ue4ss_scheduled_job_t *job = lua_ue4ss_find_scheduled_job(context, (int64_t)handle); + bool cancelled = job != NULL; + if (job) { + lua_ue4ss_disable_scheduled_job(context, job); + } + lua_pushboolean(state, cancelled); + return 1; +} + +static int +lua_ue4ss_register_keybind(lua_State *state) +{ + lua_ue4ss_context_t *context = lua_ue4ss_context_from_state(state); + int callback_idx = lua_istable(state, 2) ? 3 : 2; + int modifiers_idx = callback_idx == 3 ? 2 : 0; + luaL_checktype(state, callback_idx, LUA_TFUNCTION); + if (!context || !context->keybinds) { + return luaL_error(state, "Lua mod context is unavailable"); + } + + keybind_t bind = KEYBIND_NULL; + if (!lua_ue4ss_bind_from_args(state, 1, modifiers_idx, &bind)) { + return luaL_error(state, "invalid keybind; use a UE4SS Key value or an Overdub key string"); + } + + for (int i = 0; i < bind.count; ++i) { + if (!input_key_is_bindable(bind.keys[i])) { + return luaL_error(state, "keybind contains a non-bindable input axis"); + } + } + + if (!lua_ue4ss_pending_lock(context)) { + return luaL_error(state, "failed to lock Lua keybinds"); + } + + for (int i = 0; i < context->keybind_count; ++i) { + if (keybind_equal(context->keybinds[i].bind, bind)) { + lua_ue4ss_pending_unlock(context); + lua_pushboolean(state, false); + return 1; + } + } + + if (context->keybind_count >= CONFIG_LUA_UE4SS_MAX_KEYBINDS) { + lua_ue4ss_pending_unlock(context); + return luaL_error(state, "Lua keybind limit reached"); + } + + lua_ue4ss_keybind_t *keybind = &context->keybinds[context->keybind_count++]; + + keybind->bind = bind; + lua_pushvalue(state, callback_idx); + + keybind->callback_ref = luaL_ref(state, LUA_REGISTRYINDEX); + lua_ue4ss_pending_unlock(context); + lua_pushboolean(state, true); + return 1; +} + +static int +lua_ue4ss_is_keybind_registered(lua_State *state) +{ + lua_ue4ss_context_t *context = lua_ue4ss_context_from_state(state); + int modifiers_idx = lua_istable(state, 2) ? 2 : 0; + keybind_t bind = KEYBIND_NULL; + if (!context || !lua_ue4ss_bind_from_args(state, 1, modifiers_idx, &bind)) { + lua_pushboolean(state, false); + return 1; + } + + if (!lua_ue4ss_pending_lock(context)) { + lua_pushboolean(state, false); + return 1; + } + + for (int i = 0; i < context->keybind_count; ++i) { + if (keybind_equal(context->keybinds[i].bind, bind)) { + lua_ue4ss_pending_unlock(context); + lua_pushboolean(state, true); + return 1; + } + } + + lua_ue4ss_pending_unlock(context); + lua_pushboolean(state, false); + return 1; +} + +static void +lua_ue4ss_set_integer_field(lua_State *state, const char *name, lua_Integer value) +{ + lua_pushinteger(state, value); + lua_setfield(state, -2, name); +} + +static void +lua_ue4ss_push_command_parts(lua_State *state, str_t args) +{ + lua_newtable(state); + int table_idx = lua_absindex(state, -1); + int part_idx = 1; + uint64_t pos = 0; + + while (pos < args.len) { + while (pos < args.len && (args.data[pos] == ' ' || args.data[pos] == '\t' || args.data[pos] == '\r' || args.data[pos] == '\n')) { + pos += 1; + } + + if (pos >= args.len) { + break; + } + + uint8_t quote = 0; + if (args.data[pos] == '\'' || args.data[pos] == '"') { + quote = args.data[pos++]; + } + + luaL_Buffer buffer; + luaL_buffinit(state, &buffer); + while (pos < args.len) { + uint8_t ch = args.data[pos]; + if (quote) { + if (ch == quote) { + pos += 1; + break; + } + } else if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') { + break; + } + + if (ch == '\\' && pos + 1 < args.len && (args.data[pos + 1] == quote || args.data[pos + 1] == '\\')) { + pos += 1; + ch = args.data[pos]; + } + + luaL_addchar(&buffer, (char)ch); + pos += 1; + } + + luaL_pushresult(&buffer); + lua_rawseti(state, table_idx, part_idx++); + } +} + +static void +lua_ue4ss_set_absolute_path(lua_State *state, int table_idx, str_t path) +{ + table_idx = lua_absindex(state, table_idx); + lua_pushlstring(state, (const char *)path.data, (size_t)path.len); + lua_setfield(state, table_idx, "__absolute_path"); +} + +static void +lua_ue4ss_push_directory(lua_State *state, str_t path, int depth, int *node_budget) +{ + lua_newtable(state); + lua_ue4ss_set_absolute_path(state, -1, path); + + if (depth <= 0 || !node_budget || *node_budget <= 0 || !dir_exists(path)) { + return; + } + + *node_budget -= 1; + + int table_idx = lua_absindex(state, -1); + tmp_arena_t tmp = scratch_begin(NULL); + { + dir_entry_list_t entries = dir_list(path, tmp.arena); + for (int i = 0; i < entries.count && *node_budget > 0; ++i) { + dir_entry_t *entry = &entries.items[i]; + if (entry->kind != DIR_ENTRY_DIR) { + continue; + } + + lua_pushlstring(state, (const char *)entry->name.data, (size_t)entry->name.len); + lua_ue4ss_push_directory(state, entry->path, depth - 1, node_budget); + lua_settable(state, table_idx); + } + } + scratch_end(tmp); +} + +static int +lua_ue4ss_iterate_game_directories(lua_State *state) +{ + lua_ue4ss_context_t *context = lua_ue4ss_context_from_state(state); + if (!context) { + return luaL_error(state, "Lua mod context is unavailable"); + } + + lua_newtable(state); // root + int root_idx = lua_absindex(state, -1); + + lua_newtable(state); // Game + int game_idx = lua_absindex(state, -1); + + lua_newtable(state); // Binaries + int binaries_idx = lua_absindex(state, -1); + + lua_newtable(state); // Win64 + int win64_idx = lua_absindex(state, -1); + lua_ue4ss_set_absolute_path(state, win64_idx, context->game_dir); + + lua_newtable(state); // virtual Mods + int mods_idx = lua_absindex(state, -1); + lua_ue4ss_set_absolute_path(state, mods_idx, context->root_mod_dir); + + int node_budget = LUA_UE4SS_DIRECTORY_MAX_NODES; + lua_ue4ss_push_directory(state, context->mod_dir, LUA_UE4SS_DIRECTORY_MAX_DEPTH, &node_budget); + int mod_directory_idx = lua_absindex(state, -1); + + lua_pushvalue(state, mod_directory_idx); + lua_pushlstring(state, (const char *)context->mod_dir_name.data, (size_t)context->mod_dir_name.len); + lua_insert(state, -2); + lua_settable(state, mods_idx); + + if (!str_equal(context->mod_id, context->mod_dir_name, 0)) { + lua_pushlstring(state, (const char *)context->mod_id.data, (size_t)context->mod_id.len); + lua_pushvalue(state, mod_directory_idx); + lua_settable(state, mods_idx); + } + lua_pop(state, 1); // original mod directory table + + lua_setfield(state, win64_idx, "Mods"); + lua_setfield(state, binaries_idx, "Win64"); + lua_setfield(state, game_idx, "Binaries"); + lua_setfield(state, root_idx, "Game"); + return 1; +} + +static int +lua_ue4ss_shared_get(lua_State *state) +{ + luaL_checkany(state, 2); + lua_rawgetp(state, LUA_REGISTRYINDEX, &g_lua_ue4ss_shared_registry_key); + lua_pushvalue(state, 2); + lua_rawget(state, -2); + lua_remove(state, -2); + return 1; +} + +static int +lua_ue4ss_shared_set(lua_State *state) +{ + luaL_checkany(state, 2); + luaL_checkany(state, 3); + lua_rawgetp(state, LUA_REGISTRYINDEX, &g_lua_ue4ss_shared_registry_key); + lua_pushvalue(state, 2); + lua_pushvalue(state, 3); + lua_rawset(state, -3); + return 0; +} + +static void +lua_ue4ss_buffer_add_pattern(luaL_Buffer *buffer, str_t directory, const char *suffix) +{ + if (str_is_empty(directory)) { + return; + } + + if (buffer->n > 0) { + luaL_addchar(buffer, ';'); + } + luaL_addlstring(buffer, (const char *)directory.data, (size_t)directory.len); + luaL_addchar(buffer, '/'); + luaL_addstring(buffer, suffix); +} + +static void +lua_ue4ss_set_package_paths(lua_State *state, lua_ue4ss_context_t *context) +{ + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t entry_dir = path_dir(context->entry_path); + str_t shared = path_join(tmp.arena, context->root_mod_dir, STR_LIT("shared")); + str_t local_shared = path_join(tmp.arena, context->mod_dir, STR_LIT("shared")); + str_t scripts = path_join(tmp.arena, context->mod_dir, STR_LIT("scripts")); + + lua_getglobal(state, "package"); + int package_idx = lua_absindex(state, -1); + + luaL_Buffer path_buffer; + luaL_buffinit(state, &path_buffer); + lua_ue4ss_buffer_add_pattern(&path_buffer, entry_dir, "?.lua"); + lua_ue4ss_buffer_add_pattern(&path_buffer, entry_dir, "?/init.lua"); + + if (!path_equal(scripts, entry_dir)) { + lua_ue4ss_buffer_add_pattern(&path_buffer, scripts, "?.lua"); + lua_ue4ss_buffer_add_pattern(&path_buffer, scripts, "?/init.lua"); + } + + lua_ue4ss_buffer_add_pattern(&path_buffer, shared, "?.lua"); + lua_ue4ss_buffer_add_pattern(&path_buffer, shared, "?/?.lua"); + lua_ue4ss_buffer_add_pattern(&path_buffer, shared, "?/init.lua"); + lua_ue4ss_buffer_add_pattern(&path_buffer, local_shared, "?.lua"); + lua_ue4ss_buffer_add_pattern(&path_buffer, local_shared, "?/?.lua"); + luaL_pushresult(&path_buffer); + lua_setfield(state, package_idx, "path"); + + luaL_Buffer cpath_buffer; + luaL_buffinit(state, &cpath_buffer); + lua_ue4ss_buffer_add_pattern(&cpath_buffer, context->game_dir, "?.dll"); + lua_ue4ss_buffer_add_pattern(&cpath_buffer, context->mod_dir, "?.dll"); + lua_ue4ss_buffer_add_pattern(&cpath_buffer, entry_dir, "?.dll"); + lua_ue4ss_buffer_add_pattern(&cpath_buffer, context->root_mod_dir, "?.dll"); + luaL_pushresult(&cpath_buffer); + lua_setfield(state, package_idx, "cpath"); + lua_pop(state, 1); + } + scratch_end(tmp); +} + +bool +lua_ue4ss_register(lua_State *state, lua_ue4ss_context_t *context) +{ + if (!state || + !context || + !context->runtime || + !context->arena || + !context->commands || + !context->keybinds || + !context->hooks || + !context->notifications || + !context->pending_objects || + !context->pending_hooks || + !context->pending_inputs || + !context->pending_commands || + !context->scheduled_jobs) { + return false; + } + + lua_pushlightuserdata(state, context); + lua_rawsetp(state, LUA_REGISTRYINDEX, &g_lua_ue4ss_context_registry_key); + + lua_newtable(state); + lua_rawsetp(state, LUA_REGISTRYINDEX, &g_lua_ue4ss_shared_registry_key); + + lua_newtable(state); + lua_pushcfunction(state, lua_ue4ss_shared_get); + lua_setfield(state, -2, "GetSharedVariable"); + lua_pushcfunction(state, lua_ue4ss_shared_set); + lua_setfield(state, -2, "SetSharedVariable"); + lua_setglobal(state, "ModRef"); + + lua_pushcfunction(state, lua_ue4ss_iterate_game_directories); + lua_setglobal(state, "IterateGameDirectories"); + + lua_pushcfunction(state, lua_ue4ss_register_console_command); + lua_setglobal(state, "RegisterConsoleCommandHandler"); + lua_pushcfunction(state, lua_ue4ss_register_console_command); + lua_setglobal(state, "RegisterConsoleCommandGlobalHandler"); + lua_pushcfunction(state, lua_ue4ss_register_keybind); + lua_setglobal(state, "RegisterKeyBind"); + lua_pushcfunction(state, lua_ue4ss_register_keybind); + lua_setglobal(state, "RegisterKeyBindAsync"); + lua_pushcfunction(state, lua_ue4ss_is_keybind_registered); + lua_setglobal(state, "IsKeyBindRegistered"); + lua_pushcfunction(state, lua_ue4ss_register_hook); + lua_setglobal(state, "RegisterHook"); + lua_pushcfunction(state, lua_ue4ss_unregister_hook); + lua_setglobal(state, "UnregisterHook"); + lua_pushcfunction(state, lua_ue4ss_notify_on_new_object); + lua_setglobal(state, "NotifyOnNewObject"); + lua_pushcfunction(state, lua_ue4ss_execute_in_game_thread); + lua_setglobal(state, "ExecuteInGameThread"); + lua_pushcfunction(state, lua_ue4ss_is_in_game_thread); + lua_setglobal(state, "IsInGameThread"); + lua_pushcfunction(state, lua_ue4ss_execute_in_game_thread_with_delay); + lua_setglobal(state, "ExecuteInGameThreadWithDelay"); + lua_pushcfunction(state, lua_ue4ss_execute_async); + lua_setglobal(state, "ExecuteAsync"); + lua_pushcfunction(state, lua_ue4ss_execute_with_delay); + lua_setglobal(state, "ExecuteWithDelay"); + lua_pushcfunction(state, lua_ue4ss_loop_async); + lua_setglobal(state, "LoopAsync"); + lua_pushcfunction(state, lua_ue4ss_loop_in_game_thread_after_frames); + lua_setglobal(state, "LoopInGameThreadAfterFrames"); + lua_pushcfunction(state, lua_ue4ss_cancel_delayed_action); + lua_setglobal(state, "CancelDelayedAction"); + + lua_newtable(state); + for (int i = 0; i < COUNTOF(g_lua_ue4ss_key_constants); ++i) { + const char *name = g_lua_ue4ss_key_constants[i]; + if (name) { + lua_pushinteger(state, i); + lua_setfield(state, -2, name); + } + } + lua_setglobal(state, "Key"); + + lua_newtable(state); + lua_ue4ss_set_integer_field(state, "SHIFT", 0x10); + lua_ue4ss_set_integer_field(state, "CONTROL", 0x11); + lua_ue4ss_set_integer_field(state, "ALT", 0x12); + lua_setglobal(state, "ModifierKey"); + + lua_ue4ss_set_package_paths(state, context); + return true; +} + +static void +lua_ue4ss_disable_callback(lua_ue4ss_context_t *context, int *callback_ref) +{ + if (*callback_ref != LUA_NOREF && *callback_ref != LUA_REFNIL) { + luaL_unref(context->runtime->state, LUA_REGISTRYINDEX, *callback_ref); + } + *callback_ref = LUA_NOREF; +} + +static bool +lua_ue4ss_call_ref(lua_ue4ss_context_t *context, int callback_ref, int arg_count, int result_count, uint64_t execution_limit_us, + bool log_error, uint64_t suppressed_error_hash, uint64_t *out_error_hash) +{ + uint64_t previous_limit = context->runtime->execution_limit_us; + context->runtime->execution_limit_us = execution_limit_us; + + bool called = lua_runtime_call_ref_ex(context->runtime, callback_ref, arg_count, result_count, log_error, suppressed_error_hash, out_error_hash); + context->runtime->execution_limit_us = previous_limit; + return called; +} + +static void +lua_ue4ss_disable_scheduled_job(lua_ue4ss_context_t *context, lua_ue4ss_scheduled_job_t *job) +{ + if (!context || !job || !job->active) { + return; + } + + if (job->callback_ref != LUA_NOREF && job->callback_ref != LUA_REFNIL) { + luaL_unref(context->runtime->state, LUA_REGISTRYINDEX, job->callback_ref); + } + + *job = (lua_ue4ss_scheduled_job_t){ + .callback_ref = LUA_NOREF, + }; + context->scheduled_job_count = MAX_VAL(context->scheduled_job_count - 1, 0); +} + +static void +lua_ue4ss_dispatch_scheduled_jobs(lua_ue4ss_context_t *context, bool game_thread) +{ + uint64_t *scheduler_tick = game_thread ? &context->scheduler_tick : &context->async_scheduler_tick; + if (*scheduler_tick < UINT64_MAX) { + *scheduler_tick += 1; + } + + if (context->scheduled_job_count <= 0) { + return; + } + + lua_State *state = context->runtime->state; + uint64_t dispatch_start = time_now_us(); + uint64_t now = dispatch_start; + for (int i = 0; i < CONFIG_LUA_UE4SS_MAX_SCHEDULED_JOBS; ++i) { + lua_ue4ss_scheduled_job_t *job = &context->scheduled_jobs[i]; + if (!job->active || job->game_thread != game_thread || job->ready_tick > *scheduler_tick || job->due_us > now) { + continue; + } + + int stack_base = lua_gettop(state); + int64_t job_handle = job->handle; + bool job_loop = job->loop; + bool slow_warned = job->slow_warned; + uint32_t previous_errors = job->consecutive_errors; + uint64_t callback_error_hash = 0; + uint64_t callback_start = time_now_us(); + uint64_t execution_limit = CONFIG_LUA_UE4SS_EXECUTION_LIMIT_US; + + bool called = lua_ue4ss_call_ref(context, job->callback_ref, 0, job_loop ? 1 : 0, execution_limit, true, job->last_error_hash, &callback_error_hash); + + uint64_t callback_end = time_now_us(); + uint64_t callback_us = callback_end >= callback_start ? callback_end - callback_start : 0; + /* UE4SS's legacy async loop stops on true. Its handle-based game-thread loops ignore return values and remain active after callback errors */ + bool stop_loop = !game_thread && job_loop && called && lua_toboolean(state, -1); + lua_settop(state, stack_base); + + if (game_thread && callback_us > CONFIG_LUA_UE4SS_GAME_DISPATCH_BUDGET_US && !slow_warned) { + LOG_WARN("Lua mod '%.*s' scheduled callback %lld took %llu us (soft frame budget: %llu us)", + STR_ARG(context->mod_id), + (long long)job_handle, + (unsigned long long)callback_us, + (unsigned long long)CONFIG_LUA_UE4SS_GAME_DISPATCH_BUDGET_US); + if (job->active && job->handle == job_handle) { + job->slow_warned = true; + } + } + + if (!job->active || job->handle != job_handle) { + /* the callback may cancel or replace its own handle */ + } else if ((!called && !(game_thread && job_loop)) || !job_loop || stop_loop) { + lua_ue4ss_disable_scheduled_job(context, job); + } else { + if (called && previous_errors > 0) { + LOG_INFO("Lua mod '%.*s' scheduled callback %lld recovered after %u failed execution%s", + STR_ARG(context->mod_id), (long long)job_handle, previous_errors, previous_errors == 1 ? "" : "s"); + job->consecutive_errors = 0; + job->last_error_hash = 0; + } else if (!called) { + if (previous_errors == 0) { + LOG_WARN("Lua mod '%.*s' scheduled callback %lld will suppress repeated retry errors until it succeeds or is cancelled", + STR_ARG(context->mod_id), (long long)job_handle); + } + job->consecutive_errors = previous_errors < UINT32_MAX ? previous_errors + 1 : UINT32_MAX; + job->last_error_hash = callback_error_hash; + } + + now = callback_end; + job->due_us = job->frame_based ? 0 : (job->interval_us > UINT64_MAX - now ? UINT64_MAX : now + job->interval_us); + + uint64_t tick_delay = job->frame_based ? MAX_VAL(job->interval_ticks, 1ULL) : 1ULL; + job->ready_tick = tick_delay > UINT64_MAX - *scheduler_tick ? UINT64_MAX : *scheduler_tick + tick_delay; + } + + now = time_now_us(); + uint64_t dispatch_limit = game_thread ? CONFIG_LUA_UE4SS_GAME_DISPATCH_BUDGET_US : CONFIG_LUA_UE4SS_ASYNC_DISPATCH_BUDGET_US; + if (now - dispatch_start >= dispatch_limit) { + break; + } + } +} + +static bool +lua_ue4ss_pending_try_lock(lua_ue4ss_context_t *context) +{ + return context && atomic_i32_compare_exchange(&context->pending_lock, 1, 0) == 0; +} + +static bool +lua_ue4ss_pending_lock(lua_ue4ss_context_t *context) +{ + for (int attempt = 0; attempt < 1024; ++attempt) { + if (lua_ue4ss_pending_try_lock(context)) { + return true; + } + } + return false; +} + +static void +lua_ue4ss_pending_unlock(lua_ue4ss_context_t *context) +{ + if (context) { + (void)atomic_i32_compare_exchange(&context->pending_lock, 0, 1); + } +} + +void +lua_ue4ss_notify_uobject_constructed(lua_ue4ss_context_t *context, uobject_t *object) +{ + if (!context || !object || !context->pending_objects) { + return; + } + + if (!lua_ue4ss_pending_lock(context)) { + return; + } + + bool matches = false; + for (int i = 0; i < context->notification_count; ++i) { + lua_ue4ss_notification_t *notification = &context->notifications[i]; + if (!notification->active || notification->callback_ref == LUA_NOREF || notification->callback_ref == LUA_REFNIL) { + continue; + } + + uclass_t *target = (uclass_t *)unreal_fweak_object_resolve(notification->target_class); + if (!target || unreal_uobject_is_a(object, target)) { + /* preserve the dispatch-time class refresh when a registered UClass was unloaded, but do not queue unrelated objects for valid targets */ + matches = true; + break; + } + } + + if (!matches) { + lua_ue4ss_pending_unlock(context); + return; + } + + bool queued = false; + fweak_object_ptr_t weak = {.object_idx = -1}; + if (context->pending_object_count < CONFIG_LUA_UE4SS_MAX_PENDING_OBJECTS && unreal_fweak_object_from_object(object, &weak)) { + context->pending_objects[context->pending_object_count++].object = weak; + queued = true; + } else { + context->pending_overflow = true; + } + lua_ue4ss_pending_unlock(context); + + if (queued && context->async_events && context->wake_async) { + context->wake_async(context->wake_async_user); + } +} + +static void +lua_ue4ss_dispatch_new_objects(lua_ue4ss_context_t *context) +{ + if (!context || !context->runtime || !context->runtime->inited || context->notification_count <= 0) { + return; + } + + lua_ue4ss_pending_object_t pending[CONFIG_LUA_UE4SS_MAX_PENDING_OBJECTS]; + int pending_count = 0; + bool overflow = false; + if (!lua_ue4ss_pending_lock(context)) { + return; + } + + pending_count = context->pending_object_count; + if (pending_count > 0) { + mem_copy(pending, context->pending_objects, (uint64_t)pending_count * sizeof(*pending)); + } + + context->pending_object_count = 0; + overflow = context->pending_overflow; + context->pending_overflow = false; + lua_ue4ss_pending_unlock(context); + + if (overflow) { + LOG_WARN("Lua mod '%.*s' new-object notification queue overflowed; some notifications were dropped", STR_ARG(context->mod_id)); + } + + lua_State *state = context->runtime->state; + for (int object_idx = 0; object_idx < pending_count; ++object_idx) { + uobject_t *object = unreal_fweak_object_resolve(pending[object_idx].object); + if (!object) { + continue; + } + + int notification_count = context->notification_count; + for (int i = 0; i < notification_count; ++i) { + lua_ue4ss_notification_t *notification = &context->notifications[i]; + if (!notification->active || notification->callback_ref == LUA_NOREF || notification->callback_ref == LUA_REFNIL) { + continue; + } + + uclass_t *target = (uclass_t *)unreal_fweak_object_resolve(notification->target_class); + if (!target) { + target = unreal_uobject_find_class_by_full_name(notification->class_path); + if (target) { + fweak_object_ptr_t target_weak = {.object_idx = -1}; + if (unreal_fweak_object_from_object((uobject_t *)target, &target_weak) && lua_ue4ss_pending_lock(context)) { + notification->target_class = target_weak; + lua_ue4ss_pending_unlock(context); + } + } + } + + if (!target || !unreal_uobject_is_a(object, target)) { + continue; + } + + int stack_base = lua_gettop(state); + int callback_ref = notification->callback_ref; + if (!lua_unreal_object_push(state, object) || !lua_ue4ss_call_ref(context, callback_ref, 1, 0, CONFIG_LUA_UE4SS_EXECUTION_LIMIT_US, true, 0, NULL)) { + if (notification->callback_ref == callback_ref) { + if (lua_ue4ss_pending_lock(context)) { + lua_ue4ss_disable_callback(context, ¬ification->callback_ref); + notification->active = false; + lua_ue4ss_pending_unlock(context); + } + } + } + lua_settop(state, stack_base); + } + } +} + +void +lua_ue4ss_dispatch_game_thread(lua_ue4ss_context_t *context) +{ + if (!context || !context->runtime || !context->runtime->inited) { + return; + } + + lua_ue4ss_dispatch_scheduled_jobs(context, true); + /* a game-thread job queued by a new-object callback must not execute in the same tick. + * dispatch existing jobs before delivering new notifications. */ + if (!context->async_events) { + lua_ue4ss_dispatch_new_objects(context); + } +} + +void +lua_ue4ss_dispatch_async(lua_ue4ss_context_t *context) +{ + if (!context || !context->runtime || !context->runtime->inited) { + return; + } + + if (context->async_events) { + lua_ue4ss_dispatch_pending_hooks(context); + lua_ue4ss_dispatch_new_objects(context); + lua_ue4ss_dispatch_pending_inputs(context); + lua_ue4ss_dispatch_pending_commands(context); + } + lua_ue4ss_dispatch_scheduled_jobs(context, false); +} + +uint32_t +lua_ue4ss_async_wait_ms(lua_ue4ss_context_t *context) +{ + if (!context || !context->scheduled_jobs || context->scheduled_job_count <= 0) { + return UINT32_MAX; + } + + uint64_t now = time_now_us(); + uint64_t earliest_due = UINT64_MAX; + bool found = false; + for (int i = 0; i < CONFIG_LUA_UE4SS_MAX_SCHEDULED_JOBS; ++i) { + lua_ue4ss_scheduled_job_t *job = &context->scheduled_jobs[i]; + if (!job->active || job->game_thread) { + continue; + } + + found = true; + if (job->ready_tick > context->async_scheduler_tick) { + earliest_due = MIN_VAL(earliest_due, job->due_us); + } else if (job->due_us <= now) { + return 0; + } else { + earliest_due = MIN_VAL(earliest_due, job->due_us); + } + } + + if (!found) { + return UINT32_MAX; + } + + if (earliest_due <= now) { + return 0; + } + + uint64_t wait_ms = time_us_to_ms(earliest_due - now); + return (uint32_t)MIN_VAL(wait_ms, (uint64_t)(UINT32_MAX - 1)); +} + +bool +lua_ue4ss_queue_input(lua_ue4ss_context_t *context, input_event_t *ev) +{ + if (!context || !ev || !context->pending_inputs || !lua_ue4ss_pending_lock(context)) { + return false; + } + + bool interested = false; + for (int i = 0; i < context->keybind_count && !interested; ++i) { + lua_ue4ss_keybind_t *keybind = &context->keybinds[i]; + interested = keybind->callback_ref != LUA_NOREF && keybind->callback_ref != LUA_REFNIL && keybind_activated_by_event(keybind->bind, ev); + } + + bool queued = false; + if (interested) { + if (context->pending_input_count < CONFIG_LUA_UE4SS_MAX_PENDING_INPUTS) { + context->pending_inputs[context->pending_input_count++] = *ev; + queued = true; + } else { + context->pending_input_overflow = true; + } + } + lua_ue4ss_pending_unlock(context); + + if (queued && context->wake_async) { + context->wake_async(context->wake_async_user); + } + return queued; +} + +bool +lua_ue4ss_queue_command(lua_ue4ss_context_t *context, str_t name, str_t args) +{ + if (!context || str_is_empty(name) || !context->pending_commands || !lua_ue4ss_pending_lock(context)) { + return false; + } + + bool matched = false; + for (int i = 0; i < context->command_count; ++i) { + if (str_equal(context->commands[i].name, name, STR_CMP_FLAG_IGNORE_CASE)) { + matched = true; + break; + } + } + + lua_ue4ss_pending_unlock(context); + if (!matched) { + return false; + } + + if (name.len > SIZE_MAX - args.len) { + LOG_ERROR("Lua mod '%.*s' console command is too large to queue", STR_ARG(context->mod_id)); + return true; + } + + size_t data_size = (size_t)(name.len + args.len); + char *data = malloc(MAX_VAL(data_size, (size_t)1)); + if (!data) { + LOG_ERROR("Lua mod '%.*s' could not allocate a queued console command", STR_ARG(context->mod_id)); + return true; + } + + if (name.len > 0) { + mem_copy(data, name.data, name.len); + } + + if (args.len > 0) { + mem_copy(data + name.len, args.data, args.len); + } + + bool queued = false; + if (lua_ue4ss_pending_lock(context)) { + if (context->pending_command_count < CONFIG_LUA_UE4SS_MAX_PENDING_COMMANDS) { + context->pending_commands[context->pending_command_count++] = (lua_ue4ss_pending_command_t){ + .data = data, + .name_len = name.len, + .args_len = args.len, + }; + queued = true; + } else { + context->pending_command_overflow = true; + } + lua_ue4ss_pending_unlock(context); + } + + if (!queued) { + free(data); + } else if (context->wake_async) { + context->wake_async(context->wake_async_user); + } + + /* a registered command remains claimed even if its bounded queue overflowed */ + return true; +} + +static void +lua_ue4ss_dispatch_pending_inputs(lua_ue4ss_context_t *context) +{ + input_event_t pending[CONFIG_LUA_UE4SS_MAX_PENDING_INPUTS]; + int pending_count = 0; + bool overflow = false; + if (!context || !context->pending_inputs || !lua_ue4ss_pending_lock(context)) { + return; + } + + pending_count = context->pending_input_count; + if (pending_count > 0) { + mem_copy(pending, context->pending_inputs, (uint64_t)pending_count * sizeof(*pending)); + } + + context->pending_input_count = 0; + overflow = context->pending_input_overflow; + context->pending_input_overflow = false; + lua_ue4ss_pending_unlock(context); + + if (overflow) { + LOG_WARN("Lua mod '%.*s' input queue overflowed; some callbacks were dropped", STR_ARG(context->mod_id)); + } + + for (int i = 0; i < pending_count; ++i) { + lua_ue4ss_dispatch_keybinds(context, &pending[i]); + } +} + +static void +lua_ue4ss_dispatch_pending_commands(lua_ue4ss_context_t *context) +{ + lua_ue4ss_pending_command_t pending[CONFIG_LUA_UE4SS_MAX_PENDING_COMMANDS]; + int pending_count = 0; + bool overflow = false; + if (!context || !context->pending_commands || !lua_ue4ss_pending_lock(context)) { + return; + } + + pending_count = context->pending_command_count; + if (pending_count > 0) { + mem_copy(pending, context->pending_commands, (uint64_t)pending_count * sizeof(*pending)); + mem_zero(context->pending_commands, (uint64_t)pending_count * sizeof(*pending)); + } + + context->pending_command_count = 0; + overflow = context->pending_command_overflow; + context->pending_command_overflow = false; + lua_ue4ss_pending_unlock(context); + + if (overflow) { + LOG_WARN("Lua mod '%.*s' console command queue overflowed; some callbacks were dropped", STR_ARG(context->mod_id)); + } + + for (int i = 0; i < pending_count; ++i) { + lua_ue4ss_pending_command_t *command = &pending[i]; + + str_t name = str_make(command->data, command->name_len); + str_t args = str_make(command->data + command->name_len, command->args_len); + lua_ue4ss_dispatch_command(context, name, args, NULL); + free(command->data); + } +} + +static void +lua_ue4ss_dispatch_keybinds(lua_ue4ss_context_t *context, input_event_t *ev) +{ + if (!context || !context->runtime || !context->runtime->inited || !ev) { + return; + } + + lua_State *state = context->runtime->state; + int callback_refs[CONFIG_LUA_UE4SS_MAX_KEYBINDS]; + int callback_count = 0; + if (!lua_ue4ss_pending_lock(context)) { + return; + } + + for (int i = 0; i < context->keybind_count; ++i) { + lua_ue4ss_keybind_t *keybind = &context->keybinds[i]; + if (keybind->callback_ref != LUA_NOREF && keybind->callback_ref != LUA_REFNIL && + keybind_activated_by_event(keybind->bind, ev)) { + callback_refs[callback_count++] = keybind->callback_ref; + } + } + lua_ue4ss_pending_unlock(context); + + for (int i = 0; i < callback_count; ++i) { + int callback_ref = callback_refs[i]; + lua_settop(state, 0); + if (!lua_ue4ss_call_ref(context, callback_ref, 0, 0, CONFIG_LUA_UE4SS_EXECUTION_LIMIT_US, true, 0, NULL) && lua_ue4ss_pending_lock(context)) { + for (int keybind_idx = 0; keybind_idx < context->keybind_count; ++keybind_idx) { + if (context->keybinds[keybind_idx].callback_ref == callback_ref) { + lua_ue4ss_disable_callback(context, &context->keybinds[keybind_idx].callback_ref); + break; + } + } + lua_ue4ss_pending_unlock(context); + } + lua_settop(state, 0); + } +} + +bool +lua_ue4ss_dispatch_command(lua_ue4ss_context_t *context, str_t name, str_t args, bool *handled) +{ + if (handled) { + *handled = false; + } + + if (!context || !context->runtime || !context->runtime->inited || str_is_empty(name)) { + return false; + } + + for (int i = 0; i < context->command_count; ++i) { + lua_ue4ss_command_t *command = &context->commands[i]; + if (!str_equal(command->name, name, STR_CMP_FLAG_IGNORE_CASE)) { + continue; + } + + lua_State *state = context->runtime->state; + lua_settop(state, 0); + + luaL_Buffer full_command; + luaL_buffinit(state, &full_command); + luaL_addlstring(&full_command, (const char *)name.data, (size_t)name.len); + if (!str_is_empty(args)) { + luaL_addchar(&full_command, ' '); + luaL_addlstring(&full_command, (const char *)args.data, (size_t)args.len); + } + + luaL_pushresult(&full_command); + lua_ue4ss_push_command_parts(state, args); + lua_pushnil(state); + + bool called = lua_ue4ss_call_ref(context, command->callback_ref, 3, 1, CONFIG_LUA_UE4SS_EXECUTION_LIMIT_US, true, 0, NULL); + bool result = called && lua_toboolean(state, -1) != 0; + lua_settop(state, 0); + if (handled) { + *handled = called ? result : true; + } + return true; + } + return false; +} + +static bool +lua_ue4ss_hook_call(lua_ue4ss_context_t *context, lua_ue4ss_hook_t *hook, int *callback_ref_slot, uobject_t *object, ufunc_t *function, void *params) +{ + if (!context || !hook || !callback_ref_slot || !object || !function || *callback_ref_slot == LUA_NOREF || *callback_ref_slot == LUA_REFNIL) { + return false; + } + + lua_State *state = context->runtime->state; + int stack_base = lua_gettop(state); + int callback_ref = *callback_ref_slot; + int scope_ref = lua_unreal_param_scope_begin(state); + int arg_count = 0; + bool marshalled = scope_ref != LUA_NOREF && lua_unreal_remote_object_param_push(state, scope_ref, object) != 0; + if (marshalled) { + arg_count = 1; + } + + for (ffield_t *field = function->child_props; field && marshalled; field = field->next) { + fprop_t *prop = (fprop_t *)field; + if (!(prop->prop_flags & CPF_PARM) || (prop->prop_flags & CPF_RETURN_PARM)) { + continue; + } + + uint64_t complete_size = unreal_fprop_complete_size(prop); + bool fits = params && prop->offset_internal >= 0 && complete_size > 0 && + (uint64_t)prop->offset_internal <= function->params_size && + complete_size <= (uint64_t)function->params_size - (uint64_t)prop->offset_internal; + + void *value = fits ? unreal_fprop_value_in_container(prop, params, 0) : NULL; + bool writable = true; + if (!value || !lua_unreal_remote_param_push(state, scope_ref, prop, value, object, writable)) { + marshalled = false; + break; + } + + arg_count += 1; + } + + uint64_t callback_start = time_now_us(); + bool called = marshalled && lua_ue4ss_call_ref(context, callback_ref, arg_count, 0, CONFIG_LUA_UE4SS_EXECUTION_LIMIT_US, true, 0, NULL); + uint64_t callback_end = time_now_us(); + lua_unreal_param_scope_end(state, scope_ref); + lua_settop(state, stack_base); + + bool post = callback_ref_slot == &hook->post_callback_ref; + bool *slow_warned = post ? &hook->post_slow_warned : &hook->pre_slow_warned; + uint64_t callback_us = callback_end >= callback_start ? callback_end - callback_start : 0; + if (!context->async_events && marshalled && callback_us > CONFIG_LUA_UE4SS_GAME_DISPATCH_BUDGET_US && !*slow_warned) { + LOG_WARN("Lua mod '%.*s' %s-hook '%.*s' took %llu us (soft frame budget: %llu us)", + STR_ARG(context->mod_id), + post ? "post" : "pre", + STR_ARG(hook->target), + (unsigned long long)callback_us, + (unsigned long long)CONFIG_LUA_UE4SS_GAME_DISPATCH_BUDGET_US); + *slow_warned = true; + } + + if (!called && *callback_ref_slot == callback_ref) { + if (!marshalled) { + LOG_ERROR("Lua hook '%.*s' has an unsupported or invalid reflected parameter schema", STR_ARG(hook->target)); + } + lua_ue4ss_disable_callback(context, callback_ref_slot); + } + return called; +} + +static void +lua_ue4ss_pending_hook_destroy(lua_ue4ss_pending_hook_t *pending) +{ + if (!pending) { + return; + } + + if (pending->params && pending->function_raw) { + uint32_t destroyed = 0; + for (ffield_t *field = pending->function_raw->child_props; field && destroyed < pending->initialized_count; field = field->next) { + fprop_t *prop = (fprop_t *)field; + if (prop->prop_flags & CPF_PARM) { + unreal_fprop_destroy_in_container(prop, pending->params); + destroyed += 1; + } + } + } + + free(pending->params); + *pending = (lua_ue4ss_pending_hook_t){0}; +} + +static bool +lua_ue4ss_pending_hook_snapshot(lua_ue4ss_pending_hook_t *pending, uobject_t *object, ufunc_t *function, void *params, bool post) +{ + if (!pending || !object || !function || !unreal_fweak_object_from_object(object, &pending->object) || + !unreal_fweak_object_from_object((uobject_t *)function, &pending->function)) { + return false; + } + + pending->function_raw = function; + pending->post = post; + if (function->params_size == 0) { + return true; + } + + if (!params) { + return false; + } + + pending->params = malloc((size_t)function->params_size); + if (!pending->params) { + return false; + } + mem_zero(pending->params, function->params_size); + + for (ffield_t *field = function->child_props; field; field = field->next) { + fprop_t *prop = (fprop_t *)field; + if (!(prop->prop_flags & CPF_PARM)) { + continue; + } + + void *dst = unreal_fprop_value_in_container(prop, pending->params, 0); + void *src = unreal_fprop_value_in_container(prop, params, 0); + if (!dst || !src || !unreal_fprop_initialize_value(prop, dst)) { + lua_ue4ss_pending_hook_destroy(pending); + return false; + } + pending->initialized_count += 1; + + if (!unreal_fprop_copy_complete_value(prop, dst, src)) { + lua_ue4ss_pending_hook_destroy(pending); + return false; + } + } + return true; +} + +static bool +lua_ue4ss_queue_process_event(lua_ue4ss_context_t *context, uobject_t *object, ufunc_t *function, void *params, bool post) +{ + if (!context || !context->pending_hooks || !object || !function || !lua_ue4ss_pending_lock(context)) { + return false; + } + + bool matches = false; + for (int i = 0; i < context->hook_count; ++i) { + lua_ue4ss_hook_t *hook = &context->hooks[i]; + int callback_ref = post ? hook->post_callback_ref : hook->pre_callback_ref; + if (hook->active && callback_ref != LUA_NOREF && callback_ref != LUA_REFNIL && unreal_fweak_object_resolve(hook->function) == (uobject_t *)function) { + matches = true; + break; + } + } + lua_ue4ss_pending_unlock(context); + + if (!matches) { + return false; + } + + lua_ue4ss_pending_hook_t pending = {0}; + if (!lua_ue4ss_pending_hook_snapshot(&pending, object, function, params, post)) { + LOG_ERROR("Lua mod '%.*s' could not snapshot UFunction hook parameters", STR_ARG(context->mod_id)); + return false; + } + + bool queued = false; + if (lua_ue4ss_pending_lock(context)) { + if (context->pending_hook_count < CONFIG_LUA_UE4SS_MAX_PENDING_HOOKS) { + context->pending_hooks[context->pending_hook_count++] = pending; + queued = true; + } else { + context->pending_hook_overflow = true; + } + lua_ue4ss_pending_unlock(context); + } + + if (!queued) { + lua_ue4ss_pending_hook_destroy(&pending); + return false; + } + + if (context->wake_async) { + context->wake_async(context->wake_async_user); + } + return true; +} + +static void +lua_ue4ss_dispatch_pending_hooks(lua_ue4ss_context_t *context) +{ + if (!context || !context->runtime || !context->runtime->inited || !context->pending_hooks) { + return; + } + + lua_ue4ss_pending_hook_t pending[CONFIG_LUA_UE4SS_MAX_PENDING_HOOKS]; + int pending_count = 0; + bool overflow = false; + if (!lua_ue4ss_pending_lock(context)) { + return; + } + + pending_count = context->pending_hook_count; + if (pending_count > 0) { + mem_copy(pending, context->pending_hooks, (uint64_t)pending_count * sizeof(*pending)); + mem_zero(context->pending_hooks, (uint64_t)pending_count * sizeof(*pending)); + } + + context->pending_hook_count = 0; + overflow = context->pending_hook_overflow; + context->pending_hook_overflow = false; + lua_ue4ss_pending_unlock(context); + + if (overflow) { + LOG_WARN("Lua mod '%.*s' UFunction hook queue overflowed; some callbacks were dropped", STR_ARG(context->mod_id)); + } + + for (int i = 0; i < pending_count; ++i) { + lua_ue4ss_pending_hook_t *event = &pending[i]; + uobject_t *object = unreal_fweak_object_resolve(event->object); + ufunc_t *function = (ufunc_t *)unreal_fweak_object_resolve(event->function); + if (object && function == event->function_raw) { + lua_ue4ss_dispatch_process_event(context, object, function, event->params, event->post); + } + lua_ue4ss_pending_hook_destroy(event); + } +} + +static void +lua_ue4ss_dispatch_process_event(lua_ue4ss_context_t *context, uobject_t *obj, ufunc_t *func, void *params, bool post) +{ + if (!context || !context->runtime || !context->runtime->inited || !obj || !func) { + return; + } + + int hook_count = context->hook_count; + for (int i = 0; i < hook_count; ++i) { + lua_ue4ss_hook_t *hook = &context->hooks[i]; + if (!hook->active || unreal_fweak_object_resolve(hook->function) != (uobject_t *)func) { + continue; + } + lua_ue4ss_hook_call(context, hook, post ? &hook->post_callback_ref : &hook->pre_callback_ref, obj, func, params); + } +} + +bool +lua_ue4ss_dispatch_process_event_pre(lua_ue4ss_context_t *context, uobject_t *obj, ufunc_t *func, void *params) +{ + if (context && context->async_events) { + lua_ue4ss_queue_process_event(context, obj, func, params, false); + } else { + lua_ue4ss_dispatch_process_event(context, obj, func, params, false); + } + return false; +} + +void +lua_ue4ss_dispatch_process_event_post(lua_ue4ss_context_t *context, uobject_t *obj, ufunc_t *func, void *params, bool consumed) +{ + (void)consumed; + if (context && context->async_events) { + lua_ue4ss_queue_process_event(context, obj, func, params, true); + } else { + lua_ue4ss_dispatch_process_event(context, obj, func, params, true); + } +} diff --git a/src/lua_ue4ss_runtime.c b/src/lua_ue4ss_runtime.c new file mode 100644 index 0000000..3cf6f9c --- /dev/null +++ b/src/lua_ue4ss_runtime.c @@ -0,0 +1,619 @@ +#include "lua_ue4ss_runtime.h" + +#include "config.h" +#include "file.h" +#include "globals.h" +#include "log.h" +#include "lua_runtime.h" +#include "lua_ue4ss.h" +#include "lua_unreal_prop.h" +#include "mod_manager.h" +#include "scratch.h" +#include "types.h" + +#include + +typedef struct lua_ue4ss_runtime_s lua_ue4ss_runtime_t; +struct lua_ue4ss_runtime_s { + void *worker; + arena_t perm; + lua_runtime_t lua; + lua_unreal_context_t unreal; + lua_ue4ss_context_t api; +}; + +typedef struct lua_ue4ss_game_call_s lua_ue4ss_game_call_t; +struct lua_ue4ss_game_call_s { + uobject_t *receiver; + ufunc_t *function; + void *params; + volatile LONG executed; +}; + +typedef struct lua_ue4ss_worker_s lua_ue4ss_worker_t; +struct lua_ue4ss_worker_s { + mod_t *mod; + HANDLE thread; + HANDLE ready_event; + HANDLE wake_event; + HANDLE game_call_request_event; + HANDLE game_call_complete_event; + lua_ue4ss_game_call_t *volatile pending_game_call; + CRITICAL_SECTION state_lock; + volatile LONG stop_requested; + volatile LONG status; + char error[CONFIG_MOD_MANAGER_ERROR_MSG_MAX_LEN]; + int error_len; +}; + +enum { + LUA_UE4SS_WORKER_STARTING = 0, + LUA_UE4SS_WORKER_ACTIVE, + LUA_UE4SS_WORKER_FAILED, + LUA_UE4SS_WORKER_STOPPED, +}; + +static CRITICAL_SECTION g_lua_ue4ss_notification_lock = {0}; +static volatile LONG g_lua_ue4ss_notification_lock_ready = 0; + +static lua_ue4ss_runtime_t * +lua_ue4ss_runtime_from_mod(mod_t *mod) +{ + return mod ? (lua_ue4ss_runtime_t *)mod->lua.instance : NULL; +} + +static void +lua_ue4ss_error_set(err_msg_t *error, str_t message) +{ + error->len = (int)MIN_VAL(message.len, sizeof(error->msg)); + mem_copy(error->msg, message.data, error->len); +} + +static LONG +lua_ue4ss_worker_status(lua_ue4ss_worker_t *worker) +{ + return worker ? InterlockedCompareExchange(&worker->status, 0, 0) : LUA_UE4SS_WORKER_STOPPED; +} + +static void +lua_ue4ss_worker_set_error(lua_ue4ss_worker_t *worker, str_t error) +{ + if (!worker) { + return; + } + + worker->error_len = (int)MIN_VAL(error.len, (uint64_t)(sizeof(worker->error) - 1)); + if (worker->error_len > 0) { + mem_copy(worker->error, error.data, (uint64_t)worker->error_len); + } + worker->error[worker->error_len] = 0; +} + +static bool +lua_ue4ss_unreal_access_check(void *user) +{ + mod_t *mod = (mod_t *)user; + return mod && mod->manifest.lua.runtime_kind == MOD_LUA_RUNTIME_UE4SS && globals.game_thread_id != 0 && globals.unreal.core_object != NULL; +} + +static bool +lua_ue4ss_unreal_process_event(void *user, uobject_t *receiver, ufunc_t *function, void *params) +{ + mod_t *mod = (mod_t *)user; + if (!mod || !receiver || !function || globals.game_thread_id == 0) { + return false; + } + + if (unreal_is_in_game_thread()) { + unreal_process_event_observed(receiver, function, params); + return true; + } + + lua_ue4ss_runtime_t *runtime = lua_ue4ss_runtime_from_mod(mod); + lua_ue4ss_worker_t *worker = runtime ? (lua_ue4ss_worker_t *)runtime->worker : NULL; + if (!worker || !worker->game_call_request_event || !worker->game_call_complete_event || + InterlockedCompareExchange(&worker->stop_requested, 0, 0)) { + return false; + } + + lua_ue4ss_game_call_t call = { + .receiver = receiver, + .function = function, + .params = params, + }; + + ResetEvent(worker->game_call_complete_event); + if (InterlockedCompareExchange(&worker->stop_requested, 0, 0)) { + return false; + } + + if (InterlockedCompareExchangePointer((PVOID volatile *)&worker->pending_game_call, &call, NULL) != NULL) { + return false; + } + + SetEvent(worker->game_call_request_event); + + DWORD wait_result = WaitForSingleObject(worker->game_call_complete_event, INFINITE); + if (wait_result != WAIT_OBJECT_0) { + InterlockedCompareExchangePointer((PVOID volatile *)&worker->pending_game_call, NULL, &call); + return false; + } + return InterlockedCompareExchange(&call.executed, 0, 0) != 0; +} + +static bool +lua_ue4ss_dispatch_pending_game_call(mod_t *mod) +{ + lua_ue4ss_runtime_t *runtime = lua_ue4ss_runtime_from_mod(mod); + lua_ue4ss_worker_t *worker = runtime ? (lua_ue4ss_worker_t *)runtime->worker : NULL; + if (!worker) { + return false; + } + + lua_ue4ss_game_call_t *call = (lua_ue4ss_game_call_t *)InterlockedExchangePointer((PVOID volatile *)&worker->pending_game_call, NULL); + if (!call) { + return false; + } + + ResetEvent(worker->game_call_request_event); + if (call->receiver && call->function && unreal_uobject_is_valid(call->receiver) && unreal_uobject_is_valid((uobject_t *)call->function)) { + unreal_process_event_observed(call->receiver, call->function, call->params); + InterlockedExchange(&call->executed, 1); + } + SetEvent(worker->game_call_complete_event); + return true; +} + +static void +lua_ue4ss_cleanup(mod_t *mod) +{ + lua_ue4ss_runtime_t *runtime = lua_ue4ss_runtime_from_mod(mod); + if (!runtime) { + mod->lua.active = false; + return; + } + + lua_ue4ss_context_deinit(&runtime->api); + lua_runtime_deinit(&runtime->lua); + arena_destroy(&runtime->perm); + HeapFree(GetProcessHeap(), 0, runtime); + + mod->lua.instance = NULL; + mod->lua.active = false; +} + +static void +lua_ue4ss_wake_worker(void *user) +{ + lua_ue4ss_worker_t *worker = (lua_ue4ss_worker_t *)user; + if (worker && worker->wake_event) { + SetEvent(worker->wake_event); + } +} + +static bool +lua_ue4ss_worker_init_runtime(lua_ue4ss_worker_t *worker) +{ + mod_t *mod = worker->mod; + lua_ue4ss_runtime_t *runtime = lua_ue4ss_runtime_from_mod(mod); + if (!runtime) { + lua_ue4ss_worker_set_error(worker, STR_LIT("UE4SS runtime instance is unavailable")); + return false; + } + + if (!lua_runtime_init_with_execution_limit(&runtime->lua, CONFIG_LUA_UE4SS_EXECUTION_LIMIT_US) || !lua_runtime_enable_mod_libs(&runtime->lua)) { + lua_ue4ss_worker_set_error(worker, STR_LIT("failed to initialize Lua runtime")); + return false; + } + runtime->lua.persistent_output = true; + + runtime->api = (lua_ue4ss_context_t){ + .game_dir = mod->lua.game_dir, + .root_mod_dir = mod->lua.root_mod_dir, + .mod_dir = mod->manifest.mod_dir, + .mod_dir_name = mod->manifest.mod_dir_name, + .mod_id = mod->manifest.info.id, + .entry_path = mod->manifest.lua.path, + }; + + runtime->perm = arena_new_dynamic(CONFIG_LUA_UE4SS_ARENA_RESERVE_SIZE, CONFIG_LUA_UE4SS_ARENA_COMMIT_SIZE); + if (!lua_ue4ss_context_init(&runtime->api, &runtime->perm, &runtime->lua)) { + lua_ue4ss_worker_set_error(worker, STR_LIT("failed to allocate UE4SS runtime structures")); + return false; + } + + runtime->api.wake_async = lua_ue4ss_wake_worker; + runtime->api.wake_async_user = worker; + runtime->api.async_events = true; + + lua_unreal_context_init(&runtime->unreal); + runtime->unreal.user = mod; + runtime->unreal.access_check = lua_ue4ss_unreal_access_check; + runtime->unreal.process_event = lua_ue4ss_unreal_process_event; + + if (!lua_unreal_register(runtime->lua.state, &runtime->unreal) || !lua_ue4ss_register(runtime->lua.state, &runtime->api)) { + lua_ue4ss_worker_set_error(worker, STR_LIT("failed to register UE4SS Lua APIs")); + return false; + } + + runtime->lua.execution_limit_us = CONFIG_LUA_UE4SS_EXECUTION_LIMIT_US; + bool executed = lua_runtime_execute_file(&runtime->lua, mod->manifest.lua.path); + runtime->lua.execution_limit_us = CONFIG_LUA_UE4SS_EXECUTION_LIMIT_US; + if (!executed) { + lua_ue4ss_worker_set_error(worker, STR_LIT("Lua entry script failed")); + LOG_ERROR("Lua mod '%.*s' failed to start from '%.*s'", STR_ARG(mod->manifest.info.id), STR_ARG(mod->manifest.lua.path)); + return false; + } + return true; +} + +static DWORD WINAPI +lua_ue4ss_worker_main(void *user) +{ + lua_ue4ss_worker_t *worker = (lua_ue4ss_worker_t *)user; + EnterCriticalSection(&worker->state_lock); + bool initialized = lua_ue4ss_worker_init_runtime(worker); + LeaveCriticalSection(&worker->state_lock); + + if (!initialized) { + InterlockedExchange(&worker->status, LUA_UE4SS_WORKER_FAILED); + SetEvent(worker->ready_event); + scratch_destroy(); + return 0; + } + + InterlockedExchange(&worker->status, LUA_UE4SS_WORKER_ACTIVE); + SetEvent(worker->ready_event); + while (!InterlockedCompareExchange(&worker->stop_requested, 0, 0)) { + lua_ue4ss_runtime_t *runtime = lua_ue4ss_runtime_from_mod(worker->mod); + if (!runtime) { + break; + } + + EnterCriticalSection(&worker->state_lock); + lua_ue4ss_dispatch_async(&runtime->api); + uint32_t wait_ms = lua_ue4ss_async_wait_ms(&runtime->api); + LeaveCriticalSection(&worker->state_lock); + + if (InterlockedCompareExchange(&worker->stop_requested, 0, 0)) { + break; + } + WaitForSingleObject(worker->wake_event, wait_ms); + } + + InterlockedExchange(&worker->status, LUA_UE4SS_WORKER_STOPPED); + scratch_destroy(); + return 0; +} + +static void +lua_ue4ss_worker_destroy(mod_t *mod) +{ + lua_ue4ss_runtime_t *runtime = lua_ue4ss_runtime_from_mod(mod); + lua_ue4ss_worker_t *worker = runtime ? (lua_ue4ss_worker_t *)runtime->worker : NULL; + if (!worker) { + return; + } + + InterlockedExchange(&worker->stop_requested, 1); + if (worker->wake_event) { + SetEvent(worker->wake_event); + } + + if (worker->ready_event) { + SetEvent(worker->ready_event); + } + + InterlockedExchangePointer((PVOID volatile *)&worker->pending_game_call, NULL); + + if (worker->game_call_request_event) { + SetEvent(worker->game_call_request_event); + } + + if (worker->game_call_complete_event) { + SetEvent(worker->game_call_complete_event); + } + + if (worker->thread) { + WaitForSingleObject(worker->thread, INFINITE); + CloseHandle(worker->thread); + } + + if (worker->wake_event) { + CloseHandle(worker->wake_event); + } + + if (worker->ready_event) { + CloseHandle(worker->ready_event); + } + + if (worker->game_call_request_event) { + CloseHandle(worker->game_call_request_event); + } + + if (worker->game_call_complete_event) { + CloseHandle(worker->game_call_complete_event); + } + + DeleteCriticalSection(&worker->state_lock); + HeapFree(GetProcessHeap(), 0, worker); + runtime->worker = NULL; +} + +static void +lua_ue4ss_sync_worker_state(mod_t *mod) +{ + lua_ue4ss_runtime_t *runtime = lua_ue4ss_runtime_from_mod(mod); + lua_ue4ss_worker_t *worker = runtime ? (lua_ue4ss_worker_t *)runtime->worker : NULL; + if (!worker) { + return; + } + + LONG status = lua_ue4ss_worker_status(worker); + if (status == LUA_UE4SS_WORKER_ACTIVE && !mod->lua.active) { + mod->lua.active = true; + LOG_INFO("Lua mod '%.*s' started on UE4SS compatibility worker thread", STR_ARG(mod->manifest.info.id)); + } else if (status == LUA_UE4SS_WORKER_FAILED) { + str_t error = str_make(worker->error, (uint64_t)worker->error_len); + lua_ue4ss_error_set(&mod->lua.err_msg, str_is_empty(error) ? STR_LIT("UE4SS worker failed to start") : error); + lua_ue4ss_worker_destroy(mod); + if (InterlockedCompareExchange(&g_lua_ue4ss_notification_lock_ready, 0, 0)) { + EnterCriticalSection(&g_lua_ue4ss_notification_lock); + lua_ue4ss_cleanup(mod); + LeaveCriticalSection(&g_lua_ue4ss_notification_lock); + } else { + lua_ue4ss_cleanup(mod); + } + } +} + +static bool +lua_ue4ss_state_try_enter(mod_t *mod) +{ + lua_ue4ss_runtime_t *runtime = lua_ue4ss_runtime_from_mod(mod); + lua_ue4ss_worker_t *worker = runtime ? (lua_ue4ss_worker_t *)runtime->worker : NULL; + return worker && TryEnterCriticalSection(&worker->state_lock) != 0; +} + +static void +lua_ue4ss_state_leave(mod_t *mod) +{ + lua_ue4ss_runtime_t *runtime = lua_ue4ss_runtime_from_mod(mod); + lua_ue4ss_worker_t *worker = runtime ? (lua_ue4ss_worker_t *)runtime->worker : NULL; + if (worker) { + LeaveCriticalSection(&worker->state_lock); + } +} + +void +lua_ue4ss_runtime_system_init(void) +{ + if (!InterlockedCompareExchange(&g_lua_ue4ss_notification_lock_ready, 0, 0)) { + InitializeCriticalSection(&g_lua_ue4ss_notification_lock); + InterlockedExchange(&g_lua_ue4ss_notification_lock_ready, 1); + } +} + +bool +lua_ue4ss_runtime_start(mod_t *mod) +{ + if (!mod || !mod->has_lua || mod->manifest.lua.runtime_kind != MOD_LUA_RUNTIME_UE4SS) { + return false; + } + + if (!unreal_is_in_game_thread()) { + lua_ue4ss_error_set(&mod->lua.err_msg, STR_LIT("UE4SS Lua runtime can only be started from the game thread")); + return false; + } + + lua_ue4ss_runtime_t *runtime = lua_ue4ss_runtime_from_mod(mod); + if (mod->lua.active || runtime) { + return true; + } + + mod->lua.start_attempted = true; + lua_ue4ss_error_set(&mod->lua.err_msg, STR_NULL); + if (!file_exists(mod->manifest.lua.path)) { + lua_ue4ss_error_set(&mod->lua.err_msg, STR_LIT("Lua entry file does not exist")); + return false; + } + + runtime = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*runtime)); + if (!runtime) { + lua_ue4ss_error_set(&mod->lua.err_msg, STR_LIT("failed to allocate UE4SS Lua runtime")); + return false; + } + mod->lua.instance = runtime; + + lua_ue4ss_worker_t *worker = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*worker)); + if (!worker) { + lua_ue4ss_cleanup(mod); + lua_ue4ss_error_set(&mod->lua.err_msg, STR_LIT("failed to allocate UE4SS Lua worker")); + return false; + } + + worker->mod = mod; + InitializeCriticalSection(&worker->state_lock); + worker->ready_event = CreateEventA(NULL, TRUE, FALSE, NULL); + worker->wake_event = CreateEventA(NULL, FALSE, FALSE, NULL); + worker->game_call_request_event = CreateEventA(NULL, TRUE, FALSE, NULL); + worker->game_call_complete_event = CreateEventA(NULL, FALSE, FALSE, NULL); + + if (!worker->ready_event || !worker->wake_event || !worker->game_call_request_event || !worker->game_call_complete_event) { + if (worker->ready_event) { + CloseHandle(worker->ready_event); + } + + if (worker->wake_event) { + CloseHandle(worker->wake_event); + } + + if (worker->game_call_request_event) { + CloseHandle(worker->game_call_request_event); + } + + if (worker->game_call_complete_event) { + CloseHandle(worker->game_call_complete_event); + } + + DeleteCriticalSection(&worker->state_lock); + HeapFree(GetProcessHeap(), 0, worker); + lua_ue4ss_cleanup(mod); + lua_ue4ss_error_set(&mod->lua.err_msg, STR_LIT("failed to create UE4SS Lua worker events")); + return false; + } + + runtime->worker = worker; + worker->thread = CreateThread(NULL, 0, lua_ue4ss_worker_main, worker, 0, NULL); + if (!worker->thread) { + lua_ue4ss_worker_destroy(mod); + lua_ue4ss_cleanup(mod); + lua_ue4ss_error_set(&mod->lua.err_msg, STR_LIT("failed to create UE4SS compatibility worker thread")); + return false; + } + + /* finish the entry script before gameplay resumes, while servicing any reflected calls made during initialization on the game thread */ + HANDLE startup_events[] = {worker->ready_event, worker->game_call_request_event}; + DWORD wait_result = WAIT_FAILED; + while (1) { + wait_result = WaitForMultipleObjects((DWORD)COUNTOF(startup_events), startup_events, FALSE, INFINITE); + if (wait_result == WAIT_OBJECT_0) { + break; + } + + if (wait_result == WAIT_OBJECT_0 + 1) { + lua_ue4ss_dispatch_pending_game_call(mod); + continue; + } + break; + } + + if (wait_result != WAIT_OBJECT_0) { + lua_ue4ss_worker_set_error(worker, STR_LIT("failed while waiting for the UE4SS worker to initialize")); + InterlockedExchange(&worker->status, LUA_UE4SS_WORKER_FAILED); + } + lua_ue4ss_sync_worker_state(mod); + return mod->lua.active; +} + +void +lua_ue4ss_runtime_stop(mod_t *mod) +{ + if (!mod || !mod->has_lua || mod->manifest.lua.runtime_kind != MOD_LUA_RUNTIME_UE4SS || !unreal_is_in_game_thread()) { + return; + } + + lua_ue4ss_worker_destroy(mod); + if (InterlockedCompareExchange(&g_lua_ue4ss_notification_lock_ready, 0, 0)) { + EnterCriticalSection(&g_lua_ue4ss_notification_lock); + lua_ue4ss_cleanup(mod); + LeaveCriticalSection(&g_lua_ue4ss_notification_lock); + } else { + lua_ue4ss_cleanup(mod); + } + mod->lua.start_attempted = false; + LOG_INFO("Lua mod '%.*s' stopped", STR_ARG(mod->manifest.info.id)); +} + +bool +lua_ue4ss_runtime_is_initialized(mod_t *mod) +{ + return lua_ue4ss_runtime_from_mod(mod) != NULL; +} + +void +lua_ue4ss_runtime_tick(mod_t *mod) +{ + if (!mod || mod->manifest.lua.runtime_kind != MOD_LUA_RUNTIME_UE4SS) { + return; + } + + lua_ue4ss_sync_worker_state(mod); + if (mod->lua.active) { + lua_ue4ss_dispatch_pending_game_call(mod); + } + + if (mod->lua.active && lua_ue4ss_state_try_enter(mod)) { + lua_ue4ss_runtime_t *runtime = lua_ue4ss_runtime_from_mod(mod); + if (runtime) { + lua_ue4ss_dispatch_game_thread(&runtime->api); + } + lua_ue4ss_state_leave(mod); + } +} + +void +lua_ue4ss_runtime_queue_input(mod_t *mod, input_event_t *event) +{ + lua_ue4ss_runtime_t *runtime = lua_ue4ss_runtime_from_mod(mod); + if (runtime && mod->lua.active && mod->manifest.lua.runtime_kind == MOD_LUA_RUNTIME_UE4SS) { + lua_ue4ss_queue_input(&runtime->api, event); + } +} + +bool +lua_ue4ss_runtime_process_event_pre(mod_t *mod, uobject_t *object, ufunc_t *function, void *params) +{ + lua_ue4ss_runtime_t *runtime = lua_ue4ss_runtime_from_mod(mod); + if (runtime && mod->lua.active && mod->manifest.lua.runtime_kind == MOD_LUA_RUNTIME_UE4SS) { + lua_ue4ss_dispatch_process_event_pre(&runtime->api, object, function, params); + } + return false; +} + +void +lua_ue4ss_runtime_process_event_post(mod_t *mod, uobject_t *object, ufunc_t *function, void *params, bool consumed) +{ + lua_ue4ss_runtime_t *runtime = lua_ue4ss_runtime_from_mod(mod); + if (runtime && mod->lua.active && mod->manifest.lua.runtime_kind == MOD_LUA_RUNTIME_UE4SS) { + lua_ue4ss_dispatch_process_event_post(&runtime->api, object, function, params, consumed); + } +} + +bool +lua_ue4ss_runtime_queue_command(mod_t *mod, str_t name, str_t args) +{ + lua_ue4ss_runtime_t *runtime = lua_ue4ss_runtime_from_mod(mod); + return runtime && mod->lua.active && mod->manifest.lua.runtime_kind == MOD_LUA_RUNTIME_UE4SS && + lua_ue4ss_queue_command(&runtime->api, name, args); +} + +void +lua_ue4ss_runtime_notify_uobject_constructed(mod_manager_t *manager, uobject_t *object) +{ + if (!manager || !object || !InterlockedCompareExchange(&g_lua_ue4ss_notification_lock_ready, 0, 0)) { + return; + } + + EnterCriticalSection(&g_lua_ue4ss_notification_lock); + if (manager->mods) { + for (int i = 0; i < manager->mod_count; ++i) { + mod_t *mod = &manager->mods[i]; + lua_ue4ss_runtime_t *runtime = lua_ue4ss_runtime_from_mod(mod); + if (!mod->has_lua || mod->manifest.lua.runtime_kind != MOD_LUA_RUNTIME_UE4SS || + !runtime || !runtime->lua.inited || !runtime->api.pending_objects) { + continue; + } + lua_ue4ss_notify_uobject_constructed(&runtime->api, object); + } + } + LeaveCriticalSection(&g_lua_ue4ss_notification_lock); +} + +int +lua_ue4ss_runtime_snapshot_commands(mod_t *mod, str_t *names, int capacity) +{ + lua_ue4ss_runtime_t *runtime = lua_ue4ss_runtime_from_mod(mod); + if (!mod || !names || capacity <= 0 || !mod->lua.active || + mod->manifest.lua.runtime_kind != MOD_LUA_RUNTIME_UE4SS || !runtime || !lua_ue4ss_state_try_enter(mod)) { + return 0; + } + + int count = MIN_VAL(runtime->api.command_count, capacity); + for (int i = 0; i < count; ++i) { + names[i] = runtime->api.commands[i].name; + } + + lua_ue4ss_state_leave(mod); + return count; +} diff --git a/src/lua_unreal_prop.c b/src/lua_unreal_prop.c new file mode 100644 index 0000000..c89a23a --- /dev/null +++ b/src/lua_unreal_prop.c @@ -0,0 +1,6167 @@ +#include "lua_unreal_prop.h" + +#include "globals.h" +#include "scratch.h" + +#include "lua/src/lauxlib.h" +#include "lua/src/lua.h" + +#include +#include + +#define LUA_UNREAL_OBJECT_MT "overdub.Unreal.Object" +#define LUA_UNREAL_PROXY_MT "overdub.Unreal.StructProxy" +#define LUA_UNREAL_OWNED_MT "overdub.Unreal.OwnedValue" +#define LUA_UNREAL_FNAME_MT "overdub.Unreal.FName" +#define LUA_UNREAL_PARAM_MT "overdub.Unreal.Param" +#define LUA_UNREAL_FTEXT_MT "overdub.Unreal.FTextLiteral" +#define LUA_UNREAL_DATA_TABLE_ROW_MT "overdub.Unreal.DataTableRow" +#define LUA_UNREAL_PROPERTY_MT "overdub.Unreal.Property" +#define LUA_UNREAL_FIELD_CLASS_MT "overdub.Unreal.FieldClass" +#define LUA_UNREAL_REFLECTION_MT "overdub.Unreal.Reflection" + +#define LUA_UNREAL_MAX_ALIGNMENT (4096) +#define LUA_UNREAL_ERROR_CAP (256) + +typedef struct lua_unreal_object_s lua_unreal_object_t; +struct lua_unreal_object_s { + lua_unreal_context_t *context; + fweak_object_ptr_t weak; +}; + +typedef struct lua_unreal_data_table_row_s lua_unreal_data_table_row_t; +struct lua_unreal_data_table_row_s { + lua_unreal_context_t *context; + fweak_object_ptr_t table; + fname_t row_name; +}; + +typedef struct lua_unreal_proxy_s lua_unreal_proxy_t; +typedef int lua_unreal_selector_kind_t; +enum { + LUA_UNREAL_SELECTOR_FIELD, + LUA_UNREAL_SELECTOR_FIXED_ARRAY_ELEMENT, + LUA_UNREAL_SELECTOR_ARRAY_ELEMENT, + LUA_UNREAL_SELECTOR_MAP_KEY, + LUA_UNREAL_SELECTOR_MAP_VALUE, +}; + +struct lua_unreal_proxy_s { + lua_unreal_context_t *context; + fprop_t *prop; + lua_unreal_selector_kind_t selector_kind; + int32_t selector_index; +}; + +typedef struct lua_unreal_owned_s lua_unreal_owned_t; +struct lua_unreal_owned_s { + lua_unreal_context_t *context; + fprop_t *prop; + fweak_object_ptr_t owner; + uint32_t value_offset; + bool initialized; +}; + +typedef struct lua_unreal_param_s lua_unreal_param_t; +typedef struct lua_unreal_param_scope_s lua_unreal_param_scope_t; + +typedef enum { + LUA_UNREAL_PARAM_PROXY, + LUA_UNREAL_PARAM_BORROWED, + LUA_UNREAL_PARAM_OBJECT, +} lua_unreal_param_kind_t; + +struct lua_unreal_param_scope_s { + bool active; +}; + +struct lua_unreal_param_s { + lua_unreal_context_t *context; + lua_unreal_param_scope_t *scope; + lua_unreal_param_kind_t kind; + fprop_t *prop; + void *value; + fweak_object_ptr_t owner; + fweak_object_ptr_t object; + bool writable; + bool is_local; +}; + +typedef struct lua_unreal_ftext_literal_s lua_unreal_ftext_literal_t; +struct lua_unreal_ftext_literal_s { + lua_unreal_context_t *context; + size_t len; + char text[1]; +}; + +typedef struct lua_unreal_property_s lua_unreal_property_t; +struct lua_unreal_property_s { + lua_unreal_context_t *context; + fprop_t *prop; +}; + +typedef struct lua_unreal_field_class_s lua_unreal_field_class_t; +struct lua_unreal_field_class_s { + lua_unreal_context_t *context; + ffield_class_t *cls; +}; + +typedef struct lua_unreal_reflection_s lua_unreal_reflection_t; +struct lua_unreal_reflection_s { + lua_unreal_context_t *context; + fweak_object_ptr_t object; +}; + +typedef struct lua_unreal_method_s lua_unreal_method_t; +struct lua_unreal_method_s { + lua_unreal_context_t *context; + fweak_object_ptr_t receiver; + fweak_object_ptr_t function; +}; + +typedef struct lua_unreal_fname_s lua_unreal_fname_t; +struct lua_unreal_fname_s { + fname_t value; +}; + +static const char g_lua_unreal_context_registry_key = 0; + +static bool lua_unreal_write_transactional (lua_State *state, int value_idx, fprop_t *prop, void *dst, uobject_t *owner, char *error, size_t error_cap); +static int lua_unreal_prop_push_internal (lua_State *state, fprop_t *prop, void *value, uobject_t *owner, int parent_idx, bool live_proxy); +static int lua_unreal_prop_push_selected (lua_State *state, fprop_t *prop, void *value, uobject_t *owner, int parent_idx, bool live_proxy, lua_unreal_selector_kind_t selector_kind, int32_t selector_index, bool single_element); +static int lua_unreal_object_index (lua_State *state); +static int lua_unreal_object_newindex (lua_State *state); +static int lua_unreal_object_call_function_lua(lua_State *state); +static int lua_unreal_ufunction_call_lua (lua_State *state); +static bool lua_unreal_value_is_fixed_element (lua_State *state, int idx); +static bool lua_unreal_data_table_row_resolve (lua_unreal_data_table_row_t *row, udata_table_t **out_table, uscript_struct_t **out_row_struct, uint8_t **out_value); + +static void +lua_unreal_error_set(char *error, size_t cap, const char *fmt, ...) +{ + if (!error || cap == 0 || error[0] != '\0') { + return; + } + + va_list args; + va_start(args, fmt); + vsnprintf(error, cap, fmt, args); + va_end(args); + error[cap - 1] = '\0'; +} + +static uint32_t +lua_unreal_check_u32(lua_State *state, int idx, const char *description) +{ + lua_Integer value = luaL_checkinteger(state, idx); + if (value < 0 || (lua_Unsigned)value > UINT32_MAX) { + luaL_argerror(state, idx, description); + } + return (uint32_t)value; +} + +void +lua_unreal_context_init(lua_unreal_context_t *context) +{ + if (context) { + *context = (lua_unreal_context_t){0}; + } +} + +static lua_unreal_context_t * +lua_unreal_context_from_state(lua_State *state) +{ + lua_rawgetp(state, LUA_REGISTRYINDEX, &g_lua_unreal_context_registry_key); + lua_unreal_context_t *context = (lua_unreal_context_t *)lua_touserdata(state, -1); + lua_pop(state, 1); + return context; +} + +static bool +lua_unreal_access_allowed(lua_unreal_context_t *context) +{ + if (!context) { + return false; + } + + if (context->access_check) { + return context->access_check(context->user); + } + + return globals.engine_inited && unreal_is_in_game_thread(); +} + +static int +lua_unreal_require_access(lua_State *state, lua_unreal_context_t *context) +{ + if (!lua_unreal_access_allowed(context)) { + return luaL_error(state, "Unreal access is only available on the initialized game thread"); + } + return 0; +} + +static lua_unreal_object_t * +lua_unreal_object_test(lua_State *state, int idx) +{ + return (lua_unreal_object_t *)luaL_testudata(state, idx, LUA_UNREAL_OBJECT_MT); +} + +static uobject_t * +lua_unreal_object_resolve(lua_unreal_object_t *userdata) +{ + return userdata ? unreal_fweak_object_resolve(userdata->weak) : NULL; +} + +uobject_t * +lua_unreal_object_get(lua_State *state, int idx) +{ + return state ? lua_unreal_object_resolve(lua_unreal_object_test(state, idx)) : NULL; +} + +int +lua_unreal_object_push(lua_State *state, uobject_t *object) +{ + if (!state || !object) { + if (state) { + lua_pushnil(state); + return 1; + } + return 0; + } + + fweak_object_ptr_t weak = {0}; + if (!unreal_fweak_object_from_object(object, &weak)) { + lua_pushnil(state); + return 1; + } + + lua_unreal_object_t *userdata = (lua_unreal_object_t *)lua_newuserdatauv(state, sizeof(*userdata), 0); + userdata->context = lua_unreal_context_from_state(state); + userdata->weak = weak; + luaL_setmetatable(state, LUA_UNREAL_OBJECT_MT); + return 1; +} + +int +lua_unreal_object_push_invalid(lua_State *state) +{ + if (!state) { + return 0; + } + + lua_unreal_object_t *userdata = (lua_unreal_object_t *)lua_newuserdatauv(state, sizeof(*userdata), 0); + *userdata = (lua_unreal_object_t){ + .context = lua_unreal_context_from_state(state), + .weak = { + .object_idx = -1, + }, + }; + luaL_setmetatable(state, LUA_UNREAL_OBJECT_MT); + return 1; +} + +static int +lua_unreal_find_result_push(lua_State *state, uobject_t *object) +{ + return object ? lua_unreal_object_push(state, object) : lua_unreal_object_push_invalid(state); +} + +static int +lua_unreal_create_invalid_object_lua(lua_State *state) +{ + return lua_unreal_object_push_invalid(state); +} + +static lua_unreal_fname_t * +lua_unreal_fname_test(lua_State *state, int idx) +{ + return (lua_unreal_fname_t *)luaL_testudata(state, idx, LUA_UNREAL_FNAME_MT); +} + +static lua_unreal_ftext_literal_t * +lua_unreal_ftext_literal_test(lua_State *state, int idx) +{ + return (lua_unreal_ftext_literal_t *)luaL_testudata(state, idx, LUA_UNREAL_FTEXT_MT); +} + +static int +lua_unreal_fname_push(lua_State *state, fname_t value) +{ + lua_unreal_fname_t *userdata = (lua_unreal_fname_t *)lua_newuserdatauv(state, sizeof(*userdata), 0); + userdata->value = value; + luaL_setmetatable(state, LUA_UNREAL_FNAME_MT); + return 1; +} + +static bool +lua_unreal_string_or_fname(lua_State *state, int idx, str_t *out) +{ + idx = lua_absindex(state, idx); + *out = STR_NULL; + + if (lua_type(state, idx) == LUA_TSTRING) { + size_t len = 0; + const char *text = lua_tolstring(state, idx, &len); + *out = str_make((uint8_t *)text, (uint64_t)len); + return true; + } + + lua_unreal_fname_t *name = lua_unreal_fname_test(state, idx); + if (!name) { + return false; + } + + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t text = unreal_fname_to_str(name->value, tmp.arena); + lua_pushlstring(state, (const char *)text.data, (size_t)text.len); + lua_replace(state, idx); + } + scratch_end(tmp); + + size_t len = 0; + const char *text = lua_tolstring(state, idx, &len); + *out = str_make((uint8_t *)text, (uint64_t)len); + return true; +} + +static bool +lua_unreal_property_belongs_to_struct(ustruct_t *type, fprop_t *prop) +{ + if (!type || !prop) { + return false; + } + + for (fprop_t *current = type->prop_link; current; current = current->prop_link_next) { + if (current == prop) { + return true; + } + } + return false; +} + +static bool +lua_unreal_property_fits(fprop_t *prop, uint64_t container_size) +{ + if (!prop || prop->offset_internal < 0 || prop->elem_size <= 0 || prop->array_dim <= 0) { + return false; + } + + uint64_t complete = unreal_fprop_complete_size(prop); + return complete > 0 && (uint64_t)prop->offset_internal <= container_size && complete <= container_size - (uint64_t)prop->offset_internal; +} + +static void * +lua_unreal_owned_value(lua_unreal_owned_t *owned) +{ + return owned ? (uint8_t *)owned + owned->value_offset : NULL; +} + +static bool +lua_unreal_data_table_row_resolve(lua_unreal_data_table_row_t *row, udata_table_t **out_table, uscript_struct_t **out_row_struct, uint8_t **out_value) +{ + udata_table_t *table = row ? (udata_table_t *)unreal_fweak_object_resolve(row->table) : NULL; + if (!table || !globals.unreal.data_table || !unreal_uobject_is_a((uobject_t *)table, globals.unreal.data_table)) { + return false; + } + + uscript_struct_t *row_struct = table->row_struct; + if (!row_struct || !globals.unreal.core_scriptstruct || !unreal_uobject_is_valid((uobject_t *)row_struct) || + !unreal_uobject_is_a((uobject_t *)row_struct, globals.unreal.core_scriptstruct) || row_struct->props_size < 0) { + return false; + } + + uint8_t *value = unreal_udata_table_find_row(table, row->row_name); + if (!value) { + return false; + } + + if (out_table) { + *out_table = table; + } + + if (out_row_struct) { + *out_row_struct = row_struct; + } + + if (out_value) { + *out_value = value; + } + + return true; +} + +static bool +lua_unreal_value_resolve(lua_State *state, int idx, fprop_t **out_prop, void **out_value, uobject_t **out_owner) +{ + idx = lua_absindex(state, idx); + + lua_unreal_owned_t *owned = (lua_unreal_owned_t *)luaL_testudata(state, idx, LUA_UNREAL_OWNED_MT); + if (owned) { + if (!owned->initialized || !owned->prop) { + return false; + } + + if (out_prop) { + *out_prop = owned->prop; + } + + if (out_value) { + *out_value = lua_unreal_owned_value(owned); + } + + if (out_owner) { + *out_owner = unreal_fweak_object_resolve(owned->owner); + } + return true; + } + + lua_unreal_proxy_t *proxy = (lua_unreal_proxy_t *)luaL_testudata(state, idx, LUA_UNREAL_PROXY_MT); + if (!proxy || !proxy->prop) { + return false; + } + + if (lua_getiuservalue(state, idx, 1) == LUA_TNONE) { + lua_pop(state, 1); + return false; + } + + int parent_idx = lua_gettop(state); + + void *parent_value = NULL; + uobject_t *owner = NULL; + fprop_t *parent_prop = NULL; + ustruct_t *parent_type = NULL; + + lua_unreal_object_t *parent_object = lua_unreal_object_test(state, parent_idx); + if (parent_object) { + owner = lua_unreal_object_resolve(parent_object); + if (owner) { + parent_value = owner; + parent_type = (ustruct_t *)owner->cls; + } + } else { + lua_unreal_data_table_row_t *row = (lua_unreal_data_table_row_t *)luaL_testudata(state, parent_idx, LUA_UNREAL_DATA_TABLE_ROW_MT); + if (row) { + udata_table_t *table = NULL; + uscript_struct_t *row_struct = NULL; + if (lua_unreal_data_table_row_resolve(row, &table, &row_struct, (uint8_t **)&parent_value)) { + owner = (uobject_t *)table; + parent_type = (ustruct_t *)row_struct; + } + } else if (lua_unreal_value_resolve(state, parent_idx, &parent_prop, &parent_value, &owner) && + unreal_fprop_get_kind(parent_prop) == UNREAL_PROP_KIND_STRUCT) { + fprop_struct_t *struct_prop = (fprop_struct_t *)parent_prop; + parent_type = (ustruct_t *)struct_prop->script_struct; + } + } + + void *value = NULL; + switch (proxy->selector_kind) { + case LUA_UNREAL_SELECTOR_FIELD: { + bool valid = parent_value && parent_type && + lua_unreal_property_belongs_to_struct(parent_type, proxy->prop) && + lua_unreal_property_fits(proxy->prop, (uint64_t)parent_type->props_size); + value = valid ? unreal_fprop_value_in_container(proxy->prop, parent_value, 0) : NULL; + } break; + + case LUA_UNREAL_SELECTOR_FIXED_ARRAY_ELEMENT: { + if (parent_value && parent_prop == proxy->prop) { + value = unreal_fprop_value_at(proxy->prop, parent_value, proxy->selector_index); + } + } break; + + case LUA_UNREAL_SELECTOR_ARRAY_ELEMENT: { + if (parent_value && parent_prop && unreal_fprop_get_kind(parent_prop) == UNREAL_PROP_KIND_ARRAY) { + fprop_array_t *array_prop = (fprop_array_t *)parent_prop; + if (array_prop->inner == proxy->prop) { + value = unreal_array_get(parent_value, array_prop, proxy->selector_index); + } + } + } break; + + case LUA_UNREAL_SELECTOR_MAP_KEY: + case LUA_UNREAL_SELECTOR_MAP_VALUE: { + if (parent_value && parent_prop && unreal_fprop_get_kind(parent_prop) == UNREAL_PROP_KIND_MAP) { + fprop_map_t *map_prop = (fprop_map_t *)parent_prop; + if (lua_getiuservalue(state, idx, 2) != LUA_TNONE) { + fprop_t *key_prop = NULL; + void *key = NULL; + if (lua_unreal_value_resolve(state, -1, &key_prop, &key, NULL) && key_prop == map_prop->key_prop) { + if (proxy->selector_kind == LUA_UNREAL_SELECTOR_MAP_VALUE && map_prop->val_prop == proxy->prop) { + value = unreal_map_find_value_ptr(parent_value, map_prop, key); + } else if (proxy->selector_kind == LUA_UNREAL_SELECTOR_MAP_KEY && map_prop->key_prop == proxy->prop) { + int32_t sparse_index = unreal_map_find_index(parent_value, map_prop, key); + value = sparse_index >= 0 ? (void *)unreal_map_get_key(parent_value, map_prop, sparse_index) : NULL; + } + } + } + lua_pop(state, 1); + } + } break; + + default: break; + } + lua_pop(state, 1); + + if (!value) { + return false; + } + + if (out_prop) { + *out_prop = proxy->prop; + } + + if (out_value) { + *out_value = value; + } + + if (out_owner) { + *out_owner = owner; + } + return true; +} + +static int +lua_unreal_proxy_push(lua_State *state, fprop_t *prop, int parent_idx, lua_unreal_selector_kind_t selector_kind, int32_t selector_index) +{ + parent_idx = lua_absindex(state, parent_idx); + + lua_unreal_proxy_t *proxy = (lua_unreal_proxy_t *)lua_newuserdatauv(state, sizeof(*proxy), 2); + proxy->context = lua_unreal_context_from_state(state); + proxy->prop = prop; + proxy->selector_kind = selector_kind; + proxy->selector_index = selector_index; + + luaL_setmetatable(state, LUA_UNREAL_PROXY_MT); + lua_pushvalue(state, parent_idx); + lua_setiuservalue(state, -2, 1); + return 1; +} + +static int +lua_unreal_owned_push(lua_State *state, fprop_t *prop, const void *value, uobject_t *owner) +{ + uint64_t value_size = unreal_fprop_complete_size(prop); + if (!prop || !value || value_size == 0) { + return 0; + } + + int32_t alignment = unreal_fprop_min_alignment(prop); + if (alignment <= 0) { + alignment = 1; + } + + if (alignment > LUA_UNREAL_MAX_ALIGNMENT) { + return 0; + } + + uint64_t extra = (uint64_t)alignment - 1; + uint64_t total = sizeof(lua_unreal_owned_t) + extra + value_size; + if (total > SIZE_MAX) { + return 0; + } + + lua_unreal_owned_t *owned = (lua_unreal_owned_t *)lua_newuserdatauv(state, (size_t)total, 0); + + *owned = (lua_unreal_owned_t){ + .context = lua_unreal_context_from_state(state), + .prop = prop, + .owner = { + .object_idx = -1, + }, + }; + unreal_fweak_object_from_object(owner, &owned->owner); + + uintptr_t start = (uintptr_t)(owned + 1); + uintptr_t rem = start % (uintptr_t)alignment; + uintptr_t aligned = rem ? start + ((uintptr_t)alignment - rem) : start; + + owned->value_offset = (uint32_t)(aligned - (uintptr_t)owned); + + void *dst = lua_unreal_owned_value(owned); + if (!unreal_fprop_initialize_value(prop, dst)) { + lua_pop(state, 1); + return 0; + } + + owned->initialized = true; + luaL_setmetatable(state, LUA_UNREAL_OWNED_MT); + + bool copied = prop->array_dim == 1 + ? unreal_fprop_copy_single_value(prop, dst, value) + : unreal_fprop_copy_complete_value(prop, dst, value); + if (!copied) { + unreal_fprop_destroy_value(prop, dst); + owned->initialized = false; + lua_pop(state, 1); + return 0; + } + return 1; +} + +static bool +lua_unreal_value_is_local(lua_State *state, int idx, int depth) +{ + idx = lua_absindex(state, idx); + if (luaL_testudata(state, idx, LUA_UNREAL_OWNED_MT)) { + return true; + } + + if (depth >= 64 || !luaL_testudata(state, idx, LUA_UNREAL_PROXY_MT)) { + return false; + } + + bool result = false; + if (lua_getiuservalue(state, idx, 1) != LUA_TNONE) { + result = lua_unreal_value_is_local(state, -1, depth + 1); + } + lua_pop(state, 1); + return result; +} + +static int +lua_unreal_owned_gc(lua_State *state) +{ + lua_unreal_owned_t *owned = (lua_unreal_owned_t *)luaL_testudata(state, 1, LUA_UNREAL_OWNED_MT); + if (owned && owned->initialized && owned->prop) { + unreal_fprop_destroy_value(owned->prop, lua_unreal_owned_value(owned)); + owned->initialized = false; + } + return 0; +} + +static bool +lua_unreal_kind_is_integer(unreal_prop_kind_t kind) +{ + return kind == UNREAL_PROP_KIND_BYTE || kind == UNREAL_PROP_KIND_INT8 || + kind == UNREAL_PROP_KIND_INT16 || kind == UNREAL_PROP_KIND_INT32 || + kind == UNREAL_PROP_KIND_INT64 || kind == UNREAL_PROP_KIND_UINT16 || + kind == UNREAL_PROP_KIND_UINT32 || kind == UNREAL_PROP_KIND_UINT64 || + kind == UNREAL_PROP_KIND_ENUM; +} + +static bool +lua_unreal_kind_is_object(unreal_prop_kind_t kind) +{ + return kind == UNREAL_PROP_KIND_OBJECT || kind == UNREAL_PROP_KIND_CLASS || + kind == UNREAL_PROP_KIND_WEAK_OBJECT || kind == UNREAL_PROP_KIND_LAZY_OBJECT; +} + +static bool +lua_unreal_kind_is_soft_object(unreal_prop_kind_t kind) +{ + return kind == UNREAL_PROP_KIND_SOFT_OBJECT || kind == UNREAL_PROP_KIND_SOFT_CLASS; +} + +static int +lua_unreal_prop_push_selected(lua_State *state, fprop_t *prop, void *value, uobject_t *owner, int parent_idx, bool live_proxy, + lua_unreal_selector_kind_t selector_kind, int32_t selector_index, bool single_element) +{ + if (!state || !prop || !value || prop->array_dim <= 0) { + return 0; + } + + if (!single_element && prop->array_dim > 1) { + return live_proxy && parent_idx != 0 + ? lua_unreal_proxy_push(state, prop, parent_idx, selector_kind, selector_index) + : lua_unreal_owned_push(state, prop, value, owner); + } + + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + if (kind == UNREAL_PROP_KIND_BOOL) { + bool result = false; + if (!unreal_fprop_read_bool(prop, value, &result)) { + return 0; + } + lua_pushboolean(state, result); + return 1; + } + + if (lua_unreal_kind_is_integer(kind)) { + unreal_prop_integer_t integer = {0}; + if (!unreal_fprop_read_integer(prop, value, &integer)) { + return 0; + } + + if (!integer.is_signed && integer.value > (uint64_t)LUA_MAXINTEGER) { + return 0; + } + + lua_pushinteger(state, integer.is_signed ? (lua_Integer)(int64_t)integer.value : (lua_Integer)integer.value); + return 1; + } + + if (kind == UNREAL_PROP_KIND_FLOAT || kind == UNREAL_PROP_KIND_DOUBLE) { + double result = 0.0; + if (!unreal_fprop_read_real(prop, value, &result)) { + return 0; + } + lua_pushnumber(state, (lua_Number)result); + return 1; + } + + if (kind == UNREAL_PROP_KIND_NAME) { + fname_t name = {0}; + if (!unreal_fprop_read_name(prop, value, &name)) { + return 0; + } + return lua_unreal_fname_push(state, name); + } + + if (kind == UNREAL_PROP_KIND_TEXT) { + /* FText has no mutating Lua methods. Return an owned value so mods can cache and later restore a property after its source UObject is gone */ + return lua_unreal_owned_push(state, prop, value, owner); + } + + if (kind == UNREAL_PROP_KIND_STRING) { + return live_proxy && parent_idx != 0 + ? lua_unreal_proxy_push(state, prop, parent_idx, selector_kind, selector_index) + : lua_unreal_owned_push(state, prop, value, owner); + } + + if (lua_unreal_kind_is_soft_object(kind)) { + return live_proxy && parent_idx != 0 + ? lua_unreal_proxy_push(state, prop, parent_idx, selector_kind, selector_index) + : lua_unreal_owned_push(state, prop, value, owner); + } + + if (lua_unreal_kind_is_object(kind) || kind == UNREAL_PROP_KIND_INTERFACE) { + return lua_unreal_object_push(state, unreal_fprop_get_referenced_object(prop, value)); + } + + if (kind == UNREAL_PROP_KIND_STRUCT || kind == UNREAL_PROP_KIND_ARRAY || kind == UNREAL_PROP_KIND_SET || kind == UNREAL_PROP_KIND_MAP) { + return live_proxy && parent_idx != 0 + ? lua_unreal_proxy_push(state, prop, parent_idx, selector_kind, selector_index) + : lua_unreal_owned_push(state, prop, value, owner); + } + + return 0; +} + +static int +lua_unreal_map_value_push(lua_State *state, fprop_map_t *map_prop, void *value, const void *key, + uobject_t *owner, int parent_idx) +{ + if (!map_prop || !map_prop->key_prop || !map_prop->val_prop || !value || !key) { + return 0; + } + + int result = lua_unreal_prop_push_selected(state, map_prop->val_prop, value, owner, parent_idx, true, LUA_UNREAL_SELECTOR_MAP_VALUE, 0, true); + lua_unreal_proxy_t *proxy = result ? (lua_unreal_proxy_t *)luaL_testudata(state, -1, LUA_UNREAL_PROXY_MT) : NULL; + if (proxy) { + if (!lua_unreal_owned_push(state, map_prop->key_prop, key, owner)) { + lua_pop(state, 1); + return 0; + } + lua_setiuservalue(state, -2, 2); + } + return result; +} + +static int +lua_unreal_proxy_param_push(lua_State *state, fprop_t *prop, int parent_idx, + lua_unreal_selector_kind_t selector_kind, int32_t selector_index, + fprop_t *key_prop, const void *key, uobject_t *owner, bool writable) +{ + parent_idx = lua_absindex(state, parent_idx); + if (!lua_unreal_proxy_push(state, prop, parent_idx, selector_kind, selector_index)) { + return 0; + } + + int proxy_idx = lua_gettop(state); + if (key_prop && key) { + if (!lua_unreal_owned_push(state, key_prop, key, owner)) { + lua_pop(state, 1); + return 0; + } + lua_setiuservalue(state, proxy_idx, 2); + } + + lua_unreal_param_t *param = (lua_unreal_param_t *)lua_newuserdatauv(state, sizeof(*param), 1); + + *param = (lua_unreal_param_t){ + .context = lua_unreal_context_from_state(state), + .kind = LUA_UNREAL_PARAM_PROXY, + .owner = {.object_idx = -1}, + .object = {.object_idx = -1}, + .writable = writable, + .is_local = lua_unreal_value_is_local(state, parent_idx, 0), + }; + + luaL_setmetatable(state, LUA_UNREAL_PARAM_MT); + lua_pushvalue(state, proxy_idx); + lua_setiuservalue(state, -2, 1); + lua_remove(state, proxy_idx); + return 1; +} + +int +lua_unreal_param_scope_begin(lua_State *state) +{ + if (!state) { + return LUA_NOREF; + } + + lua_unreal_param_scope_t *scope = (lua_unreal_param_scope_t *)lua_newuserdatauv(state, sizeof(*scope), 0); + scope->active = true; + return luaL_ref(state, LUA_REGISTRYINDEX); +} + +void +lua_unreal_param_scope_end(lua_State *state, int scope_ref) +{ + if (!state || scope_ref == LUA_NOREF || scope_ref == LUA_REFNIL) { + return; + } + + lua_rawgeti(state, LUA_REGISTRYINDEX, scope_ref); + lua_unreal_param_scope_t *scope = (lua_unreal_param_scope_t *)lua_touserdata(state, -1); + if (scope) { + scope->active = false; + } + lua_pop(state, 1); + luaL_unref(state, LUA_REGISTRYINDEX, scope_ref); +} + +static lua_unreal_param_t * +lua_unreal_remote_param_new(lua_State *state, int scope_ref, lua_unreal_param_kind_t kind) +{ + lua_rawgeti(state, LUA_REGISTRYINDEX, scope_ref); + lua_unreal_param_scope_t *scope = (lua_unreal_param_scope_t *)lua_touserdata(state, -1); + if (!scope || !scope->active) { + lua_pop(state, 1); + return NULL; + } + + int scope_idx = lua_gettop(state); + lua_unreal_param_t *param = (lua_unreal_param_t *)lua_newuserdatauv(state, sizeof(*param), 1); + + *param = (lua_unreal_param_t){ + .context = lua_unreal_context_from_state(state), + .scope = scope, + .kind = kind, + .owner = {.object_idx = -1}, + .object = {.object_idx = -1}, + }; + + luaL_setmetatable(state, LUA_UNREAL_PARAM_MT); + lua_pushvalue(state, scope_idx); + lua_setiuservalue(state, -2, 1); + lua_remove(state, scope_idx); + return param; +} + +int +lua_unreal_remote_param_push(lua_State *state, int scope_ref, fprop_t *prop, void *value, uobject_t *owner, bool writable) +{ + if (!state || !prop || !value) { + return 0; + } + + lua_unreal_param_t *param = lua_unreal_remote_param_new(state, scope_ref, LUA_UNREAL_PARAM_BORROWED); + if (!param) { + return 0; + } + param->prop = prop; + param->value = value; + param->writable = writable; + unreal_fweak_object_from_object(owner, ¶m->owner); + return 1; +} + +int +lua_unreal_remote_object_param_push(lua_State *state, int scope_ref, uobject_t *object) +{ + if (!state || !object) { + return 0; + } + + lua_unreal_param_t *param = lua_unreal_remote_param_new(state, scope_ref, LUA_UNREAL_PARAM_OBJECT); + if (!param) { + return 0; + } + + if (!unreal_fweak_object_from_object(object, ¶m->object)) { + lua_pop(state, 1); + return 0; + } + return 1; +} + +static int +lua_unreal_prop_push_internal(lua_State *state, fprop_t *prop, void *value, uobject_t *owner, int parent_idx, bool live_proxy) +{ + return lua_unreal_prop_push_selected(state, prop, value, owner, parent_idx, live_proxy, LUA_UNREAL_SELECTOR_FIELD, 0, false); +} + +int +lua_unreal_prop_push(lua_State *state, fprop_t *prop, void *value, uobject_t *owner) +{ + return lua_unreal_prop_push_internal(state, prop, value, owner, 0, false); +} + +static bool +lua_unreal_copy_compatible_value(lua_State *state, int value_idx, fprop_t *prop, void *dst, bool allow_same_kind, bool *recognized) +{ + fprop_t *source_prop = NULL; + void *source_value = NULL; + + *recognized = lua_unreal_value_resolve(state, value_idx, &source_prop, &source_value, NULL); + if (!*recognized) { + return false; + } + + bool compatible = unreal_fprop_same_type(prop, source_prop); + if (!compatible && allow_same_kind) { + unreal_prop_kind_t dst_kind = unreal_fprop_get_kind(prop); + unreal_prop_kind_t src_kind = unreal_fprop_get_kind(source_prop); + /* TSoftObjectPtr and TSoftClassPtr share FSoftObjectPtr storage. + * UE4SS permits values returned by Conv_SoftObjPathToSoftObjRef to initialize either reflected property kind. */ + compatible = (dst_kind == src_kind || (lua_unreal_kind_is_soft_object(dst_kind) && lua_unreal_kind_is_soft_object(src_kind))) && prop->elem_size == source_prop->elem_size; + } + return compatible && unreal_fprop_copy_single_value(prop, dst, source_value); +} + +static bool +lua_unreal_string_like(lua_State *state, int value_idx, arena_t *arena, str_t *out) +{ + value_idx = lua_absindex(state, value_idx); + *out = STR_NULL; + + if (lua_type(state, value_idx) == LUA_TSTRING) { + size_t len = 0; + const char *text = lua_tolstring(state, value_idx, &len); + *out = str_make((uint8_t *)text, (uint64_t)len); + return text != NULL; + } + + lua_unreal_ftext_literal_t *literal = lua_unreal_ftext_literal_test(state, value_idx); + if (literal) { + *out = str_make((uint8_t *)literal->text, (uint64_t)literal->len); + return true; + } + + fprop_t *source_prop = NULL; + void *source_value = NULL; + return lua_unreal_value_resolve(state, value_idx, &source_prop, &source_value, NULL) && + unreal_fprop_read_string(source_prop, source_value, arena, out); +} + +static bool +lua_unreal_string_has_embedded_null(str_t text) +{ + for (uint64_t i = 0; i < text.len; ++i) { + if (text.data[i] == 0) { + return true; + } + } + return false; +} + +static bool +lua_unreal_write_struct(lua_State *state, int value_idx, fprop_t *prop, void *dst, uobject_t *owner, char *error, size_t error_cap); +static bool +lua_unreal_write_fixed_array(lua_State *state, int value_idx, fprop_t *prop, void *dst, uobject_t *owner, char *error, size_t error_cap); +static bool +lua_unreal_write_array(lua_State *state, int value_idx, fprop_array_t *prop, void *dst, uobject_t *owner, char *error, size_t error_cap); +static bool +lua_unreal_write_set(lua_State *state, int value_idx, fprop_set_t *prop, void *dst, uobject_t *owner, char *error, size_t error_cap); +static bool +lua_unreal_write_map(lua_State *state, int value_idx, fprop_map_t *prop, void *dst, uobject_t *owner, char *error, size_t error_cap); + +static bool +lua_unreal_write_initialized_ex(lua_State *state, int value_idx, fprop_t *prop, void *dst, uobject_t *owner, char *error, size_t error_cap, bool single_element) +{ + if (!state || !prop || !dst || prop->array_dim <= 0) { + lua_unreal_error_set(error, error_cap, "invalid reflected property layout"); + return false; + } + + if (!single_element && prop->array_dim > 1) { + return lua_unreal_write_fixed_array(state, value_idx, prop, dst, owner, error, error_cap); + } + + value_idx = lua_absindex(state, value_idx); + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + + if (kind == UNREAL_PROP_KIND_BOOL) { + if (lua_type(state, value_idx) != LUA_TBOOLEAN || !unreal_fprop_write_bool(prop, dst, lua_toboolean(state, value_idx) != 0)) { + lua_unreal_error_set(error, error_cap, "expected a boolean"); + return false; + } + return true; + } + + if (lua_unreal_kind_is_integer(kind)) { + int is_integer = 0; + lua_Integer value = lua_tointegerx(state, value_idx, &is_integer); + unreal_prop_integer_t integer = { + .value = (uint64_t)(int64_t)value, + .is_signed = value < 0, + }; + + if (!is_integer || !unreal_fprop_write_integer(prop, dst, integer)) { + lua_unreal_error_set(error, error_cap, "expected an in-range integer"); + return false; + } + return true; + } + + if (kind == UNREAL_PROP_KIND_FLOAT || kind == UNREAL_PROP_KIND_DOUBLE) { + int is_number = 0; + lua_Number value = lua_tonumberx(state, value_idx, &is_number); + if (!is_number || !unreal_fprop_write_real(prop, dst, (double)value)) { + lua_unreal_error_set(error, error_cap, "expected an in-range number"); + return false; + } + return true; + } + + if (kind == UNREAL_PROP_KIND_NAME) { + fname_t name = {0}; + lua_unreal_fname_t *name_data = lua_unreal_fname_test(state, value_idx); + if (name_data) { + name = name_data->value; + } else { + str_t text = STR_NULL; + if (!lua_unreal_string_or_fname(state, value_idx, &text)) { + lua_unreal_error_set(error, error_cap, "expected a string or FName"); + return false; + } + name = unreal_fname_from_str(text, FNAME_FIND_OR_ADD); + } + + if (!unreal_fprop_write_name(prop, dst, name)) { + lua_unreal_error_set(error, error_cap, "could not create the FName"); + return false; + } + return true; + } + + if (kind == UNREAL_PROP_KIND_STRING || kind == UNREAL_PROP_KIND_TEXT) { + bool recognized = false; + if (lua_unreal_copy_compatible_value(state, value_idx, prop, dst, true, &recognized)) { + return true; + } + + bool ok = false; + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t text = STR_NULL; + if (!lua_unreal_string_like(state, value_idx, tmp.arena, &text)) { + lua_unreal_error_set(error, error_cap, "expected a string, FString, or FText"); + } else if (lua_unreal_string_has_embedded_null(text)) { + lua_unreal_error_set(error, error_cap, "Unreal strings cannot contain embedded null bytes"); + } else if (text.len == 0) { + ok = unreal_fprop_clear_single_value(prop, dst); + if (!ok) { + lua_unreal_error_set(error, error_cap, "could not clear the string value"); + } + } else { + /* unreal_fprop_import_text uses PPF_None. FString and plain FText input therefore consume raw text; quoting here would store the quotes */ + ok = unreal_fprop_import_text(prop, dst, owner, text, tmp.arena); + if (!ok) { + lua_unreal_error_set(error, error_cap, "could not import the string value"); + } + } + } + scratch_end(tmp); + return ok; + } + + if (lua_unreal_kind_is_soft_object(kind)) { + bool recognized = false; + if (lua_unreal_copy_compatible_value(state, value_idx, prop, dst, true, &recognized)) { + return true; + } + + if (recognized) { + lua_unreal_error_set(error, error_cap, "expected a compatible soft object reference"); + return false; + } + + if (lua_isnil(state, value_idx)) { + return true; + } + + lua_unreal_object_t *userdata = lua_unreal_object_test(state, value_idx); + if (userdata) { + uobject_t *object = lua_unreal_object_resolve(userdata); + if (!object) { + lua_unreal_error_set(error, error_cap, "expected a live UObject"); + return false; + } + + if (!unreal_fprop_set_object((fprop_obj_base_t *)prop, dst, object)) { + lua_unreal_error_set(error, error_cap, "the UObject is incompatible with this soft reference"); + return false; + } + return true; + } + + if (lua_type(state, value_idx) != LUA_TSTRING) { + lua_unreal_error_set(error, error_cap, "expected nil, a path string, a UObject, or a compatible soft reference"); + return false; + } + + size_t len = 0; + const char *text = lua_tolstring(state, value_idx, &len); + str_t path = str_make((uint8_t *)text, (uint64_t)len); + if (!text || lua_unreal_string_has_embedded_null(path)) { + lua_unreal_error_set(error, error_cap, "soft reference paths cannot contain embedded null bytes"); + return false; + } + + bool ok = false; + tmp_arena_t tmp = scratch_begin(NULL); + { + ok = unreal_fprop_import_text(prop, dst, owner, path, tmp.arena); + } + scratch_end(tmp); + + if (!ok) { + lua_unreal_error_set(error, error_cap, "could not import the soft reference path"); + } + return ok; + } + + if (lua_unreal_kind_is_object(kind)) { + uobject_t *object = NULL; + if (!lua_isnil(state, value_idx)) { + lua_unreal_object_t *userdata = lua_unreal_object_test(state, value_idx); + + object = lua_unreal_object_resolve(userdata); + if (!userdata || !object) { + lua_unreal_error_set(error, error_cap, "expected nil or a live UObject"); + return false; + } + } + + if (!unreal_fprop_set_object((fprop_obj_base_t *)prop, dst, object)) { + lua_unreal_error_set(error, error_cap, "the UObject is incompatible with this property"); + return false; + } + return true; + } + + if (kind == UNREAL_PROP_KIND_INTERFACE) { + uobject_t *object = NULL; + if (!lua_isnil(state, value_idx)) { + lua_unreal_object_t *userdata = lua_unreal_object_test(state, value_idx); + object = lua_unreal_object_resolve(userdata); + if (!userdata || !object) { + lua_unreal_error_set(error, error_cap, "expected nil or a live UObject"); + return false; + } + } + + bool written = unreal_fprop_set_interface((fprop_iface_t *)prop, dst, object); + if (!written) { + lua_unreal_error_set(error, error_cap, "the UObject is incompatible with this interface property"); + } + return written; + } + + if (kind == UNREAL_PROP_KIND_STRUCT) { + return lua_unreal_write_struct(state, value_idx, prop, dst, owner, error, error_cap); + } + + if (kind == UNREAL_PROP_KIND_ARRAY) { + return lua_unreal_write_array(state, value_idx, (fprop_array_t *)prop, dst, owner, error, error_cap); + } + + if (kind == UNREAL_PROP_KIND_SET) { + return lua_unreal_write_set(state, value_idx, (fprop_set_t *)prop, dst, owner, error, error_cap); + } + + if (kind == UNREAL_PROP_KIND_MAP) { + return lua_unreal_write_map(state, value_idx, (fprop_map_t *)prop, dst, owner, error, error_cap); + } + + lua_unreal_error_set(error, error_cap, "unsupported reflected property kind"); + return false; +} + +static bool +lua_unreal_write_initialized(lua_State *state, int value_idx, fprop_t *prop, void *dst, uobject_t *owner, char *error, size_t error_cap) +{ + return lua_unreal_write_initialized_ex(state, value_idx, prop, dst, owner, error, error_cap, false); +} + +static bool +lua_unreal_temporary_from_lua(lua_State *state, int value_idx, fprop_t *prop, uobject_t *owner, arena_t *arena, + void **out_value, char *error, size_t error_cap) +{ + *out_value = NULL; + if (!prop || prop->array_dim != 1 || prop->elem_size <= 0 || !arena) { + lua_unreal_error_set(error, error_cap, "invalid container element property"); + return false; + } + + int32_t alignment = unreal_fprop_min_alignment(prop); + if (alignment <= 0) { + alignment = 1; + } + + if (alignment > LUA_UNREAL_MAX_ALIGNMENT) { + lua_unreal_error_set(error, error_cap, "container element alignment %d is unsupported", alignment); + return false; + } + + void *temporary = arena_push_zero_aligned(arena, (uint64_t)prop->elem_size, (uint64_t)alignment); + if (!temporary) { + lua_unreal_error_set(error, error_cap, "could not allocate a temporary container element"); + return false; + } + + if (!unreal_fprop_initialize_value(prop, temporary)) { + lua_unreal_error_set(error, error_cap, "could not initialize a temporary container element"); + return false; + } + + if (!lua_unreal_write_initialized(state, value_idx, prop, temporary, owner, error, error_cap)) { + unreal_fprop_destroy_value(prop, temporary); + return false; + } + + *out_value = temporary; + return true; +} + +static lua_Unsigned +lua_unreal_sequence_count(lua_State *state, int table_idx) +{ + table_idx = lua_absindex(state, table_idx); + lua_Unsigned count = (lua_Unsigned)lua_rawlen(state, table_idx); + lua_getfield(state, table_idx, "n"); + if (lua_isinteger(state, -1)) { + lua_Integer explicit_count = lua_tointeger(state, -1); + if (explicit_count >= 0) { + count = (lua_Unsigned)explicit_count; + } + } + lua_pop(state, 1); + return count; +} + +static bool +lua_unreal_write_fixed_array(lua_State *state, int value_idx, fprop_t *prop, void *dst, uobject_t *owner, char *error, size_t error_cap) +{ + value_idx = lua_absindex(state, value_idx); + + fprop_t *source_prop = NULL; + void *source_value = NULL; + if (lua_unreal_value_resolve(state, value_idx, &source_prop, &source_value, NULL)) { + if (lua_unreal_value_is_fixed_element(state, value_idx) || source_prop != prop || + !unreal_fprop_copy_complete_value(prop, dst, source_value)) { + lua_unreal_error_set(error, error_cap, "expected a compatible fixed-array value"); + return false; + } + return true; + } + + if (lua_type(state, value_idx) != LUA_TTABLE) { + lua_unreal_error_set(error, error_cap, "expected a table with %d fixed-array elements", prop->array_dim); + return false; + } + + lua_pushnil(state); + while (lua_next(state, value_idx) != 0) { + lua_Integer index = lua_isinteger(state, -2) ? lua_tointeger(state, -2) : 0; + if (index < 1 || index > prop->array_dim) { + lua_pop(state, 2); + lua_unreal_error_set(error, error_cap, "fixed-array keys must be integers from 1 through %d", prop->array_dim); + return false; + } + lua_pop(state, 1); + } + + for (int32_t i = 0; i < prop->array_dim; ++i) { + void *element = unreal_fprop_value_at(prop, dst, i); + lua_rawgeti(state, value_idx, (lua_Integer)i + 1); + bool ok = element && lua_unreal_write_initialized_ex(state, -1, prop, element, owner, error, error_cap, true); + lua_pop(state, 1); + if (!ok) { + return false; + } + } + return true; +} + +static bool +lua_unreal_write_array(lua_State *state, int value_idx, fprop_array_t *prop, void *dst, uobject_t *owner, char *error, size_t error_cap) +{ + value_idx = lua_absindex(state, value_idx); + + fprop_t *source_prop = NULL; + void *source_value = NULL; + if (lua_unreal_value_resolve(state, value_idx, &source_prop, &source_value, NULL)) { + if (!unreal_fprop_same_type(&prop->base, source_prop) || !unreal_fprop_copy_single_value(&prop->base, dst, source_value)) { + lua_unreal_error_set(error, error_cap, "expected a compatible array value"); + return false; + } + return true; + } + + if (!prop->inner || prop->inner->array_dim != 1 || lua_type(state, value_idx) != LUA_TTABLE) { + lua_unreal_error_set(error, error_cap, "expected a table or compatible array value"); + return false; + } + + lua_Unsigned count = lua_unreal_sequence_count(state, value_idx); + if (count > INT32_MAX || !unreal_array_clear(dst, prop)) { + lua_unreal_error_set(error, error_cap, "could not initialize the dynamic array"); + return false; + } + + for (lua_Unsigned i = 1; i <= count; ++i) { + lua_rawgeti(state, value_idx, (lua_Integer)i); + + bool ok = false; + tmp_arena_t tmp = scratch_begin(NULL); + { + void *element = NULL; + + ok = lua_unreal_temporary_from_lua(state, -1, prop->inner, owner, tmp.arena, &element, error, error_cap); + if (ok) { + ok = unreal_array_add(dst, prop, element) >= 0; + unreal_fprop_destroy_value(prop->inner, element); + if (!ok) { + lua_unreal_error_set(error, error_cap, "could not append dynamic-array element %llu", (unsigned long long)i); + } + } + } + scratch_end(tmp); + + lua_pop(state, 1); + if (!ok) { + return false; + } + } + return true; +} + +static bool +lua_unreal_write_set(lua_State *state, int value_idx, fprop_set_t *prop, void *dst, uobject_t *owner, char *error, size_t error_cap) +{ + value_idx = lua_absindex(state, value_idx); + + fprop_t *source_prop = NULL; + void *source_value = NULL; + if (lua_unreal_value_resolve(state, value_idx, &source_prop, &source_value, NULL)) { + if (!unreal_fprop_same_type(&prop->base, source_prop) || !unreal_fprop_copy_single_value(&prop->base, dst, source_value)) { + lua_unreal_error_set(error, error_cap, "expected a compatible set value"); + return false; + } + return true; + } + + if (!prop->elem_prop || prop->elem_prop->array_dim != 1 || lua_type(state, value_idx) != LUA_TTABLE) { + lua_unreal_error_set(error, error_cap, "expected a sequence table or compatible set value"); + return false; + } + + lua_Unsigned count = lua_unreal_sequence_count(state, value_idx); + if (count > INT32_MAX || !unreal_set_clear(dst, prop)) { + lua_unreal_error_set(error, error_cap, "could not initialize the set"); + return false; + } + + for (lua_Unsigned i = 1; i <= count; ++i) { + lua_rawgeti(state, value_idx, (lua_Integer)i); + bool ok = false; + tmp_arena_t tmp = scratch_begin(NULL); + { + void *element = NULL; + + ok = lua_unreal_temporary_from_lua(state, -1, prop->elem_prop, owner, tmp.arena, &element, error, error_cap); + if (ok) { + unreal_set_add(dst, prop, element); + ok = unreal_set_contains(dst, prop, element); + unreal_fprop_destroy_value(prop->elem_prop, element); + if (!ok) { + lua_unreal_error_set(error, error_cap, "could not add set element %llu", (unsigned long long)i); + } + } + } + scratch_end(tmp); + + lua_pop(state, 1); + if (!ok) { + return false; + } + } + return true; +} + +static bool +lua_unreal_write_map(lua_State *state, int value_idx, fprop_map_t *prop, void *dst, uobject_t *owner, char *error, size_t error_cap) +{ + value_idx = lua_absindex(state, value_idx); + + fprop_t *source_prop = NULL; + void *source_value = NULL; + if (lua_unreal_value_resolve(state, value_idx, &source_prop, &source_value, NULL)) { + if (!unreal_fprop_same_type(&prop->base, source_prop) || !unreal_fprop_copy_single_value(&prop->base, dst, source_value)) { + lua_unreal_error_set(error, error_cap, "expected a compatible map value"); + return false; + } + return true; + } + + if (!prop->key_prop || !prop->val_prop || prop->key_prop->array_dim != 1 || prop->val_prop->array_dim != 1 || + lua_type(state, value_idx) != LUA_TTABLE) { + lua_unreal_error_set(error, error_cap, "expected a table or compatible map value"); + return false; + } + + if (!unreal_map_clear(dst, prop)) { + lua_unreal_error_set(error, error_cap, "could not initialize the map"); + return false; + } + + lua_pushnil(state); + while (lua_next(state, value_idx) != 0) { + bool added = false; + tmp_arena_t tmp = scratch_begin(NULL); + { + void *key = NULL; + void *val = NULL; + bool key_ok = lua_unreal_temporary_from_lua(state, -2, prop->key_prop, owner, tmp.arena, &key, error, error_cap); + bool val_ok = key_ok && lua_unreal_temporary_from_lua(state, -1, prop->val_prop, owner, tmp.arena, &val, error, error_cap); + + if (val_ok) { + unreal_map_add(dst, prop, key, val); + added = unreal_map_find_value_ptr(dst, prop, key) != NULL; + if (!added) { + lua_unreal_error_set(error, error_cap, "could not add a map pair"); + } + } + + if (val) { + unreal_fprop_destroy_value(prop->val_prop, val); + } + + if (key) { + unreal_fprop_destroy_value(prop->key_prop, key); + } + } + scratch_end(tmp); + + lua_pop(state, 1); + if (!added) { + lua_pop(state, 1); + return false; + } + } + return true; +} + +static bool +lua_unreal_write_struct_table(lua_State *state, int value_idx, ustruct_t *type, uint64_t container_size, + void *dst, uobject_t *owner, char *error, size_t error_cap) +{ + value_idx = lua_absindex(state, value_idx); + if (lua_type(state, value_idx) != LUA_TTABLE) { + lua_unreal_error_set(error, error_cap, "expected a table"); + return false; + } + + lua_pushnil(state); + while (lua_next(state, value_idx) != 0) { + if (lua_type(state, -2) != LUA_TSTRING) { + lua_pop(state, 2); + lua_unreal_error_set(error, error_cap, "struct table keys must be field-name strings"); + return false; + } + + size_t key_len = 0; + const char *key = lua_tolstring(state, -2, &key_len); + fprop_t *field = unreal_ustruct_find_prop(type, str_make((uint8_t *)key, (uint64_t)key_len)); + if (!field) { + lua_pop(state, 2); + lua_unreal_error_set(error, error_cap, "unknown struct field '%.*s'", (int)MIN_VAL(key_len, (size_t)INT_MAX), key); + return false; + } + + if (!lua_unreal_property_fits(field, container_size)) { + lua_pop(state, 2); + lua_unreal_error_set(error, error_cap, "unsupported layout for struct field '%.*s'", (int)MIN_VAL(key_len, (size_t)INT_MAX), key); + return false; + } + lua_pop(state, 1); + } + + for (fprop_t *field = type->prop_link; field; field = field->prop_link_next) { + if (!lua_unreal_property_fits(field, container_size)) { + continue; + } + + bool ok = false; + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t name = unreal_fname_to_str(field->name, tmp.arena); + lua_pushlstring(state, (const char *)name.data, (size_t)name.len); + lua_rawget(state, value_idx); + + bool present = !lua_isnil(state, -1); + if (present) { + void *field_value = unreal_fprop_value_in_container(field, dst, 0); + + ok = field_value && lua_unreal_write_initialized(state, -1, field, field_value, owner, error, error_cap); + } else { + ok = true; + } + lua_pop(state, 1); + } + scratch_end(tmp); + + if (!ok) { + if (error && error[0] == '\0') { + lua_unreal_error_set(error, error_cap, "could not write struct field"); + } + return false; + } + } + return true; +} + +static bool +lua_unreal_write_struct(lua_State *state, int value_idx, fprop_t *prop, void *dst, uobject_t *owner, char *error, size_t error_cap) +{ + value_idx = lua_absindex(state, value_idx); + + fprop_struct_t *struct_prop = (fprop_struct_t *)prop; + ustruct_t *type = (ustruct_t *)struct_prop->script_struct; + if (!type || type->props_size < 0 || (uint64_t)type->props_size > (uint64_t)prop->elem_size) { + lua_unreal_error_set(error, error_cap, "invalid reflected struct layout"); + return false; + } + + fprop_t *source_prop = NULL; + void *source_value = NULL; + if (lua_unreal_value_resolve(state, value_idx, &source_prop, &source_value, NULL)) { + if (!unreal_fprop_same_type(prop, source_prop) || !unreal_fprop_copy_single_value(prop, dst, source_value)) { + lua_unreal_error_set(error, error_cap, "expected a compatible struct value"); + return false; + } + return true; + } + + if (!lua_unreal_write_struct_table(state, value_idx, type, (uint64_t)prop->elem_size, dst, owner, error, error_cap)) { + if (lua_type(state, value_idx) != LUA_TTABLE && error && error[0] != '\0') { + error[0] = '\0'; + lua_unreal_error_set(error, error_cap, "expected a table or compatible struct value"); + } + return false; + } + return true; +} + +static bool +lua_unreal_write_transactional(lua_State *state, int value_idx, fprop_t *prop, void *dst, uobject_t *owner, char *error, size_t error_cap) +{ + uint64_t value_size = unreal_fprop_complete_size(prop); + if (!state || !prop || !dst || value_size == 0) { + lua_unreal_error_set(error, error_cap, "invalid reflected property layout"); + return false; + } + + int32_t alignment = unreal_fprop_min_alignment(prop); + if (alignment <= 0) { + alignment = 1; + } + + if (alignment > LUA_UNREAL_MAX_ALIGNMENT) { + lua_unreal_error_set(error, error_cap, "property alignment %d is unsupported", alignment); + return false; + } + + bool copied = false; + tmp_arena_t tmp = scratch_begin(NULL); + { + void *temporary = arena_push_zero_aligned(tmp.arena, value_size, (uint64_t)alignment); + bool initialized = temporary && unreal_fprop_initialize_value(prop, temporary); + bool written = initialized && lua_unreal_write_initialized(state, value_idx, prop, temporary, owner, error, error_cap); + + copied = written && (prop->array_dim == 1 + ? unreal_fprop_copy_single_value(prop, dst, temporary) + : unreal_fprop_copy_complete_value(prop, dst, temporary)); + if (written && !copied) { + lua_unreal_error_set(error, error_cap, "could not commit the reflected value"); + } + + if (!temporary) { + lua_unreal_error_set(error, error_cap, "could not allocate temporary reflected storage"); + } else if (!initialized) { + lua_unreal_error_set(error, error_cap, "could not initialize temporary reflected storage"); + } + + if (initialized) { + unreal_fprop_destroy_value(prop, temporary); + } + } + + scratch_end(tmp); + return copied; +} + +bool +lua_unreal_prop_write(lua_State *state, int value_idx, fprop_t *prop, void *dst, uobject_t *owner) +{ + char error[LUA_UNREAL_ERROR_CAP] = {0}; + return lua_unreal_write_transactional(state, value_idx, prop, dst, owner, error, sizeof(error)); +} + +static bool +lua_unreal_write_fixed_element_transactional(lua_State *state, int value_idx, fprop_t *prop, void *array, + int32_t element_idx, uobject_t *owner, char *error, size_t error_cap) +{ + uint64_t value_size = unreal_fprop_complete_size(prop); + if (!state || !prop || !array || prop->array_dim <= 1 || element_idx < 0 || element_idx >= prop->array_dim || value_size == 0) { + lua_unreal_error_set(error, error_cap, "invalid fixed-array element"); + return false; + } + + int32_t alignment = unreal_fprop_min_alignment(prop); + if (alignment <= 0) { + alignment = 1; + } + + if (alignment > LUA_UNREAL_MAX_ALIGNMENT) { + lua_unreal_error_set(error, error_cap, "property alignment %d is unsupported", alignment); + return false; + } + + bool copied = false; + tmp_arena_t tmp = scratch_begin(NULL); + { + void *temporary = arena_push_zero_aligned(tmp.arena, value_size, (uint64_t)alignment); + bool initialized = temporary && unreal_fprop_initialize_value(prop, temporary); + bool cloned = initialized && unreal_fprop_copy_complete_value(prop, temporary, array); + void *element = cloned ? unreal_fprop_value_at(prop, temporary, element_idx) : NULL; + bool written = element && lua_unreal_write_initialized_ex(state, value_idx, prop, element, owner, error, error_cap, true); + + copied = written && unreal_fprop_copy_complete_value(prop, array, temporary); + if (written && !copied) { + lua_unreal_error_set(error, error_cap, "could not commit the fixed-array element"); + } else if (!temporary) { + lua_unreal_error_set(error, error_cap, "could not allocate temporary fixed-array storage"); + } else if (!initialized || !cloned) { + lua_unreal_error_set(error, error_cap, "could not initialize temporary fixed-array storage"); + } + + if (initialized) { + unreal_fprop_destroy_value(prop, temporary); + } + } + scratch_end(tmp); + return copied; +} + +static int +lua_unreal_value_metatable_lookup(lua_State *state) +{ + if (lua_getmetatable(state, 1)) { + lua_pushvalue(state, 2); + lua_rawget(state, -2); + lua_remove(state, -2); + return 1; + } + lua_pushnil(state); + return 1; +} + +static bool +lua_unreal_value_is_fixed_element(lua_State *state, int idx) +{ + lua_unreal_proxy_t *proxy = (lua_unreal_proxy_t *)luaL_testudata(state, idx, LUA_UNREAL_PROXY_MT); + return proxy && proxy->selector_kind == LUA_UNREAL_SELECTOR_FIXED_ARRAY_ELEMENT; +} + +static int32_t +lua_unreal_set_sparse_index_from_lua(const void *set, fprop_set_t *prop, lua_Integer lua_index) +{ + if (lua_index < 1) { + return -1; + } + + int32_t ordinal = 0; + int32_t max_index = unreal_set_max_index(set, prop); + for (int32_t sparse_index = 0; sparse_index < max_index; ++sparse_index) { + if (unreal_set_is_valid_index(set, prop, sparse_index) && ++ordinal == lua_index) { + return sparse_index; + } + } + return -1; +} + +static int +lua_unreal_value_index(lua_State *state) +{ + lua_unreal_context_t *context = lua_unreal_context_from_state(state); + lua_unreal_require_access(state, context); + + fprop_t *parent_prop = NULL; + void *parent_value = NULL; + uobject_t *owner = NULL; + + if (!lua_unreal_value_resolve(state, 1, &parent_prop, &parent_value, &owner)) { + return luaL_error(state, "the reflected value is no longer valid"); + } + + if (parent_prop->array_dim > 1 && !lua_unreal_value_is_fixed_element(state, 1)) { + if (!lua_isinteger(state, 2)) { + return lua_unreal_value_metatable_lookup(state); + } + + lua_Integer lua_index = lua_tointeger(state, 2); + if (lua_index < 1 || lua_index > parent_prop->array_dim) { + lua_pushnil(state); + return 1; + } + + int32_t index = (int32_t)lua_index - 1; + void *value = unreal_fprop_value_at(parent_prop, parent_value, index); + if (!value || !lua_unreal_prop_push_selected(state, parent_prop, value, owner, 1, true, + LUA_UNREAL_SELECTOR_FIXED_ARRAY_ELEMENT, index, true)) { + return luaL_error(state, "fixed-array element %lld has an unsupported reflected type", (long long)lua_index); + } + return 1; + } + + unreal_prop_kind_t kind = unreal_fprop_get_kind(parent_prop); + if (kind == UNREAL_PROP_KIND_STRUCT) { + if (lua_type(state, 2) != LUA_TSTRING) { + return lua_unreal_value_metatable_lookup(state); + } + + size_t key_len = 0; + const char *key = lua_tolstring(state, 2, &key_len); + fprop_struct_t *struct_prop = (fprop_struct_t *)parent_prop; + ustruct_t *type = (ustruct_t *)struct_prop->script_struct; + fprop_t *field = unreal_ustruct_find_prop(type, str_make((uint8_t *)key, (uint64_t)key_len)); + + if (!field) { + return lua_unreal_value_metatable_lookup(state); + } + + if (!lua_unreal_property_fits(field, (uint64_t)parent_prop->elem_size)) { + return luaL_error(state, "field '%s' has an unsupported reflected layout", key); + } + + void *value = unreal_fprop_value_in_container(field, parent_value, 0); + if (!value || !lua_unreal_prop_push_selected(state, field, value, owner, 1, true, + LUA_UNREAL_SELECTOR_FIELD, 0, false)) { + return luaL_error(state, "field '%s' has an unsupported reflected type", key); + } + return 1; + } + + if (kind == UNREAL_PROP_KIND_ARRAY) { + if (!lua_isinteger(state, 2)) { + return lua_unreal_value_metatable_lookup(state); + } + + fprop_array_t *array_prop = (fprop_array_t *)parent_prop; + lua_Integer lua_index = lua_tointeger(state, 2); + int32_t count = unreal_array_num(parent_value, array_prop); + if (lua_index < 1 || lua_index > count) { + lua_pushnil(state); + return 1; + } + + int32_t index = (int32_t)lua_index - 1; + void *value = unreal_array_get(parent_value, array_prop, index); + if (!array_prop->inner || !value || + !lua_unreal_prop_push_selected(state, array_prop->inner, value, owner, 1, true, + LUA_UNREAL_SELECTOR_ARRAY_ELEMENT, index, true)) { + return luaL_error(state, "array element %lld has an unsupported reflected type", (long long)lua_index); + } + return 1; + } + + if (kind == UNREAL_PROP_KIND_SET) { + if (!lua_isinteger(state, 2)) { + return lua_unreal_value_metatable_lookup(state); + } + + fprop_set_t *set_prop = (fprop_set_t *)parent_prop; + int32_t sparse_index = lua_unreal_set_sparse_index_from_lua(parent_value, set_prop, lua_tointeger(state, 2)); + const void *value = sparse_index >= 0 ? unreal_set_get(parent_value, set_prop, sparse_index) : NULL; + if (!value) { + lua_pushnil(state); + return 1; + } + + if (!set_prop->elem_prop || + !lua_unreal_prop_push_selected(state, set_prop->elem_prop, (void *)value, owner, 0, false, LUA_UNREAL_SELECTOR_FIELD, 0, true)) { + return luaL_error(state, "set element has an unsupported reflected type"); + } + return 1; + } + + if (kind == UNREAL_PROP_KIND_MAP) { + fprop_map_t *map_prop = (fprop_map_t *)parent_prop; + if (!map_prop->key_prop || !map_prop->val_prop) { + return luaL_error(state, "map metadata is incomplete"); + } + + char conversion_error[LUA_UNREAL_ERROR_CAP] = {0}; + int result = 0; + tmp_arena_t tmp = scratch_begin(NULL); + { + void *key = NULL; + bool converted = lua_unreal_temporary_from_lua(state, 2, map_prop->key_prop, owner, tmp.arena, &key, conversion_error, sizeof(conversion_error)); + void *value = converted ? unreal_map_find_value_ptr(parent_value, map_prop, key) : NULL; + if (value) { + result = lua_unreal_map_value_push(state, map_prop, value, key, owner, 1); + } + + if (key) { + unreal_fprop_destroy_value(map_prop->key_prop, key); + } + } + scratch_end(tmp); + + if (result) { + return result; + } + + if (lua_type(state, 2) == LUA_TSTRING) { + return lua_unreal_value_metatable_lookup(state); + } + + lua_pushnil(state); + return 1; + } + + return lua_unreal_value_metatable_lookup(state); +} + +static int +lua_unreal_value_newindex(lua_State *state) +{ + lua_unreal_context_t *context = lua_unreal_context_from_state(state); + lua_unreal_require_access(state, context); + + fprop_t *parent_prop = NULL; + void *parent_value = NULL; + uobject_t *owner = NULL; + + if (!lua_unreal_value_resolve(state, 1, &parent_prop, &parent_value, &owner)) { + return luaL_error(state, "the reflected value is no longer valid"); + } + + char error[LUA_UNREAL_ERROR_CAP] = {0}; + if (parent_prop->array_dim > 1 && !lua_unreal_value_is_fixed_element(state, 1)) { + lua_Integer lua_index = luaL_checkinteger(state, 2); + if (lua_index < 1 || lua_index > parent_prop->array_dim || + !lua_unreal_write_fixed_element_transactional(state, 3, parent_prop, parent_value, (int32_t)lua_index - 1, owner, error, sizeof(error))) { + return luaL_error(state, "could not assign fixed-array element: %s", error[0] ? error : "index out of range"); + } + return 0; + } + + unreal_prop_kind_t kind = unreal_fprop_get_kind(parent_prop); + if (kind == UNREAL_PROP_KIND_STRUCT) { + size_t key_len = 0; + const char *key = luaL_checklstring(state, 2, &key_len); + fprop_struct_t *struct_prop = (fprop_struct_t *)parent_prop; + ustruct_t *type = (ustruct_t *)struct_prop->script_struct; + fprop_t *field = unreal_ustruct_find_prop(type, str_make((uint8_t *)key, (uint64_t)key_len)); + + if (!field || !lua_unreal_property_fits(field, (uint64_t)parent_prop->elem_size)) { + return luaL_error(state, "unknown or unsupported struct field '%s'", key); + } + + void *dst = unreal_fprop_value_in_container(field, parent_value, 0); + if (!dst || !lua_unreal_write_transactional(state, 3, field, dst, owner, error, sizeof(error))) { + return luaL_error(state, "could not assign '%s': %s", key, error[0] ? error : "conversion failed"); + } + return 0; + } + + if (kind == UNREAL_PROP_KIND_ARRAY) { + fprop_array_t *array_prop = (fprop_array_t *)parent_prop; + lua_Integer lua_index = luaL_checkinteger(state, 2); + int32_t count = unreal_array_num(parent_value, array_prop); + if (!array_prop->inner || count < 0 || lua_index < 1 || lua_index > (lua_Integer)count + 1) { + return luaL_error(state, "array index is out of range"); + } + + bool converted = false; + tmp_arena_t tmp = scratch_begin(NULL); + { + void *element = NULL; + + converted = lua_unreal_temporary_from_lua(state, 3, array_prop->inner, owner, tmp.arena, &element, error, sizeof(error)); + if (converted) { + int32_t index = (int32_t)lua_index - 1; + bool append = index == count; + if (append) { + converted = unreal_array_add(parent_value, array_prop, element) == index; + } else { + unreal_array_set(parent_value, array_prop, index, element, false); + } + + void *committed = converted || !append ? unreal_array_get(parent_value, array_prop, index) : NULL; + + converted = committed && unreal_fprop_single_values_identical(array_prop->inner, committed, element, 0); + if (!converted && append && unreal_array_num(parent_value, array_prop) == count + 1) { + unreal_array_remove(parent_value, array_prop, index); + } + unreal_fprop_destroy_value(array_prop->inner, element); + + if (!converted) { + lua_unreal_error_set(error, sizeof(error), "could not commit the array element"); + } + } + } + scratch_end(tmp); + + if (!converted) { + return luaL_error(state, "could not assign array element: %s", error[0] ? error : "conversion failed"); + } + return 0; + } + + if (kind == UNREAL_PROP_KIND_MAP) { + fprop_map_t *map_prop = (fprop_map_t *)parent_prop; + if (!map_prop->key_prop || !map_prop->val_prop) { + return luaL_error(state, "map metadata is incomplete"); + } + + bool ok = false; + tmp_arena_t tmp = scratch_begin(NULL); + { + void *key = NULL; + void *val = NULL; + + ok = lua_unreal_temporary_from_lua(state, 2, map_prop->key_prop, owner, tmp.arena, &key, error, sizeof(error)); + if (ok && lua_isnil(state, 3)) { + unreal_map_remove(parent_value, map_prop, key); + } else if (ok) { + ok = lua_unreal_temporary_from_lua(state, 3, map_prop->val_prop, owner, tmp.arena, &val, error, sizeof(error)); + if (ok) { + unreal_map_add(parent_value, map_prop, key, val); + ok = unreal_map_find_value_ptr(parent_value, map_prop, key) != NULL; + } + } + + if (val) { + unreal_fprop_destroy_value(map_prop->val_prop, val); + } + + if (key) { + unreal_fprop_destroy_value(map_prop->key_prop, key); + } + } + scratch_end(tmp); + + if (!ok) { + return luaL_error(state, "could not assign map value: %s", error[0] ? error : "conversion failed"); + } + return 0; + } + + return luaL_error(state, "this reflected value does not support indexed assignment"); +} + +static int +lua_unreal_value_len(lua_State *state) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + + fprop_t *prop = NULL; + void *value = NULL; + if (!lua_unreal_value_resolve(state, 1, &prop, &value, NULL)) { + return luaL_error(state, "the reflected value is no longer valid"); + } + + if (prop->array_dim > 1 && !lua_unreal_value_is_fixed_element(state, 1)) { + lua_pushinteger(state, prop->array_dim); + return 1; + } + + int32_t count = -1; + switch (unreal_fprop_get_kind(prop)) { + case UNREAL_PROP_KIND_ARRAY: count = unreal_array_num(value, (fprop_array_t *)prop); break; + case UNREAL_PROP_KIND_SET: count = unreal_set_num(value, (fprop_set_t *)prop); break; + case UNREAL_PROP_KIND_MAP: count = unreal_map_num(value, (fprop_map_t *)prop); break; + default: break; + } + + if (count < 0) { + return luaL_error(state, "this reflected value has no length"); + } + + lua_pushinteger(state, count); + return 1; +} + +static int +lua_unreal_value_get_array_num_lua(lua_State *state) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + + fprop_t *prop = NULL; + void *value = NULL; + if (!lua_unreal_value_resolve(state, 1, &prop, &value, NULL) || unreal_fprop_get_kind(prop) != UNREAL_PROP_KIND_ARRAY) { + return luaL_error(state, "GetArrayNum requires a live TArray"); + } + + int32_t count = unreal_array_num(value, (fprop_array_t *)prop); + if (count < 0) { + return luaL_error(state, "the TArray is invalid"); + } + lua_pushinteger(state, count); + return 1; +} + +static int +lua_unreal_value_get_array_address_lua(lua_State *state) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + + fprop_t *prop = NULL; + void *value = NULL; + if (!lua_unreal_value_resolve(state, 1, &prop, &value, NULL) || + unreal_fprop_get_kind(prop) != UNREAL_PROP_KIND_ARRAY || + unreal_array_num(value, (fprop_array_t *)prop) < 0) { + return luaL_error(state, "GetArrayAddress requires a live TArray"); + } + + lua_pushinteger(state, (lua_Integer)(uintptr_t)value); + return 1; +} + +static int +lua_unreal_value_get_array_max_lua(lua_State *state) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + + fprop_t *prop = NULL; + void *value = NULL; + if (!lua_unreal_value_resolve(state, 1, &prop, &value, NULL) || + unreal_fprop_get_kind(prop) != UNREAL_PROP_KIND_ARRAY || + unreal_array_num(value, (fprop_array_t *)prop) < 0) { + return luaL_error(state, "GetArrayMax requires a live TArray"); + } + + lua_pushinteger(state, ((const fscript_array_t *)value)->max); + return 1; +} + +static int +lua_unreal_value_get_array_data_address_lua(lua_State *state) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + + fprop_t *prop = NULL; + void *value = NULL; + if (!lua_unreal_value_resolve(state, 1, &prop, &value, NULL) || + unreal_fprop_get_kind(prop) != UNREAL_PROP_KIND_ARRAY || + unreal_array_num(value, (fprop_array_t *)prop) < 0) { + return luaL_error(state, "GetArrayDataAddress requires a live TArray"); + } + + lua_pushinteger(state, (lua_Integer)(uintptr_t)((const fscript_array_t *)value)->data); + return 1; +} + +static int +lua_unreal_value_for_each_lua(lua_State *state) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + luaL_checktype(state, 2, LUA_TFUNCTION); + + fprop_t *prop = NULL; + void *value = NULL; + uobject_t *owner = NULL; + if (!lua_unreal_value_resolve(state, 1, &prop, &value, &owner)) { + return luaL_error(state, "the reflected value is no longer valid"); + } + + int callback_idx = lua_absindex(state, 2); + if (prop->array_dim > 1 && !lua_unreal_value_is_fixed_element(state, 1)) { + for (int32_t i = 0; i < prop->array_dim; ++i) { + lua_pushvalue(state, callback_idx); + lua_pushinteger(state, (lua_Integer)i + 1); + + if (!lua_unreal_proxy_param_push(state, prop, 1, LUA_UNREAL_SELECTOR_FIXED_ARRAY_ELEMENT, i, NULL, NULL, owner, true)) { + lua_pop(state, 1); + return luaL_error(state, "could not marshal fixed-array element %d", i + 1); + } + + if (lua_pcall(state, 2, 1, 0) != LUA_OK) { + return lua_error(state); + } + + bool stop = lua_toboolean(state, -1) != 0; + lua_pop(state, 1); + if (stop) { + break; + } + } + return 0; + } + + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + if (kind == UNREAL_PROP_KIND_ARRAY) { + fprop_array_t *array_prop = (fprop_array_t *)prop; + int32_t count = unreal_array_num(value, array_prop); + if (count < 0 || !array_prop->inner) { + return luaL_error(state, "TArray metadata is unavailable"); + } + + for (int32_t i = 0; i < count; ++i) { + lua_pushvalue(state, callback_idx); + lua_pushinteger(state, (lua_Integer)i + 1); + + if (!lua_unreal_proxy_param_push(state, array_prop->inner, 1, LUA_UNREAL_SELECTOR_ARRAY_ELEMENT, i, NULL, NULL, owner, true)) { + lua_pop(state, 1); + return luaL_error(state, "could not marshal TArray element %d", i + 1); + } + + if (lua_pcall(state, 2, 1, 0) != LUA_OK) { + return lua_error(state); + } + + bool stop = lua_toboolean(state, -1) != 0; + lua_pop(state, 1); + if (stop) { + break; + } + } + return 0; + } + + if (kind == UNREAL_PROP_KIND_SET) { + fprop_set_t *set_prop = (fprop_set_t *)prop; + if (!set_prop->elem_prop) { + return luaL_error(state, "TSet metadata is unavailable"); + } + + int32_t max_index = unreal_set_max_index(value, set_prop); + for (int32_t i = 0; i < max_index; ++i) { + const void *element = unreal_set_get(value, set_prop, i); + if (!element) { + continue; + } + + lua_pushvalue(state, callback_idx); + if (!lua_unreal_prop_push_selected(state, set_prop->elem_prop, (void *)element, owner, 0, false, LUA_UNREAL_SELECTOR_FIELD, 0, true)) { + lua_pop(state, 1); + return luaL_error(state, "could not marshal a TSet element"); + } + + if (lua_pcall(state, 1, 1, 0) != LUA_OK) { + return lua_error(state); + } + + bool stop = lua_toboolean(state, -1) != 0; + lua_pop(state, 1); + if (stop) { + break; + } + } + return 0; + } + + if (kind == UNREAL_PROP_KIND_MAP) { + fprop_map_t *map_prop = (fprop_map_t *)prop; + if (!map_prop->key_prop || !map_prop->val_prop) { + return luaL_error(state, "TMap metadata is unavailable"); + } + + int32_t max_index = unreal_map_max_index(value, map_prop); + for (int32_t i = 0; i < max_index; ++i) { + const void *key = unreal_map_get_key(value, map_prop, i); + void *val = unreal_map_get_value(value, map_prop, i); + if (!key || !val) { + continue; + } + + lua_pushvalue(state, callback_idx); + if (!lua_unreal_proxy_param_push(state, map_prop->key_prop, 1, LUA_UNREAL_SELECTOR_MAP_KEY, 0, map_prop->key_prop, key, owner, false)) { + lua_pop(state, 1); + return luaL_error(state, "could not marshal a TMap key"); + } + + if (!lua_unreal_proxy_param_push(state, map_prop->val_prop, 1, LUA_UNREAL_SELECTOR_MAP_VALUE, 0, map_prop->key_prop, key, owner, true)) { + lua_pop(state, 2); + return luaL_error(state, "could not marshal a TMap value"); + } + + if (lua_pcall(state, 2, 1, 0) != LUA_OK) { + return lua_error(state); + } + + bool stop = lua_toboolean(state, -1) != 0; + lua_pop(state, 1); + if (stop) { + break; + } + } + return 0; + } + + return luaL_error(state, "ForEach requires a fixed array, TArray, TSet, or TMap"); +} + +static int +lua_unreal_value_type_lua(lua_State *state) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + + fprop_t *prop = NULL; + if (!lua_unreal_value_resolve(state, 1, &prop, NULL, NULL)) { + return luaL_error(state, "the reflected value is no longer valid"); + } + + const char *type = "UnrealValue"; + if (prop->array_dim > 1 && !lua_unreal_value_is_fixed_element(state, 1)) { + type = "FixedArray"; + } else { + switch (unreal_fprop_get_kind(prop)) { + case UNREAL_PROP_KIND_STRING: type = "FString"; break; + case UNREAL_PROP_KIND_TEXT: type = "FText"; break; + case UNREAL_PROP_KIND_SOFT_OBJECT: type = "TSoftObjectPtr"; break; + case UNREAL_PROP_KIND_SOFT_CLASS: type = "TSoftClassPtr"; break; + case UNREAL_PROP_KIND_STRUCT: type = "UScriptStruct"; break; + case UNREAL_PROP_KIND_ARRAY: type = "TArray"; break; + case UNREAL_PROP_KIND_SET: type = "TSet"; break; + case UNREAL_PROP_KIND_MAP: type = "TMap"; break; + default: break; + } + } + lua_pushstring(state, type); + return 1; +} + +static int +lua_unreal_value_is_valid_lua(lua_State *state) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + lua_pushboolean(state, lua_unreal_value_resolve(state, 1, NULL, NULL, NULL)); + return 1; +} + +static lua_unreal_param_t * +lua_unreal_param_check(lua_State *state, int idx) +{ + lua_unreal_param_t *param = (lua_unreal_param_t *)luaL_checkudata(state, idx, LUA_UNREAL_PARAM_MT); + lua_unreal_require_access(state, param->context); + return param; +} + +static bool +lua_unreal_remote_param_is_valid(lua_unreal_param_t *param) +{ + if (!param || param->kind == LUA_UNREAL_PARAM_PROXY || !param->scope || !param->scope->active) { + return false; + } + + if (param->kind == LUA_UNREAL_PARAM_OBJECT) { + return unreal_fweak_object_resolve(param->object) != NULL; + } + + return param->kind == LUA_UNREAL_PARAM_BORROWED && param->prop && param->value; +} + +static int +lua_unreal_param_get_lua(lua_State *state) +{ + lua_unreal_param_t *param = lua_unreal_param_check(state, 1); + if (param->kind != LUA_UNREAL_PARAM_PROXY) { + if (!lua_unreal_remote_param_is_valid(param)) { + return luaL_error(state, "the Unreal parameter is no longer valid"); + } + + if (param->kind == LUA_UNREAL_PARAM_OBJECT) { + return lua_unreal_object_push(state, unreal_fweak_object_resolve(param->object)); + } + + uobject_t *owner = unreal_fweak_object_resolve(param->owner); + if (!lua_unreal_prop_push(state, param->prop, param->value, owner)) { + return luaL_error(state, "the Unreal parameter has an unsupported reflected type"); + } + return 1; + } + + if (lua_getiuservalue(state, 1, 1) == LUA_TNONE) { + lua_pop(state, 1); + return luaL_error(state, "the Unreal parameter is no longer valid"); + } + + int proxy_idx = lua_gettop(state); + fprop_t *prop = NULL; + void *value = NULL; + uobject_t *owner = NULL; + if (!lua_unreal_value_resolve(state, proxy_idx, &prop, &value, &owner)) { + lua_pop(state, 1); + return luaL_error(state, "the Unreal parameter is no longer valid"); + } + + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + bool return_proxy = prop->array_dim > 1 || kind == UNREAL_PROP_KIND_STRING || kind == UNREAL_PROP_KIND_TEXT || + lua_unreal_kind_is_soft_object(kind) || kind == UNREAL_PROP_KIND_STRUCT || + kind == UNREAL_PROP_KIND_ARRAY || kind == UNREAL_PROP_KIND_SET || kind == UNREAL_PROP_KIND_MAP; + if (return_proxy) { + return 1; + } + + if (!lua_unreal_prop_push_selected(state, prop, value, owner, 0, false, LUA_UNREAL_SELECTOR_FIELD, 0, true)) { + lua_pop(state, 1); + return luaL_error(state, "the Unreal parameter has an unsupported reflected type"); + } + lua_remove(state, proxy_idx); + return 1; +} + +static int +lua_unreal_param_set_lua(lua_State *state) +{ + lua_unreal_param_t *param = lua_unreal_param_check(state, 1); + if (!param->writable) { + return luaL_error(state, "this Unreal parameter is read-only"); + } + + if (param->kind != LUA_UNREAL_PARAM_PROXY) { + if (!lua_unreal_remote_param_is_valid(param) || param->kind != LUA_UNREAL_PARAM_BORROWED) { + return luaL_error(state, "the Unreal parameter is no longer valid"); + } + + char error[LUA_UNREAL_ERROR_CAP] = {0}; + uobject_t *owner = unreal_fweak_object_resolve(param->owner); + if (!lua_unreal_write_transactional(state, 2, param->prop, param->value, owner, error, sizeof(error))) { + return luaL_error(state, "could not set the Unreal parameter: %s", error[0] ? error : "conversion failed"); + } + return 0; + } + + if (lua_getiuservalue(state, 1, 1) == LUA_TNONE) { + lua_pop(state, 1); + return luaL_error(state, "the Unreal parameter is no longer valid"); + } + + fprop_t *prop = NULL; + void *value = NULL; + uobject_t *owner = NULL; + if (!lua_unreal_value_resolve(state, -1, &prop, &value, &owner)) { + lua_pop(state, 1); + return luaL_error(state, "the Unreal parameter is no longer valid"); + } + + char error[LUA_UNREAL_ERROR_CAP] = {0}; + bool ok = lua_unreal_write_transactional(state, 2, prop, value, owner, error, sizeof(error)); + lua_pop(state, 1); + if (!ok) { + return luaL_error(state, "could not set the Unreal parameter: %s", error[0] ? error : "conversion failed"); + } + return 0; +} + +static int +lua_unreal_param_is_valid_lua(lua_State *state) +{ + lua_unreal_param_t *param = lua_unreal_param_check(state, 1); + if (param->kind != LUA_UNREAL_PARAM_PROXY) { + lua_pushboolean(state, lua_unreal_remote_param_is_valid(param)); + return 1; + } + + bool valid = false; + if (lua_getiuservalue(state, 1, 1) != LUA_TNONE) { + valid = lua_unreal_value_resolve(state, -1, NULL, NULL, NULL); + } + lua_pop(state, 1); + lua_pushboolean(state, valid); + return 1; +} + +static int +lua_unreal_param_type_lua(lua_State *state) +{ + lua_unreal_param_t *param = lua_unreal_param_check(state, 1); + lua_pushstring(state, param->kind == LUA_UNREAL_PARAM_PROXY && param->is_local ? "LocalUnrealParam" : "RemoteUnrealParam"); + return 1; +} + +static int +lua_unreal_value_to_string_lua(lua_State *state) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + + fprop_t *prop = NULL; + void *value = NULL; + if (!lua_unreal_value_resolve(state, 1, &prop, &value, NULL)) { + return luaL_error(state, "the reflected value is no longer valid"); + } + + bool ok = false; + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t text = STR_NULL; + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + if (kind == UNREAL_PROP_KIND_STRING || kind == UNREAL_PROP_KIND_TEXT) { + ok = unreal_fprop_read_string(prop, value, tmp.arena, &text); + } else if (lua_unreal_kind_is_soft_object(kind)) { + ok = unreal_fprop_read_soft_path(prop, value, tmp.arena, &text); + } + + if (ok) { + lua_pushlstring(state, (const char *)text.data, (size_t)text.len); + } + } + scratch_end(tmp); + + if (!ok) { + return luaL_error(state, "ToString is only available for FString, FText, and soft references"); + } + return 1; +} + +static bool +lua_unreal_fstring_resolve(lua_State *state, fprop_t **out_prop, void **out_value, uobject_t **out_owner) +{ + fprop_t *prop = NULL; + void *value = NULL; + uobject_t *owner = NULL; + bool ok = lua_unreal_value_resolve(state, 1, &prop, &value, &owner) && unreal_fprop_get_kind(prop) == UNREAL_PROP_KIND_STRING; + if (ok) { + if (out_prop) { + *out_prop = prop; + } + + if (out_value) { + *out_value = value; + } + + if (out_owner) { + *out_owner = owner; + } + } + return ok; +} + +static int +lua_unreal_fstring_len_lua(lua_State *state) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + + void *value = NULL; + if (!lua_unreal_fstring_resolve(state, NULL, &value, NULL)) { + return luaL_error(state, "Len requires a live FString"); + } + + const fstring_t *string = (const fstring_t *)value; + if (string->len < 0 || string->max < string->len || (string->len > 0 && !string->data)) { + return luaL_error(state, "the FString is invalid"); + } + lua_pushinteger(state, string->len > 0 ? string->len - 1 : 0); + return 1; +} + +static int +lua_unreal_fstring_is_empty_lua(lua_State *state) +{ + lua_unreal_fstring_len_lua(state); + lua_pushboolean(state, lua_tointeger(state, -1) == 0); + lua_remove(state, -2); + return 1; +} + +static int +lua_unreal_fstring_append_lua(lua_State *state) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + + fprop_t *prop = NULL; + void *value = NULL; + uobject_t *owner = NULL; + if (!lua_unreal_fstring_resolve(state, &prop, &value, &owner)) { + return luaL_error(state, "Append requires a live FString"); + } + + char error[LUA_UNREAL_ERROR_CAP] = {0}; + bool ok = false; + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t current = STR_NULL; + str_t suffix = STR_NULL; + if (unreal_fprop_read_string(prop, value, tmp.arena, ¤t) && lua_unreal_string_like(state, 2, tmp.arena, &suffix)) { + str_t combined = str_push_concat(tmp.arena, current, suffix); + lua_pushlstring(state, (const char *)combined.data, (size_t)combined.len); + ok = lua_unreal_write_transactional(state, -1, prop, value, owner, error, sizeof(error)); + lua_pop(state, 1); + } else { + lua_unreal_error_set(error, sizeof(error), "expected a string or FString"); + } + } + scratch_end(tmp); + + if (!ok) { + return luaL_error(state, "could not append to FString: %s", error[0] ? error : "conversion failed"); + } + return 0; +} + +static int +lua_unreal_fstring_find_lua(lua_State *state) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + + fprop_t *prop = NULL; + void *value = NULL; + if (!lua_unreal_fstring_resolve(state, &prop, &value, NULL)) { + return luaL_error(state, "Find requires a live FString"); + } + + int result = 0; + bool readable = false; + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t current = STR_NULL; + str_t search = STR_NULL; + readable = unreal_fprop_read_string(prop, value, tmp.arena, ¤t) && lua_unreal_string_like(state, 2, tmp.arena, &search); + if (readable) { + str16_t haystack = str16_from_str(tmp.arena, current); + str16_t needle = str16_from_str(tmp.arena, search); + bool found = false; + for (uint64_t i = 0; i + needle.len <= haystack.len && !found; ++i) { + bool match = true; + for (uint64_t j = 0; j < needle.len; ++j) { + if (haystack.data[i + j] != needle.data[j]) { + match = false; + break; + } + } + + if (match) { + lua_pushinteger(state, (lua_Integer)i + 1); + found = true; + result = 1; + } + } + + if (!found) { + lua_pushnil(state); + result = 1; + } + } + } + scratch_end(tmp); + + if (!readable) { + return luaL_error(state, "Find expects a string or FString"); + } + return result; +} + +static int +lua_unreal_fstring_has_affix_lua(lua_State *state, bool suffix) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + + fprop_t *prop = NULL; + void *value = NULL; + if (!lua_unreal_fstring_resolve(state, &prop, &value, NULL)) { + return luaL_error(state, "%s requires a live FString", suffix ? "EndsWith" : "StartsWith"); + } + + bool matches = false; + int result = 1; + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t current = STR_NULL; + str_t affix = STR_NULL; + if (unreal_fprop_read_string(prop, value, tmp.arena, ¤t) && lua_unreal_string_like(state, 2, tmp.arena, &affix)) { + str16_t haystack = str16_from_str(tmp.arena, current); + str16_t needle = str16_from_str(tmp.arena, affix); + if (needle.len <= haystack.len) { + uint64_t offset = suffix ? haystack.len - needle.len : 0; + matches = true; + for (uint64_t i = 0; i < needle.len; ++i) { + if (haystack.data[offset + i] != needle.data[i]) { + matches = false; + break; + } + } + } + } else { + result = luaL_error(state, "%s expects a string or FString", suffix ? "EndsWith" : "StartsWith"); + } + } + scratch_end(tmp); + + lua_pushboolean(state, matches); + return result; +} + +static int +lua_unreal_fstring_starts_with_lua(lua_State *state) +{ + return lua_unreal_fstring_has_affix_lua(state, false); +} + +static int +lua_unreal_fstring_ends_with_lua(lua_State *state) +{ + return lua_unreal_fstring_has_affix_lua(state, true); +} + +static int +lua_unreal_fstring_change_case_lua(lua_State *state, bool upper) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + + fprop_t *prop = NULL; + void *value = NULL; + uobject_t *owner = NULL; + if (!lua_unreal_fstring_resolve(state, &prop, &value, &owner)) { + return luaL_error(state, "%s requires a live FString", upper ? "ToUpper" : "ToLower"); + } + + int result = 0; + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t current = STR_NULL; + if (unreal_fprop_read_string(prop, value, tmp.arena, ¤t)) { + str_t changed = upper ? str_to_upper(tmp.arena, current) : str_to_lower(tmp.arena, current); + lua_pushlstring(state, (const char *)changed.data, (size_t)changed.len); + + char error[LUA_UNREAL_ERROR_CAP] = {0}; + void *temporary = NULL; + if (lua_unreal_temporary_from_lua(state, -1, prop, owner, tmp.arena, &temporary, error, sizeof(error))) { + lua_pop(state, 1); + result = lua_unreal_owned_push(state, prop, temporary, owner); + unreal_fprop_destroy_value(prop, temporary); + } else { + lua_pop(state, 1); + } + } + } + scratch_end(tmp); + + if (!result) { + return luaL_error(state, "could not create the converted FString"); + } + return result; +} + +static int +lua_unreal_fstring_to_upper_lua(lua_State *state) +{ + return lua_unreal_fstring_change_case_lua(state, true); +} + +static int +lua_unreal_fstring_to_lower_lua(lua_State *state) +{ + return lua_unreal_fstring_change_case_lua(state, false); +} + +static int +lua_unreal_value_to_table_lua(lua_State *state) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + + fprop_t *prop = NULL; + void *value = NULL; + uobject_t *owner = NULL; + if (!lua_unreal_value_resolve(state, 1, &prop, &value, &owner)) { + return luaL_error(state, "the reflected value is no longer valid"); + } + + lua_newtable(state); + if (prop->array_dim > 1 && !lua_unreal_value_is_fixed_element(state, 1)) { + for (int32_t i = 0; i < prop->array_dim; ++i) { + void *element = unreal_fprop_value_at(prop, value, i); + if (!element || !lua_unreal_prop_push_selected(state, prop, element, owner, 1, true, LUA_UNREAL_SELECTOR_FIXED_ARRAY_ELEMENT, i, true)) { + return luaL_error(state, "could not marshal fixed-array element %d", i + 1); + } + lua_rawseti(state, -2, (lua_Integer)i + 1); + } + return 1; + } + + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + if (kind == UNREAL_PROP_KIND_STRUCT) { + fprop_struct_t *struct_prop = (fprop_struct_t *)prop; + ustruct_t *type = (ustruct_t *)struct_prop->script_struct; + if (!type) { + return luaL_error(state, "struct metadata is unavailable"); + } + + for (fprop_t *field = type->prop_link; field; field = field->prop_link_next) { + if (!lua_unreal_property_fits(field, (uint64_t)prop->elem_size)) { + continue; + } + + void *field_value = unreal_fprop_value_in_container(field, value, 0); + if (!field_value || !lua_unreal_prop_push_selected(state, field, field_value, owner, 0, false, LUA_UNREAL_SELECTOR_FIELD, 0, false)) { + return luaL_error(state, "could not marshal a struct field"); + } + + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t name = unreal_fname_to_str(field->name, tmp.arena); + lua_setfield(state, -2, (const char *)name.data); + } + scratch_end(tmp); + } + return 1; + } + + if (kind == UNREAL_PROP_KIND_ARRAY) { + fprop_array_t *array_prop = (fprop_array_t *)prop; + int32_t count = unreal_array_num(value, array_prop); + if (count < 0 || !array_prop->inner) { + return luaL_error(state, "dynamic-array metadata is unavailable"); + } + + for (int32_t i = 0; i < count; ++i) { + void *element = unreal_array_get(value, array_prop, i); + if (!element || !lua_unreal_prop_push_selected(state, array_prop->inner, element, owner, 0, false, LUA_UNREAL_SELECTOR_FIELD, 0, true)) { + return luaL_error(state, "could not marshal dynamic-array element %d", i + 1); + } + lua_rawseti(state, -2, (lua_Integer)i + 1); + } + + lua_pushinteger(state, count); + lua_setfield(state, -2, "n"); + return 1; + } + + if (kind == UNREAL_PROP_KIND_SET) { + fprop_set_t *set_prop = (fprop_set_t *)prop; + int32_t count = unreal_set_num(value, set_prop); + if (count < 0 || !set_prop->elem_prop) { + return luaL_error(state, "set metadata is unavailable"); + } + + int32_t out_index = 1; + int32_t max_index = unreal_set_max_index(value, set_prop); + for (int32_t i = 0; i < max_index; ++i) { + const void *element = unreal_set_get(value, set_prop, i); + if (!element) { + continue; + } + + if (!lua_unreal_prop_push_selected(state, set_prop->elem_prop, (void *)element, owner, 0, false, LUA_UNREAL_SELECTOR_FIELD, 0, true)) { + return luaL_error(state, "could not marshal a set element"); + } + + lua_rawseti(state, -2, out_index++); + } + lua_pushinteger(state, count); + lua_setfield(state, -2, "n"); + return 1; + } + + if (kind == UNREAL_PROP_KIND_MAP) { + fprop_map_t *map_prop = (fprop_map_t *)prop; + int32_t count = unreal_map_num(value, map_prop); + if (count < 0 || !map_prop->key_prop || !map_prop->val_prop) { + return luaL_error(state, "map metadata is unavailable"); + } + + int32_t max_index = unreal_map_max_index(value, map_prop); + for (int32_t i = 0; i < max_index; ++i) { + const void *key = unreal_map_get_key(value, map_prop, i); + void *val = unreal_map_get_value(value, map_prop, i); + + if (!key || !val) { + continue; + } + + if (!lua_unreal_prop_push_selected(state, map_prop->key_prop, (void *)key, owner, 0, false, LUA_UNREAL_SELECTOR_FIELD, 0, true) || + !lua_unreal_prop_push_selected(state, map_prop->val_prop, val, owner, 0, false, LUA_UNREAL_SELECTOR_FIELD, 0, true)) { + return luaL_error(state, "could not marshal a map pair"); + } + lua_rawset(state, -3); + } + return 1; + } + + return luaL_error(state, "this reflected value cannot be converted to a table"); +} + +static int +lua_unreal_value_clear_lua(lua_State *state) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + + fprop_t *prop = NULL; + void *value = NULL; + uobject_t *owner = NULL; + if (!lua_unreal_value_resolve(state, 1, &prop, &value, &owner)) { + return luaL_error(state, "the reflected value is no longer valid"); + } + + bool cleared = false; + switch (unreal_fprop_get_kind(prop)) { + case UNREAL_PROP_KIND_STRING: { + char error[LUA_UNREAL_ERROR_CAP] = {0}; + lua_pushliteral(state, ""); + cleared = lua_unreal_write_transactional(state, -1, prop, value, owner, error, sizeof(error)); + lua_pop(state, 1); + break; + } + + case UNREAL_PROP_KIND_ARRAY: cleared = unreal_array_clear(value, (fprop_array_t *)prop); break; + case UNREAL_PROP_KIND_SET: cleared = unreal_set_clear(value, (fprop_set_t *)prop); break; + case UNREAL_PROP_KIND_MAP: cleared = unreal_map_clear(value, (fprop_map_t *)prop); break; + default: break; + } + + if (!cleared) { + return luaL_error(state, "this reflected value cannot be cleared"); + } + return 0; +} + +static int +lua_unreal_value_add_lua(lua_State *state) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + + fprop_t *prop = NULL; + void *value = NULL; + uobject_t *owner = NULL; + if (!lua_unreal_value_resolve(state, 1, &prop, &value, &owner)) { + return luaL_error(state, "the reflected value is no longer valid"); + } + + char error[LUA_UNREAL_ERROR_CAP] = {0}; + + int result_count = 0; + tmp_arena_t tmp = scratch_begin(NULL); + { + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + switch (kind) { + case UNREAL_PROP_KIND_ARRAY: { + fprop_array_t *array_prop = (fprop_array_t *)prop; + void *element = NULL; + bool ok = array_prop->inner && lua_unreal_temporary_from_lua(state, 2, array_prop->inner, owner, tmp.arena, &element, error, sizeof(error)); + int32_t index = ok ? unreal_array_add(value, array_prop, element) : -1; + if (element) { + unreal_fprop_destroy_value(array_prop->inner, element); + } + + if (index >= 0) { + lua_pushinteger(state, (lua_Integer)index + 1); + result_count = 1; + } else { + result_count = luaL_error(state, "could not add array element: %s", error[0] ? error : "mutation failed"); + } + break; + } + + case UNREAL_PROP_KIND_SET: { + fprop_set_t *set_prop = (fprop_set_t *)prop; + void *element = NULL; + bool ok = AS_BOOL(set_prop->elem_prop); + + ok = ok && lua_unreal_temporary_from_lua(state, 2, set_prop->elem_prop, owner, tmp.arena, &element, error, sizeof(error)); + if (ok) { + unreal_set_add(value, set_prop, element); + ok = unreal_set_contains(value, set_prop, element); + } + + if (element) { + unreal_fprop_destroy_value(set_prop->elem_prop, element); + } + + if (ok) { + lua_pushboolean(state, true); + result_count = 1; + } else { + result_count = luaL_error(state, "could not add set element: %s", error[0] ? error : "mutation failed"); + } + break; + } + + case UNREAL_PROP_KIND_MAP: { + fprop_map_t *map_prop = (fprop_map_t *)prop; + void *key = NULL; + void *val = NULL; + bool ok = map_prop->key_prop && map_prop->val_prop && + lua_unreal_temporary_from_lua(state, 2, map_prop->key_prop, owner, tmp.arena, &key, error, sizeof(error)) && + lua_unreal_temporary_from_lua(state, 3, map_prop->val_prop, owner, tmp.arena, &val, error, sizeof(error)); + if (ok) { + unreal_map_add(value, map_prop, key, val); + ok = unreal_map_find_value_ptr(value, map_prop, key) != NULL; + } + + if (val) { + unreal_fprop_destroy_value(map_prop->val_prop, val); + } + + if (key) { + unreal_fprop_destroy_value(map_prop->key_prop, key); + } + + if (ok) { + lua_pushboolean(state, true); + result_count = 1; + } else { + result_count = luaL_error(state, "could not add map pair: %s", error[0] ? error : "mutation failed"); + } + break; + } + + default: { + result_count = luaL_error(state, "this reflected value does not support Add"); + break; + } + } + } + scratch_end(tmp); + return result_count; +} + +static int +lua_unreal_value_insert_lua(lua_State *state) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + + fprop_t *prop = NULL; + void *value = NULL; + uobject_t *owner = NULL; + if (!lua_unreal_value_resolve(state, 1, &prop, &value, &owner) || + unreal_fprop_get_kind(prop) != UNREAL_PROP_KIND_ARRAY) { + return luaL_error(state, "Insert requires a live TArray"); + } + + fprop_array_t *array_prop = (fprop_array_t *)prop; + lua_Integer lua_index = luaL_checkinteger(state, 2); + int32_t count = unreal_array_num(value, array_prop); + if (lua_index < 1 || lua_index > (lua_Integer)count + 1 || !array_prop->inner) { + return luaL_error(state, "array insertion index is out of range"); + } + + char error[LUA_UNREAL_ERROR_CAP] = {0}; + bool ok = false; + tmp_arena_t tmp = scratch_begin(NULL); + { + void *element = NULL; + + ok = lua_unreal_temporary_from_lua(state, 3, array_prop->inner, owner, tmp.arena, &element, error, sizeof(error)); + if (ok) { + unreal_array_insert(value, array_prop, (int32_t)lua_index - 1, element); + ok = unreal_array_num(value, array_prop) == count + 1; + unreal_fprop_destroy_value(array_prop->inner, element); + } + } + scratch_end(tmp); + + if (!ok) { + return luaL_error(state, "could not insert array element: %s", error[0] ? error : "mutation failed"); + } + return 0; +} + +static int +lua_unreal_value_contains_lua(lua_State *state) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + + fprop_t *prop = NULL; + void *value = NULL; + uobject_t *owner = NULL; + if (!lua_unreal_value_resolve(state, 1, &prop, &value, &owner)) { + return luaL_error(state, "the reflected value is no longer valid"); + } + + fprop_t *element_prop = NULL; + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + if (kind == UNREAL_PROP_KIND_ARRAY) { + element_prop = ((fprop_array_t *)prop)->inner; + } else if (kind == UNREAL_PROP_KIND_SET) { + element_prop = ((fprop_set_t *)prop)->elem_prop; + } else if (kind == UNREAL_PROP_KIND_MAP) { + element_prop = ((fprop_map_t *)prop)->key_prop; + } + + if (!element_prop) { + return luaL_error(state, "this reflected value does not support Contains"); + } + + char error[LUA_UNREAL_ERROR_CAP] = {0}; + bool converted = false; + bool found = false; + tmp_arena_t tmp = scratch_begin(NULL); + { + void *element = NULL; + + converted = lua_unreal_temporary_from_lua(state, 2, element_prop, owner, tmp.arena, &element, error, sizeof(error)); + if (converted && kind == UNREAL_PROP_KIND_ARRAY) { + fprop_array_t *array_prop = (fprop_array_t *)prop; + int32_t count = unreal_array_num(value, array_prop); + for (int32_t i = 0; i < count && !found; ++i) { + void *candidate = unreal_array_get(value, array_prop, i); + found = candidate && unreal_fprop_single_values_identical(element_prop, candidate, element, 0); + } + } else if (converted && kind == UNREAL_PROP_KIND_SET) { + found = unreal_set_contains(value, (fprop_set_t *)prop, element); + } else if (converted && kind == UNREAL_PROP_KIND_MAP) { + found = unreal_map_find_value_ptr(value, (fprop_map_t *)prop, element) != NULL; + } + + if (element) { + unreal_fprop_destroy_value(element_prop, element); + } + } + scratch_end(tmp); + + if (!converted) { + return luaL_error(state, "could not convert the lookup value: %s", error[0] ? error : "conversion failed"); + } + + lua_pushboolean(state, found); + return 1; +} + +static int +lua_unreal_value_find_lua(lua_State *state) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + + fprop_t *prop = NULL; + void *value = NULL; + uobject_t *owner = NULL; + + if (!lua_unreal_value_resolve(state, 1, &prop, &value, &owner)) { + return luaL_error(state, "Find requires a live FString or TMap"); + } + + if (unreal_fprop_get_kind(prop) == UNREAL_PROP_KIND_STRING) { + return lua_unreal_fstring_find_lua(state); + } + + if (unreal_fprop_get_kind(prop) != UNREAL_PROP_KIND_MAP) { + return luaL_error(state, "Find requires a live FString or TMap"); + } + + fprop_map_t *map_prop = (fprop_map_t *)prop; + if (!map_prop->key_prop || !map_prop->val_prop) { + return luaL_error(state, "TMap metadata is incomplete"); + } + + char error[LUA_UNREAL_ERROR_CAP] = {0}; + int result = 0; + bool converted = false; + tmp_arena_t tmp = scratch_begin(NULL); + { + void *key = NULL; + converted = lua_unreal_temporary_from_lua(state, 2, map_prop->key_prop, owner, tmp.arena, &key, error, sizeof(error)); + void *found = converted ? unreal_map_find_value_ptr(value, map_prop, key) : NULL; + if (found) { + result = lua_unreal_map_value_push(state, map_prop, found, key, owner, 1); + } + + if (key) { + unreal_fprop_destroy_value(map_prop->key_prop, key); + } + } + scratch_end(tmp); + + if (!converted) { + return luaL_error(state, "could not convert the map key: %s", error[0] ? error : "conversion failed"); + } + + if (!result) { + return luaL_error(state, "the key was not found in the TMap"); + } + return result; +} + +static int +lua_unreal_value_remove_lua(lua_State *state) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + + fprop_t *prop = NULL; + void *value = NULL; + uobject_t *owner = NULL; + if (!lua_unreal_value_resolve(state, 1, &prop, &value, &owner)) { + return luaL_error(state, "the reflected value is no longer valid"); + } + + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + if (kind == UNREAL_PROP_KIND_ARRAY) { + fprop_array_t *array_prop = (fprop_array_t *)prop; + lua_Integer lua_index = luaL_checkinteger(state, 2); + int32_t count = unreal_array_num(value, array_prop); + if (lua_index < 1 || lua_index > count) { + return luaL_error(state, "array removal index is out of range"); + } + unreal_array_remove(value, array_prop, (int32_t)lua_index - 1); + lua_pushboolean(state, unreal_array_num(value, array_prop) == count - 1); + return 1; + } + + fprop_t *element_prop = NULL; + if (kind == UNREAL_PROP_KIND_SET) { + element_prop = ((fprop_set_t *)prop)->elem_prop; + } else if (kind == UNREAL_PROP_KIND_MAP) { + element_prop = ((fprop_map_t *)prop)->key_prop; + } + + if (!element_prop) { + return luaL_error(state, "this reflected value does not support Remove"); + } + + char error[LUA_UNREAL_ERROR_CAP] = {0}; + bool converted = false; + bool removed = false; + tmp_arena_t tmp = scratch_begin(NULL); + { + void *element = NULL; + + converted = lua_unreal_temporary_from_lua(state, 2, element_prop, owner, tmp.arena, &element, error, sizeof(error)); + if (converted && kind == UNREAL_PROP_KIND_SET) { + removed = unreal_set_remove(value, (fprop_set_t *)prop, element); + } else if (converted) { + removed = unreal_map_remove(value, (fprop_map_t *)prop, element); + } + + if (element) { + unreal_fprop_destroy_value(element_prop, element); + } + } + scratch_end(tmp); + + if (!converted) { + return luaL_error(state, "could not convert the removal value: %s", error[0] ? error : "conversion failed"); + } + + lua_pushboolean(state, removed); + return 1; +} + +static int +lua_unreal_value_tostring(lua_State *state) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + + fprop_t *prop = NULL; + void *value = NULL; + if (!lua_unreal_value_resolve(state, 1, &prop, &value, NULL)) { + lua_pushliteral(state, ""); + return 1; + } + + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + if (kind == UNREAL_PROP_KIND_STRING || kind == UNREAL_PROP_KIND_TEXT || lua_unreal_kind_is_soft_object(kind)) { + return lua_unreal_value_to_string_lua(state); + } + + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t type = unreal_fprop_push_type_name(prop, tmp.arena); + str_t summary = unreal_fprop_push_value_summary(prop, value, prop->elem_size, tmp.arena); + str_t text = str_push_fmt(tmp.arena, "%.*s: %.*s", STR_ARG(type), STR_ARG(summary)); + lua_pushlstring(state, (const char *)text.data, (size_t)text.len); + } + scratch_end(tmp); + return 1; +} + +static int +lua_unreal_object_is_valid_lua(lua_State *state) +{ + lua_unreal_object_t *userdata = lua_unreal_object_test(state, 1); + lua_unreal_require_access(state, userdata ? userdata->context : NULL); + + lua_pushboolean(state, lua_unreal_object_resolve(userdata) != NULL); + return 1; +} + +static uobject_t * +lua_unreal_object_check_live(lua_State *state, int idx) +{ + lua_unreal_object_t *userdata = (lua_unreal_object_t *)luaL_checkudata(state, idx, LUA_UNREAL_OBJECT_MT); + lua_unreal_require_access(state, userdata->context); + + uobject_t *object = lua_unreal_object_resolve(userdata); + if (!object) { + luaL_error(state, "the UObject is no longer valid"); + } + return object; +} + +static int +lua_unreal_object_get_full_name_lua(lua_State *state) +{ + uobject_t *object = lua_unreal_object_check_live(state, 1); + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t path = unreal_uobject_push_ue_path_name(object, tmp.arena); + str_t class_name = object->cls ? unreal_fname_to_str(object->cls->name, tmp.arena) : STR_NULL; + str_t full_name = str_is_empty(class_name) ? path : str_push_fmt(tmp.arena, "%.*s %.*s", STR_ARG(class_name), STR_ARG(path)); + lua_pushlstring(state, (const char *)full_name.data, (size_t)full_name.len); + } + scratch_end(tmp); + return 1; +} + +static int +lua_unreal_object_get_fname_lua(lua_State *state) +{ + return lua_unreal_fname_push(state, lua_unreal_object_check_live(state, 1)->name); +} + +static int +lua_unreal_object_get_address_lua(lua_State *state) +{ + lua_pushinteger(state, (lua_Integer)(uintptr_t)lua_unreal_object_check_live(state, 1)); + return 1; +} + +static int +lua_unreal_object_get_class_lua(lua_State *state) +{ + return lua_unreal_object_push(state, (uobject_t *)lua_unreal_object_check_live(state, 1)->cls); +} + +static int +lua_unreal_object_get_outer_lua(lua_State *state) +{ + return lua_unreal_object_push(state, lua_unreal_object_check_live(state, 1)->outer); +} + +static int +lua_unreal_object_is_class_lua(lua_State *state) +{ + uobject_t *object = lua_unreal_object_check_live(state, 1); + lua_pushboolean(state, unreal_uobject_is_a(object, globals.unreal.core_class)); + return 1; +} + +static int +lua_unreal_object_is_a_lua(lua_State *state) +{ + uobject_t *object = lua_unreal_object_check_live(state, 1); + uclass_t *cls = NULL; + + if (lua_type(state, 2) == LUA_TSTRING) { + size_t len = 0; + const char *text = lua_tolstring(state, 2, &len); + str_t name = str_make((uint8_t *)text, (uint64_t)len); + cls = unreal_uobject_find_class_by_full_name(name); + if (!cls) { + cls = unreal_uclass_find(name, true, true); + } + } else { + uobject_t *class_object = lua_unreal_object_get(state, 2); + if (class_object && unreal_uobject_is_a(class_object, globals.unreal.core_class)) { + cls = (uclass_t *)class_object; + } + } + + if (!cls) { + return luaL_argerror(state, 2, "expected a live UClass or valid class name"); + } + lua_pushboolean(state, unreal_uobject_is_a(object, cls)); + return 1; +} + +static int +lua_unreal_object_has_all_flags_lua(lua_State *state) +{ + uobject_t *object = lua_unreal_object_check_live(state, 1); + eobj_flags_t flags = (eobj_flags_t)lua_unreal_check_u32(state, 2, "flags must fit in an unsigned 32-bit integer"); + lua_pushboolean(state, (object->obj_flags & flags) == flags); + return 1; +} + +static int +lua_unreal_object_has_any_flags_lua(lua_State *state) +{ + uobject_t *object = lua_unreal_object_check_live(state, 1); + eobj_flags_t flags = (eobj_flags_t)lua_unreal_check_u32(state, 2, "flags must fit in an unsigned 32-bit integer"); + lua_pushboolean(state, (object->obj_flags & flags) != 0); + return 1; +} + +static int +lua_unreal_object_has_any_internal_flags_lua(lua_State *state) +{ + uobject_t *object = lua_unreal_object_check_live(state, 1); + uint32_t flags = lua_unreal_check_u32(state, 2, "internal flags must fit in an unsigned 32-bit integer"); + fuobject_item_t *item = unreal_uobject_array_get_item(object->internal_idx); + bool valid = item && unreal_uobject_array_item_is_valid(item) && item->obj == object; + if (!valid) { + return luaL_error(state, "the UObject array entry is no longer valid"); + } + lua_pushboolean(state, ((uint32_t)item->flags & flags) != 0); + return 1; +} + +static int +lua_unreal_object_type_lua(lua_State *state) +{ + uobject_t *object = lua_unreal_object_check_live(state, 1); + const char *type = "UObject"; + if (globals.unreal.data_table && unreal_uobject_is_a(object, globals.unreal.data_table)) { + type = "UDataTable"; + } else if (unreal_uobject_is_a(object, globals.unreal.core_func)) { + type = "UFunction"; + } else if (unreal_uobject_is_a(object, globals.unreal.core_class)) { + type = "UClass"; + } else if (unreal_uobject_is_a(object, globals.unreal.core_scriptstruct)) { + type = "UScriptStruct"; + } else if (unreal_uobject_is_a(object, globals.unreal.core_enum)) { + type = "UEnum"; + } + lua_pushstring(state, type); + return 1; +} + +static int +lua_unreal_object_equal_lua(lua_State *state) +{ + lua_unreal_object_t *left = lua_unreal_object_test(state, 1); + lua_unreal_object_t *right = lua_unreal_object_test(state, 2); + bool equal = left && right && left->weak.object_idx == right->weak.object_idx && left->weak.object_serial == right->weak.object_serial; + lua_pushboolean(state, equal); + return 1; +} + +static int +lua_unreal_object_tostring(lua_State *state) +{ + lua_unreal_object_t *userdata = lua_unreal_object_test(state, 1); + lua_unreal_require_access(state, userdata ? userdata->context : NULL); + + uobject_t *object = lua_unreal_object_resolve(userdata); + if (!object) { + lua_pushliteral(state, ""); + return 1; + } + + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t name = unreal_uobject_push_full_name(object, tmp.arena); + lua_pushlstring(state, (const char *)name.data, (size_t)name.len); + } + scratch_end(tmp); + return 1; +} + +static udata_table_t * +lua_unreal_data_table_check(lua_State *state, int idx) +{ + uobject_t *object = lua_unreal_object_check_live(state, idx); + if (!globals.unreal.data_table || !unreal_uobject_is_a(object, globals.unreal.data_table)) { + luaL_argerror(state, idx, "expected a UDataTable"); + } + return (udata_table_t *)object; +} + +static uscript_struct_t * +lua_unreal_data_table_row_struct_check(lua_State *state, udata_table_t *table) +{ + uscript_struct_t *row_struct = table ? table->row_struct : NULL; + if (!row_struct || !globals.unreal.core_scriptstruct || !unreal_uobject_is_valid((uobject_t *)row_struct) || + !unreal_uobject_is_a((uobject_t *)row_struct, globals.unreal.core_scriptstruct) || row_struct->props_size < 0) { + luaL_error(state, "the UDataTable has no valid row structure"); + } + return row_struct; +} + +static fname_t +lua_unreal_data_table_row_name_check(lua_State *state, int idx) +{ + lua_unreal_fname_t *name_value = lua_unreal_fname_test(state, idx); + fname_t name = name_value ? name_value->value : (fname_t){0}; + if (!name_value) { + size_t len = 0; + const char *text = luaL_checklstring(state, idx, &len); + str_t value = str_make((uint8_t *)text, (uint64_t)len); + if (str_is_empty(value) || lua_unreal_string_has_embedded_null(value)) { + luaL_argerror(state, idx, "row name cannot be empty or contain null bytes"); + } + name = unreal_fname_from_str(value, FNAME_FIND_OR_ADD); + } + + if (unreal_fname_is_none(name)) { + luaL_argerror(state, idx, "row name cannot be None"); + } + return name; +} + +static int +lua_unreal_data_table_row_push(lua_State *state, udata_table_t *table, fname_t row_name) +{ + fweak_object_ptr_t weak = {0}; + if (!table || !unreal_fweak_object_from_object((uobject_t *)table, &weak) || !unreal_udata_table_find_row(table, row_name)) { + lua_pushnil(state); + return 1; + } + + lua_unreal_data_table_row_t *row = (lua_unreal_data_table_row_t *)lua_newuserdatauv(state, sizeof(*row), 0); + row->context = lua_unreal_context_from_state(state); + row->table = weak; + row->row_name = row_name; + luaL_setmetatable(state, LUA_UNREAL_DATA_TABLE_ROW_MT); + return 1; +} + +static int +lua_unreal_data_table_row_is_valid_lua(lua_State *state) +{ + lua_unreal_data_table_row_t *row = (lua_unreal_data_table_row_t *)luaL_checkudata(state, 1, LUA_UNREAL_DATA_TABLE_ROW_MT); + lua_unreal_require_access(state, row->context); + lua_pushboolean(state, lua_unreal_data_table_row_resolve(row, NULL, NULL, NULL)); + return 1; +} + +static int +lua_unreal_data_table_row_type_lua(lua_State *state) +{ + lua_unreal_data_table_row_t *row = (lua_unreal_data_table_row_t *)luaL_checkudata(state, 1, LUA_UNREAL_DATA_TABLE_ROW_MT); + lua_unreal_require_access(state, row->context); + if (!lua_unreal_data_table_row_resolve(row, NULL, NULL, NULL)) { + return luaL_error(state, "the UDataTable row is no longer valid"); + } + lua_pushliteral(state, "UScriptStruct"); + return 1; +} + +static int +lua_unreal_data_table_row_tostring_lua(lua_State *state) +{ + lua_unreal_data_table_row_t *row = (lua_unreal_data_table_row_t *)luaL_checkudata(state, 1, LUA_UNREAL_DATA_TABLE_ROW_MT); + lua_unreal_require_access(state, row->context); + if (!lua_unreal_data_table_row_resolve(row, NULL, NULL, NULL)) { + lua_pushliteral(state, ""); + return 1; + } + + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t name = unreal_fname_to_str(row->row_name, tmp.arena); + lua_pushlstring(state, (const char *)name.data, (size_t)name.len); + } + scratch_end(tmp); + return 1; +} + +static int +lua_unreal_data_table_row_index_lua(lua_State *state) +{ + lua_unreal_data_table_row_t *row = (lua_unreal_data_table_row_t *)luaL_checkudata(state, 1, LUA_UNREAL_DATA_TABLE_ROW_MT); + lua_unreal_require_access(state, row->context); + + size_t key_len = 0; + const char *key = luaL_checklstring(state, 2, &key_len); + udata_table_t *table = NULL; + uscript_struct_t *row_struct = NULL; + uint8_t *value = NULL; + if (lua_unreal_data_table_row_resolve(row, &table, &row_struct, &value)) { + fprop_t *field = unreal_ustruct_find_prop((ustruct_t *)row_struct, str_make((uint8_t *)key, (uint64_t)key_len)); + if (field) { + if (!lua_unreal_property_fits(field, (uint64_t)row_struct->props_size)) { + return luaL_error(state, "row field '%s' has an unsupported reflected layout", key); + } + + void *field_value = unreal_fprop_value_in_container(field, value, 0); + if (!field_value || !lua_unreal_prop_push_selected(state, field, field_value, (uobject_t *)table, 1, true, LUA_UNREAL_SELECTOR_FIELD, 0, false)) { + return luaL_error(state, "row field '%s' has an unsupported reflected type", key); + } + return 1; + } + } + + if (lua_getmetatable(state, 1)) { + lua_pushvalue(state, 2); + lua_rawget(state, -2); + lua_remove(state, -2); + if (!lua_isnil(state, -1)) { + return 1; + } + lua_pop(state, 1); + } + + if (!value) { + return luaL_error(state, "the UDataTable row is no longer valid"); + } + lua_pushnil(state); + return 1; +} + +static int +lua_unreal_data_table_row_newindex_lua(lua_State *state) +{ + lua_unreal_data_table_row_t *row = (lua_unreal_data_table_row_t *)luaL_checkudata(state, 1, LUA_UNREAL_DATA_TABLE_ROW_MT); + lua_unreal_require_access(state, row->context); + + size_t key_len = 0; + const char *key = luaL_checklstring(state, 2, &key_len); + udata_table_t *table = NULL; + uscript_struct_t *row_struct = NULL; + uint8_t *value = NULL; + + if (!lua_unreal_data_table_row_resolve(row, &table, &row_struct, &value)) { + return luaL_error(state, "the UDataTable row is no longer valid"); + } + + fprop_t *field = unreal_ustruct_find_prop((ustruct_t *)row_struct, str_make((uint8_t *)key, (uint64_t)key_len)); + if (!field || !lua_unreal_property_fits(field, (uint64_t)row_struct->props_size)) { + return luaL_error(state, "unknown or unsupported row field '%s'", key); + } + + void *dst = unreal_fprop_value_in_container(field, value, 0); + char error[LUA_UNREAL_ERROR_CAP] = {0}; + if (!dst || !lua_unreal_write_transactional(state, 3, field, dst, (uobject_t *)table, error, sizeof(error))) { + return luaL_error(state, "could not assign row field '%s': %s", key, error[0] ? error : "conversion failed"); + } + return 0; +} + +static int +lua_unreal_data_table_get_row_struct_lua(lua_State *state) +{ + udata_table_t *table = lua_unreal_data_table_check(state, 1); + uscript_struct_t *row_struct = table->row_struct; + if (!row_struct || !unreal_uobject_is_valid((uobject_t *)row_struct)) { + return lua_unreal_object_push(state, NULL); + } + return lua_unreal_object_push(state, (uobject_t *)row_struct); +} + +static int +lua_unreal_data_table_get_row_map_lua(lua_State *state) +{ + udata_table_t *table = lua_unreal_data_table_check(state, 1); + tmap_fname_uint8ptr_t *map = unreal_udata_table_get_row_map(table); + int32_t count = map ? TMAP_NUM(map) : 0; + lua_createtable(state, 0, MAX_VAL(count, 0)); + + if (map) { + TMAP_FOR_EACH_INDEX(map, idx) { + fname_t name = TMAP_KEY_AT(map, idx); + if (!TMAP_VALUE_AT(map, idx)) { + continue; + } + + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t text = unreal_fname_to_str(name, tmp.arena); + lua_pushlstring(state, (const char *)text.data, (size_t)text.len); + } + scratch_end(tmp); + + lua_unreal_data_table_row_push(state, table, name); + lua_rawset(state, -3); + } + } + return 1; +} + +static int +lua_unreal_data_table_find_row_lua(lua_State *state) +{ + udata_table_t *table = lua_unreal_data_table_check(state, 1); + fname_t name = lua_unreal_data_table_row_name_check(state, 2); + return lua_unreal_data_table_row_push(state, table, name); +} + +static int +lua_unreal_data_table_add_row_lua(lua_State *state) +{ + udata_table_t *table = lua_unreal_data_table_check(state, 1); + fname_t name = lua_unreal_data_table_row_name_check(state, 2); + uscript_struct_t *row_struct = lua_unreal_data_table_row_struct_check(state, table); + int value_idx = lua_absindex(state, 3); + + const void *source = NULL; + lua_unreal_data_table_row_t *source_row = (lua_unreal_data_table_row_t *)luaL_testudata(state, value_idx, LUA_UNREAL_DATA_TABLE_ROW_MT); + if (source_row) { + udata_table_t *source_table = NULL; + uscript_struct_t *source_row_struct = NULL; + uint8_t *source_value = NULL; + if (!lua_unreal_data_table_row_resolve(source_row, &source_table, &source_row_struct, &source_value) || source_row_struct != row_struct) { + return luaL_argerror(state, 3, "expected a live row with the same row structure"); + } + + if (source_table == table && source_row->row_name.cmp_idx == name.cmp_idx && source_row->row_name.num == name.num) { + return 0; + } + source = source_value; + } else { + fprop_t *source_prop = NULL; + void *source_value = NULL; + if (lua_unreal_value_resolve(state, value_idx, &source_prop, &source_value, NULL)) { + bool compatible = unreal_fprop_get_kind(source_prop) == UNREAL_PROP_KIND_STRUCT && ((fprop_struct_t *)source_prop)->script_struct == row_struct; + if (!compatible) { + return luaL_argerror(state, 3, "expected a compatible UScriptStruct value"); + } + source = source_value; + } + } + + char error[LUA_UNREAL_ERROR_CAP] = {0}; + bool added = false; + tmp_arena_t tmp = scratch_begin(NULL); + { + void *temporary = NULL; + bool initialized = false; + if (!source && lua_type(state, value_idx) == LUA_TTABLE) { + int32_t alignment = MAX_VAL(row_struct->min_alignment, 1); + if (alignment <= LUA_UNREAL_MAX_ALIGNMENT) { + temporary = arena_push_zero_aligned(tmp.arena, MAX_VAL((uint64_t)row_struct->props_size, 1ULL), (uint64_t)alignment); + } + + initialized = temporary && unreal_ustruct_initialize_struct((ustruct_t *)row_struct, temporary, 1); + if (!temporary) { + lua_unreal_error_set(error, sizeof(error), "could not allocate temporary row storage"); + } else if (!initialized) { + lua_unreal_error_set(error, sizeof(error), "could not initialize temporary row storage"); + } else if (!lua_unreal_write_struct_table(state, value_idx, (ustruct_t *)row_struct, (uint64_t)row_struct->props_size, temporary, (uobject_t *)table, error, sizeof(error))) { + /* the field writer provides the error */ + } else { + source = temporary; + } + } else if (!source) { + lua_unreal_error_set(error, sizeof(error), "expected a table or compatible UScriptStruct value"); + } + + if (source) { + unreal_udata_table_add_row(table, name, (const ftable_row_base_t *)source); + added = unreal_udata_table_find_row(table, name) != NULL; + if (!added) { + lua_unreal_error_set(error, sizeof(error), "the row was not added"); + } + } + + if (initialized) { + unreal_ustruct_destroy_struct((ustruct_t *)row_struct, temporary, 1); + } + } + scratch_end(tmp); + + if (!added) { + return luaL_error(state, "could not add UDataTable row: %s", error[0] ? error : "conversion failed"); + } + return 0; +} + +static int +lua_unreal_data_table_remove_row_lua(lua_State *state) +{ + udata_table_t *table = lua_unreal_data_table_check(state, 1); + fname_t name = lua_unreal_data_table_row_name_check(state, 2); + unreal_udata_table_remove_row(table, name); + return 0; +} + +static int +lua_unreal_data_table_empty_lua(lua_State *state) +{ + unreal_udata_table_empty(lua_unreal_data_table_check(state, 1)); + return 0; +} + +static int +lua_unreal_data_table_get_row_names_lua(lua_State *state) +{ + udata_table_t *table = lua_unreal_data_table_check(state, 1); + tmap_fname_uint8ptr_t *map = unreal_udata_table_get_row_map(table); + int32_t count = map ? TMAP_NUM(map) : 0; + lua_createtable(state, MAX_VAL(count, 0), 0); + + lua_Integer output_idx = 0; + if (map) { + TMAP_FOR_EACH_INDEX(map, idx) { + if (!TMAP_VALUE_AT(map, idx)) { + continue; + } + + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t text = unreal_fname_to_str(TMAP_KEY_AT(map, idx), tmp.arena); + lua_pushlstring(state, (const char *)text.data, (size_t)text.len); + } + scratch_end(tmp); + + lua_rawseti(state, -2, ++output_idx); + } + } + return 1; +} + +static int +lua_unreal_data_table_get_all_rows_lua(lua_State *state) +{ + udata_table_t *table = lua_unreal_data_table_check(state, 1); + tmap_fname_uint8ptr_t *map = unreal_udata_table_get_row_map(table); + int32_t count = map ? TMAP_NUM(map) : 0; + lua_createtable(state, MAX_VAL(count, 0), 0); + + lua_Integer output_idx = 0; + if (map) { + TMAP_FOR_EACH_INDEX(map, idx) { + fname_t name = TMAP_KEY_AT(map, idx); + if (!TMAP_VALUE_AT(map, idx)) { + continue; + } + + lua_createtable(state, 0, 2); + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t text = unreal_fname_to_str(name, tmp.arena); + lua_pushlstring(state, (const char *)text.data, (size_t)text.len); + } + scratch_end(tmp); + + lua_setfield(state, -2, "Name"); + lua_unreal_data_table_row_push(state, table, name); + lua_setfield(state, -2, "Data"); + lua_rawseti(state, -2, ++output_idx); + } + } + return 1; +} + +static int +lua_unreal_data_table_for_each_row_lua(lua_State *state) +{ + udata_table_t *table = lua_unreal_data_table_check(state, 1); + luaL_checktype(state, 2, LUA_TFUNCTION); + + int callback_idx = lua_absindex(state, 2); + tmap_fname_uint8ptr_t *map = unreal_udata_table_get_row_map(table); + int32_t count = map ? TMAP_NUM(map) : 0; + + int result = 0; + tmp_arena_t tmp = scratch_begin(NULL); + { + fname_t *names = count > 0 ? ARENA_PUSH_ARRAY(tmp.arena, fname_t, count) : NULL; + if (count <= 0 || names) { + int32_t name_count = 0; + if (map) { + TMAP_FOR_EACH_INDEX(map, idx) { + if (TMAP_VALUE_AT(map, idx) && name_count < count) { + names[name_count++] = TMAP_KEY_AT(map, idx); + } + } + } + + for (int32_t i = 0; i < name_count; ++i) { + fname_t name = names[i]; + if (!unreal_udata_table_find_row(table, name)) { + continue; + } + + lua_pushvalue(state, callback_idx); + str_t text = unreal_fname_to_str(name, tmp.arena); + lua_pushlstring(state, (const char *)text.data, (size_t)text.len); + lua_unreal_data_table_row_push(state, table, name); + + if (lua_pcall(state, 2, 1, 0) != LUA_OK) { + result = lua_error(state); + break; + } + + bool stop = lua_toboolean(state, -1) != 0; + lua_pop(state, 1); + if (stop) { + break; + } + } + } else { + result = luaL_error(state, "could not allocate UDataTable row-name snapshot"); + } + } + scratch_end(tmp); + + return result; +} + +static int +lua_unreal_object_get_world_lua(lua_State *state) +{ + uobject_t *object = lua_unreal_object_check_live(state, 1); + uworld_t *world = object->vtable && object->vtable->get_world ? object->vtable->get_world(object) : NULL; + return lua_unreal_object_push(state, (uobject_t *)world); +} + +static bool +lua_unreal_object_is_struct_type(uobject_t *object) +{ + return object && + (unreal_uobject_is_a(object, globals.unreal.core_class) || + unreal_uobject_is_a(object, globals.unreal.core_scriptstruct) || + unreal_uobject_is_a(object, globals.unreal.core_func)); +} + +static ustruct_t * +lua_unreal_ustruct_check(lua_State *state, int idx) +{ + uobject_t *object = lua_unreal_object_check_live(state, idx); + if (!lua_unreal_object_is_struct_type(object)) { + luaL_argerror(state, idx, "expected a live UStruct, UClass, UScriptStruct, or UFunction"); + } + return (ustruct_t *)object; +} + +static bool +lua_unreal_ffield_is_property(ffield_t *field) +{ + for (ffield_class_t *cls = field ? field->cls : NULL; cls; cls = cls->super_class) { + if (unreal_fname_match_text(cls->name, STR_LIT("Property"), false, true)) { + return true; + } + } + return false; +} + +static bool +lua_unreal_property_is_direct_member(ustruct_t *type, fprop_t *prop) +{ + if (!type || !prop) { + return false; + } + + for (ffield_t *field = type->child_props; field; field = field->next) { + if (field == (ffield_t *)prop && lua_unreal_ffield_is_property(field)) { + return true; + } + } + return false; +} + +static bool +lua_unreal_property_is_member(ustruct_t *type, fprop_t *prop) +{ + return lua_unreal_property_is_direct_member(type, prop) || lua_unreal_property_belongs_to_struct(type, prop); +} + +static bool +lua_unreal_property_is_nested_member(fprop_t *parent, fprop_t *prop) +{ + if (!parent || !prop) { + return false; + } + + switch (unreal_fprop_get_kind(parent)) { + case UNREAL_PROP_KIND_ARRAY: { + return ((fprop_array_t *)parent)->inner == prop; + } + + case UNREAL_PROP_KIND_SET: { + return ((fprop_set_t *)parent)->elem_prop == prop; + } + + case UNREAL_PROP_KIND_MAP: { + fprop_map_t *map = (fprop_map_t *)parent; + return map->key_prop == prop || map->val_prop == prop; + } + + case UNREAL_PROP_KIND_ENUM: { + return (fprop_t *)((fprop_enum_t *)parent)->underlying_prop == prop; + } + + default: return false; + } +} + +static bool +lua_unreal_property_resolve_depth(lua_State *state, int idx, fprop_t **out_prop, int depth) +{ + idx = lua_absindex(state, idx); + lua_unreal_property_t *property = (lua_unreal_property_t *)luaL_testudata(state, idx, LUA_UNREAL_PROPERTY_MT); + if (!property || !property->prop || depth >= 64) { + return false; + } + + int anchor_type = lua_getiuservalue(state, idx, 1); + int anchor_idx = lua_gettop(state); + bool valid = false; + + if (anchor_type == LUA_TUSERDATA) { + lua_unreal_object_t *owner_value = lua_unreal_object_test(state, anchor_idx); + if (owner_value) { + uobject_t *owner = lua_unreal_object_resolve(owner_value); + valid = lua_unreal_object_is_struct_type(owner) && lua_unreal_property_is_member((ustruct_t *)owner, property->prop); + } else { + fprop_t *parent = NULL; + valid = lua_unreal_property_resolve_depth(state, anchor_idx, &parent, depth + 1) && lua_unreal_property_is_nested_member(parent, property->prop); + } + } + + lua_pop(state, 1); + if (valid && out_prop) { + *out_prop = property->prop; + } + return valid; +} + +static bool +lua_unreal_property_resolve(lua_State *state, int idx, fprop_t **out_prop) +{ + return lua_unreal_property_resolve_depth(state, idx, out_prop, 0); +} + +static int +lua_unreal_property_push_root(lua_State *state, fprop_t *prop, ustruct_t *fallback_owner) +{ + lua_unreal_property_t *property = (lua_unreal_property_t *)lua_newuserdatauv(state, sizeof(*property), 1); + property->context = lua_unreal_context_from_state(state); + property->prop = prop; + luaL_setmetatable(state, LUA_UNREAL_PROPERTY_MT); + + if (!prop) { + return 1; + } + + ustruct_t *owner = fallback_owner; + if (prop->owner.is_uobject) { + uobject_t *candidate = prop->owner.container.obj; + if (unreal_uobject_is_valid(candidate) && lua_unreal_object_is_struct_type(candidate) && lua_unreal_property_is_member((ustruct_t *)candidate, prop)) { + owner = (ustruct_t *)candidate; + } + } + + lua_unreal_object_push(state, (uobject_t *)owner); + lua_setiuservalue(state, -2, 1); + return 1; +} + +static int +lua_unreal_property_push_nested(lua_State *state, fprop_t *prop, int parent_idx) +{ + parent_idx = lua_absindex(state, parent_idx); + lua_unreal_property_t *property = (lua_unreal_property_t *)lua_newuserdatauv(state, sizeof(*property), 1); + property->context = lua_unreal_context_from_state(state); + property->prop = prop; + luaL_setmetatable(state, LUA_UNREAL_PROPERTY_MT); + lua_pushvalue(state, parent_idx); + lua_setiuservalue(state, -2, 1); + return 1; +} + +static fprop_t * +lua_unreal_property_check_live(lua_State *state, int idx) +{ + lua_unreal_property_t *property = (lua_unreal_property_t *)luaL_checkudata(state, idx, LUA_UNREAL_PROPERTY_MT); + lua_unreal_require_access(state, property->context); + + fprop_t *prop = NULL; + if (!lua_unreal_property_resolve(state, idx, &prop)) { + luaL_error(state, "the reflected property is no longer valid"); + } + return prop; +} + +static uobject_t * +lua_unreal_property_owner_object_depth(lua_State *state, int idx, int depth) +{ + if (depth >= 64) { + return NULL; + } + + idx = lua_absindex(state, idx); + int anchor_type = lua_getiuservalue(state, idx, 1); + int anchor_idx = lua_gettop(state); + uobject_t *owner = NULL; + if (anchor_type == LUA_TUSERDATA) { + lua_unreal_object_t *object = lua_unreal_object_test(state, anchor_idx); + if (object) { + owner = lua_unreal_object_resolve(object); + } else if (luaL_testudata(state, anchor_idx, LUA_UNREAL_PROPERTY_MT)) { + owner = lua_unreal_property_owner_object_depth(state, anchor_idx, depth + 1); + } + } + lua_pop(state, 1); + return owner; +} + +static uobject_t * +lua_unreal_property_owner_object(lua_State *state, int idx) +{ + return lua_unreal_property_owner_object_depth(state, idx, 0); +} + +static int +lua_unreal_property_is_valid_lua(lua_State *state) +{ + lua_unreal_property_t *property = (lua_unreal_property_t *)luaL_checkudata(state, 1, LUA_UNREAL_PROPERTY_MT); + lua_unreal_require_access(state, property->context); + lua_pushboolean(state, lua_unreal_property_resolve(state, 1, NULL)); + return 1; +} + +static int +lua_unreal_property_get_fname_lua(lua_State *state) +{ + return lua_unreal_fname_push(state, lua_unreal_property_check_live(state, 1)->name); +} + +static int +lua_unreal_property_get_full_name_lua(lua_State *state) +{ + fprop_t *prop = lua_unreal_property_check_live(state, 1); + uobject_t *owner = lua_unreal_property_owner_object(state, 1); + + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t class_name = prop->cls ? unreal_fname_to_str(prop->cls->name, tmp.arena) : STR_LIT("Property"); + str_t prop_name = unreal_fname_to_str(prop->name, tmp.arena); + str_t owner_name = owner ? unreal_uobject_push_full_name(owner, tmp.arena) : STR_LIT(""); + str_t full_name = str_push_fmt(tmp.arena, "%.*s %.*s.%.*s", STR_ARG(class_name), STR_ARG(owner_name), STR_ARG(prop_name)); + lua_pushlstring(state, (const char *)full_name.data, (size_t)full_name.len); + } + scratch_end(tmp); + return 1; +} + +static bool +lua_unreal_field_class_resolve(lua_State *state, int idx, ffield_class_t **out_class) +{ + idx = lua_absindex(state, idx); + lua_unreal_field_class_t *field_class = (lua_unreal_field_class_t *)luaL_testudata(state, idx, LUA_UNREAL_FIELD_CLASS_MT); + if (!field_class || !field_class->cls) { + return false; + } + + if (lua_getiuservalue(state, idx, 1) != LUA_TUSERDATA) { + lua_pop(state, 1); + return false; + } + + int property_idx = lua_gettop(state); + fprop_t *prop = NULL; + bool valid = lua_unreal_property_resolve(state, property_idx, &prop); + bool found = false; + for (ffield_class_t *cls = valid ? prop->cls : NULL; cls; cls = cls->super_class) { + if (cls == field_class->cls) { + found = true; + break; + } + } + lua_pop(state, 1); + + if (found && out_class) { + *out_class = field_class->cls; + } + return found; +} + +static int +lua_unreal_field_class_push(lua_State *state, ffield_class_t *cls, int property_idx) +{ + property_idx = lua_absindex(state, property_idx); + lua_unreal_field_class_t *field_class = (lua_unreal_field_class_t *)lua_newuserdatauv(state, sizeof(*field_class), 1); + field_class->context = lua_unreal_context_from_state(state); + field_class->cls = cls; + luaL_setmetatable(state, LUA_UNREAL_FIELD_CLASS_MT); + lua_pushvalue(state, property_idx); + lua_setiuservalue(state, -2, 1); + return 1; +} + +static int +lua_unreal_property_get_class_lua(lua_State *state) +{ + fprop_t *prop = lua_unreal_property_check_live(state, 1); + return lua_unreal_field_class_push(state, prop->cls, 1); +} + +static int +lua_unreal_property_is_a_lua(lua_State *state) +{ + fprop_t *prop = lua_unreal_property_check_live(state, 1); + + lua_unreal_field_class_t *field_class = (lua_unreal_field_class_t *)luaL_testudata(state, 2, LUA_UNREAL_FIELD_CLASS_MT); + if (field_class) { + ffield_class_t *wanted = NULL; + if (!lua_unreal_field_class_resolve(state, 2, &wanted)) { + return luaL_argerror(state, 2, "the FieldClass is no longer valid"); + } + + for (ffield_class_t *cls = prop->cls; cls; cls = cls->super_class) { + if (cls == wanted) { + lua_pushboolean(state, true); + return 1; + } + } + lua_pushboolean(state, false); + return 1; + } + + str_t class_name = STR_NULL; + if (!lua_unreal_string_or_fname(state, 2, &class_name) || str_is_empty(class_name)) { + return luaL_argerror(state, 2, "expected PropertyTypes value, property class name, FName, or FieldClass"); + } + + for (ffield_class_t *cls = prop->cls; cls; cls = cls->super_class) { + if (unreal_fname_match_text(cls->name, class_name, false, true)) { + lua_pushboolean(state, true); + return 1; + } + } + lua_pushboolean(state, false); + return 1; +} + +static int +lua_unreal_property_get_offset_lua(lua_State *state) +{ + lua_pushinteger(state, lua_unreal_property_check_live(state, 1)->offset_internal); + return 1; +} + +static int +lua_unreal_property_get_array_dim_lua(lua_State *state) +{ + lua_pushinteger(state, lua_unreal_property_check_live(state, 1)->array_dim); + return 1; +} + +static int +lua_unreal_property_get_element_size_lua(lua_State *state) +{ + lua_pushinteger(state, lua_unreal_property_check_live(state, 1)->elem_size); + return 1; +} + +static int +lua_unreal_property_get_property_class_lua(lua_State *state) +{ + fprop_t *prop = lua_unreal_property_check_live(state, 1); + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + uclass_t *cls = NULL; + + if (kind == UNREAL_PROP_KIND_OBJECT || kind == UNREAL_PROP_KIND_CLASS || + kind == UNREAL_PROP_KIND_WEAK_OBJECT || kind == UNREAL_PROP_KIND_LAZY_OBJECT || + kind == UNREAL_PROP_KIND_SOFT_OBJECT || kind == UNREAL_PROP_KIND_SOFT_CLASS) { + cls = ((fprop_obj_base_t *)prop)->prop_class; + } else if (kind == UNREAL_PROP_KIND_INTERFACE) { + cls = ((fprop_iface_t *)prop)->iface_class; + } else { + return luaL_error(state, "GetPropertyClass requires an object or interface property"); + } + return lua_unreal_object_push(state, (uobject_t *)cls); +} + +static fprop_bool_t * +lua_unreal_bool_property_check(lua_State *state) +{ + fprop_t *prop = lua_unreal_property_check_live(state, 1); + if (unreal_fprop_get_kind(prop) != UNREAL_PROP_KIND_BOOL) { + luaL_error(state, "this property is not a BoolProperty"); + } + return (fprop_bool_t *)prop; +} + +static int +lua_unreal_bool_property_get_byte_mask_lua(lua_State *state) +{ + lua_pushinteger(state, lua_unreal_bool_property_check(state)->byte_mask); + return 1; +} + +static int +lua_unreal_bool_property_get_byte_offset_lua(lua_State *state) +{ + lua_pushinteger(state, lua_unreal_bool_property_check(state)->byte_offset); + return 1; +} + +static int +lua_unreal_bool_property_get_field_mask_lua(lua_State *state) +{ + lua_pushinteger(state, lua_unreal_bool_property_check(state)->field_mask); + return 1; +} + +static int +lua_unreal_bool_property_get_field_size_lua(lua_State *state) +{ + lua_pushinteger(state, lua_unreal_bool_property_check(state)->field_size); + return 1; +} + +static int +lua_unreal_property_get_struct_lua(lua_State *state) +{ + fprop_t *prop = lua_unreal_property_check_live(state, 1); + if (unreal_fprop_get_kind(prop) != UNREAL_PROP_KIND_STRUCT) { + return luaL_error(state, "GetStruct requires a StructProperty"); + } + return lua_unreal_object_push(state, (uobject_t *)((fprop_struct_t *)prop)->script_struct); +} + +static int +lua_unreal_property_get_inner_lua(lua_State *state) +{ + fprop_t *prop = lua_unreal_property_check_live(state, 1); + if (unreal_fprop_get_kind(prop) != UNREAL_PROP_KIND_ARRAY || !((fprop_array_t *)prop)->inner) { + return luaL_error(state, "GetInner requires an ArrayProperty with valid inner metadata"); + } + return lua_unreal_property_push_nested(state, ((fprop_array_t *)prop)->inner, 1); +} + +static int +lua_unreal_property_get_element_property_lua(lua_State *state) +{ + fprop_t *prop = lua_unreal_property_check_live(state, 1); + if (unreal_fprop_get_kind(prop) != UNREAL_PROP_KIND_SET || !((fprop_set_t *)prop)->elem_prop) { + return luaL_error(state, "GetElementProperty requires a SetProperty with valid element metadata"); + } + return lua_unreal_property_push_nested(state, ((fprop_set_t *)prop)->elem_prop, 1); +} + +static int +lua_unreal_property_get_key_property_lua(lua_State *state) +{ + fprop_t *prop = lua_unreal_property_check_live(state, 1); + if (unreal_fprop_get_kind(prop) != UNREAL_PROP_KIND_MAP || !((fprop_map_t *)prop)->key_prop) { + return luaL_error(state, "GetKeyProperty requires a MapProperty with valid key metadata"); + } + return lua_unreal_property_push_nested(state, ((fprop_map_t *)prop)->key_prop, 1); +} + +static int +lua_unreal_property_get_value_property_lua(lua_State *state) +{ + fprop_t *prop = lua_unreal_property_check_live(state, 1); + if (unreal_fprop_get_kind(prop) != UNREAL_PROP_KIND_MAP || !((fprop_map_t *)prop)->val_prop) { + return luaL_error(state, "GetValueProperty requires a MapProperty with valid value metadata"); + } + return lua_unreal_property_push_nested(state, ((fprop_map_t *)prop)->val_prop, 1); +} + +static int +lua_unreal_property_get_underlying_property_lua(lua_State *state) +{ + fprop_t *prop = lua_unreal_property_check_live(state, 1); + fprop_t *underlying = unreal_fprop_get_kind(prop) == UNREAL_PROP_KIND_ENUM + ? (fprop_t *)((fprop_enum_t *)prop)->underlying_prop + : NULL; + if (!underlying) { + return luaL_error(state, "GetUnderlyingProperty requires an EnumProperty with valid underlying metadata"); + } + return lua_unreal_property_push_nested(state, underlying, 1); +} + +static int +lua_unreal_property_get_enum_lua(lua_State *state) +{ + fprop_t *prop = lua_unreal_property_check_live(state, 1); + uenum_t *uenum = NULL; + if (unreal_fprop_get_kind(prop) == UNREAL_PROP_KIND_ENUM) { + uenum = ((fprop_enum_t *)prop)->uenum; + } else if (unreal_fprop_get_kind(prop) == UNREAL_PROP_KIND_BYTE) { + uenum = ((fprop_byte_t *)prop)->uenum; + } else { + return luaL_error(state, "GetEnum requires an EnumProperty or ByteProperty"); + } + return lua_unreal_object_push(state, (uobject_t *)uenum); +} + +static int +lua_unreal_property_type_lua(lua_State *state) +{ + (void)lua_unreal_property_check_live(state, 1); + lua_pushliteral(state, "Property"); + return 1; +} + +static int +lua_unreal_property_tostring_lua(lua_State *state) +{ + lua_unreal_property_t *property = (lua_unreal_property_t *)luaL_checkudata(state, 1, LUA_UNREAL_PROPERTY_MT); + lua_unreal_require_access(state, property->context); + if (!lua_unreal_property_resolve(state, 1, NULL)) { + lua_pushliteral(state, ""); + return 1; + } + return lua_unreal_property_get_full_name_lua(state); +} + +static int +lua_unreal_field_class_is_valid_lua(lua_State *state) +{ + lua_unreal_field_class_t *field_class = (lua_unreal_field_class_t *)luaL_checkudata(state, 1, LUA_UNREAL_FIELD_CLASS_MT); + lua_unreal_require_access(state, field_class->context); + lua_pushboolean(state, lua_unreal_field_class_resolve(state, 1, NULL)); + return 1; +} + +static ffield_class_t * +lua_unreal_field_class_check_live(lua_State *state, int idx) +{ + lua_unreal_field_class_t *field_class = (lua_unreal_field_class_t *)luaL_checkudata(state, idx, LUA_UNREAL_FIELD_CLASS_MT); + lua_unreal_require_access(state, field_class->context); + ffield_class_t *cls = NULL; + if (!lua_unreal_field_class_resolve(state, idx, &cls)) { + luaL_error(state, "the FieldClass is no longer valid"); + } + return cls; +} + +static int +lua_unreal_field_class_get_fname_lua(lua_State *state) +{ + return lua_unreal_fname_push(state, lua_unreal_field_class_check_live(state, 1)->name); +} + +static int +lua_unreal_field_class_type_lua(lua_State *state) +{ + (void)lua_unreal_field_class_check_live(state, 1); + lua_pushliteral(state, "FieldClass"); + return 1; +} + +static int +lua_unreal_field_class_tostring_lua(lua_State *state) +{ + ffield_class_t *cls = lua_unreal_field_class_check_live(state, 1); + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t name = unreal_fname_to_str(cls->name, tmp.arena); + lua_pushlstring(state, (const char *)name.data, (size_t)name.len); + } + scratch_end(tmp); + return 1; +} + +static uobject_t * +lua_unreal_reflection_resolve(lua_unreal_reflection_t *reflection) +{ + return reflection ? unreal_fweak_object_resolve(reflection->object) : NULL; +} + +static ustruct_t * +lua_unreal_reflection_get_type(uobject_t *object) +{ + return lua_unreal_object_is_struct_type(object) ? (ustruct_t *)object : (object ? (ustruct_t *)object->cls : NULL); +} + +static int +lua_unreal_object_reflection_lua(lua_State *state) +{ + lua_unreal_object_t *object = (lua_unreal_object_t *)luaL_checkudata(state, 1, LUA_UNREAL_OBJECT_MT); + (void)lua_unreal_object_check_live(state, 1); + + lua_unreal_reflection_t *reflection = (lua_unreal_reflection_t *)lua_newuserdatauv(state, sizeof(*reflection), 0); + reflection->context = object->context; + reflection->object = object->weak; + luaL_setmetatable(state, LUA_UNREAL_REFLECTION_MT); + return 1; +} + +static int +lua_unreal_reflection_is_valid_lua(lua_State *state) +{ + lua_unreal_reflection_t *reflection = (lua_unreal_reflection_t *)luaL_checkudata(state, 1, LUA_UNREAL_REFLECTION_MT); + lua_unreal_require_access(state, reflection->context); + lua_pushboolean(state, lua_unreal_reflection_get_type(lua_unreal_reflection_resolve(reflection)) != NULL); + return 1; +} + +static int +lua_unreal_reflection_get_property_lua(lua_State *state) +{ + lua_unreal_reflection_t *reflection = (lua_unreal_reflection_t *)luaL_checkudata(state, 1, LUA_UNREAL_REFLECTION_MT); + lua_unreal_require_access(state, reflection->context); + + str_t name = STR_NULL; + if (!lua_unreal_string_or_fname(state, 2, &name) || str_is_empty(name)) { + return luaL_argerror(state, 2, "expected a non-empty property name or FName"); + } + + ustruct_t *type = lua_unreal_reflection_get_type(lua_unreal_reflection_resolve(reflection)); + if (!type) { + return luaL_error(state, "the reflected UObject is no longer valid"); + } + + fprop_t *prop = unreal_ustruct_find_prop(type, name); + return lua_unreal_property_push_root(state, prop, type); +} + +static int +lua_unreal_reflection_type_lua(lua_State *state) +{ + lua_unreal_reflection_t *reflection = (lua_unreal_reflection_t *)luaL_checkudata(state, 1, LUA_UNREAL_REFLECTION_MT); + lua_unreal_require_access(state, reflection->context); + if (!lua_unreal_reflection_get_type(lua_unreal_reflection_resolve(reflection))) { + return luaL_error(state, "the reflected UObject is no longer valid"); + } + lua_pushliteral(state, "UObjectReflection"); + return 1; +} + +static int +lua_unreal_ustruct_for_each_property_lua(lua_State *state) +{ + ustruct_t *type = lua_unreal_ustruct_check(state, 1); + luaL_checktype(state, 2, LUA_TFUNCTION); + int callback_idx = lua_absindex(state, 2); + + for (ffield_t *field = type->child_props; field;) { + ffield_t *next = field->next; + if (lua_unreal_ffield_is_property(field)) { + lua_pushvalue(state, callback_idx); + lua_unreal_property_push_root(state, (fprop_t *)field, type); + if (lua_pcall(state, 1, 1, 0) != LUA_OK) { + return lua_error(state); + } + + bool stop = lua_toboolean(state, -1) != 0; + lua_pop(state, 1); + if (stop) { + break; + } + } + field = next; + } + return 0; +} + +static int +lua_unreal_ustruct_get_super_lua(lua_State *state) +{ + return lua_unreal_object_push(state, (uobject_t *)lua_unreal_ustruct_check(state, 1)->super_struct); +} + +static int +lua_unreal_ustruct_for_each_function_lua(lua_State *state) +{ + ustruct_t *type = lua_unreal_ustruct_check(state, 1); + luaL_checktype(state, 2, LUA_TFUNCTION); + int callback_idx = lua_absindex(state, 2); + + for (ufield_t *field = type->children; field; field = field->next) { + uobject_t *object = (uobject_t *)field; + if (!unreal_uobject_is_valid(object) || !unreal_uobject_is_a(object, globals.unreal.core_func)) { + continue; + } + + lua_pushvalue(state, callback_idx); + if (!lua_unreal_object_push(state, object)) { + lua_pop(state, 1); + return luaL_error(state, "could not marshal a UFunction"); + } + + if (lua_pcall(state, 1, 1, 0) != LUA_OK) { + return lua_error(state); + } + + bool stop = lua_toboolean(state, -1) != 0; + lua_pop(state, 1); + if (stop) { + break; + } + } + return 0; +} + +static uclass_t * +lua_unreal_uclass_check(lua_State *state, int idx) +{ + uobject_t *object = lua_unreal_object_check_live(state, idx); + if (!unreal_uobject_is_a(object, globals.unreal.core_class)) { + luaL_argerror(state, idx, "expected a live UClass"); + } + return (uclass_t *)object; +} + +static int +lua_unreal_uclass_get_cdo_lua(lua_State *state) +{ + return lua_unreal_object_push(state, lua_unreal_uclass_check(state, 1)->cdo); +} + +static int +lua_unreal_uclass_is_child_of_lua(lua_State *state) +{ + uclass_t *child = lua_unreal_uclass_check(state, 1); + uclass_t *parent = lua_unreal_uclass_check(state, 2); + bool result = false; + for (uclass_t *current = child; current; current = (uclass_t *)current->super_struct) { + if (current == parent) { + result = true; + break; + } + } + lua_pushboolean(state, result); + return 1; +} + +static ufunc_t * +lua_unreal_ufunction_check(lua_State *state, int idx) +{ + uobject_t *object = lua_unreal_object_check_live(state, idx); + if (!unreal_uobject_is_a(object, globals.unreal.core_func)) { + luaL_argerror(state, idx, "expected a live UFunction"); + } + return (ufunc_t *)object; +} + +static int +lua_unreal_ufunction_get_flags_lua(lua_State *state) +{ + lua_pushinteger(state, lua_unreal_ufunction_check(state, 1)->func_flags); + return 1; +} + +static int +lua_unreal_ufunction_set_flags_lua(lua_State *state) +{ + ufunc_t *function = lua_unreal_ufunction_check(state, 1); + function->func_flags = lua_unreal_check_u32(state, 2, "function flags must fit in an unsigned 32-bit integer"); + return 0; +} + +static uenum_t * +lua_unreal_uenum_check(lua_State *state, int idx) +{ + uobject_t *object = lua_unreal_object_check_live(state, idx); + if (!unreal_uobject_is_a(object, globals.unreal.core_enum)) { + luaL_argerror(state, idx, "expected a live UEnum"); + } + + uenum_t *uenum = (uenum_t *)object; + if (uenum->names.num < 0 || uenum->names.max < uenum->names.num || (uenum->names.num > 0 && !uenum->names.data)) { + luaL_error(state, "the UEnum name table is invalid"); + } + return uenum; +} + +static int +lua_unreal_uenum_get_name_by_value_lua(lua_State *state) +{ + uenum_t *uenum = lua_unreal_uenum_check(state, 1); + lua_Integer value = luaL_checkinteger(state, 2); + for (int32_t i = 0; i < uenum->names.num; ++i) { + if (uenum->names.data[i].value == (int64_t)value) { + return lua_unreal_fname_push(state, uenum->names.data[i].key); + } + } + lua_pushnil(state); + return 1; +} + +static int +lua_unreal_uenum_for_each_name_lua(lua_State *state) +{ + uenum_t *uenum = lua_unreal_uenum_check(state, 1); + luaL_checktype(state, 2, LUA_TFUNCTION); + int callback_idx = lua_absindex(state, 2); + + for (int32_t i = 0; i < uenum->names.num; ++i) { + lua_pushvalue(state, callback_idx); + lua_unreal_fname_push(state, uenum->names.data[i].key); + lua_pushinteger(state, (lua_Integer)uenum->names.data[i].value); + if (lua_pcall(state, 2, 1, 0) != LUA_OK) { + return lua_error(state); + } + + bool stop = lua_toboolean(state, -1) != 0; + lua_pop(state, 1); + if (stop) { + break; + } + } + return 0; +} + +static int +lua_unreal_uenum_get_name_by_index_lua(lua_State *state) +{ + uenum_t *uenum = lua_unreal_uenum_check(state, 1); + lua_Integer index = luaL_checkinteger(state, 2); + if (index < 0 || index >= uenum->names.num) { + lua_pushnil(state); + return 1; + } + + lua_unreal_fname_push(state, uenum->names.data[index].key); + lua_pushinteger(state, (lua_Integer)uenum->names.data[index].value); + return 2; +} + +static int +lua_unreal_uenum_edit_name_at_lua(lua_State *state) +{ + uenum_t *uenum = lua_unreal_uenum_check(state, 1); + lua_Integer index = luaL_checkinteger(state, 2); + if (index < 0 || index >= uenum->names.num) { + return luaL_argerror(state, 2, "enum index is out of range"); + } + + lua_unreal_fname_t *name = lua_unreal_fname_test(state, 3); + if (name) { + uenum->names.data[index].key = name->value; + } else { + size_t len = 0; + const char *text = luaL_checklstring(state, 3, &len); + uenum->names.data[index].key = unreal_fname_from_str(str_make((uint8_t *)text, (uint64_t)len), FNAME_FIND_OR_ADD); + } + return 0; +} + +static int +lua_unreal_uenum_edit_value_at_lua(lua_State *state) +{ + uenum_t *uenum = lua_unreal_uenum_check(state, 1); + lua_Integer index = luaL_checkinteger(state, 2); + if (index < 0 || index >= uenum->names.num) { + return luaL_argerror(state, 2, "enum index is out of range"); + } + uenum->names.data[index].value = (int64_t)luaL_checkinteger(state, 3); + return 0; +} + +static bool +lua_unreal_native_method_push(lua_State *state, uobject_t *object, str_t name) +{ + lua_CFunction function = NULL; + if (str_equal(name, STR_LIT("GetWorld"), 0)) { + function = lua_unreal_object_get_world_lua; + } else if (str_equal(name, STR_LIT("CallFunction"), 0)) { + function = lua_unreal_object_call_function_lua; + } + + if (!function && globals.unreal.data_table && unreal_uobject_is_a(object, globals.unreal.data_table)) { + if (str_equal(name, STR_LIT("GetRowStruct"), 0)) { + function = lua_unreal_data_table_get_row_struct_lua; + } else if (str_equal(name, STR_LIT("GetRowMap"), 0)) { + function = lua_unreal_data_table_get_row_map_lua; + } else if (str_equal(name, STR_LIT("FindRow"), 0)) { + function = lua_unreal_data_table_find_row_lua; + } else if (str_equal(name, STR_LIT("AddRow"), 0)) { + function = lua_unreal_data_table_add_row_lua; + } else if (str_equal(name, STR_LIT("RemoveRow"), 0)) { + function = lua_unreal_data_table_remove_row_lua; + } else if (str_equal(name, STR_LIT("EmptyTable"), 0)) { + function = lua_unreal_data_table_empty_lua; + } else if (str_equal(name, STR_LIT("GetRowNames"), 0)) { + function = lua_unreal_data_table_get_row_names_lua; + } else if (str_equal(name, STR_LIT("GetAllRows"), 0)) { + function = lua_unreal_data_table_get_all_rows_lua; + } else if (str_equal(name, STR_LIT("ForEachRow"), 0)) { + function = lua_unreal_data_table_for_each_row_lua; + } + } + + if (!function && unreal_uobject_is_a(object, globals.unreal.core_func)) { + if (str_equal(name, STR_LIT("GetFunctionFlags"), 0)) { + function = lua_unreal_ufunction_get_flags_lua; + } else if (str_equal(name, STR_LIT("SetFunctionFlags"), 0)) { + function = lua_unreal_ufunction_set_flags_lua; + } + } + + if (!function && unreal_uobject_is_a(object, globals.unreal.core_enum)) { + if (str_equal(name, STR_LIT("GetNameByValue"), 0)) { + function = lua_unreal_uenum_get_name_by_value_lua; + } else if (str_equal(name, STR_LIT("ForEachName"), 0)) { + function = lua_unreal_uenum_for_each_name_lua; + } else if (str_equal(name, STR_LIT("GetEnumNameByIndex"), 0)) { + function = lua_unreal_uenum_get_name_by_index_lua; + } else if (str_equal(name, STR_LIT("EditNameAt"), 0)) { + function = lua_unreal_uenum_edit_name_at_lua; + } else if (str_equal(name, STR_LIT("EditValueAt"), 0)) { + function = lua_unreal_uenum_edit_value_at_lua; + } + } + + if (!function && unreal_uobject_is_a(object, globals.unreal.core_class)) { + if (str_equal(name, STR_LIT("GetCDO"), 0)) { + function = lua_unreal_uclass_get_cdo_lua; + } else if (str_equal(name, STR_LIT("IsChildOf"), 0)) { + function = lua_unreal_uclass_is_child_of_lua; + } + } + + if (!function && lua_unreal_object_is_struct_type(object)) { + if (str_equal(name, STR_LIT("GetSuperStruct"), 0)) { + function = lua_unreal_ustruct_get_super_lua; + } else if (str_equal(name, STR_LIT("ForEachFunction"), 0)) { + function = lua_unreal_ustruct_for_each_function_lua; + } else if (str_equal(name, STR_LIT("ForEachProperty"), 0)) { + function = lua_unreal_ustruct_for_each_property_lua; + } + } + + if (!function && str_equal(name, STR_LIT("Reflection"), 0)) { + function = lua_unreal_object_reflection_lua; + } + + if (!function) { + return false; + } + lua_pushcfunction(state, function); + return true; +} + +static int +lua_unreal_object_len_lua(lua_State *state) +{ + uobject_t *object = lua_unreal_object_check_live(state, 1); + if (!globals.unreal.data_table || !unreal_uobject_is_a(object, globals.unreal.data_table)) { + return luaL_error(state, "only UDataTable objects have a length"); + } + + tmap_fname_uint8ptr_t *map = unreal_udata_table_get_row_map((udata_table_t *)object); + lua_pushinteger(state, map ? TMAP_NUM(map) : 0); + return 1; +} + +static bool +lua_unreal_method_same_receiver(lua_State *state, int idx, fweak_object_ptr_t receiver) +{ + lua_unreal_object_t *object = lua_unreal_object_test(state, idx); + return object && object->weak.object_idx == receiver.object_idx && object->weak.object_serial == receiver.object_serial; +} + +static bool +lua_unreal_call_prop_supported(fprop_t *prop, uint64_t container_size, char *error, size_t error_cap) +{ + if (!prop || !lua_unreal_property_fits(prop, container_size)) { + lua_unreal_error_set(error, error_cap, "invalid parameter layout"); + return false; + } + + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + if (kind == UNREAL_PROP_KIND_BOOL || lua_unreal_kind_is_integer(kind) || + kind == UNREAL_PROP_KIND_FLOAT || kind == UNREAL_PROP_KIND_DOUBLE || + kind == UNREAL_PROP_KIND_NAME || kind == UNREAL_PROP_KIND_STRING || + kind == UNREAL_PROP_KIND_TEXT || lua_unreal_kind_is_object(kind) || lua_unreal_kind_is_soft_object(kind) || + kind == UNREAL_PROP_KIND_INTERFACE) { + return true; + } + + if (kind == UNREAL_PROP_KIND_STRUCT) { + fprop_struct_t *struct_prop = (fprop_struct_t *)prop; + ustruct_t *type = (ustruct_t *)struct_prop->script_struct; + if (!type || type->props_size < 0 || (uint64_t)type->props_size > (uint64_t)prop->elem_size || + unreal_fname_match_text(type->name, STR_LIT("LatentActionInfo"), false, true)) { + lua_unreal_error_set(error, error_cap, "unsupported or latent struct parameter"); + return false; + } + + for (fprop_t *field = type->prop_link; field; field = field->prop_link_next) { + if (!lua_unreal_call_prop_supported(field, (uint64_t)prop->elem_size, error, error_cap)) { + return false; + } + } + return true; + } + + if (kind == UNREAL_PROP_KIND_ARRAY) { + fprop_t *inner = ((fprop_array_t *)prop)->inner; + return inner && lua_unreal_call_prop_supported(inner, unreal_fprop_complete_size(inner), error, error_cap); + } + + if (kind == UNREAL_PROP_KIND_SET) { + fprop_t *element = ((fprop_set_t *)prop)->elem_prop; + return element && lua_unreal_call_prop_supported(element, unreal_fprop_complete_size(element), error, error_cap); + } + + if (kind == UNREAL_PROP_KIND_MAP) { + fprop_map_t *map = (fprop_map_t *)prop; + return map->key_prop && map->val_prop && + lua_unreal_call_prop_supported(map->key_prop, unreal_fprop_complete_size(map->key_prop), error, error_cap) && + lua_unreal_call_prop_supported(map->val_prop, unreal_fprop_complete_size(map->val_prop), error, error_cap); + } + + lua_unreal_error_set(error, error_cap, "unsupported function parameter type"); + return false; +} + +static int +lua_unreal_call_reflected_function(lua_State *state, uobject_t *receiver, ufunc_t *function, int first_arg) +{ + uclass_t *owner_class = function ? (uclass_t *)function->outer : NULL; + + if (!receiver || + !function || + !owner_class || + !unreal_uobject_is_a((uobject_t *)function, globals.unreal.core_func) || + !unreal_uobject_is_valid((uobject_t *)owner_class) || + !unreal_uobject_is_a((uobject_t *)owner_class, globals.unreal.core_class) || + !unreal_uobject_is_a(receiver, owner_class) || + unreal_ustruct_find_func_fname((ustruct_t *)receiver->cls, function->name, false) != function) { + return luaL_error(state, "the Unreal receiver or function is no longer valid"); + } + + char error[LUA_UNREAL_ERROR_CAP] = {0}; + uint32_t reflected_count = 0; + int input_count = 0; + for (ffield_t *field = function->child_props; field; field = field->next) { + fprop_t *prop = (fprop_t *)field; + if (!(prop->prop_flags & CPF_PARM)) { + continue; + } + + reflected_count += 1; + if (!lua_unreal_call_prop_supported(prop, function->params_size, error, sizeof(error))) { + return luaL_error(state, "unsupported function schema: %s", error); + } + + bool is_return = (prop->prop_flags & CPF_RETURN_PARM) != 0; + bool is_pure_output = (prop->prop_flags & CPF_OUT_PARM) != 0 && + (prop->prop_flags & CPF_REFERENCE_PARM) == 0; + if (!is_return && !is_pure_output) { + input_count += 1; + } + } + + if (reflected_count != function->num_params) { + return luaL_error(state, "reflected parameter count mismatch (%u != %u)", reflected_count, (uint32_t)function->num_params); + } + + int supplied = lua_gettop(state) - first_arg + 1; + if (supplied != input_count) { + return luaL_error(state, "expected %d arguments, got %d", input_count, supplied); + } + + int32_t alignment = function->min_alignment; + if (alignment < 16) { + alignment = 16; + } + + if (alignment > LUA_UNREAL_MAX_ALIGNMENT) { + return luaL_error(state, "function parameter alignment %d is unsupported", alignment); + } + + int stack_base = lua_gettop(state); + int result_count = 0; + tmp_arena_t tmp = scratch_begin(NULL); + { + uint64_t params_size = MAX_VAL((uint64_t)function->params_size, 1ULL); + uint8_t *params = (uint8_t *)arena_push_zero_aligned(tmp.arena, params_size, (uint64_t)alignment); + if (params) { + uint32_t initialized_count = 0; + bool params_initialized = true; + for (ffield_t *field = function->child_props; field; field = field->next) { + fprop_t *prop = (fprop_t *)field; + if (prop->prop_flags & CPF_PARM) { + void *value = unreal_fprop_value_in_container(prop, params, 0); + if (!value || !unreal_fprop_initialize_value(prop, value)) { + params_initialized = false; + lua_unreal_error_set(error, sizeof(error), "could not initialize function parameters"); + break; + } + initialized_count += 1; + } + } + + int arg_idx = first_arg; + bool converted = params_initialized; + for (ffield_t *field = function->child_props; field && converted; field = field->next) { + fprop_t *prop = (fprop_t *)field; + bool is_return = (prop->prop_flags & CPF_RETURN_PARM) != 0; + bool is_pure_output = (prop->prop_flags & CPF_OUT_PARM) != 0 && + (prop->prop_flags & CPF_REFERENCE_PARM) == 0; + if (!(prop->prop_flags & CPF_PARM) || is_return || is_pure_output) { + continue; + } + + void *dst = unreal_fprop_value_in_container(prop, params, 0); + converted = dst && lua_unreal_write_transactional(state, arg_idx, prop, dst, receiver, error, sizeof(error)); + arg_idx += 1; + } + + bool pushed = converted; + if (converted) { + lua_unreal_context_t *context = lua_unreal_context_from_state(state); + bool called = context && context->process_event + ? context->process_event(context->user, receiver, function, function->params_size ? params : NULL) + : (unreal_process_event_observed(receiver, function, function->params_size ? params : NULL), true); + if (!called) { + lua_unreal_error_set(error, sizeof(error), "could not dispatch the Unreal function on the game thread"); + pushed = false; + } + + for (int pass = 0; pass < 2 && pushed; ++pass) { + for (ffield_t *field = function->child_props; field; field = field->next) { + fprop_t *prop = (fprop_t *)field; + if (!(prop->prop_flags & CPF_PARM)) { + continue; + } + + bool is_return = (prop->prop_flags & CPF_RETURN_PARM) != 0; + bool is_output = (prop->prop_flags & CPF_OUT_PARM) != 0 && (prop->prop_flags & CPF_CONST_PARM) == 0 && !is_return; + if ((pass == 0 && !is_return) || (pass == 1 && !is_output)) { + continue; + } + + void *value = unreal_fprop_value_in_container(prop, params, 0); + if (!value || !lua_unreal_prop_push(state, prop, value, receiver)) { + lua_unreal_error_set(error, sizeof(error), "could not marshal a function result"); + pushed = false; + break; + } + result_count += 1; + } + } + } + + uint32_t destroy_idx = 0; + for (ffield_t *field = function->child_props; field && destroy_idx < initialized_count; field = field->next) { + fprop_t *prop = (fprop_t *)field; + if (prop->prop_flags & CPF_PARM) { + unreal_fprop_destroy_in_container(prop, params); + destroy_idx += 1; + } + } + + if (!converted || !pushed) { + lua_settop(state, stack_base); + result_count = luaL_error(state, "Unreal call failed: %s", error[0] ? error : "conversion failed"); + } + } else { + result_count = luaL_error(state, "could not allocate 0x%X bytes for function parameters", function->params_size); + } + } + scratch_end(tmp); + + return result_count; +} + +static int +lua_unreal_method_call(lua_State *state) +{ + lua_unreal_method_t *method = (lua_unreal_method_t *)lua_touserdata(state, lua_upvalueindex(1)); + if (!method) { + return luaL_error(state, "invalid Unreal method closure"); + } + lua_unreal_require_access(state, method->context); + + uobject_t *receiver = unreal_fweak_object_resolve(method->receiver); + ufunc_t *function = (ufunc_t *)unreal_fweak_object_resolve(method->function); + int first_arg = lua_unreal_method_same_receiver(state, 1, method->receiver) ? 2 : 1; + return lua_unreal_call_reflected_function(state, receiver, function, first_arg); +} + +static int +lua_unreal_object_call_function_lua(lua_State *state) +{ + uobject_t *receiver = lua_unreal_object_check_live(state, 1); + ufunc_t *function = lua_unreal_ufunction_check(state, 2); + return lua_unreal_call_reflected_function(state, receiver, function, 3); +} + +static int +lua_unreal_ufunction_call_lua(lua_State *state) +{ + ufunc_t *function = lua_unreal_ufunction_check(state, 1); + uobject_t *receiver = lua_unreal_object_check_live(state, 2); + return lua_unreal_call_reflected_function(state, receiver, function, 3); +} + +static int +lua_unreal_object_index(lua_State *state) +{ + lua_unreal_object_t *userdata = (lua_unreal_object_t *)luaL_checkudata(state, 1, LUA_UNREAL_OBJECT_MT); + lua_unreal_require_access(state, userdata->context); + + size_t key_len = 0; + const char *key = luaL_checklstring(state, 2, &key_len); + uobject_t *object = lua_unreal_object_resolve(userdata); + if (!object) { + if (lua_getmetatable(state, 1)) { + lua_pushvalue(state, 2); + lua_rawget(state, -2); + lua_remove(state, -2); + if (!lua_isnil(state, -1)) { + return 1; + } + lua_pop(state, 1); + } + return luaL_error(state, "the UObject is no longer valid"); + } + + str_t name = str_make((uint8_t *)key, (uint64_t)key_len); + fprop_t *prop = unreal_ustruct_find_prop((ustruct_t *)object->cls, name); + if (prop) { + if (!lua_unreal_property_fits(prop, (uint64_t)((ustruct_t *)object->cls)->props_size)) { + return luaL_error(state, "property '%s' has an unsupported reflected layout", key); + } + + void *value = unreal_fprop_value_in_container(prop, object, 0); + if (!value || !lua_unreal_prop_push_internal(state, prop, value, object, 1, true)) { + return luaL_error(state, "property '%s' has an unsupported reflected type", key); + } + return 1; + } + + if (lua_unreal_native_method_push(state, object, name)) { + return 1; + } + + /* Core UObject methods are part of the Lua wrapper API and must win over + * reflected functions with the same name. KismetSystemLibrary, for + * example, exposes a static IsValid(Object) UFunction; resolving it before + * the wrapper's IsValid() makes ordinary UE4SS-style object validity checks + * fail with a missing-argument error. */ + if (lua_getmetatable(state, 1)) { + lua_pushvalue(state, 2); + lua_rawget(state, -2); + lua_remove(state, -2); + if (!lua_isnil(state, -1)) { + return 1; + } + lua_pop(state, 1); + } + + ufunc_t *func = unreal_ustruct_find_func((ustruct_t *)object->cls, name); + fweak_object_ptr_t func_weak = {0}; + if (func && unreal_uobject_is_a((uobject_t *)func, globals.unreal.core_func) && unreal_fweak_object_from_object((uobject_t *)func, &func_weak)) { + lua_unreal_method_t *method = (lua_unreal_method_t *)lua_newuserdatauv(state, sizeof(*method), 0); + method->context = userdata->context; + method->receiver = userdata->weak; + method->function = func_weak; + lua_pushcclosure(state, lua_unreal_method_call, 1); + return 1; + } + + lua_pushnil(state); + return 1; +} + +static int +lua_unreal_object_newindex(lua_State *state) +{ + lua_unreal_object_t *userdata = (lua_unreal_object_t *)luaL_checkudata(state, 1, LUA_UNREAL_OBJECT_MT); + lua_unreal_require_access(state, userdata->context); + + size_t key_len = 0; + const char *key = luaL_checklstring(state, 2, &key_len); + uobject_t *object = lua_unreal_object_resolve(userdata); + if (!object) { + return luaL_error(state, "the UObject is no longer valid"); + } + + fprop_t *prop = unreal_ustruct_find_prop((ustruct_t *)object->cls, str_make((uint8_t *)key, (uint64_t)key_len)); + if (!prop || !lua_unreal_property_fits(prop, (uint64_t)((ustruct_t *)object->cls)->props_size)) { + return luaL_error(state, "unknown or unsupported property '%s'", key); + } + + void *dst = unreal_fprop_value_in_container(prop, object, 0); + char error[LUA_UNREAL_ERROR_CAP] = {0}; + if (!dst || !lua_unreal_write_transactional(state, 3, prop, dst, object, error, sizeof(error))) { + return luaL_error(state, "could not assign '%s': %s", key, error[0] ? error : "conversion failed"); + } + return 0; +} + +static int +lua_unreal_object_count(lua_unreal_context_t *context) +{ + if (context && context->object_count && context->object_at) { + int count = context->object_count(context->user); + return MAX_VAL(count, 0); + } + return unreal_uobject_array_count(); +} + +static uobject_t * +lua_unreal_object_at(lua_unreal_context_t *context, int idx) +{ + if (context && context->object_count && context->object_at) { + return context->object_at(context->user, idx); + } + return unreal_uobject_array_get_obj(idx); +} + +static bool +lua_unreal_class_arg(lua_State *state, int idx, uclass_t **out_class, str_t *out_name) +{ + *out_class = NULL; + *out_name = STR_NULL; + + if (lua_isnoneornil(state, idx)) { + return true; + } + + if (lua_type(state, idx) == LUA_TSTRING || lua_unreal_fname_test(state, idx)) { + return lua_unreal_string_or_fname(state, idx, out_name) && !str_is_empty(*out_name); + } + + uobject_t *object = lua_unreal_object_get(state, idx); + if (object && unreal_uobject_is_a(object, globals.unreal.core_class)) { + *out_class = (uclass_t *)object; + return true; + } + return false; +} + +static bool +lua_unreal_optional_name(lua_State *state, int idx, str_t *out_name) +{ + *out_name = STR_NULL; + + if (lua_isnoneornil(state, idx)) { + return true; + } + + return lua_unreal_string_or_fname(state, idx, out_name) && !str_is_empty(*out_name); +} + +static eobj_flags_t +lua_unreal_flags_arg(lua_State *state, int idx) +{ + if (lua_isnoneornil(state, idx)) { + return RF_NO_FLAGS; + } + return (eobj_flags_t)lua_unreal_check_u32(state, idx, "object flags must fit in an unsigned 32-bit integer"); +} + +static bool +lua_unreal_object_matches_class(uobject_t *object, uclass_t *cls, str_t class_name, bool exact_class) +{ + if (!object) { + return false; + } + + if (cls) { + return exact_class ? object->cls == cls : unreal_uobject_is_a(object, cls); + } + + if (!str_is_empty(class_name)) { + if (exact_class) { + return object->cls && unreal_fname_match_text(object->cls->name, class_name, true, true); + } + return unreal_super_chain_contains(object->cls, class_name, true, true); + } + return true; +} + +static bool +lua_unreal_object_matches(uobject_t *object, uclass_t *cls, str_t class_name, str_t object_name, eobj_flags_t required_flags, eobj_flags_t banned_flags, bool exact_class) +{ + if (!lua_unreal_object_matches_class(object, cls, class_name, exact_class)) { + return false; + } + + if (!str_is_empty(object_name) && !unreal_fname_match_text(object->name, object_name, true, true)) { + return false; + } + + if ((object->obj_flags & required_flags) != required_flags || (object->obj_flags & banned_flags) != 0) { + return false; + } + + return true; +} + +static uobject_t * +lua_unreal_find_legacy(lua_unreal_context_t *context, str_t name) +{ + uobject_t *object = context->find_object ? context->find_object(context->user, name) : unreal_uobject_find_by_full_name(NULL, name); + if (!object && !context->find_object) { + object = unreal_uobject_find(name, false, true); + } + return object; +} + +static int +lua_unreal_find_object_lua(lua_State *state) +{ + lua_unreal_context_t *context = lua_unreal_context_from_state(state); + lua_unreal_require_access(state, context); + + int arg_count = lua_gettop(state); + if (arg_count == 1 && lua_type(state, 1) == LUA_TSTRING) { + size_t len = 0; + const char *text = lua_tolstring(state, 1, &len); + return lua_unreal_find_result_push(state, lua_unreal_find_legacy(context, str_make((uint8_t *)text, (uint64_t)len))); + } + + /* UE4SS overload: FindObject(UClass, UObject InOuter, string Name, bool ExactClass). */ + if (arg_count >= 3 && (lua_unreal_object_test(state, 1) || lua_isnil(state, 1)) && (lua_unreal_object_test(state, 2) || lua_isnil(state, 2)) && lua_type(state, 3) == LUA_TSTRING) { + uclass_t *cls = NULL; + str_t ignored_class_name = STR_NULL; + if (!lua_unreal_class_arg(state, 1, &cls, &ignored_class_name)) { + return luaL_argerror(state, 1, "expected a UClass or nil"); + } + + uobject_t *outer = lua_isnil(state, 2) ? NULL : lua_unreal_object_get(state, 2); + if (!outer && !lua_isnil(state, 2)) { + return luaL_argerror(state, 2, "expected a live UObject or nil"); + } + + size_t name_len = 0; + const char *name = lua_tolstring(state, 3, &name_len); + str_t wanted = str_make((uint8_t *)name, (uint64_t)name_len); + bool exact = lua_toboolean(state, 4) != 0; + + for (int i = 0, count = lua_unreal_object_count(context); i < count; ++i) { + uobject_t *object = lua_unreal_object_at(context, i); + if (!lua_unreal_object_matches_class(object, cls, STR_NULL, exact)) { + continue; + } + + bool name_matches = false; + if (outer) { + if (object->outer == outer && unreal_fname_match_text(object->name, wanted, false, true)) { + name_matches = true; + } else { + tmp_arena_t tmp = scratch_begin(NULL); + str_t expected = str_push_fmt(tmp.arena, "%.*s.%.*s", STR_ARG(unreal_uobject_push_full_name(outer, tmp.arena)), STR_ARG(wanted)); + name_matches = str_equal(unreal_uobject_push_full_name(object, tmp.arena), expected, 0); + scratch_end(tmp); + } + } else { + tmp_arena_t tmp = scratch_begin(NULL); + name_matches = str_equal(unreal_uobject_push_full_name(object, tmp.arena), wanted, 0); + scratch_end(tmp); + } + + if (name_matches) { + return lua_unreal_object_push(state, object); + } + } + return lua_unreal_object_push_invalid(state); + } + + /* UE4SS overload: FindObject(ClassName|UClass|nil, ObjectName|nil, RequiredFlags=0, BannedFlags=0). */ + uclass_t *cls = NULL; + str_t class_name = STR_NULL; + str_t object_name = STR_NULL; + + if (!lua_unreal_class_arg(state, 1, &cls, &class_name)) { + return luaL_argerror(state, 1, "expected a class-name string, UClass, or nil"); + } + + if (!lua_unreal_optional_name(state, 2, &object_name)) { + return luaL_argerror(state, 2, "expected an object-name string or nil"); + } + + if (!cls && str_is_empty(class_name) && str_is_empty(object_name)) { + return luaL_error(state, "class and object name cannot both be nil"); + } + + eobj_flags_t required = lua_unreal_flags_arg(state, 3); + eobj_flags_t banned = lua_unreal_flags_arg(state, 4); + for (int i = 0, count = lua_unreal_object_count(context); i < count; ++i) { + uobject_t *object = lua_unreal_object_at(context, i); + if (lua_unreal_object_matches(object, cls, class_name, object_name, required, banned, false)) { + return lua_unreal_object_push(state, object); + } + } + return lua_unreal_object_push_invalid(state); +} + +static int +lua_unreal_load_asset_lua(lua_State *state) +{ + lua_unreal_context_t *context = lua_unreal_context_from_state(state); + lua_unreal_require_access(state, context); + + size_t len = 0; + const char *text = luaL_checklstring(state, 1, &len); + str_t path = str_make((uint8_t *)text, (uint64_t)len); + + if (str_is_empty(path) || lua_unreal_string_has_embedded_null(path)) { + return luaL_argerror(state, 1, "asset path cannot be empty or contain null bytes"); + } + + if (!globals.unreal.core_object) { + return luaL_error(state, "the UObject class is unavailable"); + } + + uobject_t *asset = unreal_static_load_object(globals.unreal.core_object, NULL, path, STR_LIT(""), 0, NULL, true, NULL); + return lua_unreal_object_push(state, asset); +} + +static int +lua_unreal_static_find_object_lua(lua_State *state) +{ + lua_unreal_context_t *context = lua_unreal_context_from_state(state); + lua_unreal_require_access(state, context); + + if (lua_gettop(state) == 1) { + size_t len = 0; + const char *text = luaL_checklstring(state, 1, &len); + str_t name = str_make((uint8_t *)text, (uint64_t)len); + uobject_t *object = context->find_object ? context->find_object(context->user, name) : unreal_uobject_find_by_full_name(NULL, name); + return lua_unreal_find_result_push(state, object); + } + + /* the four-argument overload is identical to FindObject's UE-style overload */ + return lua_unreal_find_object_lua(state); +} + +static int +lua_unreal_find_objects_lua(lua_State *state) +{ + lua_unreal_context_t *context = lua_unreal_context_from_state(state); + lua_unreal_require_access(state, context); + + lua_Integer limit = 0; + if (!lua_isnoneornil(state, 1)) { + limit = luaL_checkinteger(state, 1); + if (limit < 0) { + return luaL_argerror(state, 1, "object limit cannot be negative"); + } + } + + uclass_t *cls = NULL; + str_t class_name = STR_NULL; + str_t object_name = STR_NULL; + + if (!lua_unreal_class_arg(state, 2, &cls, &class_name)) { + return luaL_argerror(state, 2, "expected a class-name string, UClass, or nil"); + } + + if (!lua_unreal_optional_name(state, 3, &object_name)) { + return luaL_argerror(state, 3, "expected an object-name string or nil"); + } + + if (!cls && str_is_empty(class_name) && str_is_empty(object_name)) { + return luaL_error(state, "class and object name cannot both be nil"); + } + + eobj_flags_t required = lua_unreal_flags_arg(state, 4); + eobj_flags_t banned = lua_unreal_flags_arg(state, 5); + bool exact = lua_toboolean(state, 6) != 0; + lua_Integer found = 0; + lua_newtable(state); + + for (int i = 0, count = lua_unreal_object_count(context); i < count && (limit == 0 || found < limit); ++i) { + uobject_t *object = lua_unreal_object_at(context, i); + if (!lua_unreal_object_matches(object, cls, class_name, object_name, required, banned, exact)) { + continue; + } + + lua_unreal_object_push(state, object); + lua_rawseti(state, -2, ++found); + } + return 1; +} + +static int +lua_unreal_find_of_lua(lua_State *state, bool all) +{ + lua_unreal_context_t *context = lua_unreal_context_from_state(state); + lua_unreal_require_access(state, context); + + size_t len = 0; + const char *text = luaL_checklstring(state, 1, &len); + str_t class_name = str_make((uint8_t *)text, (uint64_t)len); + lua_Integer found = 0; + + if (all) { + lua_newtable(state); + } + + for (int i = 0, count = lua_unreal_object_count(context); i < count; ++i) { + uobject_t *object = lua_unreal_object_at(context, i); + if (!object || unreal_uobject_is_default(object) || !lua_unreal_object_matches_class(object, NULL, class_name, false)) { + continue; + } + + if (!all) { + return lua_unreal_object_push(state, object); + } + + lua_unreal_object_push(state, object); + lua_rawseti(state, -2, ++found); + } + + if (all && found > 0) { + return 1; + } + + if (all) { + lua_pop(state, 1); + lua_pushnil(state); + return 1; + } + + return lua_unreal_object_push_invalid(state); +} + +static int +lua_unreal_find_first_of_lua(lua_State *state) +{ + return lua_unreal_find_of_lua(state, false); +} + +static int +lua_unreal_find_all_of_lua(lua_State *state) +{ + return lua_unreal_find_of_lua(state, true); +} + +static int +lua_unreal_fname_to_string_lua(lua_State *state) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + lua_unreal_fname_t *name = (lua_unreal_fname_t *)luaL_checkudata(state, 1, LUA_UNREAL_FNAME_MT); + + tmp_arena_t tmp = scratch_begin(NULL); + { + str_t text = unreal_fname_to_str(name->value, tmp.arena); + lua_pushlstring(state, (const char *)text.data, (size_t)text.len); + } + scratch_end(tmp); + return 1; +} + +static int +lua_unreal_fname_comparison_index_lua(lua_State *state) +{ + lua_unreal_fname_t *name = (lua_unreal_fname_t *)luaL_checkudata(state, 1, LUA_UNREAL_FNAME_MT); + lua_pushinteger(state, (lua_Integer)name->value.cmp_idx); + return 1; +} + +static int +lua_unreal_fname_type_lua(lua_State *state) +{ + (void)luaL_checkudata(state, 1, LUA_UNREAL_FNAME_MT); + lua_pushliteral(state, "FName"); + return 1; +} + +static int +lua_unreal_fname_equal_lua(lua_State *state) +{ + lua_unreal_fname_t *left = lua_unreal_fname_test(state, 1); + lua_unreal_fname_t *right = lua_unreal_fname_test(state, 2); + lua_pushboolean(state, left && right && left->value.cmp_idx == right->value.cmp_idx && left->value.num == right->value.num); + return 1; +} + +static int +lua_unreal_fname_equals_lua(lua_State *state) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + lua_unreal_fname_t *left = (lua_unreal_fname_t *)luaL_checkudata(state, 1, LUA_UNREAL_FNAME_MT); + lua_unreal_fname_t *right = (lua_unreal_fname_t *)luaL_checkudata(state, 2, LUA_UNREAL_FNAME_MT); + lua_pushboolean(state, left->value.cmp_idx == right->value.cmp_idx && left->value.num == right->value.num); + return 1; +} + +static int +lua_unreal_fname_lua(lua_State *state) +{ + lua_unreal_require_access(state, lua_unreal_context_from_state(state)); + + efind_name_t find_type = (efind_name_t)luaL_optinteger(state, 2, FNAME_FIND_OR_ADD); + if (find_type != FNAME_FIND && find_type != FNAME_FIND_OR_ADD) { + return luaL_argerror(state, 2, "expected EFindName.FNAME_Find or EFindName.FNAME_Add"); + } + + fname_t value = {0}; + if (lua_type(state, 1) == LUA_TSTRING) { + size_t len = 0; + const char *text = lua_tolstring(state, 1, &len); + value = unreal_fname_from_str(str_make((uint8_t *)text, (uint64_t)len), find_type); + } else if (lua_isinteger(state, 1)) { + uint32_t comparison_idx = lua_unreal_check_u32(state, 1, "comparison index must fit in an unsigned 32-bit integer"); + fname_entry_t *entry = globals.name_pool ? unreal_fname_entry_get(comparison_idx) : NULL; + if (entry && entry->header.len > 0 && entry->header.len <= FNAME_ENTRY_NAME_SIZE) { + value.cmp_idx = comparison_idx; + } + } else { + lua_unreal_fname_t *source = lua_unreal_fname_test(state, 1); + if (!source) { + return luaL_argerror(state, 1, "expected a string, comparison index, or FName"); + } + value = source->value; + } + + return lua_unreal_fname_push(state, value); +} + +static int +lua_unreal_ftext_literal_to_string_lua(lua_State *state) +{ + lua_unreal_ftext_literal_t *literal = (lua_unreal_ftext_literal_t *)luaL_checkudata(state, 1, LUA_UNREAL_FTEXT_MT); + lua_unreal_require_access(state, literal->context); + lua_pushlstring(state, literal->text, literal->len); + return 1; +} + +static int +lua_unreal_ftext_literal_type_lua(lua_State *state) +{ + lua_unreal_ftext_literal_t *literal = (lua_unreal_ftext_literal_t *)luaL_checkudata(state, 1, LUA_UNREAL_FTEXT_MT); + lua_unreal_require_access(state, literal->context); + lua_pushliteral(state, "FText"); + return 1; +} + +static int +lua_unreal_ftext_lua(lua_State *state) +{ + lua_unreal_context_t *context = lua_unreal_context_from_state(state); + lua_unreal_require_access(state, context); + + size_t len = 0; + const char *text = luaL_checklstring(state, 1, &len); + for (size_t i = 0; i < len; ++i) { + if (text[i] == '\0') { + return luaL_argerror(state, 1, "FText cannot contain embedded null bytes"); + } + } + + if (len > SIZE_MAX - sizeof(lua_unreal_ftext_literal_t)) { + return luaL_error(state, "FText is too large"); + } + + lua_unreal_ftext_literal_t *literal = (lua_unreal_ftext_literal_t *)lua_newuserdatauv(state, sizeof(*literal) + len, 0); + literal->context = context; + literal->len = len; + mem_copy(literal->text, (void *)text, len); + + literal->text[len] = '\0'; + luaL_setmetatable(state, LUA_UNREAL_FTEXT_MT); + return 1; +} + +static void +lua_unreal_register_ftext_metatable(lua_State *state) +{ + luaL_newmetatable(state, LUA_UNREAL_FTEXT_MT); + lua_pushcfunction(state, lua_unreal_ftext_literal_to_string_lua); + lua_setfield(state, -2, "ToString"); + lua_pushcfunction(state, lua_unreal_ftext_literal_type_lua); + lua_setfield(state, -2, "type"); + lua_pushcfunction(state, lua_unreal_ftext_literal_to_string_lua); + lua_setfield(state, -2, "__tostring"); + lua_pushvalue(state, -1); + lua_setfield(state, -2, "__index"); + lua_pushliteral(state, "FText"); + lua_setfield(state, -2, "__name"); + lua_pop(state, 1); +} + +static void +lua_unreal_register_property_metatable(lua_State *state) +{ + luaL_newmetatable(state, LUA_UNREAL_PROPERTY_MT); + lua_pushcfunction(state, lua_unreal_property_is_valid_lua); + lua_setfield(state, -2, "IsValid"); + lua_pushcfunction(state, lua_unreal_property_get_full_name_lua); + lua_setfield(state, -2, "GetFullName"); + lua_pushcfunction(state, lua_unreal_property_get_fname_lua); + lua_setfield(state, -2, "GetFName"); + lua_pushcfunction(state, lua_unreal_property_is_a_lua); + lua_setfield(state, -2, "IsA"); + lua_pushcfunction(state, lua_unreal_property_get_class_lua); + lua_setfield(state, -2, "GetClass"); + lua_pushcfunction(state, lua_unreal_property_get_offset_lua); + lua_setfield(state, -2, "GetOffset_Internal"); + lua_pushcfunction(state, lua_unreal_property_get_array_dim_lua); + lua_setfield(state, -2, "GetArrayDim"); + lua_pushcfunction(state, lua_unreal_property_get_element_size_lua); + lua_setfield(state, -2, "GetElementSize"); + lua_pushcfunction(state, lua_unreal_property_get_property_class_lua); + lua_setfield(state, -2, "GetPropertyClass"); + lua_pushcfunction(state, lua_unreal_bool_property_get_byte_mask_lua); + lua_setfield(state, -2, "GetByteMask"); + lua_pushcfunction(state, lua_unreal_bool_property_get_byte_offset_lua); + lua_setfield(state, -2, "GetByteOffset"); + lua_pushcfunction(state, lua_unreal_bool_property_get_field_mask_lua); + lua_setfield(state, -2, "GetFieldMask"); + lua_pushcfunction(state, lua_unreal_bool_property_get_field_size_lua); + lua_setfield(state, -2, "GetFieldSize"); + lua_pushcfunction(state, lua_unreal_property_get_struct_lua); + lua_setfield(state, -2, "GetStruct"); + lua_pushcfunction(state, lua_unreal_property_get_inner_lua); + lua_setfield(state, -2, "GetInner"); + lua_pushcfunction(state, lua_unreal_property_get_element_property_lua); + lua_setfield(state, -2, "GetElementProperty"); + lua_pushcfunction(state, lua_unreal_property_get_key_property_lua); + lua_setfield(state, -2, "GetKeyProperty"); + lua_pushcfunction(state, lua_unreal_property_get_value_property_lua); + lua_setfield(state, -2, "GetValueProperty"); + lua_pushcfunction(state, lua_unreal_property_get_underlying_property_lua); + lua_setfield(state, -2, "GetUnderlyingProperty"); + lua_pushcfunction(state, lua_unreal_property_get_enum_lua); + lua_setfield(state, -2, "GetEnum"); + lua_pushcfunction(state, lua_unreal_property_type_lua); + lua_setfield(state, -2, "type"); + lua_pushcfunction(state, lua_unreal_property_tostring_lua); + lua_setfield(state, -2, "__tostring"); + lua_pushvalue(state, -1); + lua_setfield(state, -2, "__index"); + lua_pushliteral(state, "Property"); + lua_setfield(state, -2, "__name"); + lua_pop(state, 1); +} + +static void +lua_unreal_register_field_class_metatable(lua_State *state) +{ + luaL_newmetatable(state, LUA_UNREAL_FIELD_CLASS_MT); + lua_pushcfunction(state, lua_unreal_field_class_is_valid_lua); + lua_setfield(state, -2, "IsValid"); + lua_pushcfunction(state, lua_unreal_field_class_get_fname_lua); + lua_setfield(state, -2, "GetFName"); + lua_pushcfunction(state, lua_unreal_field_class_type_lua); + lua_setfield(state, -2, "type"); + lua_pushcfunction(state, lua_unreal_field_class_tostring_lua); + lua_setfield(state, -2, "__tostring"); + lua_pushvalue(state, -1); + lua_setfield(state, -2, "__index"); + lua_pushliteral(state, "FieldClass"); + lua_setfield(state, -2, "__name"); + lua_pop(state, 1); +} + +static void +lua_unreal_register_reflection_metatable(lua_State *state) +{ + luaL_newmetatable(state, LUA_UNREAL_REFLECTION_MT); + lua_pushcfunction(state, lua_unreal_reflection_is_valid_lua); + lua_setfield(state, -2, "IsValid"); + lua_pushcfunction(state, lua_unreal_reflection_get_property_lua); + lua_setfield(state, -2, "GetProperty"); + lua_pushcfunction(state, lua_unreal_reflection_type_lua); + lua_setfield(state, -2, "type"); + lua_pushvalue(state, -1); + lua_setfield(state, -2, "__index"); + lua_pushliteral(state, "UObjectReflection"); + lua_setfield(state, -2, "__name"); + lua_pop(state, 1); +} + +static void +lua_unreal_register_fname_metatable(lua_State *state) +{ + luaL_newmetatable(state, LUA_UNREAL_FNAME_MT); + lua_pushcfunction(state, lua_unreal_fname_to_string_lua); + lua_setfield(state, -2, "__tostring"); + lua_pushcfunction(state, lua_unreal_fname_equal_lua); + lua_setfield(state, -2, "__eq"); + lua_pushvalue(state, -1); + lua_setfield(state, -2, "__index"); + lua_pushcfunction(state, lua_unreal_fname_to_string_lua); + lua_setfield(state, -2, "ToString"); + lua_pushcfunction(state, lua_unreal_fname_comparison_index_lua); + lua_setfield(state, -2, "GetComparisonIndex"); + lua_pushcfunction(state, lua_unreal_fname_equals_lua); + lua_setfield(state, -2, "Equals"); + lua_pushcfunction(state, lua_unreal_fname_type_lua); + lua_setfield(state, -2, "type"); + lua_pushliteral(state, "FName"); + lua_setfield(state, -2, "__name"); + lua_pop(state, 1); +} + +static void +lua_unreal_push_find_name_table(lua_State *state) +{ + lua_newtable(state); + lua_pushinteger(state, FNAME_FIND); + lua_setfield(state, -2, "FNAME_Find"); + lua_pushinteger(state, FNAME_FIND_OR_ADD); + lua_setfield(state, -2, "FNAME_Add"); +} + +static void +lua_unreal_register_object_flags(lua_State *state) +{ + static const struct { + const char *name; + eobj_flags_t value; + } flags[] = { + {"RF_NoFlags", RF_NO_FLAGS }, + {"RF_Public", RF_PUBLIC }, + {"RF_Standalone", RF_STANDALONE }, + {"RF_MarkAsNative", RF_MARK_AS_NATIVE }, + {"RF_Transactional", RF_TRANSACTIONAL }, + {"RF_ClassDefaultObject", RF_CLASS_DEFAULT_OBJECT }, + {"RF_ArchetypeObject", RF_ARCHETYPE_OBJECT }, + {"RF_Transient", RF_TRANSIENT }, + {"RF_MarkAsRootSet", RF_MARK_AS_ROOT_SET }, + {"RF_TagGarbageTemp", RF_TAG_GARBAGE_TEMP }, + {"RF_NeedInitialization", RF_NEED_INITIALIZATION }, + {"RF_NeedLoad", RF_NEED_LOAD }, + {"RF_KeepForCooker", RF_KEEP_FOR_COOKER }, + {"RF_NeedPostLoad", RF_NEED_POST_LOAD }, + {"RF_NeedPostLoadSubobjects", RF_NEED_POST_LOAD_SUBOBJECTS }, + {"RF_NewerVersionExists", RF_NEWER_VERSION_EXISTS }, + {"RF_BeginDestroyed", RF_BEGIN_DESTROYED }, + {"RF_FinishDestroyed", RF_FINISH_DESTROYED }, + {"RF_BeingRegenerated", RF_BEING_REGENERATED }, + {"RF_DefaultSubObject", RF_DEFAULT_SUB_OBJECT }, + {"RF_WasLoaded", RF_WAS_LOADED }, + {"RF_TextExportTransient", RF_TEXT_EXPORT_TRANSIENT }, + {"RF_LoadCompleted", RF_LOAD_COMPLETED }, + {"RF_InheritableComponentTemplate", RF_INHERITABLE_COMPONENT_TEMPLATE}, + {"RF_DuplicateTransient", RF_DUPLICATE_TRANSIENT }, + {"RF_StrongRefOnFrame", RF_STRONG_REF_ON_FRAME }, + {"RF_NonPIEDuplicateTransient", RF_NON_PIE_DUPLICATE_TRANSIENT }, + {"RF_Dynamic", RF_DYNAMIC }, + {"RF_WillBeLoaded", RF_WILL_BE_LOADED }, + {"RF_HasExternalPackage", RF_HAS_EXTERNAL_PACKAGE }, + }; + + lua_newtable(state); + for (size_t i = 0; i < sizeof(flags) / sizeof(flags[0]); ++i) { + lua_pushinteger(state, (lua_Integer)flags[i].value); + lua_setfield(state, -2, flags[i].name); + } +} + +static void +lua_unreal_register_internal_object_flags(lua_State *state) +{ + static const struct { + const char *name; + uint32_t value; + } flags[] = { + {"ReachableInCluster", 0x00800000u}, + {"ClusterRoot", 0x01000000u}, + {"Native", 0x02000000u}, + {"Async", 0x04000000u}, + {"AsyncLoading", 0x08000000u}, + {"Unreachable", 0x10000000u}, + {"PendingKill", 0x20000000u}, + {"RootSet", 0x40000000u}, + {"GarbageCollectionKeepFlags", 0x0E000000u}, + {"AllFlags", 0x7F800000u}, + }; + + lua_newtable(state); + for (size_t i = 0; i < sizeof(flags) / sizeof(flags[0]); ++i) { + lua_pushinteger(state, (lua_Integer)flags[i].value); + lua_setfield(state, -2, flags[i].name); + } +} + +static void +lua_unreal_register_property_types(lua_State *state) +{ + static const struct { + const char *name; + const char *class_name; + } types[] = { + {"ObjectProperty", "ObjectProperty" }, + {"ObjectPtrProperty", "ObjectProperty" }, + {"Int8Property", "Int8Property" }, + {"Int16Property", "Int16Property" }, + {"IntProperty", "IntProperty" }, + {"Int32Property", "Int32Property" }, + {"Int64Property", "Int64Property" }, + {"NameProperty", "NameProperty" }, + {"FloatProperty", "FloatProperty" }, + {"DoubleProperty", "DoubleProperty" }, + {"StrProperty", "StrProperty" }, + {"ByteProperty", "ByteProperty" }, + {"UInt16Property", "UInt16Property" }, + {"UIntProperty", "UInt32Property" }, + {"UInt32Property", "UInt32Property" }, + {"UInt64Property", "UInt64Property" }, + {"BoolProperty", "BoolProperty" }, + {"ArrayProperty", "ArrayProperty" }, + {"SetProperty", "SetProperty" }, + {"MapProperty", "MapProperty" }, + {"StructProperty", "StructProperty" }, + {"ClassProperty", "ClassProperty" }, + {"SoftObjectProperty", "SoftObjectProperty" }, + {"SoftClassProperty", "SoftClassProperty" }, + {"WeakObjectProperty", "WeakObjectProperty" }, + {"LazyObjectProperty", "LazyObjectProperty" }, + {"EnumProperty", "EnumProperty" }, + {"TextProperty", "TextProperty" }, + {"InterfaceProperty", "InterfaceProperty" }, + {"DelegateProperty", "DelegateProperty" }, + {"MulticastDelegateProperty", "MulticastDelegateProperty" }, + }; + + lua_newtable(state); + for (size_t i = 0; i < sizeof(types) / sizeof(types[0]); ++i) { + lua_pushstring(state, types[i].class_name); + lua_setfield(state, -2, types[i].name); + } +} + +static void +lua_unreal_register_object_metatable(lua_State *state) +{ + luaL_newmetatable(state, LUA_UNREAL_OBJECT_MT); + lua_pushcfunction(state, lua_unreal_object_index); + lua_setfield(state, -2, "__index"); + lua_pushcfunction(state, lua_unreal_object_newindex); + lua_setfield(state, -2, "__newindex"); + lua_pushcfunction(state, lua_unreal_object_tostring); + lua_setfield(state, -2, "__tostring"); + lua_pushcfunction(state, lua_unreal_object_equal_lua); + lua_setfield(state, -2, "__eq"); + lua_pushcfunction(state, lua_unreal_object_len_lua); + lua_setfield(state, -2, "__len"); + lua_pushcfunction(state, lua_unreal_ufunction_call_lua); + lua_setfield(state, -2, "__call"); + lua_pushcfunction(state, lua_unreal_object_is_valid_lua); + lua_setfield(state, -2, "IsValid"); + lua_pushcfunction(state, lua_unreal_object_get_full_name_lua); + lua_setfield(state, -2, "GetFullName"); + lua_pushcfunction(state, lua_unreal_object_get_fname_lua); + lua_setfield(state, -2, "GetFName"); + lua_pushcfunction(state, lua_unreal_object_get_address_lua); + lua_setfield(state, -2, "GetAddress"); + lua_pushcfunction(state, lua_unreal_object_get_class_lua); + lua_setfield(state, -2, "GetClass"); + lua_pushcfunction(state, lua_unreal_object_get_outer_lua); + lua_setfield(state, -2, "GetOuter"); + lua_pushcfunction(state, lua_unreal_object_is_class_lua); + lua_setfield(state, -2, "IsAnyClass"); + lua_pushcfunction(state, lua_unreal_object_is_class_lua); + lua_setfield(state, -2, "IsClass"); + lua_pushcfunction(state, lua_unreal_object_is_a_lua); + lua_setfield(state, -2, "IsA"); + lua_pushcfunction(state, lua_unreal_object_has_all_flags_lua); + lua_setfield(state, -2, "HasAllFlags"); + lua_pushcfunction(state, lua_unreal_object_has_any_flags_lua); + lua_setfield(state, -2, "HasAnyFlags"); + lua_pushcfunction(state, lua_unreal_object_has_any_internal_flags_lua); + lua_setfield(state, -2, "HasAnyInternalFlags"); + lua_pushcfunction(state, lua_unreal_object_index); + lua_setfield(state, -2, "GetPropertyValue"); + lua_pushcfunction(state, lua_unreal_object_newindex); + lua_setfield(state, -2, "SetPropertyValue"); + lua_pushcfunction(state, lua_unreal_object_type_lua); + lua_setfield(state, -2, "type"); + lua_pushliteral(state, "UObject"); + lua_setfield(state, -2, "__name"); + lua_pop(state, 1); +} + +static void +lua_unreal_register_data_table_row_metatable(lua_State *state) +{ + luaL_newmetatable(state, LUA_UNREAL_DATA_TABLE_ROW_MT); + lua_pushcfunction(state, lua_unreal_data_table_row_index_lua); + lua_setfield(state, -2, "__index"); + lua_pushcfunction(state, lua_unreal_data_table_row_newindex_lua); + lua_setfield(state, -2, "__newindex"); + lua_pushcfunction(state, lua_unreal_data_table_row_tostring_lua); + lua_setfield(state, -2, "__tostring"); + lua_pushcfunction(state, lua_unreal_data_table_row_is_valid_lua); + lua_setfield(state, -2, "IsValid"); + lua_pushcfunction(state, lua_unreal_data_table_row_index_lua); + lua_setfield(state, -2, "GetPropertyValue"); + lua_pushcfunction(state, lua_unreal_data_table_row_newindex_lua); + lua_setfield(state, -2, "SetPropertyValue"); + lua_pushcfunction(state, lua_unreal_data_table_row_type_lua); + lua_setfield(state, -2, "type"); + lua_pushcfunction(state, lua_unreal_data_table_row_tostring_lua); + lua_setfield(state, -2, "ToString"); + lua_pushliteral(state, "UScriptStruct"); + lua_setfield(state, -2, "__name"); + lua_pop(state, 1); +} + +static void +lua_unreal_register_value_metatable(lua_State *state, const char *name, bool owned) +{ + luaL_newmetatable(state, name); + lua_pushcfunction(state, lua_unreal_value_index); + lua_setfield(state, -2, "__index"); + lua_pushcfunction(state, lua_unreal_value_newindex); + lua_setfield(state, -2, "__newindex"); + lua_pushcfunction(state, lua_unreal_value_tostring); + lua_setfield(state, -2, "__tostring"); + lua_pushcfunction(state, lua_unreal_value_len); + lua_setfield(state, -2, "__len"); + lua_pushcfunction(state, lua_unreal_value_len); + lua_setfield(state, -2, "Num"); + lua_pushcfunction(state, lua_unreal_value_get_array_num_lua); + lua_setfield(state, -2, "GetArrayNum"); + lua_pushcfunction(state, lua_unreal_value_get_array_address_lua); + lua_setfield(state, -2, "GetArrayAddress"); + lua_pushcfunction(state, lua_unreal_value_get_array_max_lua); + lua_setfield(state, -2, "GetArrayMax"); + lua_pushcfunction(state, lua_unreal_value_get_array_data_address_lua); + lua_setfield(state, -2, "GetArrayDataAddress"); + lua_pushcfunction(state, lua_unreal_value_for_each_lua); + lua_setfield(state, -2, "ForEach"); + lua_pushcfunction(state, lua_unreal_value_to_table_lua); + lua_setfield(state, -2, "ToTable"); + lua_pushcfunction(state, lua_unreal_value_clear_lua); + lua_setfield(state, -2, "Clear"); + lua_pushcfunction(state, lua_unreal_value_clear_lua); + lua_setfield(state, -2, "Empty"); + lua_pushcfunction(state, lua_unreal_value_add_lua); + lua_setfield(state, -2, "Add"); + lua_pushcfunction(state, lua_unreal_value_insert_lua); + lua_setfield(state, -2, "Insert"); + lua_pushcfunction(state, lua_unreal_value_contains_lua); + lua_setfield(state, -2, "Contains"); + lua_pushcfunction(state, lua_unreal_value_find_lua); + lua_setfield(state, -2, "Find"); + lua_pushcfunction(state, lua_unreal_value_remove_lua); + lua_setfield(state, -2, "Remove"); + lua_pushcfunction(state, lua_unreal_value_is_valid_lua); + lua_setfield(state, -2, "IsValid"); + lua_pushcfunction(state, lua_unreal_value_type_lua); + lua_setfield(state, -2, "type"); + lua_pushcfunction(state, lua_unreal_value_to_string_lua); + lua_setfield(state, -2, "ToString"); + lua_pushcfunction(state, lua_unreal_fstring_len_lua); + lua_setfield(state, -2, "Len"); + lua_pushcfunction(state, lua_unreal_fstring_is_empty_lua); + lua_setfield(state, -2, "IsEmpty"); + lua_pushcfunction(state, lua_unreal_fstring_append_lua); + lua_setfield(state, -2, "Append"); + lua_pushcfunction(state, lua_unreal_fstring_starts_with_lua); + lua_setfield(state, -2, "StartsWith"); + lua_pushcfunction(state, lua_unreal_fstring_ends_with_lua); + lua_setfield(state, -2, "EndsWith"); + lua_pushcfunction(state, lua_unreal_fstring_to_upper_lua); + lua_setfield(state, -2, "ToUpper"); + lua_pushcfunction(state, lua_unreal_fstring_to_lower_lua); + lua_setfield(state, -2, "ToLower"); + + if (owned) { + lua_pushcfunction(state, lua_unreal_owned_gc); + lua_setfield(state, -2, "__gc"); + } + + lua_pushliteral(state, "UnrealValue"); + lua_setfield(state, -2, "__name"); + lua_pop(state, 1); +} + +static void +lua_unreal_register_param_metatable(lua_State *state) +{ + luaL_newmetatable(state, LUA_UNREAL_PARAM_MT); + lua_pushcfunction(state, lua_unreal_param_get_lua); + lua_setfield(state, -2, "get"); + lua_pushcfunction(state, lua_unreal_param_get_lua); + lua_setfield(state, -2, "Get"); + lua_pushcfunction(state, lua_unreal_param_set_lua); + lua_setfield(state, -2, "set"); + lua_pushcfunction(state, lua_unreal_param_set_lua); + lua_setfield(state, -2, "Set"); + lua_pushcfunction(state, lua_unreal_param_is_valid_lua); + lua_setfield(state, -2, "IsValid"); + lua_pushcfunction(state, lua_unreal_param_type_lua); + lua_setfield(state, -2, "type"); + lua_pushvalue(state, -1); + lua_setfield(state, -2, "__index"); + lua_pushliteral(state, "UnrealParam"); + lua_setfield(state, -2, "__name"); + lua_pop(state, 1); +} + +bool +lua_unreal_register_static(lua_State *state, lua_unreal_context_t *context) +{ + if (!state || !context) { + return false; + } + + lua_pushlightuserdata(state, context); + lua_rawsetp(state, LUA_REGISTRYINDEX, &g_lua_unreal_context_registry_key); + lua_unreal_register_fname_metatable(state); + lua_unreal_register_ftext_metatable(state); + + static const luaL_Reg static_functions[] = { + {"StaticFindObject", lua_unreal_static_find_object_lua}, + {"FindObject", lua_unreal_find_object_lua }, + {"FindObjects", lua_unreal_find_objects_lua }, + {"FindFirstOf", lua_unreal_find_first_of_lua }, + {"FindAllOf", lua_unreal_find_all_of_lua }, + {"LoadAsset", lua_unreal_load_asset_lua }, + {"FText", lua_unreal_ftext_lua }, + {NULL, NULL}, + }; + + lua_newtable(state); + luaL_setfuncs(state, static_functions, 0); + lua_unreal_register_object_flags(state); + lua_setfield(state, -2, "EObjectFlags"); + lua_unreal_register_internal_object_flags(state); + lua_setfield(state, -2, "EInternalObjectFlags"); + lua_unreal_register_property_types(state); + lua_setfield(state, -2, "PropertyTypes"); + lua_pushcfunction(state, lua_unreal_fname_lua); + lua_setfield(state, -2, "FName"); + lua_unreal_push_find_name_table(state); + lua_setfield(state, -2, "EFindName"); + lua_unreal_fname_push(state, (fname_t){0}); + lua_setfield(state, -2, "NAME_None"); + + for (const luaL_Reg *function = static_functions; function->name; ++function) { + lua_getfield(state, -1, function->name); + lua_setglobal(state, function->name); + } + + static const char *aliases[] = { + "EObjectFlags", + "EInternalObjectFlags", + "PropertyTypes", + "FName", + "EFindName", + "NAME_None", + }; + + for (size_t i = 0; i < sizeof(aliases) / sizeof(aliases[0]); ++i) { + lua_getfield(state, -1, aliases[i]); + lua_setglobal(state, aliases[i]); + } + lua_setglobal(state, "Unreal"); + return true; +} + +bool +lua_unreal_register_codec(lua_State *state, lua_unreal_context_t *context) +{ + if (!state || !context) { + return false; + } + + lua_pushlightuserdata(state, context); + lua_rawsetp(state, LUA_REGISTRYINDEX, &g_lua_unreal_context_registry_key); + lua_unreal_register_object_metatable(state); + lua_unreal_register_data_table_row_metatable(state); + lua_unreal_register_property_metatable(state); + lua_unreal_register_field_class_metatable(state); + lua_unreal_register_reflection_metatable(state); + lua_unreal_register_value_metatable(state, LUA_UNREAL_PROXY_MT, false); + lua_unreal_register_value_metatable(state, LUA_UNREAL_OWNED_MT, true); + lua_unreal_register_param_metatable(state); + lua_unreal_register_fname_metatable(state); + lua_unreal_register_ftext_metatable(state); + return true; +} + +bool +lua_unreal_object_metatable_push(lua_State *state) +{ + if (!state) { + return false; + } + + luaL_getmetatable(state, LUA_UNREAL_OBJECT_MT); + if (!lua_istable(state, -1)) { + lua_pop(state, 1); + return false; + } + return true; +} + +static void +lua_unreal_metatable_rename(lua_State *state, const char *metatable, const char *old_name, const char *new_name) +{ + luaL_getmetatable(state, metatable); + if (!lua_istable(state, -1)) { + lua_pop(state, 1); + return; + } + + lua_getfield(state, -1, old_name); + if (!lua_isnil(state, -1)) { + lua_setfield(state, -2, new_name); + } else { + lua_pop(state, 1); + } + + lua_pushnil(state); + lua_setfield(state, -2, old_name); + lua_pop(state, 1); +} + +void +lua_unreal_use_camel_case_names(lua_State *state) +{ + if (!state) { + return; + } + + static const char *type_metatables[] = { + LUA_UNREAL_OBJECT_MT, + LUA_UNREAL_PROXY_MT, + LUA_UNREAL_OWNED_MT, + LUA_UNREAL_FNAME_MT, + LUA_UNREAL_PARAM_MT, + LUA_UNREAL_FTEXT_MT, + LUA_UNREAL_DATA_TABLE_ROW_MT, + LUA_UNREAL_PROPERTY_MT, + LUA_UNREAL_FIELD_CLASS_MT, + LUA_UNREAL_REFLECTION_MT, + }; + + for (size_t i = 0; i < COUNTOF(type_metatables); ++i) { + lua_unreal_metatable_rename(state, type_metatables[i], "type", "Type"); + } + + lua_unreal_metatable_rename(state, LUA_UNREAL_PARAM_MT, "get", "Get"); + lua_unreal_metatable_rename(state, LUA_UNREAL_PARAM_MT, "set", "Set"); +} + +int +lua_unreal_fname_construct(lua_State *state) +{ + return lua_unreal_fname_lua(state); +} + +int +lua_unreal_ftext_construct(lua_State *state) +{ + return lua_unreal_ftext_lua(state); +} + +int +lua_unreal_name_none_push(lua_State *state) +{ + return lua_unreal_fname_push(state, (fname_t){0}); +} + +void +lua_unreal_object_flags_push(lua_State *state) +{ + lua_unreal_register_object_flags(state); +} + +void +lua_unreal_internal_object_flags_push(lua_State *state) +{ + lua_unreal_register_internal_object_flags(state); +} + +void +lua_unreal_property_types_push(lua_State *state) +{ + lua_unreal_register_property_types(state); +} + +void +lua_unreal_find_name_modes_push(lua_State *state) +{ + lua_unreal_push_find_name_table(state); +} + +bool +lua_unreal_register(lua_State *state, lua_unreal_context_t *context) +{ + if (!lua_unreal_register_codec(state, context)) { + return false; + } + + if (!lua_unreal_register_static(state, context)) { + return false; + } + + lua_pushcfunction(state, lua_unreal_create_invalid_object_lua); + lua_setglobal(state, "CreateInvalidObject"); + lua_getglobal(state, "Unreal"); + lua_pushcfunction(state, lua_unreal_create_invalid_object_lua); + lua_setfield(state, -2, "CreateInvalidObject"); + lua_pop(state, 1); + return true; +} diff --git a/src/main.c b/src/main.c index 0f613e6..a6affc1 100644 --- a/src/main.c +++ b/src/main.c @@ -86,6 +86,26 @@ ui_force_os_cursor_visible_tick(void) InterlockedExchange(&g_cursor_restore_requested, 0); } +static void +on_uobject_created(uobject_t *object, int32_t idx, void *user) +{ + (void)idx; + + mod_manager_t *manager = user; + if (manager && object) { + mod_manager_dispatch_uobject_constructed(manager, object); + } +} + +static void +on_uobject_deleted(uobject_t *object, int32_t idx, void *user) +{ + mod_manager_t *manager = user; + if (manager && object) { + mod_manager_dispatch_uobject_deleted(manager, object, idx); + } +} + static void on_engine_init(void) { @@ -99,8 +119,11 @@ on_engine_init(void) enable_input_hooks(); unreal_common_collect(&globals.unreal); + unreal_register_uobject_listener(UOBJECT_LISTENER_KIND_CREATE, on_uobject_created, &globals.mod_manager); + unreal_register_uobject_listener(UOBJECT_LISTENER_KIND_DELETE, on_uobject_deleted, &globals.mod_manager); mod_manager_start_dlls(&globals.mod_manager); + mod_manager_start_lua(&globals.mod_manager); mod_manager_start_blueprints(&globals.mod_manager); } @@ -274,10 +297,18 @@ on_input_event(input_event_t *ev) break; } + case INPUT_EVENT_ANALOG: { + if (ev->key != INPUT_KEY_NONE) { + globals.analog_values[ev->key] = ev->analog_value; + } + break; + } + case INPUT_EVENT_APP_ACTIVATION: { if (!ev->app_activated) { /* out of focus, all held keys should be released */ input_key_lost_focus(); + mem_zero(globals.analog_values, sizeof(globals.analog_values)); } break; } @@ -535,7 +566,7 @@ game_engine_tick_hook(void *self, float delta, bool idle_mode) void __fastcall process_event_hook(uobject_t *self, ufunc_t *func, void *params) { - if (globals.game_thread_id != GetCurrentThreadId() || !globals.engine_inited) { + if (!unreal_is_in_game_thread() || !globals.engine_inited) { process_event_real(self, func, params); return; } @@ -547,10 +578,29 @@ process_event_hook(uobject_t *self, ufunc_t *func, void *params) mod_manager_dispatch_process_event_post(&globals.mod_manager, self, func, params, consumed); } +void __fastcall +conditional_post_load_hook(uobject_t *self) +{ + bool on_game_thread = unreal_is_in_game_thread(); + bool can_dispatch = self && globals.engine_inited && on_game_thread; + bool has_hooks = can_dispatch && mod_manager_has_post_load_hooks(&globals.mod_manager); + bool should_dispatch = has_hooks && (self->obj_flags & RF_NEED_POST_LOAD) != 0; + + if (should_dispatch) { + mod_manager_dispatch_post_load(&globals.mod_manager, self, false); + } + + conditional_post_load_real(self); + + if (should_dispatch) { + mod_manager_dispatch_post_load(&globals.mod_manager, self, true); + } +} + void __fastcall ufunction_invoke_hook(ufunc_t *func, uobject_t *obj, fframe_t *stack, void *result) { - if (globals.game_thread_id != GetCurrentThreadId() || !globals.engine_inited) { + if (!unreal_is_in_game_thread() || !globals.engine_inited) { ufunction_invoke_real(func, obj, stack, result); return; } diff --git a/src/misc.c b/src/misc.c index 209827b..6900fd3 100644 --- a/src/misc.c +++ b/src/misc.c @@ -17,6 +17,24 @@ time_now_us(void) return (uint64_t)((now.QuadPart * 1000000ull) / freq.QuadPart); } +uint32_t +thread_current_id(void) +{ + return (uint32_t)GetCurrentThreadId(); +} + +int32_t +atomic_i32_increment(volatile int32_t *value) +{ + return (int32_t)InterlockedIncrement((volatile LONG *)value); +} + +int32_t +atomic_i32_compare_exchange(volatile int32_t *value, int32_t exchange, int32_t comparand) +{ + return (int32_t)InterlockedCompareExchange((volatile LONG *)value, (LONG)exchange, (LONG)comparand); +} + bool float_equal(float a, float b, float min_v, float step) { diff --git a/src/mod_host.c b/src/mod_host.c index 2cd4c5c..7112eeb 100644 --- a/src/mod_host.c +++ b/src/mod_host.c @@ -8,6 +8,7 @@ #include "sigscan.h" #include "str.h" #include "unreal.h" +#include "unreal_reflect.h" #include @@ -57,6 +58,17 @@ mod_register_cmd(mod_handle_t mod, str_t name, str_t description, mod_cmd_fn_t f return mod_manager_register_cmd(&globals.mod_manager, mod, name, description, fn, user); } +uclass_t *MOD_CALL +mod_define_class(mod_handle_t mod, str_t name, const unreal_class_def_t *def) +{ + mod_t *owner = mod_handle_resolve(&globals.mod_manager, mod); + if (!owner) { + LOG_ERROR("Cannot define Unreal class '%.*s': invalid mod handle", STR_ARG(name)); + return NULL; + } + return unreal_reflect_define_class_owned((unreal_reflect_owner_t)mod, owner->manifest.info.id, name, def); +} + struct nk_context *MOD_CALL mod_get_nk_ctx(void) { diff --git a/src/mod_manager.c b/src/mod_manager.c index 8e97376..da6694d 100644 --- a/src/mod_manager.c +++ b/src/mod_manager.c @@ -13,11 +13,11 @@ #include "str.h" #include "types.h" #include "unreal.h" - #include "ui_console.h" - #include "version.h" +#include "lua_mod_runtime.h" + #include static str_t @@ -508,6 +508,31 @@ mod_manifest_parse_dll_section(arena_t *arena, ini_section_t *section, str_t mod } } +static void +mod_manifest_parse_lua_section(arena_t *arena, ini_section_t *section, str_t mod_dir, mod_manifest_t *out) +{ + for (str_node_t *node = section->lines.first; node; node = node->next) { + str_t key = {0}; + str_t value = {0}; + if (!ini_parse_kv(node->str, &key, &value)) { + continue; + } + + if (str_equal_icase(key, STR_LIT("path"))) { + out->lua.path = path_is_abs(value) ? str_push_copy(arena, value) : path_join(arena, mod_dir, value); + } else if (str_equal_icase(key, STR_LIT("runtime"))) { + if (str_equal_icase(value, STR_LIT("ue4ss"))) { + out->lua.runtime_kind = MOD_LUA_RUNTIME_UE4SS; + } else if (str_equal_icase(value, STR_LIT("overdub"))) { + out->lua.runtime_kind = MOD_LUA_RUNTIME_OVERDUB; + } else { + out->lua.runtime_kind = MOD_LUA_RUNTIME_INVALID; + LOG_WARN("%.*s: invalid Lua runtime '%.*s'; expected 'ue4ss' or 'overdub'", STR_ARG(out->manifest_path), STR_ARG(value)); + } + } + } +} + static void mod_manifest_parse_assets_section(arena_t *arena, ini_section_t *section, str_t mod_dir, mod_manifest_t *out) { @@ -787,6 +812,8 @@ mod_manifest_copy(mod_manifest_t *dst, mod_manifest_t *src, arena_t *arena) mod_info_copy(&dst->info, &src->info, arena); mod_dll_info_copy(&dst->dll, &src->dll, arena); + dst->lua.path = str_push_copy(arena, src->lua.path); + dst->lua.runtime_kind = src->lua.runtime_kind; mod_asset_info_copy(&dst->asset, &src->asset, arena); dst->blueprint_count = src->blueprint_count; @@ -820,6 +847,7 @@ mod_manifest_parse(arena_t *arena, str_t mod_dir, mod_manifest_t *out) str_t config_path = path_join(tmp.arena, mod_dir, CONFIG_MOD_CONFIG_FILE_NAME); mem_zero(out, sizeof(*out)); + out->lua.runtime_kind = MOD_LUA_RUNTIME_OVERDUB; if (file_exists(manifest_path)) { str_t text = file_read_all(manifest_path, tmp.arena); if (!str_is_empty(text)) { @@ -853,6 +881,8 @@ mod_manifest_parse(arena_t *arena, str_t mod_dir, mod_manifest_t *out) mod_manifest_parse_description_section(arena, section, out); } else if (str_equal_icase(section->name, STR_LIT("code"))) { mod_manifest_parse_dll_section(arena, section, out->mod_dir, out); + } else if (str_equal_icase(section->name, STR_LIT("lua"))) { + mod_manifest_parse_lua_section(arena, section, out->mod_dir, out); } else if (str_equal_icase(section->name, STR_LIT("assets"))) { mod_manifest_parse_assets_section(arena, section, out->mod_dir, out); } else if (str_equal_icase(section->name, STR_LIT("blueprint"))) { @@ -862,6 +892,21 @@ mod_manifest_parse(arena_t *arena, str_t mod_dir, mod_manifest_t *out) } } + if (str_is_empty(out->lua.path)) { + static const str_t candidates[] = { + STR_CLIT("scripts/main.lua"), + STR_CLIT("main.lua"), + }; + + for (int i = 0; i < COUNTOF(candidates); ++i) { + str_t candidate = path_join(tmp.arena, out->mod_dir, candidates[i]); + if (file_exists(candidate)) { + out->lua.path = str_push_copy(arena, candidate); + break; + } + } + } + result = true; } } @@ -1732,6 +1777,25 @@ mod_init_dll_runtime(mod_t *m, bool is_builtin) m->has_code = is_builtin || !str_is_empty(m->manifest.dll.path); } +static void +mod_init_lua_runtime(mod_manager_t *manager, mod_t *m) +{ + m->has_lua = !str_is_empty(m->manifest.lua.path); + if (!m->has_lua) { + return; + } + + str_t root_mod_dir = mod_cfg_string_as_str(&manager->cfg.root_mod_dir); + if (!path_is_abs(root_mod_dir)) { + root_mod_dir = path_join(&manager->perm, manager->game_dir, root_mod_dir); + } else { + root_mod_dir = str_push_copy(&manager->perm, root_mod_dir); + } + + m->lua.game_dir = manager->game_dir; + m->lua.root_mod_dir = root_mod_dir; +} + static void mod_init_asset_runtime(mod_t *m) { @@ -1843,6 +1907,7 @@ mod_register(mod_manager_t *manager, mod_manifest_t *manifest) mod_init_asset_runtime(m); mod_init_blueprint_runtime(&manager->perm, m); mod_init_dll_runtime(m, false); + mod_init_lua_runtime(manager, m); mod_init_option_runtime(&manager->perm, m); if (m->has_options || m->has_blueprints) { @@ -2874,6 +2939,7 @@ mod_dll_start(mod_manager_t *manager, mod_handle_t h) mod_dll_arenas_init_free_list(&m->dll); if (!m->dll.funcs.init(mod_handle_make(m))) { + unreal_reflect_disable_owner((unreal_reflect_owner_t)h); mod_cleanup_dll_runtime(m); m->dll.err_stage = MOD_DLL_ERROR_INIT; @@ -2908,6 +2974,7 @@ mod_dll_stop(mod_manager_t *manager, mod_handle_t h) m->dll.funcs.deinit(mod_handle_make(m)); } + unreal_reflect_disable_owner((unreal_reflect_owner_t)h); mod_cleanup_dll_runtime(m); m->dll.active = false; @@ -2949,6 +3016,20 @@ mod_dll_reload(mod_manager_t *manager, mod_handle_t h) return mod_dll_start(manager, h); } +bool +mod_lua_start(mod_manager_t *manager, mod_handle_t h) +{ + mod_t *mod = mod_handle_resolve(manager, h); + return lua_mod_runtime_start(mod); +} + +void +mod_lua_stop(mod_manager_t *manager, mod_handle_t h) +{ + mod_t *mod = mod_handle_resolve(manager, h); + lua_mod_runtime_stop(mod); +} + static uobject_t * mod_blueprint_resolve_spawn_context(mod_blueprint_info_t *info) { @@ -3191,6 +3272,18 @@ mod_blueprint_tick(mod_manager_t *manager, mod_handle_t h, float delta) } } +void +mod_manager_dispatch_uobject_constructed(mod_manager_t *manager, uobject_t *object) +{ + lua_mod_runtime_notify_uobject_constructed(manager, object); +} + +void +mod_manager_dispatch_uobject_deleted(mod_manager_t *manager, uobject_t *object, int32_t idx) +{ + lua_mod_runtime_notify_uobject_deleted(manager, object, idx); +} + void mod_manager_dispatch_tick(mod_manager_t *manager, float delta) { @@ -3201,6 +3294,19 @@ mod_manager_dispatch_tick(mod_manager_t *manager, float delta) for (int i = 0; i < manager->mod_order.count; ++i) { mod_handle_t h = manager->mod_order.runtime[i]; mod_t *m = mod_handle_resolve(manager, h); + if (!m) { + continue; + } + + if (m->has_lua) { + if (m->enabled && !m->lua.active && !m->lua.start_attempted) { + mod_lua_start(manager, h); + } else if (!m->enabled && (lua_mod_runtime_is_initialized(m) || m->lua.start_attempted)) { + mod_lua_stop(manager, h); + } + lua_mod_runtime_tick(m, delta); + } + mod_dll_runtime_t *rt = &m->dll; if (m->has_code && rt->active && rt->funcs.tick) { @@ -3221,8 +3327,18 @@ mod_manager_dispatch_input(mod_manager_t *manager, input_event_t *ev) } for (int i = 0; i < manager->mod_order.count; ++i) { - mod_handle_t h = manager->mod_order.runtime[i]; - mod_t *m = mod_handle_resolve(manager, h); + mod_handle_t h = manager->mod_order.runtime[i]; + mod_t *m = mod_handle_resolve(manager, h); + if (!m) { + continue; + } + + if (m->has_lua && m->lua.active) { + if (lua_mod_runtime_input(m, ev)) { + return true; + } + } + mod_dll_runtime_t *rt = &m->dll; if (!m->has_code || !rt->active || !rt->funcs.input) { @@ -3248,8 +3364,16 @@ mod_manager_dispatch_process_event_pre(mod_manager_t *manager, uobject_t *obj, u for (int i = 0; i < manager->mod_order.count; ++i) { mod_handle_t h = manager->mod_order.runtime[i]; mod_t *m = mod_handle_resolve(manager, h); + if (!m) { + continue; + } + mod_dll_runtime_t *rt = &m->dll; + if (m->has_lua && m->lua.active && lua_mod_runtime_process_event_pre(m, obj, func, params)) { + handled = true; + } + if (!m->has_code || !rt->active || !rt->funcs.pe_pre) { continue; } @@ -3272,6 +3396,14 @@ mod_manager_dispatch_process_event_post(mod_manager_t *manager, uobject_t *obj, for (int i = 0; i < manager->mod_order.count; ++i) { mod_handle_t h = manager->mod_order.runtime[i]; mod_t *m = mod_handle_resolve(manager, h); + if (!m) { + continue; + } + + if (m->has_lua && m->lua.active) { + lua_mod_runtime_process_event_post(m, obj, func, params, consumed); + } + mod_dll_runtime_t *rt = &m->dll; if (!m->has_code || !rt->active || !rt->funcs.pe_post) { @@ -3282,6 +3414,27 @@ mod_manager_dispatch_process_event_post(mod_manager_t *manager, uobject_t *obj, } } +void +mod_manager_dispatch_post_load(mod_manager_t *manager, uobject_t *obj, bool after) +{ + if (!manager || !obj) { + return; + } + + for (int i = 0; i < manager->mod_order.count; ++i) { + mod_t *mod = mod_handle_resolve(manager, manager->mod_order.runtime[i]); + if (mod && mod->has_lua && mod->lua.active) { + lua_mod_runtime_post_load(mod, obj, after); + } + } +} + +bool +mod_manager_has_post_load_hooks(mod_manager_t *manager) +{ + return manager && lua_mod_runtime_has_post_load_hooks(); +} + bool mod_manager_dispatch_ufunction_invoke_pre(mod_manager_t *manager, ufunc_t *func, uobject_t *obj, fframe_t *stack, void *result) { @@ -3334,9 +3487,20 @@ mod_manager_dispatch_command(mod_manager_t *manager, str_t name, str_t args) return false; } + bool matched = false; for (int i = 0; i < manager->mod_order.count; ++i) { mod_handle_t h = manager->mod_order.runtime[i]; mod_t *m = mod_handle_resolve(manager, h); + if (!m) { + continue; + } + + if (m->has_lua && m->lua.active) { + if (lua_mod_runtime_command(m, name, args)) { + return true; + } + } + mod_dll_runtime_t *rt = &m->dll; if (!m->has_code || !rt->active) { @@ -3354,7 +3518,7 @@ mod_manager_dispatch_command(mod_manager_t *manager, str_t name, str_t args) } } - return false; + return matched; } bool @@ -3479,6 +3643,8 @@ mod_manager_init(mod_manager_t *manager, str_t game_dir) ASSERT(!str_is_empty(manager->config_path)); ASSERT(manager->mods != NULL); + + lua_mod_runtime_system_init(); } void @@ -3495,6 +3661,20 @@ mod_manager_start_dlls(mod_manager_t *manager) } } +void +mod_manager_start_lua(mod_manager_t *manager) +{ + for (int i = 0; i < manager->mod_order.count; ++i) { + mod_handle_t h = manager->mod_order.runtime[i]; + mod_t *m = mod_handle_resolve(manager, h); + if (!m || !m->enabled || !m->has_lua) { + continue; + } + + mod_lua_start(manager, h); + } +} + void mod_manager_start_blueprints(mod_manager_t *manager) { @@ -3574,6 +3754,10 @@ mod_has_any_errors(mod_t *m) return true; } + if (m->has_lua && m->lua.err_msg.len > 0) { + return true; + } + if (m->has_blueprints) { for (int i = 0; i < m->blueprint_count; ++i) { if (m->blueprints[i].err_stage != MOD_BP_ERROR_NONE) { @@ -3592,6 +3776,10 @@ mod_is_active(mod_t *m) return true; } + if (m->has_lua && m->lua.active) { + return true; + } + if (m->has_blueprints) { for (int i = 0; i < m->blueprint_count; ++i) { if (m->blueprints[i].active) { @@ -3622,6 +3810,11 @@ mod_manager_mod_set_enabled(mod_manager_t *manager, mod_handle_t h, bool enabled /* NOTE: assets cannot be mounted/unmounted freely at the runtime */ if (enabled) { + if (m->has_lua && !m->enabled) { + m->lua.start_attempted = false; + err_msg_set(&m->lua.err_msg, STR_NULL); + } + if (m->has_code) { mod_dll_start(manager, h); } diff --git a/src/signatures.c b/src/signatures.c index f80d26d..d08e333 100644 --- a/src/signatures.c +++ b/src/signatures.c @@ -108,42 +108,48 @@ static signature_t g_early_sigs[] = { }; static signature_t g_main_sigs[] = { - SIG_ENTRY_HOOKED(CALL_ARG, pak_file_mount, "E8 ? ? ? ? 84 C0 74 ? 41 FF C5 FF C6", 0x0401689D, 0x03E2C69D), - SIG_ENTRY_HOOKED(DIRECT, io_dispatcher_mount, "40 53 41 55 41 57 48 81 EC ? ? ? ? 48 8B 05", 0x02745980, 0x026CB8D0), - SIG_ENTRY_HOOKED(DIRECT, pak_precacher_add_new_block, "48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 55 41 54 41 55 41 56 41 57 48 8D AC 24 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 85 ?? ?? ?? ?? 45 33 C9", 0x00000000, 0x03E1CF90), - SIG_ENTRY_HOOKED(DIRECT, game_engine_tick, "48 8B C4 44 88 40 ? 48 89 48 ? 55 53", 0x0434A5A0, 0x04162180), - SIG_ENTRY_HOOKED(DIRECT, process_event, "40 55 56 57 41 54 41 55 41 56 41 57 48 81 EC ? ? ? ? 48 8D 6C 24 ? 48 89 9D ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C5 48 89 85 ? ? ? ? 8B 41", 0x029FDCD0, 0x02981E80), - SIG_ENTRY_HOOKED(DIRECT, ufunction_invoke, "48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 41 56 48 83 EC ? 48 8B 59 ? 4D 8B F1", 0x0289B0B0, 0x0281F2B0), - SIG_ENTRY_HOOKED(DIRECT, d3d12_viewport_init, "48 89 74 24 ? 48 89 7C 24 ? 55 41 54 41 55 41 56 41 57 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 45 ? 4C 8B 69", 0x02D44E20, 0x02C98770), - SIG_ENTRY_NORMAL(LEA_ADDR, globals.uobjects, "4C 8D 1D ? ? ? ? 89 41", 0x00FDCEF0, 0x00FA15D0), - SIG_ENTRY_NORMAL(LEA_ADDR, globals.name_pool, "48 8D 05 ? ? ? ? EB ? 48 8D 0D ? ? ? ? E8 ? ? ? ? C6 05 ? ? ? ? ? 8B 80 ? ? ? ? 83 8B", 0x042D26E4, 0x040E9DA4), - SIG_ENTRY_NORMAL(MOV64_ADDR, globals.gworld_ptr, "48 8B 05 ? ? ? ? 4C 8D 44 24 ? 48 8D 54 24 ? 48 89 44 24 ? 48 8B CB", 0x047AD35A, 0x045C489A), - SIG_ENTRY_NORMAL(LEA_ADDR, globals.natives, "48 8D 05 ? ? ? ? B9 ? ? ? ? 0F 1F 40 ? 66 0F 1F 84 00 ? ? ? ? ? ? ? 48 89 50 ? 48 89 50 ? 48 8D 40 ? 48 89 50 ? 48 89 50 ? 48 89 50 ? 48 89 50 ? 48 89 50 ? 48 83 E9 ? 75 ? 8B 05 ? ? ? ? 33 C9", 0x00A062C7, 0x009BC917), - SIG_ENTRY_NORMAL(LEA_ADDR, globals.uobject_vtable, "48 8D 05 ? ? ? ? ? ? ? 48 8B FA 48 8B D9", 0x02A1A6E1, 0x0299E821), - SIG_ENTRY_NORMAL(MOV64_ADDR, globals.gameplay_tags_manager_ptr, "48 8B 0D ? ? ? ? B2 ? E8 ? ? ? ? 48 8B 0D ? ? ? ? E8", 0x03FC72E3, 0x03DDD933), - SIG_ENTRY_NORMAL(LEA_ADDR, globals.on_gameplay_tag_tree_changed, "48 8D 0D ? ? ? ? 41 C6 84 24", 0x03FC467D, 0x03DDACCD), - SIG_ENTRY_NORMAL(DIRECT, static_load_object, "4C 89 4C 24 ? 48 89 54 24 ? 48 89 4C 24 ? 55 53 56 57 41 54 41 55 41 56 41 57 48 8B EC 48 83 EC ? 33 FF 49 8B F0", 0x02A14930, 0x02998AC0), - SIG_ENTRY_NORMAL(DIRECT, static_construct_object, "48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 41 56 41 57 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 84 24 ? ? ? ? ? ? ? 48 8B D9", 0x02A1B9F0, 0x0299FB10), - SIG_ENTRY_NORMAL(DIRECT, create_default_object, "4C 8B DC 55 57 49 8D AB ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 48 83 B9 ? ? ? ? 00 48 8B F9 0F 85", 0x02896DE0, 0x0281B000), - SIG_ENTRY_NORMAL(DIRECT, static_load_class, "40 55 53 57 41 56 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 8B BD", 0x02A15D70, 0x02999EF0), - SIG_ENTRY_NORMAL(DIRECT, fname_construct, "48 89 5C 24 ? 57 48 83 EC ? 48 8B D9 48 89 54 24 ? 33 C9", 0x027EF960, 0x027758B0), - SIG_ENTRY_NORMAL(DIRECT, add_uobject_delete_listener, "48 89 5C 24 ? 57 48 83 EC ? 48 8D 0D ? ? ? ? 48 8B FA FF 15", 0x02A0CFF0, 0x02991170), - SIG_ENTRY_NORMAL(CALL_ARG, tarray_grow, "E8 ? ? ? ? 48 8B 05 ? ? ? ? 48 8D 0D ? ? ? ? ? ? ? ? 48 8B 5C 24 ? 48 83 C4 ? 5F 48 FF 25 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 40 53", 0x02A0D029, 0x029911A9), - SIG_ENTRY_NORMAL(CALL_ARG, tarray_shrink, "E8 ? ? ? ? 48 8D 0D ? ? ? ? 48 83 C4 ? 5B 48 FF 25 ? ? ? ? ? 8B 42", 0x02A0D107, 0x02991287), - SIG_ENTRY_NORMAL(DIRECT, get_mcast_sparse_delegate, "48 89 5C 24 ? 57 48 83 EC ? 48 8B F9 48 8B DA 48 8D 0D ? ? ? ? FF 15 ? ? ? ? 4C 8B C7", 0x02A06FF0, 0x0298B190), - SIG_ENTRY_NORMAL(DIRECT, fscript_map_add_pair, "40 55 56 57 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 45 ? 0F B6 41", 0x02A26830, 0x029AA910), - SIG_ENTRY_NORMAL(DIRECT, fscript_map_remove_pair, "48 89 5C 24 ? 48 89 74 24 ? 55 57 41 56 48 8B EC 48 83 EC ? 0F B6 41 ? 48 8B F2", 0x029EF0A0, 0x02972FE0), - SIG_ENTRY_NORMAL(DIRECT, generic_map_find, "48 89 5C 24 ? 48 89 74 24 ? 55 57 41 56 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 45 ? 4D 8B F1", 0x041C7390, 0x03FDEB30), - SIG_ENTRY_NORMAL(DIRECT, add_tag_table_row, "48 8B C4 55 57 48 8D 68 ? 48 81 EC ? ? ? ? 48 89 58 ? 48 89 70 ? 4C 89 60 ? 4C 89 68 ? 4C 89 78", 0x03FC7410, 0x03DDDA60), - SIG_ENTRY_NORMAL(DIRECT, tmulticast_delegate_broadcast, "40 56 48 83 EC ? FF 41 ? 48 8B F1 8B 49 ? 48 89 5C 24", 0x00E6BEA0, 0x00E1FD30), - SIG_ENTRY_NORMAL(DIRECT, request_gameplay_tag, "40 53 55 56 57 48 83 EC ? 8B 81", 0x03FC8DC0, 0x03DDF410), - SIG_ENTRY_NORMAL(DIRECT, generic_array_resize, "48 85 C9 0F 84 ? ? ? ? 48 8B C4 44 89 40", 0x00000000, 0x00000000), - SIG_ENTRY_NORMAL(DIRECT, generic_array_add, "48 8B C4 4C 89 40 ? 53 48 83 EC ? 48 8B D9", 0x00000000, 0x00000000), - SIG_ENTRY_NORMAL(DIRECT, generic_array_insert, "48 85 C9 0F 84 ? ? ? ? 48 89 74 24 ? 57 48 83 EC ? 44 8B 92", 0x00000000, 0x00000000), - SIG_ENTRY_NORMAL(DIRECT, generic_array_remove, "48 85 C9 0F 84 ? ? ? ? 48 89 5C 24 ? 56 48 83 EC ? 4C 8B 4A", 0x00000000, 0x00000000), - SIG_ENTRY_NORMAL(DIRECT, generic_array_set, "48 85 C9 0F 84 ? ? ? ? 48 8B C4 4C 89 48 ? 53", 0x00000000, 0x00000000), - SIG_ENTRY_NORMAL(DIRECT, fscript_set_add_elem, "4C 8B DC 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 84 24 ? ? ? ? ? ? ? 4C 8D 41", 0x00000000, 0x00000000), - SIG_ENTRY_NORMAL(DIRECT, generic_set_remove, "4C 8B DC 49 89 5B ? 57 48 83 EC ? 49 8B F8", 0x00000000, 0x00000000), + SIG_ENTRY_HOOKED(CALL_ARG, pak_file_mount, "E8 ? ? ? ? 84 C0 74 ? 41 FF C5 FF C6", 0x0401689D, 0x03E2C69D), + SIG_ENTRY_HOOKED(DIRECT, io_dispatcher_mount, "40 53 41 55 41 57 48 81 EC ? ? ? ? 48 8B 05", 0x02745980, 0x026CB8D0), + SIG_ENTRY_HOOKED(DIRECT, pak_precacher_add_new_block, "48 89 5C 24 ?? 48 89 74 24 ?? 48 89 7C 24 ?? 55 41 54 41 55 41 56 41 57 48 8D AC 24 ?? ?? ?? ?? 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 85 ?? ?? ?? ?? 45 33 C9", 0x04007280, 0x03E1CF90), + SIG_ENTRY_HOOKED(DIRECT, game_engine_tick, "48 8B C4 44 88 40 ? 48 89 48 ? 55 53", 0x0434A5A0, 0x04162180), + SIG_ENTRY_HOOKED(DIRECT, process_event, "40 55 56 57 41 54 41 55 41 56 41 57 48 81 EC ? ? ? ? 48 8D 6C 24 ? 48 89 9D ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C5 48 89 85 ? ? ? ? 8B 41", 0x029FDCD0, 0x02981E80), + SIG_ENTRY_HOOKED(DIRECT, ufunction_invoke, "48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 41 56 48 83 EC ? 48 8B 59 ? 4D 8B F1", 0x0289B0B0, 0x0281F2B0), + SIG_ENTRY_HOOKED(DIRECT, d3d12_viewport_init, "48 89 74 24 ? 48 89 7C 24 ? 55 41 54 41 55 41 56 41 57 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 45 ? 4C 8B 69", 0x02D44E20, 0x02C98770), + SIG_ENTRY_NORMAL(LEA_ADDR, globals.uobjects, "4C 8D 1D ? ? ? ? 89 41", 0x00FDCEF0, 0x00FA15D0), + SIG_ENTRY_NORMAL(LEA_ADDR, globals.name_pool, "48 8D 05 ? ? ? ? EB ? 48 8D 0D ? ? ? ? E8 ? ? ? ? C6 05 ? ? ? ? ? 8B 80 ? ? ? ? 83 8B", 0x042D26E4, 0x040E9DA4), + SIG_ENTRY_NORMAL(MOV64_ADDR, globals.gworld_ptr, "48 8B 05 ? ? ? ? 4C 8D 44 24 ? 48 8D 54 24 ? 48 89 44 24 ? 48 8B CB", 0x047AD35A, 0x045C489A), + SIG_ENTRY_NORMAL(LEA_ADDR, globals.natives, "48 8D 05 ? ? ? ? B9 ? ? ? ? 0F 1F 40 ? 66 0F 1F 84 00 ? ? ? ? ? ? ? 48 89 50 ? 48 89 50 ? 48 8D 40 ? 48 89 50 ? 48 89 50 ? 48 89 50 ? 48 89 50 ? 48 89 50 ? 48 83 E9 ? 75 ? 8B 05 ? ? ? ? 33 C9", 0x00A062C7, 0x009BC917), + SIG_ENTRY_NORMAL(LEA_ADDR, globals.uobject_vtable, "48 8D 05 ? ? ? ? ? ? ? 48 8B FA 48 8B D9", 0x02A1A6E1, 0x0299E821), + SIG_ENTRY_NORMAL(MOV64_ADDR, globals.gameplay_tags_manager_ptr, "48 8B 0D ? ? ? ? B2 ? E8 ? ? ? ? 48 8B 0D ? ? ? ? E8", 0x03FC72E3, 0x03DDD933), + SIG_ENTRY_NORMAL(LEA_ADDR, globals.on_gameplay_tag_tree_changed, "48 8D 0D ? ? ? ? 41 C6 84 24", 0x03FC467D, 0x03DDACCD), + SIG_ENTRY_NORMAL(DIRECT, static_load_object, "4C 89 4C 24 ? 48 89 54 24 ? 48 89 4C 24 ? 55 53 56 57 41 54 41 55 41 56 41 57 48 8B EC 48 83 EC ? 33 FF 49 8B F0", 0x02A14930, 0x02998AC0), + SIG_ENTRY_NORMAL(DIRECT, static_construct_object, "48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 41 56 41 57 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 84 24 ? ? ? ? ? ? ? 48 8B D9", 0x02A1B9F0, 0x0299FB10), + SIG_ENTRY_NORMAL(DIRECT, create_default_object, "4C 8B DC 55 57 49 8D AB ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 48 83 B9 ? ? ? ? 00 48 8B F9 0F 85", 0x02896DE0, 0x0281B000), + SIG_ENTRY_NORMAL(DIRECT, static_load_class, "40 55 53 57 41 56 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 8B BD", 0x02A15D70, 0x02999EF0), + SIG_ENTRY_NORMAL(DIRECT, fname_construct, "48 89 5C 24 ? 57 48 83 EC ? 48 8B D9 48 89 54 24 ? 33 C9", 0x027EF960, 0x027758B0), + SIG_ENTRY_NORMAL(DIRECT, add_uobject_delete_listener, "48 89 5C 24 ? 57 48 83 EC ? 48 8D 0D ? ? ? ? 48 8B FA FF 15", 0x02A0CFF0, 0x02991170), + SIG_ENTRY_NORMAL(CALL_ARG, tarray_grow, "E8 ? ? ? ? 48 8B 05 ? ? ? ? 48 8D 0D ? ? ? ? ? ? ? ? 48 8B 5C 24 ? 48 83 C4 ? 5F 48 FF 25 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 40 53", 0x02A0D029, 0x029911A9), + SIG_ENTRY_NORMAL(CALL_ARG, tarray_shrink, "E8 ? ? ? ? 48 8D 0D ? ? ? ? 48 83 C4 ? 5B 48 FF 25 ? ? ? ? ? 8B 42", 0x02A0D107, 0x02991287), + SIG_ENTRY_NORMAL(DIRECT, get_mcast_sparse_delegate, "48 89 5C 24 ? 57 48 83 EC ? 48 8B F9 48 8B DA 48 8D 0D ? ? ? ? FF 15 ? ? ? ? 4C 8B C7", 0x02A06FF0, 0x0298B190), + SIG_ENTRY_NORMAL(DIRECT, fscript_map_add_pair, "40 55 56 57 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 45 ? 0F B6 41", 0x02A26830, 0x029AA910), + SIG_ENTRY_NORMAL(DIRECT, fscript_map_remove_pair, "48 89 5C 24 ? 48 89 74 24 ? 55 57 41 56 48 8B EC 48 83 EC ? 0F B6 41 ? 48 8B F2", 0x029EF0A0, 0x02972FE0), + SIG_ENTRY_NORMAL(DIRECT, generic_map_find, "48 89 5C 24 ? 48 89 74 24 ? 55 57 41 56 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 45 ? 4D 8B F1", 0x041C7390, 0x03FDEB30), + SIG_ENTRY_NORMAL(DIRECT, add_tag_table_row, "48 8B C4 55 57 48 8D 68 ? 48 81 EC ? ? ? ? 48 89 58 ? 48 89 70 ? 4C 89 60 ? 4C 89 68 ? 4C 89 78", 0x03FC7410, 0x03DDDA60), + SIG_ENTRY_NORMAL(DIRECT, tmulticast_delegate_broadcast, "40 56 48 83 EC ? FF 41 ? 48 8B F1 8B 49 ? 48 89 5C 24", 0x00E6BEA0, 0x00E1FD30), + SIG_ENTRY_NORMAL(DIRECT, request_gameplay_tag, "40 53 55 56 57 48 83 EC ? 8B 81", 0x03FC8DC0, 0x03DDF410), + SIG_ENTRY_NORMAL(DIRECT, generic_array_resize, "48 85 C9 0F 84 ? ? ? ? 48 8B C4 44 89 40", 0x04419C30, 0x00000000), + SIG_ENTRY_NORMAL(DIRECT, generic_array_add, "48 8B C4 4C 89 40 ? 53 48 83 EC ? 48 8B D9", 0x04419350, 0x00000000), + SIG_ENTRY_NORMAL(DIRECT, generic_array_insert, "48 85 C9 0F 84 ? ? ? ? 48 89 74 24 ? 57 48 83 EC ? 44 8B 92", 0x044198A0, 0x00000000), + SIG_ENTRY_NORMAL(DIRECT, generic_array_remove, "48 85 C9 0F 84 ? ? ? ? 48 89 5C 24 ? 56 48 83 EC ? 4C 8B 4A", 0x04419A20, 0x00000000), + SIG_ENTRY_NORMAL(DIRECT, generic_array_set, "48 85 C9 0F 84 ? ? ? ? 48 8B C4 4C 89 48 ? 53", 0x0441A210, 0x00000000), + SIG_ENTRY_NORMAL(DIRECT, fscript_set_add_elem, "4C 8B DC 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 84 24 ? ? ? ? ? ? ? 4C 8D 41", 0x02A26D40, 0x00000000), + SIG_ENTRY_NORMAL(DIRECT, generic_set_remove, "4C 8B DC 49 89 5B ? 57 48 83 EC ? 49 8B F8", 0x041C7CA0, 0x00000000), + SIG_ENTRY_NORMAL(DIRECT, ustruct_static_link, "48 89 5C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 55 41 56 41 57 48 8D 6C 24 ? 48 81 EC ? ? ? ? 45 33 F6 C7 45 ? ? ? ? ? 48 8D 45 ? 4C 89 75 ? 0F 57 C0 66 44 89 75 ? 4C 8D 3D ? ? ? ? 44 89 75 ? 4C 89 7D ? 0F B6 F2", 0x00000000, 0x00000000), + SIG_ENTRY_NORMAL(DIRECT, uclass_create_link_and_add_child_funcs_to_map, "45 85 C0 0F 84 ? ? ? ? 4C 8B DC 55", 0x00000000, 0x00000000), + SIG_ENTRY_NORMAL(DIRECT, uclass_assemble_ref_tok_stream, "48 8B C4 55 41 56 48 8D 68 ? 48 81 EC ? ? ? ? 48 89 58 ? 4C 8D B1", 0x00000000, 0x00000000), + SIG_ENTRY_NORMAL(DIRECT, uclass_add_native_func, "48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC ? 48 8B D9 48 89 54 24 ? 33 C9", 0x00000000, 0x00000000), + SIG_ENTRY_HOOKED(DIRECT, conditional_post_load, "40 53 48 83 EC ? 48 8B D9 8B 49 ? 8B C1 C1 E8 ? A8 ? 74", 0x00000000, 0x00000000), + SIG_ENTRY_NORMAL(DIRECT, ffield_construct, "48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 41 56 48 83 EC ? ? ? ? 49 8B F0 48 8B EA E8", 0x00000000, 0x00000000), }; static signature_t g_input_sigs[] = { @@ -255,7 +261,7 @@ signatures_init(void) for (int i = 0; i < SIG_KIND_MAX; ++i) { signature_t *sigs = g_sig_table[i].sigs; - for (int j = 0; j < g_sig_table[i].count; ++i) { + for (int j = 0; j < g_sig_table[i].count; ++j) { signature_t *s = &sigs[j]; max_resolved += 1; @@ -287,4 +293,3 @@ enable_input_hooks(void) { enable_hooks(g_sig_table[SIG_KIND_INPUT].sigs, g_sig_table[SIG_KIND_INPUT].count); } - diff --git a/src/ui_console.c b/src/ui_console.c index 3cfdb6b..6561fa5 100644 --- a/src/ui_console.c +++ b/src/ui_console.c @@ -3,9 +3,70 @@ #include "config.h" #include "globals.h" #include "log.h" +#include "lua_mod_runtime.h" #include "scratch.h" #include "str.h" #include "ui_nuklear.h" +#include "unreal.h" + +#include +#include + +#define UI_CONSOLE_PREFIX_CAP (UI_CONSOLE_TIMESTAMP_CAP + 6) + +enum { + UI_CONSOLE_PREFIX_TIMESTAMP = 1 << 0, + UI_CONSOLE_PREFIX_LEVEL = 1 << 1, +}; + +void +ui_console_on_frame_begin(ui_console_t *console, uint64_t frame_counter) +{ + if (!unreal_is_in_game_thread()) { + return; + } + + log_ui_on_frame_begin(frame_counter); + ui_console_flush_logs(console); +} + +static void +ui_console_format_timestamp(char buffer[UI_CONSOLE_TIMESTAMP_CAP], const SYSTEMTIME *time, uint64_t frame) +{ + snprintf(buffer, UI_CONSOLE_TIMESTAMP_CAP, "%04d-%02d-%02d %02d:%02d:%02d.%03d#%03llu", + time->wYear, time->wMonth, time->wDay, time->wHour, time->wMinute, time->wSecond, time->wMilliseconds, (unsigned long long)frame); +} + +static void +ui_console_message_timestamp(const log_message_t *message, char buffer[UI_CONSOLE_TIMESTAMP_CAP]) +{ + FILETIME now = { + .dwLowDateTime = (DWORD)message->timestamp, + .dwHighDateTime = (DWORD)(message->timestamp >> 32), + }; + FILETIME local_time; + SYSTEMTIME time = {0}; + FileTimeToLocalFileTime(&now, &local_time); + FileTimeToSystemTime(&local_time, &time); + ui_console_format_timestamp(buffer, &time, message->frame); +} + +static str_t +ui_console_level_prefix(ui_console_log_level_t level) +{ + switch (level) { + case UI_CONSOLE_LOG_DEBUG: + return STR_LIT("[DBG] "); + case UI_CONSOLE_LOG_INFO: + return STR_LIT("[INF] "); + case UI_CONSOLE_LOG_WARN: + return STR_LIT("[WRN] "); + case UI_CONSOLE_LOG_ERROR: + return STR_LIT("[ERR] "); + default: + return STR_LIT("[UNK] "); + } +} static struct nk_color ui_console_level_color(ui_console_log_level_t level) @@ -97,7 +158,64 @@ ui_console_position_str_array(void) static uint8_t * ui_console_line_slot_ptr(ui_console_t *console, int slot_idx) { - return console->line_text_storage + ((uint64_t)slot_idx * (uint64_t)console->max_line_len); + uint64_t stride = (uint64_t)console->max_line_len + UI_CONSOLE_PREFIX_CAP; + return console->line_text_storage + (uint64_t)slot_idx * stride + UI_CONSOLE_PREFIX_CAP; +} + +static uint8_t +ui_console_prefix_flags(const ui_console_t *console) +{ + uint8_t flags = 0; + + if (console->cfg.show_timestamp) { + flags |= UI_CONSOLE_PREFIX_TIMESTAMP; + } + + if (console->cfg.show_log_level) { + flags |= UI_CONSOLE_PREFIX_LEVEL; + } + + return flags; +} + +static void +ui_console_update_line_prefix(ui_console_line_t *line, uint8_t flags) +{ + uint8_t *start = line->text.data; + + if (flags & UI_CONSOLE_PREFIX_LEVEL) { + str_t prefix = ui_console_level_prefix(line->level); + start -= prefix.len; + mem_copy(start, prefix.data, prefix.len); + } + + if (flags & UI_CONSOLE_PREFIX_TIMESTAMP) { + str_t timestamp = str_from_cstr(line->timestamp); + start -= timestamp.len + 1; + mem_copy(start, timestamp.data, timestamp.len); + start[timestamp.len] = ' '; + } + + uint64_t prefix_len = (uint64_t)(line->text.data - start); + line->display_text = (str_t){.data = start, .len = prefix_len + line->text.len}; + line->row_w = 0.0f; +} + +static void +ui_console_update_prefixes(ui_console_t *console) +{ + uint8_t flags = ui_console_prefix_flags(console); + if (console->prefix_flags == flags) { + return; + } + + // rebuild retained prefixes only when a toggle changes + console->prefix_flags = flags; + int count = MIN_VAL(console->line_count, console->max_lines); + + for (int i = 0; i < count; ++i) { + ui_console_update_line_prefix(&console->lines[i], flags); + } } static uint8_t * @@ -124,6 +242,31 @@ ui_console_slot_copy(uint8_t *dst, int dst_cap, str_t src) return str_make(dst, n); } +static str_t +ui_console_line_copy(uint8_t *dst, int dst_cap, str_t src) +{ + if (!dst || dst_cap <= 0) { + return (str_t){0}; + } + + uint64_t dst_len = 0; + for (uint64_t src_idx = 0; src_idx < src.len && dst_len < (uint64_t)(dst_cap - 1); ++src_idx) { + if (src.data[src_idx] == '\t') { + uint64_t space_count = CONFIG_NK_CONSOLE_TAB_WIDTH - (dst_len % CONFIG_NK_CONSOLE_TAB_WIDTH); + while (space_count > 0 && dst_len < (uint64_t)(dst_cap - 1)) { + dst[dst_len++] = ' '; + space_count -= 1; + } + } else { + dst[dst_len++] = src.data[src_idx]; + } + } + + dst[dst_len] = 0; + // empty messages still need a slot pointer for the prefix + return (str_t){.data = dst, .len = dst_len}; +} + static void ui_console_set_input(ui_console_t *console, str_t text) { @@ -209,8 +352,10 @@ ui_console_history_next(ui_console_t *console) } static void -ui_console_store_line(ui_console_t *console, ui_console_log_level_t level, str_t text) +ui_console_store_line(ui_console_t *console, ui_console_log_level_t level, str_t text, const char *timestamp) { + ASSERT(unreal_is_in_game_thread()); + if (!console->lines || !console->line_text_storage) { return; } @@ -219,9 +364,10 @@ ui_console_store_line(ui_console_t *console, ui_console_log_level_t level, str_t ui_console_line_t *l = &console->lines[slot_idx]; uint8_t *slot = ui_console_line_slot_ptr(console, slot_idx); - l->text = ui_console_slot_copy(slot, console->max_line_len, text); + l->text = ui_console_line_copy(slot, console->max_line_len, text); l->level = level; - l->row_w = 0.0f; + ui_console_slot_copy((uint8_t *)l->timestamp, sizeof(l->timestamp), str_from_cstr(timestamp)); + ui_console_update_line_prefix(l, ui_console_prefix_flags(console)); console->line_count += 1; console->scroll_to_bottom = true; @@ -235,13 +381,15 @@ ui_console_init(ui_console_t *console, arena_t *arena) } console->max_lines = CONFIG_NK_CONSOLE_MAX_LINES; - console->max_line_len = CONFIG_NK_CONSOLE_MAX_LINE_LEN; + console->max_line_len = CONFIG_NK_CONSOLE_MAX_LINE_LEN + 1; console->input_max = CONFIG_NK_CONSOLE_MAX_INPUT_LEN; console->history_max = CONFIG_NK_CONSOLE_MAX_HISTORY; console->history_pos = -1; + uint64_t line_stride = (uint64_t)console->max_line_len + UI_CONSOLE_PREFIX_CAP; + console->lines = ARENA_PUSH_ARRAY_ZERO(arena, ui_console_line_t, console->max_lines); - console->line_text_storage = ARENA_PUSH_ARRAY_ZERO(arena, uint8_t, (uint64_t)console->max_lines *(uint64_t)console->max_line_len); + console->line_text_storage = ARENA_PUSH_ARRAY_ZERO(arena, uint8_t, (uint64_t)console->max_lines * line_stride); console->input_buf = ARENA_PUSH_ARRAY_ZERO(arena, uint8_t, console->input_max); console->input = str_make(console->input_buf, 0); @@ -249,12 +397,15 @@ ui_console_init(ui_console_t *console, arena_t *arena) console->history = ARENA_PUSH_ARRAY_ZERO(arena, str_t, console->history_max); console->history_storage = ARENA_PUSH_ARRAY_ZERO(arena, uint8_t, (uint64_t)console->history_max *(uint64_t)console->input_max); - console->cfg.toggle_bind = keybind_parse(CONFIG_NK_CONSOLE_DEFAULT_TOGGLE_KEY, KEYBIND_NULL); - console->cfg.auto_scroll = true; - console->cfg.wrap_lines = true; - console->cfg.position = UI_CONSOLE_POSITION_BOTTOM; - console->cfg.min_level = UI_CONSOLE_LOG_DEBUG; - console->saved_cfg = console->cfg; + console->cfg.toggle_bind = keybind_parse(CONFIG_NK_CONSOLE_DEFAULT_TOGGLE_KEY, KEYBIND_NULL); + console->cfg.auto_scroll = true; + console->cfg.wrap_lines = true; + console->cfg.show_timestamp = false; + console->cfg.show_log_level = false; + console->cfg.position = UI_CONSOLE_POSITION_BOTTOM; + console->cfg.min_level = UI_CONSOLE_LOG_DEBUG; + console->saved_cfg = console->cfg; + console->prefix_flags = 0; console->drag.height_ratio = CONFIG_NK_CONSOLE_DEFAULT_HEIGHT_RATIO; console->drag.dragging = false; @@ -265,7 +416,10 @@ ui_console_init(ui_console_t *console, arena_t *arena) console->inited = true; console->closed = true; - lua_runtime_init(&console->lua); + lua_unreal_context_init(&console->lua_unreal); + if (lua_runtime_init(&console->lua) && !lua_unreal_register(console->lua.state, &console->lua_unreal)) { + LOG_ERROR("Failed to register the Lua Unreal bindings"); + } } bool @@ -286,6 +440,10 @@ ui_console_load_cfg(ui_console_t *console, str_list_t lines) console->cfg.auto_scroll = str_parse_bool(value, true); } else if (str_equal_icase(key, STR_LIT("wrap_lines"))) { console->cfg.wrap_lines = str_parse_bool(value, true); + } else if (str_equal_icase(key, STR_LIT("show_timestamp"))) { + console->cfg.show_timestamp = str_parse_bool(value, false); + } else if (str_equal_icase(key, STR_LIT("show_log_level"))) { + console->cfg.show_log_level = str_parse_bool(value, false); } else if (str_equal_icase(key, STR_LIT("position"))) { console->cfg.position = ui_console_position_from_str(value); } else if (str_equal_icase(key, STR_LIT("min_level"))) { @@ -315,6 +473,8 @@ ui_console_save_cfg(ui_console_t *console, arena_t *arena, str_list_t *lines) str_list_push_fmt(arena, lines, "toggle_keybind = %.*s", STR_ARG(toggle_bind_str)); str_list_push_fmt(arena, lines, "auto_scroll = %.*s", STR_ARG(STR_BOOL(console->cfg.auto_scroll))); str_list_push_fmt(arena, lines, "wrap_lines = %.*s", STR_ARG(STR_BOOL(console->cfg.wrap_lines))); + str_list_push_fmt(arena, lines, "show_timestamp = %.*s", STR_ARG(STR_BOOL(console->cfg.show_timestamp))); + str_list_push_fmt(arena, lines, "show_log_level = %.*s", STR_ARG(STR_BOOL(console->cfg.show_log_level))); str_list_push_fmt(arena, lines, "position = %.*s", STR_ARG(ui_console_position_to_str(console->cfg.position))); str_list_push_fmt(arena, lines, "min_level = %.*s", STR_ARG(ui_console_log_level_to_str(console->cfg.min_level))); } @@ -335,6 +495,14 @@ ui_console_cfg_is_dirty(ui_console_t *console) return true; } + if (console->cfg.show_timestamp != console->saved_cfg.show_timestamp) { + return true; + } + + if (console->cfg.show_log_level != console->saved_cfg.show_log_level) { + return true; + } + if (console->cfg.position != console->saved_cfg.position) { return true; } @@ -348,41 +516,93 @@ ui_console_cfg_is_dirty(ui_console_t *console) } void -ui_console_logv(ui_console_t *console, ui_console_log_level_t level, const char *fmt, va_list ap) +ui_console_append_log(ui_console_t *console, const log_message_t *message) { - if (!console->inited) { - return; - } + ASSERT(unreal_is_in_game_thread()); + + char timestamp[UI_CONSOLE_TIMESTAMP_CAP]; + ui_console_message_timestamp(message, timestamp); tmp_arena_t tmp = scratch_begin(NULL); { - str_t msg = str_push_vfmt(tmp.arena, fmt, ap); - str_list_t lines = str_split_lines(tmp.arena, msg); + str_list_t lines = str_split_lines(tmp.arena, message->text); + for (str_node_t *node = lines.first; node; node = node->next) { - ui_console_store_line(console, level, node->str); + ui_console_store_line(console, ui_console_level_from_log(message->level), node->str, timestamp); } } scratch_end(tmp); } +void +ui_console_flush_logs(ui_console_t *console) +{ + if (!unreal_is_in_game_thread()) { + return; + } + + if (console->inited) { + log_ui_flush(console); + } +} + +static log_level_t +ui_console_level_from_unreal(elog_verbosity_type_t verbosity) +{ + switch (verbosity & ELVT_VERBOSITY_MASK) { + case ELVT_FATAL: + case ELVT_ERROR: { + return LOG_LEVEL_ERROR; + } + + case ELVT_WARNING: { + return LOG_LEVEL_WARN; + } + + case ELVT_VERBOSE: + case ELVT_VERY_VERBOSE: { + return LOG_LEVEL_DEBUG; + } + + default: { + return LOG_LEVEL_INFO; + } + } +} + +static void +ui_console_unreal_output(void *user, str_t text, elog_verbosity_type_t verbosity) +{ + (void)user; + log_ui_enqueue(ui_console_level_from_unreal(verbosity), text); +} + static bool ui_console_execute_builtin(ui_console_t *console, mod_manager_t *mod_manager, str_t cmd_name, str_t cmd_args) { - (void)console; - (void)cmd_args; - if (str_equal(cmd_name, STR_LIT("help"), STR_CMP_FLAG_IGNORE_CASE)) { CONSOLE_INFO("Overdub commands:"); CONSOLE_INFO(" :help - List available commands"); + CONSOLE_INFO(" :unreal - Execute an Unreal console command"); CONSOLE_INFO("Enter Lua expressions or statements without a prefix."); for (int i = 0; i < mod_manager->mod_order.count; ++i) { mod_handle_t h = mod_manager->mod_order.runtime[i]; mod_t *m = mod_handle_resolve(mod_manager, h); - if (m && m->has_code && m->dll.command_count > 0) { + + str_t lua_commands[CONFIG_NK_CONSOLE_MAX_COMMANDS]; + int lua_command_count = lua_mod_runtime_snapshot_commands(m, lua_commands, COUNTOF(lua_commands)); + int dll_command_count = m && m->has_code && m->dll.active ? m->dll.command_count : 0; + + if (m && (lua_command_count > 0 || dll_command_count > 0)) { CONSOLE_INFO("Commands provided by '%.*s':", STR_ARG(m->manifest.info.name)); - for (int i = 0; i < m->dll.command_count; ++i) { - mod_cmd_t *cmd = &m->dll.commands[i]; + + for (int j = 0; j < lua_command_count; ++j) { + CONSOLE_INFO(" :%.*s - Lua command", STR_ARG(lua_commands[j])); + } + + for (int j = 0; j < dll_command_count; ++j) { + mod_cmd_t *cmd = &m->dll.commands[j]; CONSOLE_INFO(" :%.*s - %.*s", STR_ARG(cmd->name), STR_ARG(cmd->description)); } } @@ -390,6 +610,19 @@ ui_console_execute_builtin(ui_console_t *console, mod_manager_t *mod_manager, st return true; } + if (str_equal(cmd_name, STR_LIT("unreal"), STR_CMP_FLAG_IGNORE_CASE)) { + if (str_is_empty(cmd_args)) { + CONSOLE_ERROR("Usage: :unreal "); + return true; + } + + if (!unreal_execute_console_command(cmd_args, ui_console_unreal_output, console)) { + CONSOLE_ERROR("Unreal console command execution is unavailable"); + } + + return true; + } + return false; } @@ -442,6 +675,8 @@ ui_console_draw_lines(ui_console_t *console, struct nk_context *ctx) return; } + ui_console_update_prefixes(console); + int total = console->line_count; int visible = MIN_VAL(total, console->max_lines); int start = MAX_VAL(0, total - visible); @@ -455,6 +690,7 @@ ui_console_draw_lines(ui_console_t *console, struct nk_context *ctx) continue; } + str_t text = line->display_text; struct nk_color level_color = ui_console_level_color(line->level); struct nk_text_options options = { .alignment = NK_TEXT_LEFT, @@ -465,10 +701,14 @@ ui_console_draw_lines(ui_console_t *console, struct nk_context *ctx) if (console->cfg.wrap_lines) { options.flags |= NK_TEXT_OPTION_WRAP | NK_TEXT_OPTION_AUTO_HEIGHT; } else { + if (line->row_w == 0.0f) { + line->row_w = ui_text_width(ctx, text); + } + nk_layout_row_static(ctx, CONFIG_NK_CONSOLE_LINE_HEIGHT, (int)line->row_w, 1); } - ui_str_ex(ctx, line->text, &options); + ui_str_ex(ctx, text, &options); shown += 1; } @@ -478,14 +718,17 @@ ui_console_draw_lines(ui_console_t *console, struct nk_context *ctx) } } -static void +static bool ui_console_draw_log_widget(ui_console_t *console, struct nk_context *ctx) { + bool selection_active = false; + if (nk_group_scrolled_begin(ctx, &console->scroll, "console.log", 0)) { if (console->cfg.wrap_lines) { console->scroll.x = 0; } ui_console_draw_lines(console, ctx); + selection_active = ctx->current->layout->text_selection.selection.active; nk_group_scrolled_end(ctx); } @@ -495,10 +738,12 @@ ui_console_draw_log_widget(ui_console_t *console, struct nk_context *ctx) } console->scroll_to_bottom = false; } + + return selection_active; } static void -ui_console_draw_cmd_widget(ui_console_t *console, mod_manager_t *mod_manager, struct nk_context *ctx) +ui_console_draw_cmd_widget(ui_console_t *console, mod_manager_t *mod_manager, struct nk_context *ctx, bool log_selection_active) { struct nk_input *in = &ctx->input; @@ -513,7 +758,7 @@ ui_console_draw_cmd_widget(ui_console_t *console, mod_manager_t *mod_manager, st } } - if (console->focus_input) { + if (console->focus_input || nk_window_is_active(ctx, CONFIG_UI_CONSOLE_WINDOW_NAME)) { nk_edit_focus(ctx, NK_EDIT_ALWAYS_INSERT_MODE); console->focus_input = false; } @@ -522,21 +767,58 @@ ui_console_draw_cmd_widget(ui_console_t *console, mod_manager_t *mod_manager, st int max = console->input_max; char *buf = (char *)console->input_buf; + enum nk_keys log_selection_keys[] = { + NK_KEY_COPY, + NK_KEY_LEFT, + NK_KEY_RIGHT, + NK_KEY_TEXT_SELECT_ALL, + NK_KEY_TEXT_WORD_LEFT, + NK_KEY_TEXT_WORD_RIGHT, + }; + + struct nk_key saved_log_selection_keys[COUNTOF(log_selection_keys)]; + struct nk_key text_end_key = in->keyboard.keys[NK_KEY_TEXT_END]; + struct nk_key shift_key = in->keyboard.keys[NK_KEY_SHIFT]; + + for (int i = 0; i < COUNTOF(log_selection_keys); ++i) { + enum nk_keys key = log_selection_keys[i]; + saved_log_selection_keys[i] = in->keyboard.keys[key]; + if (log_selection_active) { + in->keyboard.keys[key].clicked = 0; + } + } + + if (history_changed) { + struct nk_edit_state *edit_state = &ctx->current->edit; + edit_state->cursor = 0; + edit_state->sel_start = 0; + edit_state->sel_end = 0; + in->keyboard.keys[NK_KEY_SHIFT] = (struct nk_key){0}; + + if (input_len > 0) { + in->keyboard.keys[NK_KEY_TEXT_END] = (struct nk_key){.down = nk_true, .clicked = 1}; + } else { + edit_state->scrollbar.x = 0; + } + } + nk_flags flags = - (nk_flags)NK_EDIT_FIELD | - NK_EDIT_SELECTABLE | - NK_EDIT_CLIPBOARD | - NK_EDIT_SIG_ENTER | + (nk_flags)NK_EDIT_FIELD | + NK_EDIT_SELECTABLE | + NK_EDIT_CLIPBOARD | + NK_EDIT_SIG_ENTER | NK_EDIT_GOTO_END_ON_ACTIVATE | NK_EDIT_ALWAYS_INSERT_MODE; nk_flags edit = nk_edit_string(ctx, flags, buf, &input_len, max, nk_filter_default); - console->input = str_make(console->input_buf, (uint64_t)input_len); - - if (history_changed) { - console->input = str_make(console->input_buf, console->input.len); + for (int i = 0; i < COUNTOF(log_selection_keys); ++i) { + in->keyboard.keys[log_selection_keys[i]] = saved_log_selection_keys[i]; } + in->keyboard.keys[NK_KEY_TEXT_END] = text_end_key; + in->keyboard.keys[NK_KEY_SHIFT] = shift_key; + + console->input = str_make(console->input_buf, (uint64_t)input_len); if (edit & NK_EDIT_COMMITED) { ui_console_execute(console, mod_manager, console->input); @@ -682,23 +964,14 @@ ui_console_update_handle(ui_console_t *console, } void -ui_console_compute_row_widths(ui_console_t *console, struct nk_context *ctx) +ui_console_draw(ui_console_t *console, struct nk_context *ctx, mod_manager_t *mod_manager, unsigned int viewport_width, unsigned int viewport_height) { - if (!console->lines || console->cfg.wrap_lines) { + if (!unreal_is_in_game_thread()) { return; } - for (int i = 0; i < console->line_count; ++i) { - ui_console_line_t *line = &console->lines[i % console->max_lines]; - if (line->row_w == 0.0f) { - line->row_w = ui_text_width(ctx, line->text); - } - } -} + ui_console_flush_logs(console); -void -ui_console_draw(ui_console_t *console, struct nk_context *ctx, mod_manager_t *mod_manager, unsigned int viewport_width, unsigned int viewport_height) -{ if (!console->inited || !ctx) { return; } @@ -726,8 +999,6 @@ ui_console_draw(ui_console_t *console, struct nk_context *ctx, mod_manager_t *mo if (nk_begin(ctx, CONFIG_UI_CONSOLE_WINDOW_NAME, bounds, flags)) { struct nk_rect content = nk_window_get_content_region(ctx); - ui_console_compute_row_widths(console, ctx); - float pad_y = ctx->style.window.padding.y; float gap_y = ctx->style.window.spacing.y; float gap_x = ctx->style.window.spacing.x; @@ -772,10 +1043,10 @@ ui_console_draw(ui_console_t *console, struct nk_context *ctx, mod_manager_t *mo ui_console_draw_handle(console, ctx); nk_layout_space_push(ctx, log_r); - ui_console_draw_log_widget(console, ctx); + bool log_selection_active = ui_console_draw_log_widget(console, ctx); nk_layout_space_push(ctx, input_r); - ui_console_draw_cmd_widget(console, mod_manager, ctx); + ui_console_draw_cmd_widget(console, mod_manager, ctx, log_selection_active); nk_layout_space_push(ctx, level_r); ui_console_draw_level_selector(console, ctx, level_r.w); diff --git a/src/ui_manager.c b/src/ui_manager.c index ef4d8dc..b60620f 100644 --- a/src/ui_manager.c +++ b/src/ui_manager.c @@ -458,6 +458,44 @@ is_any_window_interactive(struct nk_context *ctx) return is_any_window(ctx, 0, NK_WINDOW_CLOSED | NK_WINDOW_HIDDEN | NK_WINDOW_MINIMIZED | NK_WINDOW_NOT_INTERACTIVE); } +static inline bool +window_captures_keyboard(struct nk_window *win) +{ + if (!win) { + return false; + } + + if (win->edit.active) { + return true; + } + + bool popup_active = win->popup.active && win->popup.win; + if (!popup_active) { + return false; + } + + if (win->popup.type == NK_PANEL_COMBO) { + return true; + } + + return win->popup.win->edit.active; +} + +static bool +is_any_keyboard_capture_active(struct nk_context *ctx) +{ + ASSERT(ctx != NULL); + + for (struct nk_window *win = ctx->begin; win; win = win->next) { + if (!(win->flags & (NK_WINDOW_CLOSED | NK_WINDOW_HIDDEN | (enum nk_window_flags)NK_WINDOW_NO_INPUT)) && + window_captures_keyboard(win)) { + return true; + } + } + + return false; +} + bool ui_manager_should_show_cursor(ui_manager_t *manager) { @@ -534,6 +572,10 @@ ui_manager_should_consume_input_pre(ui_manager_t *manager, input_event_t *ev) return true; } + if (input_event_is_keyboard(ev) && is_any_keyboard_capture_active(manager->ctx)) { + return true; + } + if (is_any_window_open(manager->ctx)) { if (input_event_is_mouse(ev)) { return ui_manager_mouse_event_should_consume(manager, ev); @@ -792,6 +834,8 @@ ui_manager_on_input_event_post(ui_manager_t *manager, input_event_t *ev) void ui_manager_on_frame_begin(ui_manager_t *manager, uint64_t frame_counter) { + ui_console_on_frame_begin(&manager->console, frame_counter); + if (!manager->inited || !manager->ctx) { return; } diff --git a/src/ui_mod_manager.c b/src/ui_mod_manager.c index c6b4f16..8f35e39 100644 --- a/src/ui_mod_manager.c +++ b/src/ui_mod_manager.c @@ -2,6 +2,7 @@ #include "arena.h" #include "config.h" #include "globals.h" +#include "lua_mod_runtime.h" #include "mod_manager.h" #include "scratch.h" #include "str.h" @@ -428,11 +429,13 @@ form_console_cfg(struct nk_context *ctx, ui_keybind_capture_t *capture, ui_conso ui_console_cfg_t *cfg = &console->cfg; ui_console_cfg_t *saved_cfg = &console->saved_cfg; - form_keybind(ctx, &grid_state, capture, STR_LIT("Console shortcut: "), STR_LIT("Shortcut that opens or closes the console"), STR_LIT("console.toggle_keybind"), &saved_cfg->toggle_bind, &cfg->toggle_bind); - form_bool (ctx, &grid_state, STR_LIT("Auto-scroll: "), STR_LIT("Scroll to the newest message when console output changes"), &saved_cfg->auto_scroll, &cfg->auto_scroll); - form_bool (ctx, &grid_state, STR_LIT("Wrap lines: "), STR_LIT("Wrap long console output to the visible width"), &saved_cfg->wrap_lines, &cfg->wrap_lines); - form_enum (ctx, &grid_state, STR_LIT("Position: "), STR_LIT("Place the console at the top or bottom of the screen"), &saved_cfg->position, &cfg->position, ui_console_position_str_array()); - form_enum (ctx, &grid_state, STR_LIT("Minimum log level: "), STR_LIT("Hide messages below the selected severity"), &saved_cfg->min_level, &cfg->min_level, ui_console_log_level_str_array()); + form_keybind(ctx, &grid_state, capture, STR_LIT("Console shortcut: "), STR_LIT("Shortcut that opens or closes the console"), STR_LIT("console.toggle_keybind"), &saved_cfg->toggle_bind, &cfg->toggle_bind); + form_bool (ctx, &grid_state, STR_LIT("Auto-scroll: "), STR_LIT("Scroll to the newest message when console output changes"), &saved_cfg->auto_scroll, &cfg->auto_scroll); + form_bool (ctx, &grid_state, STR_LIT("Wrap lines: "), STR_LIT("Wrap long console output to the visible width"), &saved_cfg->wrap_lines, &cfg->wrap_lines); + form_bool (ctx, &grid_state, STR_LIT("Show timestamp: "), STR_LIT("Show local date/time and the frame within the second (#000 is the first frame)"), &saved_cfg->show_timestamp, &cfg->show_timestamp); + form_bool (ctx, &grid_state, STR_LIT("Show log level: "), STR_LIT("Prefix messages with [DBG], [INF], [WRN], or [ERR]"), &saved_cfg->show_log_level, &cfg->show_log_level); + form_enum (ctx, &grid_state, STR_LIT("Position: "), STR_LIT("Place the console at the top or bottom of the screen"), &saved_cfg->position, &cfg->position, ui_console_position_str_array()); + form_enum (ctx, &grid_state, STR_LIT("Minimum log level: "), STR_LIT("Hide messages below the selected severity"), &saved_cfg->min_level, &cfg->min_level, ui_console_log_level_str_array()); return ui_console_cfg_is_dirty(console); } @@ -508,6 +511,10 @@ mod_status_text(mod_t *m, arena_t *arena) str_list_push(tmp.arena, &parts, STR_LIT("Code")); } + if (m->has_lua && m->lua.err_msg.len > 0) { + str_list_push(tmp.arena, &parts, STR_LIT("Lua")); + } + if (m->has_blueprints) { for (int i = 0; i < m->blueprint_count; ++i) { if (m->blueprints[i].err_stage != MOD_BP_ERROR_NONE) { @@ -720,15 +727,39 @@ draw_mod_header(ui_mod_manager_t *ui, struct nk_context *ctx, mod_manager_t *man scratch_end(tmp); } +static bool +draw_custom_config(struct nk_context *ctx, mod_t *m) +{ + bool drawn = false; + if (m->has_code && m->dll.funcs.draw_config) { + m->dll.funcs.draw_config(mod_handle_make(m), ctx); + drawn = true; + } + + if (m->has_lua && m->lua.active && lua_mod_runtime_draw_config(m, ctx)) { + drawn = true; + } + + return drawn; +} + +static bool +has_custom_config(mod_t *m) +{ + if (m->has_code && m->dll.funcs.draw_config) { + return true; + } + + return m->has_lua && m->lua.active && lua_mod_runtime_has_draw_config(m); +} + static void draw_config_section(ui_mod_manager_t *ui, struct nk_context *ctx, mod_manager_t *manager, mod_t *m) { static struct nk_grid_state option_grid_state = {0}; tmp_arena_t tmp = scratch_begin(NULL); if (nk_tree_state_push(ctx, NK_TREE_TAB, "Config", &ui->inspector.options_open)) { - if (m->has_code && m->dll.funcs.draw_config) { - m->dll.funcs.draw_config(mod_handle_make(m), ctx); - } else { + if (!draw_custom_config(ctx, m)) { bool dirty = false; if (m->has_options) { @@ -918,6 +949,32 @@ draw_assets_section(ui_mod_manager_t *ui, struct nk_context *ctx, mod_manager_t } } +static void +draw_lua_section(ui_mod_manager_t *ui, struct nk_context *ctx, mod_t *m) +{ + static struct nk_grid_state info_grid = {0}; + static struct nk_grid_state runtime_grid = {0}; + + if (nk_tree_state_push(ctx, NK_TREE_TAB, "Lua", &ui->inspector.lua_open)) { + if (nk_tree_state_push(ctx, NK_TREE_NODE, "Script info", &ui->inspector.lua_info_open)) { + draw_key_value(ctx, &info_grid, STR_LIT("Entry:"), m->manifest.lua.path, UI_C_TEXT, false); + draw_key_value(ctx, &info_grid, STR_LIT("Lua runtime:"), mod_lua_runtime_kind_to_str(m->manifest.lua.runtime_kind), UI_C_TEXT, false); + nk_tree_pop(ctx); + } + + if (nk_tree_state_push(ctx, NK_TREE_NODE, "Runtime", &ui->inspector.lua_runtime_open)) { + draw_key_value(ctx, &runtime_grid, STR_LIT("Running:"), STR_BOOL(m->lua.active), m->lua.active ? UI_C_GREEN : UI_C_RED, false); + if (m->lua.err_msg.len > 0) { + draw_key_value(ctx, &runtime_grid, STR_LIT("Error:"), err_msg_as_str(m->lua.err_msg), UI_C_RED, false); + } + nk_tree_pop(ctx); + } + + nk_tree_pop(ctx); + draw_spacer(ctx, 6.0f); + } +} + static void draw_blueprints_section(ui_mod_manager_t *ui, struct nk_context *ctx, mod_manager_t *manager, mod_t *m) { @@ -1088,6 +1145,14 @@ dialog_close(ui_mod_manager_t *ui) ui->dialog.kind = UI_DIALOG_NONE; } +static void +dialog_keep_above_manager(struct nk_context *ctx, const char *dialog_name) +{ + if (nk_window_is_active(ctx, "mod_manager")) { + nk_window_set_focus(ctx, dialog_name); + } +} + static void draw_config_dialog(ui_mod_manager_t *ui, struct nk_context *ctx, mod_manager_t *manager) { @@ -1101,6 +1166,8 @@ draw_config_dialog(ui_mod_manager_t *ui, struct nk_context *ctx, mod_manager_t * const float min_w = 460.0f; const float min_h = 240.0f; + dialog_keep_above_manager(ctx, name); + if (nk_begin(ctx, name, ui->dialog.config_win.bounds, flags)) { struct nk_rect content = nk_window_get_content_region(ctx); float gap_y = ctx->style.window.spacing.y; @@ -1254,6 +1321,8 @@ draw_reorder_dialog(ui_mod_manager_t *ui, struct nk_context *ctx, mod_manager_t const float min_w = 420.0f; const float min_h = 320.0f; + dialog_keep_above_manager(ctx, name); + if (nk_begin(ctx, name, ui->dialog.reorder_win.bounds, flags)) { ui_win_clamp_bounds(ctx, name, nk_vec2(min_w, min_h), nk_vec2((float)ui->vw, (float)ui->vh)); draw_reorder_content(ui, ctx, manager); @@ -1300,7 +1369,7 @@ draw_right_panel(ui_mod_manager_t *ui, struct nk_context *ctx, mod_manager_t *ma draw_mod_header(ui, ctx, manager, m); - if (m->has_options || m->has_blueprints || (m->has_code && m->dll.funcs.draw_config)) { + if (m->has_options || m->has_blueprints || has_custom_config(m)) { draw_config_section(ui, ctx, manager, m); } @@ -1308,6 +1377,10 @@ draw_right_panel(ui_mod_manager_t *ui, struct nk_context *ctx, mod_manager_t *ma draw_code_section(ui, ctx, manager, m); } + if (m->has_lua) { + draw_lua_section(ui, ctx, m); + } + if (m->has_assets) { draw_assets_section(ui, ctx, manager, m); } @@ -1320,7 +1393,11 @@ draw_right_panel(ui_mod_manager_t *ui, struct nk_context *ctx, mod_manager_t *ma m->dll.funcs.draw_panel(mod_handle_make(m), ctx); } - if (!m->has_options && !m->has_code && !m->has_assets && !m->has_blueprints) { + if (m->has_lua && m->lua.active) { + lua_mod_runtime_draw_panel(m, ctx); + } + + if (!m->has_options && !m->has_code && !m->has_lua && !m->has_assets && !m->has_blueprints) { nk_layout_row_dynamic(ctx, 20.0f, 1); nk_label(ctx, "This mod does not expose any settings or runtime controls", NK_TEXT_LEFT); } @@ -1537,6 +1614,9 @@ ui_mod_manager_init(ui_mod_manager_t *ui, ui_keybind_capture_t *cap) .code_open = NK_MAXIMIZED, .code_dll_info_open = NK_MINIMIZED, .code_runtime_open = NK_MAXIMIZED, + .lua_open = NK_MAXIMIZED, + .lua_info_open = NK_MINIMIZED, + .lua_runtime_open = NK_MAXIMIZED, .blueprints_open = NK_MAXIMIZED, .blueprints_info_open = NK_MINIMIZED, .blueprints_runtime_open = NK_MAXIMIZED, diff --git a/src/unreal.c b/src/unreal.c index 53a65ea..07590ca 100644 --- a/src/unreal.c +++ b/src/unreal.c @@ -17,6 +17,12 @@ STATIC_ASSERT(_Alignof(fcritical_section_t) == _Alignof(CRITICAL_SECTION), "crit TMAP_DEFINE_FUNCS(unreal_tmap_fname_uint8ptr, tmap_fname_uint8ptr_t, fname_t, uint8_t *, TMAP_FNAME_UINT8PTR_KEY_EQUAL, TMAP_FNAME_UINT8PTR_KEY_HASH) +bool +unreal_is_in_game_thread(void) +{ + return globals.game_thread_id != 0 && globals.game_thread_id == thread_current_id(); +} + /* ===================================================== FNAME ====================================================== */ fname_pool_t * @@ -171,17 +177,12 @@ fname_t unreal_fname_from_str(str_t s, efind_name_t find_type) { fname_t fname = {0}; -#if !defined BUILD_TEST_UI tmp_arena_t tmp = scratch_begin(NULL); { str16_t s16 = str16_from_str(tmp.arena, s); fname_construct(&fname, (const wchar_t *)s16.data, find_type); } scratch_end(tmp); -#else - (void)s; - (void)find_type; -#endif return fname; } @@ -617,6 +618,12 @@ unreal_common_collect(unreal_common_t *common) common->data_asset = (uclass_t *)obj; } else if (str_equal(full_name, STR_LIT("/Script/Engine.DataTable"), 0)) { common->data_table = (uclass_t *)obj; + } else if (str_equal(full_name, STR_LIT("/Script/Engine.KismetSystemLibrary"), 0)) { + common->kismet_sys_lib_cls = (uclass_t *)obj; + } else if (str_equal(full_name, STR_LIT("/Script/Engine.Default__KismetSystemLibrary"), 0)) { + common->kismet_sys_lib_cdo = obj; + } else if (str_equal(full_name, STR_LIT("/Script/Engine.KismetSystemLibrary.ExecuteConsoleCommand"), 0)) { + common->exec_console_cmd = (ufunc_t *)obj; } else if (str_equal(full_name, STR_LIT("/Script/Engine.Default__GameplayStatics"), 0)) { common->gameplay_statics_cdo = obj; } else if (str_equal(full_name, STR_LIT("/Script/Engine.GameplayStatics.BeginDeferredActorSpawnFromClass"), 0)) { @@ -625,6 +632,8 @@ unreal_common_collect(unreal_common_t *common) common->finish_spawn = (ufunc_t *)obj; } else if (str_equal(full_name, STR_LIT("/Script/Engine.Actor.K2_DestroyActor"), 0)) { common->destroy_actor = (ufunc_t *)obj; + } else if (str_equal(full_name, STR_LIT("/Engine/Transient"), 0)) { + common->transient_package = obj; } scratch_end(tmp); } @@ -767,7 +776,6 @@ unreal_common_collect(unreal_common_t *common) fuobject_item_t * unreal_uobject_array_get_item(int idx) { -#if !defined BUILD_TEST_UI MASSERT(globals.uobjects != NULL, "uobject array is missing"); fchunked_fixed_uobject_array_t *a = &globals.uobjects->obj_objs; @@ -788,10 +796,6 @@ unreal_uobject_array_get_item(int idx) } return &chunk[within_idx]; -#else - (void)idx; - return false; -#endif } bool @@ -844,6 +848,53 @@ unreal_uclass_is_child_of(uclass_t *child, uclass_t *parent) return false; } +static bool +unreal_uclass_find_interface(uclass_t *cls, uclass_t *interface_cls, bool native, int32_t *out_offset) +{ + bool valid = cls && interface_cls && (interface_cls->class_flags & CLASS_INTERFACE); + bool found = false; + for (uclass_t *current = cls; current && valid && !found; current = (uclass_t *)current->super_struct) { + tarray_fimplemented_interface_t *interfaces = ¤t->interfaces; + valid = interfaces->num >= 0 && interfaces->max >= interfaces->num && interfaces->num <= 4096; + if (valid) { + valid = interfaces->num == 0 || interfaces->data; + } + + for (int32_t i = 0; i < interfaces->num && valid && !found; ++i) { + fimplemented_interface_t *entry = &interfaces->data[i]; + bool matches = entry->cls && unreal_uclass_is_child_of(entry->cls, interface_cls); + if (matches && (!native || !entry->implemented_by_k2)) { + found = true; + if (out_offset) { + *out_offset = entry->pointer_offset; + } + } + } + } + return found; +} + +bool +unreal_uclass_implements_interface(uclass_t *cls, uclass_t *interface_cls) +{ + return unreal_uclass_find_interface(cls, interface_cls, false, NULL); +} + +void * +unreal_uobject_get_interface_address(uobject_t *obj, uclass_t *interface_cls) +{ + void *result = NULL; + bool native = interface_cls && (interface_cls->class_flags & CLASS_NATIVE); + int32_t offset = 0; + bool found = obj && unreal_uclass_find_interface(obj->cls, interface_cls, native, &offset); + if (found && native) { + result = (uint8_t *)obj + offset; + } else if (found) { + result = obj; + } + return result; +} + bool unreal_uobject_is_default(uobject_t *obj) { @@ -993,102 +1044,114 @@ unreal_uobject_push_full_name(uobject_t *obj, arena_t *arena) return result; } +str_t +unreal_uobject_push_ue_path_name(uobject_t *obj, arena_t *arena) +{ + str_t result = STR_NULL; + if (obj) { + uint64_t len = unreal_uobject_get_full_name_len(obj); + if (len > 0) { + uint8_t *buf = ARENA_PUSH_ARRAY(arena, uint8_t, len + 1); + if (buf) { + tmp_arena_t tmp = scratch_begin(arena); + { + uint64_t depth = 0; + for (uobject_t *cur = obj; cur; cur = cur->outer) { + depth += 1; + } + + uobject_t **chain = ARENA_PUSH_ARRAY(tmp.arena, uobject_t *, depth); + uint64_t i = depth; + for (uobject_t *cur = obj; cur; cur = cur->outer) { + chain[--i] = cur; + } + + uint64_t written = 0; + for (i = 0; i < depth; ++i) { + if (i > 0) { + uobject_t *outer = chain[i - 1]; + bool first_subobject = globals.unreal.core_package && outer->cls != globals.unreal.core_package && + outer->outer && outer->outer->cls == globals.unreal.core_package; + buf[written++] = first_subobject ? ':' : '.'; + } + + written += unreal_fname_utf8_write(buf + written, len - written, chain[i]->name); + } + MASSERT(written == len, "UE path-name length mismatch"); + } + scratch_end(tmp); + + buf[len] = '\0'; + result = str_make(buf, len); + } + } + } + return result; +} + int unreal_uobject_array_count(void) { -#if !defined BUILD_TEST_UI MASSERT(globals.uobjects != NULL, "uobject array is missing"); return globals.uobjects->obj_objs.num_elems; -#else - return 0; -#endif } int unreal_uobject_array_capacity(void) { -#if !defined BUILD_TEST_UI MASSERT(globals.uobjects != NULL, "uobject array is missing"); return globals.uobjects->obj_objs.max_elems; -#else - return 0; -#endif } int unreal_uobject_array_num_chunks(void) { -#if !defined BUILD_TEST_UI MASSERT(globals.uobjects != NULL, "uobject array is missing"); return globals.uobjects->obj_objs.num_chunks; -#else - return 0; -#endif } int unreal_uobject_array_max_chunks(void) { -#if !defined BUILD_TEST_UI MASSERT(globals.uobjects != NULL, "uobject array is missing"); return globals.uobjects->obj_objs.max_chunks; -#else - return 0; -#endif } int unreal_uobject_array_first_gc_index(void) { -#if !defined BUILD_TEST_UI MASSERT(globals.uobjects != NULL, "uobject array is missing"); return globals.uobjects->obj_first_cg_idx; -#else - return 0; -#endif } int unreal_uobject_array_last_non_gc_index(void) { -#if !defined BUILD_TEST_UI MASSERT(globals.uobjects != NULL, "uobject array is missing"); return globals.uobjects->obj_last_non_cg_idx; -#else - return 0; -#endif } bool unreal_uobject_array_is_open_for_disregard_for_gc(void) { -#if !defined BUILD_TEST_UI MASSERT(globals.uobjects != NULL, "uobject array is missing"); return globals.uobjects->open_for_disregard_for_gc; -#else - return 0; -#endif } static void add_uobject_create_listener(fuobject_listener_t *listener) { -#if !defined BUILD_TEST_UI MASSERT(globals.uobjects != NULL, "uobject array is missing"); int32_t idx = globals.uobjects->create_listeners.num++; if (globals.uobjects->create_listeners.num > globals.uobjects->create_listeners.max) { tarray_grow((void *)&globals.uobjects->create_listeners); } globals.uobjects->create_listeners.data[idx] = listener; -#else - (void)listener; -#endif } static void remove_uobject_create_listener(fuobject_listener_t *listener) { -#if !defined BUILD_TEST_UI MASSERT(globals.uobjects != NULL, "uobject array is missing"); tarray_fuobject_listener_t *arr = &globals.uobjects->create_listeners; int32_t num = arr->num; @@ -1108,15 +1171,11 @@ remove_uobject_create_listener(fuobject_listener_t *listener) arr->num = num - 1; tarray_shrink((void *)arr); } -#else - (void)listener; -#endif } static void remove_uobject_delete_listener(fuobject_listener_t *listener) { -#if !defined BUILD_TEST_UI EnterCriticalSection((LPCRITICAL_SECTION)&globals.uobjects->delete_listeners_critical); tarray_fuobject_listener_t *arr = &globals.uobjects->delete_listeners; @@ -1139,9 +1198,6 @@ remove_uobject_delete_listener(fuobject_listener_t *listener) } LeaveCriticalSection((LPCRITICAL_SECTION)&globals.uobjects->delete_listeners_critical); -#else - (void)listener; -#endif } void @@ -1228,14 +1284,12 @@ unreal_uobject_listener_add(uobject_listener_t *listener) ASSERT(listener != NULL); if (!listener->occupied) { -#if !defined BUILD_TEST_UI if (listener->kind == UOBJECT_LISTENER_KIND_CREATE) { add_uobject_create_listener((fuobject_listener_t *)listener); } else if (listener->kind == UOBJECT_LISTENER_KIND_DELETE) { ASSERT(add_uobject_delete_listener != NULL); add_uobject_delete_listener(globals.uobjects, (fuobject_listener_t *)listener); } -#endif listener->occupied = true; } } @@ -1404,38 +1458,312 @@ unreal_uobject_find_by_full_name(uclass_t *cls, str_t full_name) return NULL; } +static bool +unreal_uobject_path_matches(uobject_t *obj, str_t path_name) +{ + if (!obj || str_is_empty(path_name)) { + return false; + } + + uint64_t end = path_name.len; + for (uobject_t *current = obj; current; current = current->outer) { + uint64_t start = end; + while (start > 0 && path_name.data[start - 1] != '.' && path_name.data[start - 1] != ':') { + start -= 1; + } + + str_t component = str_make(path_name.data + start, end - start); + if (str_is_empty(component) || !unreal_fname_match_text(current->name, component, false, true)) { + return false; + } + + if (start == 0) { + return current->outer == NULL; + } + + end = start - 1; + } + return false; +} + +uobject_t * +unreal_uobject_find_by_path_name(uclass_t *cls, str_t path_name) +{ + for (int i = 0, count = unreal_uobject_array_count(); i < count; ++i) { + uobject_t *obj = unreal_uobject_array_get_obj(i); + if (obj && (!cls || unreal_uobject_is_a(obj, cls)) && unreal_uobject_path_matches(obj, path_name)) { + return obj; + } + } + return NULL; +} + +static fuobject_item_t * +unreal_uobject_get_live_item(uobject_t *obj) +{ + if (!obj) { + return NULL; + } + + fuobject_item_t *item = unreal_uobject_array_get_item(obj->internal_idx); + return item && unreal_uobject_array_item_is_valid(item) && item->obj == obj ? item : NULL; +} + +uint32_t +unreal_uobject_get_internal_flags(uobject_t *obj) +{ + fuobject_item_t *item = unreal_uobject_get_live_item(obj); + return item ? (uint32_t)item->flags : 0; +} + +bool +unreal_uobject_is_rooted(uobject_t *obj) +{ + fuobject_item_t *item = unreal_uobject_get_live_item(obj); + return item && (((uint32_t)item->flags & IOF_ROOT_SET) != 0); +} + +bool +unreal_uobject_add_to_root(uobject_t *obj) +{ + fuobject_item_t *item = unreal_uobject_get_live_item(obj); + if (!item) { + return false; + } + + InterlockedOr((volatile LONG *)&item->flags, (LONG)IOF_ROOT_SET); + return true; +} + +bool +unreal_uobject_remove_from_root(uobject_t *obj) +{ + fuobject_item_t *item = unreal_uobject_get_live_item(obj); + if (!item) { + return false; + } + + InterlockedAnd((volatile LONG *)&item->flags, (LONG)~IOF_ROOT_SET); + return true; +} + void unreal_process_event(uobject_t *self, ufunc_t *func, void *params) { -#if !defined BUILD_TEST_UI if (self && func) { process_event_real(self, func, params); } -#else - (void)self; - (void)func; - (void)params; -#endif } void unreal_process_event_observed(uobject_t *self, ufunc_t *func, void *params) { -#if !defined BUILD_TEST_UI if (self && self->vtable && self->vtable->process_event && func) { self->vtable->process_event(self, func, params); } -#else - (void)self; - (void)func; - (void)params; -#endif } +typedef struct unreal_console_output_s unreal_console_output_t; +struct unreal_console_output_s { + foutput_device_t base; + unreal_console_output_fn_t callback; + void *user; +}; + +static void __fastcall +unreal_console_output_destruct(foutput_device_t *base) +{ + (void)base; +} + +static void +unreal_console_output_emit(foutput_device_t *base, const wchar_t *text, elog_verbosity_type_t verbosity) +{ + unreal_console_output_t *output = (unreal_console_output_t *)base; + if (!output->callback || !text) { + return; + } + + tmp_arena_t tmp = scratch_begin(NULL); + { + str16_t text16 = str16_from_wstr_with_cap(text, 16384); + str_t text8 = str_from_str16(tmp.arena, text16); + + output->callback(output->user, text8, verbosity); + } + scratch_end(tmp); +} + +static void __fastcall +unreal_console_output_serialize_time(foutput_device_t *base, const wchar_t *text, elog_verbosity_type_t verbosity, const fname_t *category, const double time) +{ + (void)category; + (void)time; + unreal_console_output_emit(base, text, verbosity); +} + +static void __fastcall +unreal_console_output_serialize(foutput_device_t *base, const wchar_t *text, elog_verbosity_type_t verbosity, const fname_t *category) +{ + (void)category; + unreal_console_output_emit(base, text, verbosity); +} + +static void __fastcall +unreal_console_output_noop(foutput_device_t *base) +{ + (void)base; +} + +static void __fastcall +unreal_console_output_dump(foutput_device_t *base, void *archive) +{ + (void)base; + (void)archive; +} + +static bool __fastcall +unreal_console_output_true(foutput_device_t *base) +{ + (void)base; + return true; +} + +static bool __fastcall +unreal_console_output_false(foutput_device_t *base) +{ + (void)base; + return false; +} + +static foutput_device_vtable_t g_unreal_console_output_vtable = { + .destructor = unreal_console_output_destruct, + .serialize_time = unreal_console_output_serialize_time, + .serialize = unreal_console_output_serialize, + .flush = unreal_console_output_noop, + .tear_down = unreal_console_output_noop, + .dump = unreal_console_output_dump, + .is_memory_only = unreal_console_output_true, + .can_be_used_on_any_thread = unreal_console_output_false, + .can_be_used_on_multiple_threads = unreal_console_output_false, +}; + +static uobject_t * +unreal_find_local_player(uworld_t *world) +{ + uobject_t *fallback = NULL; + for (int i = 0; i < unreal_uobject_array_count(); ++i) { + uobject_t *object = unreal_uobject_array_get_obj(i); + if (!object) { + continue; + } + + bool is_local_player = unreal_uobject_is_a(object, globals.unreal.local_player); + if (!is_local_player || unreal_uobject_is_default(object)) { + continue; + } + + if (!fallback) { + fallback = object; + } + + if (!world || !object->vtable || !object->vtable->get_world) { + continue; + } + + if (object->vtable->get_world(object) == world) { + return object; + } + } + + return fallback; +} + +static bool +unreal_address_is_executable(void *address) +{ + MEMORY_BASIC_INFORMATION info = {0}; + if (!address || !VirtualQuery(address, &info, sizeof(info))) { + return false; + } + + DWORD protect = info.Protect & 0xff; + switch (protect) { + case PAGE_EXECUTE: + case PAGE_EXECUTE_READ: + case PAGE_EXECUTE_READWRITE: + case PAGE_EXECUTE_WRITECOPY: { + return true; + } + + default: { + return false; + } + } +} + +bool +unreal_execute_console_command(str_t command, unreal_console_output_fn_t callback, void *user) +{ + if (str_is_empty(command)) { + return false; + } + + uworld_t *world = unreal_get_current_world(); + uobject_t *local_player = unreal_find_local_player(world); + if (local_player) { + fexec_t *exec = (fexec_t *)((uint8_t *)local_player + sizeof(uobject_t)); + if (exec->vtable && unreal_address_is_executable((void *)exec->vtable->exec)) { + tmp_arena_t tmp = scratch_begin(NULL); + { + fstring_t cmd = unreal_fstring_from_str(command, tmp.arena); + unreal_console_output_t output = { + .base = { + .vftable = &g_unreal_console_output_vtable, + .auto_emit_line_terminator = true, + }, + .callback = callback, + .user = user, + }; + + bool handled = exec->vtable->exec(exec, world, (const wchar_t *)cmd.data, &output.base); + if (!handled) { + unreal_console_output_emit(&output.base, L"Command not recognized", ELVT_WARNING); + } + } + scratch_end(tmp); + return true; + } + } + + uobject_t *cdo = globals.unreal.kismet_sys_lib_cdo; + ufunc_t *func = globals.unreal.exec_console_cmd; + if (!cdo || !func) { + return false; + } + + tmp_arena_t tmp = scratch_begin(NULL); + { + execute_console_cmd_params_t params = { + .world_ctx_obj = (uobject_t *)world, + .cmd = unreal_fstring_from_str(command, tmp.arena), + }; + unreal_process_event_observed(cdo, func, ¶ms); + } + scratch_end(tmp); + return true; +} uobject_t * unreal_spawn_actor(uobject_t *world_ctx_obj, uclass_t *cls) { + bool valid_class = cls && globals.unreal.actor && unreal_uclass_is_child_of(cls, globals.unreal.actor); + bool ready = world_ctx_obj && valid_class && !(cls->class_flags & CLASS_ABSTRACT); + ready = ready && globals.unreal.gameplay_statics_cdo && globals.unreal.begin_spawn && globals.unreal.finish_spawn; + if (!ready) { + return NULL; + } + uobject_t *result = NULL; tmp_arena_t tmp = scratch_begin(NULL); { @@ -1458,22 +1786,14 @@ unreal_spawn_actor(uobject_t *world_ctx_obj, uclass_t *cls) .collision_handling_override = 3, }; - uobject_t *gameplay_statics_cdo = globals.unreal.gameplay_statics_cdo; - ufunc_t *begin_spawn = globals.unreal.begin_spawn; - ufunc_t *finish_spawn = globals.unreal.finish_spawn; - - MASSERT(gameplay_statics_cdo != NULL, "missing /Script/Engine.Default__GameplayStatics"); - MASSERT(begin_spawn != NULL, "missing /Script/Engine.GameplayStatics.BeginDeferredActorSpawnFromClass"); - MASSERT(finish_spawn != NULL, "missing /Script/Engine.GameplayStatics.FinishSpawningActor"); - - unreal_process_event(gameplay_statics_cdo, begin_spawn, p1); + unreal_process_event(globals.unreal.gameplay_statics_cdo, globals.unreal.begin_spawn, p1); if (p1->return_value) { *p2 = (finish_actor_spawn_params_t){ .actor = p1->return_value, - .spawn_transform = xf, + .spawn_transform = xf, }; - unreal_process_event(gameplay_statics_cdo, finish_spawn, p2); + unreal_process_event(globals.unreal.gameplay_statics_cdo, globals.unreal.finish_spawn, p2); if (p2->return_value) { result = (uobject_t *)p2->return_value; } @@ -1488,7 +1808,7 @@ void unreal_despawn_actor(uobject_t *actor) { ufunc_t *destroy_actor = globals.unreal.destroy_actor; - if (actor) { + if (actor && destroy_actor && globals.unreal.actor && unreal_uobject_is_a(actor, globals.unreal.actor)) { unreal_process_event(actor, destroy_actor, NULL); } } @@ -1502,6 +1822,34 @@ unreal_static_construct_object(fstatic_construct_obj_params_t *params) return static_construct_object(params); } +uobject_t * +unreal_get_transient_package(void) +{ + return globals.unreal.transient_package; +} + +uobject_t * +unreal_construct_object(uclass_t *cls, uobject_t *outer) +{ + if (!cls || !outer || (cls->class_flags & CLASS_ABSTRACT)) { + return NULL; + } + + if (globals.unreal.actor && unreal_uclass_is_child_of(cls, globals.unreal.actor)) { + return NULL; + } + + if (cls->class_within && !unreal_uobject_is_a(outer, cls->class_within)) { + return NULL; + } + + fstatic_construct_obj_params_t params = { + .cls = cls, + .outer = outer, + }; + return unreal_static_construct_object(¶ms); +} + uobject_t * unreal_static_load_object(uclass_t *obj_cls, uobject_t *outer, str_t name, str_t filename, uint32_t load_flags, void *sandbox, bool allow_obj_reconcile, void *instancing_ctx) { @@ -1515,18 +1863,7 @@ unreal_static_load_object(uclass_t *obj_cls, uobject_t *outer, str_t name, str_t const wchar_t *namew = str16_is_empty(name16) ? NULL : name16.data; const wchar_t *filenamew = str16_is_empty(filename16) ? NULL : filename16.data; -#if !defined BUILD_TEST_UI result = static_load_object(obj_cls, outer, namew, filenamew, load_flags, sandbox, allow_obj_reconcile, instancing_ctx); -#else - (void)filenamew; - (void)namew; - (void)obj_cls; - (void)outer; - (void)load_flags; - (void)sandbox; - (void)allow_obj_reconcile; - (void)instancing_ctx; -#endif } scratch_end(tmp); return result; @@ -1545,16 +1882,7 @@ unreal_static_load_class(uclass_t *base_cls, uobject_t *outer, str_t name, str_t const wchar_t *namew = str16_is_empty(name16) ? NULL : name16.data; const wchar_t *filenamew = str16_is_empty(filename16) ? NULL : filename16.data; -#if !defined BUILD_TEST_UI result = static_load_class(base_cls, outer, namew, filenamew, load_flags); -#else - (void)filenamew; - (void)namew; - (void)base_cls; - (void)outer; - (void)load_flags; -#endif - } scratch_end(tmp); return result; @@ -1631,7 +1959,6 @@ unreal_mount_pak(str_t file_path, int order) str16_t mount_file_path16 = str16_from_str(tmp.arena, mount_file_path); if (!str16_is_empty(mount_file_path16)) { -#if !defined BUILD_TEST_UI if (pak_only) { unreal_pak_only_mount_push(); } @@ -1639,10 +1966,6 @@ unreal_mount_pak(str_t file_path, int order) if (pak_only) { unreal_pak_only_mount_pop(); } -#else - (void)order; - (void)pak_only; -#endif } } } @@ -1694,14 +2017,7 @@ unreal_mount_iostore(str_t file_path, int order) faes_key_t enc_key = {0}; fio_status_t *result_status = NULL; -#if !defined BUILD_TEST_UI result_status = io_dispatcher_mount(globals.io_dispatcher, &status, &env, &enc_guid, &enc_key); -#else - (void)env; - (void)status; - (void)enc_guid; - (void)enc_key; -#endif result = (result_status && result_status->err_code == IO_ERROR_OK); } } @@ -1713,14 +2029,8 @@ unreal_mount_iostore(str_t file_path, int order) fnative_func_ptr_t unreal_get_native(uint8_t opcode) { - fnative_func_ptr_t func = NULL; -#if !defined BUILD_TEST_UI ASSERT(globals.natives != NULL); - func = globals.natives[opcode]; -#else - (void)opcode; -#endif - return func; + return globals.natives[opcode]; } bool @@ -1772,14 +2082,9 @@ unreal_ustruct_find_func_fname(ustruct_t *s, fname_t name, bool ignore_num) void * unreal_get_mcast_sparse_delegate(uobject_t *delegate_owner, fname_t delegate_name) { -#if !defined BUILD_TEST_UI if (get_mcast_sparse_delegate) { return get_mcast_sparse_delegate(delegate_owner, delegate_name); } -#else - (void)delegate_owner; - (void)delegate_name; -#endif return NULL; } diff --git a/src/unreal_prop.c b/src/unreal_prop.c index 510d4c6..9cf115b 100644 --- a/src/unreal_prop.c +++ b/src/unreal_prop.c @@ -46,6 +46,28 @@ typedef struct unreal_prop_script_interface_s { uobject_t *object; void *interface_ptr; } unreal_prop_script_interface_t; +STATIC_ASSERT(sizeof(unreal_prop_script_interface_t) == 0x10, "invalid script-interface size"); + +typedef const fmulticast_script_delegate_t *(__fastcall *unreal_mcast_get_fn_t) (fprop_mcast_delegate_t *prop, const void *value); +typedef void (__fastcall *unreal_mcast_set_fn_t) (fprop_mcast_delegate_t *prop, void *value, fmulticast_script_delegate_t delegate); +typedef void (__fastcall *unreal_mcast_add_fn_t) (fprop_mcast_delegate_t *prop, fscript_delegate_t delegate, uobject_t *owner, void *value); +typedef void (__fastcall *unreal_mcast_remove_fn_t) (fprop_mcast_delegate_t *prop, const fscript_delegate_t *delegate, uobject_t *owner, void *value); +typedef void (__fastcall *unreal_mcast_clear_fn_t) (fprop_mcast_delegate_t *prop, uobject_t *owner, void *value); +typedef fmulticast_script_delegate_t *(__fastcall *unreal_mcast_get_list_fn_t)(fprop_mcast_delegate_t *prop, const void *value); + +typedef struct unreal_mcast_vtable_s unreal_mcast_vtable_t; +struct unreal_mcast_vtable_s { + fprop_vtable_t base; + unreal_mcast_get_fn_t get; + unreal_mcast_set_fn_t set; + unreal_mcast_add_fn_t add; + unreal_mcast_remove_fn_t remove; + unreal_mcast_clear_fn_t clear; + unreal_mcast_get_list_fn_t get_list; +}; +STATIC_ASSERT(offsetof(unreal_mcast_vtable_t, get) == 0x130, "invalid multicast-delegate GetMulticastDelegate vtable offset"); +STATIC_ASSERT(offsetof(unreal_mcast_vtable_t, add) == 0x140, "invalid multicast-delegate AddDelegate vtable offset"); +STATIC_ASSERT(offsetof(unreal_mcast_vtable_t, remove) == 0x148, "invalid multicast-delegate RemoveDelegate vtable offset"); fprop_t * unreal_ustruct_find_prop(ustruct_t *s, str_t name) @@ -118,6 +140,20 @@ unreal_fprop_get_kind(fprop_t *prop) return UNREAL_PROP_KIND_UNKNOWN; } +unreal_func_param_role_t +unreal_fprop_get_param_role(fprop_t *prop) +{ + if (prop && (prop->prop_flags & CPF_RETURN_PARM)) { + return UNREAL_FUNC_PARAM_RETURN; + } + + if (prop && (prop->prop_flags & CPF_OUT_PARM) && !(prop->prop_flags & CPF_CONST_PARM)) { + return UNREAL_FUNC_PARAM_OUTPUT; + } + + return UNREAL_FUNC_PARAM_INPUT; +} + bool unreal_fprop_struct_is(fprop_t *prop, fname_t struct_name) { @@ -472,6 +508,83 @@ unreal_fprop_read_name(fprop_t *prop, const void *value, fname_t *out) return true; } +bool +unreal_fprop_read_string(fprop_t *prop, const void *value, arena_t *arena, str_t *out) +{ + if (!prop || !value || !arena || !out) { + return false; + } + + const fstring_t *string = NULL; + switch (unreal_fprop_get_kind(prop)) { + case UNREAL_PROP_KIND_STRING: { + if (prop->elem_size < (int32_t)sizeof(fstring_t)) { + return false; + } + string = (const fstring_t *)value; + break; + } + + case UNREAL_PROP_KIND_TEXT: { + if (prop->elem_size < (int32_t)sizeof(ftext_t)) { + return false; + } + + const ftext_t *text = (const ftext_t *)value; + if (!text->text_data.obj) { + *out = STR_NULL; + return true; + } + + itext_data_t *data = text->text_data.obj; + if (!data->vtable || !data->vtable->get_display_string) { + return false; + } + string = data->vtable->get_display_string(data); + break; + } + + default: { + return false; + } + } + + if (!string || string->len < 0 || string->len > 1024 * 1024 + 1 || (string->len > 0 && !string->data)) { + return false; + } + + *out = unreal_fstring_to_str(*string, arena); + return string->len <= 1 || out->data != NULL; +} + +bool +unreal_fprop_read_soft_path(fprop_t *prop, const void *value, arena_t *arena, str_t *out) +{ + if (!prop || !value || !arena || !out) { + return false; + } + + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + if ((kind != UNREAL_PROP_KIND_SOFT_OBJECT && kind != UNREAL_PROP_KIND_SOFT_CLASS) || + prop->elem_size < (int32_t)sizeof(unreal_prop_soft_object_ptr_t)) { + return false; + } + + const unreal_prop_soft_object_ptr_t *soft = (const unreal_prop_soft_object_ptr_t *)value; + + str_t asset = unreal_fname_to_str(soft->path.asset_path_name, arena); + str_t sub = unreal_fstring_to_str(soft->path.sub_path_string, arena); + if (str_is_empty(asset)) { + *out = STR_NULL; + } else if (str_is_empty(sub)) { + *out = asset; + } else { + *out = str_push_fmt(arena, "%.*s:%.*s", STR_ARG(asset), STR_ARG(sub)); + } + + return str_is_empty(asset) || out->data != NULL; +} + bool unreal_fprop_write_bool(fprop_t *prop, void *value, bool input) { @@ -711,6 +824,270 @@ unreal_fweak_object_resolve(fweak_object_ptr_t weak) return item->obj; } +bool +unreal_fweak_object_from_object(uobject_t *object, fweak_object_ptr_t *out) +{ + if (!object || !out || object->internal_idx < 0) { + return false; + } + + fuobject_item_t *item = unreal_uobject_array_get_item(object->internal_idx); + if (!item || item->obj != object || !unreal_uobject_array_item_is_valid(item)) { + return false; + } + + int32_t serial = item->serial_num; + if (serial <= 0) { + if (!globals.uobjects) { + return false; + } + + int32_t candidate = atomic_i32_increment(&globals.uobjects->master_serial_num.counter); + if (candidate <= 0) { + return false; + } + + int32_t existing = atomic_i32_compare_exchange(&item->serial_num, candidate, 0); + serial = existing > 0 ? existing : candidate; + } + + if (item->obj != object || item->serial_num != serial || !unreal_uobject_array_item_is_valid(item)) { + return false; + } + + *out = (fweak_object_ptr_t){ + .object_idx = object->internal_idx, + .object_serial = serial, + }; + return true; +} + +bool +unreal_ufunction_signature_compatible(ufunc_t *signature, ufunc_t *function) +{ + if (!signature || !function) { + return false; + } + + if (signature == function) { + return true; + } + + const eprop_flags_t ignored = CPF_PERSISTENT_INSTANCE | + CPF_EXPORT_OBJECT | + CPF_INSTANCED_REFERENCE | + CPF_CONTAINS_INSTANCED_REFERENCE | + CPF_IS_PLAIN_OLD_DATA | + CPF_NO_DESTRUCTOR | + CPF_ZERO_CONSTRUCTOR | + CPF_HAS_GET_VALUE_TYPE_HASH | + CPF_CONST_PARM | + CPF_UOBJECT_WRAPPER | + CPF_NATIVE_ACCESS_SPECIFIER_PUBLIC | + CPF_NATIVE_ACCESS_SPECIFIER_PROTECTED | + CPF_NATIVE_ACCESS_SPECIFIER_PRIVATE | + CPF_ADVANCED_DISPLAY | + CPF_BLUEPRINT_VISIBLE | + CPF_BLUEPRINT_READ_ONLY; + + fprop_t *signature_param = (fprop_t *)signature->child_props; + fprop_t *function_param = (fprop_t *)function->child_props; + + bool compatible = true; + while (compatible && signature_param && (signature_param->prop_flags & CPF_PARM)) { + compatible = function_param && (function_param->prop_flags & CPF_PARM); + if (!compatible) { + break; + } + + uint64_t signature_size = unreal_fprop_complete_size(signature_param); + uint64_t function_size = unreal_fprop_complete_size(function_param); + eprop_flags_t flag_diff = (signature_param->prop_flags ^ function_param->prop_flags) & ~ignored; + bool same_type = unreal_fprop_same_type(signature_param, function_param); + bool same_offset = signature_param->offset_internal == function_param->offset_internal; + + compatible = same_type && signature_size == function_size && same_offset && flag_diff == 0; + signature_param = (fprop_t *)signature_param->next; + function_param = (fprop_t *)function_param->next; + } + + if (function_param && (function_param->prop_flags & CPF_PARM)) { + compatible = false; + } + return compatible; +} + +ufunc_t * +unreal_fprop_delegate_signature(fprop_t *prop) +{ + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + + ufunc_t *signature = NULL; + if (kind == UNREAL_PROP_KIND_DELEGATE) { + signature = ((fprop_delegate_t *)prop)->signature_func; + } else if (kind == UNREAL_PROP_KIND_MULTICAST_INLINE_DELEGATE || kind == UNREAL_PROP_KIND_MULTICAST_SPARSE_DELEGATE) { + signature = ((fprop_mcast_delegate_t *)prop)->signature_func; + } + return signature; +} + +bool +unreal_fscript_delegate_make(fscript_delegate_t *out, uobject_t *target, ufunc_t *function) +{ + if (!out || !target || !target->cls || !function || (function->func_flags & FUNC_FLAG_STATIC)) { + return false; + } + + if (!globals.unreal.core_func || !unreal_uobject_is_a((uobject_t *)function, globals.unreal.core_func)) { + return false; + } + + ufunc_t *target_func = unreal_ustruct_find_func_fname((ustruct_t *)target->cls, function->name, false); + fweak_object_ptr_t weak = {0}; + if (target_func != function || !unreal_fweak_object_from_object(target, &weak)) { + return false; + } + + *out = (fscript_delegate_t){ + .object = weak, + .function_name = function->name, + }; + return true; +} + +static bool +unreal_fscript_delegate_equal(const fscript_delegate_t *left, const fscript_delegate_t *right) +{ + return left && right && left->object.object_idx == right->object.object_idx && left->object.object_serial == right->object.object_serial && + unreal_fname_equal(left->function_name, right->function_name, false); +} + +static bool +unreal_fprop_delegate_fits(uobject_t *owner, fprop_t *prop) +{ + if (!owner || !owner->cls || !prop || prop->array_dim != 1 || prop->offset_internal < 0) { + return false; + } + + bool linked = false; + for (fprop_t *current = ((ustruct_t *)owner->cls)->prop_link; current && !linked; current = current->prop_link_next) { + linked = current == prop; + } + + uint64_t complete = unreal_fprop_complete_size(prop); + uint64_t container_size = (uint64_t)((ustruct_t *)owner->cls)->props_size; + bool offset_valid = (uint64_t)prop->offset_internal <= container_size; + if (offset_valid) { + offset_valid = complete <= container_size - (uint64_t)prop->offset_internal; + } + return linked && complete > 0 && offset_valid; +} + +static fmulticast_script_delegate_t * +unreal_fprop_delegate_list(uobject_t *owner, fprop_t *prop) +{ + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + bool multicast = kind == UNREAL_PROP_KIND_MULTICAST_INLINE_DELEGATE || kind == UNREAL_PROP_KIND_MULTICAST_SPARSE_DELEGATE; + if (!multicast || !unreal_fprop_delegate_fits(owner, prop)) { + return NULL; + } + + unreal_mcast_vtable_t *vtable = (unreal_mcast_vtable_t *)prop->vtable; + void *value = unreal_fprop_value_in_container(prop, owner, 0); + fmulticast_script_delegate_t *list = NULL; + if (vtable && vtable->get && value) { + list = (fmulticast_script_delegate_t *)vtable->get((fprop_mcast_delegate_t *)prop, value); + } + return list; +} + +bool +unreal_fprop_delegate_contains(uobject_t *owner, fprop_t *prop, const fscript_delegate_t *binding) +{ + if (!binding || !unreal_fprop_delegate_fits(owner, prop)) { + return false; + } + + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + void *value = unreal_fprop_value_in_container(prop, owner, 0); + if (kind == UNREAL_PROP_KIND_DELEGATE) { + return unreal_fscript_delegate_equal((fscript_delegate_t *)value, binding); + } + + fmulticast_script_delegate_t *list = unreal_fprop_delegate_list(owner, prop); + bool found = false; + if (list && list->num >= 0 && list->num <= list->max && (list->num == 0 || list->data)) { + for (int32_t i = 0; i < list->num && !found; ++i) { + found = unreal_fscript_delegate_equal(&list->data[i], binding); + } + } + return found; +} + +bool +unreal_fprop_delegate_bind(uobject_t *owner, fprop_t *prop, const fscript_delegate_t *binding) +{ + if (!binding || !unreal_fprop_delegate_fits(owner, prop)) { + return false; + } + + uobject_t *target = unreal_fweak_object_resolve(binding->object); + ufunc_t *function = NULL; + ufunc_t *signature = unreal_fprop_delegate_signature(prop); + if (target && target->cls) { + function = unreal_ustruct_find_func_fname((ustruct_t *)target->cls, binding->function_name, false); + } + + if (!function || (function->func_flags & FUNC_FLAG_STATIC) || !unreal_ufunction_signature_compatible(signature, function)) { + return false; + } + + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + void *value = unreal_fprop_value_in_container(prop, owner, 0); + if (kind == UNREAL_PROP_KIND_DELEGATE) { + fscript_delegate_t *current = value; + bool has_function = current && (current->function_name.cmp_idx != 0 || current->function_name.num != 0); + bool occupied = has_function && unreal_fweak_object_resolve(current->object) != NULL; + if (occupied) { + return false; + } + + if (current) { + *current = *binding; + } + } else { + unreal_mcast_vtable_t *vtable = (unreal_mcast_vtable_t *)prop->vtable; + if (!vtable || !vtable->add || unreal_fprop_delegate_contains(owner, prop, binding)) { + return false; + } + + vtable->add((fprop_mcast_delegate_t *)prop, *binding, owner, NULL); + } + return unreal_fprop_delegate_contains(owner, prop, binding); +} + +bool +unreal_fprop_delegate_unbind(uobject_t *owner, fprop_t *prop, const fscript_delegate_t *binding) +{ + if (!unreal_fprop_delegate_contains(owner, prop, binding)) { + return false; + } + + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + void *value = unreal_fprop_value_in_container(prop, owner, 0); + if (kind == UNREAL_PROP_KIND_DELEGATE) { + *(fscript_delegate_t *)value = (fscript_delegate_t){0}; + } else { + unreal_mcast_vtable_t *vtable = (unreal_mcast_vtable_t *)prop->vtable; + if (!vtable || !vtable->remove) { + return false; + } + + vtable->remove((fprop_mcast_delegate_t *)prop, binding, owner, NULL); + } + return !unreal_fprop_delegate_contains(owner, prop, binding); +} + static str_t unreal_fstring_push_plain(const fstring_t *string, arena_t *arena) { @@ -1472,6 +1849,39 @@ unreal_fprop_get_referenced_object(fprop_t *prop, const void *value) } } +uclass_t * +unreal_fprop_get_reference_class(fprop_t *prop) +{ + if (!prop) { + return NULL; + } + + switch (unreal_fprop_get_kind(prop)) { + case UNREAL_PROP_KIND_CLASS: { + return ((fprop_class_t *)prop)->meta_class; + } + + case UNREAL_PROP_KIND_SOFT_CLASS: { + return ((fprop_class_soft_t *)prop)->meta_class; + } + + case UNREAL_PROP_KIND_OBJECT: + case UNREAL_PROP_KIND_SOFT_OBJECT: + case UNREAL_PROP_KIND_WEAK_OBJECT: + case UNREAL_PROP_KIND_LAZY_OBJECT: { + return ((fprop_obj_base_t *)prop)->prop_class; + } + + case UNREAL_PROP_KIND_INTERFACE: { + return ((fprop_iface_t *)prop)->iface_class; + } + + default: { + return NULL; + } + } +} + bool unreal_fprop_object_is_compatible(fprop_obj_base_t *prop, uobject_t *object) { @@ -1512,6 +1922,32 @@ unreal_fprop_set_object(fprop_obj_base_t *prop, void *value, uobject_t *object) return true; } +bool +unreal_fprop_interface_is_compatible(fprop_iface_t *prop, uobject_t *object) +{ + bool compatible = prop && unreal_fprop_get_kind(&prop->base) == UNREAL_PROP_KIND_INTERFACE && prop->iface_class; + if (compatible && object) { + compatible = unreal_uobject_get_interface_address(object, prop->iface_class) != NULL; + } + return compatible; +} + +bool +unreal_fprop_set_interface(fprop_iface_t *prop, void *value, uobject_t *object) +{ + unreal_prop_script_interface_t result = {0}; + bool valid = prop && value && prop->base.elem_size >= (int32_t)sizeof(result) && unreal_fprop_interface_is_compatible(prop, object); + if (valid && object) { + result.object = object; + result.interface_ptr = unreal_uobject_get_interface_address(object, prop->iface_class); + } + + if (valid) { + mem_copy(value, &result, sizeof(result)); + } + return valid; +} + void unreal_fprop_initialize_in_container(fprop_t *prop, void *container) { @@ -1581,11 +2017,21 @@ unreal_fprop_import_text(fprop_t *prop, void *value, uobject_t *owner, str_t tex if (unreal_fprop_copy_single_value(prop, copy, value)) { const wchar_t *end = unreal_fprop_import_text_direct(prop, (const wchar_t *)wide.data, copy, owner); if (end) { - while (*end == L' ' || *end == L'\t' || *end == L'\r' || *end == L'\n') { - end += 1; + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + bool consumed = kind == UNREAL_PROP_KIND_SOFT_OBJECT || kind == UNREAL_PROP_KIND_SOFT_CLASS; + if (kind == UNREAL_PROP_KIND_STRUCT) { + uscript_struct_t *type = ((fprop_struct_t *)prop)->script_struct; + consumed = type && (type->struct_flags & ESF_IMPORT_TEXT_ITEM_NATIVE) != 0; } - if (*end == L'\0') { + if (!consumed) { + while (*end == L' ' || *end == L'\t' || *end == L'\r' || *end == L'\n') { + end += 1; + } + consumed = *end == L'\0'; + } + + if (consumed) { result = unreal_fprop_copy_single_value(prop, value, copy); } } @@ -1987,3 +2433,536 @@ unreal_map_find(void *map, fprop_map_t *prop, const void *key, void *out_val) } return generic_map_find(map, prop, key, out_val); } + +static str_t +unreal_prop_snapshot_copy_text(unreal_prop_snapshot_builder_t *builder, unreal_prop_snapshot_t *snapshot, str_t text) +{ + if (str_is_empty(text)) { + return STR_NULL; + } + + uint64_t length = text.len; + if (length > builder->max_text_length) { + length = builder->max_text_length; + while (length > 0 && (text.data[length] & 0xC0) == 0x80) { + length -= 1; + } + + snapshot->truncated = true; + builder->truncated = true; + } + + return str_push_copy(builder->arena, str_slice(text, 0, length)); +} + +static unreal_prop_snapshot_t * +unreal_prop_snapshot_alloc(unreal_prop_snapshot_builder_t *builder) +{ + if (!builder || !builder->arena || builder->node_count >= builder->max_nodes) { + if (builder) { + builder->truncated = true; + } + + return NULL; + } + + unreal_prop_snapshot_t *snapshot = ARENA_PUSH_ZERO(builder->arena, unreal_prop_snapshot_t); + if (snapshot) { + snapshot->expanded = true; + builder->node_count += 1; + } else { + builder->truncated = true; + } + + return snapshot; +} + +static void +unreal_prop_snapshot_push_child(unreal_prop_snapshot_t *parent, unreal_prop_snapshot_t *child) +{ + if (!parent || !child) { + return; + } + + QUEUE_PUSH(parent->first_child, parent->last_child, child); +} + +static bool +unreal_prop_snapshot_is_object_reference(unreal_prop_kind_t kind) +{ + return kind == UNREAL_PROP_KIND_OBJECT || + kind == UNREAL_PROP_KIND_CLASS || + kind == UNREAL_PROP_KIND_WEAK_OBJECT || + kind == UNREAL_PROP_KIND_LAZY_OBJECT || + kind == UNREAL_PROP_KIND_INTERFACE; +} + +static void +unreal_prop_snapshot_set_metadata(unreal_prop_snapshot_builder_t *builder, unreal_prop_snapshot_t *snapshot, fprop_t *prop, str_t name) +{ + tmp_arena_t tmp = scratch_begin(builder->arena); + { + str_t type = unreal_fprop_push_type_name(prop, tmp.arena); + + snapshot->name = unreal_prop_snapshot_copy_text(builder, snapshot, name); + snapshot->type = unreal_prop_snapshot_copy_text(builder, snapshot, type); + snapshot->prop_flags = prop->prop_flags; + } + scratch_end(tmp); +} + +static void +unreal_prop_snapshot_format_leaf(unreal_prop_snapshot_builder_t *builder, unreal_prop_snapshot_t *snapshot, fprop_t *prop, const void *value) +{ + tmp_arena_t tmp = scratch_begin(builder->arena); + { + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + str_t summary = STR_NULL; + str_t tooltip = STR_NULL; + + if (kind == UNREAL_PROP_KIND_BOOL) { + bool boolean = false; + if (unreal_fprop_read_bool(prop, value, &boolean)) { + summary = STR_BOOL(boolean); + } + } else if (kind == UNREAL_PROP_KIND_FLOAT || kind == UNREAL_PROP_KIND_DOUBLE) { + double real = 0.0; + if (unreal_fprop_read_real(prop, value, &real)) { + if (kind == UNREAL_PROP_KIND_FLOAT) { + summary = str_push_fmt(tmp.arena, "%.9g", real); + } else { + summary = str_push_fmt(tmp.arena, "%.17g", real); + } + } + } else if (kind == UNREAL_PROP_KIND_BYTE || + kind == UNREAL_PROP_KIND_INT8 || + kind == UNREAL_PROP_KIND_INT16 || + kind == UNREAL_PROP_KIND_INT32 || + kind == UNREAL_PROP_KIND_INT64 || + kind == UNREAL_PROP_KIND_UINT16 || + kind == UNREAL_PROP_KIND_UINT32 || + kind == UNREAL_PROP_KIND_UINT64) { + unreal_prop_integer_t integer = {0}; + if (unreal_fprop_read_integer(prop, value, &integer)) { + if (integer.is_signed) { + summary = str_push_fmt(tmp.arena, "%lld", (long long)(int64_t)integer.value); + } else { + summary = str_push_fmt(tmp.arena, "%llu", (unsigned long long)integer.value); + } + } + } else if (kind == UNREAL_PROP_KIND_ENUM) { + fprop_enum_t *enum_prop = (fprop_enum_t *)prop; + unreal_prop_integer_t integer_value = {0}; + if (unreal_fprop_read_integer(prop, value, &integer_value)) { + int64_t integer = (int64_t)integer_value.value; + if (enum_prop->uenum) { + for (int32_t i = 0; i < enum_prop->uenum->names.num && str_is_empty(summary); ++i) { + if (enum_prop->uenum->names.data[i].value == integer) { + summary = unreal_fname_to_str(enum_prop->uenum->names.data[i].key, tmp.arena); + } + } + } + + if (str_is_empty(summary)) { + summary = str_push_fmt(tmp.arena, "%lld", (long long)integer); + } + } + } else if (kind == UNREAL_PROP_KIND_NAME) { + fname_t name_value = {0}; + if (unreal_fprop_read_name(prop, value, &name_value)) { + summary = unreal_fname_to_str(name_value, tmp.arena); + } + } else if (kind == UNREAL_PROP_KIND_STRING || kind == UNREAL_PROP_KIND_TEXT) { + bool read = unreal_fprop_read_string(prop, value, tmp.arena, &summary); + if (read && str_is_empty(summary)) { + summary = STR_LIT("\"\""); + } + } else if (unreal_prop_snapshot_is_object_reference(kind)) { + uobject_t *object = unreal_fprop_get_referenced_object(prop, value); + if (!object) { + summary = unreal_fprop_push_value_summary(prop, value, prop->elem_size, tmp.arena); + if (str_is_empty(summary)) { + summary = STR_LIT("None"); + } + } else if (!unreal_uobject_is_valid(object)) { + summary = STR_LIT(""); + } else { + summary = unreal_uobject_push_name(object, tmp.arena); + tooltip = unreal_uobject_push_full_name(object, tmp.arena); + } + } else if (kind == UNREAL_PROP_KIND_SOFT_OBJECT || kind == UNREAL_PROP_KIND_SOFT_CLASS) { + unreal_fprop_read_soft_path(prop, value, tmp.arena, &summary); + } else { + summary = unreal_fprop_push_value_summary(prop, value, prop->elem_size, tmp.arena); + } + + if (str_is_empty(summary)) { + summary = STR_LIT(""); + } + + snapshot->value = unreal_prop_snapshot_copy_text(builder, snapshot, summary); + snapshot->tooltip = unreal_prop_snapshot_copy_text(builder, snapshot, tooltip); + } + scratch_end(tmp); +} + +static bool +unreal_prop_snapshot_child_layout_valid(fprop_t *parent, fprop_t *child) +{ + if (!parent || !child || child->offset_internal < 0 || child->elem_size <= 0 || child->array_dim <= 0) { + return false; + } + + uint64_t child_end = (uint64_t)child->offset_internal + unreal_fprop_complete_size(child); + return child_end <= (uint64_t)parent->elem_size; +} + +static unreal_prop_snapshot_t * +unreal_fprop_snapshot_build_internal(unreal_prop_snapshot_builder_t *builder, fprop_t *prop, str_t name, const uint8_t *value, + uint32_t depth, bool allow_fixed_array); + +static void +unreal_prop_snapshot_build_fixed_array(unreal_prop_snapshot_builder_t *builder, + unreal_prop_snapshot_t *snapshot, + fprop_t *prop, + const uint8_t *value, + uint32_t depth) +{ + snapshot->value = str_push_fmt(builder->arena, "Num=%d", prop->array_dim); + + uint32_t shown = (uint32_t)prop->array_dim; + if (shown > builder->max_container_elements) { + shown = builder->max_container_elements; + snapshot->truncated = true; + builder->truncated = true; + } + + for (uint32_t i = 0; i < shown; ++i) { + unreal_prop_snapshot_t *child = NULL; + tmp_arena_t tmp = scratch_begin(builder->arena); + { + str_t child_name = str_push_fmt(tmp.arena, "[%u]", i); + const uint8_t *child_value = NULL; + if (value) { + child_value = value + (uint64_t)i * (uint64_t)prop->elem_size; + } + + child = unreal_fprop_snapshot_build_internal(builder, prop, child_name, child_value, depth + 1, false); + } + scratch_end(tmp); + + if (!child) { + snapshot->truncated = true; + break; + } + + unreal_prop_snapshot_push_child(snapshot, child); + } +} + +static void +unreal_prop_snapshot_build_struct(unreal_prop_snapshot_builder_t *builder, + unreal_prop_snapshot_t *snapshot, + fprop_t *prop, + const uint8_t *value, + uint32_t depth) +{ + fprop_struct_t *struct_prop = (fprop_struct_t *)prop; + if (!struct_prop->script_struct || !struct_prop->script_struct->child_props) { + if (value) { + unreal_prop_snapshot_format_leaf(builder, snapshot, prop, value); + } + + return; + } + + snapshot->value = str_push_copy(builder->arena, STR_LIT("{...}")); + for (ffield_t *field = struct_prop->script_struct->child_props; field; field = field->next) { + fprop_t *child_prop = (fprop_t *)field; + if (!unreal_prop_snapshot_child_layout_valid(prop, child_prop)) { + snapshot->truncated = true; + builder->truncated = true; + continue; + } + + unreal_prop_snapshot_t *child = NULL; + tmp_arena_t tmp = scratch_begin(builder->arena); + { + str_t child_name = unreal_fname_to_str(child_prop->name, tmp.arena); + const uint8_t *child_value = NULL; + if (value) { + child_value = value + child_prop->offset_internal; + } + + child = unreal_fprop_snapshot_build_internal(builder, child_prop, child_name, child_value, depth + 1, true); + } + scratch_end(tmp); + + if (!child) { + snapshot->truncated = true; + break; + } + + unreal_prop_snapshot_push_child(snapshot, child); + } +} + +static void +unreal_prop_snapshot_build_array(unreal_prop_snapshot_builder_t *builder, unreal_prop_snapshot_t *snapshot, fprop_array_t *prop, + const uint8_t *value, uint32_t depth) +{ + if (!value) { + return; + } + + int32_t count = unreal_array_num(value, prop); + if (count < 0 || !prop->inner) { + snapshot->value = str_push_copy(builder->arena, STR_LIT("")); + return; + } + + snapshot->value = str_push_fmt(builder->arena, "Num=%d", count); + int32_t shown = count; + if ((uint32_t)shown > builder->max_container_elements) { + shown = (int32_t)builder->max_container_elements; + snapshot->truncated = true; + builder->truncated = true; + } + + for (int32_t i = 0; i < shown; ++i) { + void *item = unreal_array_get((void *)value, prop, i); + if (!item) { + snapshot->truncated = true; + builder->truncated = true; + continue; + } + + unreal_prop_snapshot_t *child = NULL; + tmp_arena_t tmp = scratch_begin(builder->arena); + { + str_t child_name = str_push_fmt(tmp.arena, "[%d]", i); + child = unreal_fprop_snapshot_build_internal(builder, prop->inner, child_name, item, depth + 1, true); + } + scratch_end(tmp); + + if (!child) { + snapshot->truncated = true; + break; + } + + unreal_prop_snapshot_push_child(snapshot, child); + } +} + +static void +unreal_prop_snapshot_build_set(unreal_prop_snapshot_builder_t *builder, + unreal_prop_snapshot_t *snapshot, + fprop_set_t *prop, + const uint8_t *value, + uint32_t depth) +{ + if (!value) { + return; + } + + int32_t count = unreal_set_num(value, prop); + int32_t max_index = unreal_set_max_index(value, prop); + if (count < 0 || max_index < 0 || !prop->elem_prop) { + snapshot->value = str_push_copy(builder->arena, STR_LIT("")); + return; + } + + snapshot->value = str_push_fmt(builder->arena, "Num=%d", count); + int32_t shown = 0; + for (int32_t i = 0; i < max_index && shown < count; ++i) { + const void *item = unreal_set_get(value, prop, i); + if (!item) { + continue; + } + + if ((uint32_t)shown >= builder->max_container_elements) { + snapshot->truncated = true; + builder->truncated = true; + break; + } + + unreal_prop_snapshot_t *child = NULL; + tmp_arena_t tmp = scratch_begin(builder->arena); + { + str_t child_name = str_push_fmt(tmp.arena, "[%d]", shown); + child = unreal_fprop_snapshot_build_internal(builder, prop->elem_prop, child_name, item, depth + 1, true); + } + scratch_end(tmp); + + if (!child) { + snapshot->truncated = true; + break; + } + + unreal_prop_snapshot_push_child(snapshot, child); + shown += 1; + } +} + +static unreal_prop_snapshot_t * +unreal_prop_snapshot_build_map_pair(unreal_prop_snapshot_builder_t *builder, + fprop_map_t *prop, + int32_t shown, + const void *key_value, + const void *map_value, + uint32_t depth) +{ + unreal_prop_snapshot_t *pair = unreal_prop_snapshot_alloc(builder); + if (!pair) { + return NULL; + } + + tmp_arena_t tmp = scratch_begin(builder->arena); + { + str_t key_type = unreal_fprop_push_type_name(prop->key_prop, tmp.arena); + str_t val_type = unreal_fprop_push_type_name(prop->val_prop, tmp.arena); + str_t name = str_push_fmt(tmp.arena, "[%d]", shown); + str_t type = str_push_fmt(tmp.arena, "TPair<%.*s, %.*s>", STR_ARG(key_type), STR_ARG(val_type)); + + pair->name = unreal_prop_snapshot_copy_text(builder, pair, name); + pair->type = unreal_prop_snapshot_copy_text(builder, pair, type); + pair->value = str_push_copy(builder->arena, STR_LIT("{...}")); + } + scratch_end(tmp); + + unreal_prop_snapshot_t *key = unreal_fprop_snapshot_build_internal(builder, prop->key_prop, STR_LIT("Key"), key_value, depth + 1, true); + unreal_prop_snapshot_t *val = unreal_fprop_snapshot_build_internal(builder, prop->val_prop, STR_LIT("Value"), map_value, depth + 1, true); + if (key) { + unreal_prop_snapshot_push_child(pair, key); + } else { + pair->truncated = true; + } + + if (val) { + unreal_prop_snapshot_push_child(pair, val); + } else { + pair->truncated = true; + } + + return pair; +} + +static void +unreal_prop_snapshot_build_map(unreal_prop_snapshot_builder_t *builder, + unreal_prop_snapshot_t *snapshot, + fprop_map_t *prop, + const uint8_t *value, + uint32_t depth) +{ + if (!value) { + return; + } + + int32_t count = unreal_map_num(value, prop); + int32_t max_index = unreal_map_max_index(value, prop); + if (count < 0 || max_index < 0 || !prop->key_prop || !prop->val_prop) { + snapshot->value = str_push_copy(builder->arena, STR_LIT("")); + return; + } + + snapshot->value = str_push_fmt(builder->arena, "Num=%d", count); + int32_t shown = 0; + for (int32_t i = 0; i < max_index && shown < count; ++i) { + const void *key_value = unreal_map_get_key(value, prop, i); + void *map_value = unreal_map_get_value((void *)value, prop, i); + if (!key_value || !map_value) { + continue; + } + + if ((uint32_t)shown >= builder->max_container_elements) { + snapshot->truncated = true; + builder->truncated = true; + break; + } + + unreal_prop_snapshot_t *pair = unreal_prop_snapshot_build_map_pair(builder, prop, shown, key_value, map_value, depth + 1); + if (!pair) { + snapshot->truncated = true; + break; + } + + unreal_prop_snapshot_push_child(snapshot, pair); + shown += 1; + } +} + +static unreal_prop_snapshot_t * +unreal_fprop_snapshot_build_internal(unreal_prop_snapshot_builder_t *builder, + fprop_t *prop, + str_t name, + const uint8_t *value, + uint32_t depth, + bool allow_fixed_array) +{ + if (!builder || !prop || prop->elem_size <= 0 || prop->array_dim <= 0) { + if (builder) { + builder->truncated = true; + } + + return NULL; + } + + unreal_prop_snapshot_t *snapshot = unreal_prop_snapshot_alloc(builder); + if (!snapshot) { + return NULL; + } + + unreal_prop_snapshot_set_metadata(builder, snapshot, prop, name); + unreal_prop_kind_t kind = unreal_fprop_get_kind(prop); + bool has_children = (allow_fixed_array && prop->array_dim > 1) || + kind == UNREAL_PROP_KIND_STRUCT || + kind == UNREAL_PROP_KIND_ARRAY || + kind == UNREAL_PROP_KIND_SET || + kind == UNREAL_PROP_KIND_MAP; + + if (depth >= builder->max_depth && has_children) { + snapshot->value = str_push_copy(builder->arena, STR_LIT("")); + snapshot->truncated = true; + builder->truncated = true; + } else if (allow_fixed_array && prop->array_dim > 1) { + unreal_prop_snapshot_build_fixed_array(builder, snapshot, prop, value, depth); + } else if (kind == UNREAL_PROP_KIND_STRUCT) { + unreal_prop_snapshot_build_struct(builder, snapshot, prop, value, depth); + } else if (kind == UNREAL_PROP_KIND_ARRAY) { + unreal_prop_snapshot_build_array(builder, snapshot, (fprop_array_t *)prop, value, depth); + } else if (kind == UNREAL_PROP_KIND_SET) { + unreal_prop_snapshot_build_set(builder, snapshot, (fprop_set_t *)prop, value, depth); + } else if (kind == UNREAL_PROP_KIND_MAP) { + unreal_prop_snapshot_build_map(builder, snapshot, (fprop_map_t *)prop, value, depth); + } else if (value) { + unreal_prop_snapshot_format_leaf(builder, snapshot, prop, value); + } + + if (builder->truncated && builder->node_count >= builder->max_nodes) { + snapshot->truncated = true; + } + + return snapshot; +} + +void +unreal_prop_snapshot_builder_init(unreal_prop_snapshot_builder_t *builder, arena_t *arena) +{ + if (!builder) { + return; + } + + *builder = (unreal_prop_snapshot_builder_t){ + .arena = arena, + .max_depth = 8, + .max_container_elements = 128, + .max_nodes = 4096, + .max_text_length = 512, + }; +} + +unreal_prop_snapshot_t * +unreal_fprop_snapshot_build(unreal_prop_snapshot_builder_t *builder, fprop_t *prop, str_t name, const void *value) +{ + return unreal_fprop_snapshot_build_internal(builder, prop, name, value, 0, true); +} diff --git a/src/unreal_reflect.c b/src/unreal_reflect.c new file mode 100644 index 0000000..b1f390f --- /dev/null +++ b/src/unreal_reflect.c @@ -0,0 +1,1798 @@ +#include "unreal_reflect.h" + +#include "globals.h" +#include "log.h" +#include "scratch.h" +#include "signatures.h" + +#include + +typedef uint8_t unreal_reflect_class_state_t; +enum { + UNREAL_REFLECT_CLASS_BUILDING, + UNREAL_REFLECT_CLASS_READY, + UNREAL_REFLECT_CLASS_FAILED, +}; + +typedef struct unreal_reflect_class_s unreal_reflect_class_t; +typedef struct unreal_reflect_func_s unreal_reflect_func_t; + +struct unreal_reflect_func_s { + ufunc_t *function; + fprop_t **params; + uint32_t num_params; + fprop_t *ret; + unreal_func_impl_fn_t impl; + void *user; + bool active; +}; + +struct unreal_reflect_class_s { + unreal_reflect_class_t *next; + str_t scope; + str_t name; + fname_t engine_name; + unreal_reflect_owner_t owner; + uclass_t *parent; + uclass_t *cls; + fprop_t **props; + uint32_t num_props; + unreal_reflect_func_t *funcs; + uint32_t num_funcs; + uint64_t schema_hash; + unreal_reflect_class_state_t state; +}; + +static unreal_reflect_class_t *g_classes; +static ufunc_t *g_linking_func; + +/* NOTE: class schemas and their rooted UClass objects intentionally survive every mod generation */ + +static bool +unreal_reflect_str_has_null(str_t text) +{ + bool found = text.len > 0 && !text.data; + for (uint64_t i = 0; i < text.len && !found; ++i) { + found = text.data[i] == 0; + } + return found; +} + +static uint64_t +unreal_reflect_hash_bytes(uint64_t hash, const void *data, uint64_t size) +{ + const uint8_t *bytes = data; + for (uint64_t i = 0; i < size; ++i) { + hash ^= bytes[i]; + hash *= 1099511628211ULL; + } + return hash; +} + +static uint64_t +unreal_reflect_hash_append(uint64_t hash, str_t text) +{ + return unreal_reflect_hash_bytes(hash, text.data, text.len); +} + +static uint64_t +unreal_reflect_class_hash(str_t scope, str_t name) +{ + uint64_t hash = unreal_reflect_hash_append(14695981039346656037ULL, scope); + hash ^= 0; + hash *= 1099511628211ULL; + return unreal_reflect_hash_append(hash, name); +} + +static uint64_t +unreal_reflect_hash_u64(uint64_t hash, uint64_t value) +{ + return unreal_reflect_hash_append(hash, str_make(&value, sizeof(value))); +} + +static bool +unreal_reflect_class_def_has_props(const unreal_class_def_t *def) +{ + uint32_t props_end = offsetof(unreal_class_def_t, num_props) + sizeof(def->num_props); + return def->struct_size >= props_end; +} + +static uint32_t +unreal_reflect_class_prop_count(const unreal_class_def_t *def) +{ + uint32_t count = 0; + if (unreal_reflect_class_def_has_props(def)) { + count = def->num_props; + } + return count; +} + +static bool +unreal_reflect_class_def_has_funcs(const unreal_class_def_t *def) +{ + uint32_t funcs_end = offsetof(unreal_class_def_t, num_funcs) + sizeof(def->num_funcs); + return def->struct_size >= funcs_end; +} + +static uint32_t +unreal_reflect_class_func_count(const unreal_class_def_t *def) +{ + uint32_t count = 0; + if (unreal_reflect_class_def_has_funcs(def)) { + count = def->num_funcs; + } + return count; +} + +static unreal_prop_type_t +unreal_reflect_prop_type(const unreal_prop_def_t *def) +{ + unreal_prop_type_t type = { + .type = def->type, + .cls = def->cls, + .struct_type = def->struct_type, + .enum_type = def->enum_type, + }; + + if (def->type == UNREAL_PROP_KIND_ARRAY || def->type == UNREAL_PROP_KIND_SET || def->type == UNREAL_PROP_KIND_MAP || def->type == UNREAL_PROP_KIND_ENUM) { + type.inner = &def->inner; + } + + if (def->type == UNREAL_PROP_KIND_MAP) { + type.value = &def->value; + } + return type; +} + +static bool +unreal_reflect_kind_is_signed_integer(unreal_prop_kind_t type) +{ + return type == UNREAL_PROP_KIND_INT8 || type == UNREAL_PROP_KIND_INT16 || type == UNREAL_PROP_KIND_INT32 || type == UNREAL_PROP_KIND_INT64; +} + +static bool +unreal_reflect_kind_is_unsigned_integer(unreal_prop_kind_t type) +{ + return type == UNREAL_PROP_KIND_BYTE || type == UNREAL_PROP_KIND_UINT16 || type == UNREAL_PROP_KIND_UINT32 || type == UNREAL_PROP_KIND_UINT64; +} + +static bool +unreal_reflect_kind_is_integer(unreal_prop_kind_t type) +{ + return unreal_reflect_kind_is_signed_integer(type) || unreal_reflect_kind_is_unsigned_integer(type); +} + +static bool +unreal_reflect_kind_is_object_reference(unreal_prop_kind_t type) +{ + return type == UNREAL_PROP_KIND_OBJECT || type == UNREAL_PROP_KIND_CLASS || type == UNREAL_PROP_KIND_WEAK_OBJECT || type == UNREAL_PROP_KIND_LAZY_OBJECT; +} + +static bool +unreal_reflect_kind_is_soft_reference(unreal_prop_kind_t type) +{ + return type == UNREAL_PROP_KIND_SOFT_OBJECT || type == UNREAL_PROP_KIND_SOFT_CLASS; +} + +static bool +unreal_reflect_kind_is_string(unreal_prop_kind_t type) +{ + return type == UNREAL_PROP_KIND_STRING || type == UNREAL_PROP_KIND_TEXT; +} + +static bool +unreal_reflect_kind_has_inner(unreal_prop_kind_t type) +{ + return type == UNREAL_PROP_KIND_ARRAY || type == UNREAL_PROP_KIND_SET || type == UNREAL_PROP_KIND_MAP || type == UNREAL_PROP_KIND_ENUM; +} + +static uint32_t +unreal_reflect_scalar_size(unreal_prop_kind_t type) +{ + uint32_t size = 0; + switch (type) { + case UNREAL_PROP_KIND_BOOL: + case UNREAL_PROP_KIND_BYTE: + case UNREAL_PROP_KIND_INT8: { + size = 1; + break; + } + + case UNREAL_PROP_KIND_INT16: + case UNREAL_PROP_KIND_UINT16: { + size = 2; + break; + } + + case UNREAL_PROP_KIND_INT32: + case UNREAL_PROP_KIND_UINT32: + case UNREAL_PROP_KIND_FLOAT: { + size = 4; + break; + } + + case UNREAL_PROP_KIND_INT64: + case UNREAL_PROP_KIND_UINT64: + case UNREAL_PROP_KIND_DOUBLE: { + size = 8; + break; + } + + default: { + break; + } + } + return size; +} + +static uint64_t +unreal_reflect_type_hash(uint64_t hash, const unreal_prop_type_t *type) +{ + hash = unreal_reflect_hash_u64(hash, type->type); + if (unreal_reflect_kind_is_object_reference(type->type) || unreal_reflect_kind_is_soft_reference(type->type) || type->type == UNREAL_PROP_KIND_INTERFACE) { + hash = unreal_reflect_hash_u64(hash, (uintptr_t)type->cls); + } else if (type->type == UNREAL_PROP_KIND_STRUCT) { + hash = unreal_reflect_hash_u64(hash, (uintptr_t)type->struct_type); + } else if (type->type == UNREAL_PROP_KIND_ENUM) { + hash = unreal_reflect_hash_u64(hash, (uintptr_t)type->enum_type); + } + + if (unreal_reflect_kind_has_inner(type->type) && type->inner) { + hash = unreal_reflect_type_hash(hash, type->inner); + } + + if (type->type == UNREAL_PROP_KIND_MAP && type->value) { + hash = unreal_reflect_type_hash(hash, type->value); + } + return hash; +} + +static uint64_t +unreal_reflect_items_hash(uint64_t hash, const unreal_prop_type_t *type, const void *items, uint32_t count) +{ + uint32_t scalar_size = unreal_reflect_scalar_size(type->type); + if (scalar_size > 0) { + return unreal_reflect_hash_bytes(hash, items, (uint64_t)scalar_size * count); + } + + for (uint32_t i = 0; i < count; ++i) { + if (unreal_reflect_kind_is_object_reference(type->type) || type->type == UNREAL_PROP_KIND_INTERFACE) { + uobject_t *const *objects = items; + hash = unreal_reflect_hash_u64(hash, (uintptr_t)objects[i]); + } else if (type->type == UNREAL_PROP_KIND_NAME || + unreal_reflect_kind_is_string(type->type) || + unreal_reflect_kind_is_soft_reference(type->type) || + type->type == UNREAL_PROP_KIND_STRUCT) { + const str_t *texts = items; + hash = unreal_reflect_hash_append(hash, texts[i]); + } else if (type->type == UNREAL_PROP_KIND_ENUM) { + const int64_t *values = items; + hash = unreal_reflect_hash_u64(hash, (uint64_t)values[i]); + } + } + return hash; +} + +static uint64_t +unreal_reflect_prop_hash(uint64_t hash, const unreal_prop_def_t *def) +{ + unreal_prop_type_t type = unreal_reflect_prop_type(def); + + hash = unreal_reflect_hash_append(hash, def->name); + hash = unreal_reflect_type_hash(hash, &type); + hash = unreal_reflect_hash_u64(hash, def->flags); + + switch (def->type) { + case UNREAL_PROP_KIND_BOOL: { + hash = unreal_reflect_hash_u64(hash, def->boolean.default_val); + break; + } + + case UNREAL_PROP_KIND_INT8: + case UNREAL_PROP_KIND_INT16: + case UNREAL_PROP_KIND_INT32: + case UNREAL_PROP_KIND_INT64: { + hash = unreal_reflect_hash_u64(hash, (uint64_t)def->integer.default_val); + break; + } + + case UNREAL_PROP_KIND_BYTE: + case UNREAL_PROP_KIND_UINT16: + case UNREAL_PROP_KIND_UINT32: + case UNREAL_PROP_KIND_UINT64: { + hash = unreal_reflect_hash_u64(hash, def->unsigned_integer.default_val); + break; + } + + case UNREAL_PROP_KIND_FLOAT: + case UNREAL_PROP_KIND_DOUBLE: { + hash = unreal_reflect_hash_bytes(hash, &def->real.default_val, sizeof(def->real.default_val)); + break; + } + + case UNREAL_PROP_KIND_OBJECT: + case UNREAL_PROP_KIND_CLASS: + case UNREAL_PROP_KIND_WEAK_OBJECT: + case UNREAL_PROP_KIND_LAZY_OBJECT: + case UNREAL_PROP_KIND_INTERFACE: { + hash = unreal_reflect_hash_u64(hash, (uintptr_t)def->object.default_val); + break; + } + + case UNREAL_PROP_KIND_NAME: { + hash = unreal_reflect_hash_append(hash, def->fname.default_val); + break; + } + + case UNREAL_PROP_KIND_STRING: + case UNREAL_PROP_KIND_TEXT: { + hash = unreal_reflect_hash_append(hash, def->string.default_val); + break; + } + + case UNREAL_PROP_KIND_SOFT_OBJECT: + case UNREAL_PROP_KIND_SOFT_CLASS: { + hash = unreal_reflect_hash_append(hash, def->soft.default_val); + break; + } + + case UNREAL_PROP_KIND_STRUCT: { + hash = unreal_reflect_hash_append(hash, def->structure.default_val); + break; + } + + case UNREAL_PROP_KIND_ENUM: { + hash = unreal_reflect_hash_u64(hash, (uint64_t)def->enumeration.default_val); + break; + } + + case UNREAL_PROP_KIND_ARRAY: + case UNREAL_PROP_KIND_SET: { + const unreal_prop_array_default_t *defaults = &def->array.default_val; + if (def->type == UNREAL_PROP_KIND_SET) { + defaults = &def->set.default_val; + } + + hash = unreal_reflect_hash_u64(hash, defaults->count); + hash = unreal_reflect_items_hash(hash, &def->inner, defaults->items, defaults->count); + break; + } + + case UNREAL_PROP_KIND_MAP: { + hash = unreal_reflect_hash_u64(hash, def->map.default_val.count); + hash = unreal_reflect_items_hash(hash, &def->inner, def->map.default_val.keys, def->map.default_val.count); + hash = unreal_reflect_items_hash(hash, &def->value, def->map.default_val.values, def->map.default_val.count); + break; + } + + default: { + break; + } + } + return hash; +} + +static uint64_t +unreal_reflect_func_hash(uint64_t hash, const unreal_func_def_t *def) +{ + hash = unreal_reflect_hash_append(hash, def->name); + hash = unreal_reflect_hash_u64(hash, def->flags); + hash = unreal_reflect_hash_u64(hash, def->num_params); + + for (uint32_t i = 0; i < def->num_params; ++i) { + unreal_prop_type_t type = unreal_reflect_prop_type(&def->params[i]); + + hash = unreal_reflect_hash_append(hash, def->params[i].name); + hash = unreal_reflect_type_hash(hash, &type); + hash = unreal_reflect_hash_u64(hash, def->params[i].flags); + } + + hash = unreal_reflect_type_hash(hash, &def->ret); + return hash; +} + +static uint64_t +unreal_reflect_schema_hash(const unreal_class_def_t *def) +{ + uint32_t prop_count = unreal_reflect_class_prop_count(def); + uint32_t func_count = unreal_reflect_class_func_count(def); + uint64_t hash = unreal_reflect_hash_u64(14695981039346656037ULL, (uintptr_t)def->parent); + + hash = unreal_reflect_hash_u64(hash, prop_count); + for (uint32_t i = 0; i < prop_count; ++i) { + hash = unreal_reflect_prop_hash(hash, &def->props[i]); + } + + hash = unreal_reflect_hash_u64(hash, func_count); + for (uint32_t i = 0; i < func_count; ++i) { + hash = unreal_reflect_func_hash(hash, &def->funcs[i]); + } + return hash; +} + +static str_t +unreal_reflect_engine_name(uint8_t *buf, uint64_t cap, str_t scope, str_t name) +{ + uint64_t len = str_write_fmt(buf, cap, "OD_%016llX_", (unsigned long long)unreal_reflect_class_hash(scope, name)); + if (len >= cap) { + len = cap - 1; + } + + for (uint64_t i = 0; i < name.len && len + 1 < cap; ++i) { + uint8_t ch = name.data[i]; + bool valid = (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || ch == '_'; + if (!valid) { + ch = '_'; + } + buf[len++] = ch; + } + + buf[len] = 0; + return str_make(buf, len); +} + +static unreal_reflect_class_t * +unreal_reflect_class_find(str_t scope, str_t name) +{ + unreal_reflect_class_t *found = NULL; + for (unreal_reflect_class_t *entry = g_classes; entry && !found; entry = entry->next) { + if (str_equal(entry->scope, scope, 0) && str_equal(entry->name, name, 0)) { + found = entry; + } + } + return found; +} + +static uobject_t * +unreal_reflect_object_find(uobject_t *outer, fname_t name) +{ + uobject_t *found = NULL; + for (int i = 0, count = unreal_uobject_array_count(); i < count && !found; ++i) { + uobject_t *object = unreal_uobject_array_get_obj(i); + if (object && object->outer == outer && unreal_fname_equal(object->name, name, false)) { + found = object; + } + } + return found; +} + +static bool +unreal_reflect_runtime_ready(void) +{ + bool on_game_thread = unreal_is_in_game_thread(); + bool have_types = globals.unreal.core_class && globals.unreal.core_object && globals.unreal.transient_package; + bool have_funcs = static_construct_object && create_default_object && ustruct_static_link && uclass_assemble_ref_tok_stream; + return globals.engine_inited && on_game_thread && have_types && have_funcs; +} + +static bool +unreal_reflect_type_is_hashable(const unreal_prop_type_t *type) +{ + bool hashable = false; + if (type) { + hashable = type->type == UNREAL_PROP_KIND_BOOL || unreal_reflect_kind_is_integer(type->type); + hashable = hashable || type->type == UNREAL_PROP_KIND_FLOAT || type->type == UNREAL_PROP_KIND_DOUBLE; + hashable = hashable || type->type == UNREAL_PROP_KIND_NAME || type->type == UNREAL_PROP_KIND_STRING; + hashable = hashable || unreal_reflect_kind_is_object_reference(type->type) || unreal_reflect_kind_is_soft_reference(type->type); + hashable = hashable || type->type == UNREAL_PROP_KIND_ENUM; + } + return hashable; +} + +static bool +unreal_reflect_type_valid(const unreal_prop_type_t *type, bool allow_container) +{ + bool valid = type != NULL; + if (valid) { + switch (type->type) { + case UNREAL_PROP_KIND_BOOL: + case UNREAL_PROP_KIND_BYTE: + case UNREAL_PROP_KIND_INT8: + case UNREAL_PROP_KIND_INT16: + case UNREAL_PROP_KIND_INT32: + case UNREAL_PROP_KIND_INT64: + case UNREAL_PROP_KIND_UINT16: + case UNREAL_PROP_KIND_UINT32: + case UNREAL_PROP_KIND_UINT64: + case UNREAL_PROP_KIND_FLOAT: + case UNREAL_PROP_KIND_DOUBLE: + case UNREAL_PROP_KIND_NAME: + case UNREAL_PROP_KIND_STRING: + case UNREAL_PROP_KIND_TEXT: { + break; + } + + case UNREAL_PROP_KIND_OBJECT: + case UNREAL_PROP_KIND_CLASS: + case UNREAL_PROP_KIND_SOFT_OBJECT: + case UNREAL_PROP_KIND_SOFT_CLASS: + case UNREAL_PROP_KIND_WEAK_OBJECT: + case UNREAL_PROP_KIND_LAZY_OBJECT: { + valid = type->cls && unreal_uobject_is_a((uobject_t *)type->cls, globals.unreal.core_class); + break; + } + + case UNREAL_PROP_KIND_INTERFACE: { + valid = type->cls && unreal_uobject_is_a((uobject_t *)type->cls, globals.unreal.core_class) && (type->cls->class_flags & CLASS_INTERFACE); + break; + } + + case UNREAL_PROP_KIND_STRUCT: { + valid = type->struct_type && globals.unreal.core_scriptstruct && + unreal_uobject_is_a((uobject_t *)type->struct_type, globals.unreal.core_scriptstruct) && + type->struct_type->props_size >= 0 && type->struct_type->min_alignment > 0; + break; + } + + case UNREAL_PROP_KIND_ENUM: { + valid = type->enum_type && globals.unreal.core_enum && unreal_uobject_is_a((uobject_t *)type->enum_type, globals.unreal.core_enum) && + type->inner && unreal_reflect_kind_is_integer(type->inner->type); + break; + } + + case UNREAL_PROP_KIND_ARRAY: { + valid = allow_container && type->inner && unreal_reflect_type_valid(type->inner, false); + break; + } + + case UNREAL_PROP_KIND_SET: { + valid = allow_container && type->inner; + if (valid) { + valid = unreal_reflect_type_valid(type->inner, false) && unreal_reflect_type_is_hashable(type->inner); + } + break; + } + + case UNREAL_PROP_KIND_MAP: { + valid = allow_container && type->inner && type->value; + if (valid) { + valid = unreal_reflect_type_valid(type->inner, false) && unreal_reflect_type_valid(type->value, false); + } + + if (valid) { + valid = unreal_reflect_type_is_hashable(type->inner); + } + break; + } + + default: { + valid = false; + break; + } + } + } + return valid; +} + +static bool +unreal_reflect_signed_default_valid(unreal_prop_kind_t type, int64_t value) +{ + bool valid = true; + if (type == UNREAL_PROP_KIND_INT8) { + valid = value >= INT8_MIN && value <= INT8_MAX; + } else if (type == UNREAL_PROP_KIND_INT16) { + valid = value >= INT16_MIN && value <= INT16_MAX; + } else if (type == UNREAL_PROP_KIND_INT32) { + valid = value >= INT32_MIN && value <= INT32_MAX; + } + return valid; +} + +static bool +unreal_reflect_unsigned_default_valid(unreal_prop_kind_t type, uint64_t value) +{ + bool valid = true; + if (type == UNREAL_PROP_KIND_BYTE) { + valid = value <= UINT8_MAX; + } else if (type == UNREAL_PROP_KIND_UINT16) { + valid = value <= UINT16_MAX; + } else if (type == UNREAL_PROP_KIND_UINT32) { + valid = value <= UINT32_MAX; + } + return valid; +} + +static bool +unreal_reflect_object_default_valid(const unreal_prop_type_t *type, uobject_t *object) +{ + bool valid = true; + if (object && type->type == UNREAL_PROP_KIND_INTERFACE) { + valid = unreal_uobject_get_interface_address(object, type->cls) != NULL; + } else if (object && type->type == UNREAL_PROP_KIND_CLASS) { + valid = unreal_uobject_is_a(object, globals.unreal.core_class); + if (valid) { + valid = unreal_uclass_is_child_of((uclass_t *)object, type->cls); + } + } else if (object) { + valid = unreal_uobject_is_a(object, type->cls); + } + return valid; +} + +static bool +unreal_reflect_text_default_valid(str_t text) +{ + return !unreal_reflect_str_has_null(text); +} + +static bool +unreal_reflect_enum_default_valid(const unreal_prop_type_t *type, int64_t value) +{ + bool valid = type && type->inner; + if (valid && unreal_reflect_kind_is_signed_integer(type->inner->type)) { + valid = unreal_reflect_signed_default_valid(type->inner->type, value); + } else if (valid && unreal_reflect_kind_is_unsigned_integer(type->inner->type)) { + valid = value >= 0 && unreal_reflect_unsigned_default_valid(type->inner->type, (uint64_t)value); + } else { + valid = false; + } + return valid; +} + +static bool +unreal_reflect_item_valid(const unreal_prop_type_t *type, const void *items, uint32_t index) +{ + bool valid = true; + if (unreal_reflect_kind_is_object_reference(type->type) || type->type == UNREAL_PROP_KIND_INTERFACE) { + uobject_t *const *objects = items; + valid = unreal_reflect_object_default_valid(type, objects[index]); + } else if (type->type == UNREAL_PROP_KIND_NAME) { + const str_t *texts = items; + valid = !unreal_reflect_str_has_null(texts[index]) && texts[index].len < FNAME_ENTRY_NAME_SIZE; + } else if (unreal_reflect_kind_is_string(type->type) || + unreal_reflect_kind_is_soft_reference(type->type) || + type->type == UNREAL_PROP_KIND_STRUCT) { + const str_t *texts = items; + valid = unreal_reflect_text_default_valid(texts[index]); + } else if (type->type == UNREAL_PROP_KIND_ENUM) { + const int64_t *values = items; + valid = unreal_reflect_enum_default_valid(type, values[index]); + } + return valid; +} + +static bool +unreal_reflect_items_valid(const unreal_prop_type_t *type, const void *items, uint32_t count) +{ + bool valid = count <= INT32_MAX && (count == 0 || items); + for (uint32_t i = 0; i < count && valid; ++i) { + valid = unreal_reflect_item_valid(type, items, i); + } + return valid; +} + +static bool +unreal_reflect_default_valid(const unreal_prop_def_t *def) +{ + unreal_prop_type_t type = unreal_reflect_prop_type(def); + bool valid = true; + if (unreal_reflect_kind_is_signed_integer(def->type)) { + valid = unreal_reflect_signed_default_valid(def->type, def->integer.default_val); + } else if (unreal_reflect_kind_is_unsigned_integer(def->type)) { + valid = unreal_reflect_unsigned_default_valid(def->type, def->unsigned_integer.default_val); + } else if (def->type == UNREAL_PROP_KIND_FLOAT) { + double value = def->real.default_val; + valid = value != value || (value >= -FLT_MAX && value <= FLT_MAX); + } else if (unreal_reflect_kind_is_object_reference(def->type) || def->type == UNREAL_PROP_KIND_INTERFACE) { + valid = unreal_reflect_object_default_valid(&type, def->object.default_val); + } else if (def->type == UNREAL_PROP_KIND_NAME) { + valid = !unreal_reflect_str_has_null(def->fname.default_val) && def->fname.default_val.len < FNAME_ENTRY_NAME_SIZE; + } else if (unreal_reflect_kind_is_string(def->type)) { + valid = unreal_reflect_text_default_valid(def->string.default_val); + } else if (unreal_reflect_kind_is_soft_reference(def->type)) { + valid = unreal_reflect_text_default_valid(def->soft.default_val); + } else if (def->type == UNREAL_PROP_KIND_STRUCT) { + valid = unreal_reflect_text_default_valid(def->structure.default_val); + } else if (def->type == UNREAL_PROP_KIND_ENUM) { + valid = unreal_reflect_enum_default_valid(&type, def->enumeration.default_val); + } else if (def->type == UNREAL_PROP_KIND_ARRAY) { + valid = unreal_reflect_items_valid(&def->inner, def->array.default_val.items, def->array.default_val.count); + } else if (def->type == UNREAL_PROP_KIND_SET) { + valid = unreal_reflect_items_valid(&def->inner, def->set.default_val.items, def->set.default_val.count); + } else if (def->type == UNREAL_PROP_KIND_MAP) { + valid = unreal_reflect_items_valid(&def->inner, def->map.default_val.keys, def->map.default_val.count); + if (valid) { + valid = unreal_reflect_items_valid(&def->value, def->map.default_val.values, def->map.default_val.count); + } + } + return valid; +} + +static bool +unreal_reflect_prop_valid(const unreal_class_def_t *class_def, uint32_t index) +{ + const unreal_prop_def_t *def = &class_def->props[index]; + unreal_prop_type_t type = unreal_reflect_prop_type(def); + bool valid = !str_is_empty(def->name) && def->name.len <= 256 && !unreal_reflect_str_has_null(def->name); + if (valid) { + valid = unreal_reflect_type_valid(&type, true) && unreal_reflect_default_valid(def); + } + + eprop_flags_t invalid_flags = CPF_PARM | CPF_OUT_PARM | CPF_RETURN_PARM | CPF_REFERENCE_PARM | CPF_CONST_PARM | CPF_NET | CPF_REP_NOTIFY; + if (valid) { + valid = (def->flags & invalid_flags) == 0; + } + + for (fprop_t *prop = class_def->parent->prop_link; prop && valid; prop = prop->prop_link_next) { + valid = !unreal_fname_match_text(prop->name, def->name, true, true); + } + + for (uint32_t i = 0; i < index && valid; ++i) { + valid = !str_equal(class_def->props[i].name, def->name, STR_CMP_FLAG_IGNORE_CASE); + } + return valid; +} + +static bool +unreal_reflect_func_param_valid(const unreal_func_def_t *func, uint32_t index) +{ + const unreal_prop_def_t *def = &func->params[index]; + unreal_prop_type_t type = unreal_reflect_prop_type(def); + + bool valid = !str_is_empty(def->name) && def->name.len <= 256 && !unreal_reflect_str_has_null(def->name); + if (valid) { + valid = !str_equal(def->name, STR_LIT("ReturnValue"), STR_CMP_FLAG_IGNORE_CASE); + } + + if (valid) { + valid = unreal_reflect_type_valid(&type, true) && (def->flags & ~CPF_CONST_PARM) == 0; + } + + for (uint32_t i = 0; i < index && valid; ++i) { + valid = !str_equal(func->params[i].name, def->name, STR_CMP_FLAG_IGNORE_CASE); + } + return valid; +} + +static bool +unreal_reflect_func_valid(const unreal_class_def_t *class_def, uint32_t index) +{ + const unreal_func_def_t *def = &class_def->funcs[index]; + + bool valid = !str_is_empty(def->name) && def->name.len <= 256 && !unreal_reflect_str_has_null(def->name) && def->impl; + if (valid) { + valid = def->num_params <= UINT8_MAX && (def->num_params == 0 || def->params); + } + + efunc_flags_t allowed_flags = FUNC_FLAG_FINAL | FUNC_FLAG_PUBLIC | FUNC_FLAG_PRIVATE | FUNC_FLAG_PROTECTED | FUNC_FLAG_BLUEPRINT_CALLABLE | FUNC_FLAG_BLUEPRINT_PURE | FUNC_FLAG_CONST; + if (valid) { + valid = (def->flags & ~allowed_flags) == 0; + } + + efunc_flags_t visibility = def->flags & (FUNC_FLAG_PUBLIC | FUNC_FLAG_PRIVATE | FUNC_FLAG_PROTECTED); + if (valid) { + valid = visibility == 0 || visibility == FUNC_FLAG_PUBLIC || visibility == FUNC_FLAG_PRIVATE || visibility == FUNC_FLAG_PROTECTED; + } + + for (uint32_t i = 0; i < def->num_params && valid; ++i) { + valid = unreal_reflect_func_param_valid(def, i); + } + + bool has_ret = def->ret.type != UNREAL_PROP_KIND_UNKNOWN; + if (valid && has_ret) { + valid = unreal_reflect_type_valid(&def->ret, true) && def->num_params < UINT8_MAX; + } + + if (valid) { + valid = !unreal_ustruct_find_func((ustruct_t *)class_def->parent, def->name); + } + + for (uint32_t i = 0; i < index && valid; ++i) { + valid = !str_equal(class_def->funcs[i].name, def->name, STR_CMP_FLAG_IGNORE_CASE); + } + return valid; +} + +static bool +unreal_reflect_class_def_valid(str_t scope, str_t name, const unreal_class_def_t *def) +{ + bool text_valid = !str_is_empty(scope) && !str_is_empty(name) && name.len <= 256; + if (text_valid) { + text_valid = !unreal_reflect_str_has_null(scope) && !unreal_reflect_str_has_null(name); + } + + uint32_t min_def_size = offsetof(unreal_class_def_t, parent) + sizeof(def->parent); + bool def_valid = def && def->struct_size >= min_def_size && def->parent; + if (def_valid) { + def_valid = unreal_uobject_is_a((uobject_t *)def->parent, globals.unreal.core_class); + } + + uint32_t count = 0; + if (def_valid) { + count = unreal_reflect_class_prop_count(def); + } + + if (def_valid && count > 0) { + def_valid = def->props != NULL; + } + + for (uint32_t i = 0; i < count && def_valid; ++i) { + def_valid = unreal_reflect_prop_valid(def, i); + } + + uint32_t func_count = 0; + if (def_valid) { + func_count = unreal_reflect_class_func_count(def); + } + + if (def_valid && func_count > 0) { + def_valid = def->funcs != NULL; + } + + for (uint32_t i = 0; i < func_count && def_valid; ++i) { + def_valid = unreal_reflect_func_valid(def, i); + } + return text_valid && def_valid; +} + +static fname_t +unreal_reflect_type_name(unreal_prop_kind_t type) +{ + fname_t name = FNAME_NONE; + switch (type) { + case UNREAL_PROP_KIND_BOOL: { + name = globals.unreal.bool_prop; + break; + } + + case UNREAL_PROP_KIND_BYTE: { + name = globals.unreal.byte_prop; + break; + } + + case UNREAL_PROP_KIND_INT8: { + name = globals.unreal.int8_prop; + break; + } + + case UNREAL_PROP_KIND_INT16: { + name = globals.unreal.int16_prop; + break; + } + + case UNREAL_PROP_KIND_INT32: { + name = globals.unreal.int_prop; + break; + } + + case UNREAL_PROP_KIND_INT64: { + name = globals.unreal.int64_prop; + break; + } + + case UNREAL_PROP_KIND_UINT16: { + name = globals.unreal.uint16_prop; + break; + } + + case UNREAL_PROP_KIND_UINT32: { + name = globals.unreal.uint32_prop; + break; + } + + case UNREAL_PROP_KIND_UINT64: { + name = globals.unreal.uint64_prop; + break; + } + + case UNREAL_PROP_KIND_FLOAT: { + name = globals.unreal.float_prop; + break; + } + + case UNREAL_PROP_KIND_DOUBLE: { + name = globals.unreal.double_prop; + break; + } + + case UNREAL_PROP_KIND_OBJECT: { + name = globals.unreal.obj_prop; + break; + } + + case UNREAL_PROP_KIND_NAME: { + name = globals.unreal.name_prop; + break; + } + + case UNREAL_PROP_KIND_STRING: { + name = globals.unreal.str_prop; + break; + } + + case UNREAL_PROP_KIND_TEXT: { + name = globals.unreal.text_prop; + break; + } + + case UNREAL_PROP_KIND_CLASS: { + name = globals.unreal.class_prop; + break; + } + + case UNREAL_PROP_KIND_SOFT_OBJECT: { + name = globals.unreal.soft_obj_prop; + break; + } + + case UNREAL_PROP_KIND_SOFT_CLASS: { + name = globals.unreal.soft_class_prop; + break; + } + + case UNREAL_PROP_KIND_WEAK_OBJECT: { + name = globals.unreal.weak_obj_prop; + break; + } + + case UNREAL_PROP_KIND_LAZY_OBJECT: { + name = globals.unreal.lazy_obj_prop; + break; + } + + case UNREAL_PROP_KIND_INTERFACE: { + name = globals.unreal.interface_prop; + break; + } + + case UNREAL_PROP_KIND_STRUCT: { + name = globals.unreal.struct_prop; + break; + } + + case UNREAL_PROP_KIND_ENUM: { + name = globals.unreal.enum_prop; + break; + } + + case UNREAL_PROP_KIND_ARRAY: { + name = globals.unreal.array_prop; + break; + } + + case UNREAL_PROP_KIND_SET: { + name = globals.unreal.set_prop; + break; + } + + case UNREAL_PROP_KIND_MAP: { + name = globals.unreal.map_prop; + break; + } + + default: { + break; + } + } + return name; +} + +static bool +unreal_reflect_type_runtime_ready(const unreal_prop_type_t *type) +{ + bool ready = type && !unreal_fname_is_none(unreal_reflect_type_name(type->type)); + if (ready && unreal_reflect_kind_has_inner(type->type)) { + ready = unreal_reflect_type_runtime_ready(type->inner); + } + + if (ready && type->type == UNREAL_PROP_KIND_MAP) { + ready = unreal_reflect_type_runtime_ready(type->value); + } + return ready; +} + +static bool +unreal_reflect_schema_runtime_ready(const unreal_class_def_t *def) +{ + uint32_t prop_count = unreal_reflect_class_prop_count(def); + uint32_t func_count = unreal_reflect_class_func_count(def); + + bool ready = (prop_count == 0 && func_count == 0) || ffield_construct; + for (uint32_t i = 0; i < prop_count && ready; ++i) { + unreal_prop_type_t type = unreal_reflect_prop_type(&def->props[i]); + ready = unreal_reflect_type_runtime_ready(&type); + + if (ready && type.type == UNREAL_PROP_KIND_ARRAY && def->props[i].array.default_val.count > 0) { + ready = generic_array_resize != NULL; + } else if (ready && type.type == UNREAL_PROP_KIND_SET && def->props[i].set.default_val.count > 0) { + ready = fscript_set_add_elem != NULL; + } else if (ready && type.type == UNREAL_PROP_KIND_MAP && def->props[i].map.default_val.count > 0) { + ready = fscript_map_add_pair != NULL; + } + } + + for (uint32_t i = 0; i < func_count && ready; ++i) { + const unreal_func_def_t *func = &def->funcs[i]; + for (uint32_t j = 0; j < func->num_params && ready; ++j) { + unreal_prop_type_t type = unreal_reflect_prop_type(&func->params[j]); + ready = unreal_reflect_type_runtime_ready(&type); + } + + if (ready && func->ret.type != UNREAL_PROP_KIND_UNKNOWN) { + ready = unreal_reflect_type_runtime_ready(&func->ret); + } + } + + if (ready && func_count > 0) { + ready = globals.unreal.core_func && uclass_create_link_and_add_child_funcs_to_map && uclass_add_native_func; + } + return ready; +} + +static bool +unreal_reflect_attach_prop(ffield_variant_t owner, fprop_t *prop) +{ + bool attached = prop != NULL; + if (attached && owner.is_uobject) { + ufield_t *field = (ufield_t *)owner.container.obj; + attached = field && field->vtable && field->vtable->add_cpp_prop; + if (attached) { + field->vtable->add_cpp_prop(field, prop); + } + } else if (attached) { + ffield_t *field = owner.container.field; + attached = field && field->vtable && field->vtable->add_cpp_prop; + if (attached) { + field->vtable->add_cpp_prop(field, prop); + } + } + return attached; +} + +static bool +unreal_reflect_configure_prop(fprop_t *prop, const unreal_prop_type_t *type) +{ + bool configured = prop != NULL; + bool object_kind = unreal_reflect_kind_is_object_reference(type->type) || unreal_reflect_kind_is_soft_reference(type->type); + if (configured && object_kind) { + ((fprop_obj_base_t *)prop)->prop_class = type->cls; + + if (type->type == UNREAL_PROP_KIND_CLASS) { + ((fprop_obj_base_t *)prop)->prop_class = globals.unreal.core_class; + ((fprop_class_t *)prop)->meta_class = type->cls; + } else if (type->type == UNREAL_PROP_KIND_SOFT_CLASS) { + ((fprop_obj_base_t *)prop)->prop_class = globals.unreal.core_class; + ((fprop_class_soft_t *)prop)->meta_class = type->cls; + } + } else if (configured && type->type == UNREAL_PROP_KIND_STRUCT) { + ((fprop_struct_t *)prop)->script_struct = type->struct_type; + } else if (configured && type->type == UNREAL_PROP_KIND_ENUM) { + ((fprop_enum_t *)prop)->uenum = type->enum_type; + } else if (configured && type->type == UNREAL_PROP_KIND_INTERFACE) { + ((fprop_iface_t *)prop)->iface_class = type->cls; + } + return configured; +} + +static bool +unreal_reflect_prop_has_inner(unreal_prop_kind_t type) +{ + return type == UNREAL_PROP_KIND_ARRAY || type == UNREAL_PROP_KIND_SET || type == UNREAL_PROP_KIND_ENUM; +} + +static bool +unreal_reflect_inner_matches(fprop_t *prop, unreal_prop_kind_t type, fprop_t *inner) +{ + bool matches = false; + if (type == UNREAL_PROP_KIND_ARRAY) { + matches = ((fprop_array_t *)prop)->inner == inner; + } else if (type == UNREAL_PROP_KIND_SET) { + matches = ((fprop_set_t *)prop)->elem_prop == inner; + } else if (type == UNREAL_PROP_KIND_ENUM) { + matches = (fprop_t *)((fprop_enum_t *)prop)->underlying_prop == inner; + } + return matches; +} + +static fprop_t * +unreal_reflect_construct_prop(ffield_variant_t owner, fname_t name, const unreal_prop_type_t *type, bool hash_required) +{ + fname_t type_name = unreal_reflect_type_name(type->type); + fprop_t *prop = (fprop_t *)ffield_construct(&type_name, &owner, &name, RF_TRANSIENT); + if (!unreal_reflect_configure_prop(prop, type)) { + prop = NULL; + } + + if (prop && hash_required) { + /* NOTE: Set/Map AddCppProperty checks this before StaticLink computes the property type's normal flags; + validation limits this to known hashable types */ + prop->prop_flags |= CPF_HAS_GET_VALUE_TYPE_HASH; + } + + if (prop && unreal_reflect_prop_has_inner(type->type)) { + ffield_variant_t inner_owner = { + .container.field = (ffield_t *)prop, + .is_uobject = false, + }; + + bool inner_hash_required = type->type == UNREAL_PROP_KIND_SET; + fprop_t *inner = unreal_reflect_construct_prop(inner_owner, FNAME_NONE, type->inner, inner_hash_required); + if (!inner || !unreal_reflect_inner_matches(prop, type->type, inner)) { + prop = NULL; + } + } + + if (prop && type->type == UNREAL_PROP_KIND_MAP) { + ffield_variant_t inner_owner = { + .container.field = (ffield_t *)prop, + .is_uobject = false, + }; + + fprop_t *key = unreal_reflect_construct_prop(inner_owner, FNAME_NONE, type->inner, true); + fprop_t *val = NULL; + if (key) { + val = unreal_reflect_construct_prop(inner_owner, FNAME_NONE, type->value, false); + } + + if (!key || !val || ((fprop_map_t *)prop)->key_prop != key || ((fprop_map_t *)prop)->val_prop != val) { + prop = NULL; + } + } + + if (prop && !unreal_reflect_attach_prop(owner, prop)) { + prop = NULL; + } + return prop; +} + +static bool +unreal_reflect_construct_props(unreal_reflect_class_t *entry, const unreal_class_def_t *def) +{ + ffield_variant_t owner = { + .container.obj = (uobject_t *)entry->cls, + .is_uobject = true, + }; + + bool built = true; + for (uint32_t remaining = entry->num_props; remaining > 0 && built; --remaining) { + uint32_t index = remaining - 1; + const unreal_prop_def_t *prop_def = &def->props[index]; + unreal_prop_type_t type = unreal_reflect_prop_type(prop_def); + fname_t name = unreal_fname_from_str(prop_def->name, FNAME_FIND_OR_ADD); + fprop_t *prop = unreal_reflect_construct_prop(owner, name, &type, false); + if (prop) { + prop->prop_flags |= prop_def->flags; + entry->props[index] = prop; + } else { + built = false; + } + } + return built; +} + +static unreal_reflect_func_t * +unreal_reflect_func_find(ufunc_t *function) +{ + unreal_reflect_func_t *found = NULL; + for (unreal_reflect_class_t *cls = g_classes; cls && !found; cls = cls->next) { + for (uint32_t i = 0; i < cls->num_funcs && !found; ++i) { + if (cls->funcs[i].function == function) { + found = &cls->funcs[i]; + } + } + } + return found; +} + +static void +unreal_reflect_func_call(unreal_reflect_func_t *entry, uobject_t *object, void *params, void *result) +{ + if (entry->active && entry->impl) { + unreal_func_call_t call = { + .object = object, + .function = entry->function, + .params = params, + .return_value = entry->ret ? result : NULL, + .user = entry->user, + }; + entry->impl(&call); + } +} + +static bool +unreal_reflect_func_step_params(unreal_reflect_func_t *entry, fframe_t *stack, void *params) +{ + bool stepped = true; + for (uint32_t i = 0; i < entry->num_params && stepped; ++i) { + void *value = unreal_fprop_value_in_container(entry->params[i], params, 0); + stepped = value && unreal_fframe_step(stack, value); + } + + if (stepped) { + stepped = stack->code && *stack->code == EX_END_FUNCTION_PARMS; + } + + if (stepped) { + stack->code += 1; + } + return stepped; +} + +static void __fastcall +unreal_reflect_func_thunk(uobject_t *object, fframe_t *stack, void *result) +{ + ufunc_t *function = stack ? stack->current_native_func : NULL; + if (!function && stack) { + function = stack->node; + } + + unreal_reflect_func_t *entry = unreal_reflect_func_find(function); + if (!entry || !stack) { + LOG_ERROR("cannot dispatch an unregistered custom Unreal function"); + return; + } + + if (!stack->code) { + unreal_reflect_func_call(entry, object, stack->locals, result); + return; + } + + tmp_arena_t tmp = scratch_begin(NULL); + { + uint64_t size = MAX_VAL((uint64_t)function->params_size, 1ULL); + uint64_t alignment = MAX_VAL((uint64_t)function->min_alignment, 1ULL); + + void *params = arena_push_zero_aligned(tmp.arena, size, alignment); + bool initialized = params && unreal_ustruct_initialize_struct((ustruct_t *)function, params, 1); + + bool stepped = initialized && unreal_reflect_func_step_params(entry, stack, params); + if (stepped) { + unreal_reflect_func_call(entry, object, params, result); + } else { + LOG_ERROR("cannot read parameters for custom Unreal function"); + } + + if (initialized) { + unreal_ustruct_destroy_struct((ustruct_t *)function, params, 1); + } + } + scratch_end(tmp); +} + +static ufunc_t * +unreal_reflect_linking_func(void) +{ + return g_linking_func; +} + +static efunc_flags_t +unreal_reflect_func_flags(const unreal_func_def_t *def) +{ + efunc_flags_t flags = def->flags | FUNC_FLAG_NATIVE; + efunc_flags_t visibility = flags & (FUNC_FLAG_PUBLIC | FUNC_FLAG_PRIVATE | FUNC_FLAG_PROTECTED); + if (visibility == 0) { + flags |= FUNC_FLAG_PUBLIC; + } + return flags; +} + +static bool +unreal_reflect_construct_func_params(unreal_reflect_func_t *entry, const unreal_func_def_t *def) +{ + ffield_variant_t owner = { + .container.obj = (uobject_t *)entry->function, + .is_uobject = true, + }; + + bool built = true; + if (def->ret.type != UNREAL_PROP_KIND_UNKNOWN) { + fname_t name = unreal_fname_from_str(STR_LIT("ReturnValue"), FNAME_FIND_OR_ADD); + entry->ret = unreal_reflect_construct_prop(owner, name, &def->ret, false); + built = entry->ret != NULL; + if (built) { + entry->ret->prop_flags |= CPF_PARM | CPF_OUT_PARM | CPF_RETURN_PARM; + } + } + + for (uint32_t remaining = def->num_params; remaining > 0 && built; --remaining) { + uint32_t index = remaining - 1; + const unreal_prop_def_t *param_def = &def->params[index]; + unreal_prop_type_t type = unreal_reflect_prop_type(param_def); + fname_t name = unreal_fname_from_str(param_def->name, FNAME_FIND_OR_ADD); + + fprop_t *param = unreal_reflect_construct_prop(owner, name, &type, false); + if (param) { + param->prop_flags |= CPF_PARM | param_def->flags; + entry->params[index] = param; + } else { + built = false; + } + } + return built; +} + +static bool +unreal_reflect_link_func(unreal_reflect_class_t *cls, unreal_reflect_func_t *entry, const unreal_func_def_t *def) +{ + bool linked = false; + tmp_arena_t tmp = scratch_begin(NULL); + { + char *name8 = str_push_cstr(tmp.arena, def->name); + str16_t name16 = str16_from_str(tmp.arena, def->name); + wchar_t *wide = str16_push_wstr(tmp.arena, name16); + if (name8 && wide) { + uclass_add_native_func(cls->cls, wide, unreal_reflect_func_thunk); + entry->function->vtable->bind((ufield_t *)entry->function); + ustruct_static_link((ustruct_t *)entry->function, true); + + fclass_func_link_info_t info = { + .create_func_ptr = unreal_reflect_linking_func, + .func_name = name8, + }; + + ufunc_t *previous = g_linking_func; + g_linking_func = entry->function; + uclass_create_link_and_add_child_funcs_to_map(cls->cls, &info, 1); + g_linking_func = previous; + + ufunc_t *found = unreal_ustruct_find_func((ustruct_t *)cls->cls, def->name); + linked = found == entry->function && entry->function->func != NULL; + } + } + scratch_end(tmp); + return linked; +} + +static bool +unreal_reflect_func_layout_valid(unreal_reflect_func_t *entry, uint32_t expected_params) +{ + ufunc_t *function = entry->function; + bool valid = function->num_params == expected_params && function->props_size >= 0 && function->props_size <= UINT16_MAX && function->min_alignment > 0; + if (valid && expected_params > 0) { + valid = function->params_size > 0; + } + + uint32_t count = 0; + for (ffield_t *field = function->child_props; field && valid; field = field->next) { + fprop_t *prop = (fprop_t *)field; + valid = (prop->prop_flags & CPF_PARM) != 0 && prop->offset_internal >= 0; + if (valid) { + uint64_t size = unreal_fprop_complete_size(prop); + valid = size > 0 && (uint64_t)prop->offset_internal <= function->params_size && size <= function->params_size - (uint64_t)prop->offset_internal; + } + count += 1; + } + + valid = valid && count == expected_params; + if (valid && entry->ret) { + valid = function->return_val_offset == entry->ret->offset_internal; + } else if (valid) { + valid = function->return_val_offset == UINT16_MAX; + } + return valid; +} + +static bool +unreal_reflect_construct_func(unreal_reflect_class_t *cls, uint32_t index, const unreal_func_def_t *def) +{ + unreal_reflect_func_t *entry = &cls->funcs[index]; + fstatic_construct_obj_params_t params = { + .cls = globals.unreal.core_func, + .outer = (uobject_t *)cls->cls, + .name = unreal_fname_from_str(def->name, FNAME_FIND_OR_ADD), + .set_flags = RF_PUBLIC | RF_TRANSIENT, + }; + + entry->function = (ufunc_t *)unreal_static_construct_object(¶ms); + entry->num_params = def->num_params; + entry->impl = def->impl; + entry->user = def->user; + entry->active = false; + if (def->num_params > 0) { + entry->params = ARENA_PUSH_ARRAY_ZERO(&globals.perm, fprop_t *, def->num_params); + } + + bool built = entry->function && (def->num_params == 0 || entry->params); + if (built) { + entry->function->func_flags = unreal_reflect_func_flags(def); + built = unreal_reflect_construct_func_params(entry, def); + } + + if (built) { + built = unreal_reflect_link_func(cls, entry, def); + } + + uint32_t expected_params = def->num_params + (def->ret.type != UNREAL_PROP_KIND_UNKNOWN); + if (built) { + built = unreal_reflect_func_layout_valid(entry, expected_params); + } + return built; +} + +static bool +unreal_reflect_construct_funcs(unreal_reflect_class_t *entry, const unreal_class_def_t *def) +{ + bool built = true; + for (uint32_t i = 0; i < entry->num_funcs && built; ++i) { + built = unreal_reflect_construct_func(entry, i, &def->funcs[i]); + } + return built; +} + +static void +unreal_reflect_update_funcs(unreal_reflect_class_t *entry, const unreal_class_def_t *def) +{ + for (uint32_t i = 0; i < entry->num_funcs; ++i) { + entry->funcs[i].impl = def->funcs[i].impl; + entry->funcs[i].user = def->funcs[i].user; + entry->funcs[i].active = true; + } +} + +static bool +unreal_reflect_write_text(fprop_t *prop, void *value, uobject_t *owner, str_t text) +{ + bool written = false; + if (str_is_empty(text)) { + written = unreal_fprop_clear_single_value(prop, value); + } else { + tmp_arena_t tmp = scratch_begin(NULL); + { + written = unreal_fprop_import_text(prop, value, owner, text, tmp.arena); + } + scratch_end(tmp); + } + return written; +} + +static bool +unreal_reflect_write_struct(fprop_t *prop, void *value, uobject_t *owner, str_t text) +{ + bool written = true; + if (!str_is_empty(text)) { + written = unreal_reflect_write_text(prop, value, owner, text); + } + return written; +} + +static bool +unreal_reflect_write_enum(fprop_t *prop, void *value, const unreal_prop_type_t *type, int64_t input) +{ + unreal_prop_integer_t integer = { + .value = (uint64_t)input, + .is_signed = unreal_reflect_kind_is_signed_integer(type->inner->type), + }; + return unreal_fprop_write_integer(prop, value, integer); +} + +static bool +unreal_reflect_write_item(fprop_t *prop, void *value, uobject_t *owner, const unreal_prop_type_t *type, const void *items, uint32_t index) +{ + bool written = false; + uint32_t scalar_size = unreal_reflect_scalar_size(type->type); + if (scalar_size > 0) { + const uint8_t *bytes = items; + written = unreal_fprop_copy_single_value(prop, value, bytes + (uint64_t)index * scalar_size); + } else if (unreal_reflect_kind_is_object_reference(type->type)) { + uobject_t *const *objects = items; + written = unreal_fprop_set_object((fprop_obj_base_t *)prop, value, objects[index]); + } else if (type->type == UNREAL_PROP_KIND_INTERFACE) { + uobject_t *const *objects = items; + written = unreal_fprop_set_interface((fprop_iface_t *)prop, value, objects[index]); + } else if (type->type == UNREAL_PROP_KIND_NAME) { + const str_t *texts = items; + fname_t name = FNAME_NONE; + if (!str_is_empty(texts[index])) { + name = unreal_fname_from_str(texts[index], FNAME_FIND_OR_ADD); + } + written = unreal_fprop_write_name(prop, value, name); + } else if (unreal_reflect_kind_is_string(type->type) || unreal_reflect_kind_is_soft_reference(type->type)) { + const str_t *texts = items; + written = unreal_reflect_write_text(prop, value, owner, texts[index]); + } else if (type->type == UNREAL_PROP_KIND_STRUCT) { + const str_t *texts = items; + written = unreal_reflect_write_struct(prop, value, owner, texts[index]); + } else if (type->type == UNREAL_PROP_KIND_ENUM) { + const int64_t *values = items; + written = unreal_reflect_write_enum(prop, value, type, values[index]); + } + return written; +} + +static void * +unreal_reflect_push_prop_value(arena_t *arena, fprop_t *prop) +{ + uint64_t size = unreal_fprop_complete_size(prop); + int32_t alignment = unreal_fprop_min_alignment(prop); + void *value = NULL; + if (size > 0 && alignment > 0) { + value = arena_push_zero_aligned(arena, size, (uint64_t)alignment); + } + return value; +} + +static bool +unreal_reflect_array_default(fprop_array_t *prop, void *value, uobject_t *owner, const unreal_prop_def_t *def) +{ + int32_t count = (int32_t)def->array.default_val.count; + if (count > 0) { + unreal_array_resize(value, prop, count); + } + + bool written = unreal_array_num(value, prop) == count; + for (int32_t i = 0; i < count && written; ++i) { + void *dst = unreal_array_get(value, prop, i); + written = unreal_reflect_write_item(prop->inner, dst, owner, &def->inner, def->array.default_val.items, (uint32_t)i); + } + return written; +} + +static bool +unreal_reflect_set_default(fprop_set_t *prop, void *value, uobject_t *owner, const unreal_prop_def_t *def) +{ + bool written = unreal_set_clear(value, prop); + tmp_arena_t tmp = scratch_begin(NULL); + { + void *item = unreal_reflect_push_prop_value(tmp.arena, prop->elem_prop); + for (uint32_t i = 0; i < def->set.default_val.count && written; ++i) { + bool initialized = item && unreal_fprop_initialize_value(prop->elem_prop, item); + + written = initialized && unreal_reflect_write_item(prop->elem_prop, item, owner, &def->inner, def->set.default_val.items, i); + if (written) { + unreal_set_add(value, prop, item); + written = unreal_set_contains(value, prop, item); + } + + if (initialized) { + unreal_fprop_destroy_value(prop->elem_prop, item); + } + } + } + scratch_end(tmp); + return written; +} + +static bool +unreal_reflect_map_default(fprop_map_t *prop, void *value, uobject_t *owner, const unreal_prop_def_t *def) +{ + bool written = unreal_map_clear(value, prop); + tmp_arena_t tmp = scratch_begin(NULL); + { + void *key = unreal_reflect_push_prop_value(tmp.arena, prop->key_prop); + void *val = unreal_reflect_push_prop_value(tmp.arena, prop->val_prop); + for (uint32_t i = 0; i < def->map.default_val.count && written; ++i) { + bool key_initialized = key && unreal_fprop_initialize_value(prop->key_prop, key); + bool val_initialized = val && unreal_fprop_initialize_value(prop->val_prop, val); + + written = key_initialized && val_initialized; + if (written) { + written = unreal_reflect_write_item(prop->key_prop, key, owner, &def->inner, def->map.default_val.keys, i); + } + + if (written) { + written = unreal_reflect_write_item(prop->val_prop, val, owner, &def->value, def->map.default_val.values, i); + } + + if (written) { + unreal_map_add(value, prop, key, val); + void *stored = unreal_map_find_value_ptr(value, prop, key); + written = stored && unreal_fprop_single_values_identical(prop->val_prop, stored, val, 0); + } + + if (val_initialized) { + unreal_fprop_destroy_value(prop->val_prop, val); + } + + if (key_initialized) { + unreal_fprop_destroy_value(prop->key_prop, key); + } + } + } + scratch_end(tmp); + return written; +} + +static bool +unreal_reflect_apply_default(fprop_t *prop, uobject_t *cdo, const unreal_prop_def_t *def) +{ + void *value = unreal_fprop_value_in_container(prop, cdo, 0); + bool written = value != NULL; + if (written && def->type == UNREAL_PROP_KIND_BOOL) { + written = unreal_fprop_write_bool(prop, value, def->boolean.default_val); + } else if (written && unreal_reflect_kind_is_signed_integer(def->type)) { + unreal_prop_integer_t integer = { + .value = (uint64_t)def->integer.default_val, + .is_signed = true, + }; + written = unreal_fprop_write_integer(prop, value, integer); + } else if (written && unreal_reflect_kind_is_unsigned_integer(def->type)) { + unreal_prop_integer_t integer = { + .value = def->unsigned_integer.default_val, + }; + written = unreal_fprop_write_integer(prop, value, integer); + } else if (written && (def->type == UNREAL_PROP_KIND_FLOAT || def->type == UNREAL_PROP_KIND_DOUBLE)) { + written = unreal_fprop_write_real(prop, value, def->real.default_val); + } else if (written && unreal_reflect_kind_is_object_reference(def->type)) { + written = unreal_fprop_set_object((fprop_obj_base_t *)prop, value, def->object.default_val); + } else if (written && def->type == UNREAL_PROP_KIND_INTERFACE) { + written = unreal_fprop_set_interface((fprop_iface_t *)prop, value, def->object.default_val); + } else if (written && def->type == UNREAL_PROP_KIND_NAME) { + fname_t name = FNAME_NONE; + if (!str_is_empty(def->fname.default_val)) { + name = unreal_fname_from_str(def->fname.default_val, FNAME_FIND_OR_ADD); + } + written = unreal_fprop_write_name(prop, value, name); + } else if (written && unreal_reflect_kind_is_string(def->type)) { + written = unreal_reflect_write_text(prop, value, cdo, def->string.default_val); + } else if (written && unreal_reflect_kind_is_soft_reference(def->type)) { + written = unreal_reflect_write_text(prop, value, cdo, def->soft.default_val); + } else if (written && def->type == UNREAL_PROP_KIND_STRUCT) { + written = unreal_reflect_write_struct(prop, value, cdo, def->structure.default_val); + } else if (written && def->type == UNREAL_PROP_KIND_ENUM) { + unreal_prop_type_t type = unreal_reflect_prop_type(def); + written = unreal_reflect_write_enum(prop, value, &type, def->enumeration.default_val); + } else if (written && def->type == UNREAL_PROP_KIND_ARRAY) { + written = unreal_reflect_array_default((fprop_array_t *)prop, value, cdo, def); + } else if (written && def->type == UNREAL_PROP_KIND_SET) { + written = unreal_reflect_set_default((fprop_set_t *)prop, value, cdo, def); + } else if (written && def->type == UNREAL_PROP_KIND_MAP) { + written = unreal_reflect_map_default((fprop_map_t *)prop, value, cdo, def); + } + return written; +} + +static bool +unreal_reflect_apply_defaults(unreal_reflect_class_t *entry, const unreal_class_def_t *def) +{ + bool applied = entry->cls->cdo != NULL; + for (uint32_t i = 0; i < entry->num_props && applied; ++i) { + applied = unreal_reflect_apply_default(entry->props[i], entry->cls->cdo, &def->props[i]); + if (!applied) { + fprop_t *prop = entry->props[i]; + int32_t offset = prop ? prop->offset_internal : -1; + int32_t size = prop ? prop->elem_size : 0; + LOG_ERROR("cannot apply default for Unreal property '%.*s' (type=%u, offset=%d, size=%d)", STR_ARG(def->props[i].name), def->props[i].type, offset, size); + } + } + return applied; +} + +uclass_t * +unreal_reflect_define_class_owned(unreal_reflect_owner_t owner, str_t scope, str_t name, const unreal_class_def_t *def) +{ + uclass_t *result = NULL; + if (!unreal_reflect_runtime_ready()) { + LOG_ERROR("cannot define Unreal class '%.*s': custom reflection is unavailable or the caller is not on the game thread", STR_ARG(name)); + return NULL; + } + + if (!unreal_reflect_class_def_valid(scope, name, def)) { + LOG_ERROR("cannot define Unreal class '%.*s': invalid scope, name, definition, or parent class", STR_ARG(name)); + return NULL; + } + + if (!unreal_reflect_schema_runtime_ready(def)) { + LOG_ERROR("cannot define Unreal class '%.*s': required reflection constructors, linkers, or container operations are unavailable", STR_ARG(name)); + return NULL; + } + + uint64_t schema_hash = unreal_reflect_schema_hash(def); + unreal_reflect_class_t *entry = unreal_reflect_class_find(scope, name); + if (entry) { + if (entry->schema_hash != schema_hash) { + LOG_ERROR("cannot redefine Unreal class '%.*s' with a different schema", STR_ARG(name)); + } else if (entry->state == UNREAL_REFLECT_CLASS_READY) { + entry->owner = owner; + unreal_reflect_update_funcs(entry, def); + result = entry->cls; + } else { + LOG_ERROR("cannot use Unreal class '%.*s' because its first definition did not complete", STR_ARG(name)); + } + return result; + } + + entry = ARENA_PUSH_ZERO(&globals.perm, unreal_reflect_class_t); + + str_t scope_copy = str_push_copy(&globals.perm, scope); + str_t name_copy = str_push_copy(&globals.perm, name); + uint32_t num_props = unreal_reflect_class_prop_count(def); + uint32_t num_funcs = unreal_reflect_class_func_count(def); + + fprop_t **props = NULL; + if (num_props > 0) { + props = ARENA_PUSH_ARRAY_ZERO(&globals.perm, fprop_t *, num_props); + } + + unreal_reflect_func_t *funcs = NULL; + if (num_funcs > 0) { + funcs = ARENA_PUSH_ARRAY_ZERO(&globals.perm, unreal_reflect_func_t, num_funcs); + } + + bool allocated = entry && scope_copy.data && name_copy.data; + allocated = allocated && (num_props == 0 || props) && (num_funcs == 0 || funcs); + if (!allocated) { + LOG_ERROR("cannot define Unreal class '%.*s': permanent registry allocation failed", STR_ARG(name)); + return NULL; + } + + uint8_t engine_name_buf[320]; + str_t engine_name = unreal_reflect_engine_name(engine_name_buf, sizeof(engine_name_buf), scope, name); + fname_t engine_fname = unreal_fname_from_str(engine_name, FNAME_FIND_OR_ADD); + if (unreal_reflect_object_find(globals.unreal.transient_package, engine_fname)) { + LOG_ERROR("cannot define Unreal class '%.*s': generated engine name '%.*s' is already in use", STR_ARG(name), STR_ARG(engine_name)); + return NULL; + } + + fstatic_construct_obj_params_t params = { + .cls = globals.unreal.core_class, + .outer = globals.unreal.transient_package, + .name = engine_fname, + .set_flags = RF_PUBLIC | RF_STANDALONE | RF_TRANSIENT, + }; + + uclass_t *cls = (uclass_t *)unreal_static_construct_object(¶ms); + if (!cls || !unreal_uobject_add_to_root((uobject_t *)cls)) { + LOG_ERROR("cannot define Unreal class '%.*s': UClass construction or rooting failed", STR_ARG(name)); + return NULL; + } + + entry->scope = scope_copy; + entry->name = name_copy; + entry->engine_name = engine_fname; + entry->owner = owner; + entry->parent = def->parent; + entry->cls = cls; + entry->props = props; + entry->num_props = num_props; + entry->funcs = funcs; + entry->num_funcs = num_funcs; + entry->schema_hash = schema_hash; + entry->state = UNREAL_REFLECT_CLASS_BUILDING; + entry->next = g_classes; + g_classes = entry; + + cls->vtable->set_super_struct((ustruct_t *)cls, (ustruct_t *)def->parent); + cls->class_flags = def->parent->class_flags & CLASS_SCRIPT_INHERIT; + cls->class_within = def->parent->class_within; + cls->class_config_name = def->parent->class_config_name; + + if (!unreal_reflect_construct_props(entry, def)) { + entry->state = UNREAL_REFLECT_CLASS_FAILED; + LOG_ERROR("cannot define Unreal class '%.*s': reflected property construction failed", STR_ARG(name)); + return NULL; + } + + if (!unreal_reflect_construct_funcs(entry, def)) { + entry->state = UNREAL_REFLECT_CLASS_FAILED; + LOG_ERROR("cannot define Unreal class '%.*s': reflected function construction failed", STR_ARG(name)); + return NULL; + } + + cls->vtable->bind((ufield_t *)cls); + ustruct_static_link((ustruct_t *)cls, true); + uclass_assemble_ref_tok_stream(cls, true); + + cls->cdo = create_default_object(cls); + if (!cls->cdo) { + entry->state = UNREAL_REFLECT_CLASS_FAILED; + LOG_ERROR("cannot define Unreal class '%.*s': default object construction failed", STR_ARG(name)); + } else if (!unreal_reflect_apply_defaults(entry, def)) { + entry->state = UNREAL_REFLECT_CLASS_FAILED; + LOG_ERROR("cannot define Unreal class '%.*s': applying default property values failed", STR_ARG(name)); + } else { + unreal_reflect_update_funcs(entry, def); + entry->state = UNREAL_REFLECT_CLASS_READY; + result = cls; + } + return result; +} + +uclass_t * +unreal_reflect_define_class(str_t scope, str_t name, const unreal_class_def_t *def) +{ + return unreal_reflect_define_class_owned(UNREAL_REFLECT_OWNER_PERSISTENT, scope, name, def); +} + +void +unreal_reflect_disable_owner(unreal_reflect_owner_t owner) +{ + for (unreal_reflect_class_t *cls = g_classes; cls; cls = cls->next) { + if (owner != UNREAL_REFLECT_OWNER_PERSISTENT && cls->owner == owner) { + for (uint32_t i = 0; i < cls->num_funcs; ++i) { + cls->funcs[i].active = false; + cls->funcs[i].impl = NULL; + cls->funcs[i].user = NULL; + } + } + } +} diff --git a/src/vendor.c b/src/vendor.c index ff2bae1..11cdec4 100644 --- a/src/vendor.c +++ b/src/vendor.c @@ -99,10 +99,6 @@ nk_runtime_font_rasterize(const void *ttf, return result; } -#if defined BUILD_TEST_UI -# include "nuklear/d3d11/nuklear_d3d11.c" -#endif - #if COMPILER_MSVC # pragma warning(pop) #elif COMPILER_GCC diff --git a/test/fonts/nk_font_dejavusansmono.h b/test/fonts/nk_font_dejavusansmono.h deleted file mode 100644 index a77c96c..0000000 --- a/test/fonts/nk_font_dejavusansmono.h +++ /dev/null @@ -1,27926 +0,0 @@ -unsigned char g_nk_dejavusansmono_ttf[] = { - 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x00, 0x04, 0x00, 0x20, - 0x46, 0x46, 0x54, 0x4d, 0x66, 0x09, 0x1d, 0xae, 0x00, 0x00, 0x01, 0x2c, - 0x00, 0x00, 0x00, 0x1c, 0x47, 0x44, 0x45, 0x46, 0x7f, 0x6b, 0x72, 0x48, - 0x00, 0x00, 0x01, 0x48, 0x00, 0x00, 0x00, 0xb0, 0x47, 0x50, 0x4f, 0x53, - 0x5c, 0x18, 0x98, 0x96, 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x39, 0xaa, - 0x47, 0x53, 0x55, 0x42, 0xee, 0x5b, 0x04, 0x56, 0x00, 0x00, 0x3b, 0xa4, - 0x00, 0x00, 0x04, 0x80, 0x4f, 0x53, 0x2f, 0x32, 0x8c, 0xfc, 0x69, 0xb2, - 0x00, 0x00, 0x40, 0x24, 0x00, 0x00, 0x00, 0x56, 0x63, 0x6d, 0x61, 0x70, - 0x5e, 0x50, 0xd1, 0xd7, 0x00, 0x00, 0x40, 0x7c, 0x00, 0x00, 0x16, 0x8a, - 0x63, 0x76, 0x74, 0x20, 0xe9, 0x97, 0x07, 0x0c, 0x00, 0x00, 0x57, 0x08, - 0x00, 0x00, 0x02, 0x30, 0x66, 0x70, 0x67, 0x6d, 0x5b, 0x02, 0x6b, 0xdf, - 0x00, 0x00, 0x59, 0x38, 0x00, 0x00, 0x00, 0xac, 0x67, 0x61, 0x73, 0x70, - 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x59, 0xe4, 0x00, 0x00, 0x00, 0x0c, - 0x67, 0x6c, 0x79, 0x66, 0x77, 0xb3, 0x6d, 0xea, 0x00, 0x00, 0x59, 0xf0, - 0x00, 0x03, 0xd1, 0xac, 0x68, 0x65, 0x61, 0x64, 0xfc, 0xfa, 0x50, 0xbc, - 0x00, 0x04, 0x2b, 0x9c, 0x00, 0x00, 0x00, 0x36, 0x68, 0x68, 0x65, 0x61, - 0x08, 0xb8, 0x02, 0x07, 0x00, 0x04, 0x2b, 0xd4, 0x00, 0x00, 0x00, 0x24, - 0x68, 0x6d, 0x74, 0x78, 0x39, 0x67, 0x3a, 0x7e, 0x00, 0x04, 0x2b, 0xf8, - 0x00, 0x00, 0x19, 0xe4, 0x6c, 0x6f, 0x63, 0x61, 0x17, 0xbc, 0xfd, 0x84, - 0x00, 0x04, 0x45, 0xdc, 0x00, 0x00, 0x33, 0xbc, 0x6d, 0x61, 0x78, 0x70, - 0x12, 0x94, 0x04, 0x27, 0x00, 0x04, 0x79, 0x98, 0x00, 0x00, 0x00, 0x20, - 0x6e, 0x61, 0x6d, 0x65, 0x60, 0xe4, 0xea, 0x89, 0x00, 0x04, 0x79, 0xb8, - 0x00, 0x00, 0x21, 0x15, 0x70, 0x6f, 0x73, 0x74, 0x8d, 0xb6, 0x48, 0x95, - 0x00, 0x04, 0x9a, 0xd0, 0x00, 0x00, 0x7a, 0xf0, 0x70, 0x72, 0x65, 0x70, - 0x3a, 0xc7, 0xc0, 0x07, 0x00, 0x05, 0x15, 0xc0, 0x00, 0x00, 0x07, 0x1b, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc9, 0x89, 0x6f, 0x31, - 0x00, 0x00, 0x00, 0x00, 0xce, 0x3f, 0xd7, 0x3e, 0x00, 0x00, 0x00, 0x00, - 0xce, 0x3f, 0xd7, 0x3e, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, - 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x19, 0x00, 0x03, - 0x02, 0x87, 0x00, 0x01, 0x02, 0x88, 0x02, 0x99, 0x00, 0x03, 0x02, 0x9a, - 0x02, 0x9a, 0x00, 0x01, 0x02, 0x9b, 0x02, 0xa1, 0x00, 0x03, 0x02, 0xa2, - 0x02, 0xa3, 0x00, 0x01, 0x02, 0xa4, 0x02, 0xa8, 0x00, 0x03, 0x02, 0xa9, - 0x02, 0xaa, 0x00, 0x01, 0x02, 0xab, 0x02, 0xaf, 0x00, 0x03, 0x02, 0xb0, - 0x02, 0xb0, 0x00, 0x01, 0x02, 0xb1, 0x02, 0xb9, 0x00, 0x03, 0x02, 0xba, - 0x02, 0xc0, 0x00, 0x01, 0x02, 0xc1, 0x02, 0xc6, 0x00, 0x03, 0x02, 0xc7, - 0x02, 0xc7, 0x00, 0x01, 0x02, 0xc8, 0x02, 0xc8, 0x00, 0x03, 0x02, 0xc9, - 0x04, 0x75, 0x00, 0x01, 0x04, 0x76, 0x04, 0x81, 0x00, 0x03, 0x04, 0x82, - 0x04, 0xc8, 0x00, 0x01, 0x04, 0xc9, 0x04, 0xc9, 0x00, 0x03, 0x04, 0xca, - 0x04, 0xcb, 0x00, 0x01, 0x04, 0xcc, 0x04, 0xd9, 0x00, 0x03, 0x04, 0xda, - 0x0b, 0xa1, 0x00, 0x01, 0x0b, 0xa2, 0x0b, 0xa3, 0x00, 0x02, 0x0b, 0xa4, - 0x0c, 0x6f, 0x00, 0x01, 0x0c, 0x70, 0x0c, 0x77, 0x00, 0x02, 0x0c, 0x78, - 0x0c, 0xed, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0xb0, 0x00, 0xf8, 0x00, 0x06, - 0x44, 0x46, 0x4c, 0x54, 0x00, 0x26, 0x61, 0x72, 0x61, 0x62, 0x00, 0x30, - 0x63, 0x79, 0x72, 0x6c, 0x00, 0x3e, 0x67, 0x72, 0x65, 0x6b, 0x00, 0x50, - 0x6c, 0x61, 0x6f, 0x20, 0x00, 0x5c, 0x6c, 0x61, 0x74, 0x6e, 0x00, 0x6a, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x0a, 0x00, 0x01, 0x53, 0x52, 0x42, 0x20, 0x00, 0x0a, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x01, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x01, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x34, 0x00, 0x08, - 0x49, 0x53, 0x4d, 0x20, 0x00, 0x34, 0x4b, 0x53, 0x4d, 0x20, 0x00, 0x34, - 0x4c, 0x53, 0x4d, 0x20, 0x00, 0x34, 0x4d, 0x4f, 0x4c, 0x20, 0x00, 0x34, - 0x4e, 0x53, 0x4d, 0x20, 0x00, 0x34, 0x52, 0x4f, 0x4d, 0x20, 0x00, 0x34, - 0x53, 0x4b, 0x53, 0x20, 0x00, 0x34, 0x53, 0x53, 0x4d, 0x20, 0x00, 0x34, - 0x00, 0x00, 0xff, 0xff, 0x00, 0x01, 0x00, 0x01, 0x00, 0x05, 0x6d, 0x61, - 0x72, 0x6b, 0x00, 0x20, 0x6d, 0x61, 0x72, 0x6b, 0x00, 0x2c, 0x6d, 0x61, - 0x72, 0x6b, 0x00, 0x34, 0x6d, 0x6b, 0x6d, 0x6b, 0x00, 0x3a, 0x72, 0x74, - 0x62, 0x64, 0x00, 0x42, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x03, - 0x00, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0x00, 0x07, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x16, - 0x00, 0x1e, 0x00, 0x26, 0x00, 0x2e, 0x00, 0x36, 0x00, 0x3e, 0x00, 0x46, - 0x00, 0x50, 0x00, 0x58, 0x00, 0x60, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01, - 0x00, 0x52, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01, 0x00, 0x78, 0x00, 0x05, - 0x00, 0x01, 0x00, 0x01, 0x00, 0xc0, 0x00, 0x04, 0x00, 0x01, 0x00, 0x01, - 0x01, 0x9a, 0x00, 0x05, 0x00, 0x01, 0x00, 0x01, 0x09, 0x7c, 0x00, 0x04, - 0x00, 0x01, 0x00, 0x01, 0x0a, 0x9e, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, - 0x12, 0x84, 0x1b, 0xa4, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x35, 0xaa, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x35, 0xd2, 0x00, 0x01, 0x00, 0x08, - 0x00, 0x01, 0x38, 0x3a, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x16, 0x00, 0x01, - 0x00, 0x22, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x04, 0x00, 0x01, 0x02, 0x70, - 0xfd, 0xe4, 0x00, 0x01, 0x00, 0x01, 0x04, 0x80, 0x00, 0x01, 0x00, 0x01, - 0x04, 0x7b, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x26, 0x00, 0x1e, 0x00, 0x01, 0x00, 0x30, - 0x00, 0x0c, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x01, 0x02, 0x63, - 0x07, 0x22, 0x00, 0x01, 0x02, 0x63, 0x06, 0xe0, 0x00, 0x01, 0x00, 0x02, - 0x04, 0x7c, 0x04, 0x7f, 0x00, 0x01, 0x00, 0x03, 0x04, 0x79, 0x04, 0x7a, - 0x04, 0x7d, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x14, - 0x00, 0x00, 0x00, 0x1a, 0x00, 0x01, 0x02, 0x5d, 0x04, 0x6a, 0x00, 0x01, - 0x02, 0x5d, 0x04, 0x6a, 0x00, 0x01, 0x02, 0x62, 0x04, 0x6a, 0x00, 0x01, - 0x00, 0xb8, 0x00, 0xae, 0x00, 0x01, 0x00, 0xc2, 0x00, 0x0c, 0x00, 0x08, - 0x00, 0x12, 0x00, 0x24, 0x00, 0x36, 0x00, 0x48, 0x00, 0x5a, 0x00, 0x6c, - 0x00, 0x7e, 0x00, 0x90, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x01, - 0x03, 0xe0, 0x00, 0x50, 0x00, 0x01, 0x03, 0x7c, 0x00, 0x48, 0x00, 0x02, - 0x00, 0x06, 0x00, 0x0c, 0x00, 0x01, 0x03, 0x30, 0xff, 0xe0, 0x00, 0x01, - 0x02, 0xac, 0xff, 0xdc, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x01, - 0x03, 0xe0, 0x00, 0x50, 0x00, 0x01, 0x03, 0x7c, 0x00, 0x48, 0x00, 0x02, - 0x00, 0x06, 0x00, 0x0c, 0x00, 0x01, 0x03, 0x3c, 0xff, 0x88, 0x00, 0x01, - 0x02, 0x50, 0xff, 0x84, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x01, - 0x03, 0xa8, 0x00, 0x2c, 0x00, 0x01, 0x01, 0x20, 0xfd, 0xdc, 0x00, 0x02, - 0x00, 0x06, 0x00, 0x0c, 0x00, 0x01, 0x03, 0x54, 0xff, 0x60, 0x00, 0x01, - 0x01, 0x0c, 0xfd, 0xdc, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x01, - 0x03, 0xe0, 0x00, 0x50, 0x00, 0x01, 0x03, 0x7c, 0x00, 0x48, 0x00, 0x02, - 0x00, 0x06, 0x00, 0x0c, 0x00, 0x01, 0x02, 0x0c, 0xff, 0xa4, 0x00, 0x01, - 0x03, 0x10, 0x00, 0x20, 0x00, 0x02, 0x00, 0x01, 0x0c, 0x70, 0x0c, 0x77, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x04, 0x78, 0x04, 0x7b, 0x04, 0x80, - 0x00, 0x03, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, - 0x00, 0x1a, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x07, 0xc0, - 0x07, 0x6e, 0x00, 0x01, 0x07, 0xca, 0x00, 0x0c, 0x00, 0xec, 0x01, 0xda, - 0x01, 0xe0, 0x01, 0xe6, 0x01, 0xec, 0x01, 0xf2, 0x01, 0xf8, 0x01, 0xfe, - 0x02, 0x04, 0x02, 0x0a, 0x02, 0x10, 0x02, 0x16, 0x02, 0x1c, 0x02, 0x22, - 0x02, 0x28, 0x02, 0x2e, 0x02, 0x34, 0x02, 0x3a, 0x02, 0x40, 0x02, 0x46, - 0x02, 0x4c, 0x02, 0x52, 0x02, 0x58, 0x02, 0x5e, 0x02, 0x64, 0x02, 0x6a, - 0x02, 0x70, 0x02, 0x76, 0x02, 0x7c, 0x02, 0x82, 0x02, 0x88, 0x02, 0x8e, - 0x02, 0x94, 0x02, 0x9a, 0x02, 0xa0, 0x02, 0xa6, 0x02, 0xac, 0x02, 0xb2, - 0x02, 0xb8, 0x02, 0xbe, 0x02, 0xc4, 0x02, 0xca, 0x02, 0xd0, 0x02, 0xd6, - 0x02, 0xdc, 0x02, 0xe2, 0x02, 0xe8, 0x02, 0xee, 0x02, 0xf4, 0x02, 0xfa, - 0x03, 0x00, 0x03, 0x06, 0x03, 0x0c, 0x03, 0x12, 0x03, 0x18, 0x03, 0x1e, - 0x03, 0x24, 0x03, 0x2a, 0x03, 0x30, 0x03, 0x36, 0x03, 0x3c, 0x03, 0x42, - 0x03, 0x48, 0x03, 0x4e, 0x03, 0x54, 0x03, 0x5a, 0x03, 0x60, 0x03, 0x66, - 0x03, 0x6c, 0x03, 0x72, 0x03, 0x78, 0x03, 0x7e, 0x03, 0x84, 0x03, 0x8a, - 0x03, 0x90, 0x03, 0x96, 0x03, 0x9c, 0x03, 0xa2, 0x03, 0xa8, 0x03, 0xae, - 0x03, 0xb4, 0x03, 0xba, 0x03, 0xc0, 0x03, 0xc6, 0x03, 0xcc, 0x03, 0xd2, - 0x03, 0xd8, 0x03, 0xde, 0x03, 0xe4, 0x03, 0xea, 0x03, 0xf0, 0x03, 0xf6, - 0x03, 0xfc, 0x04, 0x02, 0x04, 0x08, 0x04, 0x0e, 0x04, 0x14, 0x04, 0x1a, - 0x04, 0x20, 0x04, 0x26, 0x04, 0x2c, 0x04, 0x32, 0x04, 0x38, 0x04, 0x3e, - 0x04, 0x44, 0x04, 0x4a, 0x04, 0x50, 0x04, 0x56, 0x04, 0x5c, 0x04, 0x62, - 0x04, 0x68, 0x04, 0x6e, 0x04, 0x74, 0x04, 0x7a, 0x04, 0x80, 0x04, 0x86, - 0x04, 0x8c, 0x04, 0x92, 0x04, 0x98, 0x04, 0x9e, 0x04, 0xa4, 0x04, 0xaa, - 0x04, 0xb0, 0x04, 0xb6, 0x04, 0xbc, 0x04, 0xc2, 0x04, 0xc8, 0x04, 0xce, - 0x04, 0xd4, 0x04, 0xda, 0x04, 0xe0, 0x04, 0xe6, 0x04, 0xec, 0x04, 0xf2, - 0x04, 0xf8, 0x04, 0xfe, 0x05, 0x04, 0x05, 0x0a, 0x05, 0x10, 0x05, 0x16, - 0x05, 0x1c, 0x05, 0x22, 0x05, 0x28, 0x05, 0x2e, 0x05, 0x34, 0x05, 0x3a, - 0x05, 0x40, 0x05, 0x46, 0x05, 0x4c, 0x05, 0x52, 0x05, 0x58, 0x05, 0x5e, - 0x05, 0x64, 0x05, 0x6a, 0x05, 0x70, 0x05, 0x76, 0x05, 0x7c, 0x05, 0x82, - 0x05, 0x88, 0x05, 0x8e, 0x05, 0x94, 0x05, 0x9a, 0x05, 0xa0, 0x05, 0xa6, - 0x05, 0xac, 0x05, 0xb2, 0x05, 0xb8, 0x05, 0xbe, 0x05, 0xc4, 0x05, 0xca, - 0x05, 0xd0, 0x05, 0xd6, 0x05, 0xdc, 0x05, 0xe2, 0x05, 0xe8, 0x05, 0xee, - 0x05, 0xf4, 0x05, 0xfa, 0x06, 0x00, 0x06, 0x06, 0x06, 0x0c, 0x06, 0x12, - 0x06, 0x18, 0x06, 0x1e, 0x06, 0x24, 0x06, 0x2a, 0x06, 0x30, 0x06, 0x36, - 0x06, 0x3c, 0x06, 0x42, 0x06, 0x48, 0x06, 0x4e, 0x06, 0x54, 0x06, 0x5a, - 0x06, 0x60, 0x06, 0x66, 0x06, 0x6c, 0x06, 0x72, 0x06, 0x78, 0x06, 0x7e, - 0x06, 0x84, 0x06, 0x8a, 0x06, 0x90, 0x06, 0x96, 0x06, 0x9c, 0x06, 0xa2, - 0x06, 0xa8, 0x06, 0xae, 0x06, 0xb4, 0x06, 0xba, 0x06, 0xc0, 0x06, 0xc6, - 0x06, 0xcc, 0x06, 0xd2, 0x06, 0xd8, 0x06, 0xde, 0x06, 0xe4, 0x06, 0xea, - 0x06, 0xf0, 0x06, 0xf6, 0x06, 0xfc, 0x07, 0x02, 0x07, 0x08, 0x07, 0x0e, - 0x07, 0x14, 0x07, 0x1a, 0x07, 0x20, 0x07, 0x26, 0x07, 0x2c, 0x07, 0x32, - 0x07, 0x38, 0x07, 0x3e, 0x07, 0x44, 0x07, 0x4a, 0x07, 0x50, 0x07, 0x56, - 0x07, 0x5c, 0x00, 0x01, 0x02, 0x58, 0x00, 0x00, 0x00, 0x01, 0x02, 0x64, - 0xfd, 0xdf, 0x00, 0x01, 0x01, 0xd4, 0x02, 0x7c, 0x00, 0x01, 0x02, 0x64, - 0xff, 0xb2, 0x00, 0x01, 0x02, 0x68, 0xfe, 0x88, 0x00, 0x01, 0x02, 0x30, - 0xff, 0x60, 0x00, 0x01, 0x02, 0x74, 0xff, 0x58, 0x00, 0x01, 0x02, 0x74, - 0xff, 0x58, 0x00, 0x01, 0x01, 0xfc, 0xfd, 0xcc, 0x00, 0x01, 0x02, 0x0c, - 0xfd, 0xd0, 0x00, 0x01, 0x02, 0x3c, 0xfd, 0xb7, 0x00, 0x01, 0x02, 0x08, - 0xff, 0x7c, 0x00, 0x01, 0x02, 0x08, 0xff, 0x8c, 0x00, 0x01, 0x02, 0x30, - 0xfd, 0xe0, 0x00, 0x01, 0x02, 0x30, 0xfd, 0xec, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x4c, 0x00, 0x01, 0x02, 0xa0, 0xfe, 0x84, 0x00, 0x01, 0x03, 0x28, - 0xfe, 0xdc, 0x00, 0x01, 0x03, 0x20, 0xfe, 0xc0, 0x00, 0x01, 0x01, 0x54, - 0xff, 0x70, 0x00, 0x01, 0x01, 0x6c, 0xff, 0x78, 0x00, 0x01, 0x02, 0x90, - 0xfd, 0xcc, 0x00, 0x01, 0x02, 0x88, 0xfd, 0xd0, 0x00, 0x01, 0x02, 0x60, - 0xff, 0x78, 0x00, 0x01, 0x02, 0x3c, 0xff, 0x44, 0x00, 0x01, 0x02, 0x28, - 0xfe, 0x44, 0x00, 0x01, 0x01, 0xfc, 0xff, 0x64, 0x00, 0x01, 0x02, 0x14, - 0xfe, 0x7c, 0x00, 0x01, 0x02, 0x74, 0xff, 0x58, 0x00, 0x01, 0x02, 0x4c, - 0xfe, 0x5c, 0x00, 0x01, 0x02, 0x38, 0xff, 0x28, 0x00, 0x01, 0x02, 0x50, - 0xfd, 0xdc, 0x00, 0x01, 0x02, 0x40, 0xfe, 0xb4, 0x00, 0x01, 0x02, 0x40, - 0xfd, 0xe0, 0x00, 0x01, 0x02, 0x74, 0xff, 0x58, 0x00, 0x01, 0x02, 0x74, - 0xff, 0x58, 0x00, 0x01, 0x02, 0x34, 0xfd, 0xe8, 0x00, 0x01, 0x02, 0x60, - 0xfd, 0xe0, 0x00, 0x01, 0x02, 0x74, 0xff, 0x58, 0x00, 0x01, 0x02, 0x64, - 0xfd, 0xec, 0x00, 0x01, 0x02, 0x0c, 0xfd, 0xe7, 0x00, 0x01, 0x02, 0x34, - 0xfd, 0xdc, 0x00, 0x01, 0x02, 0x58, 0xfd, 0xdc, 0x00, 0x01, 0x02, 0x48, - 0xfd, 0xe0, 0x00, 0x01, 0x02, 0x2e, 0xfd, 0xe4, 0x00, 0x01, 0x02, 0x11, - 0xfd, 0xe3, 0x00, 0x01, 0x01, 0xd4, 0xff, 0x44, 0x00, 0x01, 0x02, 0x35, - 0xff, 0x6a, 0x00, 0x01, 0x02, 0x54, 0xff, 0x6a, 0x00, 0x01, 0x02, 0x60, - 0xff, 0x5f, 0x00, 0x01, 0x02, 0x0d, 0xfe, 0x70, 0x00, 0x01, 0x02, 0x69, - 0xfd, 0xa8, 0x00, 0x01, 0x02, 0x46, 0xfd, 0xa8, 0x00, 0x01, 0x02, 0x57, - 0xfd, 0xda, 0x00, 0x01, 0x02, 0x57, 0xfd, 0xda, 0x00, 0x01, 0x02, 0x85, - 0xfd, 0xa8, 0x00, 0x01, 0x02, 0x40, 0xfd, 0xa8, 0x00, 0x01, 0x02, 0x54, - 0xfd, 0xda, 0x00, 0x01, 0x02, 0x51, 0xfd, 0xda, 0x00, 0x01, 0x02, 0x58, - 0xfd, 0xa8, 0x00, 0x01, 0x02, 0x3a, 0xfd, 0xa8, 0x00, 0x01, 0x02, 0x42, - 0xfd, 0xda, 0x00, 0x01, 0x02, 0x60, 0xfd, 0xda, 0x00, 0x01, 0x02, 0x82, - 0xff, 0x6a, 0x00, 0x01, 0x02, 0x4c, 0xff, 0x6a, 0x00, 0x01, 0x02, 0x5b, - 0xff, 0x9b, 0x00, 0x01, 0x02, 0x5a, 0xff, 0x9c, 0x00, 0x01, 0x02, 0x5b, - 0xff, 0x6a, 0x00, 0x01, 0x02, 0x49, 0xff, 0x6a, 0x00, 0x01, 0x02, 0x57, - 0xff, 0x9c, 0x00, 0x01, 0x02, 0x54, 0xff, 0x9c, 0x00, 0x01, 0x02, 0x4c, - 0xff, 0x6a, 0x00, 0x01, 0x02, 0x34, 0xff, 0x6a, 0x00, 0x01, 0x02, 0x4b, - 0xff, 0x9c, 0x00, 0x01, 0x02, 0x5d, 0xff, 0x9c, 0x00, 0x01, 0x01, 0xd4, - 0xff, 0x4c, 0x00, 0x01, 0x01, 0x94, 0xff, 0x40, 0x00, 0x01, 0x01, 0xf4, - 0xff, 0x6a, 0x00, 0x01, 0x02, 0x56, 0xff, 0x6a, 0x00, 0x01, 0x01, 0xe0, - 0xff, 0x38, 0x00, 0x01, 0x01, 0x88, 0xff, 0x38, 0x00, 0x01, 0x01, 0xf4, - 0xff, 0x6a, 0x00, 0x01, 0x02, 0x62, 0xff, 0x6a, 0x00, 0x01, 0x02, 0x74, - 0xfd, 0xa8, 0x00, 0x01, 0x02, 0x5c, 0xfd, 0xa8, 0x00, 0x01, 0x01, 0xac, - 0xfe, 0x0c, 0x00, 0x01, 0x02, 0x58, 0xfe, 0x0c, 0x00, 0x01, 0x02, 0x54, - 0xfd, 0xa8, 0x00, 0x01, 0x02, 0x48, 0xfd, 0xa8, 0x00, 0x01, 0x01, 0x84, - 0xff, 0x06, 0x00, 0x01, 0x02, 0x58, 0xff, 0x06, 0x00, 0x01, 0x02, 0x54, - 0xfd, 0xa8, 0x00, 0x01, 0x02, 0x38, 0xfd, 0xa7, 0x00, 0x01, 0x01, 0xb8, - 0xfd, 0xe4, 0x00, 0x01, 0x02, 0x58, 0xfe, 0x0c, 0x00, 0x01, 0x02, 0x68, - 0xfd, 0xa8, 0x00, 0x01, 0x02, 0x64, 0xfd, 0xa8, 0x00, 0x01, 0x01, 0xc4, - 0xfd, 0xe4, 0x00, 0x01, 0x02, 0x58, 0xfe, 0x0c, 0x00, 0x01, 0x01, 0xf4, - 0xfe, 0x0c, 0x00, 0x01, 0x01, 0xf4, 0xfe, 0x0c, 0x00, 0x01, 0x01, 0xf4, - 0xfe, 0x0c, 0x00, 0x01, 0x01, 0xf4, 0xfe, 0x0c, 0x00, 0x01, 0x02, 0x3f, - 0xff, 0x6a, 0x00, 0x01, 0x01, 0xc6, 0xff, 0x6a, 0x00, 0x01, 0x01, 0x2c, - 0xff, 0x6a, 0x00, 0x01, 0x01, 0x2c, 0xff, 0x6a, 0x00, 0x01, 0x02, 0x54, - 0xff, 0x5f, 0x00, 0x01, 0x01, 0xee, 0xff, 0x6a, 0x00, 0x01, 0x01, 0x2c, - 0xff, 0x6a, 0x00, 0x01, 0x01, 0x2c, 0xff, 0x6a, 0x00, 0x01, 0x02, 0x54, - 0xff, 0x64, 0x00, 0x01, 0x02, 0x54, 0xff, 0x64, 0x00, 0x01, 0x01, 0xb8, - 0xff, 0x64, 0x00, 0x01, 0x02, 0x10, 0xff, 0x64, 0x00, 0x01, 0x02, 0x4c, - 0xfe, 0x70, 0x00, 0x01, 0x01, 0x98, 0xfe, 0x70, 0x00, 0x01, 0x02, 0x4f, - 0xfe, 0xa2, 0x00, 0x01, 0x02, 0x5b, 0xfe, 0xa2, 0x00, 0x01, 0x02, 0xc0, - 0x00, 0x1c, 0x00, 0x01, 0x02, 0x64, 0xfd, 0xd8, 0x00, 0x01, 0x02, 0xcc, - 0xfd, 0xd8, 0x00, 0x01, 0x02, 0x18, 0xff, 0x80, 0x00, 0x01, 0x02, 0x64, - 0xff, 0x58, 0x00, 0x01, 0x02, 0x64, 0xff, 0x78, 0x00, 0x01, 0x02, 0xb0, - 0xff, 0x58, 0x00, 0x01, 0x02, 0x64, 0xfe, 0x68, 0x00, 0x01, 0x02, 0x1c, - 0xfe, 0x68, 0x00, 0x01, 0x02, 0x44, 0xfe, 0x8c, 0x00, 0x01, 0x02, 0x58, - 0xfe, 0x8c, 0x00, 0x01, 0x02, 0x2c, 0xff, 0x4c, 0x00, 0x01, 0x02, 0x6c, - 0xff, 0x84, 0x00, 0x01, 0x02, 0x6c, 0xff, 0x84, 0x00, 0x01, 0x02, 0x54, - 0xff, 0x70, 0x00, 0x01, 0x02, 0x3c, 0xff, 0x84, 0x00, 0x01, 0x02, 0x58, - 0xff, 0x7c, 0x00, 0x01, 0x02, 0x6c, 0xff, 0x84, 0x00, 0x01, 0x02, 0x48, - 0xff, 0x80, 0x00, 0x01, 0x02, 0x48, 0xff, 0x7c, 0x00, 0x01, 0x02, 0x54, - 0xff, 0x74, 0x00, 0x01, 0x02, 0x00, 0xfd, 0x90, 0x00, 0x01, 0x02, 0x00, - 0xfd, 0x90, 0x00, 0x01, 0x02, 0x08, 0xfe, 0x88, 0x00, 0x01, 0x02, 0x0c, - 0xfe, 0x6c, 0x00, 0x01, 0x02, 0x00, 0xfd, 0x90, 0x00, 0x01, 0x02, 0x00, - 0xfd, 0x90, 0x00, 0x01, 0x01, 0x3c, 0xff, 0x84, 0x00, 0x01, 0x01, 0x54, - 0xff, 0x70, 0x00, 0x01, 0x02, 0x00, 0xfd, 0x90, 0x00, 0x01, 0x02, 0x00, - 0xfd, 0x90, 0x00, 0x01, 0x01, 0x7c, 0xff, 0x80, 0x00, 0x01, 0x01, 0x44, - 0xff, 0x5c, 0x00, 0x01, 0x02, 0x38, 0xff, 0x5c, 0x00, 0x01, 0x02, 0x38, - 0xff, 0x5c, 0x00, 0x01, 0x02, 0x38, 0xff, 0x5c, 0x00, 0x01, 0x02, 0x38, - 0xff, 0x5c, 0x00, 0x01, 0x01, 0xbc, 0xfd, 0xc0, 0x00, 0x01, 0x01, 0x8c, - 0xfd, 0xbd, 0x00, 0x01, 0x01, 0xbc, 0xfd, 0xc0, 0x00, 0x01, 0x01, 0x9c, - 0xfd, 0xbc, 0x00, 0x01, 0x01, 0x98, 0xfe, 0x0c, 0x00, 0x01, 0x01, 0x58, - 0xfe, 0x10, 0x00, 0x01, 0x01, 0x2c, 0xff, 0x6c, 0x00, 0x01, 0x01, 0x10, - 0xff, 0x64, 0x00, 0x01, 0x01, 0x5c, 0xfe, 0x1c, 0x00, 0x01, 0x01, 0x09, - 0xfe, 0x18, 0x00, 0x01, 0x01, 0x2c, 0xff, 0x6c, 0x00, 0x01, 0x01, 0x2c, - 0xff, 0x6c, 0x00, 0x01, 0x01, 0x78, 0xfe, 0x14, 0x00, 0x01, 0x01, 0x44, - 0xfe, 0x11, 0x00, 0x01, 0x01, 0x2c, 0xff, 0x6c, 0x00, 0x01, 0x01, 0x2c, - 0xff, 0x6c, 0x00, 0x01, 0x01, 0x4c, 0xfe, 0x10, 0x00, 0x01, 0x01, 0x20, - 0xfe, 0x18, 0x00, 0x01, 0x01, 0x2c, 0xff, 0x6c, 0x00, 0x01, 0x01, 0x04, - 0xff, 0x6c, 0x00, 0x01, 0x00, 0xf0, 0xff, 0x6c, 0x00, 0x01, 0x00, 0xd8, - 0xff, 0x6c, 0x00, 0x01, 0x00, 0xf0, 0xff, 0x6c, 0x00, 0x01, 0x00, 0xd0, - 0xff, 0x70, 0x00, 0x01, 0x00, 0xf0, 0xff, 0x6c, 0x00, 0x01, 0x00, 0xd0, - 0xff, 0x68, 0x00, 0x01, 0x00, 0xf0, 0xff, 0x6c, 0x00, 0x01, 0x00, 0xdc, - 0xff, 0x6c, 0x00, 0x01, 0x01, 0x7a, 0xfd, 0xd7, 0x00, 0x01, 0x01, 0x7a, - 0xfd, 0xd7, 0x00, 0x01, 0x01, 0xe0, 0xff, 0x93, 0x00, 0x01, 0x02, 0x5e, - 0xff, 0x8d, 0x00, 0x01, 0x01, 0x7a, 0xfd, 0xd7, 0x00, 0x01, 0x01, 0x7a, - 0xfd, 0xd7, 0x00, 0x01, 0x01, 0x92, 0xff, 0x9f, 0x00, 0x01, 0x02, 0x5e, - 0xff, 0x9f, 0x00, 0x01, 0x02, 0x5e, 0xff, 0x2d, 0x00, 0x01, 0x02, 0x64, - 0xff, 0x0f, 0x00, 0x01, 0x01, 0x9e, 0xff, 0x75, 0x00, 0x01, 0x02, 0x6a, - 0xff, 0x81, 0x00, 0x01, 0x01, 0xe0, 0xfe, 0x19, 0x00, 0x01, 0x01, 0xe0, - 0xfd, 0xb9, 0x00, 0x01, 0x01, 0x38, 0xff, 0x8d, 0x00, 0x01, 0x02, 0x6a, - 0xff, 0x81, 0x00, 0x01, 0x02, 0x3a, 0xff, 0x4b, 0x00, 0x01, 0x01, 0xda, - 0xff, 0x51, 0x00, 0x01, 0x00, 0xd8, 0xff, 0x81, 0x00, 0x01, 0x00, 0xa2, - 0xff, 0x5d, 0x00, 0x01, 0x02, 0x58, 0xfe, 0x6d, 0x00, 0x01, 0x01, 0xfe, - 0xfe, 0x61, 0x00, 0x01, 0x02, 0x64, 0xff, 0x87, 0x00, 0x01, 0x02, 0x6a, - 0xff, 0x75, 0x00, 0x01, 0x03, 0x12, 0xff, 0x75, 0x00, 0x01, 0x02, 0xac, - 0xfe, 0xa3, 0x00, 0x01, 0x02, 0x46, 0xff, 0x15, 0x00, 0x01, 0x02, 0x58, - 0xff, 0x27, 0x00, 0x01, 0x01, 0xfe, 0xfe, 0x55, 0x00, 0x01, 0x01, 0xc2, - 0xfd, 0xc5, 0x00, 0x01, 0x02, 0x40, 0xff, 0x81, 0x00, 0x01, 0x02, 0x4c, - 0xff, 0x7b, 0x00, 0x01, 0x02, 0x52, 0xff, 0x4b, 0x00, 0x01, 0x02, 0x52, - 0xff, 0x6f, 0x00, 0x01, 0x01, 0xb0, 0xff, 0x27, 0x00, 0x01, 0x02, 0x10, - 0xfd, 0xd2, 0x00, 0x01, 0x02, 0x4c, 0xfd, 0xe9, 0x00, 0x01, 0x02, 0x04, - 0xfd, 0xd1, 0x00, 0x01, 0x02, 0x2e, 0xfe, 0x91, 0x00, 0x01, 0x02, 0x1c, - 0xfd, 0xad, 0x00, 0x01, 0x01, 0x92, 0xfd, 0xbc, 0x00, 0x01, 0x02, 0x3a, - 0xfe, 0x8b, 0x00, 0x01, 0x02, 0x52, 0xfe, 0x85, 0x00, 0x01, 0x02, 0x78, - 0xfd, 0xd0, 0x00, 0x01, 0x02, 0x74, 0xff, 0x58, 0x00, 0x01, 0x02, 0x44, - 0xfd, 0xd8, 0x00, 0x01, 0x01, 0xf4, 0xfd, 0xd0, 0x00, 0x01, 0x02, 0x34, - 0xfd, 0xe0, 0x00, 0x01, 0x02, 0x45, 0xfd, 0xdf, 0x00, 0x01, 0x02, 0x08, - 0xfe, 0x6e, 0x00, 0x01, 0x02, 0x50, 0xfd, 0xdc, 0x00, 0x01, 0x02, 0x0d, - 0xfe, 0x70, 0x00, 0x02, 0x00, 0x0d, 0x04, 0x51, 0x04, 0x51, 0x00, 0x00, - 0x04, 0x55, 0x04, 0x75, 0x00, 0x01, 0x04, 0x91, 0x04, 0xa1, 0x00, 0x22, - 0x0b, 0xa4, 0x0b, 0xdf, 0x00, 0x33, 0x0b, 0xe2, 0x0b, 0xe5, 0x00, 0x6f, - 0x0b, 0xe8, 0x0b, 0xeb, 0x00, 0x73, 0x0b, 0xfb, 0x0b, 0xfb, 0x00, 0x77, - 0x0c, 0x02, 0x0c, 0x03, 0x00, 0x78, 0x0c, 0x06, 0x0c, 0x6a, 0x00, 0x7a, - 0x0c, 0x6c, 0x0c, 0x6f, 0x00, 0xdf, 0x0c, 0xe2, 0x0c, 0xe7, 0x00, 0xe3, - 0x0c, 0xe9, 0x0c, 0xe9, 0x00, 0xe9, 0x0c, 0xeb, 0x0c, 0xec, 0x00, 0xea, - 0x00, 0x01, 0x00, 0x03, 0x04, 0x78, 0x04, 0x7b, 0x04, 0x80, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1a, - 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, - 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb8, 0x00, 0xae, - 0x00, 0x01, 0x00, 0xce, 0x00, 0x0c, 0x00, 0x08, 0x00, 0x12, 0x00, 0x24, - 0x00, 0x36, 0x00, 0x48, 0x00, 0x5a, 0x00, 0x6c, 0x00, 0x7e, 0x00, 0x90, - 0x00, 0x02, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x01, 0x03, 0x9c, 0x06, 0x68, - 0x00, 0x01, 0x00, 0x93, 0x07, 0x35, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0c, - 0x00, 0x01, 0x03, 0x9c, 0x06, 0x68, 0x00, 0x01, 0x00, 0x5b, 0x07, 0x19, - 0x00, 0x02, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x01, 0x03, 0x9c, 0x06, 0x68, - 0x00, 0x01, 0x00, 0x9b, 0x07, 0xf6, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0c, - 0x00, 0x01, 0x03, 0x54, 0x06, 0x6c, 0x00, 0x01, 0x00, 0x2b, 0x07, 0xfa, - 0x00, 0x02, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x01, 0x03, 0x9c, 0x06, 0x68, - 0x00, 0x01, 0x00, 0xdf, 0x05, 0xdd, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0c, - 0x00, 0x01, 0x03, 0x9c, 0x06, 0x68, 0x00, 0x01, 0x00, 0xdf, 0x05, 0xdd, - 0x00, 0x02, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x01, 0x03, 0x9c, 0x06, 0x68, - 0x00, 0x01, 0x00, 0xdf, 0x05, 0xdd, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0c, - 0x00, 0x01, 0x03, 0x5c, 0x06, 0x68, 0x00, 0x01, 0x00, 0x9f, 0x05, 0xdd, - 0x00, 0x02, 0x00, 0x01, 0x0c, 0x70, 0x0c, 0x77, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x09, 0x04, 0x76, 0x04, 0x77, 0x04, 0x79, 0x04, 0x7a, 0x04, 0x7c, - 0x04, 0x7d, 0x04, 0x7e, 0x04, 0x7f, 0x04, 0x81, 0x00, 0x09, 0x00, 0x00, - 0x00, 0x26, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, - 0x00, 0x38, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, - 0x00, 0x4a, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x56, 0x00, 0x01, - 0x02, 0x5d, 0x04, 0x6a, 0x00, 0x01, 0x02, 0x5d, 0x04, 0x6a, 0x00, 0x01, - 0x02, 0x5d, 0x04, 0x6a, 0x00, 0x01, 0x02, 0x5d, 0x04, 0x6a, 0x00, 0x01, - 0x02, 0x5d, 0x04, 0x6a, 0x00, 0x01, 0x02, 0x62, 0x04, 0x6a, 0x00, 0x01, - 0x02, 0x5d, 0x04, 0x6a, 0x00, 0x01, 0x02, 0x5d, 0x04, 0x6a, 0x00, 0x01, - 0x02, 0x68, 0x04, 0xb0, 0x00, 0x01, 0x07, 0x7c, 0x07, 0x1e, 0x00, 0x01, - 0x07, 0x92, 0x00, 0x0c, 0x00, 0xe2, 0x01, 0xc6, 0x01, 0xcc, 0x01, 0xd2, - 0x01, 0xd8, 0x01, 0xde, 0x01, 0xe4, 0x01, 0xea, 0x01, 0xf0, 0x01, 0xf6, - 0x01, 0xfc, 0x02, 0x02, 0x02, 0x08, 0x02, 0x0e, 0x02, 0x14, 0x02, 0x1a, - 0x02, 0x20, 0x02, 0x26, 0x02, 0x2c, 0x02, 0x32, 0x02, 0x38, 0x02, 0x3e, - 0x02, 0x44, 0x02, 0x4a, 0x02, 0x50, 0x02, 0x56, 0x02, 0x5c, 0x02, 0x62, - 0x02, 0x68, 0x02, 0x6e, 0x02, 0x74, 0x02, 0x7a, 0x02, 0x80, 0x02, 0x86, - 0x02, 0x8c, 0x02, 0x92, 0x02, 0x98, 0x02, 0x9e, 0x02, 0xa4, 0x02, 0xaa, - 0x02, 0xb0, 0x02, 0xb6, 0x02, 0xbc, 0x02, 0xc2, 0x02, 0xc8, 0x02, 0xce, - 0x02, 0xd4, 0x02, 0xda, 0x02, 0xe0, 0x02, 0xe6, 0x02, 0xec, 0x02, 0xf2, - 0x02, 0xf8, 0x02, 0xfe, 0x03, 0x04, 0x03, 0x0a, 0x03, 0x10, 0x03, 0x16, - 0x03, 0x1c, 0x03, 0x22, 0x03, 0x28, 0x03, 0x2e, 0x03, 0x34, 0x03, 0x3a, - 0x03, 0x40, 0x03, 0x46, 0x03, 0x4c, 0x03, 0x52, 0x03, 0x58, 0x03, 0x5e, - 0x03, 0x64, 0x03, 0x6a, 0x03, 0x70, 0x03, 0x76, 0x03, 0x7c, 0x03, 0x82, - 0x03, 0x88, 0x03, 0x8e, 0x03, 0x94, 0x03, 0x9a, 0x03, 0xa0, 0x03, 0xa6, - 0x03, 0xac, 0x03, 0xb2, 0x03, 0xb8, 0x03, 0xbe, 0x03, 0xc4, 0x03, 0xca, - 0x03, 0xd0, 0x03, 0xd6, 0x03, 0xdc, 0x03, 0xe2, 0x03, 0xe8, 0x03, 0xee, - 0x03, 0xf4, 0x03, 0xfa, 0x04, 0x00, 0x04, 0x06, 0x04, 0x0c, 0x04, 0x12, - 0x04, 0x18, 0x04, 0x1e, 0x04, 0x24, 0x04, 0x2a, 0x04, 0x30, 0x04, 0x36, - 0x04, 0x3c, 0x04, 0x42, 0x04, 0x48, 0x04, 0x4e, 0x04, 0x54, 0x04, 0x5a, - 0x04, 0x60, 0x04, 0x66, 0x04, 0x6c, 0x04, 0x72, 0x04, 0x78, 0x04, 0x7e, - 0x04, 0x84, 0x04, 0x8a, 0x04, 0x90, 0x04, 0x96, 0x04, 0x9c, 0x04, 0xa2, - 0x04, 0xa8, 0x04, 0xae, 0x04, 0xb4, 0x04, 0xba, 0x04, 0xc0, 0x04, 0xc6, - 0x04, 0xcc, 0x04, 0xd2, 0x04, 0xd8, 0x04, 0xde, 0x04, 0xe4, 0x04, 0xea, - 0x04, 0xf0, 0x04, 0xf6, 0x04, 0xfc, 0x05, 0x02, 0x05, 0x08, 0x05, 0x0e, - 0x05, 0x14, 0x05, 0x1a, 0x05, 0x20, 0x05, 0x26, 0x05, 0x2c, 0x05, 0x32, - 0x05, 0x38, 0x05, 0x3e, 0x05, 0x44, 0x05, 0x4a, 0x05, 0x50, 0x05, 0x56, - 0x05, 0x5c, 0x05, 0x62, 0x05, 0x68, 0x05, 0x6e, 0x05, 0x74, 0x05, 0x7a, - 0x05, 0x80, 0x05, 0x86, 0x05, 0x8c, 0x05, 0x92, 0x05, 0x98, 0x05, 0x9e, - 0x05, 0xa4, 0x05, 0xaa, 0x05, 0xb0, 0x05, 0xb6, 0x05, 0xbc, 0x05, 0xc2, - 0x05, 0xc8, 0x05, 0xce, 0x05, 0xd4, 0x05, 0xda, 0x05, 0xe0, 0x05, 0xe6, - 0x05, 0xec, 0x05, 0xf2, 0x05, 0xf8, 0x05, 0xfe, 0x06, 0x04, 0x06, 0x0a, - 0x06, 0x10, 0x06, 0x16, 0x06, 0x1c, 0x06, 0x22, 0x06, 0x28, 0x06, 0x2e, - 0x06, 0x34, 0x06, 0x3a, 0x06, 0x40, 0x06, 0x46, 0x06, 0x4c, 0x06, 0x52, - 0x06, 0x58, 0x06, 0x5e, 0x06, 0x64, 0x06, 0x6a, 0x06, 0x70, 0x06, 0x76, - 0x06, 0x7c, 0x06, 0x82, 0x06, 0x88, 0x06, 0x8e, 0x06, 0x94, 0x06, 0x9a, - 0x06, 0xa0, 0x06, 0xa6, 0x06, 0xac, 0x06, 0xb2, 0x06, 0xb8, 0x06, 0xbe, - 0x06, 0xc4, 0x06, 0xca, 0x06, 0xd0, 0x06, 0xd6, 0x06, 0xdc, 0x06, 0xe2, - 0x06, 0xe8, 0x06, 0xee, 0x06, 0xf4, 0x06, 0xfa, 0x07, 0x00, 0x07, 0x06, - 0x07, 0x0c, 0x00, 0x01, 0x02, 0x98, 0x04, 0x84, 0x00, 0x01, 0x02, 0x64, - 0x08, 0x74, 0x00, 0x01, 0x02, 0xd0, 0x05, 0x20, 0x00, 0x01, 0x01, 0xcc, - 0x04, 0xb8, 0x00, 0x01, 0x02, 0x68, 0x06, 0xa8, 0x00, 0x01, 0x02, 0x64, - 0x02, 0xfc, 0x00, 0x01, 0x02, 0x38, 0x04, 0xa0, 0x00, 0x01, 0x02, 0x7c, - 0x03, 0xd4, 0x00, 0x01, 0x02, 0x24, 0x04, 0xa0, 0x00, 0x01, 0x01, 0xf4, - 0x04, 0x7c, 0x00, 0x01, 0x02, 0x04, 0x04, 0x60, 0x00, 0x01, 0x02, 0x04, - 0x05, 0x48, 0x00, 0x01, 0x01, 0xd0, 0x04, 0x4c, 0x00, 0x01, 0x01, 0xc0, - 0x05, 0x44, 0x00, 0x01, 0x02, 0x04, 0x02, 0xfc, 0x00, 0x01, 0x01, 0x98, - 0x04, 0x20, 0x00, 0x01, 0x02, 0x5c, 0x03, 0xf0, 0x00, 0x01, 0x01, 0xdc, - 0x05, 0x74, 0x00, 0x01, 0x01, 0x40, 0x03, 0xb8, 0x00, 0x01, 0x01, 0x34, - 0x04, 0x48, 0x00, 0x01, 0x00, 0xe8, 0x06, 0xb8, 0x00, 0x01, 0x00, 0xec, - 0x06, 0xd4, 0x00, 0x01, 0x01, 0x9c, 0x05, 0x28, 0x00, 0x01, 0x01, 0x7c, - 0x05, 0xf4, 0x00, 0x01, 0x02, 0x58, 0x04, 0x54, 0x00, 0x01, 0x02, 0xfc, - 0x05, 0x84, 0x00, 0x01, 0x02, 0x9c, 0x05, 0xf8, 0x00, 0x01, 0x01, 0xf0, - 0x05, 0xcc, 0x00, 0x01, 0x03, 0x90, 0x06, 0xc4, 0x00, 0x01, 0x02, 0x98, - 0x04, 0x28, 0x00, 0x01, 0x01, 0xf8, 0x04, 0x6c, 0x00, 0x01, 0x01, 0xf0, - 0x03, 0xf0, 0x00, 0x01, 0x02, 0x74, 0x03, 0xbc, 0x00, 0x01, 0x02, 0xac, - 0x04, 0x3c, 0x00, 0x01, 0x02, 0x98, 0x04, 0x30, 0x00, 0x01, 0x02, 0xbc, - 0x04, 0xda, 0x00, 0x01, 0x01, 0x18, 0x05, 0x78, 0x00, 0x01, 0x01, 0xae, - 0x05, 0x78, 0x00, 0x01, 0x02, 0x5f, 0x04, 0x60, 0x00, 0x01, 0x01, 0x9f, - 0x03, 0x0c, 0x00, 0x01, 0x02, 0x69, 0x03, 0xe8, 0x00, 0x01, 0x02, 0x46, - 0x03, 0xe8, 0x00, 0x01, 0x02, 0x57, 0x03, 0xe8, 0x00, 0x01, 0x02, 0x57, - 0x03, 0xe8, 0x00, 0x01, 0x02, 0x85, 0x03, 0xe8, 0x00, 0x01, 0x02, 0x40, - 0x03, 0xe8, 0x00, 0x01, 0x02, 0x54, 0x03, 0xe8, 0x00, 0x01, 0x02, 0x54, - 0x03, 0xe8, 0x00, 0x01, 0x02, 0x5b, 0x03, 0xe8, 0x00, 0x01, 0x02, 0x3a, - 0x03, 0xe8, 0x00, 0x01, 0x02, 0x42, 0x03, 0xe8, 0x00, 0x01, 0x02, 0x60, - 0x03, 0xe8, 0x00, 0x01, 0x02, 0x82, 0x04, 0x4c, 0x00, 0x01, 0x02, 0x4c, - 0x04, 0x4c, 0x00, 0x01, 0x02, 0x5b, 0x05, 0x13, 0x00, 0x01, 0x02, 0x5a, - 0x05, 0x14, 0x00, 0x01, 0x02, 0x5b, 0x04, 0x9d, 0x00, 0x01, 0x02, 0x49, - 0x04, 0xaf, 0x00, 0x01, 0x02, 0x57, 0x05, 0x14, 0x00, 0x01, 0x02, 0x54, - 0x05, 0x14, 0x00, 0x01, 0x02, 0x4c, 0x04, 0xe2, 0x00, 0x01, 0x02, 0x34, - 0x04, 0xe2, 0x00, 0x01, 0x02, 0x4b, 0x05, 0xaa, 0x00, 0x01, 0x02, 0x5d, - 0x05, 0xaa, 0x00, 0x01, 0x01, 0x90, 0x05, 0x6c, 0x00, 0x01, 0x01, 0x38, - 0x04, 0xf4, 0x00, 0x01, 0x01, 0xf4, 0x06, 0x40, 0x00, 0x01, 0x02, 0x5e, - 0x05, 0xaa, 0x00, 0x01, 0x01, 0x20, 0x05, 0x20, 0x00, 0x01, 0x01, 0x08, - 0x04, 0xe4, 0x00, 0x01, 0x01, 0xf4, 0x06, 0x40, 0x00, 0x01, 0x02, 0x62, - 0x05, 0xaa, 0x00, 0x01, 0x01, 0xd2, 0x03, 0xe8, 0x00, 0x01, 0x01, 0xba, - 0x03, 0xe8, 0x00, 0x01, 0x01, 0xac, 0x03, 0xe8, 0x00, 0x01, 0x02, 0x58, - 0x03, 0xe8, 0x00, 0x01, 0x01, 0xb2, 0x03, 0xe8, 0x00, 0x01, 0x01, 0xa6, - 0x03, 0xe8, 0x00, 0x01, 0x01, 0x84, 0x03, 0xe8, 0x00, 0x01, 0x02, 0x58, - 0x03, 0xe8, 0x00, 0x01, 0x01, 0xb2, 0x03, 0xe8, 0x00, 0x01, 0x01, 0x96, - 0x03, 0xe7, 0x00, 0x01, 0x01, 0xb8, 0x03, 0xe8, 0x00, 0x01, 0x02, 0x58, - 0x03, 0xe8, 0x00, 0x01, 0x01, 0xc6, 0x03, 0xe8, 0x00, 0x01, 0x01, 0xc2, - 0x03, 0xe8, 0x00, 0x01, 0x01, 0xc4, 0x03, 0xe8, 0x00, 0x01, 0x02, 0x58, - 0x03, 0xe8, 0x00, 0x01, 0x02, 0x6f, 0x04, 0x4d, 0x00, 0x01, 0x02, 0xbc, - 0x04, 0xe2, 0x00, 0x01, 0x02, 0xaa, 0x04, 0xbf, 0x00, 0x01, 0x02, 0x98, - 0x04, 0xf1, 0x00, 0x01, 0x02, 0x21, 0x05, 0x54, 0x00, 0x01, 0x01, 0xb1, - 0x05, 0x19, 0x00, 0x01, 0x01, 0xff, 0x06, 0x0e, 0x00, 0x01, 0x01, 0xf1, - 0x06, 0x0e, 0x00, 0x01, 0x01, 0x8c, 0x05, 0x78, 0x00, 0x01, 0x00, 0xf3, - 0x05, 0x78, 0x00, 0x01, 0x00, 0xfa, 0x06, 0xa4, 0x00, 0x01, 0x00, 0xfa, - 0x06, 0xa4, 0x00, 0x01, 0x02, 0x54, 0x04, 0x80, 0x00, 0x01, 0x02, 0x54, - 0x04, 0x80, 0x00, 0x01, 0x01, 0xb8, 0x04, 0x80, 0x00, 0x01, 0x02, 0x10, - 0x04, 0x80, 0x00, 0x01, 0x01, 0xcc, 0x03, 0x26, 0x00, 0x01, 0x01, 0x94, - 0x02, 0x7e, 0x00, 0x01, 0x02, 0x4f, 0x03, 0xe8, 0x00, 0x01, 0x02, 0x5b, - 0x03, 0xe8, 0x00, 0x01, 0x02, 0xb0, 0x04, 0xb8, 0x00, 0x01, 0x02, 0x0c, - 0x08, 0xd8, 0x00, 0x01, 0x02, 0x58, 0x08, 0xe0, 0x00, 0x01, 0x02, 0x8c, - 0x05, 0x50, 0x00, 0x01, 0x02, 0x58, 0x05, 0x44, 0x00, 0x01, 0x01, 0x80, - 0x04, 0xd8, 0x00, 0x01, 0x01, 0x1c, 0x03, 0xf4, 0x00, 0x01, 0x02, 0x2c, - 0x05, 0x61, 0x00, 0x01, 0x02, 0x44, 0x05, 0x66, 0x00, 0x01, 0x02, 0x5c, - 0x06, 0xd8, 0x00, 0x01, 0x02, 0x50, 0x06, 0xe8, 0x00, 0x01, 0x02, 0x68, - 0x03, 0x3c, 0x00, 0x01, 0x02, 0x10, 0x02, 0xe8, 0x00, 0x01, 0x02, 0x0c, - 0x03, 0xc8, 0x00, 0x01, 0x02, 0x5c, 0x03, 0x9c, 0x00, 0x01, 0x02, 0x04, - 0x04, 0xc8, 0x00, 0x01, 0x02, 0x5c, 0x04, 0xd8, 0x00, 0x01, 0x02, 0x5c, - 0x03, 0xf4, 0x00, 0x01, 0x02, 0x30, 0x04, 0x14, 0x00, 0x01, 0x02, 0x2c, - 0x04, 0xc4, 0x00, 0x01, 0x02, 0x30, 0x04, 0xe0, 0x00, 0x01, 0x02, 0x40, - 0x04, 0xf0, 0x00, 0x01, 0x02, 0x2c, 0x05, 0x00, 0x00, 0x01, 0x02, 0x20, - 0x05, 0x64, 0x00, 0x01, 0x02, 0x20, 0x05, 0x60, 0x00, 0x01, 0x01, 0xf8, - 0x04, 0x80, 0x00, 0x01, 0x01, 0xd4, 0x04, 0x7c, 0x00, 0x01, 0x01, 0x74, - 0x04, 0x4c, 0x00, 0x01, 0x01, 0x60, 0x04, 0x30, 0x00, 0x01, 0x01, 0xdc, - 0x04, 0xa4, 0x00, 0x01, 0x01, 0xc8, 0x04, 0xb0, 0x00, 0x01, 0x01, 0x30, - 0x04, 0x90, 0x00, 0x01, 0x01, 0x80, 0x04, 0x84, 0x00, 0x01, 0x01, 0xdc, - 0x05, 0x40, 0x00, 0x01, 0x01, 0xd8, 0x05, 0x5c, 0x00, 0x01, 0x01, 0x20, - 0x04, 0xe0, 0x00, 0x01, 0x01, 0x18, 0x04, 0xdc, 0x00, 0x01, 0x02, 0x0c, - 0x04, 0xac, 0x00, 0x01, 0x02, 0x04, 0x04, 0xb8, 0x00, 0x01, 0x02, 0x08, - 0x05, 0x54, 0x00, 0x01, 0x02, 0x14, 0x05, 0x60, 0x00, 0x01, 0x02, 0x40, - 0x03, 0x14, 0x00, 0x01, 0x01, 0xb4, 0x03, 0x10, 0x00, 0x01, 0x01, 0x94, - 0x04, 0x4c, 0x00, 0x01, 0x01, 0x38, 0x04, 0x88, 0x00, 0x01, 0x02, 0x34, - 0x04, 0x0f, 0x00, 0x01, 0x01, 0xce, 0x03, 0xb7, 0x00, 0x01, 0x02, 0x35, - 0x03, 0xde, 0x00, 0x01, 0x01, 0xf3, 0x03, 0xc5, 0x00, 0x01, 0x01, 0x18, - 0x05, 0x44, 0x00, 0x01, 0x00, 0xb4, 0x05, 0x38, 0x00, 0x01, 0x01, 0x30, - 0x05, 0x48, 0x00, 0x01, 0x01, 0x0c, 0x05, 0x3c, 0x00, 0x01, 0x01, 0x44, - 0x03, 0x8c, 0x00, 0x01, 0x00, 0xdc, 0x03, 0x3c, 0x00, 0x01, 0x01, 0xc8, - 0x03, 0x98, 0x00, 0x01, 0x01, 0x78, 0x03, 0x88, 0x00, 0x01, 0x01, 0x28, - 0x04, 0x4c, 0x00, 0x01, 0x00, 0xd0, 0x04, 0x58, 0x00, 0x01, 0x01, 0x24, - 0x04, 0x54, 0x00, 0x01, 0x00, 0xd4, 0x04, 0x74, 0x00, 0x01, 0x00, 0xf0, - 0x06, 0xd8, 0x00, 0x01, 0x00, 0xc0, 0x06, 0xdc, 0x00, 0x01, 0x00, 0xe8, - 0x06, 0xdc, 0x00, 0x01, 0x00, 0xc0, 0x06, 0xe4, 0x00, 0x01, 0x00, 0xec, - 0x06, 0xf4, 0x00, 0x01, 0x00, 0xd0, 0x06, 0xe4, 0x00, 0x01, 0x00, 0xf0, - 0x06, 0xe8, 0x00, 0x01, 0x00, 0xc8, 0x06, 0xe0, 0x00, 0x01, 0x01, 0x84, - 0x05, 0x30, 0x00, 0x01, 0x01, 0xa8, 0x04, 0x54, 0x00, 0x01, 0x01, 0xc4, - 0x05, 0x4c, 0x00, 0x01, 0x02, 0x68, 0x04, 0x84, 0x00, 0x01, 0x01, 0x84, - 0x06, 0x30, 0x00, 0x01, 0x01, 0xd8, 0x05, 0x70, 0x00, 0x01, 0x01, 0x80, - 0x06, 0x4c, 0x00, 0x01, 0x02, 0x68, 0x05, 0x3c, 0x00, 0x01, 0x02, 0xf8, - 0x05, 0x70, 0x00, 0x01, 0x02, 0xf8, 0x04, 0xf8, 0x00, 0x01, 0x01, 0xac, - 0x05, 0xb8, 0x00, 0x01, 0x02, 0x6c, 0x05, 0x24, 0x00, 0x01, 0x02, 0x64, - 0x05, 0xac, 0x00, 0x01, 0x02, 0x60, 0x04, 0xd4, 0x00, 0x01, 0x01, 0x30, - 0x05, 0x9c, 0x00, 0x01, 0x02, 0x68, 0x05, 0x38, 0x00, 0x01, 0x02, 0x3c, - 0x06, 0x08, 0x00, 0x01, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x01, 0x01, 0xf7, - 0x05, 0xef, 0x00, 0x01, 0x02, 0x0a, 0x06, 0x14, 0x00, 0x01, 0x02, 0x50, - 0x06, 0x14, 0x00, 0x01, 0x01, 0xc8, 0x06, 0x10, 0x00, 0x01, 0x02, 0x4c, - 0x06, 0x64, 0x00, 0x01, 0x02, 0x68, 0x06, 0xbc, 0x00, 0x01, 0x02, 0x8c, - 0x03, 0xd8, 0x00, 0x01, 0x02, 0x78, 0x03, 0x84, 0x00, 0x01, 0x02, 0x38, - 0x03, 0x84, 0x00, 0x01, 0x02, 0x54, 0x03, 0xb4, 0x00, 0x01, 0x01, 0xe4, - 0x04, 0x88, 0x00, 0x01, 0x01, 0x87, 0x03, 0x52, 0x00, 0x01, 0x02, 0x20, - 0x04, 0x6d, 0x00, 0x01, 0x02, 0x24, 0x04, 0x76, 0x00, 0x01, 0x01, 0xea, - 0x03, 0x88, 0x00, 0x01, 0x02, 0x32, 0x03, 0x7a, 0x00, 0x01, 0x01, 0xaf, - 0x04, 0x60, 0x00, 0x01, 0x01, 0xee, 0x03, 0x1c, 0x00, 0x01, 0x02, 0x83, - 0x03, 0x4d, 0x00, 0x01, 0x02, 0x3b, 0x03, 0x29, 0x00, 0x01, 0x01, 0xfc, - 0x03, 0x52, 0x00, 0x01, 0x01, 0xa6, 0x02, 0x44, 0x00, 0x01, 0x02, 0x05, - 0x03, 0x68, 0x00, 0x01, 0x01, 0x70, 0x02, 0x5f, 0x00, 0x01, 0x02, 0x29, - 0x03, 0x49, 0x00, 0x01, 0x02, 0x20, 0x03, 0x52, 0x00, 0x01, 0x02, 0x7c, - 0x03, 0xd4, 0x00, 0x01, 0x02, 0x6f, 0x04, 0x7e, 0x00, 0x01, 0x03, 0xea, - 0x08, 0x34, 0x00, 0x01, 0x02, 0xd4, 0x04, 0xc4, 0x00, 0x01, 0x01, 0x87, - 0x04, 0x90, 0x00, 0x02, 0x00, 0x0f, 0x04, 0x51, 0x04, 0x51, 0x00, 0x00, - 0x04, 0x53, 0x04, 0x54, 0x00, 0x01, 0x04, 0x56, 0x04, 0x75, 0x00, 0x03, - 0x04, 0x9b, 0x04, 0x9b, 0x00, 0x23, 0x04, 0x9e, 0x04, 0xa1, 0x00, 0x24, - 0x0b, 0xa4, 0x0b, 0xdf, 0x00, 0x28, 0x0b, 0xe2, 0x0b, 0xe5, 0x00, 0x64, - 0x0b, 0xe8, 0x0b, 0xeb, 0x00, 0x68, 0x0b, 0xfb, 0x0b, 0xfb, 0x00, 0x6c, - 0x0b, 0xfe, 0x0c, 0x01, 0x00, 0x6d, 0x0c, 0x04, 0x0c, 0x6f, 0x00, 0x71, - 0x0c, 0xe2, 0x0c, 0xe2, 0x00, 0xdd, 0x0c, 0xe7, 0x0c, 0xe7, 0x00, 0xde, - 0x0c, 0xe9, 0x0c, 0xe9, 0x00, 0xdf, 0x0c, 0xeb, 0x0c, 0xec, 0x00, 0xe0, - 0x00, 0x01, 0x00, 0x09, 0x04, 0x76, 0x04, 0x77, 0x04, 0x79, 0x04, 0x7a, - 0x04, 0x7c, 0x04, 0x7d, 0x04, 0x7e, 0x04, 0x7f, 0x04, 0x81, 0x00, 0x09, - 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x32, - 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x44, - 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x56, - 0x00, 0x01, 0x02, 0x5d, 0x04, 0x6a, 0x00, 0x01, 0x02, 0x5d, 0x04, 0x6a, - 0x00, 0x01, 0x02, 0x5d, 0x04, 0x6a, 0x00, 0x01, 0x02, 0x5d, 0x04, 0x6a, - 0x00, 0x01, 0x02, 0x5d, 0x04, 0x6a, 0x00, 0x01, 0x02, 0x62, 0x04, 0x6a, - 0x00, 0x01, 0x02, 0x5d, 0x04, 0x6a, 0x00, 0x01, 0x02, 0x5d, 0x04, 0x6a, - 0x00, 0x01, 0x02, 0x68, 0x04, 0xb0, 0x00, 0x01, 0x09, 0x0e, 0x08, 0x56, - 0x00, 0x01, 0x09, 0x14, 0x00, 0x0c, 0x01, 0x09, 0x02, 0x14, 0x02, 0x1a, - 0x02, 0x20, 0x02, 0x26, 0x02, 0x2c, 0x02, 0x32, 0x02, 0x38, 0x02, 0x3e, - 0x02, 0x44, 0x02, 0x4a, 0x02, 0x50, 0x02, 0x56, 0x02, 0x5c, 0x02, 0x62, - 0x02, 0x68, 0x02, 0x6e, 0x02, 0x74, 0x02, 0x7a, 0x02, 0x80, 0x02, 0x86, - 0x02, 0x8c, 0x02, 0x92, 0x02, 0x98, 0x02, 0x9e, 0x02, 0xa4, 0x02, 0xaa, - 0x02, 0xb0, 0x02, 0xb6, 0x02, 0xbc, 0x02, 0xc2, 0x02, 0xc8, 0x02, 0xce, - 0x02, 0xd4, 0x02, 0xda, 0x02, 0xe0, 0x02, 0xe6, 0x02, 0xec, 0x02, 0xf2, - 0x02, 0xf8, 0x02, 0xfe, 0x03, 0x04, 0x03, 0x0a, 0x03, 0x10, 0x03, 0x16, - 0x03, 0x1c, 0x03, 0x22, 0x03, 0x28, 0x03, 0x2e, 0x03, 0x34, 0x03, 0x3a, - 0x03, 0x40, 0x03, 0x46, 0x03, 0x4c, 0x03, 0x52, 0x03, 0x58, 0x03, 0x5e, - 0x03, 0x64, 0x03, 0x6a, 0x03, 0x70, 0x03, 0x76, 0x03, 0x7c, 0x03, 0x82, - 0x03, 0x88, 0x03, 0x8e, 0x03, 0x94, 0x03, 0x9a, 0x03, 0xa0, 0x03, 0xa6, - 0x03, 0xac, 0x03, 0xb2, 0x03, 0xb8, 0x03, 0xbe, 0x03, 0xc4, 0x03, 0xca, - 0x03, 0xd0, 0x03, 0xd6, 0x03, 0xdc, 0x03, 0xe2, 0x03, 0xe8, 0x03, 0xee, - 0x03, 0xf4, 0x03, 0xfa, 0x04, 0x00, 0x04, 0x06, 0x04, 0x0c, 0x04, 0x12, - 0x04, 0x18, 0x04, 0x1e, 0x04, 0x24, 0x04, 0x2a, 0x04, 0x30, 0x04, 0x36, - 0x04, 0x3c, 0x04, 0x42, 0x04, 0x48, 0x04, 0x4e, 0x04, 0x54, 0x04, 0x5a, - 0x04, 0x60, 0x04, 0x66, 0x04, 0x6c, 0x04, 0x72, 0x04, 0x78, 0x04, 0x7e, - 0x04, 0x84, 0x04, 0x8a, 0x04, 0x90, 0x04, 0x96, 0x04, 0x9c, 0x04, 0xa2, - 0x04, 0xa8, 0x04, 0xae, 0x04, 0xb4, 0x04, 0xba, 0x04, 0xc0, 0x04, 0xc6, - 0x04, 0xcc, 0x04, 0xd2, 0x04, 0xd8, 0x04, 0xde, 0x04, 0xe4, 0x04, 0xea, - 0x04, 0xf0, 0x04, 0xf6, 0x04, 0xfc, 0x05, 0x02, 0x05, 0x08, 0x05, 0x0e, - 0x05, 0x14, 0x05, 0x1a, 0x05, 0x20, 0x05, 0x26, 0x05, 0x2c, 0x05, 0x32, - 0x05, 0x38, 0x05, 0x3e, 0x05, 0x44, 0x05, 0x4a, 0x05, 0x50, 0x05, 0x56, - 0x05, 0x5c, 0x05, 0x62, 0x05, 0x68, 0x05, 0x6e, 0x05, 0x74, 0x05, 0x7a, - 0x05, 0x80, 0x05, 0x86, 0x05, 0x8c, 0x05, 0x92, 0x05, 0x98, 0x05, 0x9e, - 0x05, 0xa4, 0x05, 0xaa, 0x05, 0xb0, 0x05, 0xb6, 0x05, 0xbc, 0x05, 0xc2, - 0x05, 0xc8, 0x05, 0xce, 0x05, 0xd4, 0x05, 0xda, 0x05, 0xe0, 0x05, 0xe6, - 0x05, 0xec, 0x05, 0xf2, 0x05, 0xf8, 0x05, 0xfe, 0x06, 0x04, 0x06, 0x0a, - 0x06, 0x10, 0x06, 0x16, 0x06, 0x1c, 0x06, 0x22, 0x06, 0x28, 0x06, 0x2e, - 0x06, 0x34, 0x06, 0x3a, 0x06, 0x40, 0x06, 0x46, 0x06, 0x4c, 0x06, 0x52, - 0x06, 0x58, 0x06, 0x5e, 0x06, 0x64, 0x06, 0x6a, 0x06, 0x70, 0x06, 0x76, - 0x06, 0x7c, 0x06, 0x82, 0x06, 0x88, 0x06, 0x8e, 0x06, 0x94, 0x06, 0x9a, - 0x06, 0xa0, 0x06, 0xa6, 0x06, 0xac, 0x06, 0xb2, 0x06, 0xb8, 0x06, 0xbe, - 0x06, 0xc4, 0x06, 0xca, 0x06, 0xd0, 0x06, 0xd6, 0x06, 0xdc, 0x06, 0xe2, - 0x06, 0xe8, 0x06, 0xee, 0x06, 0xf4, 0x06, 0xfa, 0x07, 0x00, 0x07, 0x06, - 0x07, 0x0c, 0x07, 0x12, 0x07, 0x18, 0x07, 0x1e, 0x07, 0x24, 0x07, 0x2a, - 0x07, 0x30, 0x07, 0x36, 0x07, 0x3c, 0x07, 0x42, 0x07, 0x48, 0x07, 0x4e, - 0x07, 0x54, 0x07, 0x5a, 0x07, 0x60, 0x07, 0x66, 0x07, 0x6c, 0x07, 0x72, - 0x07, 0x78, 0x07, 0x7e, 0x07, 0x84, 0x07, 0x8a, 0x07, 0x90, 0x07, 0x96, - 0x07, 0x9c, 0x07, 0xa2, 0x07, 0xa8, 0x07, 0xae, 0x07, 0xb4, 0x07, 0xba, - 0x07, 0xc0, 0x07, 0xc6, 0x07, 0xcc, 0x07, 0xd2, 0x07, 0xd8, 0x07, 0xde, - 0x07, 0xe4, 0x07, 0xea, 0x07, 0xf0, 0x07, 0xf6, 0x07, 0xfc, 0x08, 0x02, - 0x08, 0x08, 0x08, 0x0e, 0x08, 0x14, 0x08, 0x1a, 0x08, 0x20, 0x08, 0x26, - 0x08, 0x2c, 0x08, 0x32, 0x08, 0x38, 0x08, 0x3e, 0x08, 0x44, 0x00, 0x01, - 0x04, 0x44, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0xb3, 0x00, 0x00, 0x00, 0x01, 0x01, 0x78, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x7a, 0x00, 0x00, 0x00, 0x01, 0x01, 0x4f, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x03, 0xe2, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, - 0x04, 0x44, 0x00, 0x00, 0x00, 0x01, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, - 0x04, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x03, 0xe4, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x01, 0x2a, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x04, 0x44, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x03, 0x93, 0x00, 0x00, 0x00, 0x01, 0x04, 0x44, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, - 0x03, 0xc6, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0xd0, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x76, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, 0x03, 0xbe, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x01, 0xb9, 0xfe, 0x59, 0x00, 0x01, - 0x04, 0x44, 0x00, 0x00, 0x00, 0x01, 0x03, 0x78, 0x00, 0x00, 0x00, 0x01, - 0x04, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x03, 0xbe, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x01, 0x1a, 0xfe, 0x56, 0x00, 0x01, - 0x03, 0xc2, 0xfe, 0x56, 0x00, 0x01, 0x01, 0xc6, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x03, 0x78, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x03, 0x73, 0x00, 0x00, 0x00, 0x01, 0x04, 0x44, 0x00, 0x00, 0x00, 0x01, - 0x01, 0x1a, 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x04, 0x44, 0x00, 0x00, 0x00, 0x01, 0x04, 0x44, 0x00, 0x00, 0x00, 0x01, - 0x04, 0x44, 0x00, 0x00, 0x00, 0x01, 0x04, 0x44, 0x00, 0x00, 0x00, 0x01, - 0x04, 0x44, 0x00, 0x00, 0x00, 0x01, 0x04, 0x44, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x7a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x7a, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x7a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x7a, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x36, 0x00, 0x00, 0x00, 0x01, 0x03, 0xe4, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x01, 0x34, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x36, 0x00, 0x00, 0x00, 0x01, 0x03, 0xc6, 0x00, 0x00, 0x00, 0x01, - 0x03, 0xc6, 0x00, 0x00, 0x00, 0x01, 0x03, 0xc6, 0x00, 0x00, 0x00, 0x01, - 0x03, 0xc6, 0x00, 0x00, 0x00, 0x01, 0x03, 0xc6, 0x00, 0x00, 0x00, 0x01, - 0x03, 0xc6, 0x00, 0x00, 0x00, 0x01, 0x02, 0x76, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x76, 0x00, 0x00, 0x00, 0x01, 0x02, 0x76, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x76, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x03, 0xbe, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x01, 0x1a, 0xfe, 0x56, 0x00, 0x01, - 0x01, 0x1a, 0xfe, 0x56, 0x00, 0x01, 0x01, 0x1a, 0xfe, 0x56, 0x00, 0x01, - 0x04, 0x44, 0x00, 0x00, 0x00, 0x01, 0x04, 0x44, 0x00, 0x00, 0x00, 0x01, - 0x03, 0xc6, 0x00, 0x00, 0x00, 0x01, 0x02, 0xb3, 0x00, 0x00, 0x00, 0x01, - 0x02, 0xb3, 0x00, 0x00, 0x00, 0x01, 0x02, 0xd0, 0x00, 0x00, 0x00, 0x01, - 0x02, 0xb3, 0x00, 0x00, 0x00, 0x01, 0x02, 0xd0, 0x00, 0x00, 0x00, 0x01, - 0x02, 0xb3, 0x00, 0x00, 0x00, 0x01, 0x02, 0xd0, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x36, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x36, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x7a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x76, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x7a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x76, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x7a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x76, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x7a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x76, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, - 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, - 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, - 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, 0x03, 0xe2, 0x00, 0x00, 0x00, 0x01, - 0x03, 0xbe, 0x00, 0x00, 0x00, 0x01, 0x03, 0xe2, 0x00, 0x00, 0x00, 0x01, - 0x03, 0xbe, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, - 0x01, 0xb9, 0xfe, 0x59, 0x00, 0x01, 0x04, 0x44, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x03, 0x78, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x03, 0x78, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x03, 0x78, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x03, 0x78, 0x00, 0x00, 0x00, 0x01, - 0x03, 0xe4, 0x00, 0x00, 0x00, 0x01, 0x03, 0xbe, 0x00, 0x00, 0x00, 0x01, - 0x03, 0xe4, 0x00, 0x00, 0x00, 0x01, 0x03, 0xbe, 0x00, 0x00, 0x00, 0x01, - 0x04, 0x39, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, - 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x04, 0x44, 0x00, 0x00, 0x00, 0x01, - 0x01, 0xc6, 0x00, 0x00, 0x00, 0x01, 0x04, 0x44, 0x00, 0x00, 0x00, 0x01, - 0x01, 0xc6, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x03, 0x78, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x03, 0x78, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x03, 0x93, 0x00, 0x00, 0x00, 0x01, - 0x03, 0x73, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x01, 0x1a, 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x0a, 0x00, 0x00, 0x00, 0x01, - 0x02, 0xb3, 0x00, 0x00, 0x00, 0x01, 0x02, 0xd0, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x36, 0x00, 0x00, 0x00, 0x01, 0x02, 0x36, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, 0x02, 0x56, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0xb3, 0x00, 0x00, 0x00, 0x01, - 0x01, 0x22, 0xfe, 0x56, 0x00, 0x01, 0x01, 0x68, 0xfe, 0x56, 0x00, 0x01, - 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, - 0x03, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x04, 0x44, 0x00, 0x00, 0x00, 0x01, - 0x04, 0x44, 0x00, 0x00, 0x00, 0x01, 0x03, 0x78, 0x00, 0x00, 0x00, 0x01, - 0x04, 0x08, 0x00, 0x00, 0x00, 0x01, 0x04, 0x1c, 0x00, 0x00, 0x00, 0x01, - 0x03, 0xe4, 0x00, 0x00, 0x00, 0x01, 0x03, 0xbe, 0xfe, 0x56, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x01, 0xf9, 0x00, 0x00, 0x00, 0x01, - 0x01, 0xff, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x04, 0x58, 0xfe, 0x56, 0x00, 0x01, 0x01, 0xd2, 0x00, 0x00, 0x00, 0x01, - 0x01, 0x1a, 0xfe, 0x56, 0x00, 0x01, 0x04, 0x6a, 0xfe, 0xf8, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x04, 0x44, 0x00, 0x00, 0x00, 0x01, - 0x01, 0xc6, 0x00, 0x00, 0x00, 0x01, 0x04, 0x44, 0x00, 0x00, 0x00, 0x01, - 0x02, 0xa4, 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, - 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, 0x02, 0x9a, 0xfe, 0x56, 0x00, 0x01, - 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, - 0x04, 0x49, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1e, 0x00, 0x24, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x44, 0x00, 0x5d, 0x00, 0x1a, 0x00, 0x82, 0x00, 0x87, - 0x00, 0x34, 0x00, 0x8a, 0x00, 0x98, 0x00, 0x3a, 0x00, 0x9a, 0x00, 0xa7, - 0x00, 0x49, 0x00, 0xaa, 0x00, 0xb8, 0x00, 0x57, 0x00, 0xba, 0x00, 0xc2, - 0x00, 0x66, 0x00, 0xc4, 0x00, 0xc5, 0x00, 0x6f, 0x00, 0xc8, 0x00, 0xc8, - 0x00, 0x71, 0x00, 0xca, 0x00, 0xd9, 0x00, 0x72, 0x00, 0xdc, 0x00, 0xe3, - 0x00, 0x82, 0x00, 0xe5, 0x00, 0xef, 0x00, 0x8a, 0x00, 0xf2, 0x00, 0xf3, - 0x00, 0x95, 0x00, 0xf6, 0x00, 0xf7, 0x00, 0x97, 0x00, 0xfa, 0x00, 0xfc, - 0x00, 0x99, 0x00, 0xff, 0x01, 0x06, 0x00, 0x9c, 0x01, 0x09, 0x01, 0x13, - 0x00, 0xa4, 0x01, 0x16, 0x01, 0x17, 0x00, 0xaf, 0x01, 0x1a, 0x01, 0x1f, - 0x00, 0xb1, 0x01, 0x22, 0x01, 0x23, 0x00, 0xb7, 0x01, 0x26, 0x01, 0x33, - 0x00, 0xb9, 0x01, 0x36, 0x01, 0x6b, 0x00, 0xc7, 0x01, 0xf1, 0x01, 0xf2, - 0x00, 0xfd, 0x01, 0xf4, 0x01, 0xf5, 0x00, 0xff, 0x0b, 0x69, 0x0b, 0x69, - 0x01, 0x01, 0x0b, 0x6b, 0x0b, 0x6b, 0x01, 0x02, 0x0b, 0x72, 0x0b, 0x72, - 0x01, 0x03, 0x0b, 0x75, 0x0b, 0x76, 0x01, 0x04, 0x0b, 0x96, 0x0b, 0x97, - 0x01, 0x06, 0x0b, 0xa0, 0x0b, 0xa0, 0x01, 0x08, 0x00, 0x01, 0x00, 0x01, - 0x02, 0xaf, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x02, 0x7c, - 0x00, 0x00, 0x00, 0x01, 0x17, 0xec, 0x17, 0x0a, 0x00, 0x02, 0x18, 0x1a, - 0x00, 0x0c, 0x01, 0xba, 0x06, 0xea, 0x06, 0xf0, 0x06, 0xf6, 0x06, 0xfc, - 0x07, 0x02, 0x07, 0x08, 0x07, 0x0e, 0x07, 0x14, 0x07, 0x1a, 0x07, 0x20, - 0x07, 0x26, 0x07, 0x2c, 0x07, 0x32, 0x07, 0x38, 0x07, 0x3e, 0x07, 0x44, - 0x07, 0x4a, 0x07, 0x50, 0x07, 0x56, 0x07, 0x5c, 0x07, 0x62, 0x07, 0x68, - 0x07, 0x6e, 0x07, 0x74, 0x07, 0x7a, 0x07, 0x80, 0x07, 0x86, 0x07, 0x8c, - 0x07, 0x92, 0x07, 0x98, 0x07, 0x9e, 0x07, 0xa4, 0x07, 0xaa, 0x07, 0xb0, - 0x07, 0xb6, 0x07, 0xbc, 0x07, 0xc2, 0x07, 0xc8, 0x07, 0xce, 0x07, 0xd4, - 0x07, 0xda, 0x07, 0xe0, 0x07, 0xe6, 0x07, 0xec, 0x07, 0xf2, 0x07, 0xf8, - 0x07, 0xfe, 0x08, 0x04, 0x08, 0x0a, 0x08, 0x10, 0x08, 0x16, 0x08, 0x1c, - 0x08, 0x22, 0x08, 0x28, 0x08, 0x2e, 0x08, 0x34, 0x08, 0x3a, 0x08, 0x40, - 0x08, 0x46, 0x08, 0x4c, 0x08, 0x52, 0x08, 0x58, 0x08, 0x5e, 0x08, 0x64, - 0x08, 0x6a, 0x08, 0x70, 0x08, 0x76, 0x08, 0x7c, 0x00, 0x00, 0x08, 0x82, - 0x00, 0x00, 0x08, 0x88, 0x08, 0x8e, 0x08, 0x94, 0x08, 0x9a, 0x08, 0xa0, - 0x08, 0xa6, 0x08, 0xac, 0x08, 0xb2, 0x08, 0xb8, 0x08, 0xbe, 0x08, 0xc4, - 0x08, 0xca, 0x08, 0xd0, 0x08, 0xd6, 0x08, 0xdc, 0x08, 0xe2, 0x08, 0xe8, - 0x08, 0xee, 0x08, 0xf4, 0x08, 0xfa, 0x09, 0x00, 0x09, 0x06, 0x09, 0x0c, - 0x09, 0x12, 0x09, 0x18, 0x09, 0x1e, 0x09, 0x24, 0x09, 0x2a, 0x09, 0x30, - 0x09, 0x36, 0x09, 0x3c, 0x09, 0x42, 0x09, 0x48, 0x00, 0x00, 0x09, 0x4e, - 0x00, 0x00, 0x09, 0x54, 0x00, 0x00, 0x09, 0x5a, 0x00, 0x00, 0x09, 0x60, - 0x00, 0x00, 0x09, 0x66, 0x00, 0x00, 0x09, 0x6c, 0x09, 0x72, 0x09, 0x78, - 0x09, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x09, 0x84, 0x00, 0x00, 0x09, 0x8a, - 0x00, 0x00, 0x09, 0x90, 0x00, 0x00, 0x09, 0x96, 0x00, 0x00, 0x09, 0x9c, - 0x00, 0x00, 0x09, 0xa2, 0x00, 0x00, 0x09, 0xa8, 0x00, 0x00, 0x09, 0xae, - 0x09, 0xb4, 0x09, 0xba, 0x00, 0x00, 0x09, 0xc0, 0x00, 0x00, 0x09, 0xc6, - 0x00, 0x00, 0x09, 0xcc, 0x00, 0x00, 0x09, 0xd2, 0x00, 0x00, 0x09, 0xd8, - 0x00, 0x00, 0x09, 0xde, 0x09, 0xe4, 0x09, 0xea, 0x00, 0x00, 0x09, 0xf0, - 0x00, 0x00, 0x09, 0xf6, 0x00, 0x00, 0x09, 0xfc, 0x00, 0x00, 0x0a, 0x02, - 0x00, 0x00, 0x0a, 0x08, 0x0a, 0x0e, 0x0a, 0x14, 0x0a, 0x1a, 0x0a, 0x20, - 0x00, 0x00, 0x0a, 0x26, 0x00, 0x00, 0x0a, 0x2c, 0x00, 0x00, 0x0a, 0x32, - 0x00, 0x00, 0x0a, 0x38, 0x00, 0x00, 0x0a, 0x3e, 0x00, 0x00, 0x0a, 0x44, - 0x0a, 0x4a, 0x0a, 0x50, 0x0a, 0x56, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x5c, - 0x00, 0x00, 0x0a, 0x62, 0x00, 0x00, 0x0a, 0x68, 0x00, 0x00, 0x0a, 0x6e, - 0x00, 0x00, 0x0a, 0x74, 0x00, 0x00, 0x0a, 0x7a, 0x00, 0x00, 0x0a, 0x80, - 0x00, 0x00, 0x0a, 0x86, 0x00, 0x00, 0x0a, 0x8c, 0x00, 0x00, 0x0a, 0x92, - 0x00, 0x00, 0x0a, 0x98, 0x00, 0x00, 0x0a, 0x9e, 0x00, 0x00, 0x0a, 0xa4, - 0x00, 0x00, 0x0a, 0xaa, 0x00, 0x00, 0x0a, 0xb0, 0x0a, 0xb6, 0x0a, 0xbc, - 0x00, 0x00, 0x0a, 0xc2, 0x00, 0x00, 0x0a, 0xc8, 0x00, 0x00, 0x0a, 0xce, - 0x00, 0x00, 0x0a, 0xd4, 0x00, 0x00, 0x0a, 0xda, 0x0a, 0xe0, 0x0a, 0xe6, - 0x00, 0x00, 0x0a, 0xec, 0x00, 0x00, 0x0a, 0xf2, 0x00, 0x00, 0x0a, 0xf8, - 0x00, 0x00, 0x0a, 0xfe, 0x0b, 0x04, 0x00, 0x00, 0x0b, 0x0a, 0x00, 0x00, - 0x00, 0x00, 0x0b, 0x10, 0x00, 0x00, 0x0b, 0x16, 0x00, 0x00, 0x0b, 0x1c, - 0x00, 0x00, 0x0b, 0x22, 0x00, 0x00, 0x0b, 0x28, 0x00, 0x00, 0x0b, 0x2e, - 0x00, 0x00, 0x0b, 0x34, 0x00, 0x00, 0x0b, 0x3a, 0x00, 0x00, 0x0b, 0x40, - 0x0b, 0x46, 0x0b, 0x4c, 0x0b, 0x52, 0x0b, 0x58, 0x00, 0x00, 0x0b, 0x5e, - 0x00, 0x00, 0x0b, 0x64, 0x00, 0x00, 0x0b, 0x6a, 0x00, 0x00, 0x0b, 0x70, - 0x00, 0x00, 0x0b, 0x76, 0x00, 0x00, 0x0b, 0x7c, 0x0b, 0x82, 0x00, 0x00, - 0x0b, 0x88, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x8e, 0x00, 0x00, 0x0b, 0x94, - 0x00, 0x00, 0x0b, 0x9a, 0x00, 0x00, 0x0b, 0xa0, 0x00, 0x00, 0x0b, 0xa6, - 0x00, 0x00, 0x0b, 0xac, 0x00, 0x00, 0x0b, 0xb2, 0x00, 0x00, 0x0b, 0xb8, - 0x0b, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xc4, 0x00, 0x00, 0x0b, 0xca, - 0x00, 0x00, 0x0b, 0xd0, 0x0b, 0xd6, 0x0b, 0xdc, 0x0b, 0xe2, 0x0b, 0xe8, - 0x00, 0x00, 0x0b, 0xee, 0x00, 0x00, 0x0b, 0xf4, 0x00, 0x00, 0x0b, 0xfa, - 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x06, 0x00, 0x00, 0x0c, 0x0c, - 0x0c, 0x12, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x0c, 0x1e, 0x0c, 0x24, - 0x00, 0x00, 0x0c, 0x2a, 0x00, 0x00, 0x0c, 0x30, 0x0c, 0x36, 0x00, 0x00, - 0x0c, 0x3c, 0x00, 0x00, 0x0c, 0x42, 0x0c, 0x48, 0x00, 0x00, 0x0c, 0x4e, - 0x00, 0x00, 0x0c, 0x54, 0x0c, 0x5a, 0x00, 0x00, 0x0c, 0x60, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x66, 0x00, 0x00, 0x0c, 0x6c, 0x0c, 0x72, 0x0c, 0x78, - 0x0c, 0x7e, 0x0c, 0x84, 0x0c, 0x8a, 0x0c, 0x90, 0x0c, 0x96, 0x0c, 0x9c, - 0x00, 0x00, 0x0c, 0xa2, 0x00, 0x00, 0x0c, 0xa8, 0x0c, 0xae, 0x00, 0x00, - 0x0c, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xba, 0x00, 0x00, 0x0c, 0xc0, - 0x00, 0x00, 0x0c, 0xc6, 0x0c, 0xcc, 0x0c, 0xd2, 0x0c, 0xd8, 0x0c, 0xde, - 0x00, 0x00, 0x0c, 0xe4, 0x00, 0x00, 0x0c, 0xea, 0x00, 0x00, 0x0c, 0xf0, - 0x00, 0x00, 0x0c, 0xf6, 0x00, 0x00, 0x0c, 0xfc, 0x00, 0x00, 0x0d, 0x02, - 0x0d, 0x08, 0x0d, 0x0e, 0x0d, 0x14, 0x0d, 0x1a, 0x00, 0x00, 0x0d, 0x20, - 0x00, 0x00, 0x0d, 0x26, 0x0d, 0x2c, 0x00, 0x00, 0x0d, 0x32, 0x00, 0x00, - 0x00, 0x00, 0x0d, 0x38, 0x0d, 0x3e, 0x0d, 0x44, 0x00, 0x00, 0x0d, 0x4a, - 0x00, 0x00, 0x0d, 0x50, 0x00, 0x00, 0x0d, 0x56, 0x00, 0x00, 0x0d, 0x5c, - 0x0d, 0x62, 0x00, 0x00, 0x0d, 0x68, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x6e, - 0x00, 0x00, 0x0d, 0x74, 0x0d, 0x7a, 0x00, 0x00, 0x0d, 0x80, 0x00, 0x00, - 0x00, 0x00, 0x0d, 0x86, 0x00, 0x00, 0x0d, 0x8c, 0x0d, 0x92, 0x0d, 0x98, - 0x0d, 0x9e, 0x0d, 0xa4, 0x00, 0x00, 0x0d, 0xaa, 0x00, 0x00, 0x0d, 0xb0, - 0x00, 0x00, 0x0d, 0xb6, 0x00, 0x00, 0x0d, 0xbc, 0x00, 0x00, 0x0d, 0xc2, - 0x00, 0x00, 0x0d, 0xc8, 0x00, 0x00, 0x0d, 0xce, 0x00, 0x00, 0x0d, 0xd4, - 0x00, 0x00, 0x0d, 0xda, 0x00, 0x00, 0x0d, 0xe0, 0x0d, 0xe6, 0x00, 0x00, - 0x0d, 0xec, 0x00, 0x00, 0x00, 0x00, 0x0d, 0xf2, 0x00, 0x00, 0x0d, 0xf8, - 0x00, 0x00, 0x0d, 0xfe, 0x00, 0x00, 0x0e, 0x04, 0x00, 0x00, 0x0e, 0x0a, - 0x00, 0x00, 0x0e, 0x10, 0x00, 0x00, 0x0e, 0x16, 0x00, 0x00, 0x0e, 0x1c, - 0x00, 0x00, 0x0e, 0x22, 0x00, 0x00, 0x0e, 0x28, 0x00, 0x00, 0x0e, 0x2e, - 0x0e, 0x34, 0x0e, 0x3a, 0x0e, 0x40, 0x0e, 0x46, 0x0e, 0x4c, 0x0e, 0x52, - 0x0e, 0x58, 0x0e, 0x5e, 0x0e, 0x64, 0x0e, 0x6a, 0x0e, 0x70, 0x0e, 0x76, - 0x0e, 0x7c, 0x0e, 0x82, 0x0e, 0x88, 0x0e, 0x8e, 0x0e, 0x94, 0x0e, 0x9a, - 0x0e, 0xa0, 0x0e, 0xa6, 0x0e, 0xac, 0x0e, 0xb2, 0x0e, 0xb8, 0x0e, 0xbe, - 0x0e, 0xc4, 0x0e, 0xca, 0x0e, 0xd0, 0x0e, 0xd6, 0x0e, 0xdc, 0x0e, 0xe2, - 0x0e, 0xe8, 0x0e, 0xee, 0x0e, 0xf4, 0x0e, 0xfa, 0x0f, 0x00, 0x0f, 0x06, - 0x0f, 0x0c, 0x0f, 0x12, 0x0f, 0x18, 0x0f, 0x1e, 0x0f, 0x24, 0x0f, 0x2a, - 0x0f, 0x30, 0x0f, 0x36, 0x0f, 0x3c, 0x0f, 0x42, 0x0f, 0x48, 0x0f, 0x4e, - 0x0f, 0x54, 0x0f, 0x5a, 0x0f, 0x60, 0x0f, 0x66, 0x0f, 0x6c, 0x0f, 0x72, - 0x0f, 0x78, 0x0f, 0x7e, 0x0f, 0x84, 0x0f, 0x8a, 0x0f, 0x90, 0x0f, 0x96, - 0x0f, 0x9c, 0x0f, 0xa2, 0x0f, 0xa8, 0x0f, 0xae, 0x0f, 0xb4, 0x0f, 0xba, - 0x0f, 0xc0, 0x0f, 0xc6, 0x0f, 0xcc, 0x0f, 0xd2, 0x0f, 0xd8, 0x0f, 0xde, - 0x0f, 0xe4, 0x0f, 0xea, 0x0f, 0xf0, 0x0f, 0xf6, 0x0f, 0xfc, 0x10, 0x02, - 0x10, 0x08, 0x10, 0x0e, 0x10, 0x14, 0x10, 0x1a, 0x10, 0x20, 0x10, 0x26, - 0x10, 0x2c, 0x10, 0x32, 0x10, 0x38, 0x10, 0x3e, 0x10, 0x44, 0x10, 0x4a, - 0x10, 0x50, 0x10, 0x56, 0x10, 0x5c, 0x10, 0x62, 0x10, 0x68, 0x10, 0x6e, - 0x10, 0x74, 0x10, 0x7a, 0x10, 0x80, 0x10, 0x86, 0x10, 0x8c, 0x10, 0x92, - 0x10, 0x98, 0x10, 0x9e, 0x10, 0xa4, 0x10, 0xaa, 0x10, 0xb0, 0x10, 0xb6, - 0x10, 0xbc, 0x10, 0xc2, 0x10, 0xc8, 0x10, 0xce, 0x10, 0xd4, 0x10, 0xda, - 0x10, 0xe0, 0x10, 0xe6, 0x10, 0xec, 0x10, 0xf2, 0x10, 0xf8, 0x10, 0xfe, - 0x11, 0x04, 0x11, 0x0a, 0x11, 0x10, 0x11, 0x16, 0x11, 0x1c, 0x11, 0x22, - 0x11, 0x28, 0x11, 0x2e, 0x11, 0x34, 0x11, 0x3a, 0x11, 0x40, 0x11, 0x46, - 0x11, 0x4c, 0x11, 0x52, 0x11, 0x58, 0x11, 0x5e, 0x11, 0x64, 0x11, 0x6a, - 0x11, 0x70, 0x11, 0x76, 0x11, 0x7c, 0x11, 0x82, 0x11, 0x88, 0x11, 0x8e, - 0x11, 0x94, 0x11, 0x9a, 0x11, 0xa0, 0x11, 0xa6, 0x11, 0xac, 0x11, 0xb2, - 0x11, 0xb8, 0x11, 0xbe, 0x11, 0xc4, 0x11, 0xca, 0x11, 0xd0, 0x11, 0xd6, - 0x11, 0xdc, 0x11, 0xe2, 0x11, 0xe8, 0x11, 0xee, 0x11, 0xf4, 0x11, 0xfa, - 0x12, 0x00, 0x12, 0x06, 0x12, 0x0c, 0x12, 0x12, 0x12, 0x18, 0x12, 0x1e, - 0x12, 0x24, 0x12, 0x2a, 0x12, 0x30, 0x12, 0x36, 0x12, 0x3c, 0x12, 0x42, - 0x12, 0x48, 0x12, 0x4e, 0x12, 0x54, 0x12, 0x5a, 0x12, 0x60, 0x12, 0x66, - 0x12, 0x6c, 0x12, 0x72, 0x12, 0x78, 0x12, 0x7e, 0x12, 0x84, 0x12, 0x8a, - 0x12, 0x90, 0x12, 0x96, 0x12, 0x9c, 0x12, 0xa2, 0x12, 0xa8, 0x12, 0xae, - 0x12, 0xb4, 0x12, 0xba, 0x12, 0xc0, 0x12, 0xc6, 0x12, 0xcc, 0x12, 0xd2, - 0x12, 0xd8, 0x12, 0xde, 0x12, 0xe4, 0x12, 0xea, 0x12, 0xf0, 0x12, 0xf6, - 0x12, 0xfc, 0x13, 0x02, 0x13, 0x08, 0x13, 0x0e, 0x13, 0x14, 0x13, 0x1a, - 0x13, 0x20, 0x13, 0x26, 0x13, 0x2c, 0x13, 0x32, 0x13, 0x38, 0x13, 0x3e, - 0x13, 0x44, 0x13, 0x4a, 0x13, 0x50, 0x13, 0x56, 0x13, 0x5c, 0x13, 0x62, - 0x13, 0x68, 0x13, 0x6e, 0x13, 0x74, 0x13, 0x7a, 0x13, 0x80, 0x13, 0x86, - 0x13, 0x8c, 0x13, 0x92, 0x13, 0x98, 0x13, 0x9e, 0x13, 0xa4, 0x13, 0xaa, - 0x13, 0xb0, 0x13, 0xb6, 0x13, 0xbc, 0x13, 0xc2, 0x13, 0xc8, 0x13, 0xce, - 0x13, 0xd4, 0x13, 0xda, 0x13, 0xe0, 0x13, 0xe6, 0x13, 0xec, 0x13, 0xf2, - 0x13, 0xf8, 0x13, 0xfe, 0x14, 0x04, 0x14, 0x0a, 0x14, 0x10, 0x14, 0x16, - 0x14, 0x1c, 0x14, 0x22, 0x14, 0x28, 0x14, 0x2e, 0x14, 0x34, 0x00, 0x00, - 0x14, 0x3a, 0x00, 0x00, 0x14, 0x40, 0x00, 0x00, 0x14, 0x46, 0x00, 0x00, - 0x14, 0x4c, 0x00, 0x00, 0x14, 0x52, 0x00, 0x00, 0x14, 0x58, 0x00, 0x00, - 0x14, 0x5e, 0x00, 0x00, 0x14, 0x64, 0x00, 0x00, 0x14, 0x6a, 0x00, 0x00, - 0x14, 0x70, 0x00, 0x00, 0x14, 0x76, 0x00, 0x00, 0x14, 0x7c, 0x00, 0x00, - 0x14, 0x82, 0x00, 0x00, 0x14, 0x88, 0x00, 0x00, 0x14, 0x8e, 0x00, 0x00, - 0x14, 0x94, 0x00, 0x00, 0x14, 0x9a, 0x00, 0x00, 0x14, 0xa0, 0x00, 0x00, - 0x14, 0xa6, 0x00, 0x00, 0x14, 0xac, 0x00, 0x00, 0x14, 0xb2, 0x00, 0x00, - 0x14, 0xb8, 0x00, 0x00, 0x14, 0xbe, 0x00, 0x00, 0x14, 0xc4, 0x00, 0x00, - 0x14, 0xca, 0x00, 0x00, 0x14, 0xd0, 0x00, 0x00, 0x14, 0xd6, 0x00, 0x00, - 0x14, 0xdc, 0x00, 0x00, 0x14, 0xe2, 0x00, 0x00, 0x14, 0xe8, 0x00, 0x00, - 0x14, 0xee, 0x00, 0x00, 0x14, 0xf4, 0x00, 0x00, 0x14, 0xfa, 0x15, 0x00, - 0x15, 0x06, 0x15, 0x0c, 0x15, 0x12, 0x15, 0x18, 0x15, 0x1e, 0x15, 0x24, - 0x15, 0x2a, 0x15, 0x30, 0x15, 0x36, 0x15, 0x3c, 0x15, 0x42, 0x15, 0x48, - 0x15, 0x4e, 0x15, 0x54, 0x15, 0x5a, 0x15, 0x60, 0x15, 0x66, 0x15, 0x6c, - 0x15, 0x72, 0x15, 0x78, 0x15, 0x7e, 0x15, 0x84, 0x15, 0x8a, 0x15, 0x90, - 0x15, 0x96, 0x15, 0x9c, 0x15, 0xa2, 0x15, 0xa8, 0x15, 0xae, 0x15, 0xb4, - 0x15, 0xba, 0x15, 0xc0, 0x15, 0xc6, 0x15, 0xcc, 0x15, 0xd2, 0x15, 0xd8, - 0x15, 0xde, 0x15, 0xe4, 0x15, 0xea, 0x15, 0xf0, 0x15, 0xf6, 0x15, 0xfc, - 0x16, 0x02, 0x00, 0x00, 0x00, 0x00, 0x16, 0x08, 0x00, 0x00, 0x16, 0x0e, - 0x16, 0x14, 0x16, 0x1a, 0x16, 0x20, 0x16, 0x26, 0x16, 0x2c, 0x16, 0x32, - 0x16, 0x38, 0x16, 0x3e, 0x16, 0x44, 0x16, 0x4a, 0x16, 0x50, 0x16, 0x56, - 0x16, 0x5c, 0x16, 0x62, 0x16, 0x68, 0x16, 0x6e, 0x16, 0x74, 0x16, 0x7a, - 0x16, 0x80, 0x16, 0x86, 0x16, 0x8c, 0x16, 0x92, 0x16, 0x98, 0x16, 0x9e, - 0x16, 0xa4, 0x16, 0xaa, 0x16, 0xb0, 0x16, 0xb6, 0x16, 0xbc, 0x16, 0xc2, - 0x16, 0xc8, 0x16, 0xce, 0x16, 0xd4, 0x16, 0xda, 0x16, 0xe0, 0x16, 0xe6, - 0x16, 0xec, 0x16, 0xf2, 0x16, 0xf8, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0xb3, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0xb3, 0x00, 0x00, 0x00, 0x01, 0x02, 0x36, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x36, 0x00, 0x00, 0x00, 0x01, 0x02, 0x7a, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x7a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x9e, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x9e, 0x00, 0x00, 0x00, 0x01, 0x02, 0x9a, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x9a, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x9a, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x36, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x36, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x9a, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0xb3, - 0x04, 0x60, 0x00, 0x01, 0x02, 0xb3, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x76, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x76, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, - 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, 0x02, 0x9a, - 0x06, 0x14, 0x00, 0x01, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x32, - 0x06, 0x14, 0x00, 0x01, 0x02, 0x32, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x7a, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x7a, 0x00, 0x00, 0x00, 0x01, 0x02, 0xb3, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x7a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x7a, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x7a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x7a, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x36, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x36, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x36, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x36, 0x00, 0x00, 0x00, 0x01, 0x02, 0x36, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x36, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0xb3, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x76, 0x00, 0x00, 0x00, 0x01, 0x02, 0x76, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x76, 0x00, 0x00, 0x00, 0x01, 0x02, 0x76, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0xb3, 0x00, 0x00, 0x00, 0x01, 0x02, 0xb3, - 0x00, 0x00, 0x00, 0x01, 0x02, 0xb3, 0x00, 0x00, 0x00, 0x01, 0x02, 0xb3, - 0x00, 0x00, 0x00, 0x01, 0x02, 0xb3, 0x00, 0x00, 0x00, 0x01, 0x02, 0xb3, - 0x00, 0x00, 0x00, 0x01, 0x02, 0xb3, 0x00, 0x00, 0x00, 0x01, 0x02, 0x36, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x36, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x36, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x7a, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x76, 0x00, 0x00, 0x00, 0x01, 0x02, 0x7a, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x76, 0x00, 0x00, 0x00, 0x01, 0x02, 0x7a, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x76, 0x00, 0x00, 0x00, 0x01, 0x02, 0x7a, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x76, 0x04, 0x60, 0x00, 0x01, 0x02, 0x7a, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x76, 0x00, 0x00, 0x00, 0x01, 0x02, 0x9a, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, 0x02, 0x9a, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, 0x02, 0x9a, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, 0x02, 0x9a, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x9a, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x9a, 0x06, 0x14, 0x00, 0x01, 0x02, 0x9a, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x9a, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x32, 0x00, 0x00, 0x00, 0x01, 0x02, 0x9a, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x32, 0x06, 0x14, 0x00, 0x01, 0x02, 0x9a, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x32, 0x00, 0x00, 0x00, 0x01, 0x02, 0x9a, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x32, - 0x06, 0x14, 0x00, 0x01, 0x02, 0x32, 0x00, 0x00, 0x00, 0x01, 0x02, 0x9a, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x32, - 0x06, 0x14, 0x00, 0x01, 0x02, 0x32, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0xe3, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x36, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x36, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x36, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x0a, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x0a, - 0x00, 0x00, 0x00, 0x01, 0x02, 0xb3, 0x05, 0xd5, 0x00, 0x01, 0x02, 0xb3, - 0x00, 0x00, 0x00, 0x01, 0x02, 0xb3, 0x04, 0x60, 0x00, 0x01, 0x02, 0xb3, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x36, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x36, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x36, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x36, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x56, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x56, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0xb3, 0x05, 0xd5, 0x00, 0x01, 0x02, 0xb3, - 0x00, 0x00, 0x00, 0x01, 0x03, 0x02, 0x05, 0xd5, 0x00, 0x01, 0x03, 0x02, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x9a, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x9a, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x9a, 0x06, 0x14, 0x00, 0x01, 0x02, 0x9a, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x32, 0x06, 0x14, 0x00, 0x01, 0x02, 0x32, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x01, 0xf9, 0x05, 0xd5, 0x00, 0x01, 0x01, 0xf9, - 0x00, 0x00, 0x00, 0x01, 0x01, 0xff, 0x04, 0x60, 0x00, 0x01, 0x01, 0xff, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0xec, 0x05, 0xd5, 0x00, 0x01, 0x02, 0xec, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x36, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x36, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x36, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x36, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x8c, 0x06, 0x14, 0x00, 0x01, 0x02, 0x8c, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x29, 0x04, 0x60, 0x00, 0x01, 0x02, 0x29, - 0x00, 0x00, 0x00, 0x01, 0x02, 0xb3, 0x04, 0x60, 0x00, 0x01, 0x02, 0xb3, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x59, 0x06, 0x14, 0x00, 0x01, 0x02, 0x59, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x76, 0x04, 0x60, 0x00, 0x01, 0x02, 0x76, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x76, 0x04, 0x60, 0x00, 0x01, 0x02, 0x76, - 0x00, 0x00, 0x00, 0x01, 0x01, 0x9a, 0x04, 0x60, 0x00, 0x01, 0x01, 0x9a, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x76, 0x04, 0x60, 0x00, 0x01, 0x02, 0x76, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x5a, 0x04, 0x60, 0x00, 0x01, 0x02, 0x5a, - 0x00, 0x00, 0x00, 0x01, 0x01, 0x72, 0x04, 0x60, 0x00, 0x01, 0x01, 0x72, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x76, 0x04, 0x60, 0x00, 0x01, 0x02, 0x76, - 0x00, 0x00, 0x00, 0x01, 0x02, 0xb1, 0x04, 0x60, 0x00, 0x01, 0x02, 0xb1, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x3e, 0x06, 0x14, 0x00, 0x01, 0x02, 0x3e, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x95, 0x04, 0x60, 0x00, 0x01, 0x02, 0x95, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x6e, 0x04, 0x60, 0x00, 0x01, 0x02, 0x6e, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x6f, 0x06, 0x14, 0x00, 0x01, 0x02, 0x6f, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x6f, 0x06, 0x14, 0x00, 0x01, 0x02, 0x6f, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x44, 0x04, 0x60, 0x00, 0x01, 0x02, 0x44, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x38, 0x06, 0x14, 0x00, 0x01, 0x02, 0x38, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x50, 0x06, 0x14, 0x00, 0x01, 0x02, 0x50, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x3e, 0x06, 0x14, 0x00, 0x01, 0x02, 0x3e, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0xb6, 0x04, 0x60, 0x00, 0x01, 0x02, 0xb6, - 0xfe, 0x56, 0x00, 0x01, 0x01, 0xfc, 0x04, 0x66, 0x00, 0x01, 0x02, 0x26, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x36, 0x04, 0x60, 0x00, 0x01, 0x02, 0x36, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x63, 0x04, 0x60, 0x00, 0x01, 0x02, 0x63, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x04, 0x60, 0x00, 0x01, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x04, 0x60, 0x00, 0x01, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x73, 0x06, 0x14, 0x00, 0x01, 0x02, 0x73, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x73, 0x06, 0x14, 0x00, 0x01, 0x02, 0x73, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x78, 0x04, 0x60, 0x00, 0x01, 0x02, 0x78, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x73, 0x06, 0x14, 0x00, 0x01, 0x02, 0x73, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0xa4, 0x04, 0x60, 0x00, 0x01, 0x02, 0xa4, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x1c, 0x04, 0x60, 0x00, 0x01, 0x02, 0x1c, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0xff, 0x8e, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x24, 0x06, 0x14, 0x00, 0x01, 0x02, 0x24, - 0x00, 0x00, 0x00, 0x01, 0x02, 0xaa, 0x06, 0x14, 0x00, 0x01, 0x02, 0xaa, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x24, 0x06, 0x14, 0x00, 0x01, 0x02, 0x24, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x20, 0x04, 0x60, 0x00, 0x01, 0x02, 0x20, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x3e, 0x04, 0x60, 0x00, 0x01, 0x02, 0x3e, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x1a, 0x06, 0x14, 0x00, 0x01, 0x02, 0x1a, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x24, 0x06, 0x14, 0x00, 0x01, 0x02, 0x24, - 0x00, 0x00, 0x00, 0x01, 0x02, 0xaa, 0x06, 0x14, 0x00, 0x01, 0x02, 0xaa, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x76, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0xb3, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x35, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0xb3, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x03, 0x27, - 0x05, 0xf0, 0x00, 0x01, 0x03, 0x27, 0x00, 0x00, 0x00, 0x01, 0x02, 0x7d, - 0x04, 0x7b, 0x00, 0x01, 0x02, 0x7d, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xe0, 0x00, 0x01, 0x02, 0x68, 0x02, 0x9c, 0x00, 0x01, 0x02, 0x52, - 0x05, 0xe0, 0x00, 0x01, 0x02, 0x52, 0x02, 0x9c, 0x00, 0x01, 0x02, 0x45, - 0x05, 0xe0, 0x00, 0x01, 0x02, 0x45, 0x02, 0x9c, 0x00, 0x01, 0x02, 0x5e, - 0x05, 0xe0, 0x00, 0x01, 0x02, 0x5e, 0x02, 0x9c, 0x00, 0x01, 0x02, 0x72, - 0x05, 0xe0, 0x00, 0x01, 0x02, 0x72, 0x02, 0x9c, 0x00, 0x01, 0x02, 0x90, - 0x05, 0xe0, 0x00, 0x01, 0x02, 0x90, 0x02, 0x9c, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xe0, 0x00, 0x01, 0x02, 0x68, 0x02, 0x9c, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xe0, 0x00, 0x01, 0x02, 0x68, 0x02, 0x9c, 0x00, 0x01, 0x02, 0xbc, - 0x05, 0xe0, 0x00, 0x01, 0x02, 0xbc, 0x02, 0x9c, 0x00, 0x01, 0x02, 0x3f, - 0x05, 0xe0, 0x00, 0x01, 0x02, 0x3f, 0x02, 0x9c, 0x00, 0x01, 0x02, 0x61, - 0x05, 0xe0, 0x00, 0x01, 0x02, 0x61, 0x02, 0x9c, 0x00, 0x01, 0x02, 0x69, - 0x05, 0xe0, 0x00, 0x01, 0x02, 0x69, 0x02, 0x9c, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xe0, 0x00, 0x01, 0x02, 0x68, 0x02, 0x9c, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xe0, 0x00, 0x01, 0x02, 0x68, 0x02, 0x9c, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xe0, 0x00, 0x01, 0x02, 0x68, 0x02, 0x9c, 0x00, 0x01, 0x02, 0x47, - 0x05, 0xe0, 0x00, 0x01, 0x02, 0x47, 0x02, 0x9c, 0x00, 0x01, 0x02, 0x1b, - 0x05, 0xe0, 0x00, 0x01, 0x02, 0x1b, 0x02, 0x9c, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xe0, 0x00, 0x01, 0x02, 0x68, 0x02, 0x9c, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xe0, 0x00, 0x01, 0x02, 0x68, 0x02, 0x9c, 0x00, 0x01, 0x02, 0x68, - 0x05, 0xe0, 0x00, 0x01, 0x02, 0x68, 0x02, 0x9c, 0x00, 0x01, 0x02, 0x36, - 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x5c, - 0x02, 0x9c, 0x00, 0x01, 0x02, 0x61, 0x05, 0xf0, 0x00, 0x01, 0x02, 0x61, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x64, 0x05, 0xe2, 0x00, 0x01, 0x02, 0x64, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x35, 0x05, 0xf0, 0x00, 0x01, 0x02, 0x35, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x67, 0x05, 0xf0, 0x00, 0x01, 0x03, 0x27, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x65, 0x05, 0xe2, 0x00, 0x01, 0x02, 0x65, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x60, 0x05, 0xe2, 0x00, 0x01, 0x02, 0x60, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x36, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x36, - 0xfe, 0x4c, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0xa4, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x69, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x69, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x9a, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x9a, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x68, 0x06, 0x14, 0x00, 0x01, 0x02, 0x68, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x69, 0x06, 0x14, 0x00, 0x01, 0x02, 0x69, - 0xfe, 0x56, 0x00, 0x01, 0x02, 0x31, 0x05, 0xd5, 0x00, 0x01, 0x02, 0x31, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x1f, 0x04, 0x60, 0x00, 0x01, 0x02, 0x1f, - 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x05, 0xd5, 0x00, 0x01, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x05, 0xd5, 0x00, 0x02, 0x00, 0x25, - 0x00, 0x24, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x44, 0x00, 0x5d, 0x00, 0x1a, - 0x00, 0x82, 0x00, 0x98, 0x00, 0x34, 0x00, 0x9a, 0x00, 0xb8, 0x00, 0x4b, - 0x00, 0xba, 0x00, 0xc2, 0x00, 0x6a, 0x00, 0xc4, 0x00, 0xc8, 0x00, 0x73, - 0x00, 0xca, 0x00, 0xf0, 0x00, 0x78, 0x00, 0xf2, 0x00, 0xf3, 0x00, 0x9f, - 0x00, 0xf6, 0x01, 0x6b, 0x00, 0xa1, 0x01, 0xd1, 0x01, 0xd1, 0x01, 0x17, - 0x01, 0xe6, 0x01, 0xe6, 0x01, 0x18, 0x01, 0xf1, 0x01, 0xf2, 0x01, 0x19, - 0x01, 0xf4, 0x02, 0x0d, 0x01, 0x1b, 0x02, 0x0f, 0x02, 0x13, 0x01, 0x35, - 0x02, 0x15, 0x02, 0x3c, 0x01, 0x3a, 0x02, 0x3e, 0x02, 0x42, 0x01, 0x62, - 0x02, 0x44, 0x02, 0x48, 0x01, 0x67, 0x03, 0x69, 0x03, 0x71, 0x01, 0x6c, - 0x03, 0x73, 0x03, 0x88, 0x01, 0x75, 0x03, 0x8d, 0x03, 0x8e, 0x01, 0x8b, - 0x03, 0x9b, 0x03, 0x9c, 0x01, 0x8d, 0x05, 0x10, 0x05, 0x10, 0x01, 0x8f, - 0x05, 0x12, 0x05, 0x24, 0x01, 0x90, 0x05, 0x7a, 0x05, 0x7a, 0x01, 0xa3, - 0x05, 0xb1, 0x05, 0xb1, 0x01, 0xa4, 0x07, 0x3f, 0x07, 0x3f, 0x01, 0xa5, - 0x07, 0x82, 0x07, 0x82, 0x01, 0xa6, 0x07, 0x85, 0x07, 0x85, 0x01, 0xa7, - 0x07, 0x88, 0x07, 0x8a, 0x01, 0xa8, 0x07, 0x8c, 0x07, 0x8c, 0x01, 0xab, - 0x0b, 0x69, 0x0b, 0x69, 0x01, 0xac, 0x0b, 0x6b, 0x0b, 0x6c, 0x01, 0xad, - 0x0b, 0x71, 0x0b, 0x72, 0x01, 0xaf, 0x0b, 0x75, 0x0b, 0x76, 0x01, 0xb1, - 0x0b, 0x96, 0x0b, 0x97, 0x01, 0xb3, 0x0b, 0x9d, 0x0b, 0xa0, 0x01, 0xb5, - 0x0c, 0xdf, 0x0c, 0xdf, 0x01, 0xb9, 0x00, 0x02, 0x00, 0x07, 0x02, 0x88, - 0x02, 0x99, 0x00, 0x00, 0x02, 0x9b, 0x02, 0xa1, 0x00, 0x12, 0x02, 0xa4, - 0x02, 0xa8, 0x00, 0x19, 0x02, 0xab, 0x02, 0xae, 0x00, 0x1e, 0x02, 0xb1, - 0x02, 0xb9, 0x00, 0x22, 0x02, 0xc1, 0x02, 0xc6, 0x00, 0x2b, 0x02, 0xc8, - 0x02, 0xc8, 0x00, 0x31, 0x00, 0x32, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00, - 0x00, 0xd0, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, - 0x00, 0xe2, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, - 0x00, 0xf4, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x01, 0x06, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x01, 0x12, 0x00, 0x00, - 0x01, 0x18, 0x00, 0x00, 0x01, 0x1e, 0x00, 0x00, 0x01, 0x24, 0x00, 0x00, - 0x01, 0x2a, 0x00, 0x00, 0x01, 0x30, 0x00, 0x00, 0x01, 0x36, 0x00, 0x00, - 0x01, 0x3c, 0x00, 0x00, 0x01, 0x42, 0x00, 0x01, 0x01, 0x48, 0x00, 0x01, - 0x01, 0x4e, 0x00, 0x01, 0x01, 0x54, 0x00, 0x01, 0x01, 0x5a, 0x00, 0x01, - 0x01, 0x60, 0x00, 0x01, 0x01, 0x66, 0x00, 0x01, 0x01, 0x6c, 0x00, 0x01, - 0x01, 0x72, 0x00, 0x01, 0x01, 0x78, 0x00, 0x01, 0x01, 0x7e, 0x00, 0x01, - 0x01, 0x84, 0x00, 0x01, 0x01, 0x8a, 0x00, 0x01, 0x01, 0x90, 0x00, 0x01, - 0x01, 0x96, 0x00, 0x01, 0x01, 0x9c, 0x00, 0x01, 0x01, 0xa2, 0x00, 0x01, - 0x01, 0xa8, 0x00, 0x01, 0x01, 0xae, 0x00, 0x01, 0x01, 0xb4, 0x00, 0x01, - 0x01, 0xba, 0x00, 0x01, 0x01, 0xc0, 0x00, 0x01, 0x01, 0xc6, 0x00, 0x01, - 0x01, 0xcc, 0x00, 0x01, 0x01, 0xd2, 0x00, 0x01, 0x01, 0xd8, 0x00, 0x01, - 0x01, 0xde, 0x00, 0x00, 0x01, 0xe4, 0x00, 0x00, 0x01, 0xea, 0x00, 0x00, - 0x01, 0xf0, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, 0x04, 0x60, 0x00, 0x01, 0x02, 0x68, - 0x04, 0x60, 0x00, 0x01, 0x00, 0x08, 0x00, 0x04, 0xfb, 0x2f, 0x00, 0x02, - 0x00, 0x06, 0x02, 0x88, 0x02, 0x99, 0x00, 0x00, 0x02, 0x9b, 0x02, 0xa1, - 0x00, 0x12, 0x02, 0xa4, 0x02, 0xa8, 0x00, 0x19, 0x02, 0xab, 0x02, 0xb9, - 0x00, 0x1e, 0x02, 0xc1, 0x02, 0xc6, 0x00, 0x2d, 0x02, 0xc8, 0x02, 0xc8, - 0x00, 0x33, 0x00, 0x01, 0x01, 0xc8, 0x01, 0xbe, 0x00, 0x02, 0x01, 0xd8, - 0x00, 0x0c, 0x00, 0x1b, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x7a, 0x00, 0x80, - 0x00, 0x86, 0x00, 0x8c, 0x00, 0x92, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xa4, - 0x00, 0xaa, 0x00, 0xb0, 0x00, 0xb6, 0x00, 0xbc, 0x00, 0xc2, 0x00, 0xc8, - 0x00, 0xce, 0x00, 0xd4, 0x00, 0xda, 0x00, 0xe0, 0x00, 0xe6, 0x00, 0xec, - 0x00, 0xf2, 0x00, 0xf8, 0x00, 0xfe, 0x01, 0x04, 0x01, 0x0a, 0x01, 0x10, - 0x01, 0x16, 0x01, 0x1c, 0x01, 0x22, 0x01, 0x28, 0x01, 0x2e, 0x01, 0x34, - 0x01, 0x3a, 0x01, 0x40, 0x01, 0x46, 0x01, 0x4c, 0x01, 0x52, 0x01, 0x58, - 0x01, 0x5e, 0x01, 0x64, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x76, 0x01, 0x7c, - 0x01, 0x82, 0x01, 0x88, 0x01, 0x8e, 0x01, 0x94, 0x01, 0x9a, 0x01, 0xa0, - 0x01, 0xa6, 0x01, 0xac, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd1, 0x04, 0xa0, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd1, 0x04, 0xa0, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd1, 0x04, 0xa0, 0x00, 0x01, 0x04, 0xd1, 0xfe, 0x14, 0x00, 0x01, - 0x04, 0xd1, 0x04, 0xa0, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd1, 0x04, 0xa0, 0x00, 0x01, 0x04, 0xd1, 0xfe, 0x14, 0x00, 0x01, - 0x04, 0xd1, 0x04, 0xa0, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd1, 0x04, 0xa0, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd1, 0x04, 0xa0, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd1, 0x04, 0xa0, 0x00, 0x01, 0x04, 0xd1, 0xfe, 0x14, 0x00, 0x01, - 0x04, 0xd1, 0x04, 0xa0, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd1, 0x04, 0xa0, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd1, 0x04, 0xa0, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd1, 0x04, 0xa0, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd2, 0x06, 0x10, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd1, 0x04, 0xa0, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd2, 0x06, 0x10, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd1, 0x04, 0xa0, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd2, 0x06, 0x10, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd1, 0x04, 0xa0, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd1, 0x06, 0x10, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd1, 0x04, 0xa0, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd1, 0x04, 0xa0, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd1, 0x04, 0xa0, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd1, 0x04, 0xa0, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd1, 0x04, 0xa0, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd1, 0x04, 0xa0, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, - 0x04, 0xd1, 0x04, 0xa0, 0x00, 0x02, 0x00, 0x01, 0x04, 0xac, 0x04, 0xc6, - 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x04, 0xc9, 0x04, 0xc9, 0x00, 0x00, - 0x04, 0xcc, 0x04, 0xd9, 0x00, 0x01, 0x00, 0x0f, 0x00, 0x01, 0x00, 0x3e, - 0x00, 0x01, 0x00, 0x44, 0x00, 0x01, 0x00, 0x4a, 0x00, 0x01, 0x00, 0x50, - 0x00, 0x01, 0x00, 0x56, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x62, - 0x00, 0x01, 0x00, 0x68, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x01, 0x00, 0x74, - 0x00, 0x01, 0x00, 0x7a, 0x00, 0x01, 0x00, 0x80, 0x00, 0x01, 0x00, 0x86, - 0x00, 0x01, 0x00, 0x8c, 0x00, 0x01, 0x00, 0x92, 0x00, 0x01, 0xff, 0xf7, - 0x04, 0x74, 0x00, 0x01, 0x04, 0xd1, 0x04, 0x77, 0x00, 0x01, 0x04, 0xd1, - 0x04, 0x77, 0x00, 0x01, 0x04, 0xd1, 0x04, 0x77, 0x00, 0x01, 0x04, 0xd1, - 0x04, 0x77, 0x00, 0x01, 0x04, 0xd1, 0x00, 0x00, 0x00, 0x01, 0x04, 0xd1, - 0x00, 0x00, 0x00, 0x01, 0x04, 0xd1, 0x04, 0x74, 0x00, 0x01, 0x04, 0xd1, - 0x00, 0x00, 0x00, 0x01, 0x04, 0xd1, 0x04, 0x60, 0x00, 0x01, 0x04, 0xd1, - 0x04, 0x7e, 0x00, 0x01, 0x04, 0xd1, 0x04, 0x7e, 0x00, 0x01, 0x04, 0xd1, - 0x04, 0x60, 0x00, 0x01, 0x04, 0xd1, 0x04, 0x7e, 0x00, 0x01, 0x04, 0xd1, - 0x04, 0x60, 0x00, 0x01, 0x00, 0x08, 0x00, 0x04, 0xfb, 0x2f, 0x00, 0x02, - 0x00, 0x02, 0x04, 0xc9, 0x04, 0xc9, 0x00, 0x00, 0x04, 0xcc, 0x04, 0xd9, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0xca, - 0x01, 0x38, 0x00, 0x06, 0x44, 0x46, 0x4c, 0x54, 0x00, 0x26, 0x61, 0x72, - 0x61, 0x62, 0x00, 0x30, 0x63, 0x79, 0x72, 0x6c, 0x00, 0x44, 0x67, 0x72, - 0x65, 0x6b, 0x00, 0x60, 0x6c, 0x61, 0x6f, 0x20, 0x00, 0x6c, 0x6c, 0x61, - 0x74, 0x6e, 0x00, 0x76, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x05, - 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x07, 0x00, 0x08, 0x00, 0x0a, - 0x00, 0x01, 0x53, 0x52, 0x42, 0x20, 0x00, 0x12, 0x00, 0x00, 0xff, 0xff, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x02, 0x00, 0x00, - 0x00, 0x05, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x34, 0x00, 0x08, 0x49, 0x53, 0x4d, 0x20, 0x00, 0x3e, 0x4b, 0x53, - 0x4d, 0x20, 0x00, 0x3e, 0x4c, 0x53, 0x4d, 0x20, 0x00, 0x3e, 0x4d, 0x4f, - 0x4c, 0x20, 0x00, 0x34, 0x4e, 0x53, 0x4d, 0x20, 0x00, 0x3e, 0x52, 0x4f, - 0x4d, 0x20, 0x00, 0x34, 0x53, 0x4b, 0x53, 0x20, 0x00, 0x3e, 0x53, 0x53, - 0x4d, 0x20, 0x00, 0x3e, 0x00, 0x00, 0xff, 0xff, 0x00, 0x02, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0xff, 0xff, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x06, 0x00, 0x09, 0x63, 0x63, 0x6d, 0x70, 0x00, 0x38, 0x64, 0x6c, - 0x69, 0x67, 0x00, 0x3e, 0x66, 0x69, 0x6e, 0x61, 0x00, 0x44, 0x69, 0x6e, - 0x69, 0x74, 0x00, 0x4a, 0x6c, 0x69, 0x67, 0x61, 0x00, 0x50, 0x6c, 0x6f, - 0x63, 0x6c, 0x00, 0x56, 0x6c, 0x6f, 0x63, 0x6c, 0x00, 0x5c, 0x6d, 0x65, - 0x64, 0x69, 0x00, 0x62, 0x72, 0x6c, 0x69, 0x67, 0x00, 0x68, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x05, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x06, 0x00, 0x0a, 0x00, 0x16, 0x00, 0x1e, 0x00, 0x26, - 0x00, 0x2e, 0x00, 0x36, 0x00, 0x3e, 0x00, 0x46, 0x00, 0x4e, 0x00, 0x56, - 0x00, 0x5e, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x50, 0x00, 0x06, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x54, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, - 0x00, 0xdc, 0x00, 0x01, 0x00, 0x09, 0x00, 0x01, 0x00, 0xe0, 0x00, 0x01, - 0x00, 0x09, 0x00, 0x01, 0x01, 0x64, 0x00, 0x01, 0x00, 0x09, 0x00, 0x01, - 0x01, 0xe4, 0x00, 0x04, 0x00, 0x09, 0x00, 0x01, 0x02, 0x64, 0x00, 0x04, - 0x00, 0x09, 0x00, 0x01, 0x02, 0x82, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, - 0x02, 0xc0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0xd8, 0x00, 0x01, - 0x00, 0x06, 0x0b, 0xd3, 0x00, 0x01, 0x00, 0x01, 0x01, 0x0c, 0x00, 0x02, - 0x00, 0x14, 0x00, 0x1c, 0x00, 0x24, 0x00, 0x24, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x4c, - 0x00, 0x4d, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x08, 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x01, 0x02, 0x88, 0x02, 0x9d, - 0x00, 0x02, 0x02, 0x9e, 0x02, 0xa1, 0x00, 0x03, 0x02, 0xa4, 0x02, 0xa8, - 0x00, 0x03, 0x02, 0xab, 0x02, 0xbb, 0x00, 0x03, 0x02, 0xc1, 0x02, 0xc4, - 0x00, 0x03, 0x02, 0xc5, 0x02, 0xc8, 0x00, 0x02, 0x02, 0xcb, 0x02, 0xcb, - 0x00, 0x02, 0x00, 0x03, 0x00, 0x08, 0x00, 0x16, 0x00, 0x26, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x02, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x03, - 0x00, 0x03, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x00, 0x01, - 0x00, 0x06, 0x08, 0x37, 0x00, 0x01, 0x00, 0x01, 0x03, 0x6a, 0x00, 0x02, - 0x00, 0x70, 0x00, 0x35, 0x0b, 0xfd, 0x0b, 0xff, 0x0c, 0x01, 0x0c, 0x03, - 0x0c, 0x05, 0x0c, 0x09, 0x0c, 0x0b, 0x0c, 0x0f, 0x0c, 0x11, 0x0c, 0x15, - 0x0c, 0x19, 0x0c, 0x1d, 0x0c, 0x21, 0x0c, 0x25, 0x0c, 0x27, 0x0c, 0x29, - 0x0c, 0x2b, 0x0c, 0x2d, 0x0c, 0x31, 0x0c, 0x35, 0x0c, 0x39, 0x0c, 0x3d, - 0x0c, 0x41, 0x0c, 0x45, 0x0c, 0x49, 0x0c, 0x4d, 0x0c, 0x51, 0x0c, 0x55, - 0x0c, 0x59, 0x0c, 0x5d, 0x0c, 0x61, 0x0c, 0x65, 0x0c, 0x69, 0x0c, 0x6b, - 0x0c, 0x6d, 0x0b, 0xb9, 0x0b, 0xb1, 0x0b, 0xa5, 0x0b, 0xa9, 0x0b, 0xb5, - 0x0b, 0xad, 0x0b, 0xc9, 0x0b, 0xc5, 0x0b, 0xcd, 0x0b, 0xd1, 0x0b, 0xd7, - 0x0b, 0xd5, 0x0b, 0xbd, 0x0b, 0xd9, 0x0b, 0xdd, 0x0b, 0xe3, 0x0b, 0xe9, - 0x0b, 0xe1, 0x00, 0x02, 0x00, 0x04, 0x04, 0x52, 0x04, 0x6a, 0x00, 0x00, - 0x04, 0x6c, 0x04, 0x75, 0x00, 0x19, 0x04, 0x91, 0x04, 0xa1, 0x00, 0x23, - 0x0c, 0xea, 0x0c, 0xea, 0x00, 0x34, 0x00, 0x02, 0x00, 0x54, 0x00, 0x27, - 0x0c, 0x07, 0x0c, 0x0d, 0x0c, 0x13, 0x0c, 0x17, 0x0c, 0x1b, 0x0c, 0x1f, - 0x0c, 0x23, 0x0c, 0x2f, 0x0c, 0x33, 0x0c, 0x37, 0x0c, 0x3b, 0x0c, 0x3f, - 0x0c, 0x43, 0x0c, 0x47, 0x0c, 0x4b, 0x0c, 0x4f, 0x0c, 0x53, 0x0c, 0x57, - 0x0c, 0x5b, 0x0c, 0x5f, 0x0c, 0x63, 0x0c, 0x67, 0x0b, 0xe7, 0x0c, 0x6f, - 0x0b, 0xbb, 0x0b, 0xb3, 0x0b, 0xa7, 0x0b, 0xab, 0x0b, 0xb7, 0x0b, 0xaf, - 0x0b, 0xcb, 0x0b, 0xc7, 0x0b, 0xcf, 0x0b, 0xd3, 0x0b, 0xbf, 0x0b, 0xdb, - 0x0b, 0xdf, 0x0b, 0xe5, 0x0b, 0xeb, 0x00, 0x02, 0x00, 0x08, 0x04, 0x56, - 0x04, 0x56, 0x00, 0x00, 0x04, 0x58, 0x04, 0x58, 0x00, 0x01, 0x04, 0x5a, - 0x04, 0x5e, 0x00, 0x02, 0x04, 0x63, 0x04, 0x6a, 0x00, 0x07, 0x04, 0x6c, - 0x04, 0x72, 0x00, 0x0f, 0x04, 0x74, 0x04, 0x75, 0x00, 0x16, 0x04, 0x91, - 0x04, 0x9a, 0x00, 0x18, 0x04, 0x9d, 0x04, 0xa1, 0x00, 0x22, 0x00, 0x02, - 0x00, 0x54, 0x00, 0x27, 0x0c, 0x06, 0x0c, 0x0c, 0x0c, 0x12, 0x0c, 0x16, - 0x0c, 0x1a, 0x0c, 0x1e, 0x0c, 0x22, 0x0c, 0x2e, 0x0c, 0x32, 0x0c, 0x36, - 0x0c, 0x3a, 0x0c, 0x3e, 0x0c, 0x42, 0x0c, 0x46, 0x0c, 0x4a, 0x0c, 0x4e, - 0x0c, 0x52, 0x0c, 0x56, 0x0c, 0x5a, 0x0c, 0x5e, 0x0c, 0x62, 0x0c, 0x66, - 0x0b, 0xe6, 0x0c, 0x6e, 0x0b, 0xba, 0x0b, 0xb2, 0x0b, 0xa6, 0x0b, 0xaa, - 0x0b, 0xb6, 0x0b, 0xae, 0x0b, 0xca, 0x0b, 0xc6, 0x0b, 0xce, 0x0b, 0xd2, - 0x0b, 0xbe, 0x0b, 0xda, 0x0b, 0xde, 0x0b, 0xe4, 0x0b, 0xea, 0x00, 0x02, - 0x00, 0x08, 0x04, 0x56, 0x04, 0x56, 0x00, 0x00, 0x04, 0x58, 0x04, 0x58, - 0x00, 0x01, 0x04, 0x5a, 0x04, 0x5e, 0x00, 0x02, 0x04, 0x63, 0x04, 0x6a, - 0x00, 0x07, 0x04, 0x6c, 0x04, 0x72, 0x00, 0x0f, 0x04, 0x74, 0x04, 0x75, - 0x00, 0x16, 0x04, 0x91, 0x04, 0x9a, 0x00, 0x18, 0x04, 0x9d, 0x04, 0xa1, - 0x00, 0x22, 0x00, 0x01, 0x00, 0x1e, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x14, - 0x00, 0x01, 0x00, 0x04, 0x0c, 0x76, 0x00, 0x02, 0x0c, 0x09, 0x00, 0x01, - 0x00, 0x04, 0x0c, 0x77, 0x00, 0x02, 0x0c, 0x09, 0x00, 0x01, 0x00, 0x02, - 0x0c, 0x5a, 0x0c, 0x5b, 0x00, 0x01, 0x00, 0x3e, 0x00, 0x02, 0x00, 0x0a, - 0x00, 0x24, 0x00, 0x03, 0x00, 0x08, 0x00, 0x0e, 0x00, 0x14, 0x0c, 0x74, - 0x00, 0x02, 0x0c, 0x03, 0x0c, 0x72, 0x00, 0x02, 0x0b, 0xff, 0x0c, 0x70, - 0x00, 0x02, 0x0b, 0xfd, 0x00, 0x03, 0x00, 0x08, 0x00, 0x0e, 0x00, 0x14, - 0x0c, 0x75, 0x00, 0x02, 0x0c, 0x03, 0x0c, 0x73, 0x00, 0x02, 0x0b, 0xff, - 0x0c, 0x71, 0x00, 0x02, 0x0b, 0xfd, 0x00, 0x01, 0x00, 0x02, 0x0c, 0x5a, - 0x0c, 0x5b, 0x00, 0x01, 0x00, 0x1a, 0x00, 0x01, 0x00, 0x08, 0x00, 0x02, - 0x00, 0x06, 0x00, 0x0c, 0x0b, 0xa3, 0x00, 0x02, 0x00, 0x4f, 0x0b, 0xa2, - 0x00, 0x02, 0x00, 0x4c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x49, 0x00, 0x02, - 0x00, 0x0a, 0x00, 0x02, 0x00, 0xf3, 0x01, 0xe6, 0x00, 0x01, 0x00, 0x02, - 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x01, 0x04, 0xd1, 0x01, 0x90, 0x00, 0x05, - 0x00, 0x00, 0x05, 0x33, 0x05, 0x99, 0x00, 0x00, 0x01, 0x1e, 0x05, 0x33, - 0x05, 0x99, 0x00, 0x00, 0x03, 0xd7, 0x00, 0x66, 0x02, 0x12, 0x00, 0x00, - 0x02, 0x0b, 0x06, 0x09, 0x03, 0x08, 0x04, 0x02, 0x02, 0x04, 0xe6, 0x00, - 0x26, 0xff, 0xd2, 0x00, 0xf9, 0xfb, 0x02, 0x00, 0x00, 0x28, 0x00, 0x00, - 0x00, 0x00, 0x50, 0x66, 0x45, 0x64, 0x00, 0x40, 0x00, 0x20, 0xff, 0xff, - 0x06, 0x14, 0xfe, 0x14, 0x01, 0x9a, 0x07, 0x6d, 0x01, 0xe3, 0x60, 0x00, - 0x01, 0xdf, 0xdf, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x04, - 0x00, 0x00, 0x08, 0x4c, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x80, - 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x03, 0x00, 0x0a, - 0x00, 0x00, 0x08, 0x4c, 0x00, 0x04, 0x08, 0x20, 0x00, 0x00, 0x02, 0x04, - 0x02, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7e, 0x01, 0xc3, - 0x01, 0xe3, 0x01, 0xf0, 0x01, 0xf6, 0x01, 0xf9, 0x02, 0x21, 0x02, 0x41, - 0x02, 0x45, 0x02, 0x4d, 0x02, 0xb9, 0x02, 0xc1, 0x02, 0xc9, 0x02, 0xd3, - 0x02, 0xde, 0x02, 0xe9, 0x02, 0xee, 0x02, 0xf3, 0x03, 0x3f, 0x03, 0x43, - 0x03, 0x58, 0x03, 0x61, 0x03, 0x75, 0x03, 0x7a, 0x03, 0x7e, 0x03, 0x8a, - 0x03, 0x8c, 0x03, 0xa1, 0x03, 0xce, 0x03, 0xe1, 0x04, 0x5f, 0x04, 0x63, - 0x04, 0x73, 0x04, 0x9b, 0x04, 0xa5, 0x04, 0xb3, 0x04, 0xbb, 0x04, 0xc4, - 0x04, 0xc8, 0x04, 0xcc, 0x04, 0xf9, 0x05, 0x11, 0x05, 0x1d, 0x05, 0x56, - 0x05, 0x5f, 0x05, 0x87, 0x05, 0x8a, 0x06, 0x07, 0x06, 0x0a, 0x06, 0x0c, - 0x06, 0x15, 0x06, 0x1b, 0x06, 0x1f, 0x06, 0x3a, 0x06, 0x55, 0x06, 0x5a, - 0x06, 0x6d, 0x06, 0x74, 0x06, 0x7b, 0x06, 0x80, 0x06, 0x84, 0x06, 0x87, - 0x06, 0x91, 0x06, 0x98, 0x06, 0xa4, 0x06, 0xa9, 0x06, 0xaf, 0x06, 0xbe, - 0x06, 0xcc, 0x06, 0xf9, 0x0e, 0x82, 0x0e, 0x84, 0x0e, 0x88, 0x0e, 0x8a, - 0x0e, 0x8d, 0x0e, 0x97, 0x0e, 0x9f, 0x0e, 0xa3, 0x0e, 0xa5, 0x0e, 0xa7, - 0x0e, 0xab, 0x0e, 0xb9, 0x0e, 0xbc, 0x0e, 0xcd, 0x10, 0xfc, 0x1d, 0x02, - 0x1d, 0x09, 0x1d, 0x14, 0x1d, 0x17, 0x1d, 0x1f, 0x1d, 0x2e, 0x1d, 0x3c, - 0x1d, 0x5b, 0x1d, 0x65, 0x1d, 0x78, 0x1d, 0x7b, 0x1d, 0x85, 0x1d, 0xb7, - 0x1d, 0xbf, 0x1e, 0x13, 0x1e, 0x2d, 0x1e, 0x4d, 0x1e, 0x63, 0x1e, 0x79, - 0x1e, 0x99, 0x1e, 0x9b, 0x1e, 0xa1, 0x1e, 0xad, 0x1e, 0xb1, 0x1e, 0xb9, - 0x1e, 0xbd, 0x1e, 0xc7, 0x1e, 0xcd, 0x1e, 0xdd, 0x1e, 0xe5, 0x1e, 0xeb, - 0x1e, 0xf5, 0x1e, 0xf9, 0x1f, 0x15, 0x1f, 0x1d, 0x1f, 0x45, 0x1f, 0x4d, - 0x1f, 0x57, 0x1f, 0x59, 0x1f, 0x5b, 0x1f, 0x5d, 0x1f, 0x7d, 0x1f, 0xb4, - 0x1f, 0xc4, 0x1f, 0xd3, 0x1f, 0xdb, 0x1f, 0xef, 0x1f, 0xf4, 0x1f, 0xfe, - 0x20, 0x0a, 0x20, 0x23, 0x20, 0x26, 0x20, 0x37, 0x20, 0x3a, 0x20, 0x3e, - 0x20, 0x49, 0x20, 0x4b, 0x20, 0x5f, 0x20, 0x71, 0x20, 0x8e, 0x20, 0x9c, - 0x20, 0xb5, 0x20, 0xb9, 0x21, 0x02, 0x21, 0x05, 0x21, 0x0f, 0x21, 0x17, - 0x21, 0x1a, 0x21, 0x1d, 0x21, 0x22, 0x21, 0x24, 0x21, 0x26, 0x21, 0x2b, - 0x21, 0x2e, 0x21, 0x48, 0x21, 0x5f, 0x22, 0x0d, 0x22, 0x0f, 0x22, 0x13, - 0x22, 0x15, 0x22, 0x20, 0x22, 0x2d, 0x22, 0x3d, 0x22, 0x69, 0x22, 0x8b, - 0x22, 0x92, 0x22, 0xa5, 0x22, 0xc6, 0x22, 0xcd, 0x22, 0xe9, 0x22, 0xef, - 0x23, 0x06, 0x23, 0x15, 0x23, 0x19, 0x23, 0x21, 0x23, 0x28, 0x23, 0x2b, - 0x23, 0x35, 0x23, 0x3e, 0x23, 0x44, 0x23, 0x49, 0x23, 0x4d, 0x23, 0x50, - 0x23, 0x54, 0x23, 0x5c, 0x23, 0x60, 0x23, 0x65, 0x23, 0x69, 0x23, 0x70, - 0x23, 0x7a, 0x23, 0x7d, 0x23, 0x83, 0x23, 0x8b, 0x23, 0x95, 0x23, 0xae, - 0x23, 0xcf, 0x24, 0x23, 0x26, 0x2f, 0x26, 0x8b, 0x26, 0x9c, 0x26, 0xa1, - 0x26, 0xb1, 0x27, 0x04, 0x27, 0x09, 0x27, 0x27, 0x27, 0x4b, 0x27, 0x4d, - 0x27, 0x52, 0x27, 0x56, 0x27, 0x5e, 0x27, 0x75, 0x27, 0x94, 0x27, 0xaf, - 0x27, 0xbe, 0x27, 0xc2, 0x27, 0xc6, 0x27, 0xe0, 0x27, 0xe9, 0x29, 0xeb, - 0x29, 0xfb, 0x2a, 0x2f, 0x2a, 0x6b, 0x2b, 0x0d, 0x2b, 0x1a, 0x2c, 0x64, - 0x2c, 0x70, 0x2c, 0x77, 0x2c, 0x7a, 0x2c, 0x7f, 0x2e, 0x18, 0x2e, 0x1f, - 0x2e, 0x25, 0x2e, 0x2e, 0xa7, 0x16, 0xa7, 0x1f, 0xa7, 0x27, 0xa7, 0x8e, - 0xa7, 0x91, 0xa7, 0xaa, 0xf6, 0xc5, 0xfb, 0x02, 0xfb, 0x81, 0xfb, 0x95, - 0xfb, 0x9f, 0xfb, 0xad, 0xfb, 0xe9, 0xfb, 0xff, 0xfe, 0x74, 0xfe, 0xfc, - 0xfe, 0xff, 0xff, 0xfd, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, - 0x00, 0xa0, 0x01, 0xcd, 0x01, 0xe6, 0x01, 0xf4, 0x01, 0xf8, 0x01, 0xfc, - 0x02, 0x24, 0x02, 0x43, 0x02, 0x4c, 0x02, 0x50, 0x02, 0xbb, 0x02, 0xc6, - 0x02, 0xcc, 0x02, 0xd6, 0x02, 0xe0, 0x02, 0xee, 0x02, 0xf3, 0x03, 0x00, - 0x03, 0x43, 0x03, 0x58, 0x03, 0x61, 0x03, 0x74, 0x03, 0x7a, 0x03, 0x7e, - 0x03, 0x84, 0x03, 0x8c, 0x03, 0x8e, 0x03, 0xa3, 0x03, 0xd0, 0x03, 0xf0, - 0x04, 0x62, 0x04, 0x72, 0x04, 0x90, 0x04, 0xa2, 0x04, 0xaa, 0x04, 0xba, - 0x04, 0xc0, 0x04, 0xc7, 0x04, 0xcb, 0x04, 0xcf, 0x05, 0x10, 0x05, 0x1a, - 0x05, 0x31, 0x05, 0x59, 0x05, 0x61, 0x05, 0x89, 0x06, 0x06, 0x06, 0x09, - 0x06, 0x0c, 0x06, 0x15, 0x06, 0x1b, 0x06, 0x1f, 0x06, 0x21, 0x06, 0x40, - 0x06, 0x5a, 0x06, 0x60, 0x06, 0x74, 0x06, 0x79, 0x06, 0x7e, 0x06, 0x83, - 0x06, 0x86, 0x06, 0x91, 0x06, 0x98, 0x06, 0xa4, 0x06, 0xa9, 0x06, 0xaf, - 0x06, 0xbe, 0x06, 0xcc, 0x06, 0xf0, 0x0e, 0x81, 0x0e, 0x84, 0x0e, 0x87, - 0x0e, 0x8a, 0x0e, 0x8d, 0x0e, 0x94, 0x0e, 0x99, 0x0e, 0xa1, 0x0e, 0xa5, - 0x0e, 0xa7, 0x0e, 0xaa, 0x0e, 0xad, 0x0e, 0xbb, 0x0e, 0xc8, 0x10, 0xd0, - 0x1d, 0x02, 0x1d, 0x08, 0x1d, 0x14, 0x1d, 0x16, 0x1d, 0x1d, 0x1d, 0x2c, - 0x1d, 0x30, 0x1d, 0x3e, 0x1d, 0x62, 0x1d, 0x77, 0x1d, 0x7b, 0x1d, 0x85, - 0x1d, 0x9b, 0x1d, 0xb9, 0x1e, 0x00, 0x1e, 0x18, 0x1e, 0x30, 0x1e, 0x54, - 0x1e, 0x68, 0x1e, 0x7c, 0x1e, 0x9b, 0x1e, 0x9f, 0x1e, 0xac, 0x1e, 0xb0, - 0x1e, 0xb6, 0x1e, 0xbc, 0x1e, 0xc6, 0x1e, 0xca, 0x1e, 0xd8, 0x1e, 0xe0, - 0x1e, 0xe8, 0x1e, 0xee, 0x1e, 0xf8, 0x1f, 0x00, 0x1f, 0x18, 0x1f, 0x20, - 0x1f, 0x48, 0x1f, 0x50, 0x1f, 0x59, 0x1f, 0x5b, 0x1f, 0x5d, 0x1f, 0x5f, - 0x1f, 0x80, 0x1f, 0xb6, 0x1f, 0xc6, 0x1f, 0xd6, 0x1f, 0xdd, 0x1f, 0xf2, - 0x1f, 0xf6, 0x20, 0x00, 0x20, 0x10, 0x20, 0x26, 0x20, 0x2f, 0x20, 0x39, - 0x20, 0x3c, 0x20, 0x45, 0x20, 0x4b, 0x20, 0x5f, 0x20, 0x70, 0x20, 0x74, - 0x20, 0x90, 0x20, 0xa0, 0x20, 0xb8, 0x21, 0x02, 0x21, 0x05, 0x21, 0x0d, - 0x21, 0x15, 0x21, 0x19, 0x21, 0x1d, 0x21, 0x22, 0x21, 0x24, 0x21, 0x26, - 0x21, 0x2a, 0x21, 0x2e, 0x21, 0x48, 0x21, 0x53, 0x21, 0x90, 0x22, 0x0f, - 0x22, 0x11, 0x22, 0x15, 0x22, 0x17, 0x22, 0x27, 0x22, 0x34, 0x22, 0x41, - 0x22, 0x6d, 0x22, 0x8f, 0x22, 0x95, 0x22, 0xc5, 0x22, 0xcd, 0x22, 0xda, - 0x22, 0xef, 0x23, 0x00, 0x23, 0x08, 0x23, 0x18, 0x23, 0x1c, 0x23, 0x25, - 0x23, 0x2b, 0x23, 0x35, 0x23, 0x37, 0x23, 0x41, 0x23, 0x47, 0x23, 0x4b, - 0x23, 0x50, 0x23, 0x52, 0x23, 0x57, 0x23, 0x5e, 0x23, 0x63, 0x23, 0x68, - 0x23, 0x6b, 0x23, 0x73, 0x23, 0x7d, 0x23, 0x80, 0x23, 0x88, 0x23, 0x95, - 0x23, 0x9b, 0x23, 0xce, 0x24, 0x23, 0x25, 0x00, 0x26, 0x38, 0x26, 0x90, - 0x26, 0xa0, 0x26, 0xb0, 0x27, 0x01, 0x27, 0x06, 0x27, 0x0c, 0x27, 0x29, - 0x27, 0x4d, 0x27, 0x4f, 0x27, 0x56, 0x27, 0x58, 0x27, 0x61, 0x27, 0x94, - 0x27, 0x98, 0x27, 0xb1, 0x27, 0xc2, 0x27, 0xc5, 0x27, 0xe0, 0x27, 0xe6, - 0x29, 0xeb, 0x29, 0xfa, 0x2a, 0x2f, 0x2a, 0x6a, 0x2b, 0x05, 0x2b, 0x12, - 0x2c, 0x64, 0x2c, 0x6d, 0x2c, 0x75, 0x2c, 0x79, 0x2c, 0x7c, 0x2e, 0x18, - 0x2e, 0x1f, 0x2e, 0x22, 0x2e, 0x2e, 0xa7, 0x08, 0xa7, 0x1b, 0xa7, 0x22, - 0xa7, 0x89, 0xa7, 0x90, 0xa7, 0xaa, 0xf6, 0xc5, 0xfb, 0x01, 0xfb, 0x52, - 0xfb, 0x8a, 0xfb, 0x9e, 0xfb, 0xaa, 0xfb, 0xe8, 0xfb, 0xfc, 0xfe, 0x70, - 0xfe, 0x76, 0xfe, 0xff, 0xff, 0xf9, 0xff, 0xff, 0x00, 0x00, 0xff, 0xe3, - 0xff, 0xc2, 0xff, 0xb9, 0xff, 0xb7, 0xff, 0xb4, 0xff, 0xb3, 0xff, 0xb1, - 0xff, 0xaf, 0xff, 0xae, 0xff, 0xa8, 0xff, 0xa6, 0xff, 0xa5, 0xff, 0xa1, - 0xff, 0x9f, 0xff, 0x9d, 0xff, 0x9c, 0xff, 0x98, 0xff, 0x94, 0xff, 0x88, - 0xff, 0x85, 0xff, 0x71, 0xff, 0x69, 0xff, 0x57, 0xff, 0x53, 0xff, 0x50, - 0xff, 0x4b, 0xff, 0x4a, 0xff, 0x49, 0xff, 0x48, 0xff, 0x47, 0xff, 0x39, - 0xff, 0x37, 0xff, 0x29, 0xff, 0x0d, 0xff, 0x07, 0xff, 0x03, 0xfe, 0xfd, - 0xfe, 0xf9, 0xfe, 0xf7, 0xfe, 0xf5, 0xfe, 0xf3, 0xfe, 0xdd, 0xfe, 0xd5, - 0xfe, 0xc2, 0xfe, 0xc0, 0xfe, 0xbf, 0xfe, 0xbe, 0xfe, 0x43, 0xfe, 0x42, - 0xfe, 0x41, 0xfe, 0x39, 0xfe, 0x34, 0xfe, 0x31, 0xfe, 0x30, 0xfe, 0x2b, - 0xfe, 0x27, 0xfe, 0x22, 0xfe, 0x1c, 0xfe, 0x18, 0xfe, 0x16, 0xfe, 0x14, - 0xfe, 0x13, 0xfe, 0x0a, 0xfe, 0x04, 0xfd, 0xf9, 0xfd, 0xf5, 0xfd, 0xf0, - 0xfd, 0xe2, 0xfd, 0xd5, 0xfd, 0xb2, 0xf6, 0x2b, 0xf6, 0x2a, 0xf6, 0x28, - 0xf6, 0x27, 0xf6, 0x25, 0xf6, 0x1f, 0xf6, 0x1e, 0xf6, 0x1d, 0xf6, 0x1c, - 0xf6, 0x1b, 0xf6, 0x19, 0xf6, 0x18, 0xf6, 0x17, 0xf6, 0x0c, 0xf4, 0x0a, - 0xe8, 0x05, 0xe8, 0x00, 0xe7, 0xf6, 0xe7, 0xf5, 0xe7, 0xf0, 0xe7, 0xe4, - 0xe7, 0xe3, 0xe7, 0xe2, 0xe7, 0xdc, 0xe7, 0xcb, 0xe7, 0xc9, 0xe7, 0xc0, - 0xe7, 0xab, 0xe7, 0xaa, 0xe7, 0x6a, 0xe7, 0x66, 0xe7, 0x64, 0xe7, 0x5e, - 0xe7, 0x5a, 0xe7, 0x58, 0xe7, 0x57, 0xe7, 0x54, 0xe7, 0x4a, 0xe7, 0x48, - 0xe7, 0x44, 0xe7, 0x42, 0xe7, 0x3a, 0xe7, 0x38, 0xe7, 0x2e, 0xe7, 0x2c, - 0xe7, 0x2a, 0xe7, 0x28, 0xe7, 0x26, 0xe7, 0x20, 0xe7, 0x1e, 0xe7, 0x1c, - 0xe7, 0x1a, 0xe7, 0x18, 0xe7, 0x17, 0xe7, 0x16, 0xe7, 0x15, 0xe7, 0x14, - 0xe7, 0x12, 0xe7, 0x11, 0xe7, 0x10, 0xe7, 0x0e, 0xe7, 0x0d, 0xe7, 0x0b, - 0xe7, 0x0a, 0xe7, 0x09, 0xe7, 0x04, 0xe7, 0x02, 0xe6, 0xfa, 0xe6, 0xf9, - 0xe6, 0xf8, 0xe6, 0xf2, 0xe6, 0xf1, 0xe6, 0xde, 0xe6, 0xce, 0xe6, 0xcc, - 0xe6, 0xcb, 0xe6, 0xc8, 0xe6, 0xc6, 0xe6, 0x7e, 0xe6, 0x7c, 0xe6, 0x75, - 0xe6, 0x70, 0xe6, 0x6f, 0xe6, 0x6d, 0xe6, 0x69, 0xe6, 0x68, 0xe6, 0x67, - 0xe6, 0x64, 0xe6, 0x62, 0xe6, 0x49, 0xe6, 0x3f, 0xe6, 0x0f, 0xe6, 0x0e, - 0xe6, 0x0d, 0xe6, 0x0c, 0xe6, 0x0b, 0xe6, 0x05, 0xe5, 0xff, 0xe5, 0xfc, - 0xe5, 0xf9, 0xe5, 0xf6, 0xe5, 0xf4, 0xe5, 0xd5, 0xe5, 0xcf, 0xe5, 0xc3, - 0xe5, 0xbe, 0xe5, 0xae, 0xe5, 0xad, 0xe5, 0xab, 0xe5, 0xa9, 0xe5, 0xa6, - 0xe5, 0xa4, 0xe5, 0x9b, 0xe5, 0x9a, 0xe5, 0x98, 0xe5, 0x96, 0xe5, 0x95, - 0xe5, 0x93, 0xe5, 0x92, 0xe5, 0x90, 0xe5, 0x8f, 0xe5, 0x8d, 0xe5, 0x8b, - 0xe5, 0x8a, 0xe5, 0x88, 0xe5, 0x86, 0xe5, 0x84, 0xe5, 0x80, 0xe5, 0x77, - 0xe5, 0x72, 0xe5, 0x53, 0xe5, 0x00, 0xe4, 0x24, 0xe4, 0x1c, 0xe4, 0x18, - 0xe4, 0x15, 0xe4, 0x07, 0xe3, 0xb8, 0xe3, 0xb7, 0xe3, 0xb5, 0xe3, 0xb4, - 0xe3, 0xb3, 0xe3, 0xb2, 0xe3, 0xaf, 0xe3, 0xae, 0xe3, 0xac, 0xe3, 0x8e, - 0xe3, 0x8b, 0xe3, 0x8a, 0xe3, 0x87, 0xe3, 0x85, 0xe3, 0x6c, 0xe3, 0x67, - 0xe1, 0x66, 0xe1, 0x58, 0xe1, 0x25, 0xe0, 0xeb, 0xe0, 0x52, 0xe0, 0x4e, - 0xdf, 0x05, 0xde, 0xfd, 0xde, 0xf9, 0xde, 0xf8, 0xde, 0xf7, 0xdd, 0x5f, - 0xdd, 0x59, 0xdd, 0x57, 0xdd, 0x4f, 0x64, 0x76, 0x64, 0x72, 0x64, 0x70, - 0x64, 0x0f, 0x64, 0x0e, 0x63, 0xf6, 0x14, 0xdc, 0x10, 0xa1, 0x10, 0x52, - 0x10, 0x4a, 0x10, 0x42, 0x10, 0x38, 0x0f, 0xfe, 0x0f, 0xec, 0x0d, 0x7c, - 0x0d, 0x7b, 0x0d, 0x79, 0x0c, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, - 0x00, 0x00, 0x0c, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, - 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x01, 0xc3, 0x00, 0x00, 0x00, 0x62, - 0x00, 0x00, 0x01, 0xcd, 0x00, 0x00, 0x01, 0xe3, 0x00, 0x00, 0x01, 0x86, - 0x00, 0x00, 0x01, 0xe6, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x01, 0x9d, - 0x00, 0x00, 0x01, 0xf4, 0x00, 0x00, 0x01, 0xf6, 0x00, 0x00, 0x01, 0xa8, - 0x00, 0x00, 0x01, 0xf8, 0x00, 0x00, 0x01, 0xf9, 0x00, 0x00, 0x01, 0xab, - 0x00, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x02, 0x21, 0x00, 0x00, 0x01, 0xad, - 0x00, 0x00, 0x02, 0x24, 0x00, 0x00, 0x02, 0x41, 0x00, 0x00, 0x01, 0xd3, - 0x00, 0x00, 0x02, 0x43, 0x00, 0x00, 0x02, 0x45, 0x00, 0x00, 0x01, 0xf1, - 0x00, 0x00, 0x02, 0x4c, 0x00, 0x00, 0x02, 0x4d, 0x00, 0x00, 0x01, 0xf4, - 0x00, 0x00, 0x02, 0x50, 0x00, 0x00, 0x02, 0xb9, 0x00, 0x00, 0x01, 0xf6, - 0x00, 0x00, 0x02, 0xbb, 0x00, 0x00, 0x02, 0xc1, 0x00, 0x00, 0x02, 0x60, - 0x00, 0x00, 0x02, 0xc6, 0x00, 0x00, 0x02, 0xc9, 0x00, 0x00, 0x02, 0x67, - 0x00, 0x00, 0x02, 0xcc, 0x00, 0x00, 0x02, 0xd3, 0x00, 0x00, 0x02, 0x6b, - 0x00, 0x00, 0x02, 0xd6, 0x00, 0x00, 0x02, 0xde, 0x00, 0x00, 0x02, 0x73, - 0x00, 0x00, 0x02, 0xe0, 0x00, 0x00, 0x02, 0xe9, 0x00, 0x00, 0x02, 0x7c, - 0x00, 0x00, 0x02, 0xee, 0x00, 0x00, 0x02, 0xee, 0x00, 0x00, 0x02, 0x86, - 0x00, 0x00, 0x02, 0xf3, 0x00, 0x00, 0x02, 0xf3, 0x00, 0x00, 0x02, 0x87, - 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x3f, 0x00, 0x00, 0x02, 0x88, - 0x00, 0x00, 0x03, 0x43, 0x00, 0x00, 0x03, 0x43, 0x00, 0x00, 0x02, 0xc8, - 0x00, 0x00, 0x03, 0x58, 0x00, 0x00, 0x03, 0x58, 0x00, 0x00, 0x02, 0xc9, - 0x00, 0x00, 0x03, 0x61, 0x00, 0x00, 0x03, 0x61, 0x00, 0x00, 0x02, 0xca, - 0x00, 0x00, 0x03, 0x74, 0x00, 0x00, 0x03, 0x75, 0x00, 0x00, 0x02, 0xcb, - 0x00, 0x00, 0x03, 0x7a, 0x00, 0x00, 0x03, 0x7a, 0x00, 0x00, 0x02, 0xcd, - 0x00, 0x00, 0x03, 0x7e, 0x00, 0x00, 0x03, 0x7e, 0x00, 0x00, 0x02, 0xce, - 0x00, 0x00, 0x03, 0x84, 0x00, 0x00, 0x03, 0x8a, 0x00, 0x00, 0x02, 0xcf, - 0x00, 0x00, 0x03, 0x8c, 0x00, 0x00, 0x03, 0x8c, 0x00, 0x00, 0x02, 0xd6, - 0x00, 0x00, 0x03, 0x8e, 0x00, 0x00, 0x03, 0xa1, 0x00, 0x00, 0x02, 0xd7, - 0x00, 0x00, 0x03, 0xa3, 0x00, 0x00, 0x03, 0xce, 0x00, 0x00, 0x02, 0xeb, - 0x00, 0x00, 0x03, 0xd0, 0x00, 0x00, 0x03, 0xe1, 0x00, 0x00, 0x03, 0x17, - 0x00, 0x00, 0x03, 0xf0, 0x00, 0x00, 0x04, 0x5f, 0x00, 0x00, 0x03, 0x29, - 0x00, 0x00, 0x04, 0x62, 0x00, 0x00, 0x04, 0x63, 0x00, 0x00, 0x03, 0x99, - 0x00, 0x00, 0x04, 0x72, 0x00, 0x00, 0x04, 0x73, 0x00, 0x00, 0x03, 0x9b, - 0x00, 0x00, 0x04, 0x90, 0x00, 0x00, 0x04, 0x9b, 0x00, 0x00, 0x03, 0x9d, - 0x00, 0x00, 0x04, 0xa2, 0x00, 0x00, 0x04, 0xa5, 0x00, 0x00, 0x03, 0xa9, - 0x00, 0x00, 0x04, 0xaa, 0x00, 0x00, 0x04, 0xb3, 0x00, 0x00, 0x03, 0xad, - 0x00, 0x00, 0x04, 0xba, 0x00, 0x00, 0x04, 0xbb, 0x00, 0x00, 0x03, 0xb7, - 0x00, 0x00, 0x04, 0xc0, 0x00, 0x00, 0x04, 0xc4, 0x00, 0x00, 0x03, 0xb9, - 0x00, 0x00, 0x04, 0xc7, 0x00, 0x00, 0x04, 0xc8, 0x00, 0x00, 0x03, 0xbe, - 0x00, 0x00, 0x04, 0xcb, 0x00, 0x00, 0x04, 0xcc, 0x00, 0x00, 0x03, 0xc0, - 0x00, 0x00, 0x04, 0xcf, 0x00, 0x00, 0x04, 0xf9, 0x00, 0x00, 0x03, 0xc2, - 0x00, 0x00, 0x05, 0x10, 0x00, 0x00, 0x05, 0x11, 0x00, 0x00, 0x03, 0xed, - 0x00, 0x00, 0x05, 0x1a, 0x00, 0x00, 0x05, 0x1d, 0x00, 0x00, 0x03, 0xef, - 0x00, 0x00, 0x05, 0x31, 0x00, 0x00, 0x05, 0x56, 0x00, 0x00, 0x03, 0xf3, - 0x00, 0x00, 0x05, 0x59, 0x00, 0x00, 0x05, 0x5f, 0x00, 0x00, 0x04, 0x19, - 0x00, 0x00, 0x05, 0x61, 0x00, 0x00, 0x05, 0x87, 0x00, 0x00, 0x04, 0x20, - 0x00, 0x00, 0x05, 0x89, 0x00, 0x00, 0x05, 0x8a, 0x00, 0x00, 0x04, 0x47, - 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x06, 0x07, 0x00, 0x00, 0x04, 0x49, - 0x00, 0x00, 0x06, 0x09, 0x00, 0x00, 0x06, 0x0a, 0x00, 0x00, 0x04, 0x4b, - 0x00, 0x00, 0x06, 0x0c, 0x00, 0x00, 0x06, 0x0c, 0x00, 0x00, 0x04, 0x4d, - 0x00, 0x00, 0x06, 0x15, 0x00, 0x00, 0x06, 0x15, 0x00, 0x00, 0x04, 0x4e, - 0x00, 0x00, 0x06, 0x1b, 0x00, 0x00, 0x06, 0x1b, 0x00, 0x00, 0x04, 0x4f, - 0x00, 0x00, 0x06, 0x1f, 0x00, 0x00, 0x06, 0x1f, 0x00, 0x00, 0x04, 0x50, - 0x00, 0x00, 0x06, 0x21, 0x00, 0x00, 0x06, 0x3a, 0x00, 0x00, 0x04, 0x51, - 0x00, 0x00, 0x06, 0x40, 0x00, 0x00, 0x06, 0x55, 0x00, 0x00, 0x04, 0x6b, - 0x00, 0x00, 0x06, 0x5a, 0x00, 0x00, 0x06, 0x5a, 0x00, 0x00, 0x04, 0x81, - 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x06, 0x6d, 0x00, 0x00, 0x04, 0x82, - 0x00, 0x00, 0x06, 0x74, 0x00, 0x00, 0x06, 0x74, 0x00, 0x00, 0x04, 0x90, - 0x00, 0x00, 0x06, 0x79, 0x00, 0x00, 0x06, 0x7b, 0x00, 0x00, 0x04, 0x91, - 0x00, 0x00, 0x06, 0x7e, 0x00, 0x00, 0x06, 0x80, 0x00, 0x00, 0x04, 0x94, - 0x00, 0x00, 0x06, 0x83, 0x00, 0x00, 0x06, 0x84, 0x00, 0x00, 0x04, 0x97, - 0x00, 0x00, 0x06, 0x86, 0x00, 0x00, 0x06, 0x87, 0x00, 0x00, 0x04, 0x99, - 0x00, 0x00, 0x06, 0x91, 0x00, 0x00, 0x06, 0x91, 0x00, 0x00, 0x04, 0x9b, - 0x00, 0x00, 0x06, 0x98, 0x00, 0x00, 0x06, 0x98, 0x00, 0x00, 0x04, 0x9c, - 0x00, 0x00, 0x06, 0xa4, 0x00, 0x00, 0x06, 0xa4, 0x00, 0x00, 0x04, 0x9d, - 0x00, 0x00, 0x06, 0xa9, 0x00, 0x00, 0x06, 0xa9, 0x00, 0x00, 0x04, 0x9e, - 0x00, 0x00, 0x06, 0xaf, 0x00, 0x00, 0x06, 0xaf, 0x00, 0x00, 0x04, 0x9f, - 0x00, 0x00, 0x06, 0xbe, 0x00, 0x00, 0x06, 0xbe, 0x00, 0x00, 0x04, 0xa0, - 0x00, 0x00, 0x06, 0xcc, 0x00, 0x00, 0x06, 0xcc, 0x00, 0x00, 0x04, 0xa1, - 0x00, 0x00, 0x06, 0xf0, 0x00, 0x00, 0x06, 0xf9, 0x00, 0x00, 0x04, 0xa2, - 0x00, 0x00, 0x0e, 0x81, 0x00, 0x00, 0x0e, 0x82, 0x00, 0x00, 0x04, 0xac, - 0x00, 0x00, 0x0e, 0x84, 0x00, 0x00, 0x0e, 0x84, 0x00, 0x00, 0x04, 0xae, - 0x00, 0x00, 0x0e, 0x87, 0x00, 0x00, 0x0e, 0x88, 0x00, 0x00, 0x04, 0xaf, - 0x00, 0x00, 0x0e, 0x8a, 0x00, 0x00, 0x0e, 0x8a, 0x00, 0x00, 0x04, 0xb1, - 0x00, 0x00, 0x0e, 0x8d, 0x00, 0x00, 0x0e, 0x8d, 0x00, 0x00, 0x04, 0xb2, - 0x00, 0x00, 0x0e, 0x94, 0x00, 0x00, 0x0e, 0x97, 0x00, 0x00, 0x04, 0xb3, - 0x00, 0x00, 0x0e, 0x99, 0x00, 0x00, 0x0e, 0x9f, 0x00, 0x00, 0x04, 0xb7, - 0x00, 0x00, 0x0e, 0xa1, 0x00, 0x00, 0x0e, 0xa3, 0x00, 0x00, 0x04, 0xbe, - 0x00, 0x00, 0x0e, 0xa5, 0x00, 0x00, 0x0e, 0xa5, 0x00, 0x00, 0x04, 0xc1, - 0x00, 0x00, 0x0e, 0xa7, 0x00, 0x00, 0x0e, 0xa7, 0x00, 0x00, 0x04, 0xc2, - 0x00, 0x00, 0x0e, 0xaa, 0x00, 0x00, 0x0e, 0xab, 0x00, 0x00, 0x04, 0xc3, - 0x00, 0x00, 0x0e, 0xad, 0x00, 0x00, 0x0e, 0xb9, 0x00, 0x00, 0x04, 0xc5, - 0x00, 0x00, 0x0e, 0xbb, 0x00, 0x00, 0x0e, 0xbc, 0x00, 0x00, 0x04, 0xd2, - 0x00, 0x00, 0x0e, 0xc8, 0x00, 0x00, 0x0e, 0xcd, 0x00, 0x00, 0x04, 0xd4, - 0x00, 0x00, 0x10, 0xd0, 0x00, 0x00, 0x10, 0xfc, 0x00, 0x00, 0x04, 0xda, - 0x00, 0x00, 0x1d, 0x02, 0x00, 0x00, 0x1d, 0x02, 0x00, 0x00, 0x05, 0x07, - 0x00, 0x00, 0x1d, 0x08, 0x00, 0x00, 0x1d, 0x09, 0x00, 0x00, 0x05, 0x08, - 0x00, 0x00, 0x1d, 0x14, 0x00, 0x00, 0x1d, 0x14, 0x00, 0x00, 0x05, 0x0a, - 0x00, 0x00, 0x1d, 0x16, 0x00, 0x00, 0x1d, 0x17, 0x00, 0x00, 0x05, 0x0b, - 0x00, 0x00, 0x1d, 0x1d, 0x00, 0x00, 0x1d, 0x1f, 0x00, 0x00, 0x05, 0x0d, - 0x00, 0x00, 0x1d, 0x2c, 0x00, 0x00, 0x1d, 0x2e, 0x00, 0x00, 0x05, 0x10, - 0x00, 0x00, 0x1d, 0x30, 0x00, 0x00, 0x1d, 0x3c, 0x00, 0x00, 0x05, 0x13, - 0x00, 0x00, 0x1d, 0x3e, 0x00, 0x00, 0x1d, 0x5b, 0x00, 0x00, 0x05, 0x20, - 0x00, 0x00, 0x1d, 0x62, 0x00, 0x00, 0x1d, 0x65, 0x00, 0x00, 0x05, 0x3e, - 0x00, 0x00, 0x1d, 0x77, 0x00, 0x00, 0x1d, 0x78, 0x00, 0x00, 0x05, 0x42, - 0x00, 0x00, 0x1d, 0x7b, 0x00, 0x00, 0x1d, 0x7b, 0x00, 0x00, 0x05, 0x44, - 0x00, 0x00, 0x1d, 0x85, 0x00, 0x00, 0x1d, 0x85, 0x00, 0x00, 0x05, 0x45, - 0x00, 0x00, 0x1d, 0x9b, 0x00, 0x00, 0x1d, 0xb7, 0x00, 0x00, 0x05, 0x46, - 0x00, 0x00, 0x1d, 0xb9, 0x00, 0x00, 0x1d, 0xbf, 0x00, 0x00, 0x05, 0x63, - 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1e, 0x13, 0x00, 0x00, 0x05, 0x6a, - 0x00, 0x00, 0x1e, 0x18, 0x00, 0x00, 0x1e, 0x2d, 0x00, 0x00, 0x05, 0x7e, - 0x00, 0x00, 0x1e, 0x30, 0x00, 0x00, 0x1e, 0x4d, 0x00, 0x00, 0x05, 0x94, - 0x00, 0x00, 0x1e, 0x54, 0x00, 0x00, 0x1e, 0x63, 0x00, 0x00, 0x05, 0xb2, - 0x00, 0x00, 0x1e, 0x68, 0x00, 0x00, 0x1e, 0x79, 0x00, 0x00, 0x05, 0xc2, - 0x00, 0x00, 0x1e, 0x7c, 0x00, 0x00, 0x1e, 0x99, 0x00, 0x00, 0x05, 0xd4, - 0x00, 0x00, 0x1e, 0x9b, 0x00, 0x00, 0x1e, 0x9b, 0x00, 0x00, 0x05, 0xf2, - 0x00, 0x00, 0x1e, 0x9f, 0x00, 0x00, 0x1e, 0xa1, 0x00, 0x00, 0x05, 0xf3, - 0x00, 0x00, 0x1e, 0xac, 0x00, 0x00, 0x1e, 0xad, 0x00, 0x00, 0x05, 0xf6, - 0x00, 0x00, 0x1e, 0xb0, 0x00, 0x00, 0x1e, 0xb1, 0x00, 0x00, 0x05, 0xf8, - 0x00, 0x00, 0x1e, 0xb6, 0x00, 0x00, 0x1e, 0xb9, 0x00, 0x00, 0x05, 0xfa, - 0x00, 0x00, 0x1e, 0xbc, 0x00, 0x00, 0x1e, 0xbd, 0x00, 0x00, 0x05, 0xfe, - 0x00, 0x00, 0x1e, 0xc6, 0x00, 0x00, 0x1e, 0xc7, 0x00, 0x00, 0x06, 0x00, - 0x00, 0x00, 0x1e, 0xca, 0x00, 0x00, 0x1e, 0xcd, 0x00, 0x00, 0x06, 0x02, - 0x00, 0x00, 0x1e, 0xd8, 0x00, 0x00, 0x1e, 0xdd, 0x00, 0x00, 0x06, 0x06, - 0x00, 0x00, 0x1e, 0xe0, 0x00, 0x00, 0x1e, 0xe5, 0x00, 0x00, 0x06, 0x0c, - 0x00, 0x00, 0x1e, 0xe8, 0x00, 0x00, 0x1e, 0xeb, 0x00, 0x00, 0x06, 0x12, - 0x00, 0x00, 0x1e, 0xee, 0x00, 0x00, 0x1e, 0xf5, 0x00, 0x00, 0x06, 0x16, - 0x00, 0x00, 0x1e, 0xf8, 0x00, 0x00, 0x1e, 0xf9, 0x00, 0x00, 0x06, 0x1e, - 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x1f, 0x15, 0x00, 0x00, 0x06, 0x20, - 0x00, 0x00, 0x1f, 0x18, 0x00, 0x00, 0x1f, 0x1d, 0x00, 0x00, 0x06, 0x36, - 0x00, 0x00, 0x1f, 0x20, 0x00, 0x00, 0x1f, 0x45, 0x00, 0x00, 0x06, 0x3c, - 0x00, 0x00, 0x1f, 0x48, 0x00, 0x00, 0x1f, 0x4d, 0x00, 0x00, 0x06, 0x62, - 0x00, 0x00, 0x1f, 0x50, 0x00, 0x00, 0x1f, 0x57, 0x00, 0x00, 0x06, 0x68, - 0x00, 0x00, 0x1f, 0x59, 0x00, 0x00, 0x1f, 0x59, 0x00, 0x00, 0x06, 0x70, - 0x00, 0x00, 0x1f, 0x5b, 0x00, 0x00, 0x1f, 0x5b, 0x00, 0x00, 0x06, 0x71, - 0x00, 0x00, 0x1f, 0x5d, 0x00, 0x00, 0x1f, 0x5d, 0x00, 0x00, 0x06, 0x72, - 0x00, 0x00, 0x1f, 0x5f, 0x00, 0x00, 0x1f, 0x7d, 0x00, 0x00, 0x06, 0x73, - 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x1f, 0xb4, 0x00, 0x00, 0x06, 0x92, - 0x00, 0x00, 0x1f, 0xb6, 0x00, 0x00, 0x1f, 0xc4, 0x00, 0x00, 0x06, 0xc7, - 0x00, 0x00, 0x1f, 0xc6, 0x00, 0x00, 0x1f, 0xd3, 0x00, 0x00, 0x06, 0xd6, - 0x00, 0x00, 0x1f, 0xd6, 0x00, 0x00, 0x1f, 0xdb, 0x00, 0x00, 0x06, 0xe4, - 0x00, 0x00, 0x1f, 0xdd, 0x00, 0x00, 0x1f, 0xef, 0x00, 0x00, 0x06, 0xea, - 0x00, 0x00, 0x1f, 0xf2, 0x00, 0x00, 0x1f, 0xf4, 0x00, 0x00, 0x06, 0xfd, - 0x00, 0x00, 0x1f, 0xf6, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0x07, 0x00, - 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x0a, 0x00, 0x00, 0x07, 0x09, - 0x00, 0x00, 0x20, 0x10, 0x00, 0x00, 0x20, 0x23, 0x00, 0x00, 0x07, 0x14, - 0x00, 0x00, 0x20, 0x26, 0x00, 0x00, 0x20, 0x26, 0x00, 0x00, 0x07, 0x28, - 0x00, 0x00, 0x20, 0x2f, 0x00, 0x00, 0x20, 0x37, 0x00, 0x00, 0x07, 0x29, - 0x00, 0x00, 0x20, 0x39, 0x00, 0x00, 0x20, 0x3a, 0x00, 0x00, 0x07, 0x32, - 0x00, 0x00, 0x20, 0x3c, 0x00, 0x00, 0x20, 0x3e, 0x00, 0x00, 0x07, 0x34, - 0x00, 0x00, 0x20, 0x45, 0x00, 0x00, 0x20, 0x49, 0x00, 0x00, 0x07, 0x37, - 0x00, 0x00, 0x20, 0x4b, 0x00, 0x00, 0x20, 0x4b, 0x00, 0x00, 0x07, 0x3c, - 0x00, 0x00, 0x20, 0x5f, 0x00, 0x00, 0x20, 0x5f, 0x00, 0x00, 0x07, 0x3d, - 0x00, 0x00, 0x20, 0x70, 0x00, 0x00, 0x20, 0x71, 0x00, 0x00, 0x07, 0x3e, - 0x00, 0x00, 0x20, 0x74, 0x00, 0x00, 0x20, 0x8e, 0x00, 0x00, 0x07, 0x40, - 0x00, 0x00, 0x20, 0x90, 0x00, 0x00, 0x20, 0x9c, 0x00, 0x00, 0x07, 0x5b, - 0x00, 0x00, 0x20, 0xa0, 0x00, 0x00, 0x20, 0xb5, 0x00, 0x00, 0x07, 0x68, - 0x00, 0x00, 0x20, 0xb8, 0x00, 0x00, 0x20, 0xb9, 0x00, 0x00, 0x07, 0x7e, - 0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x07, 0x80, - 0x00, 0x00, 0x21, 0x05, 0x00, 0x00, 0x21, 0x05, 0x00, 0x00, 0x07, 0x81, - 0x00, 0x00, 0x21, 0x0d, 0x00, 0x00, 0x21, 0x0f, 0x00, 0x00, 0x07, 0x82, - 0x00, 0x00, 0x21, 0x15, 0x00, 0x00, 0x21, 0x17, 0x00, 0x00, 0x07, 0x85, - 0x00, 0x00, 0x21, 0x19, 0x00, 0x00, 0x21, 0x1a, 0x00, 0x00, 0x07, 0x88, - 0x00, 0x00, 0x21, 0x1d, 0x00, 0x00, 0x21, 0x1d, 0x00, 0x00, 0x07, 0x8a, - 0x00, 0x00, 0x21, 0x22, 0x00, 0x00, 0x21, 0x22, 0x00, 0x00, 0x07, 0x8b, - 0x00, 0x00, 0x21, 0x24, 0x00, 0x00, 0x21, 0x24, 0x00, 0x00, 0x07, 0x8c, - 0x00, 0x00, 0x21, 0x26, 0x00, 0x00, 0x21, 0x26, 0x00, 0x00, 0x07, 0x8d, - 0x00, 0x00, 0x21, 0x2a, 0x00, 0x00, 0x21, 0x2b, 0x00, 0x00, 0x07, 0x8e, - 0x00, 0x00, 0x21, 0x2e, 0x00, 0x00, 0x21, 0x2e, 0x00, 0x00, 0x07, 0x90, - 0x00, 0x00, 0x21, 0x48, 0x00, 0x00, 0x21, 0x48, 0x00, 0x00, 0x07, 0x91, - 0x00, 0x00, 0x21, 0x53, 0x00, 0x00, 0x21, 0x5f, 0x00, 0x00, 0x07, 0x92, - 0x00, 0x00, 0x21, 0x90, 0x00, 0x00, 0x22, 0x0d, 0x00, 0x00, 0x07, 0x9f, - 0x00, 0x00, 0x22, 0x0f, 0x00, 0x00, 0x22, 0x0f, 0x00, 0x00, 0x08, 0x1d, - 0x00, 0x00, 0x22, 0x11, 0x00, 0x00, 0x22, 0x13, 0x00, 0x00, 0x08, 0x1e, - 0x00, 0x00, 0x22, 0x15, 0x00, 0x00, 0x22, 0x15, 0x00, 0x00, 0x08, 0x21, - 0x00, 0x00, 0x22, 0x17, 0x00, 0x00, 0x22, 0x20, 0x00, 0x00, 0x08, 0x22, - 0x00, 0x00, 0x22, 0x27, 0x00, 0x00, 0x22, 0x2d, 0x00, 0x00, 0x08, 0x2c, - 0x00, 0x00, 0x22, 0x34, 0x00, 0x00, 0x22, 0x3d, 0x00, 0x00, 0x08, 0x33, - 0x00, 0x00, 0x22, 0x41, 0x00, 0x00, 0x22, 0x69, 0x00, 0x00, 0x08, 0x3d, - 0x00, 0x00, 0x22, 0x6d, 0x00, 0x00, 0x22, 0x8b, 0x00, 0x00, 0x08, 0x66, - 0x00, 0x00, 0x22, 0x8f, 0x00, 0x00, 0x22, 0x92, 0x00, 0x00, 0x08, 0x85, - 0x00, 0x00, 0x22, 0x95, 0x00, 0x00, 0x22, 0xa5, 0x00, 0x00, 0x08, 0x89, - 0x00, 0x00, 0x22, 0xc5, 0x00, 0x00, 0x22, 0xc6, 0x00, 0x00, 0x08, 0x9a, - 0x00, 0x00, 0x22, 0xcd, 0x00, 0x00, 0x22, 0xcd, 0x00, 0x00, 0x08, 0x9c, - 0x00, 0x00, 0x22, 0xda, 0x00, 0x00, 0x22, 0xe9, 0x00, 0x00, 0x08, 0x9d, - 0x00, 0x00, 0x22, 0xef, 0x00, 0x00, 0x22, 0xef, 0x00, 0x00, 0x08, 0xad, - 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x23, 0x06, 0x00, 0x00, 0x08, 0xae, - 0x00, 0x00, 0x23, 0x08, 0x00, 0x00, 0x23, 0x15, 0x00, 0x00, 0x08, 0xb5, - 0x00, 0x00, 0x23, 0x18, 0x00, 0x00, 0x23, 0x19, 0x00, 0x00, 0x08, 0xc3, - 0x00, 0x00, 0x23, 0x1c, 0x00, 0x00, 0x23, 0x21, 0x00, 0x00, 0x08, 0xc5, - 0x00, 0x00, 0x23, 0x25, 0x00, 0x00, 0x23, 0x28, 0x00, 0x00, 0x08, 0xcb, - 0x00, 0x00, 0x23, 0x2b, 0x00, 0x00, 0x23, 0x2b, 0x00, 0x00, 0x08, 0xcf, - 0x00, 0x00, 0x23, 0x35, 0x00, 0x00, 0x23, 0x35, 0x00, 0x00, 0x08, 0xd0, - 0x00, 0x00, 0x23, 0x37, 0x00, 0x00, 0x23, 0x3e, 0x00, 0x00, 0x08, 0xd1, - 0x00, 0x00, 0x23, 0x41, 0x00, 0x00, 0x23, 0x44, 0x00, 0x00, 0x08, 0xd9, - 0x00, 0x00, 0x23, 0x47, 0x00, 0x00, 0x23, 0x49, 0x00, 0x00, 0x08, 0xdd, - 0x00, 0x00, 0x23, 0x4b, 0x00, 0x00, 0x23, 0x4d, 0x00, 0x00, 0x08, 0xe0, - 0x00, 0x00, 0x23, 0x50, 0x00, 0x00, 0x23, 0x50, 0x00, 0x00, 0x08, 0xe3, - 0x00, 0x00, 0x23, 0x52, 0x00, 0x00, 0x23, 0x54, 0x00, 0x00, 0x08, 0xe4, - 0x00, 0x00, 0x23, 0x57, 0x00, 0x00, 0x23, 0x5c, 0x00, 0x00, 0x08, 0xe7, - 0x00, 0x00, 0x23, 0x5e, 0x00, 0x00, 0x23, 0x60, 0x00, 0x00, 0x08, 0xed, - 0x00, 0x00, 0x23, 0x63, 0x00, 0x00, 0x23, 0x65, 0x00, 0x00, 0x08, 0xf0, - 0x00, 0x00, 0x23, 0x68, 0x00, 0x00, 0x23, 0x69, 0x00, 0x00, 0x08, 0xf3, - 0x00, 0x00, 0x23, 0x6b, 0x00, 0x00, 0x23, 0x70, 0x00, 0x00, 0x08, 0xf5, - 0x00, 0x00, 0x23, 0x73, 0x00, 0x00, 0x23, 0x7a, 0x00, 0x00, 0x08, 0xfb, - 0x00, 0x00, 0x23, 0x7d, 0x00, 0x00, 0x23, 0x7d, 0x00, 0x00, 0x09, 0x03, - 0x00, 0x00, 0x23, 0x80, 0x00, 0x00, 0x23, 0x83, 0x00, 0x00, 0x09, 0x04, - 0x00, 0x00, 0x23, 0x88, 0x00, 0x00, 0x23, 0x8b, 0x00, 0x00, 0x09, 0x08, - 0x00, 0x00, 0x23, 0x95, 0x00, 0x00, 0x23, 0x95, 0x00, 0x00, 0x09, 0x0c, - 0x00, 0x00, 0x23, 0x9b, 0x00, 0x00, 0x23, 0xae, 0x00, 0x00, 0x09, 0x0d, - 0x00, 0x00, 0x23, 0xce, 0x00, 0x00, 0x23, 0xcf, 0x00, 0x00, 0x09, 0x21, - 0x00, 0x00, 0x24, 0x23, 0x00, 0x00, 0x24, 0x23, 0x00, 0x00, 0x09, 0x23, - 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x2f, 0x00, 0x00, 0x09, 0x24, - 0x00, 0x00, 0x26, 0x38, 0x00, 0x00, 0x26, 0x8b, 0x00, 0x00, 0x0a, 0x54, - 0x00, 0x00, 0x26, 0x90, 0x00, 0x00, 0x26, 0x9c, 0x00, 0x00, 0x0a, 0xa8, - 0x00, 0x00, 0x26, 0xa0, 0x00, 0x00, 0x26, 0xa1, 0x00, 0x00, 0x0a, 0xb5, - 0x00, 0x00, 0x26, 0xb0, 0x00, 0x00, 0x26, 0xb1, 0x00, 0x00, 0x0a, 0xb7, - 0x00, 0x00, 0x27, 0x01, 0x00, 0x00, 0x27, 0x04, 0x00, 0x00, 0x0a, 0xb9, - 0x00, 0x00, 0x27, 0x06, 0x00, 0x00, 0x27, 0x09, 0x00, 0x00, 0x0a, 0xbd, - 0x00, 0x00, 0x27, 0x0c, 0x00, 0x00, 0x27, 0x27, 0x00, 0x00, 0x0a, 0xc1, - 0x00, 0x00, 0x27, 0x29, 0x00, 0x00, 0x27, 0x4b, 0x00, 0x00, 0x0a, 0xdd, - 0x00, 0x00, 0x27, 0x4d, 0x00, 0x00, 0x27, 0x4d, 0x00, 0x00, 0x0b, 0x00, - 0x00, 0x00, 0x27, 0x4f, 0x00, 0x00, 0x27, 0x52, 0x00, 0x00, 0x0b, 0x01, - 0x00, 0x00, 0x27, 0x56, 0x00, 0x00, 0x27, 0x56, 0x00, 0x00, 0x0b, 0x05, - 0x00, 0x00, 0x27, 0x58, 0x00, 0x00, 0x27, 0x5e, 0x00, 0x00, 0x0b, 0x06, - 0x00, 0x00, 0x27, 0x61, 0x00, 0x00, 0x27, 0x75, 0x00, 0x00, 0x0b, 0x0d, - 0x00, 0x00, 0x27, 0x94, 0x00, 0x00, 0x27, 0x94, 0x00, 0x00, 0x0b, 0x22, - 0x00, 0x00, 0x27, 0x98, 0x00, 0x00, 0x27, 0xaf, 0x00, 0x00, 0x0b, 0x23, - 0x00, 0x00, 0x27, 0xb1, 0x00, 0x00, 0x27, 0xbe, 0x00, 0x00, 0x0b, 0x3b, - 0x00, 0x00, 0x27, 0xc2, 0x00, 0x00, 0x27, 0xc2, 0x00, 0x00, 0x0b, 0x49, - 0x00, 0x00, 0x27, 0xc5, 0x00, 0x00, 0x27, 0xc6, 0x00, 0x00, 0x0b, 0x4a, - 0x00, 0x00, 0x27, 0xe0, 0x00, 0x00, 0x27, 0xe0, 0x00, 0x00, 0x0b, 0x4c, - 0x00, 0x00, 0x27, 0xe6, 0x00, 0x00, 0x27, 0xe9, 0x00, 0x00, 0x0b, 0x4d, - 0x00, 0x00, 0x29, 0xeb, 0x00, 0x00, 0x29, 0xeb, 0x00, 0x00, 0x0b, 0x51, - 0x00, 0x00, 0x29, 0xfa, 0x00, 0x00, 0x29, 0xfb, 0x00, 0x00, 0x0b, 0x52, - 0x00, 0x00, 0x2a, 0x2f, 0x00, 0x00, 0x2a, 0x2f, 0x00, 0x00, 0x0b, 0x54, - 0x00, 0x00, 0x2a, 0x6a, 0x00, 0x00, 0x2a, 0x6b, 0x00, 0x00, 0x0b, 0x55, - 0x00, 0x00, 0x2b, 0x05, 0x00, 0x00, 0x2b, 0x0d, 0x00, 0x00, 0x0b, 0x57, - 0x00, 0x00, 0x2b, 0x12, 0x00, 0x00, 0x2b, 0x1a, 0x00, 0x00, 0x0b, 0x60, - 0x00, 0x00, 0x2c, 0x64, 0x00, 0x00, 0x2c, 0x64, 0x00, 0x00, 0x0b, 0x69, - 0x00, 0x00, 0x2c, 0x6d, 0x00, 0x00, 0x2c, 0x70, 0x00, 0x00, 0x0b, 0x6a, - 0x00, 0x00, 0x2c, 0x75, 0x00, 0x00, 0x2c, 0x77, 0x00, 0x00, 0x0b, 0x6e, - 0x00, 0x00, 0x2c, 0x79, 0x00, 0x00, 0x2c, 0x7a, 0x00, 0x00, 0x0b, 0x71, - 0x00, 0x00, 0x2c, 0x7c, 0x00, 0x00, 0x2c, 0x7f, 0x00, 0x00, 0x0b, 0x73, - 0x00, 0x00, 0x2e, 0x18, 0x00, 0x00, 0x2e, 0x18, 0x00, 0x00, 0x0b, 0x77, - 0x00, 0x00, 0x2e, 0x1f, 0x00, 0x00, 0x2e, 0x1f, 0x00, 0x00, 0x0b, 0x78, - 0x00, 0x00, 0x2e, 0x22, 0x00, 0x00, 0x2e, 0x25, 0x00, 0x00, 0x0b, 0x79, - 0x00, 0x00, 0x2e, 0x2e, 0x00, 0x00, 0x2e, 0x2e, 0x00, 0x00, 0x0b, 0x7d, - 0x00, 0x00, 0xa7, 0x08, 0x00, 0x00, 0xa7, 0x16, 0x00, 0x00, 0x0b, 0x7e, - 0x00, 0x00, 0xa7, 0x1b, 0x00, 0x00, 0xa7, 0x1f, 0x00, 0x00, 0x0b, 0x8d, - 0x00, 0x00, 0xa7, 0x22, 0x00, 0x00, 0xa7, 0x27, 0x00, 0x00, 0x0b, 0x92, - 0x00, 0x00, 0xa7, 0x89, 0x00, 0x00, 0xa7, 0x8e, 0x00, 0x00, 0x0b, 0x98, - 0x00, 0x00, 0xa7, 0x90, 0x00, 0x00, 0xa7, 0x91, 0x00, 0x00, 0x0b, 0x9e, - 0x00, 0x00, 0xa7, 0xaa, 0x00, 0x00, 0xa7, 0xaa, 0x00, 0x00, 0x0b, 0xa0, - 0x00, 0x00, 0xf6, 0xc5, 0x00, 0x00, 0xf6, 0xc5, 0x00, 0x00, 0x0b, 0xa1, - 0x00, 0x00, 0xfb, 0x01, 0x00, 0x00, 0xfb, 0x02, 0x00, 0x00, 0x0b, 0xa2, - 0x00, 0x00, 0xfb, 0x52, 0x00, 0x00, 0xfb, 0x81, 0x00, 0x00, 0x0b, 0xa4, - 0x00, 0x00, 0xfb, 0x8a, 0x00, 0x00, 0xfb, 0x95, 0x00, 0x00, 0x0b, 0xd4, - 0x00, 0x00, 0xfb, 0x9e, 0x00, 0x00, 0xfb, 0x9f, 0x00, 0x00, 0x0b, 0xe0, - 0x00, 0x00, 0xfb, 0xaa, 0x00, 0x00, 0xfb, 0xad, 0x00, 0x00, 0x0b, 0xe2, - 0x00, 0x00, 0xfb, 0xe8, 0x00, 0x00, 0xfb, 0xe9, 0x00, 0x00, 0x0b, 0xe6, - 0x00, 0x00, 0xfb, 0xfc, 0x00, 0x00, 0xfb, 0xff, 0x00, 0x00, 0x0b, 0xe8, - 0x00, 0x00, 0xfe, 0x70, 0x00, 0x00, 0xfe, 0x74, 0x00, 0x00, 0x0b, 0xec, - 0x00, 0x00, 0xfe, 0x76, 0x00, 0x00, 0xfe, 0xfc, 0x00, 0x00, 0x0b, 0xf1, - 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0xfe, 0xff, 0x00, 0x00, 0x0c, 0x78, - 0x00, 0x00, 0xff, 0xf9, 0x00, 0x00, 0xff, 0xfd, 0x00, 0x00, 0x0c, 0x79, - 0x00, 0x01, 0xd5, 0x5a, 0x00, 0x01, 0xd5, 0x5a, 0x00, 0x00, 0x0c, 0x7e, - 0x00, 0x01, 0xd6, 0x70, 0x00, 0x01, 0xd6, 0xa3, 0x00, 0x00, 0x0c, 0x7f, - 0x00, 0x01, 0xd7, 0xf6, 0x00, 0x01, 0xd7, 0xff, 0x00, 0x00, 0x0c, 0xb3, - 0x00, 0x06, 0x02, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, - 0x00, 0x08, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, 0x00, 0x0d, - 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, - 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, - 0x00, 0x1a, 0x00, 0x1b, 0x00, 0x1c, 0x00, 0x1d, 0x00, 0x1e, 0x00, 0x1f, - 0x00, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, - 0x00, 0x26, 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, - 0x00, 0x2c, 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30, 0x00, 0x31, - 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, - 0x00, 0x38, 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, - 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, - 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x48, 0x00, 0x49, - 0x00, 0x4a, 0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, - 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, - 0x00, 0x56, 0x00, 0x57, 0x00, 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, - 0x00, 0x5c, 0x00, 0x5d, 0x00, 0x5e, 0x00, 0x5f, 0x00, 0x60, 0x00, 0x61, - 0x00, 0x00, 0x00, 0x86, 0x00, 0x87, 0x00, 0x89, 0x00, 0x8b, 0x00, 0x93, - 0x00, 0x98, 0x00, 0x9e, 0x00, 0xa3, 0x00, 0xa2, 0x00, 0xa4, 0x00, 0xa6, - 0x00, 0xa5, 0x00, 0xa7, 0x00, 0xa9, 0x00, 0xab, 0x00, 0xaa, 0x00, 0xac, - 0x00, 0xad, 0x00, 0xaf, 0x00, 0xae, 0x00, 0xb0, 0x00, 0xb1, 0x00, 0xb3, - 0x00, 0xb5, 0x00, 0xb4, 0x00, 0xb6, 0x00, 0xb8, 0x00, 0xb7, 0x00, 0xbc, - 0x00, 0xbb, 0x00, 0xbd, 0x00, 0xbe, 0x07, 0x24, 0x00, 0x72, 0x00, 0x64, - 0x00, 0x65, 0x00, 0x69, 0x07, 0x26, 0x00, 0x78, 0x00, 0xa1, 0x00, 0x70, - 0x00, 0x6b, 0x07, 0x8b, 0x00, 0x76, 0x00, 0x6a, 0x08, 0x5c, 0x00, 0x88, - 0x00, 0x9a, 0x08, 0x29, 0x00, 0x73, 0x08, 0x60, 0x08, 0x61, 0x00, 0x67, - 0x00, 0x77, 0x08, 0x11, 0x08, 0x1e, 0x08, 0x1d, 0x03, 0x08, 0x08, 0x30, - 0x00, 0x6c, 0x00, 0x7c, 0x02, 0xf1, 0x00, 0xa8, 0x00, 0xba, 0x00, 0x81, - 0x00, 0x63, 0x00, 0x6e, 0x08, 0x25, 0x01, 0x54, 0x08, 0x44, 0x08, 0x15, - 0x00, 0x6d, 0x00, 0x7d, 0x07, 0x28, 0x00, 0x62, 0x00, 0x82, 0x00, 0x85, - 0x00, 0x97, 0x01, 0x14, 0x01, 0x15, 0x07, 0x17, 0x07, 0x18, 0x07, 0x20, - 0x07, 0x21, 0x07, 0x1c, 0x07, 0x1d, 0x00, 0xb9, 0x09, 0xee, 0x00, 0xc1, - 0x01, 0x3a, 0x00, 0x00, 0x07, 0x74, 0x07, 0x32, 0x07, 0x33, 0x0b, 0xa2, - 0x0b, 0xa3, 0x07, 0x25, 0x00, 0x79, 0x07, 0x1e, 0x07, 0x22, 0x07, 0x2a, - 0x00, 0x84, 0x00, 0x8c, 0x00, 0x83, 0x00, 0x8d, 0x00, 0x8a, 0x00, 0x8f, - 0x00, 0x90, 0x00, 0x91, 0x00, 0x8e, 0x00, 0x95, 0x00, 0x96, 0x00, 0x00, - 0x00, 0x94, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x9b, 0x00, 0xf3, 0x02, 0x67, - 0x02, 0x79, 0x00, 0x71, 0x02, 0x75, 0x02, 0x76, 0x02, 0x77, 0x00, 0x7a, - 0x02, 0x7a, 0x02, 0x78, 0x02, 0x68, 0x00, 0x00, 0x00, 0xb8, 0x00, 0xcb, - 0x00, 0xb8, 0x00, 0xcb, 0x00, 0xaa, 0x01, 0x91, 0x00, 0xb8, 0x00, 0x66, - 0x00, 0x00, 0x00, 0xb8, 0x00, 0x87, 0x02, 0x7f, 0x00, 0x02, 0x00, 0x02, - 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0xb8, 0x00, 0xc3, 0x00, 0xcb, - 0x00, 0x02, 0x00, 0xcb, 0x00, 0xb8, 0x00, 0xb8, 0x01, 0xcb, 0x01, 0x89, - 0x01, 0xba, 0x00, 0xcb, 0x00, 0xa6, 0x00, 0xfc, 0x00, 0xcb, 0x00, 0x83, - 0x00, 0xf2, 0x01, 0x0a, 0x03, 0xc7, 0x01, 0x37, 0x00, 0x83, 0x00, 0xbe, - 0x00, 0x00, 0x00, 0x58, 0x04, 0x21, 0x00, 0xcb, 0x00, 0x8f, 0x00, 0x9c, - 0x00, 0x02, 0x00, 0x02, 0x00, 0x8f, 0x03, 0xe7, 0x00, 0x75, 0x03, 0xbc, - 0x00, 0xd3, 0x00, 0xc9, 0x00, 0xdb, 0x00, 0x75, 0x03, 0xe7, 0x01, 0x39, - 0x03, 0xba, 0x00, 0xcb, 0x01, 0xd3, 0x00, 0x21, 0x01, 0xdf, 0x00, 0xb8, - 0x00, 0x89, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, - 0x03, 0xbe, 0x00, 0x89, 0x00, 0xc3, 0x03, 0xbe, 0x00, 0x7b, 0x03, 0xbe, - 0x03, 0x58, 0x01, 0x1f, 0x01, 0x6d, 0x00, 0xa4, 0x01, 0xae, 0x00, 0x00, - 0x00, 0x7b, 0x00, 0xb8, 0x01, 0x6f, 0x00, 0x7f, 0x02, 0x7b, 0x00, 0xb8, - 0x02, 0x52, 0x00, 0x8f, 0x00, 0xcd, 0x04, 0xd1, 0x00, 0x00, 0x00, 0xcd, - 0x00, 0x87, 0x00, 0x87, 0x00, 0x93, 0x00, 0xa4, 0x00, 0x6f, 0x00, 0xcd, - 0x00, 0xcb, 0x00, 0xb8, 0x00, 0x83, 0x01, 0x91, 0x00, 0xdd, 0x00, 0xb4, - 0x00, 0x8b, 0x00, 0xf4, 0x00, 0x98, 0x02, 0xe9, 0x00, 0x5a, 0x00, 0xb4, - 0x00, 0xba, 0x00, 0xc5, 0x04, 0x21, 0x00, 0xfe, 0x00, 0x0e, 0x00, 0x02, - 0x00, 0x02, 0x00, 0x02, 0x01, 0xd5, 0x00, 0xf6, 0x00, 0x7f, 0x02, 0xaa, - 0x02, 0x3d, 0x02, 0x66, 0x00, 0x8b, 0x00, 0xc5, 0x00, 0x8f, 0x00, 0x9a, - 0x00, 0x9a, 0x01, 0x83, 0x00, 0xd5, 0x00, 0x73, 0x04, 0x00, 0x01, 0x0a, - 0x00, 0xfe, 0x00, 0xe1, 0x05, 0xd5, 0x02, 0x2b, 0x00, 0xa4, 0x00, 0xb4, - 0x00, 0x9c, 0x00, 0x00, 0x00, 0x62, 0x00, 0x9c, 0x05, 0xd5, 0x05, 0x98, - 0x00, 0x87, 0x02, 0x7f, 0x05, 0xd5, 0x05, 0xd5, 0x05, 0xf0, 0x00, 0xa4, - 0x00, 0x00, 0x00, 0x1d, 0x06, 0xb8, 0x06, 0x14, 0x07, 0x23, 0x01, 0xd3, - 0x00, 0xb8, 0x00, 0xcb, 0x00, 0xa6, 0x01, 0xbc, 0x01, 0x31, 0x02, 0x4e, - 0x00, 0xd3, 0x01, 0x0a, 0x00, 0x7b, 0x00, 0x54, 0x03, 0x5c, 0x03, 0x71, - 0x03, 0xdb, 0x01, 0x85, 0x04, 0x23, 0x04, 0x77, 0x03, 0xe9, 0x00, 0x8f, - 0x02, 0x00, 0x03, 0x60, 0x00, 0x6a, 0x00, 0xcf, 0x05, 0xd5, 0x06, 0x14, - 0x00, 0x8f, 0x07, 0x23, 0x00, 0x8f, 0x06, 0x66, 0x01, 0x79, 0x04, 0x60, - 0x04, 0x60, 0x04, 0x60, 0x04, 0x7b, 0x00, 0x00, 0x00, 0x7b, 0x02, 0x77, - 0x04, 0x60, 0x01, 0xaa, 0x00, 0xe9, 0x06, 0x14, 0x07, 0x62, 0x03, 0xf8, - 0x00, 0x7b, 0x02, 0x21, 0x00, 0xc5, 0x00, 0x9c, 0x00, 0x7f, 0x02, 0x7b, - 0x00, 0x00, 0x00, 0xb4, 0x02, 0x52, 0x05, 0x4e, 0x05, 0x4e, 0x04, 0xd1, - 0x00, 0x66, 0x00, 0x9c, 0x00, 0x9c, 0x00, 0x66, 0x00, 0x9c, 0x00, 0x8f, - 0x00, 0x66, 0x00, 0x9c, 0x00, 0x8f, 0x06, 0x10, 0x00, 0xcd, 0x03, 0xfa, - 0x00, 0x83, 0x00, 0x91, 0x02, 0xfe, 0x01, 0x48, 0x04, 0x46, 0x03, 0x3f, - 0x00, 0x8f, 0x00, 0x7b, 0x04, 0x4c, 0x00, 0x98, 0x00, 0xa2, 0x00, 0x00, - 0x00, 0x27, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x6f, 0x03, 0x35, 0x00, 0x6a, - 0x00, 0x6f, 0x00, 0x7b, 0x05, 0x8d, 0x05, 0x8d, 0x05, 0x8d, 0x05, 0x8d, - 0x00, 0xaa, 0x00, 0xaa, 0x00, 0x2d, 0x05, 0x8d, 0x03, 0x96, 0x02, 0x7b, - 0x00, 0xf6, 0x00, 0x7f, 0x02, 0xaa, 0x01, 0x33, 0x02, 0x3d, 0x00, 0x9c, - 0x02, 0x66, 0x01, 0x8b, 0x00, 0x8f, 0x02, 0xf6, 0x00, 0xcd, 0x00, 0x6f, - 0x03, 0x44, 0x00, 0x37, 0x00, 0x66, 0x00, 0x1d, 0x05, 0xee, 0x00, 0x85, - 0x01, 0xb4, 0x06, 0x14, 0x00, 0x00, 0x07, 0x7d, 0x00, 0x73, 0x05, 0xd5, - 0x00, 0x00, 0x14, 0x00, 0xb7, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, - 0x00, 0x2c, 0x20, 0x10, 0xb0, 0x02, 0x25, 0x49, 0x64, 0xb0, 0x40, 0x51, - 0x58, 0x20, 0xc8, 0x59, 0x21, 0x2d, 0x2c, 0xb0, 0x02, 0x25, 0x49, 0x64, - 0xb0, 0x40, 0x51, 0x58, 0x20, 0xc8, 0x59, 0x21, 0x2d, 0x2c, 0x20, 0x10, - 0x07, 0x20, 0xb0, 0x00, 0x50, 0xb0, 0x0d, 0x79, 0x20, 0xb8, 0xff, 0xff, - 0x50, 0x58, 0x04, 0x1b, 0x05, 0x59, 0xb0, 0x05, 0x1c, 0xb0, 0x03, 0x25, - 0x08, 0xb0, 0x04, 0x25, 0x23, 0xe1, 0x20, 0xb0, 0x00, 0x50, 0xb0, 0x0d, - 0x79, 0x20, 0xb8, 0xff, 0xff, 0x50, 0x58, 0x04, 0x1b, 0x05, 0x59, 0xb0, - 0x05, 0x1c, 0xb0, 0x03, 0x25, 0x08, 0xe1, 0x2d, 0x2c, 0x4b, 0x50, 0x58, - 0x20, 0xb8, 0x01, 0x17, 0x45, 0x44, 0x59, 0x21, 0x2d, 0x2c, 0xb0, 0x02, - 0x25, 0x45, 0x60, 0x44, 0x2d, 0x2c, 0x4b, 0x53, 0x58, 0xb0, 0x02, 0x25, - 0xb0, 0x02, 0x25, 0x45, 0x44, 0x59, 0x21, 0x21, 0x2d, 0x2c, 0x45, 0x44, - 0x2d, 0x2c, 0xb0, 0x02, 0x25, 0xb0, 0x02, 0x25, 0x49, 0xb0, 0x05, 0x25, - 0xb0, 0x05, 0x25, 0x49, 0x60, 0xb0, 0x20, 0x63, 0x68, 0x20, 0x8a, 0x10, - 0x8a, 0x23, 0x3a, 0x8a, 0x10, 0x65, 0x3a, 0x2d, 0x00, 0x00, 0x00, 0x02, - 0x00, 0x08, 0x00, 0x02, 0xff, 0xff, 0x00, 0x03, 0x00, 0x02, 0x00, 0x68, - 0xfe, 0x96, 0x04, 0x68, 0x05, 0xa4, 0x00, 0x03, 0x00, 0x07, 0x00, 0x1f, - 0xbc, 0x00, 0x04, 0x01, 0x14, 0x00, 0x00, 0x00, 0x06, 0x01, 0x14, 0xb6, - 0x01, 0x08, 0x05, 0x83, 0x02, 0x04, 0x00, 0x2f, 0xc4, 0xd4, 0xec, 0x31, - 0x00, 0x10, 0xd4, 0xec, 0xd4, 0xec, 0x30, 0x13, 0x11, 0x21, 0x11, 0x25, - 0x21, 0x11, 0x21, 0x68, 0x04, 0x00, 0xfc, 0x73, 0x03, 0x1b, 0xfc, 0xe5, - 0xfe, 0x96, 0x07, 0x0e, 0xf8, 0xf2, 0x72, 0x06, 0x29, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x02, 0xcf, 0x05, 0xd5, 0x00, 0x05, - 0x00, 0x09, 0x00, 0x1f, 0x40, 0x0f, 0x03, 0x87, 0x06, 0x86, 0x00, 0x88, - 0x08, 0x04, 0x03, 0x07, 0x01, 0x03, 0x06, 0x00, 0x0a, 0x10, 0xd4, 0x3c, - 0xec, 0x32, 0x39, 0x39, 0x31, 0x00, 0x2f, 0xe4, 0xfc, 0xec, 0x30, 0x01, - 0x33, 0x11, 0x03, 0x23, 0x03, 0x11, 0x33, 0x15, 0x23, 0x02, 0x04, 0xcb, - 0x15, 0xa1, 0x15, 0xcb, 0xcb, 0x05, 0xd5, 0xfd, 0x71, 0xfe, 0x9b, 0x01, - 0x65, 0xfd, 0xb8, 0xfe, 0x00, 0x02, 0x01, 0x52, 0x03, 0xaa, 0x03, 0x7f, - 0x05, 0xd5, 0x00, 0x03, 0x00, 0x07, 0x00, 0x1d, 0x40, 0x0e, 0x05, 0x01, - 0x89, 0x04, 0x00, 0x88, 0x08, 0x00, 0x04, 0x02, 0x06, 0x04, 0x04, 0x08, - 0x10, 0xd4, 0xec, 0xdc, 0xec, 0x31, 0x00, 0x10, 0xf4, 0x3c, 0xec, 0x32, - 0x30, 0x01, 0x11, 0x23, 0x11, 0x23, 0x11, 0x23, 0x11, 0x03, 0x7f, 0xae, - 0xd1, 0xae, 0x05, 0xd5, 0xfd, 0xd5, 0x02, 0x2b, 0xfd, 0xd5, 0x02, 0x2b, - 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x04, 0xcd, 0x05, 0xbe, 0x00, 0x1b, - 0x00, 0x1f, 0x00, 0x4a, 0x40, 0x30, 0x1c, 0x17, 0x07, 0x8c, 0x03, 0x00, - 0x19, 0x05, 0x01, 0x1e, 0x15, 0x09, 0x8c, 0x13, 0x0f, 0x0b, 0x11, 0x0d, - 0x1f, 0x1e, 0x1d, 0x1c, 0x1b, 0x1a, 0x18, 0x17, 0x16, 0x13, 0x12, 0x11, - 0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0a, 0x09, 0x08, 0x05, 0x04, 0x03, 0x02, - 0x01, 0x00, 0x1a, 0x06, 0x14, 0x20, 0x10, 0xd4, 0xcc, 0x17, 0x39, 0x31, - 0x00, 0x2f, 0x3c, 0xd4, 0x3c, 0x3c, 0xfc, 0x3c, 0x3c, 0xd4, 0x3c, 0x3c, - 0xc4, 0x32, 0xec, 0x32, 0x32, 0x30, 0x01, 0x03, 0x33, 0x13, 0x33, 0x03, - 0x33, 0x15, 0x21, 0x03, 0x33, 0x15, 0x21, 0x03, 0x23, 0x13, 0x23, 0x03, - 0x23, 0x13, 0x21, 0x35, 0x21, 0x13, 0x21, 0x35, 0x21, 0x13, 0x01, 0x23, - 0x03, 0x33, 0x02, 0xac, 0x68, 0xf5, 0x69, 0xa0, 0x69, 0xf4, 0xfe, 0xe7, - 0x54, 0xfa, 0xfe, 0xdf, 0x68, 0xa0, 0x69, 0xf6, 0x69, 0x9f, 0x68, 0xfe, - 0xfe, 0x01, 0x29, 0x54, 0xfe, 0xf6, 0x01, 0x2f, 0x68, 0x01, 0x08, 0xf5, - 0x54, 0xf6, 0x05, 0xbe, 0xfe, 0x61, 0x01, 0x9f, 0xfe, 0x61, 0x9a, 0xfe, - 0xb2, 0x99, 0xfe, 0x62, 0x01, 0x9e, 0xfe, 0x62, 0x01, 0x9e, 0x99, 0x01, - 0x4e, 0x9a, 0x01, 0x9f, 0xfd, 0xc7, 0xfe, 0xb2, 0x00, 0x03, 0x00, 0xbe, - 0xfe, 0xd3, 0x04, 0x5a, 0x06, 0x14, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x2f, - 0x00, 0x64, 0x40, 0x39, 0x08, 0x28, 0x24, 0x00, 0x07, 0x29, 0x18, 0x04, - 0x25, 0x14, 0x2f, 0x10, 0x17, 0x13, 0x01, 0x25, 0x8b, 0x24, 0x8e, 0x1f, - 0x28, 0x8f, 0x1e, 0x14, 0x8b, 0x13, 0x8e, 0x01, 0x8f, 0x0e, 0x21, 0x1e, - 0x10, 0x04, 0x06, 0x24, 0x08, 0x2c, 0x05, 0x00, 0x0b, 0x06, 0x1b, 0x13, - 0x05, 0x28, 0x20, 0x0e, 0x03, 0x00, 0x07, 0x1e, 0x17, 0x0f, 0x03, 0x07, - 0x30, 0x10, 0xd4, 0x17, 0x3c, 0xec, 0x17, 0x32, 0xfc, 0x3c, 0xec, 0x10, - 0xfc, 0xe4, 0xee, 0x31, 0x00, 0x2f, 0xc6, 0x32, 0xc4, 0xee, 0xf6, 0xee, - 0x10, 0xee, 0xc6, 0xf6, 0xee, 0x11, 0x12, 0x39, 0x11, 0x39, 0x11, 0x12, - 0x17, 0x39, 0x11, 0x12, 0x39, 0x30, 0x01, 0x11, 0x3e, 0x01, 0x35, 0x34, - 0x26, 0x27, 0x11, 0x0e, 0x01, 0x15, 0x14, 0x16, 0x13, 0x23, 0x03, 0x2e, - 0x01, 0x27, 0x35, 0x1e, 0x01, 0x17, 0x11, 0x2e, 0x01, 0x35, 0x34, 0x36, - 0x37, 0x35, 0x33, 0x17, 0x1e, 0x01, 0x17, 0x15, 0x2e, 0x01, 0x27, 0x11, - 0x1e, 0x01, 0x15, 0x14, 0x06, 0x07, 0x02, 0xb4, 0x6e, 0x7c, 0x70, 0xde, - 0x68, 0x75, 0x6d, 0xd4, 0x64, 0x01, 0x66, 0xc9, 0x62, 0x64, 0xcb, 0x63, - 0xc8, 0xca, 0xd3, 0xbf, 0x64, 0x01, 0x4f, 0xa2, 0x54, 0x55, 0xa1, 0x50, - 0xce, 0xd8, 0xe9, 0xbc, 0x02, 0x44, 0xfe, 0x4e, 0x03, 0x74, 0x64, 0x5d, - 0x67, 0xd1, 0x01, 0x9d, 0x04, 0x70, 0x5e, 0x56, 0x64, 0xfb, 0xc0, 0x01, - 0x2d, 0x05, 0x2e, 0x29, 0xb4, 0x3e, 0x42, 0x02, 0x01, 0xca, 0x1f, 0xb6, - 0x96, 0x9d, 0xbb, 0x0e, 0xeb, 0xeb, 0x05, 0x1e, 0x1a, 0xad, 0x2b, 0x2f, - 0x04, 0xfe, 0x51, 0x1f, 0xc2, 0x9a, 0x9a, 0xce, 0x09, 0x00, 0x00, 0x00, - 0x00, 0x05, 0x00, 0x21, 0x00, 0x00, 0x04, 0xb0, 0x05, 0x98, 0x00, 0x0b, - 0x00, 0x1a, 0x00, 0x1e, 0x00, 0x2a, 0x00, 0x39, 0x00, 0x56, 0x40, 0x2f, - 0x1e, 0x37, 0x1d, 0x28, 0x22, 0x1c, 0x0f, 0x1b, 0x03, 0x09, 0x92, 0x0f, - 0x22, 0x92, 0x37, 0x93, 0x28, 0x92, 0x2e, 0x91, 0x0f, 0x93, 0x03, 0x92, - 0x18, 0x1c, 0x1b, 0x2b, 0x1f, 0x1e, 0x1d, 0x06, 0x0a, 0x15, 0x0b, 0x00, - 0x0a, 0x0c, 0x25, 0x0a, 0x34, 0x0b, 0x1f, 0x0a, 0x2b, 0x0c, 0x3a, 0x10, - 0xc4, 0xd4, 0xec, 0xfc, 0xec, 0x10, 0xee, 0xfe, 0xee, 0x39, 0x39, 0x11, - 0x12, 0x39, 0x39, 0x31, 0x00, 0x2f, 0xee, 0xee, 0xf6, 0xee, 0xfe, 0xee, - 0x10, 0xee, 0x11, 0x39, 0x11, 0x39, 0x11, 0x12, 0x39, 0x12, 0x39, 0x30, - 0x01, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, - 0x07, 0x34, 0x36, 0x33, 0x32, 0x16, 0x17, 0x1e, 0x01, 0x15, 0x14, 0x06, - 0x23, 0x22, 0x26, 0x01, 0x27, 0x01, 0x17, 0x25, 0x14, 0x16, 0x33, 0x32, - 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x34, 0x36, 0x33, 0x32, - 0x16, 0x17, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x02, 0xb8, - 0x69, 0x4e, 0x4d, 0x6b, 0x6c, 0x4c, 0x4e, 0x69, 0x87, 0xb8, 0x86, 0x40, - 0x73, 0x2e, 0x2e, 0x32, 0xba, 0x87, 0x88, 0xb6, 0xfe, 0x48, 0x23, 0x04, - 0x12, 0x29, 0xfc, 0x17, 0x69, 0x4f, 0x4d, 0x6c, 0x6c, 0x4d, 0x4d, 0x6b, - 0x87, 0xb8, 0x87, 0x40, 0x75, 0x2d, 0x2d, 0x31, 0xba, 0x86, 0x87, 0xb8, - 0x01, 0x3f, 0x4e, 0x6a, 0x6b, 0x4d, 0x4d, 0x6c, 0x6a, 0x4f, 0x87, 0xb9, - 0x30, 0x2e, 0x2f, 0x74, 0x3f, 0x85, 0xba, 0xb7, 0x01, 0x1a, 0x60, 0x01, - 0xa2, 0x60, 0xe5, 0x4f, 0x69, 0x6b, 0x4d, 0x4d, 0x6b, 0x6a, 0x4e, 0x87, - 0xb9, 0x30, 0x2d, 0x2d, 0x75, 0x41, 0x86, 0xb9, 0xb8, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x39, 0xff, 0xe3, 0x04, 0xc5, 0x05, 0xf0, 0x00, 0x2a, - 0x00, 0x37, 0x00, 0xb3, 0x40, 0x62, 0x11, 0x10, 0x02, 0x12, 0x0f, 0x17, - 0x0c, 0x0d, 0x0c, 0x0e, 0x17, 0x0d, 0x0d, 0x0c, 0x2d, 0x2c, 0x02, 0x2e, - 0x2b, 0x17, 0x00, 0x01, 0x00, 0x32, 0x33, 0x34, 0x35, 0x36, 0x05, 0x31, - 0x37, 0x17, 0x01, 0x01, 0x00, 0x42, 0x37, 0x0c, 0x09, 0x06, 0x01, 0x05, - 0x07, 0x0f, 0x31, 0x0d, 0x18, 0x00, 0x2b, 0x03, 0x22, 0x07, 0x31, 0x97, - 0x12, 0x22, 0x21, 0x25, 0x97, 0x1e, 0x96, 0x12, 0x99, 0x07, 0x0d, 0x00, - 0x28, 0x01, 0x07, 0x06, 0x03, 0x21, 0x0c, 0x08, 0x04, 0x37, 0x2b, 0x21, - 0x18, 0x28, 0x1b, 0x0f, 0x21, 0x04, 0x13, 0x08, 0x28, 0x12, 0x21, 0x1b, - 0x08, 0x0d, 0x10, 0x1b, 0x2e, 0x12, 0x15, 0x38, 0x10, 0xdc, 0xec, 0xc4, - 0xfc, 0xc4, 0x10, 0xc6, 0xee, 0x10, 0xee, 0x11, 0x39, 0x11, 0x12, 0x39, - 0x11, 0x39, 0x39, 0x11, 0x12, 0x39, 0x12, 0x17, 0x39, 0x11, 0x39, 0x31, - 0x00, 0x2f, 0xc6, 0xe4, 0xf6, 0xee, 0xd6, 0xce, 0x10, 0xee, 0x11, 0x12, - 0x17, 0x39, 0x11, 0x12, 0x39, 0x11, 0x17, 0x39, 0x30, 0x4b, 0x53, 0x58, - 0x07, 0x10, 0x0e, 0xed, 0x11, 0x17, 0x39, 0x07, 0x10, 0x0e, 0xed, 0x11, - 0x17, 0x39, 0x07, 0x10, 0x05, 0xed, 0x07, 0x10, 0x05, 0xed, 0x11, 0x17, - 0x39, 0x59, 0x22, 0x09, 0x01, 0x3e, 0x01, 0x35, 0x34, 0x2f, 0x01, 0x33, - 0x15, 0x14, 0x06, 0x07, 0x17, 0x23, 0x27, 0x0e, 0x01, 0x23, 0x22, 0x00, - 0x35, 0x34, 0x36, 0x37, 0x2e, 0x01, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, - 0x17, 0x15, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x07, 0x0e, - 0x01, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x3e, 0x01, 0x37, 0x02, - 0x23, 0x01, 0xa0, 0x27, 0x26, 0x03, 0x01, 0xa4, 0x4a, 0x4b, 0xaa, 0xd5, - 0x4e, 0x53, 0xba, 0x6a, 0xd8, 0xfe, 0xe6, 0x8a, 0x8b, 0x32, 0x30, 0xc7, - 0xad, 0x41, 0x83, 0x46, 0x3b, 0x7d, 0x45, 0x61, 0x70, 0x3a, 0x36, 0x5c, - 0x5b, 0xc8, 0x9b, 0x2a, 0x5c, 0x2c, 0x1b, 0x23, 0x10, 0x03, 0x8b, 0xfd, - 0xd1, 0x31, 0x96, 0x68, 0x20, 0x46, 0x07, 0x27, 0xa1, 0xf3, 0x58, 0xe5, - 0x6d, 0x46, 0x44, 0x01, 0x0d, 0xcc, 0x89, 0xea, 0x64, 0x48, 0x8a, 0x47, - 0x96, 0xae, 0x18, 0x17, 0xb7, 0x27, 0x25, 0x5b, 0x4d, 0x3b, 0x81, 0xcf, - 0x49, 0xa3, 0x5c, 0x97, 0xc7, 0x18, 0x17, 0x0f, 0x17, 0x0d, 0x00, 0x00, - 0x00, 0x01, 0x02, 0x10, 0x03, 0xaa, 0x02, 0xbe, 0x05, 0xd5, 0x00, 0x03, - 0x00, 0x12, 0xb7, 0x01, 0x00, 0x88, 0x04, 0x00, 0x04, 0x02, 0x04, 0x10, - 0xd4, 0xec, 0x31, 0x00, 0x10, 0xf4, 0xc4, 0x30, 0x01, 0x11, 0x23, 0x11, - 0x02, 0xbe, 0xae, 0x05, 0xd5, 0xfd, 0xd5, 0x02, 0x2b, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0xaa, 0xfe, 0xf2, 0x03, 0x75, 0x06, 0x12, 0x00, 0x0d, - 0x00, 0x1f, 0x40, 0x0f, 0x06, 0x9c, 0x00, 0x9b, 0x0e, 0x0d, 0x07, 0x00, - 0x03, 0x12, 0x06, 0x00, 0x18, 0x0a, 0x0e, 0x10, 0xd4, 0xec, 0x32, 0xec, - 0x11, 0x39, 0x39, 0x31, 0x00, 0x10, 0xfc, 0xec, 0x30, 0x01, 0x06, 0x02, - 0x15, 0x14, 0x12, 0x17, 0x23, 0x26, 0x02, 0x35, 0x34, 0x12, 0x37, 0x03, - 0x75, 0x85, 0x83, 0x83, 0x85, 0xa0, 0x97, 0x94, 0x94, 0x97, 0x06, 0x12, - 0xe4, 0xfe, 0x3b, 0xe6, 0xe5, 0xfe, 0x3a, 0xe6, 0xee, 0x01, 0xc3, 0xe0, - 0xdf, 0x01, 0xc4, 0xec, 0x00, 0x01, 0x01, 0x5c, 0xfe, 0xf2, 0x03, 0x27, - 0x06, 0x12, 0x00, 0x0d, 0x00, 0x1f, 0x40, 0x0f, 0x07, 0x9c, 0x00, 0x9b, - 0x0e, 0x07, 0x01, 0x0b, 0x08, 0x00, 0x18, 0x04, 0x12, 0x0b, 0x0e, 0x10, - 0xd4, 0xfc, 0xec, 0x32, 0x11, 0x39, 0x39, 0x31, 0x00, 0x10, 0xfc, 0xec, - 0x30, 0x01, 0x33, 0x16, 0x12, 0x15, 0x14, 0x02, 0x07, 0x23, 0x36, 0x12, - 0x35, 0x34, 0x02, 0x01, 0x5c, 0xa0, 0x97, 0x94, 0x94, 0x97, 0xa0, 0x85, - 0x83, 0x83, 0x06, 0x12, 0xec, 0xfe, 0x3c, 0xdf, 0xe1, 0xfe, 0x3c, 0xec, - 0xe8, 0x01, 0xc6, 0xe3, 0xe4, 0x01, 0xc6, 0x00, 0x00, 0x01, 0x00, 0xa6, - 0x02, 0x4a, 0x04, 0x2b, 0x05, 0xf0, 0x00, 0x11, 0x00, 0x4e, 0x40, 0x2c, - 0x10, 0x0d, 0x0b, 0x00, 0x04, 0x0c, 0x09, 0x07, 0x04, 0x02, 0x04, 0x08, - 0x03, 0x9d, 0x05, 0x11, 0x0c, 0x9d, 0x0a, 0x01, 0x0e, 0x96, 0x12, 0x08, - 0x0c, 0x0a, 0x03, 0x09, 0x06, 0x11, 0x03, 0x01, 0x03, 0x02, 0x00, 0x19, - 0x0f, 0x04, 0x0b, 0x09, 0x19, 0x0d, 0x06, 0x12, 0x10, 0xd4, 0x3c, 0xec, - 0x32, 0xdc, 0x3c, 0xec, 0x32, 0x17, 0x39, 0x11, 0x12, 0x17, 0x39, 0x31, - 0x00, 0x10, 0xf4, 0xd4, 0x3c, 0xec, 0x32, 0xc4, 0xec, 0x32, 0x17, 0x39, - 0x12, 0x17, 0x39, 0x30, 0x01, 0x0d, 0x01, 0x07, 0x25, 0x11, 0x23, 0x11, - 0x05, 0x27, 0x2d, 0x01, 0x37, 0x05, 0x11, 0x33, 0x11, 0x25, 0x04, 0x2b, - 0xfe, 0x9a, 0x01, 0x66, 0x39, 0xfe, 0xb0, 0x73, 0xfe, 0xb0, 0x39, 0x01, - 0x66, 0xfe, 0x9a, 0x39, 0x01, 0x50, 0x73, 0x01, 0x50, 0x04, 0xdf, 0xc2, - 0xc3, 0x62, 0xcb, 0xfe, 0x87, 0x01, 0x79, 0xcb, 0x62, 0xc3, 0xc2, 0x63, - 0xcb, 0x01, 0x79, 0xfe, 0x87, 0xcb, 0x00, 0x00, 0x00, 0x01, 0x00, 0x58, - 0x00, 0x71, 0x04, 0x79, 0x04, 0x93, 0x00, 0x0b, 0x00, 0x27, 0x40, 0x14, - 0x00, 0xa1, 0x09, 0x01, 0xa0, 0x05, 0xa1, 0x07, 0x03, 0x0c, 0x02, 0x1a, - 0x04, 0x00, 0x1c, 0x08, 0x1a, 0x0a, 0x06, 0x0c, 0x10, 0xd4, 0x3c, 0xec, - 0xfc, 0x3c, 0xec, 0x31, 0x00, 0x10, 0xd4, 0x3c, 0xec, 0xfc, 0x3c, 0xec, - 0x30, 0x01, 0x11, 0x21, 0x15, 0x21, 0x11, 0x23, 0x11, 0x21, 0x35, 0x21, - 0x11, 0x02, 0xbc, 0x01, 0xbd, 0xfe, 0x43, 0xa8, 0xfe, 0x44, 0x01, 0xbc, - 0x04, 0x93, 0xfe, 0x44, 0xaa, 0xfe, 0x44, 0x01, 0xbc, 0xaa, 0x01, 0xbc, - 0x00, 0x01, 0x01, 0x93, 0xfe, 0xe1, 0x02, 0xf2, 0x01, 0x2f, 0x00, 0x05, - 0x00, 0x18, 0x40, 0x0b, 0x03, 0xa3, 0x00, 0xa2, 0x06, 0x03, 0x04, 0x01, - 0x1d, 0x00, 0x06, 0x10, 0xd4, 0xec, 0xd4, 0xcc, 0x31, 0x00, 0x10, 0xfc, - 0xec, 0x30, 0x01, 0x33, 0x15, 0x03, 0x23, 0x13, 0x01, 0xf6, 0xfc, 0xc5, - 0x9a, 0x63, 0x01, 0x2f, 0xcf, 0xfe, 0x81, 0x01, 0x7f, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x64, 0x01, 0xdf, 0x03, 0x6d, 0x02, 0x83, 0x00, 0x03, - 0x00, 0x11, 0xb6, 0x00, 0xa0, 0x02, 0x04, 0x01, 0x00, 0x04, 0x10, 0xd4, - 0xc4, 0x31, 0x00, 0x10, 0xd4, 0xec, 0x30, 0x01, 0x21, 0x15, 0x21, 0x01, - 0x64, 0x02, 0x09, 0xfd, 0xf7, 0x02, 0x83, 0xa4, 0x00, 0x01, 0x01, 0xe9, - 0x00, 0x00, 0x02, 0xe5, 0x01, 0x31, 0x00, 0x03, 0x00, 0x10, 0xb6, 0x00, - 0xa2, 0x02, 0x01, 0x1d, 0x00, 0x04, 0x10, 0xd4, 0xec, 0x31, 0x00, 0x2f, - 0xec, 0x30, 0x01, 0x33, 0x11, 0x23, 0x01, 0xe9, 0xfc, 0xfc, 0x01, 0x31, - 0xfe, 0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x66, 0xff, 0x42, 0x04, 0x37, - 0x05, 0xd5, 0x00, 0x03, 0x00, 0x18, 0x40, 0x0b, 0x02, 0x00, 0x88, 0x04, - 0x01, 0x1e, 0x00, 0x02, 0x1e, 0x03, 0x04, 0x10, 0xd4, 0xec, 0xd4, 0xec, - 0x31, 0x00, 0x10, 0xf4, 0xc4, 0x30, 0x01, 0x33, 0x01, 0x23, 0x03, 0x79, - 0xbe, 0xfc, 0xee, 0xbf, 0x05, 0xd5, 0xf9, 0x6d, 0x00, 0x03, 0x00, 0x85, - 0xff, 0xe3, 0x04, 0x4c, 0x05, 0xf0, 0x00, 0x0b, 0x00, 0x17, 0x00, 0x23, - 0x01, 0x0a, 0x40, 0x1a, 0x03, 0xa5, 0x09, 0x12, 0x97, 0x1e, 0x0c, 0x97, - 0x18, 0x96, 0x1e, 0x99, 0x24, 0x15, 0x1e, 0x1b, 0x06, 0x21, 0x00, 0x1b, - 0x22, 0x0f, 0x1e, 0x21, 0x1f, 0x24, 0x10, 0xfc, 0xec, 0xec, 0xd4, 0xec, - 0x10, 0xee, 0x31, 0x00, 0x10, 0xe4, 0xf4, 0xec, 0x10, 0xee, 0xd4, 0xee, - 0x30, 0x40, 0xd6, 0x2f, 0x00, 0x2f, 0x01, 0x2f, 0x02, 0x2f, 0x03, 0x2f, - 0x04, 0x2f, 0x05, 0x2f, 0x06, 0x2f, 0x07, 0x2f, 0x08, 0x2f, 0x09, 0x2f, - 0x0a, 0x2f, 0x0b, 0x3f, 0x00, 0x3f, 0x01, 0x3f, 0x02, 0x3f, 0x03, 0x3f, - 0x04, 0x3f, 0x05, 0x3f, 0x06, 0x3f, 0x07, 0x3f, 0x08, 0x3f, 0x09, 0x3f, - 0x0a, 0x3f, 0x0b, 0x4f, 0x00, 0x4f, 0x01, 0x4f, 0x02, 0x4f, 0x0a, 0x4f, - 0x0b, 0x5f, 0x00, 0x5f, 0x01, 0x5f, 0x02, 0x5f, 0x0a, 0x5f, 0x0b, 0x9f, - 0x00, 0x9f, 0x01, 0x9f, 0x02, 0x9f, 0x03, 0x9f, 0x04, 0x9f, 0x05, 0x9f, - 0x06, 0x9f, 0x07, 0x9f, 0x08, 0x9f, 0x09, 0x9f, 0x0a, 0x9f, 0x0b, 0xaf, - 0x00, 0xaf, 0x01, 0xaf, 0x02, 0xaf, 0x03, 0xaf, 0x04, 0xaf, 0x05, 0xaf, - 0x06, 0xaf, 0x07, 0xaf, 0x08, 0xaf, 0x09, 0xaf, 0x0a, 0xaf, 0x0b, 0xbf, - 0x00, 0xbf, 0x01, 0xbf, 0x02, 0xbf, 0x03, 0xbf, 0x04, 0xbf, 0x05, 0xbf, - 0x06, 0xbf, 0x07, 0xbf, 0x08, 0xbf, 0x09, 0xbf, 0x0a, 0xbf, 0x0b, 0x46, - 0x2f, 0x00, 0x2f, 0x01, 0x2f, 0x02, 0x2f, 0x03, 0x2f, 0x04, 0x2f, 0x05, - 0x2f, 0x06, 0x2f, 0x07, 0x2f, 0x08, 0x2f, 0x09, 0x2f, 0x0a, 0x2f, 0x0b, - 0x5f, 0x00, 0x5f, 0x01, 0x5f, 0x02, 0x5f, 0x03, 0x5f, 0x04, 0x5f, 0x05, - 0x5f, 0x06, 0x5f, 0x07, 0x5f, 0x08, 0x5f, 0x09, 0x5f, 0x0a, 0x5f, 0x0b, - 0xbf, 0x00, 0xbf, 0x01, 0xbf, 0x02, 0xbf, 0x03, 0xbf, 0x04, 0xbf, 0x05, - 0xbf, 0x06, 0xbf, 0x07, 0xbf, 0x08, 0xbf, 0x09, 0xbf, 0x0a, 0xbf, 0x0b, - 0x24, 0x5d, 0x01, 0x5d, 0x01, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, - 0x06, 0x23, 0x22, 0x26, 0x13, 0x22, 0x02, 0x11, 0x10, 0x12, 0x33, 0x32, - 0x12, 0x11, 0x10, 0x02, 0x27, 0x32, 0x12, 0x11, 0x10, 0x02, 0x23, 0x22, - 0x02, 0x11, 0x10, 0x12, 0x01, 0xe3, 0x4d, 0x36, 0x38, 0x50, 0x4f, 0x39, - 0x38, 0x4b, 0x85, 0x8d, 0x8b, 0x8b, 0x8d, 0x8e, 0x8b, 0x8b, 0x8e, 0xef, - 0xf5, 0xf5, 0xef, 0xef, 0xf4, 0xf4, 0x02, 0xee, 0x37, 0x50, 0x50, 0x37, - 0x38, 0x4e, 0x4c, 0x02, 0x9c, 0xfe, 0xd0, 0xfe, 0xc9, 0xfe, 0xca, 0xfe, - 0xd0, 0x01, 0x30, 0x01, 0x36, 0x01, 0x37, 0x01, 0x30, 0xa0, 0xfe, 0x78, - 0xfe, 0x81, 0xfe, 0x82, 0xfe, 0x78, 0x01, 0x88, 0x01, 0x7e, 0x01, 0x7f, - 0x01, 0x88, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf6, 0x00, 0x00, 0x04, 0x46, - 0x05, 0xd5, 0x00, 0x0a, 0x00, 0x26, 0x40, 0x14, 0x03, 0x97, 0x04, 0x02, - 0x97, 0x05, 0x88, 0x07, 0x00, 0x97, 0x09, 0x08, 0x23, 0x06, 0x1e, 0x03, - 0x00, 0x23, 0x01, 0x0b, 0x10, 0xd4, 0xec, 0xc4, 0xfc, 0xec, 0x31, 0x00, - 0x2f, 0xec, 0x32, 0xf4, 0xec, 0xd4, 0xec, 0x30, 0x25, 0x21, 0x11, 0x05, - 0x35, 0x25, 0x33, 0x11, 0x21, 0x15, 0x21, 0x01, 0x0e, 0x01, 0x3a, 0xfe, - 0xae, 0x01, 0x50, 0xca, 0x01, 0x36, 0xfc, 0xc8, 0xaa, 0x04, 0x75, 0x4c, - 0xb8, 0x4a, 0xfa, 0xd5, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x98, - 0x00, 0x00, 0x04, 0x23, 0x05, 0xf0, 0x00, 0x1c, 0x00, 0x51, 0x40, 0x29, - 0x00, 0x1c, 0x25, 0x05, 0x06, 0x05, 0x18, 0x19, 0x1a, 0x03, 0x17, 0x1b, - 0x25, 0x06, 0x06, 0x05, 0x42, 0x10, 0x11, 0xa7, 0x0d, 0x97, 0x14, 0x96, - 0x04, 0x00, 0x97, 0x02, 0x00, 0x10, 0x0a, 0x02, 0x01, 0x0a, 0x1e, 0x17, - 0x22, 0x10, 0x03, 0x24, 0x1d, 0x10, 0xfc, 0xc4, 0xfc, 0xec, 0xc0, 0xc0, - 0x11, 0x12, 0x39, 0x31, 0x00, 0x2f, 0xec, 0x32, 0xf4, 0xec, 0xf4, 0xcc, - 0x30, 0x4b, 0x53, 0x58, 0x07, 0x10, 0x05, 0xed, 0x11, 0x17, 0x39, 0x07, - 0x10, 0x05, 0xed, 0x17, 0x32, 0x59, 0x22, 0x25, 0x21, 0x15, 0x21, 0x35, - 0x36, 0x00, 0x37, 0x3e, 0x01, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, - 0x35, 0x3e, 0x01, 0x33, 0x32, 0x04, 0x15, 0x14, 0x06, 0x07, 0x0e, 0x01, - 0x01, 0x75, 0x02, 0xae, 0xfc, 0x75, 0xbb, 0x01, 0x18, 0x35, 0x64, 0x46, - 0x93, 0x80, 0x5b, 0xc8, 0x70, 0x67, 0xc7, 0x61, 0xdb, 0x01, 0x0b, 0x59, - 0x64, 0x38, 0xd5, 0xaa, 0xaa, 0xaa, 0xc5, 0x01, 0x2e, 0x3e, 0x7a, 0x97, - 0x4f, 0x7d, 0x8e, 0x42, 0x43, 0xcc, 0x31, 0x32, 0xe9, 0xbd, 0x60, 0xc0, - 0x74, 0x41, 0xe6, 0x00, 0x00, 0x01, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x37, - 0x05, 0xf0, 0x00, 0x28, 0x00, 0x47, 0x40, 0x29, 0x00, 0x13, 0x97, 0x15, - 0x0a, 0x8b, 0x09, 0xa6, 0x0d, 0x97, 0x06, 0x1f, 0x8b, 0x20, 0xa6, 0x1c, - 0x97, 0x23, 0x96, 0x06, 0x99, 0x15, 0xa9, 0x29, 0x16, 0x13, 0x00, 0x03, - 0x14, 0x19, 0x1e, 0x26, 0x10, 0x1e, 0x03, 0x22, 0x1f, 0x14, 0x09, 0x1f, - 0x29, 0x10, 0xfc, 0xc4, 0xc4, 0xfc, 0xec, 0xd4, 0xec, 0x11, 0x17, 0x39, - 0x31, 0x00, 0x10, 0xec, 0xe4, 0xf4, 0xec, 0xf4, 0xec, 0x10, 0xee, 0xf6, - 0xee, 0x10, 0xee, 0x39, 0x30, 0x01, 0x1e, 0x01, 0x15, 0x14, 0x04, 0x23, - 0x22, 0x26, 0x27, 0x35, 0x1e, 0x01, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, - 0x2b, 0x01, 0x35, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, - 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x04, 0x15, 0x14, 0x06, 0x03, 0x08, - 0x93, 0x9c, 0xfe, 0xeb, 0xf5, 0x67, 0xd6, 0x67, 0x66, 0xc6, 0x62, 0xa6, - 0xb2, 0xb2, 0x98, 0x9a, 0x9a, 0x8b, 0x9c, 0x91, 0x86, 0x59, 0xbe, 0x68, - 0x79, 0xbd, 0x49, 0xda, 0x01, 0x05, 0x89, 0x03, 0x1f, 0x27, 0xc7, 0x95, - 0xce, 0xeb, 0x26, 0x24, 0xc9, 0x35, 0x34, 0x96, 0x8d, 0x82, 0x99, 0xa6, - 0x7a, 0x6d, 0x73, 0x7b, 0x28, 0x28, 0xba, 0x20, 0x20, 0xdb, 0xb5, 0x7b, - 0xa4, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x66, 0x00, 0x00, 0x04, 0x6f, - 0x05, 0xd5, 0x00, 0x02, 0x00, 0x0d, 0x00, 0x42, 0x40, 0x1f, 0x01, 0x0d, - 0x03, 0x0d, 0x00, 0x03, 0x03, 0x0d, 0x42, 0x00, 0x03, 0x0b, 0x07, 0x97, - 0x05, 0x01, 0x03, 0x88, 0x09, 0x01, 0x0c, 0x0a, 0x00, 0x1e, 0x08, 0x04, - 0x06, 0x0f, 0x0c, 0x24, 0x0e, 0x10, 0xfc, 0xfc, 0xd4, 0x3c, 0xec, 0x32, - 0x11, 0x39, 0x31, 0x00, 0x2f, 0xe4, 0xd4, 0x3c, 0xec, 0x32, 0x12, 0x39, - 0x30, 0x4b, 0x53, 0x58, 0x07, 0x10, 0x04, 0xc9, 0x07, 0x10, 0x05, 0xc9, - 0x59, 0x22, 0x09, 0x01, 0x21, 0x03, 0x33, 0x11, 0x33, 0x15, 0x23, 0x11, - 0x23, 0x11, 0x21, 0x35, 0x02, 0xdf, 0xfe, 0x29, 0x01, 0xd7, 0x21, 0xea, - 0xc7, 0xc7, 0xc9, 0xfd, 0x87, 0x05, 0x1d, 0xfc, 0xeb, 0x03, 0xcd, 0xfc, - 0x33, 0xa4, 0xfe, 0x9c, 0x01, 0x64, 0xbf, 0x00, 0x00, 0x01, 0x00, 0x8f, - 0xff, 0xe3, 0x04, 0x2d, 0x05, 0xd5, 0x00, 0x1d, 0x00, 0x3d, 0x40, 0x22, - 0x04, 0x07, 0x1d, 0x1a, 0x97, 0x07, 0x11, 0x8b, 0x10, 0x8e, 0x14, 0x97, - 0x0d, 0x02, 0x97, 0x00, 0x88, 0x0d, 0x99, 0x07, 0xaa, 0x1e, 0x03, 0x1e, - 0x00, 0x17, 0x1e, 0x01, 0x0a, 0x22, 0x00, 0x10, 0x1f, 0x1e, 0x10, 0xfc, - 0xc4, 0xfc, 0xc4, 0xec, 0x10, 0xee, 0x31, 0x00, 0x10, 0xe4, 0xe4, 0xf4, - 0xec, 0x10, 0xee, 0xf6, 0xee, 0x10, 0xfe, 0xc4, 0x12, 0x39, 0x30, 0x13, - 0x21, 0x15, 0x21, 0x11, 0x3e, 0x01, 0x33, 0x32, 0x00, 0x15, 0x14, 0x00, - 0x23, 0x22, 0x26, 0x27, 0x35, 0x1e, 0x01, 0x33, 0x32, 0x36, 0x35, 0x34, - 0x26, 0x23, 0x22, 0x06, 0x07, 0xcf, 0x02, 0xf4, 0xfd, 0xc4, 0x2b, 0x57, - 0x2c, 0xe8, 0x01, 0x10, 0xfe, 0xe3, 0xf7, 0x77, 0xc5, 0x4e, 0x5c, 0xba, - 0x61, 0xa7, 0xb5, 0xbb, 0xa7, 0x51, 0x9a, 0x46, 0x05, 0xd5, 0xaa, 0xfe, - 0x91, 0x10, 0x0f, 0xfe, 0xee, 0xea, 0xec, 0xfe, 0xf0, 0x20, 0x20, 0xcd, - 0x32, 0x31, 0xb0, 0xa2, 0xa0, 0xb2, 0x25, 0x25, 0x00, 0x02, 0x00, 0x85, - 0xff, 0xe3, 0x04, 0x4c, 0x05, 0xf0, 0x00, 0x18, 0x00, 0x24, 0x00, 0x3d, - 0x40, 0x23, 0x07, 0x1f, 0x19, 0x97, 0x0a, 0x1f, 0x97, 0x10, 0x0a, 0xab, - 0x04, 0x01, 0x8b, 0x00, 0x8e, 0x04, 0x97, 0x16, 0x96, 0x10, 0x99, 0x25, - 0x22, 0x1e, 0x00, 0x26, 0x0d, 0x22, 0x07, 0x06, 0x1c, 0x01, 0x13, 0x1f, - 0x25, 0x10, 0xfc, 0xec, 0xec, 0xfc, 0xe4, 0xec, 0x31, 0x00, 0x10, 0xe4, - 0xf4, 0xec, 0xf4, 0xec, 0x10, 0xe5, 0x10, 0xee, 0x10, 0xee, 0x11, 0x39, - 0x30, 0x01, 0x15, 0x2e, 0x01, 0x23, 0x22, 0x02, 0x11, 0x3e, 0x01, 0x33, - 0x32, 0x12, 0x15, 0x14, 0x02, 0x23, 0x20, 0x02, 0x11, 0x10, 0x00, 0x21, - 0x32, 0x16, 0x01, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, - 0x34, 0x26, 0x03, 0xdf, 0x3f, 0x8e, 0x4d, 0xc0, 0xc6, 0x30, 0xaa, 0x6e, - 0xd8, 0xed, 0xf4, 0xdd, 0xfe, 0xfc, 0xf2, 0x01, 0x23, 0x01, 0x14, 0x4a, - 0x94, 0xfe, 0xdd, 0x81, 0x94, 0x94, 0x81, 0x86, 0x88, 0x88, 0x05, 0xb4, - 0xba, 0x25, 0x27, 0xfe, 0xdf, 0xfe, 0xe7, 0x64, 0x6b, 0xfe, 0xf7, 0xf3, - 0xf2, 0xfe, 0xf6, 0x01, 0x75, 0x01, 0x91, 0x01, 0x7a, 0x01, 0x8d, 0x1f, - 0xfd, 0x6c, 0xba, 0xa4, 0xa4, 0xba, 0xb1, 0xad, 0xae, 0xb0, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x8b, 0x00, 0x00, 0x04, 0x37, 0x05, 0xd5, 0x00, 0x06, - 0x00, 0x35, 0x40, 0x19, 0x05, 0x25, 0x02, 0x03, 0x02, 0x03, 0x25, 0x04, - 0x05, 0x04, 0x42, 0x05, 0x97, 0x00, 0x88, 0x03, 0x05, 0x03, 0x01, 0x04, - 0x01, 0x22, 0x00, 0x1f, 0x07, 0x10, 0xfc, 0xec, 0xc4, 0x11, 0x39, 0x39, - 0x31, 0x00, 0x2f, 0xf4, 0xec, 0x30, 0x4b, 0x53, 0x58, 0x07, 0x10, 0x05, - 0xed, 0x07, 0x10, 0x05, 0xed, 0x59, 0x22, 0x13, 0x21, 0x15, 0x01, 0x23, - 0x01, 0x21, 0x8b, 0x03, 0xac, 0xfd, 0xea, 0xd3, 0x02, 0x08, 0xfd, 0x35, - 0x05, 0xd5, 0x56, 0xfa, 0x81, 0x05, 0x2b, 0x00, 0x00, 0x03, 0x00, 0x83, - 0xff, 0xe3, 0x04, 0x4e, 0x05, 0xf0, 0x00, 0x0b, 0x00, 0x23, 0x00, 0x2f, - 0x00, 0x43, 0x40, 0x25, 0x18, 0x0c, 0x00, 0x97, 0x27, 0x06, 0x97, 0x1e, - 0x2d, 0x97, 0x12, 0x96, 0x1e, 0x99, 0x27, 0xa9, 0x30, 0x18, 0x0c, 0x24, - 0x2a, 0x1e, 0x15, 0x24, 0x1e, 0x0f, 0x09, 0x1e, 0x15, 0x1b, 0x22, 0x03, - 0x1e, 0x0f, 0x21, 0x1f, 0x30, 0x10, 0xfc, 0xc4, 0xec, 0xfc, 0xc4, 0xec, - 0x10, 0xee, 0x10, 0xee, 0x11, 0x39, 0x39, 0x31, 0x00, 0x10, 0xec, 0xe4, - 0xf4, 0xec, 0x10, 0xee, 0x10, 0xee, 0x39, 0x39, 0x30, 0x01, 0x22, 0x06, - 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x25, 0x2e, 0x01, - 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x07, 0x1e, 0x01, - 0x15, 0x14, 0x04, 0x23, 0x22, 0x24, 0x35, 0x34, 0x36, 0x13, 0x14, 0x16, - 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x02, 0x68, 0x87, - 0x93, 0x95, 0x85, 0x88, 0x93, 0x95, 0xfe, 0xca, 0x81, 0x91, 0xf2, 0xd0, - 0xd1, 0xf2, 0x91, 0x81, 0x96, 0x9f, 0xfe, 0xfe, 0xe4, 0xe4, 0xfe, 0xff, - 0x9f, 0x4d, 0x80, 0x79, 0x7a, 0x80, 0x7f, 0x7b, 0x79, 0x80, 0x02, 0xc5, - 0x97, 0x8a, 0x8a, 0x99, 0x97, 0x8c, 0x89, 0x98, 0x54, 0x21, 0xb4, 0x7f, - 0xb2, 0xd1, 0xd1, 0xb2, 0x7f, 0xb4, 0x21, 0x21, 0xc8, 0x9f, 0xca, 0xe4, - 0xe3, 0xc9, 0xa0, 0xc9, 0x01, 0x62, 0x78, 0x7e, 0x7e, 0x78, 0x7a, 0x80, - 0x81, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x7f, 0xff, 0xe3, 0x04, 0x46, - 0x05, 0xf0, 0x00, 0x0b, 0x00, 0x24, 0x00, 0x3b, 0x40, 0x22, 0x13, 0x06, - 0x00, 0x97, 0x16, 0xab, 0x10, 0x0d, 0x8b, 0x0c, 0x8e, 0x10, 0x97, 0x22, - 0x06, 0x97, 0x1c, 0x96, 0x22, 0x99, 0x25, 0x13, 0x06, 0x03, 0x01, 0x1f, - 0x22, 0x09, 0x1e, 0x0c, 0x26, 0x19, 0x1f, 0x25, 0x10, 0xfc, 0xe4, 0xec, - 0xfc, 0xec, 0xec, 0x31, 0x00, 0x10, 0xe4, 0xf4, 0xec, 0x10, 0xee, 0xf6, - 0xee, 0x10, 0xf5, 0xee, 0x11, 0x39, 0x30, 0x01, 0x32, 0x36, 0x35, 0x34, - 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x03, 0x35, 0x1e, 0x01, 0x33, - 0x32, 0x12, 0x11, 0x0e, 0x01, 0x23, 0x22, 0x02, 0x35, 0x34, 0x12, 0x33, - 0x20, 0x12, 0x11, 0x10, 0x00, 0x21, 0x22, 0x26, 0x02, 0x54, 0x81, 0x93, - 0x93, 0x81, 0x86, 0x88, 0x87, 0xe1, 0x3f, 0x8e, 0x4d, 0xc0, 0xc5, 0x2f, - 0xaa, 0x6e, 0xd8, 0xed, 0xf3, 0xde, 0x01, 0x04, 0xf2, 0xfe, 0xdd, 0xfe, - 0xeb, 0x49, 0x94, 0x02, 0x96, 0xba, 0xa4, 0xa4, 0xba, 0xb1, 0xad, 0xae, - 0xb0, 0xfd, 0x89, 0xba, 0x25, 0x27, 0x01, 0x21, 0x01, 0x19, 0x64, 0x6b, - 0x01, 0x0a, 0xf4, 0xf1, 0x01, 0x09, 0xfe, 0x8a, 0xfe, 0x6f, 0xfe, 0x87, - 0xfe, 0x73, 0x1f, 0x00, 0x00, 0x02, 0x01, 0xe9, 0x00, 0x00, 0x02, 0xe5, - 0x04, 0x27, 0x00, 0x03, 0x00, 0x07, 0x00, 0x1b, 0x40, 0x0d, 0x02, 0xa2, - 0x00, 0xac, 0x04, 0xa2, 0x06, 0x05, 0x01, 0x1d, 0x04, 0x00, 0x08, 0x10, - 0xd4, 0x3c, 0xec, 0x32, 0x31, 0x00, 0x2f, 0xec, 0xf4, 0xec, 0x30, 0x01, - 0x33, 0x11, 0x23, 0x11, 0x33, 0x11, 0x23, 0x01, 0xe9, 0xfc, 0xfc, 0xfc, - 0xfc, 0x04, 0x27, 0xfe, 0xd1, 0xfe, 0x39, 0xfe, 0xcf, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x01, 0x93, 0xfe, 0xe1, 0x02, 0xf2, 0x04, 0x27, 0x00, 0x05, - 0x00, 0x09, 0x00, 0x25, 0x40, 0x13, 0x08, 0xa2, 0x06, 0x03, 0xa3, 0x00, - 0xa2, 0x06, 0xac, 0x0a, 0x03, 0x04, 0x00, 0x1d, 0x01, 0x07, 0x1d, 0x06, - 0x0a, 0x10, 0xd4, 0xfc, 0xd4, 0xfc, 0xd4, 0xcc, 0x31, 0x00, 0x10, 0xe4, - 0xfc, 0xec, 0x10, 0xee, 0x30, 0x01, 0x33, 0x15, 0x03, 0x23, 0x13, 0x03, - 0x33, 0x11, 0x23, 0x01, 0xf6, 0xfc, 0xc5, 0x9a, 0x63, 0x0d, 0xfc, 0xfc, - 0x01, 0x2f, 0xcf, 0xfe, 0x81, 0x01, 0x7f, 0x03, 0xc7, 0xfe, 0xd1, 0x00, - 0x00, 0x01, 0x00, 0x58, 0x00, 0x8d, 0x04, 0x79, 0x04, 0x77, 0x00, 0x06, - 0x00, 0x21, 0x40, 0x12, 0x05, 0x04, 0x02, 0x01, 0x00, 0x05, 0x03, 0xae, - 0x06, 0xad, 0x07, 0x01, 0x02, 0x00, 0x28, 0x04, 0x27, 0x07, 0x10, 0xfc, - 0xec, 0x32, 0x39, 0x31, 0x00, 0x10, 0xf4, 0xec, 0x17, 0x39, 0x30, 0x09, - 0x02, 0x15, 0x01, 0x35, 0x01, 0x04, 0x79, 0xfc, 0xae, 0x03, 0x52, 0xfb, - 0xdf, 0x04, 0x21, 0x03, 0xc1, 0xfe, 0xc0, 0xfe, 0xc3, 0xb7, 0x01, 0xa2, - 0xa6, 0x01, 0xa2, 0x00, 0x00, 0x02, 0x00, 0x58, 0x01, 0x60, 0x04, 0x79, - 0x03, 0xa2, 0x00, 0x03, 0x00, 0x07, 0x00, 0x1b, 0x40, 0x0c, 0x04, 0xa0, - 0x06, 0x02, 0xa0, 0x00, 0x08, 0x05, 0x01, 0x04, 0x00, 0x08, 0x10, 0xd4, - 0x3c, 0xc4, 0x32, 0x31, 0x00, 0x10, 0xd4, 0xec, 0xd4, 0xec, 0x30, 0x13, - 0x21, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x58, 0x04, 0x21, 0xfb, 0xdf, - 0x04, 0x21, 0xfb, 0xdf, 0x02, 0x0c, 0xac, 0x02, 0x42, 0xaa, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x58, 0x00, 0x8d, 0x04, 0x79, 0x04, 0x77, 0x00, 0x06, - 0x00, 0x21, 0x40, 0x12, 0x06, 0x05, 0x03, 0x02, 0x00, 0x05, 0x04, 0xae, - 0x01, 0xad, 0x07, 0x06, 0x02, 0x28, 0x04, 0x00, 0x27, 0x07, 0x10, 0xfc, - 0x3c, 0xec, 0x39, 0x31, 0x00, 0x10, 0xf4, 0xec, 0x17, 0x39, 0x30, 0x13, - 0x35, 0x01, 0x15, 0x01, 0x35, 0x01, 0x58, 0x04, 0x21, 0xfb, 0xdf, 0x03, - 0x52, 0x03, 0xc1, 0xb6, 0xfe, 0x5e, 0xa6, 0xfe, 0x5e, 0xb7, 0x01, 0x3d, - 0x00, 0x02, 0x00, 0xf4, 0x00, 0x00, 0x04, 0x10, 0x05, 0xf0, 0x00, 0x1e, - 0x00, 0x22, 0x00, 0x7b, 0x40, 0x42, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x05, - 0x0c, 0x06, 0x25, 0x19, 0x1a, 0x19, 0x03, 0x04, 0x02, 0x02, 0x05, 0x25, - 0x1a, 0x1a, 0x19, 0x42, 0x1d, 0x1a, 0x05, 0x02, 0x04, 0x06, 0x19, 0x0f, - 0x00, 0x1f, 0x10, 0x8b, 0x0f, 0x8d, 0x0c, 0x97, 0x13, 0x96, 0x1f, 0x86, - 0x21, 0x06, 0x20, 0x19, 0x16, 0x09, 0x05, 0x01, 0x00, 0x1a, 0x20, 0x09, - 0x00, 0x03, 0x01, 0x09, 0x29, 0x16, 0x0f, 0x01, 0x20, 0x03, 0x1f, 0x23, - 0x10, 0xd4, 0xec, 0xc4, 0xd4, 0xd4, 0xec, 0x10, 0xee, 0x11, 0x12, 0x39, - 0x11, 0x12, 0x39, 0x11, 0x12, 0x39, 0x12, 0x39, 0x31, 0x00, 0x2f, 0xee, - 0xf6, 0xfe, 0xf4, 0xee, 0x10, 0xcd, 0x11, 0x39, 0x39, 0x17, 0x39, 0x30, - 0x4b, 0x53, 0x58, 0x07, 0x10, 0x04, 0xed, 0x11, 0x17, 0x39, 0x07, 0x10, - 0x04, 0xed, 0x11, 0x17, 0x39, 0x59, 0x22, 0x01, 0x23, 0x35, 0x34, 0x36, - 0x3f, 0x01, 0x3e, 0x01, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x35, - 0x3e, 0x01, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x0f, 0x01, 0x0e, 0x01, - 0x1d, 0x01, 0x03, 0x33, 0x15, 0x23, 0x02, 0xac, 0xbe, 0x3d, 0x54, 0x5a, - 0x3e, 0x2f, 0x83, 0x6d, 0x4e, 0xb2, 0x62, 0x5e, 0xbf, 0x68, 0xba, 0xdd, - 0x43, 0x5e, 0x58, 0x45, 0x26, 0xc5, 0xcb, 0xcb, 0x01, 0x91, 0x9a, 0x62, - 0x89, 0x52, 0x59, 0x3b, 0x58, 0x31, 0x59, 0x6e, 0x45, 0x44, 0xbc, 0x39, - 0x38, 0xc0, 0xa1, 0x4c, 0x83, 0x5c, 0x56, 0x42, 0x54, 0x3d, 0x2f, 0xfe, - 0xf2, 0xfe, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1b, 0xfe, 0xc1, 0x04, 0x9a, - 0x05, 0x73, 0x00, 0x0b, 0x00, 0x34, 0x00, 0x70, 0x40, 0x31, 0x28, 0x2b, - 0x24, 0x1a, 0x17, 0x03, 0x0e, 0x0c, 0x09, 0x1b, 0x34, 0x03, 0xaf, 0x17, - 0x09, 0xaf, 0x0c, 0x11, 0x27, 0x24, 0xaf, 0x2b, 0x17, 0x1e, 0xaf, 0x31, - 0x2b, 0x35, 0x27, 0x0d, 0x06, 0x28, 0x0c, 0x00, 0x06, 0x2b, 0x14, 0x00, - 0x1a, 0x0d, 0x2e, 0x0c, 0x14, 0x21, 0x2b, 0x0c, 0x2d, 0x2e, 0x35, 0x10, - 0xdc, 0xec, 0xfc, 0xc4, 0x10, 0xfe, 0x3c, 0xc4, 0x10, 0xee, 0x11, 0x12, - 0x39, 0x11, 0x12, 0x39, 0x31, 0x00, 0x10, 0xc4, 0xd4, 0xfc, 0xc4, 0x10, - 0xfe, 0xc4, 0xd5, 0xc4, 0xee, 0x10, 0xee, 0x39, 0x39, 0x11, 0x12, 0x39, - 0x11, 0x12, 0x39, 0x11, 0x12, 0x39, 0x30, 0x40, 0x0d, 0x80, 0x05, 0x80, - 0x06, 0x80, 0x07, 0x80, 0x13, 0x80, 0x14, 0x80, 0x15, 0x06, 0x01, 0x5d, - 0x01, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, - 0x13, 0x23, 0x35, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, - 0x32, 0x16, 0x17, 0x35, 0x34, 0x26, 0x23, 0x22, 0x00, 0x11, 0x10, 0x00, - 0x21, 0x32, 0x36, 0x37, 0x17, 0x0e, 0x01, 0x23, 0x20, 0x00, 0x11, 0x10, - 0x00, 0x21, 0x32, 0x12, 0x15, 0x04, 0x0e, 0x80, 0x6b, 0x6b, 0x81, 0x81, - 0x6b, 0x6b, 0x80, 0x8c, 0x90, 0x25, 0x83, 0x52, 0xa1, 0xd3, 0xd3, 0xa1, - 0x50, 0x86, 0x24, 0xb0, 0x91, 0xf6, 0xfe, 0xdd, 0x01, 0x4a, 0x01, 0x12, - 0x36, 0x6c, 0x39, 0x30, 0x3f, 0x7b, 0x3a, 0xfe, 0x9b, 0xfe, 0x5d, 0x01, - 0x78, 0x01, 0x3c, 0xd1, 0xfa, 0x02, 0x21, 0x81, 0x9b, 0x9b, 0x81, 0x82, - 0x9b, 0x9b, 0xfe, 0xe8, 0x6f, 0x3f, 0x44, 0xf2, 0xbc, 0xbc, 0xf2, 0x46, - 0x3d, 0x3f, 0x9c, 0xbe, 0xfe, 0x81, 0xfe, 0xb9, 0xfe, 0xb7, 0xfe, 0x7a, - 0x14, 0x15, 0x87, 0x19, 0x18, 0x01, 0xd2, 0x01, 0x8c, 0x01, 0x86, 0x01, - 0xce, 0xfe, 0xf6, 0xe0, 0x00, 0x02, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, - 0x05, 0xd5, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x98, 0x40, 0x41, 0x00, 0x25, - 0x01, 0x00, 0x04, 0x05, 0x04, 0x02, 0x25, 0x05, 0x04, 0x07, 0x25, 0x05, - 0x04, 0x06, 0x25, 0x05, 0x05, 0x04, 0x09, 0x25, 0x03, 0x0a, 0x08, 0x25, - 0x03, 0x0a, 0x01, 0x25, 0x0a, 0x03, 0x0a, 0x00, 0x25, 0x02, 0x00, 0x03, - 0x03, 0x0a, 0x42, 0x00, 0x03, 0x07, 0x97, 0x01, 0xb0, 0x03, 0x88, 0x09, - 0x05, 0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x02, 0x01, 0x00, 0x09, 0x05, - 0x2f, 0x0a, 0x0b, 0x10, 0xdc, 0xec, 0x17, 0x39, 0x31, 0x00, 0x2f, 0x3c, - 0xe4, 0xfc, 0xec, 0x12, 0x39, 0x30, 0x4b, 0x53, 0x58, 0x07, 0x10, 0x08, - 0xed, 0x07, 0x10, 0x05, 0xed, 0x07, 0x05, 0xed, 0x07, 0x05, 0xed, 0x07, - 0x10, 0x05, 0xed, 0x07, 0x05, 0xed, 0x07, 0x05, 0xed, 0x07, 0x10, 0x08, - 0xed, 0x59, 0x22, 0xb2, 0x07, 0x03, 0x01, 0x01, 0x5d, 0x40, 0x1a, 0x0a, - 0x00, 0x0f, 0x00, 0x8f, 0x00, 0x8f, 0x00, 0x04, 0x03, 0x01, 0x0b, 0x02, - 0x04, 0x03, 0x0c, 0x04, 0x09, 0x07, 0x06, 0x08, 0x86, 0x01, 0x89, 0x02, - 0x08, 0x5d, 0x00, 0x5d, 0x01, 0x03, 0x21, 0x01, 0x33, 0x01, 0x23, 0x03, - 0x21, 0x03, 0x23, 0x02, 0x68, 0xd5, 0x01, 0xaa, 0xfe, 0xb1, 0xf5, 0x01, - 0xc9, 0xd1, 0x6e, 0xfd, 0xf5, 0x6c, 0xd1, 0x05, 0x23, 0xfd, 0x04, 0x03, - 0xae, 0xfa, 0x2b, 0x01, 0x85, 0xfe, 0x7b, 0x00, 0x00, 0x03, 0x00, 0xa6, - 0x00, 0x00, 0x04, 0x71, 0x05, 0xd5, 0x00, 0x08, 0x00, 0x11, 0x00, 0x20, - 0x00, 0x3d, 0x40, 0x23, 0x19, 0x00, 0x97, 0x0a, 0x09, 0x97, 0x12, 0x88, - 0x01, 0x97, 0x0a, 0xb1, 0x1f, 0x11, 0x0b, 0x19, 0x1f, 0x13, 0x08, 0x02, - 0x05, 0x00, 0x0e, 0x1e, 0x16, 0x05, 0x32, 0x1c, 0x31, 0x09, 0x00, 0x1e, - 0x12, 0x30, 0x21, 0x10, 0xfc, 0xec, 0x32, 0xfc, 0xec, 0xd4, 0xec, 0x11, - 0x17, 0x39, 0x39, 0x39, 0x31, 0x00, 0x2f, 0xec, 0xec, 0xf4, 0xec, 0x10, - 0xee, 0x39, 0x30, 0x01, 0x11, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, - 0x03, 0x11, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x25, 0x21, 0x32, - 0x16, 0x15, 0x14, 0x06, 0x07, 0x1e, 0x01, 0x15, 0x14, 0x04, 0x29, 0x01, - 0x01, 0x71, 0xef, 0xb0, 0x96, 0x9e, 0xa8, 0xef, 0xeb, 0x92, 0x83, 0x81, - 0x94, 0xfe, 0x4a, 0x01, 0xba, 0xe5, 0xf8, 0x83, 0x83, 0x93, 0xa7, 0xfe, - 0xf6, 0xfe, 0xf9, 0xfe, 0x46, 0x02, 0xc9, 0xfd, 0xdd, 0x7b, 0x8d, 0x92, - 0x89, 0x02, 0x66, 0xfe, 0x3e, 0x70, 0x7d, 0x71, 0x64, 0xa6, 0xc6, 0xb5, - 0x89, 0x9e, 0x14, 0x16, 0xcf, 0xa0, 0xcb, 0xcf, 0x00, 0x01, 0x00, 0x8b, - 0xff, 0xe3, 0x04, 0x31, 0x05, 0xf0, 0x00, 0x19, 0x00, 0x2e, 0x40, 0x1a, - 0x19, 0xb3, 0x00, 0xb2, 0x16, 0x97, 0x03, 0x0d, 0xb3, 0x0c, 0xb2, 0x10, - 0x97, 0x09, 0x96, 0x03, 0x99, 0x1a, 0x13, 0x32, 0x0c, 0x00, 0x31, 0x06, - 0x30, 0x1a, 0x10, 0xfc, 0xec, 0x32, 0xec, 0x31, 0x00, 0x10, 0xe4, 0xf4, - 0xec, 0xf4, 0xec, 0x10, 0xee, 0xf6, 0xee, 0x30, 0x25, 0x0e, 0x01, 0x23, - 0x20, 0x00, 0x11, 0x10, 0x00, 0x21, 0x32, 0x16, 0x17, 0x15, 0x2e, 0x01, - 0x23, 0x22, 0x02, 0x11, 0x10, 0x12, 0x33, 0x32, 0x36, 0x37, 0x04, 0x31, - 0x4d, 0xa2, 0x5b, 0xfe, 0xe1, 0xfe, 0xc3, 0x01, 0x3f, 0x01, 0x1d, 0x5b, - 0xa2, 0x4d, 0x4a, 0xaa, 0x56, 0xc5, 0xc4, 0xc4, 0xc5, 0x58, 0xa9, 0x49, - 0x35, 0x29, 0x29, 0x01, 0x96, 0x01, 0x70, 0x01, 0x6e, 0x01, 0x99, 0x29, - 0x29, 0xcf, 0x3d, 0x40, 0xfe, 0xd0, 0xfe, 0xcd, 0xfe, 0xce, 0xfe, 0xd0, - 0x40, 0x3d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x89, 0x00, 0x00, 0x04, 0x52, - 0x05, 0xd5, 0x00, 0x08, 0x00, 0x11, 0x00, 0x28, 0x40, 0x15, 0x06, 0x97, - 0x09, 0x88, 0x00, 0x97, 0x0f, 0x06, 0x00, 0x0f, 0x09, 0x07, 0x03, 0x32, - 0x0c, 0x31, 0x07, 0x1e, 0x10, 0x30, 0x12, 0x10, 0xfc, 0xec, 0xfc, 0xec, - 0x11, 0x39, 0x39, 0x39, 0x39, 0x31, 0x00, 0x2f, 0xec, 0xf4, 0xec, 0x30, - 0x25, 0x20, 0x36, 0x11, 0x10, 0x26, 0x21, 0x23, 0x11, 0x13, 0x20, 0x00, - 0x11, 0x10, 0x00, 0x29, 0x01, 0x11, 0x01, 0xb4, 0x00, 0xff, 0xca, 0xc9, - 0xff, 0x00, 0x60, 0x64, 0x01, 0x56, 0x01, 0x44, 0xfe, 0xbc, 0xfe, 0xaa, - 0xfe, 0xd1, 0xa6, 0xfb, 0x01, 0x48, 0x01, 0x4b, 0xfb, 0xfb, 0x77, 0x05, - 0x2f, 0xfe, 0x94, 0xfe, 0x80, 0xfe, 0x82, 0xfe, 0x95, 0x05, 0xd5, 0x00, - 0x00, 0x01, 0x00, 0xc5, 0x00, 0x00, 0x04, 0x4e, 0x05, 0xd5, 0x00, 0x0b, - 0x00, 0x29, 0x40, 0x16, 0x06, 0x97, 0x04, 0x02, 0x97, 0x00, 0x88, 0x08, - 0x97, 0x04, 0xb1, 0x0a, 0x01, 0x05, 0x09, 0x31, 0x07, 0x03, 0x1e, 0x00, - 0x33, 0x0c, 0x10, 0xfc, 0xec, 0x32, 0xfc, 0xc4, 0xc4, 0x31, 0x00, 0x2f, - 0xec, 0xec, 0xf4, 0xec, 0x10, 0xee, 0x30, 0x13, 0x21, 0x15, 0x21, 0x11, - 0x21, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0xc5, 0x03, 0x76, 0xfd, 0x54, - 0x02, 0x8e, 0xfd, 0x72, 0x02, 0xbf, 0xfc, 0x77, 0x05, 0xd5, 0xaa, 0xfe, - 0x46, 0xaa, 0xfd, 0xe3, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xe9, - 0x00, 0x00, 0x04, 0x58, 0x05, 0xd5, 0x00, 0x09, 0x00, 0x24, 0x40, 0x13, - 0x06, 0x97, 0x04, 0x02, 0x97, 0x00, 0x88, 0x04, 0xb1, 0x08, 0x05, 0x01, - 0x31, 0x07, 0x03, 0x1e, 0x00, 0x34, 0x0a, 0x10, 0xfc, 0xec, 0x32, 0xfc, - 0xc4, 0x31, 0x00, 0x2f, 0xec, 0xf4, 0xec, 0x10, 0xee, 0x30, 0x13, 0x21, - 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x11, 0x23, 0xe9, 0x03, 0x6f, 0xfd, - 0x5c, 0x02, 0x65, 0xfd, 0x9b, 0xcb, 0x05, 0xd5, 0xaa, 0xfe, 0x48, 0xaa, - 0xfd, 0x37, 0x00, 0x00, 0x00, 0x01, 0x00, 0x66, 0xff, 0xe3, 0x04, 0x50, - 0x05, 0xf0, 0x00, 0x1d, 0x00, 0x3c, 0x40, 0x21, 0x19, 0x1a, 0x00, 0x16, - 0x03, 0x1a, 0x97, 0x1c, 0x16, 0x97, 0x03, 0x0d, 0xb3, 0x0c, 0xb2, 0x10, - 0x97, 0x09, 0x96, 0x03, 0x99, 0x1e, 0x1b, 0x19, 0x1e, 0x0c, 0x00, 0x36, - 0x13, 0x32, 0x06, 0x35, 0x1e, 0x10, 0xfc, 0xec, 0xfc, 0xc4, 0xfc, 0xc4, - 0x31, 0x00, 0x10, 0xe4, 0xf4, 0xec, 0xf4, 0xec, 0x10, 0xfe, 0xd4, 0xee, - 0x11, 0x12, 0x39, 0x11, 0x39, 0x30, 0x25, 0x0e, 0x01, 0x23, 0x20, 0x00, - 0x11, 0x10, 0x00, 0x21, 0x32, 0x16, 0x17, 0x15, 0x2e, 0x01, 0x23, 0x22, - 0x02, 0x11, 0x10, 0x12, 0x33, 0x32, 0x36, 0x37, 0x11, 0x23, 0x35, 0x21, - 0x04, 0x50, 0x51, 0xcb, 0x76, 0xfe, 0xe4, 0xfe, 0xc4, 0x01, 0x40, 0x01, - 0x1d, 0x5e, 0xac, 0x50, 0x51, 0xaa, 0x5f, 0xc5, 0xc5, 0xbf, 0xc6, 0x43, - 0x65, 0x29, 0xd9, 0x01, 0x9a, 0x7b, 0x4b, 0x4d, 0x01, 0x97, 0x01, 0x6f, - 0x01, 0x6e, 0x01, 0x99, 0x35, 0x36, 0xcf, 0x4d, 0x49, 0xfe, 0xcf, 0xfe, - 0xce, 0xfe, 0xc9, 0xfe, 0xd5, 0x1f, 0x21, 0x01, 0x91, 0xa6, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x89, 0x00, 0x00, 0x04, 0x48, 0x05, 0xd5, 0x00, 0x0b, - 0x00, 0x26, 0x40, 0x14, 0x08, 0x97, 0x02, 0xb1, 0x04, 0x00, 0x88, 0x0a, - 0x06, 0x07, 0x03, 0x1e, 0x05, 0x31, 0x09, 0x01, 0x1e, 0x00, 0x30, 0x0c, - 0x10, 0xfc, 0xec, 0x32, 0xfc, 0xec, 0x32, 0x31, 0x00, 0x2f, 0x3c, 0xe4, - 0x32, 0xfc, 0xec, 0x30, 0x13, 0x33, 0x11, 0x21, 0x11, 0x33, 0x11, 0x23, - 0x11, 0x21, 0x11, 0x23, 0x89, 0xcb, 0x02, 0x29, 0xcb, 0xcb, 0xfd, 0xd7, - 0xcb, 0x05, 0xd5, 0xfd, 0x9c, 0x02, 0x64, 0xfa, 0x2b, 0x02, 0xc7, 0xfd, - 0x39, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc9, 0x00, 0x00, 0x04, 0x06, - 0x05, 0xd5, 0x00, 0x0b, 0x00, 0x25, 0x40, 0x13, 0x0a, 0x02, 0x97, 0x00, - 0x88, 0x08, 0x04, 0x97, 0x06, 0x05, 0x01, 0x37, 0x03, 0x1e, 0x07, 0x00, - 0x37, 0x09, 0x0c, 0x10, 0xd4, 0xec, 0x32, 0xfc, 0xec, 0x32, 0x31, 0x00, - 0x2f, 0xec, 0x32, 0xf4, 0xec, 0x32, 0x30, 0x13, 0x21, 0x15, 0x21, 0x11, - 0x21, 0x15, 0x21, 0x35, 0x21, 0x11, 0x21, 0xc9, 0x03, 0x3d, 0xfe, 0xc7, - 0x01, 0x39, 0xfc, 0xc3, 0x01, 0x39, 0xfe, 0xc7, 0x05, 0xd5, 0xaa, 0xfb, - 0x7f, 0xaa, 0xaa, 0x04, 0x81, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x6d, - 0xff, 0xe3, 0x03, 0xbc, 0x05, 0xd5, 0x00, 0x11, 0x00, 0x2c, 0x40, 0x17, - 0x0c, 0x07, 0x08, 0x01, 0x00, 0xb2, 0x04, 0x97, 0x0f, 0x08, 0x97, 0x0a, - 0x88, 0x0f, 0x99, 0x12, 0x09, 0x07, 0x1e, 0x0b, 0x00, 0x35, 0x12, 0x10, - 0xfc, 0xd4, 0xfc, 0xc4, 0x31, 0x00, 0x10, 0xe4, 0xf4, 0xec, 0x10, 0xee, - 0xf6, 0xce, 0x11, 0x39, 0x39, 0x30, 0x37, 0x35, 0x1e, 0x01, 0x33, 0x32, - 0x36, 0x35, 0x11, 0x21, 0x35, 0x21, 0x11, 0x10, 0x06, 0x23, 0x22, 0x26, - 0x6d, 0x5b, 0xc2, 0x68, 0x8f, 0x71, 0xfe, 0x83, 0x02, 0x47, 0xd3, 0xf7, - 0x60, 0xbe, 0x3d, 0xec, 0x51, 0x51, 0x95, 0xcb, 0x03, 0x44, 0xaa, 0xfc, - 0x12, 0xfe, 0xe6, 0xea, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x89, - 0x00, 0x00, 0x04, 0xc9, 0x05, 0xd5, 0x00, 0x0b, 0x00, 0x97, 0x40, 0x21, - 0x08, 0x25, 0x09, 0x08, 0x05, 0x06, 0x05, 0x07, 0x25, 0x06, 0x05, 0x42, - 0x08, 0x05, 0x02, 0x03, 0x03, 0x00, 0xb4, 0x0a, 0x06, 0x08, 0x05, 0x04, - 0x03, 0x06, 0x01, 0x09, 0x01, 0x1e, 0x00, 0x30, 0x0c, 0x10, 0xfc, 0xec, - 0x32, 0x10, 0xc0, 0x17, 0x39, 0x31, 0x00, 0x2f, 0x3c, 0xec, 0x32, 0x17, - 0x39, 0x30, 0x4b, 0x53, 0x58, 0x07, 0x05, 0xed, 0x07, 0x10, 0x08, 0xed, - 0x59, 0x22, 0xb2, 0x08, 0x04, 0x01, 0x01, 0x5d, 0x40, 0x4c, 0x07, 0x05, - 0x16, 0x05, 0x17, 0x08, 0x26, 0x05, 0x26, 0x08, 0x36, 0x02, 0x46, 0x02, - 0x55, 0x02, 0x57, 0x08, 0x58, 0x09, 0x64, 0x02, 0x7a, 0x05, 0x79, 0x08, - 0x7b, 0x09, 0x0e, 0x02, 0x03, 0x01, 0x04, 0x07, 0x05, 0x00, 0x06, 0x02, - 0x07, 0x16, 0x05, 0x17, 0x08, 0x27, 0x05, 0x2c, 0x06, 0x2b, 0x07, 0x26, - 0x08, 0x3a, 0x03, 0x49, 0x03, 0x47, 0x06, 0x47, 0x07, 0x5b, 0x03, 0x57, - 0x05, 0x58, 0x06, 0x58, 0x07, 0x57, 0x08, 0x6b, 0x03, 0x7a, 0x03, 0x78, - 0x07, 0x17, 0x5d, 0x00, 0x5d, 0x13, 0x33, 0x11, 0x01, 0x33, 0x09, 0x01, - 0x23, 0x01, 0x07, 0x11, 0x23, 0x89, 0xcb, 0x02, 0x77, 0xed, 0xfd, 0xbb, - 0x02, 0x56, 0xf4, 0xfe, 0x19, 0x9a, 0xcb, 0x05, 0xd5, 0xfd, 0x68, 0x02, - 0x98, 0xfd, 0x9e, 0xfc, 0x8d, 0x02, 0xec, 0xa4, 0xfd, 0xb8, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xd7, 0x00, 0x00, 0x04, 0x73, 0x05, 0xd5, 0x00, 0x05, - 0x00, 0x18, 0x40, 0x0c, 0x02, 0x97, 0x00, 0x88, 0x04, 0x01, 0x1e, 0x03, - 0x31, 0x00, 0x34, 0x06, 0x10, 0xfc, 0xec, 0xec, 0x31, 0x00, 0x2f, 0xe4, - 0xec, 0x30, 0x13, 0x33, 0x11, 0x21, 0x15, 0x21, 0xd7, 0xcb, 0x02, 0xd1, - 0xfc, 0x64, 0x05, 0xd5, 0xfa, 0xd5, 0xaa, 0x00, 0x00, 0x01, 0x00, 0x56, - 0x00, 0x00, 0x04, 0x79, 0x05, 0xd5, 0x00, 0x0c, 0x00, 0x85, 0x40, 0x2c, - 0x08, 0x02, 0x03, 0x02, 0x07, 0x03, 0x03, 0x02, 0x0a, 0x01, 0x02, 0x01, - 0x09, 0x02, 0x02, 0x01, 0x42, 0x0a, 0x07, 0x02, 0x03, 0x00, 0x08, 0x03, - 0x00, 0xb4, 0x0b, 0x05, 0x09, 0x08, 0x03, 0x02, 0x01, 0x05, 0x0a, 0x06, - 0x06, 0x04, 0x2f, 0x0a, 0x06, 0x00, 0x30, 0x0d, 0x10, 0xfc, 0xec, 0xfc, - 0xec, 0x11, 0x17, 0x39, 0x31, 0x00, 0x2f, 0x3c, 0xec, 0x32, 0xc4, 0x11, - 0x17, 0x39, 0x30, 0x4b, 0x53, 0x58, 0x07, 0x10, 0x05, 0xc9, 0x07, 0x10, - 0x04, 0xc9, 0x07, 0x10, 0x04, 0xc9, 0x07, 0x10, 0x05, 0xc9, 0x59, 0x22, - 0xb2, 0x0f, 0x0a, 0x01, 0x00, 0x5d, 0x40, 0x24, 0x05, 0x08, 0x0a, 0x09, - 0x17, 0x01, 0x18, 0x03, 0x17, 0x08, 0x18, 0x09, 0x26, 0x01, 0x29, 0x03, - 0x26, 0x08, 0x29, 0x09, 0x36, 0x01, 0x39, 0x03, 0x36, 0x08, 0x38, 0x09, - 0x0e, 0x0f, 0x07, 0x0f, 0x07, 0x0f, 0x0a, 0x03, 0x5d, 0x01, 0x5d, 0x13, - 0x21, 0x09, 0x01, 0x21, 0x11, 0x23, 0x11, 0x01, 0x23, 0x01, 0x11, 0x23, - 0x56, 0x01, 0x0e, 0x01, 0x02, 0x01, 0x04, 0x01, 0x0f, 0xbb, 0xfe, 0xf6, - 0x99, 0xfe, 0xf5, 0xba, 0x05, 0xd5, 0xfd, 0x08, 0x02, 0xf8, 0xfa, 0x2b, - 0x05, 0x27, 0xfc, 0xed, 0x03, 0x13, 0xfa, 0xd9, 0x00, 0x01, 0x00, 0x8b, - 0x00, 0x00, 0x04, 0x46, 0x05, 0xd5, 0x00, 0x09, 0x00, 0x6d, 0x40, 0x1c, - 0x07, 0x01, 0x02, 0x01, 0x02, 0x06, 0x07, 0x06, 0x42, 0x07, 0x02, 0x03, - 0x00, 0xb4, 0x08, 0x05, 0x06, 0x01, 0x07, 0x02, 0x11, 0x04, 0x31, 0x07, - 0x11, 0x00, 0x30, 0x0a, 0x10, 0xfc, 0xec, 0xfc, 0xec, 0x11, 0x39, 0x39, - 0x31, 0x00, 0x2f, 0x3c, 0xec, 0x32, 0x39, 0x39, 0x30, 0x4b, 0x53, 0x58, - 0x07, 0x10, 0x04, 0xc9, 0x07, 0x10, 0x04, 0xc9, 0x59, 0x22, 0xb2, 0x17, - 0x01, 0x01, 0x01, 0x5d, 0x40, 0x26, 0x17, 0x02, 0x18, 0x07, 0x29, 0x02, - 0x26, 0x07, 0x38, 0x07, 0x57, 0x02, 0x64, 0x02, 0x6a, 0x07, 0x75, 0x02, - 0x7a, 0x07, 0x0a, 0x18, 0x06, 0x26, 0x01, 0x29, 0x06, 0x46, 0x01, 0x49, - 0x06, 0x57, 0x01, 0x67, 0x01, 0x68, 0x06, 0x08, 0x5d, 0x00, 0x5d, 0x13, - 0x21, 0x01, 0x11, 0x33, 0x11, 0x21, 0x01, 0x11, 0x23, 0x8b, 0x01, 0x00, - 0x01, 0xf8, 0xc3, 0xff, 0x00, 0xfe, 0x08, 0xc3, 0x05, 0xd5, 0xfb, 0x33, - 0x04, 0xcd, 0xfa, 0x2b, 0x04, 0xcd, 0xfb, 0x33, 0x00, 0x02, 0x00, 0x75, - 0xff, 0xe3, 0x04, 0x5c, 0x05, 0xf0, 0x00, 0x0b, 0x00, 0x17, 0x00, 0x23, - 0x40, 0x13, 0x09, 0x97, 0x0f, 0x03, 0x97, 0x15, 0x96, 0x0f, 0x99, 0x18, - 0x00, 0x32, 0x0c, 0x36, 0x06, 0x32, 0x12, 0x35, 0x18, 0x10, 0xfc, 0xec, - 0xfc, 0xec, 0x31, 0x00, 0x10, 0xe4, 0xf4, 0xec, 0x10, 0xee, 0x30, 0x01, - 0x10, 0x02, 0x23, 0x22, 0x02, 0x11, 0x10, 0x12, 0x33, 0x32, 0x12, 0x13, - 0x10, 0x02, 0x23, 0x22, 0x02, 0x11, 0x10, 0x12, 0x33, 0x32, 0x12, 0x03, - 0x89, 0x87, 0x9a, 0x99, 0x87, 0x87, 0x99, 0x9a, 0x87, 0xd3, 0xf7, 0xfd, - 0xfd, 0xf6, 0xf7, 0xfc, 0xfd, 0xf7, 0x02, 0xe9, 0x01, 0x49, 0x01, 0x1a, - 0xfe, 0xe6, 0xfe, 0xb7, 0xfe, 0xb8, 0xfe, 0xe6, 0x01, 0x19, 0x01, 0x49, - 0xfe, 0x7a, 0xfe, 0x80, 0x01, 0x7e, 0x01, 0x88, 0x01, 0x87, 0x01, 0x80, - 0xfe, 0x80, 0x00, 0x00, 0x00, 0x02, 0x00, 0xc5, 0x00, 0x00, 0x04, 0x75, - 0x05, 0xd5, 0x00, 0x08, 0x00, 0x13, 0x00, 0x2b, 0x40, 0x18, 0x01, 0x97, - 0x10, 0x00, 0x97, 0x09, 0x88, 0x12, 0x10, 0x0a, 0x08, 0x02, 0x04, 0x00, - 0x05, 0x32, 0x0d, 0x38, 0x11, 0x00, 0x1e, 0x09, 0x33, 0x14, 0x10, 0xfc, - 0xec, 0x32, 0xfc, 0xec, 0x11, 0x17, 0x39, 0x31, 0x00, 0x2f, 0xf4, 0xec, - 0xd4, 0xec, 0x30, 0x01, 0x11, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, - 0x25, 0x21, 0x32, 0x04, 0x15, 0x14, 0x04, 0x2b, 0x01, 0x11, 0x23, 0x01, - 0x8f, 0xea, 0x8c, 0x9d, 0x9c, 0x8d, 0xfe, 0x4c, 0x01, 0xb4, 0xfa, 0x01, - 0x02, 0xfe, 0xff, 0xfb, 0xea, 0xca, 0x05, 0x2f, 0xfd, 0xcf, 0x94, 0x85, - 0x85, 0x93, 0xa6, 0xe3, 0xdb, 0xdd, 0xe2, 0xfd, 0xa8, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x75, 0xfe, 0xf2, 0x04, 0x5c, 0x05, 0xf0, 0x00, 0x11, - 0x00, 0x1d, 0x00, 0x3d, 0x40, 0x20, 0x00, 0x1e, 0x10, 0x11, 0x0f, 0x1b, - 0x97, 0x03, 0x15, 0x97, 0x09, 0x96, 0x03, 0x99, 0x11, 0x1e, 0x11, 0x18, - 0x10, 0x0c, 0x0f, 0x00, 0x18, 0x12, 0x32, 0x0c, 0x36, 0x18, 0x32, 0x06, - 0x35, 0x1e, 0x10, 0xfc, 0xec, 0xfc, 0xec, 0x11, 0x39, 0x39, 0x11, 0x39, - 0x11, 0x39, 0x31, 0x00, 0x10, 0xc4, 0xe4, 0xf4, 0xec, 0x10, 0xee, 0x39, - 0x12, 0x39, 0x12, 0x39, 0x30, 0x05, 0x22, 0x06, 0x23, 0x22, 0x02, 0x11, - 0x10, 0x12, 0x33, 0x32, 0x12, 0x11, 0x10, 0x02, 0x07, 0x17, 0x07, 0x13, - 0x10, 0x02, 0x23, 0x22, 0x02, 0x11, 0x10, 0x12, 0x33, 0x32, 0x12, 0x02, - 0x8f, 0x07, 0x1a, 0x08, 0xfa, 0xf7, 0xf7, 0xfc, 0xfd, 0xf7, 0x89, 0x8b, - 0xc8, 0x97, 0x10, 0x87, 0x9a, 0x99, 0x87, 0x87, 0x99, 0x9a, 0x87, 0x1b, - 0x02, 0x01, 0x80, 0x01, 0x86, 0x01, 0x87, 0x01, 0x80, 0xfe, 0x80, 0xfe, - 0x79, 0xfe, 0xda, 0xfe, 0x99, 0x48, 0xbe, 0x64, 0x03, 0xf7, 0x01, 0x49, - 0x01, 0x1a, 0xfe, 0xe6, 0xfe, 0xb7, 0xfe, 0xb8, 0xfe, 0xe6, 0x01, 0x19, - 0x00, 0x02, 0x00, 0x8f, 0x00, 0x00, 0x04, 0xd1, 0x05, 0xd5, 0x00, 0x13, - 0x00, 0x1c, 0x00, 0x6a, 0x40, 0x38, 0x09, 0x08, 0x07, 0x03, 0x0a, 0x06, - 0x25, 0x03, 0x04, 0x03, 0x05, 0x25, 0x04, 0x04, 0x03, 0x42, 0x06, 0x04, - 0x00, 0x15, 0x03, 0x04, 0x15, 0x97, 0x09, 0x14, 0x97, 0x0d, 0x88, 0x0b, - 0x04, 0x05, 0x11, 0x16, 0x09, 0x06, 0x03, 0x0a, 0x03, 0x11, 0x00, 0x1c, - 0x0e, 0x03, 0x0a, 0x19, 0x32, 0x04, 0x11, 0x31, 0x14, 0x0a, 0x1e, 0x0c, - 0x30, 0x1d, 0x10, 0xfc, 0xec, 0x32, 0xfc, 0xc4, 0xec, 0x11, 0x17, 0x39, - 0x11, 0x39, 0x11, 0x17, 0x39, 0x11, 0x39, 0x31, 0x00, 0x2f, 0x3c, 0xf4, - 0xec, 0xd4, 0xec, 0x12, 0x39, 0x12, 0x39, 0x12, 0x39, 0x30, 0x4b, 0x53, - 0x58, 0x07, 0x10, 0x05, 0xed, 0x07, 0x10, 0x0e, 0xed, 0x11, 0x17, 0x39, - 0x59, 0x22, 0x01, 0x1e, 0x01, 0x17, 0x13, 0x23, 0x03, 0x2e, 0x01, 0x2b, - 0x01, 0x11, 0x23, 0x11, 0x21, 0x32, 0x04, 0x15, 0x14, 0x06, 0x01, 0x11, - 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x02, 0xf8, 0x4e, 0x6e, 0x52, - 0xcb, 0xd9, 0xb2, 0x4d, 0x7b, 0x63, 0xc1, 0xcb, 0x01, 0xa0, 0xf6, 0x01, - 0x06, 0xa1, 0xfd, 0xd0, 0xdd, 0x91, 0x8e, 0x97, 0x90, 0x02, 0xc1, 0x14, - 0x6f, 0xa6, 0xfe, 0x68, 0x01, 0x79, 0xa1, 0x5d, 0xfd, 0x89, 0x05, 0xd5, - 0xde, 0xd2, 0x94, 0xbb, 0x02, 0x59, 0xfd, 0xee, 0x82, 0x86, 0x81, 0x89, - 0x00, 0x01, 0x00, 0x8b, 0xff, 0xe3, 0x04, 0x4a, 0x05, 0xf0, 0x00, 0x27, - 0x00, 0x84, 0x40, 0x3d, 0x0d, 0x0c, 0x02, 0x0e, 0x0b, 0x25, 0x1e, 0x1f, - 0x1e, 0x08, 0x09, 0x02, 0x07, 0x0a, 0x25, 0x1f, 0x1f, 0x1e, 0x42, 0x0a, - 0x0b, 0x1e, 0x1f, 0x04, 0x01, 0x15, 0xb3, 0x14, 0xa7, 0x18, 0x97, 0x11, - 0x01, 0xb3, 0x00, 0xa7, 0x04, 0x97, 0x25, 0x96, 0x11, 0x99, 0x28, 0x1e, - 0x0a, 0x0b, 0x1f, 0x1b, 0x07, 0x00, 0x26, 0x1b, 0x39, 0x0e, 0x31, 0x14, - 0x07, 0x39, 0x22, 0x30, 0x28, 0x10, 0xfc, 0xec, 0xc4, 0xfc, 0xec, 0xe4, - 0x11, 0x12, 0x39, 0x39, 0x39, 0x39, 0x31, 0x00, 0x10, 0xe4, 0xf4, 0xec, - 0xf4, 0xec, 0x10, 0xee, 0xf6, 0xee, 0x11, 0x17, 0x39, 0x30, 0x4b, 0x53, - 0x58, 0x07, 0x10, 0x0e, 0xed, 0x11, 0x17, 0x39, 0x07, 0x10, 0x0e, 0xed, - 0x11, 0x17, 0x39, 0x59, 0x22, 0xb2, 0x08, 0x02, 0x01, 0x01, 0x5d, 0x40, - 0x0a, 0x07, 0x00, 0x07, 0x01, 0x07, 0x02, 0x03, 0x07, 0x02, 0x01, 0x5d, - 0x00, 0x5d, 0x01, 0x15, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, - 0x1f, 0x01, 0x1e, 0x01, 0x15, 0x14, 0x04, 0x23, 0x22, 0x26, 0x27, 0x35, - 0x1e, 0x01, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x2f, 0x01, 0x2e, 0x01, - 0x35, 0x34, 0x24, 0x33, 0x32, 0x16, 0x03, 0xf4, 0x5c, 0xb9, 0x5e, 0x8f, - 0xa6, 0x6d, 0x95, 0x6a, 0xd2, 0xc0, 0xfe, 0xf8, 0xfc, 0x69, 0xd4, 0x6b, - 0x73, 0xcd, 0x68, 0x99, 0xaa, 0x75, 0x91, 0x6c, 0xd0, 0xbc, 0x01, 0x0d, - 0xdf, 0x56, 0xbe, 0x05, 0xa2, 0xcd, 0x3b, 0x3c, 0x85, 0x71, 0x63, 0x68, - 0x23, 0x18, 0x31, 0xd2, 0xb5, 0xd5, 0xe0, 0x2d, 0x2d, 0xd7, 0x49, 0x44, - 0x89, 0x7b, 0x70, 0x76, 0x20, 0x19, 0x2f, 0xbe, 0xa0, 0xc8, 0xf1, 0x27, - 0x00, 0x01, 0x00, 0x2f, 0x00, 0x00, 0x04, 0xa2, 0x05, 0xd5, 0x00, 0x07, - 0x00, 0x1c, 0x40, 0x0e, 0x06, 0x02, 0x97, 0x00, 0x88, 0x04, 0x01, 0x3a, - 0x03, 0x1e, 0x00, 0x3a, 0x05, 0x08, 0x10, 0xd4, 0xec, 0xfc, 0xec, 0x31, - 0x00, 0x2f, 0xf4, 0xec, 0x32, 0x30, 0x13, 0x21, 0x15, 0x21, 0x11, 0x23, - 0x11, 0x21, 0x2f, 0x04, 0x73, 0xfe, 0x2d, 0xcb, 0xfe, 0x2b, 0x05, 0xd5, - 0xaa, 0xfa, 0xd5, 0x05, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x93, - 0xff, 0xe3, 0x04, 0x3d, 0x05, 0xd5, 0x00, 0x1d, 0x00, 0x29, 0x40, 0x17, - 0x0f, 0x03, 0x12, 0x00, 0x04, 0x01, 0x09, 0x97, 0x18, 0x99, 0x10, 0x01, - 0x88, 0x1e, 0x0f, 0x1e, 0x11, 0x31, 0x02, 0x1e, 0x00, 0x30, 0x1e, 0x10, - 0xfc, 0xec, 0xfc, 0xec, 0x31, 0x00, 0x10, 0xe4, 0x32, 0xf4, 0xec, 0x11, - 0x17, 0x39, 0x30, 0x13, 0x11, 0x33, 0x11, 0x14, 0x16, 0x17, 0x1e, 0x01, - 0x33, 0x32, 0x36, 0x37, 0x3e, 0x01, 0x35, 0x11, 0x33, 0x11, 0x14, 0x06, - 0x07, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x27, 0x2e, 0x01, 0x93, 0xcb, 0x0c, - 0x0f, 0x20, 0x79, 0x56, 0x57, 0x78, 0x21, 0x0f, 0x0c, 0xca, 0x39, 0x46, - 0x42, 0xaa, 0x6a, 0x69, 0xaa, 0x43, 0x45, 0x3a, 0x02, 0x3d, 0x03, 0x98, - 0xfc, 0x0c, 0x6d, 0x5d, 0x19, 0x3b, 0x3c, 0x3c, 0x3b, 0x19, 0x5c, 0x6c, - 0x03, 0xf6, 0xfc, 0x68, 0xe5, 0xc1, 0x3f, 0x3b, 0x3a, 0x3a, 0x3b, 0x3e, - 0xc5, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x39, 0x00, 0x00, 0x04, 0x98, - 0x05, 0xd5, 0x00, 0x06, 0x00, 0x4c, 0x40, 0x29, 0x01, 0x25, 0x02, 0x03, - 0x02, 0x00, 0x25, 0x06, 0x00, 0x03, 0x03, 0x02, 0x00, 0x25, 0x01, 0x00, - 0x04, 0x05, 0x04, 0x06, 0x25, 0x05, 0x05, 0x04, 0x42, 0x00, 0x05, 0x01, - 0xb4, 0x03, 0x06, 0x04, 0x03, 0x01, 0x00, 0x05, 0x02, 0x2f, 0x05, 0x30, - 0x07, 0x10, 0xfc, 0xec, 0x17, 0x39, 0x31, 0x00, 0x2f, 0xec, 0x32, 0x39, - 0x30, 0x4b, 0x53, 0x58, 0x07, 0x10, 0x05, 0xed, 0x07, 0x10, 0x08, 0xed, - 0x07, 0x10, 0x08, 0xed, 0x07, 0x10, 0x05, 0xed, 0x59, 0x22, 0x25, 0x01, - 0x33, 0x01, 0x23, 0x01, 0x33, 0x02, 0x68, 0x01, 0x5f, 0xd1, 0xfe, 0x4b, - 0xf5, 0xfe, 0x4b, 0xd1, 0xaa, 0x05, 0x2b, 0xfa, 0x2b, 0x05, 0xd5, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd1, 0x05, 0xd5, 0x00, 0x0c, - 0x00, 0xe1, 0x40, 0x44, 0x05, 0x06, 0x05, 0x09, 0x0a, 0x09, 0x04, 0x0a, - 0x09, 0x03, 0x0a, 0x0b, 0x0a, 0x02, 0x01, 0x02, 0x0b, 0x0b, 0x0a, 0x06, - 0x25, 0x07, 0x08, 0x07, 0x05, 0x25, 0x04, 0x05, 0x08, 0x08, 0x07, 0x02, - 0x25, 0x03, 0x02, 0x0c, 0x00, 0x0c, 0x01, 0x25, 0x00, 0x0c, 0x42, 0x0a, - 0x05, 0x02, 0x03, 0x08, 0x03, 0x06, 0x00, 0xb4, 0x0b, 0x08, 0x0c, 0x0b, - 0x0a, 0x09, 0x08, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x0b, 0x07, 0x00, - 0x2f, 0xcc, 0x17, 0x39, 0x31, 0x00, 0x2f, 0x3c, 0xfc, 0x3c, 0xc4, 0x11, - 0x17, 0x39, 0x30, 0x4b, 0x53, 0x58, 0x07, 0x05, 0xed, 0x07, 0x10, 0x08, - 0xed, 0x07, 0x10, 0x08, 0xed, 0x07, 0x10, 0x05, 0xed, 0x07, 0x10, 0x08, - 0xc9, 0x07, 0x10, 0x05, 0xc9, 0x07, 0x05, 0xc9, 0x07, 0x10, 0x08, 0xc9, - 0x59, 0x22, 0xb2, 0x18, 0x09, 0x01, 0x01, 0x5d, 0x40, 0x5e, 0x1f, 0x03, - 0x1f, 0x04, 0x1f, 0x0a, 0x2f, 0x03, 0x2f, 0x04, 0x2b, 0x0a, 0x3f, 0x03, - 0x3f, 0x04, 0x38, 0x0a, 0x5a, 0x02, 0x5a, 0x05, 0x0b, 0x17, 0x0b, 0x26, - 0x02, 0x2a, 0x03, 0x25, 0x04, 0x2a, 0x05, 0x28, 0x08, 0x2b, 0x09, 0x25, - 0x0b, 0x26, 0x0c, 0x35, 0x02, 0x3a, 0x03, 0x35, 0x04, 0x3a, 0x05, 0x3b, - 0x08, 0x3a, 0x09, 0x34, 0x0b, 0x36, 0x0c, 0x54, 0x00, 0x54, 0x01, 0x5a, - 0x02, 0x58, 0x03, 0x57, 0x04, 0x56, 0x05, 0x5b, 0x06, 0x5b, 0x07, 0x52, - 0x08, 0x57, 0x09, 0x58, 0x0b, 0x5d, 0x0c, 0x67, 0x08, 0x68, 0x0c, 0x79, - 0x03, 0x76, 0x04, 0x79, 0x09, 0x76, 0x0b, 0x23, 0x5d, 0x00, 0x5d, 0x11, - 0x33, 0x1b, 0x01, 0x33, 0x1b, 0x01, 0x33, 0x03, 0x23, 0x0b, 0x01, 0x23, - 0xc5, 0x8f, 0xaa, 0xd3, 0xac, 0x8f, 0xc5, 0xdf, 0xbf, 0xcb, 0xca, 0xbf, - 0x05, 0xd5, 0xfb, 0x44, 0x03, 0x22, 0xfc, 0xdc, 0x04, 0xbe, 0xfa, 0x2b, - 0x03, 0x77, 0xfc, 0x89, 0x00, 0x01, 0x00, 0x12, 0x00, 0x00, 0x04, 0xbe, - 0x05, 0xd5, 0x00, 0x0b, 0x00, 0xc6, 0x40, 0x4b, 0x09, 0x25, 0x0a, 0x0b, - 0x0a, 0x08, 0x25, 0x07, 0x08, 0x0b, 0x0b, 0x0a, 0x08, 0x25, 0x09, 0x08, - 0x05, 0x06, 0x05, 0x07, 0x25, 0x06, 0x06, 0x05, 0x03, 0x25, 0x04, 0x05, - 0x04, 0x02, 0x25, 0x01, 0x02, 0x05, 0x05, 0x04, 0x02, 0x25, 0x03, 0x02, - 0x0b, 0x00, 0x0b, 0x01, 0x25, 0x00, 0x00, 0x0b, 0x42, 0x0b, 0x08, 0x05, - 0x02, 0x04, 0x03, 0x00, 0xb4, 0x09, 0x06, 0x0b, 0x08, 0x07, 0x05, 0x02, - 0x05, 0x00, 0x04, 0x3b, 0x06, 0x2f, 0x00, 0x3b, 0x0a, 0x30, 0x0c, 0x10, - 0xfc, 0xe4, 0xfc, 0xe4, 0x11, 0x17, 0x39, 0x31, 0x00, 0x2f, 0x3c, 0xec, - 0x32, 0x17, 0x39, 0x30, 0x4b, 0x53, 0x58, 0x07, 0x10, 0x05, 0xed, 0x07, - 0x10, 0x08, 0xed, 0x07, 0x10, 0x08, 0xed, 0x07, 0x10, 0x05, 0xed, 0x07, - 0x10, 0x05, 0xed, 0x07, 0x10, 0x08, 0xed, 0x07, 0x10, 0x08, 0xed, 0x07, - 0x10, 0x05, 0xed, 0x59, 0x22, 0xb2, 0x37, 0x02, 0x01, 0x00, 0x5d, 0x40, - 0x38, 0x0d, 0x05, 0x04, 0x0b, 0x18, 0x05, 0x27, 0x01, 0x28, 0x03, 0x29, - 0x05, 0x26, 0x0b, 0x58, 0x0b, 0x78, 0x02, 0x79, 0x05, 0x77, 0x0b, 0x0b, - 0x00, 0x02, 0x00, 0x02, 0x0f, 0x08, 0x0f, 0x08, 0x14, 0x02, 0x1a, 0x08, - 0x21, 0x02, 0x25, 0x05, 0x2b, 0x08, 0x25, 0x0b, 0x35, 0x02, 0x55, 0x02, - 0x59, 0x08, 0x58, 0x0b, 0x65, 0x02, 0x73, 0x02, 0x10, 0x5d, 0x01, 0x5d, - 0x13, 0x33, 0x09, 0x01, 0x33, 0x09, 0x01, 0x23, 0x09, 0x01, 0x23, 0x01, - 0x56, 0xd9, 0x01, 0x48, 0x01, 0x4e, 0xd9, 0xfe, 0x41, 0x01, 0xdf, 0xd9, - 0xfe, 0x92, 0xfe, 0x75, 0xda, 0x01, 0xf4, 0x05, 0xd5, 0xfd, 0xcd, 0x02, - 0x33, 0xfd, 0x42, 0xfc, 0xe9, 0x02, 0x83, 0xfd, 0x7d, 0x03, 0x17, 0x00, - 0x00, 0x01, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, 0x05, 0xd5, 0x00, 0x08, - 0x00, 0x59, 0x40, 0x2e, 0x03, 0x25, 0x04, 0x05, 0x04, 0x02, 0x25, 0x01, - 0x02, 0x05, 0x05, 0x04, 0x02, 0x25, 0x03, 0x02, 0x08, 0x00, 0x08, 0x01, - 0x25, 0x00, 0x00, 0x08, 0x42, 0x02, 0x03, 0x00, 0xb4, 0x06, 0x02, 0x07, - 0x03, 0x05, 0x04, 0x01, 0x07, 0x00, 0x04, 0x3c, 0x05, 0x1e, 0x00, 0x3c, - 0x07, 0x09, 0x10, 0xd4, 0xec, 0xfc, 0xec, 0x11, 0x12, 0x39, 0x11, 0x12, - 0x39, 0x11, 0x39, 0x31, 0x00, 0x2f, 0xec, 0x32, 0x39, 0x30, 0x4b, 0x53, - 0x58, 0x07, 0x10, 0x05, 0xed, 0x07, 0x10, 0x08, 0xed, 0x07, 0x10, 0x08, - 0xed, 0x07, 0x10, 0x05, 0xed, 0x59, 0x22, 0x13, 0x33, 0x09, 0x01, 0x33, - 0x01, 0x11, 0x23, 0x11, 0x25, 0xd7, 0x01, 0x6c, 0x01, 0x6b, 0xd9, 0xfe, - 0x21, 0xcb, 0x05, 0xd5, 0xfd, 0x6d, 0x02, 0x93, 0xfc, 0xc9, 0xfd, 0x62, - 0x02, 0x9e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x9c, 0x00, 0x00, 0x04, 0x91, - 0x05, 0xd5, 0x00, 0x09, 0x00, 0x45, 0x40, 0x1c, 0x08, 0x25, 0x02, 0x03, - 0x02, 0x03, 0x25, 0x07, 0x08, 0x07, 0x42, 0x08, 0x97, 0x00, 0x88, 0x03, - 0x97, 0x05, 0x08, 0x03, 0x00, 0x01, 0x04, 0x2f, 0x00, 0x06, 0x30, 0x0a, - 0x10, 0xfc, 0xc4, 0xfc, 0xc4, 0x11, 0x39, 0x39, 0x31, 0x00, 0x2f, 0xec, - 0xf4, 0xec, 0x30, 0x4b, 0x53, 0x58, 0x07, 0x10, 0x05, 0xed, 0x07, 0x10, - 0x05, 0xed, 0x59, 0x22, 0xb2, 0x08, 0x08, 0x01, 0x01, 0x5d, 0xb2, 0x07, - 0x03, 0x01, 0x5d, 0x13, 0x21, 0x15, 0x01, 0x21, 0x15, 0x21, 0x35, 0x01, - 0x21, 0xb2, 0x03, 0xc9, 0xfc, 0xf4, 0x03, 0x22, 0xfc, 0x0b, 0x02, 0xf7, - 0xfd, 0x1f, 0x05, 0xd5, 0x9a, 0xfb, 0x6f, 0xaa, 0x9a, 0x04, 0x91, 0x00, - 0x00, 0x01, 0x01, 0xcf, 0xfe, 0xf2, 0x03, 0x77, 0x06, 0x14, 0x00, 0x07, - 0x00, 0x1e, 0x40, 0x0f, 0x04, 0xb6, 0x06, 0xb7, 0x02, 0xb6, 0x00, 0xb5, - 0x08, 0x05, 0x01, 0x03, 0x3d, 0x00, 0x08, 0x10, 0xd4, 0xfc, 0xc4, 0x32, - 0x31, 0x00, 0x10, 0xfc, 0xec, 0xf4, 0xec, 0x30, 0x01, 0x21, 0x15, 0x23, - 0x11, 0x33, 0x15, 0x21, 0x01, 0xcf, 0x01, 0xa8, 0xf0, 0xf0, 0xfe, 0x58, - 0x06, 0x14, 0x8f, 0xf9, 0xfc, 0x8f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x66, - 0xff, 0x42, 0x04, 0x37, 0x05, 0xd5, 0x00, 0x03, 0x00, 0x18, 0x40, 0x0b, - 0x01, 0x00, 0x88, 0x04, 0x01, 0x1e, 0x02, 0x00, 0x1e, 0x03, 0x04, 0x10, - 0xd4, 0xec, 0xd4, 0xec, 0x31, 0x00, 0x10, 0xf4, 0xc4, 0x30, 0x09, 0x01, - 0x23, 0x01, 0x01, 0x25, 0x03, 0x12, 0xbe, 0xfc, 0xed, 0x05, 0xd5, 0xf9, - 0x6d, 0x06, 0x93, 0x00, 0x00, 0x01, 0x01, 0x5a, 0xfe, 0xf2, 0x03, 0x02, - 0x06, 0x14, 0x00, 0x07, 0x00, 0x1e, 0x40, 0x0f, 0x03, 0xb6, 0x01, 0xb7, - 0x05, 0xb6, 0x00, 0xb5, 0x08, 0x00, 0x3d, 0x06, 0x02, 0x04, 0x08, 0x10, - 0xd4, 0xc4, 0x32, 0xec, 0x31, 0x00, 0x10, 0xfc, 0xec, 0xf4, 0xec, 0x30, - 0x01, 0x11, 0x21, 0x35, 0x33, 0x11, 0x23, 0x35, 0x03, 0x02, 0xfe, 0x58, - 0xf0, 0xf0, 0x06, 0x14, 0xf8, 0xde, 0x8f, 0x06, 0x04, 0x8f, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x48, 0x03, 0xa8, 0x04, 0x89, 0x05, 0xd5, 0x00, 0x06, - 0x00, 0x18, 0x40, 0x0a, 0x03, 0x04, 0x01, 0x00, 0x88, 0x07, 0x03, 0x01, - 0x05, 0x07, 0x10, 0xd4, 0xcc, 0x39, 0x31, 0x00, 0x10, 0xf4, 0xcc, 0x32, - 0x39, 0x30, 0x09, 0x01, 0x23, 0x09, 0x01, 0x23, 0x01, 0x02, 0xc1, 0x01, - 0xc8, 0xb2, 0xfe, 0x91, 0xfe, 0x92, 0xb2, 0x01, 0xc8, 0x05, 0xd5, 0xfd, - 0xd3, 0x01, 0x8b, 0xfe, 0x75, 0x02, 0x2d, 0x00, 0x00, 0x01, 0x00, 0x00, - 0xfe, 0x1d, 0x04, 0xd1, 0xfe, 0x6d, 0x00, 0x03, 0x00, 0x0f, 0xb5, 0x00, - 0xb8, 0x01, 0x04, 0x00, 0x02, 0x2f, 0xcc, 0x31, 0x00, 0x10, 0xd4, 0xec, - 0x30, 0x01, 0x15, 0x21, 0x35, 0x04, 0xd1, 0xfb, 0x2f, 0xfe, 0x6d, 0x50, - 0x50, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x17, 0x04, 0xee, 0x02, 0xf6, - 0x06, 0x66, 0x00, 0x03, 0x00, 0x25, 0x40, 0x09, 0x01, 0xba, 0x00, 0xb9, - 0x04, 0x01, 0x3c, 0x03, 0x04, 0x10, 0xd4, 0xec, 0x31, 0x00, 0x10, 0xf4, - 0x4b, 0xb0, 0x09, 0x54, 0x4b, 0xb0, 0x0e, 0x54, 0x5b, 0x58, 0xb9, 0x00, - 0x00, 0x00, 0x40, 0x38, 0x59, 0xec, 0x30, 0x09, 0x01, 0x23, 0x01, 0x01, - 0xdd, 0x01, 0x19, 0x9a, 0xfe, 0xbb, 0x06, 0x66, 0xfe, 0x88, 0x01, 0x78, - 0x00, 0x02, 0x00, 0x85, 0xff, 0xe3, 0x04, 0x23, 0x04, 0x7b, 0x00, 0x0b, - 0x00, 0x29, 0x00, 0x6e, 0x40, 0x2a, 0x0a, 0x07, 0x00, 0x1a, 0x20, 0x0c, - 0x18, 0x0f, 0x07, 0x00, 0xb6, 0x18, 0x07, 0x8c, 0x12, 0x21, 0x8b, 0x20, - 0xbf, 0x1d, 0x8c, 0x24, 0xbe, 0x12, 0x99, 0x18, 0x0d, 0x01, 0x18, 0x04, - 0x19, 0x0e, 0x0a, 0x06, 0x0c, 0x44, 0x20, 0x04, 0x06, 0x15, 0x3e, 0x2a, - 0x10, 0xf4, 0xec, 0xc4, 0xfc, 0xec, 0x32, 0x32, 0x11, 0x39, 0x39, 0x31, - 0x00, 0x2f, 0xc4, 0xe4, 0xf4, 0xfc, 0xf4, 0xec, 0x10, 0xee, 0x10, 0xee, - 0x11, 0x39, 0x11, 0x39, 0x12, 0x39, 0x11, 0x12, 0x39, 0x30, 0x40, 0x1d, - 0x30, 0x1f, 0x30, 0x20, 0x30, 0x21, 0x30, 0x22, 0xa0, 0x00, 0xa0, 0x01, - 0xa0, 0x02, 0xa0, 0x0a, 0xa0, 0x0b, 0xa2, 0x16, 0xa0, 0x17, 0xa0, 0x18, - 0xa0, 0x19, 0xa0, 0x1a, 0x0e, 0x5d, 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, - 0x16, 0x33, 0x32, 0x36, 0x37, 0x35, 0x37, 0x11, 0x23, 0x35, 0x0e, 0x01, - 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x3b, 0x01, 0x35, 0x2e, 0x01, 0x23, - 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x17, 0x1e, 0x01, - 0x02, 0xbe, 0x3d, 0xa1, 0xa3, 0x7a, 0x6c, 0x98, 0xae, 0x01, 0xb9, 0xb9, - 0x3b, 0xb3, 0x80, 0xab, 0xcc, 0xfb, 0xf3, 0xf7, 0x01, 0x86, 0x93, 0x5e, - 0xc0, 0x5b, 0x66, 0xbb, 0x58, 0x8b, 0xc5, 0x3d, 0x26, 0x20, 0x02, 0x33, - 0x71, 0x70, 0x65, 0x70, 0xd3, 0xba, 0x29, 0x4c, 0xfd, 0x81, 0xa6, 0x64, - 0x5f, 0xc1, 0xa2, 0xbb, 0xc2, 0x1d, 0x86, 0x79, 0x36, 0x34, 0xb8, 0x27, - 0x27, 0x52, 0x52, 0x32, 0x93, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xc1, - 0xff, 0xe3, 0x04, 0x58, 0x06, 0x14, 0x00, 0x0b, 0x00, 0x1c, 0x00, 0x30, - 0x40, 0x1a, 0x18, 0x0c, 0x09, 0x03, 0x8c, 0x0f, 0x09, 0x8c, 0x15, 0x99, - 0x0f, 0xbe, 0x1b, 0x9b, 0x19, 0x00, 0x12, 0x12, 0x47, 0x18, 0x0c, 0x06, - 0x06, 0x1a, 0x46, 0x1d, 0x10, 0xf4, 0xec, 0x32, 0x32, 0xfc, 0xec, 0x31, - 0x00, 0x2f, 0xec, 0xe4, 0xf4, 0xec, 0x10, 0xee, 0x11, 0x39, 0x39, 0x30, - 0x01, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, - 0x01, 0x3e, 0x01, 0x33, 0x32, 0x12, 0x11, 0x10, 0x02, 0x23, 0x22, 0x26, - 0x27, 0x15, 0x23, 0x11, 0x33, 0x03, 0x96, 0x88, 0x85, 0x86, 0x8a, 0x8a, - 0x86, 0x85, 0x88, 0xfd, 0xe3, 0x2c, 0x9b, 0x66, 0xca, 0xe8, 0xe9, 0xcb, - 0x64, 0x99, 0x2e, 0xb8, 0xb8, 0x02, 0x2f, 0xd6, 0xda, 0xdb, 0xd5, 0xd4, - 0xdc, 0xda, 0x02, 0x78, 0x52, 0x58, 0xfe, 0xc9, 0xfe, 0xef, 0xfe, 0xeb, - 0xfe, 0xc5, 0x57, 0x53, 0x8d, 0x06, 0x14, 0x00, 0x00, 0x01, 0x00, 0xc3, - 0xff, 0xe3, 0x04, 0x25, 0x04, 0x7b, 0x00, 0x19, 0x00, 0x2f, 0x40, 0x1a, - 0x0c, 0x8b, 0x0d, 0xc0, 0x10, 0x00, 0x8b, 0x19, 0xc0, 0x16, 0x8c, 0x03, - 0x10, 0x8c, 0x09, 0xbe, 0x03, 0x99, 0x1a, 0x13, 0x12, 0x0c, 0x00, 0x06, - 0x46, 0x1a, 0x10, 0xf4, 0xc4, 0x32, 0xec, 0x31, 0x00, 0x10, 0xe4, 0xf4, - 0xec, 0x10, 0xfe, 0xf4, 0xee, 0x10, 0xf5, 0xee, 0x30, 0x25, 0x0e, 0x01, - 0x23, 0x20, 0x00, 0x11, 0x10, 0x00, 0x21, 0x32, 0x16, 0x17, 0x15, 0x2e, - 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x04, - 0x25, 0x4a, 0x9d, 0x52, 0xfe, 0xfc, 0xfe, 0xdb, 0x01, 0x25, 0x01, 0x04, - 0x51, 0x9a, 0x4e, 0x49, 0x93, 0x5d, 0xad, 0xba, 0xbb, 0xac, 0x60, 0x98, - 0x41, 0x39, 0x2b, 0x2b, 0x01, 0x38, 0x01, 0x14, 0x01, 0x14, 0x01, 0x38, - 0x2a, 0x2c, 0xc1, 0x41, 0x3a, 0xe0, 0xd0, 0xcf, 0xe1, 0x3b, 0x3e, 0x00, - 0x00, 0x02, 0x00, 0x7b, 0xff, 0xe3, 0x04, 0x12, 0x06, 0x14, 0x00, 0x10, - 0x00, 0x1c, 0x00, 0x30, 0x40, 0x1a, 0x05, 0x00, 0x14, 0x1a, 0x8c, 0x0e, - 0x14, 0x8c, 0x08, 0x99, 0x0e, 0xbe, 0x01, 0x9b, 0x03, 0x17, 0x04, 0x00, - 0x06, 0x02, 0x47, 0x11, 0x12, 0x0b, 0x48, 0x1d, 0x10, 0xf4, 0xec, 0xfc, - 0xec, 0x32, 0x32, 0x31, 0x00, 0x2f, 0xec, 0xe4, 0xf4, 0xec, 0x10, 0xee, - 0x11, 0x39, 0x39, 0x30, 0x01, 0x11, 0x33, 0x11, 0x23, 0x35, 0x0e, 0x01, - 0x23, 0x22, 0x02, 0x11, 0x10, 0x12, 0x33, 0x32, 0x16, 0x01, 0x14, 0x16, - 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x03, 0x5a, 0xb8, - 0xb8, 0x2e, 0x99, 0x64, 0xcb, 0xe9, 0xea, 0xca, 0x65, 0x9a, 0xfe, 0x0f, - 0x88, 0x85, 0x85, 0x8b, 0x8b, 0x85, 0x85, 0x88, 0x03, 0xd1, 0x02, 0x43, - 0xf9, 0xec, 0x8d, 0x53, 0x57, 0x01, 0x3b, 0x01, 0x15, 0x01, 0x11, 0x01, - 0x37, 0x57, 0xfe, 0x0b, 0xd6, 0xda, 0xdc, 0xd4, 0xd5, 0xdb, 0xda, 0x00, - 0x00, 0x02, 0x00, 0x7b, 0xff, 0xe3, 0x04, 0x58, 0x04, 0x7b, 0x00, 0x15, - 0x00, 0x1c, 0x00, 0x45, 0x40, 0x26, 0x00, 0x16, 0x03, 0x01, 0x0a, 0x8b, - 0x09, 0x8d, 0x06, 0x16, 0xb6, 0x01, 0x06, 0x8c, 0x0d, 0x01, 0xc1, 0x19, - 0x8c, 0x13, 0xbe, 0x0d, 0x99, 0x1d, 0x03, 0x02, 0x1c, 0x10, 0x09, 0x16, - 0x06, 0x00, 0x49, 0x1c, 0x12, 0x10, 0x48, 0x1d, 0x10, 0xf4, 0xec, 0xfc, - 0xec, 0xc4, 0x11, 0x12, 0x39, 0x39, 0x31, 0x00, 0x10, 0xe4, 0xf4, 0xec, - 0xe4, 0x10, 0xee, 0x10, 0xee, 0x10, 0xf4, 0xee, 0x12, 0x39, 0x11, 0x39, - 0x30, 0x01, 0x15, 0x21, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x15, - 0x0e, 0x01, 0x23, 0x20, 0x00, 0x11, 0x10, 0x00, 0x33, 0x32, 0x12, 0x07, - 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x04, 0x58, 0xfc, 0xe3, 0xbf, 0xae, - 0x58, 0xc0, 0x6d, 0x69, 0xc3, 0x5b, 0xfe, 0xfb, 0xfe, 0xda, 0x01, 0x20, - 0xf0, 0xd6, 0xf7, 0xb8, 0x04, 0x91, 0x88, 0x85, 0xac, 0x10, 0x02, 0x5e, - 0x5a, 0x06, 0xb7, 0xc8, 0x38, 0x39, 0xb7, 0x2b, 0x2b, 0x01, 0x39, 0x01, - 0x13, 0x01, 0x0c, 0x01, 0x40, 0xfe, 0xde, 0xc5, 0xa2, 0xa9, 0xb0, 0x9c, - 0x00, 0x01, 0x00, 0xc3, 0x00, 0x00, 0x04, 0x27, 0x06, 0x14, 0x00, 0x13, - 0x00, 0x34, 0x40, 0x1a, 0x05, 0x10, 0x01, 0x0c, 0x08, 0xb6, 0x06, 0x01, - 0x8c, 0x00, 0x9b, 0x0e, 0x06, 0xc2, 0x0a, 0x02, 0x13, 0x07, 0x00, 0x09, - 0x05, 0x06, 0x0d, 0x0f, 0x0b, 0x14, 0x10, 0xd4, 0x3c, 0xc4, 0xfc, 0x3c, - 0xc4, 0x32, 0x39, 0x39, 0x31, 0x00, 0x2f, 0xe4, 0x32, 0xfc, 0xec, 0x10, - 0xee, 0x32, 0x12, 0x39, 0x39, 0x30, 0x01, 0x15, 0x23, 0x22, 0x06, 0x1d, - 0x01, 0x21, 0x15, 0x21, 0x11, 0x23, 0x11, 0x21, 0x35, 0x21, 0x35, 0x34, - 0x36, 0x33, 0x04, 0x27, 0xd1, 0x63, 0x4d, 0x01, 0x81, 0xfe, 0x7f, 0xb8, - 0xfe, 0xd5, 0x01, 0x2b, 0xa9, 0xb3, 0x06, 0x14, 0x99, 0x51, 0x67, 0x63, - 0x8f, 0xfc, 0x2f, 0x03, 0xd1, 0x8f, 0x4e, 0xb8, 0xae, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x7b, 0xfe, 0x48, 0x04, 0x12, 0x04, 0x7b, 0x00, 0x0b, - 0x00, 0x29, 0x00, 0x48, 0x40, 0x27, 0x19, 0x0c, 0x1e, 0x1b, 0x27, 0x09, - 0x03, 0x12, 0x8b, 0x13, 0x16, 0x09, 0x8c, 0x1e, 0x16, 0x8c, 0x0f, 0x03, - 0x8c, 0x24, 0xbe, 0x1e, 0x0f, 0xc3, 0x28, 0xc2, 0x2a, 0x27, 0x19, 0x00, - 0x06, 0x0c, 0x47, 0x06, 0x12, 0x12, 0x21, 0x48, 0x2a, 0x10, 0xf4, 0xc4, - 0xec, 0xfc, 0xec, 0x32, 0x32, 0x31, 0x00, 0x10, 0xe4, 0xe4, 0xc4, 0xf4, - 0xec, 0x10, 0xee, 0x10, 0xee, 0x10, 0xd5, 0xee, 0x11, 0x12, 0x39, 0x39, - 0x11, 0x39, 0x39, 0x30, 0x01, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, - 0x16, 0x33, 0x32, 0x36, 0x13, 0x14, 0x02, 0x23, 0x22, 0x26, 0x27, 0x35, - 0x1e, 0x01, 0x33, 0x32, 0x36, 0x3d, 0x02, 0x0e, 0x01, 0x23, 0x22, 0x02, - 0x11, 0x10, 0x12, 0x33, 0x32, 0x16, 0x17, 0x35, 0x33, 0x03, 0x5a, 0x87, - 0x81, 0x87, 0x8e, 0x8f, 0x88, 0x7f, 0x87, 0xb8, 0xee, 0xe7, 0x4c, 0xa6, - 0x53, 0x62, 0xa0, 0x43, 0x95, 0x88, 0x2c, 0x98, 0x6d, 0xc4, 0xea, 0xea, - 0xc4, 0x6c, 0x96, 0x2f, 0xb8, 0x02, 0x39, 0xcf, 0xd7, 0xd7, 0xcf, 0xcf, - 0xd9, 0xda, 0xfe, 0xdd, 0xfc, 0xfe, 0xfc, 0x1c, 0x1b, 0xb6, 0x2e, 0x2c, - 0xa2, 0xb0, 0x08, 0x7d, 0x5e, 0x5c, 0x01, 0x3a, 0x01, 0x07, 0x01, 0x08, - 0x01, 0x3a, 0x56, 0x5a, 0x91, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc3, - 0x00, 0x00, 0x04, 0x1b, 0x06, 0x14, 0x00, 0x13, 0x00, 0x2c, 0x40, 0x18, - 0x09, 0x0e, 0x03, 0x00, 0x03, 0x01, 0x06, 0x8c, 0x11, 0xbe, 0x0c, 0x9b, - 0x0a, 0x01, 0x02, 0x06, 0x00, 0x4a, 0x0d, 0x09, 0x06, 0x0b, 0x46, 0x14, - 0x10, 0xf4, 0xec, 0x32, 0xfc, 0xec, 0x31, 0x00, 0x2f, 0x3c, 0xec, 0xf4, - 0xec, 0x11, 0x17, 0x39, 0x39, 0x30, 0x01, 0x11, 0x23, 0x11, 0x34, 0x26, - 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, 0x11, 0x3e, 0x01, 0x33, - 0x32, 0x16, 0x04, 0x1b, 0xb9, 0x6a, 0x71, 0x81, 0x8b, 0xb8, 0xb8, 0x31, - 0xa8, 0x73, 0xab, 0xa9, 0x02, 0xb6, 0xfd, 0x4a, 0x02, 0xb6, 0x97, 0x8e, - 0xb7, 0xab, 0xfd, 0x87, 0x06, 0x14, 0xfd, 0xa4, 0x60, 0x63, 0xe1, 0x00, - 0x00, 0x02, 0x00, 0xb2, 0x00, 0x00, 0x04, 0x44, 0x06, 0x14, 0x00, 0x09, - 0x00, 0x0d, 0x00, 0x2e, 0x40, 0x19, 0x08, 0xb6, 0x00, 0x0c, 0xc4, 0x0a, - 0x9b, 0x00, 0xc2, 0x06, 0x02, 0xb6, 0x04, 0x03, 0x4c, 0x0b, 0x01, 0x06, - 0x05, 0x4c, 0x00, 0x4b, 0x0a, 0x07, 0x0e, 0x10, 0xd4, 0x3c, 0xe4, 0xec, - 0xfc, 0x3c, 0xec, 0x31, 0x00, 0x2f, 0xec, 0x32, 0xe4, 0xfc, 0xec, 0x10, - 0xee, 0x30, 0x01, 0x21, 0x11, 0x21, 0x15, 0x21, 0x35, 0x21, 0x11, 0x21, - 0x01, 0x33, 0x15, 0x23, 0x01, 0x00, 0x01, 0xd7, 0x01, 0x6d, 0xfc, 0x6e, - 0x01, 0x6d, 0xfe, 0xe1, 0x01, 0x1f, 0xb8, 0xb8, 0x04, 0x60, 0xfc, 0x2f, - 0x8f, 0x8f, 0x03, 0x42, 0x02, 0x43, 0xe9, 0x00, 0x00, 0x02, 0x00, 0xba, - 0xfe, 0x56, 0x03, 0x10, 0x06, 0x14, 0x00, 0x0d, 0x00, 0x11, 0x00, 0x38, - 0x40, 0x1d, 0x05, 0x00, 0x01, 0x0a, 0x8c, 0x08, 0x01, 0xb6, 0x03, 0x10, - 0xc4, 0x0e, 0x9b, 0x03, 0xc2, 0x08, 0xc3, 0x12, 0x0b, 0x08, 0x02, 0x09, - 0x02, 0x0f, 0x04, 0x06, 0x0e, 0x00, 0x12, 0x10, 0xd4, 0x3c, 0xec, 0x32, - 0xc4, 0xc4, 0x12, 0x39, 0x39, 0x31, 0x00, 0x10, 0xe4, 0xe4, 0xfc, 0xec, - 0x10, 0xee, 0x10, 0xee, 0x11, 0x39, 0x39, 0x30, 0x05, 0x11, 0x21, 0x35, - 0x21, 0x11, 0x14, 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x36, 0x11, 0x33, - 0x15, 0x23, 0x02, 0x58, 0xfe, 0xc3, 0x01, 0xf5, 0xb3, 0xa5, 0xfe, 0xea, - 0x5a, 0x5a, 0xb8, 0xb8, 0x14, 0x03, 0xe5, 0x8f, 0xfb, 0x8c, 0xc3, 0xd3, - 0x9c, 0x7d, 0x06, 0xa5, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xec, - 0x00, 0x00, 0x04, 0xb2, 0x06, 0x14, 0x00, 0x0b, 0x00, 0xc5, 0x40, 0x3a, - 0x08, 0x17, 0x09, 0x08, 0x05, 0x06, 0x05, 0x07, 0x17, 0x06, 0x06, 0x05, - 0x09, 0x17, 0x03, 0x02, 0x08, 0x17, 0x07, 0x08, 0x03, 0x02, 0x05, 0x17, - 0x06, 0x05, 0x02, 0x03, 0x02, 0x04, 0x17, 0x03, 0x03, 0x02, 0x42, 0x08, - 0x05, 0x02, 0x03, 0x03, 0xc2, 0x00, 0x9b, 0x0a, 0x06, 0x08, 0x05, 0x04, - 0x03, 0x06, 0x09, 0x01, 0x06, 0x06, 0x44, 0x00, 0x45, 0x0c, 0x10, 0xf4, - 0xec, 0xec, 0x32, 0x11, 0x17, 0x39, 0x31, 0x00, 0x2f, 0x3c, 0xec, 0xe4, - 0x17, 0x39, 0x30, 0x4b, 0x53, 0x58, 0x07, 0x10, 0x05, 0xed, 0x07, 0x10, - 0x08, 0xed, 0x07, 0x08, 0xed, 0x07, 0x04, 0xed, 0x07, 0x10, 0x05, 0xed, - 0x07, 0x10, 0x08, 0xed, 0x59, 0x22, 0xb2, 0x08, 0x07, 0x01, 0x01, 0x5d, - 0x40, 0x52, 0x06, 0x02, 0x08, 0x08, 0x16, 0x02, 0x18, 0x05, 0x18, 0x08, - 0x35, 0x02, 0x34, 0x05, 0x36, 0x08, 0x46, 0x02, 0x66, 0x02, 0x75, 0x02, - 0x76, 0x05, 0x0c, 0x09, 0x03, 0x08, 0x08, 0x19, 0x03, 0x17, 0x04, 0x18, - 0x05, 0x19, 0x06, 0x1a, 0x07, 0x18, 0x08, 0x28, 0x03, 0x27, 0x05, 0x28, - 0x07, 0x3b, 0x03, 0x3b, 0x04, 0x37, 0x05, 0x39, 0x07, 0x37, 0x08, 0x4a, - 0x03, 0x49, 0x07, 0x59, 0x06, 0x59, 0x07, 0x6b, 0x03, 0x69, 0x04, 0x69, - 0x06, 0x69, 0x07, 0x79, 0x03, 0x78, 0x05, 0x79, 0x06, 0x79, 0x07, 0x1c, - 0x5d, 0x00, 0x5d, 0x13, 0x33, 0x11, 0x01, 0x33, 0x09, 0x01, 0x23, 0x01, - 0x07, 0x11, 0x23, 0xec, 0xbe, 0x01, 0xe3, 0xe0, 0xfe, 0x47, 0x01, 0xfe, - 0xe1, 0xfe, 0x62, 0x89, 0xbe, 0x06, 0x14, 0xfc, 0x7b, 0x01, 0xd1, 0xfe, - 0x5a, 0xfd, 0x46, 0x02, 0x42, 0x81, 0xfe, 0x3f, 0x00, 0x01, 0x00, 0xa0, - 0x00, 0x00, 0x04, 0x0a, 0x06, 0x1f, 0x00, 0x0d, 0x00, 0x26, 0x40, 0x13, - 0x09, 0x00, 0x03, 0x0a, 0xb6, 0x0c, 0xc5, 0x03, 0xb6, 0x05, 0x03, 0x06, - 0x04, 0x00, 0x06, 0x0b, 0x4c, 0x09, 0x0e, 0x10, 0xd4, 0xec, 0xfc, 0xcc, - 0x39, 0x39, 0x31, 0x00, 0x2f, 0xec, 0xfc, 0xec, 0x11, 0x39, 0x39, 0x30, - 0x01, 0x14, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x26, 0x35, 0x11, 0x21, - 0x35, 0x21, 0x02, 0x7f, 0x5b, 0x59, 0xd7, 0xe9, 0xa5, 0xb5, 0xfe, 0xd9, - 0x01, 0xdf, 0x01, 0x96, 0x7c, 0x7e, 0x9c, 0xd4, 0xc2, 0x03, 0xf9, 0x90, - 0x00, 0x01, 0x00, 0x6d, 0x00, 0x00, 0x04, 0x6f, 0x04, 0x7b, 0x00, 0x22, - 0x00, 0xa3, 0x40, 0x27, 0x18, 0x12, 0x0f, 0x09, 0x04, 0x07, 0x00, 0x1d, - 0x1b, 0x06, 0x07, 0x15, 0x0c, 0x8c, 0x20, 0x03, 0xbe, 0x1b, 0xc2, 0x19, - 0x10, 0x07, 0x00, 0x11, 0x0f, 0x08, 0x4d, 0x06, 0x4e, 0x11, 0x4d, 0x0f, - 0x4e, 0x1c, 0x18, 0x4d, 0x1a, 0x45, 0x23, 0x10, 0xf4, 0x4b, 0xb0, 0x0c, - 0x54, 0x4b, 0xb0, 0x11, 0x54, 0x5b, 0x58, 0xb9, 0x00, 0x1a, 0xff, 0xc0, - 0x38, 0x59, 0xfc, 0x3c, 0xfc, 0xec, 0xfc, 0xec, 0x11, 0x12, 0x39, 0x31, - 0x00, 0x2f, 0x3c, 0x3c, 0xe4, 0xf4, 0x3c, 0xec, 0x32, 0x11, 0x39, 0x11, - 0x39, 0x39, 0x11, 0x17, 0x39, 0x30, 0x40, 0x47, 0x30, 0x04, 0x30, 0x05, - 0x30, 0x06, 0x30, 0x07, 0x30, 0x08, 0x30, 0x09, 0x30, 0x0a, 0x30, 0x0b, - 0x3f, 0x16, 0x3f, 0x17, 0x3f, 0x18, 0x3f, 0x19, 0x3f, 0x1a, 0x3f, 0x1b, - 0x3f, 0x1c, 0x3f, 0x1d, 0x3f, 0x1e, 0x80, 0x03, 0x80, 0x04, 0x80, 0x05, - 0x80, 0x06, 0x80, 0x07, 0x80, 0x08, 0x80, 0x09, 0x80, 0x0a, 0x80, 0x0b, - 0x8f, 0x16, 0x8f, 0x17, 0x8f, 0x18, 0x8f, 0x19, 0x8f, 0x1a, 0x8f, 0x1b, - 0x8f, 0x1c, 0x8f, 0x1d, 0x8f, 0x1e, 0x23, 0x01, 0x5d, 0x01, 0x3e, 0x01, - 0x33, 0x32, 0x16, 0x19, 0x01, 0x23, 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, - 0x15, 0x11, 0x23, 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, - 0x11, 0x33, 0x15, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x02, 0xa4, 0x22, 0x69, - 0x4a, 0x87, 0x6f, 0xa8, 0x35, 0x46, 0x50, 0x3b, 0xa8, 0x39, 0x4a, 0x49, - 0x39, 0xa7, 0xa7, 0x21, 0x63, 0x3f, 0x4c, 0x65, 0x03, 0xee, 0x48, 0x45, - 0xd1, 0xfe, 0xdf, 0xfd, 0x77, 0x02, 0x81, 0xed, 0x73, 0x7b, 0xe5, 0xfd, - 0x7f, 0x02, 0x81, 0xf0, 0x70, 0x7b, 0xe5, 0xfd, 0x7f, 0x04, 0x60, 0x60, - 0x3c, 0x3f, 0x46, 0x00, 0x00, 0x01, 0x00, 0xc3, 0x00, 0x00, 0x04, 0x1b, - 0x04, 0x7b, 0x00, 0x13, 0x00, 0x2c, 0x40, 0x18, 0x09, 0x0e, 0x03, 0x00, - 0x03, 0x01, 0x06, 0x8c, 0x11, 0xbe, 0x0c, 0xc2, 0x0a, 0x01, 0x02, 0x06, - 0x00, 0x4a, 0x0d, 0x09, 0x06, 0x0b, 0x46, 0x14, 0x10, 0xf4, 0xec, 0x32, - 0xfc, 0xec, 0x31, 0x00, 0x2f, 0x3c, 0xe4, 0xf4, 0xec, 0x11, 0x17, 0x39, - 0x39, 0x30, 0x01, 0x11, 0x23, 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, - 0x11, 0x23, 0x11, 0x33, 0x15, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x04, 0x1b, - 0xb9, 0x6a, 0x71, 0x81, 0x8b, 0xb8, 0xb8, 0x31, 0xa8, 0x73, 0xab, 0xa9, - 0x02, 0xb6, 0xfd, 0x4a, 0x02, 0xb6, 0x97, 0x8e, 0xb7, 0xab, 0xfd, 0x87, - 0x04, 0x60, 0xa8, 0x60, 0x63, 0xe1, 0x00, 0x00, 0x00, 0x02, 0x00, 0x89, - 0xff, 0xe3, 0x04, 0x48, 0x04, 0x7b, 0x00, 0x0b, 0x00, 0x17, 0x00, 0x23, - 0x40, 0x13, 0x06, 0x8c, 0x12, 0x00, 0x8c, 0x0c, 0xbe, 0x12, 0x99, 0x18, - 0x09, 0x12, 0x0f, 0x44, 0x03, 0x12, 0x15, 0x3e, 0x18, 0x10, 0xf4, 0xec, - 0xfc, 0xec, 0x31, 0x00, 0x10, 0xe4, 0xf4, 0xec, 0x10, 0xee, 0x30, 0x01, - 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x27, - 0x32, 0x12, 0x11, 0x10, 0x02, 0x23, 0x22, 0x02, 0x11, 0x10, 0x12, 0x02, - 0x68, 0x8c, 0x90, 0x90, 0x8c, 0x8d, 0x90, 0x90, 0x8d, 0xe9, 0xf7, 0xf6, - 0xea, 0xe9, 0xf6, 0xf6, 0x03, 0xdf, 0xda, 0xd6, 0xd5, 0xdb, 0xdb, 0xd5, - 0xd6, 0xda, 0x9c, 0xfe, 0xd2, 0xfe, 0xe2, 0xfe, 0xe1, 0xfe, 0xd3, 0x01, - 0x2d, 0x01, 0x1f, 0x01, 0x1e, 0x01, 0x2e, 0x00, 0x00, 0x02, 0x00, 0xbe, - 0xfe, 0x56, 0x04, 0x54, 0x04, 0x7b, 0x00, 0x10, 0x00, 0x1c, 0x00, 0x33, - 0x40, 0x1c, 0x05, 0x00, 0x14, 0x1a, 0x8c, 0x0e, 0x14, 0x8c, 0x08, 0xbe, - 0x0e, 0x99, 0x01, 0xc3, 0x03, 0xc2, 0x1d, 0x11, 0x12, 0x0b, 0x47, 0x17, - 0x04, 0x00, 0x06, 0x02, 0x46, 0x1d, 0x10, 0xf4, 0xec, 0x32, 0x32, 0xfc, - 0xec, 0x31, 0x00, 0x10, 0xe4, 0xe4, 0xe4, 0xf4, 0xec, 0x10, 0xee, 0x11, - 0x39, 0x39, 0x30, 0x25, 0x11, 0x23, 0x11, 0x33, 0x15, 0x3e, 0x01, 0x33, - 0x32, 0x12, 0x11, 0x10, 0x02, 0x23, 0x22, 0x26, 0x01, 0x34, 0x26, 0x23, - 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x01, 0x77, 0xb9, 0xb9, - 0x2e, 0x99, 0x64, 0xcb, 0xe7, 0xe8, 0xca, 0x66, 0x99, 0x01, 0xf0, 0x87, - 0x85, 0x86, 0x8a, 0x8a, 0x86, 0x85, 0x87, 0x8d, 0xfd, 0xc9, 0x06, 0x0a, - 0x8f, 0x53, 0x57, 0xfe, 0xc6, 0xfe, 0xea, 0xfe, 0xef, 0xfe, 0xc9, 0x57, - 0x01, 0xf5, 0xd6, 0xda, 0xdb, 0xd5, 0xd4, 0xdc, 0xda, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x89, 0xfe, 0x52, 0x04, 0x1f, 0x04, 0x77, 0x00, 0x0b, - 0x00, 0x1c, 0x00, 0x33, 0x40, 0x1c, 0x18, 0x0c, 0x09, 0x03, 0x8c, 0x0f, - 0x09, 0x8c, 0x15, 0xbe, 0x0f, 0x99, 0x1b, 0xc3, 0x19, 0xc2, 0x1d, 0x18, - 0x0c, 0x06, 0x06, 0x1a, 0x47, 0x00, 0x12, 0x12, 0x3e, 0x1d, 0x10, 0xf4, - 0xec, 0xfc, 0xec, 0x32, 0x32, 0x31, 0x00, 0x10, 0xe4, 0xe4, 0xe4, 0xf4, - 0xec, 0x10, 0xee, 0x11, 0x39, 0x39, 0x30, 0x01, 0x14, 0x16, 0x33, 0x32, - 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x01, 0x0e, 0x01, 0x23, 0x22, - 0x02, 0x11, 0x10, 0x12, 0x33, 0x32, 0x16, 0x17, 0x35, 0x33, 0x11, 0x23, - 0x01, 0x4c, 0x87, 0x85, 0x85, 0x89, 0x89, 0x85, 0x85, 0x87, 0x02, 0x1a, - 0x2d, 0x99, 0x65, 0xc9, 0xe9, 0xe8, 0xca, 0x64, 0x99, 0x2e, 0xb9, 0xb9, - 0x02, 0x2b, 0xd6, 0xda, 0xdb, 0xd5, 0xd5, 0xdb, 0xda, 0xfd, 0x8a, 0x53, - 0x59, 0x01, 0x37, 0x01, 0x11, 0x01, 0x16, 0x01, 0x3a, 0x57, 0x53, 0x8f, - 0xf9, 0xf6, 0x00, 0x00, 0x00, 0x01, 0x01, 0x6a, 0x00, 0x00, 0x04, 0x83, - 0x04, 0x7b, 0x00, 0x11, 0x00, 0x4f, 0x40, 0x13, 0x06, 0x07, 0x0b, 0x03, - 0x00, 0x11, 0x03, 0x97, 0x0e, 0xbe, 0x09, 0xc2, 0x07, 0x0a, 0x06, 0x06, - 0x00, 0x08, 0x12, 0x10, 0xd4, 0xc4, 0xec, 0x32, 0x31, 0x00, 0x2f, 0xe4, - 0xf4, 0xec, 0xd4, 0xcc, 0x11, 0x39, 0x11, 0x39, 0x30, 0x40, 0x25, 0x10, - 0x00, 0x10, 0x01, 0x10, 0x11, 0x20, 0x00, 0x20, 0x01, 0x20, 0x11, 0x30, - 0x00, 0x30, 0x01, 0x33, 0x10, 0x30, 0x11, 0x40, 0x00, 0x40, 0x01, 0x43, - 0x10, 0x40, 0x11, 0x50, 0x00, 0x50, 0x01, 0x50, 0x10, 0x50, 0x11, 0x12, - 0x5d, 0x01, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, - 0x15, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x17, 0x04, 0x83, 0x3b, 0x7a, 0x49, - 0xac, 0xb6, 0xb9, 0xb9, 0x2e, 0xbf, 0x83, 0x44, 0x76, 0x36, 0x03, 0x79, - 0x2e, 0x2a, 0xd8, 0xcc, 0xfd, 0xd3, 0x04, 0x60, 0xdb, 0x77, 0x7f, 0x22, - 0x24, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xd5, 0xff, 0xe3, 0x04, 0x06, - 0x04, 0x7b, 0x00, 0x27, 0x00, 0x75, 0x40, 0x40, 0x0d, 0x0c, 0x02, 0x0e, - 0x0b, 0x17, 0x1f, 0x1e, 0x08, 0x09, 0x02, 0x07, 0x0a, 0x17, 0x1e, 0x1f, - 0x1e, 0x42, 0x1d, 0x1e, 0x18, 0x0a, 0x0b, 0x1e, 0x1f, 0x04, 0x15, 0x00, - 0x8b, 0x01, 0xc0, 0x04, 0x14, 0x8b, 0x15, 0xc0, 0x18, 0x8c, 0x11, 0x04, - 0x8c, 0x25, 0xbe, 0x11, 0x99, 0x28, 0x1d, 0x0a, 0x0b, 0x1f, 0x1b, 0x07, - 0x00, 0x4f, 0x1b, 0x06, 0x0e, 0x49, 0x07, 0x06, 0x14, 0x22, 0x45, 0x28, - 0x10, 0xf4, 0xc4, 0xec, 0xfc, 0xec, 0xe4, 0x11, 0x12, 0x39, 0x39, 0x39, - 0x39, 0x31, 0x00, 0x10, 0xe4, 0xf4, 0xec, 0x10, 0xfe, 0xf5, 0xee, 0x10, - 0xf5, 0xee, 0x12, 0x17, 0x39, 0x11, 0x12, 0x39, 0x30, 0x4b, 0x53, 0x58, - 0x07, 0x10, 0x0e, 0xed, 0x11, 0x17, 0x39, 0x07, 0x0e, 0xed, 0x11, 0x17, - 0x39, 0x59, 0x22, 0x01, 0x15, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, - 0x16, 0x1f, 0x01, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x27, - 0x35, 0x1e, 0x01, 0x33, 0x32, 0x36, 0x35, 0x34, 0x2f, 0x02, 0x2e, 0x01, - 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x03, 0xcd, 0x4f, 0xa0, 0x53, 0x7d, - 0x7b, 0x5c, 0xb7, 0x4a, 0x89, 0x8d, 0xec, 0xd2, 0x53, 0xb6, 0x6a, 0x67, - 0xbc, 0x54, 0x7a, 0x86, 0xf5, 0x08, 0x45, 0x9f, 0x92, 0xda, 0xca, 0x5a, - 0xa6, 0x04, 0x39, 0xb4, 0x2e, 0x2e, 0x51, 0x53, 0x4b, 0x4a, 0x23, 0x0e, - 0x1a, 0x9c, 0x7d, 0xa6, 0xbb, 0x23, 0x23, 0xbe, 0x35, 0x35, 0x63, 0x59, - 0x80, 0x31, 0x02, 0x0e, 0x1f, 0x93, 0x7f, 0xa1, 0xaf, 0x21, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x83, 0x00, 0x00, 0x04, 0x08, 0x05, 0x9e, 0x00, 0x13, - 0x00, 0x31, 0x40, 0x18, 0x0e, 0x05, 0x08, 0x0f, 0x03, 0xb6, 0x00, 0x11, - 0x01, 0xc2, 0x08, 0xb6, 0x0a, 0x08, 0x0b, 0x09, 0x02, 0x04, 0x00, 0x06, - 0x10, 0x12, 0x0e, 0x14, 0x10, 0xd4, 0x3c, 0xc4, 0xfc, 0x3c, 0xc4, 0x32, - 0x39, 0x39, 0x31, 0x00, 0x2f, 0xec, 0xf4, 0x3c, 0xc4, 0xec, 0x32, 0x11, - 0x39, 0x39, 0x30, 0x01, 0x11, 0x21, 0x15, 0x21, 0x11, 0x14, 0x16, 0x3b, - 0x01, 0x15, 0x23, 0x22, 0x26, 0x35, 0x11, 0x21, 0x35, 0x21, 0x11, 0x02, - 0x66, 0x01, 0xa2, 0xfe, 0x5e, 0x5e, 0x75, 0xcf, 0xe1, 0xcf, 0xaa, 0xfe, - 0xd5, 0x01, 0x2b, 0x05, 0x9e, 0xfe, 0xc2, 0x8f, 0xfd, 0xa0, 0x7c, 0x62, - 0x93, 0xa6, 0xcb, 0x02, 0x60, 0x8f, 0x01, 0x3e, 0x00, 0x01, 0x00, 0xc3, - 0xff, 0xe3, 0x04, 0x1b, 0x04, 0x5e, 0x00, 0x13, 0x00, 0x2c, 0x40, 0x18, - 0x09, 0x0e, 0x03, 0x00, 0x03, 0x01, 0x06, 0x8c, 0x11, 0x99, 0x0a, 0x01, - 0xc2, 0x0c, 0x0d, 0x09, 0x06, 0x0b, 0x4a, 0x02, 0x06, 0x00, 0x46, 0x14, - 0x10, 0xf4, 0xec, 0xfc, 0xec, 0x32, 0x31, 0x00, 0x2f, 0xe4, 0x32, 0xf4, - 0xec, 0x11, 0x17, 0x39, 0x39, 0x30, 0x13, 0x11, 0x33, 0x11, 0x14, 0x16, - 0x33, 0x32, 0x36, 0x35, 0x11, 0x33, 0x11, 0x23, 0x35, 0x0e, 0x01, 0x23, - 0x22, 0x26, 0xc3, 0xb8, 0x6b, 0x70, 0x82, 0x8a, 0xb9, 0xb9, 0x31, 0xa9, - 0x71, 0xac, 0xa8, 0x01, 0xa8, 0x02, 0xb6, 0xfd, 0x4a, 0x97, 0x8e, 0xb7, - 0xab, 0x02, 0x79, 0xfb, 0xa2, 0xa8, 0x61, 0x64, 0xe1, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x64, 0x00, 0x00, 0x04, 0x6d, 0x04, 0x60, 0x00, 0x06, - 0x00, 0x65, 0x40, 0x29, 0x03, 0x17, 0x04, 0x05, 0x04, 0x02, 0x17, 0x01, - 0x02, 0x05, 0x05, 0x04, 0x02, 0x17, 0x03, 0x02, 0x06, 0x00, 0x06, 0x01, - 0x17, 0x00, 0x00, 0x06, 0x42, 0x02, 0x03, 0x00, 0xc2, 0x05, 0x06, 0x05, - 0x03, 0x02, 0x01, 0x05, 0x04, 0x49, 0x00, 0x45, 0x07, 0x10, 0xf4, 0xec, - 0x17, 0x39, 0x31, 0x00, 0x2f, 0xe4, 0x32, 0x39, 0x30, 0x4b, 0x53, 0x58, - 0x07, 0x10, 0x05, 0xed, 0x07, 0x10, 0x08, 0xed, 0x07, 0x10, 0x08, 0xed, - 0x07, 0x10, 0x05, 0xed, 0x59, 0x22, 0xb2, 0x27, 0x02, 0x01, 0x00, 0x5d, - 0x40, 0x0e, 0x07, 0x00, 0x07, 0x01, 0x08, 0x03, 0x08, 0x04, 0x04, 0x05, - 0x02, 0x25, 0x02, 0x02, 0x5d, 0x01, 0x5d, 0x13, 0x33, 0x09, 0x01, 0x33, - 0x01, 0x23, 0x64, 0xbf, 0x01, 0x45, 0x01, 0x46, 0xbf, 0xfe, 0x72, 0xed, - 0x04, 0x60, 0xfc, 0x54, 0x03, 0xac, 0xfb, 0xa0, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x04, 0xd1, 0x04, 0x60, 0x00, 0x0c, 0x01, 0x11, 0x40, 0x45, - 0x0b, 0x02, 0x03, 0x02, 0x0a, 0x09, 0x0a, 0x03, 0x03, 0x02, 0x0a, 0x0b, - 0x0a, 0x04, 0x05, 0x04, 0x09, 0x05, 0x05, 0x04, 0x06, 0x17, 0x07, 0x08, - 0x07, 0x05, 0x17, 0x04, 0x05, 0x08, 0x08, 0x07, 0x02, 0x17, 0x03, 0x02, - 0x0c, 0x00, 0x0c, 0x01, 0x17, 0x00, 0x0c, 0x42, 0x0a, 0x05, 0x02, 0x03, - 0x08, 0x03, 0x06, 0x00, 0xc2, 0x0b, 0x08, 0x0c, 0x0b, 0x0a, 0x09, 0x08, - 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x0b, 0x07, 0x00, 0x2f, 0xcc, 0x17, - 0x39, 0x31, 0x00, 0x2f, 0x3c, 0xf4, 0x3c, 0xc4, 0x11, 0x17, 0x39, 0x30, - 0x4b, 0x53, 0x58, 0x07, 0x05, 0xed, 0x07, 0x10, 0x08, 0xed, 0x07, 0x10, - 0x08, 0xed, 0x07, 0x10, 0x05, 0xed, 0x07, 0x10, 0x05, 0xc9, 0x07, 0x10, - 0x08, 0xc9, 0x07, 0x10, 0x08, 0xc9, 0x07, 0x10, 0x05, 0xc9, 0x59, 0x22, - 0xb2, 0x0f, 0x0a, 0x01, 0x00, 0x5d, 0x40, 0x8c, 0x0b, 0x09, 0x04, 0x0b, - 0x1f, 0x00, 0x1f, 0x01, 0x1d, 0x02, 0x1a, 0x03, 0x1c, 0x04, 0x19, 0x05, - 0x1c, 0x09, 0x1b, 0x0a, 0x1a, 0x0b, 0x1f, 0x0c, 0x26, 0x00, 0x26, 0x01, - 0x29, 0x02, 0x26, 0x05, 0x29, 0x06, 0x29, 0x07, 0x23, 0x08, 0x2c, 0x0c, - 0x39, 0x02, 0x36, 0x05, 0x39, 0x06, 0x39, 0x07, 0x33, 0x08, 0x3c, 0x0c, - 0x45, 0x08, 0x49, 0x09, 0x46, 0x0b, 0x4a, 0x0c, 0x56, 0x08, 0x58, 0x09, - 0x57, 0x0b, 0x59, 0x0c, 0x66, 0x02, 0x69, 0x03, 0x66, 0x04, 0x69, 0x05, - 0x6a, 0x09, 0x65, 0x0b, 0x76, 0x02, 0x7a, 0x05, 0x78, 0x08, 0x7c, 0x09, - 0x72, 0x0b, 0x2d, 0x0f, 0x0a, 0x19, 0x02, 0x1f, 0x03, 0x1f, 0x04, 0x19, - 0x05, 0x1f, 0x0a, 0x1f, 0x0a, 0x2b, 0x02, 0x2b, 0x05, 0x3e, 0x02, 0x3e, - 0x05, 0x3c, 0x0a, 0x48, 0x0a, 0x59, 0x0a, 0x6a, 0x02, 0x69, 0x05, 0x68, - 0x0a, 0x7b, 0x02, 0x7f, 0x03, 0x79, 0x04, 0x7f, 0x04, 0x7a, 0x05, 0x7c, - 0x0a, 0x7f, 0x0a, 0x18, 0x5d, 0x01, 0x5d, 0x11, 0x33, 0x1b, 0x01, 0x33, - 0x1b, 0x01, 0x33, 0x01, 0x23, 0x0b, 0x01, 0x23, 0xb6, 0xc3, 0xa0, 0x9d, - 0xa2, 0xc3, 0xb6, 0xfe, 0xfa, 0xb0, 0xb3, 0xb2, 0xb0, 0x04, 0x60, 0xfc, - 0x77, 0x02, 0x42, 0xfd, 0xbe, 0x03, 0x89, 0xfb, 0xa0, 0x02, 0x66, 0xfd, - 0x9a, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x4c, 0x00, 0x00, 0x04, 0x85, - 0x04, 0x60, 0x00, 0x0b, 0x00, 0xa9, 0x40, 0x48, 0x05, 0x17, 0x06, 0x07, - 0x06, 0x04, 0x17, 0x03, 0x04, 0x07, 0x07, 0x06, 0x04, 0x17, 0x05, 0x04, - 0x01, 0x02, 0x01, 0x03, 0x17, 0x02, 0x02, 0x01, 0x0b, 0x17, 0x00, 0x01, - 0x00, 0x0a, 0x17, 0x09, 0x0a, 0x01, 0x01, 0x00, 0x0a, 0x17, 0x0b, 0x0a, - 0x07, 0x08, 0x07, 0x09, 0x17, 0x08, 0x08, 0x07, 0x42, 0x0a, 0x07, 0x04, - 0x01, 0x04, 0x08, 0x00, 0xc2, 0x05, 0x02, 0x0a, 0x07, 0x04, 0x01, 0x04, - 0x08, 0x00, 0x02, 0x49, 0x08, 0x06, 0x45, 0x0c, 0x10, 0xf4, 0xc4, 0xfc, - 0xc4, 0x11, 0x17, 0x39, 0x31, 0x00, 0x2f, 0x3c, 0xe4, 0x32, 0x17, 0x39, - 0x30, 0x4b, 0x53, 0x58, 0x07, 0x10, 0x05, 0xed, 0x07, 0x10, 0x08, 0xed, - 0x07, 0x10, 0x08, 0xed, 0x07, 0x10, 0x05, 0xed, 0x07, 0x10, 0x05, 0xed, - 0x07, 0x10, 0x08, 0xed, 0x07, 0x10, 0x08, 0xed, 0x07, 0x10, 0x05, 0xed, - 0x59, 0x22, 0xb2, 0x07, 0x0a, 0x01, 0x00, 0x5d, 0x40, 0x1e, 0x09, 0x01, - 0x06, 0x07, 0x66, 0x01, 0x69, 0x07, 0x76, 0x01, 0x79, 0x07, 0x06, 0x07, - 0x01, 0x07, 0x07, 0x06, 0x0a, 0x15, 0x0a, 0x3a, 0x04, 0x34, 0x0a, 0x5a, - 0x04, 0x56, 0x0a, 0x08, 0x5d, 0x01, 0x5d, 0x09, 0x02, 0x23, 0x09, 0x01, - 0x23, 0x09, 0x01, 0x33, 0x09, 0x01, 0x04, 0x5e, 0xfe, 0x6f, 0x01, 0xb8, - 0xd5, 0xfe, 0xb8, 0xfe, 0xb9, 0xd5, 0x01, 0xb8, 0xfe, 0x6f, 0xcc, 0x01, - 0x29, 0x01, 0x27, 0x04, 0x60, 0xfd, 0xe8, 0xfd, 0xb8, 0x01, 0xc1, 0xfe, - 0x3f, 0x02, 0x48, 0x02, 0x18, 0xfe, 0x6b, 0x01, 0x95, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x68, 0xfe, 0x56, 0x04, 0x81, 0x04, 0x60, 0x00, 0x12, - 0x00, 0xa0, 0x40, 0x45, 0x0d, 0x17, 0x0e, 0x0d, 0x02, 0x03, 0x02, 0x0a, - 0x0b, 0x02, 0x09, 0x0c, 0x17, 0x03, 0x03, 0x02, 0x11, 0x17, 0x12, 0x00, - 0x12, 0x10, 0x17, 0x0f, 0x10, 0x00, 0x00, 0x12, 0x10, 0x17, 0x11, 0x10, - 0x0d, 0x0e, 0x0d, 0x0f, 0x17, 0x0e, 0x0e, 0x0d, 0x42, 0x10, 0x13, 0x0d, - 0x00, 0x0e, 0x09, 0x8c, 0x07, 0xc3, 0x11, 0x0e, 0xc2, 0x13, 0x11, 0x10, - 0x0f, 0x0d, 0x0a, 0x07, 0x00, 0x07, 0x12, 0x08, 0x12, 0x49, 0x0e, 0x45, - 0x13, 0x10, 0xf4, 0xec, 0xc4, 0x11, 0x17, 0x39, 0x31, 0x00, 0x10, 0xe4, - 0x32, 0xf4, 0xec, 0x11, 0x39, 0x39, 0x12, 0x39, 0x30, 0x4b, 0x53, 0x58, - 0x07, 0x10, 0x05, 0xed, 0x07, 0x10, 0x08, 0xed, 0x07, 0x10, 0x08, 0xed, - 0x07, 0x10, 0x05, 0xed, 0x07, 0x10, 0x05, 0xed, 0x11, 0x17, 0x39, 0x07, - 0x10, 0x08, 0xed, 0x59, 0x22, 0xb2, 0x38, 0x12, 0x01, 0x01, 0x5d, 0x40, - 0x1a, 0x04, 0x10, 0x76, 0x10, 0x02, 0x08, 0x11, 0x08, 0x12, 0x19, 0x0c, - 0x19, 0x0d, 0x26, 0x0e, 0x26, 0x0f, 0x38, 0x11, 0x49, 0x11, 0x49, 0x12, - 0x59, 0x0d, 0x0a, 0x5d, 0x00, 0x5d, 0x01, 0x06, 0x07, 0x02, 0x07, 0x0e, - 0x01, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x36, 0x37, 0x01, 0x33, 0x09, 0x01, - 0x33, 0x03, 0x5a, 0x2e, 0x47, 0x63, 0x22, 0x2e, 0x8a, 0x5c, 0x94, 0x6d, - 0x51, 0x5c, 0x47, 0xfe, 0x4f, 0xc3, 0x01, 0x4c, 0x01, 0x47, 0xc3, 0x01, - 0x68, 0x75, 0xbf, 0xfe, 0xf8, 0x3a, 0x4e, 0x4e, 0x9a, 0x5e, 0xc4, 0x04, - 0x4e, 0xfc, 0x94, 0x03, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xcb, - 0x00, 0x00, 0x04, 0x10, 0x04, 0x62, 0x00, 0x09, 0x00, 0x58, 0x40, 0x1c, - 0x03, 0x17, 0x07, 0x08, 0x07, 0x08, 0x17, 0x02, 0x03, 0x02, 0x42, 0x08, - 0xb6, 0x00, 0xc2, 0x03, 0xb6, 0x05, 0x08, 0x03, 0x00, 0x04, 0x01, 0x49, - 0x00, 0x06, 0x45, 0x0a, 0x10, 0xf4, 0xc4, 0xec, 0x32, 0x11, 0x39, 0x39, - 0x31, 0x00, 0x2f, 0xec, 0xf4, 0xec, 0x30, 0x4b, 0x53, 0x58, 0x07, 0x10, - 0x05, 0xed, 0x07, 0x10, 0x05, 0xed, 0x59, 0x22, 0xb2, 0x38, 0x08, 0x01, - 0x01, 0x5d, 0x40, 0x15, 0x36, 0x03, 0x38, 0x08, 0x45, 0x03, 0x4a, 0x08, - 0x57, 0x03, 0x58, 0x08, 0x65, 0x03, 0x6a, 0x08, 0x75, 0x03, 0x7a, 0x08, - 0x0a, 0x5d, 0x13, 0x21, 0x15, 0x01, 0x21, 0x15, 0x21, 0x35, 0x01, 0x21, - 0xe3, 0x03, 0x2d, 0xfd, 0x7d, 0x02, 0x83, 0xfc, 0xbb, 0x02, 0x83, 0xfd, - 0x95, 0x04, 0x62, 0xa8, 0xfc, 0xdc, 0x96, 0xaa, 0x03, 0x25, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xdd, 0xfe, 0xb2, 0x03, 0xf4, 0x06, 0x14, 0x00, 0x24, - 0x00, 0x66, 0x40, 0x35, 0x19, 0x0f, 0x15, 0x0b, 0x06, 0x25, 0x09, 0x1a, - 0x10, 0x15, 0x1d, 0x0b, 0x05, 0x20, 0x21, 0x03, 0x00, 0x0b, 0xb6, 0x09, - 0x00, 0xb6, 0x01, 0xc6, 0x09, 0xc7, 0x15, 0xb6, 0x13, 0xb5, 0x25, 0x0c, - 0x09, 0x0a, 0x05, 0x24, 0x16, 0x19, 0x00, 0x1d, 0x0a, 0x05, 0x13, 0x02, - 0x14, 0x00, 0x20, 0x19, 0x3d, 0x0a, 0x0f, 0x05, 0x25, 0x10, 0xd4, 0x3c, - 0xc4, 0xfc, 0x3c, 0xc4, 0x32, 0x39, 0x39, 0x11, 0x12, 0x39, 0x11, 0x12, - 0x39, 0x39, 0x11, 0x12, 0x39, 0x39, 0x31, 0x00, 0x10, 0xfc, 0xec, 0xe4, - 0xf4, 0xec, 0x10, 0xee, 0x12, 0x17, 0x39, 0x12, 0x39, 0x11, 0x39, 0x39, - 0x11, 0x12, 0x39, 0x11, 0x12, 0x39, 0x39, 0x30, 0x05, 0x15, 0x23, 0x22, - 0x26, 0x3d, 0x01, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x36, 0x3d, - 0x01, 0x34, 0x36, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x06, 0x1d, 0x01, 0x14, - 0x06, 0x07, 0x1e, 0x01, 0x1d, 0x01, 0x14, 0x16, 0x33, 0x03, 0xf4, 0x40, - 0xf9, 0xa9, 0x6b, 0x8c, 0x3e, 0x3e, 0x8d, 0x6a, 0xa9, 0xf9, 0x40, 0x46, - 0x8c, 0x55, 0x5b, 0x6e, 0x6f, 0x5a, 0x55, 0x8c, 0xbe, 0x90, 0x94, 0xdd, - 0xef, 0x97, 0x74, 0x8f, 0x72, 0x96, 0xf0, 0xdd, 0x93, 0x8f, 0x57, 0x8e, - 0xf8, 0x9d, 0x8e, 0x19, 0x1b, 0x8e, 0x9c, 0xf8, 0x8f, 0x56, 0x00, 0x00, - 0x00, 0x01, 0x02, 0x12, 0xfe, 0x1d, 0x02, 0xbe, 0x06, 0x1d, 0x00, 0x03, - 0x00, 0x12, 0xb7, 0x01, 0x00, 0xb5, 0x04, 0x00, 0x04, 0x02, 0x04, 0x10, - 0xd4, 0xec, 0x31, 0x00, 0x10, 0xfc, 0xcc, 0x30, 0x01, 0x11, 0x23, 0x11, - 0x02, 0xbe, 0xac, 0x06, 0x1d, 0xf8, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xdd, 0xfe, 0xb2, 0x03, 0xf4, 0x06, 0x14, 0x00, 0x24, - 0x00, 0x6a, 0x40, 0x37, 0x1f, 0x25, 0x1b, 0x16, 0x0c, 0x0f, 0x08, 0x1b, - 0x0b, 0x15, 0x19, 0x0f, 0x04, 0x05, 0x20, 0x03, 0x00, 0x19, 0xb6, 0x1b, - 0x00, 0xb6, 0x23, 0xc6, 0x1b, 0xc7, 0x0f, 0xb6, 0x11, 0xb5, 0x25, 0x1c, - 0x19, 0x1a, 0x15, 0x0f, 0x01, 0x04, 0x00, 0x08, 0x1a, 0x15, 0x23, 0x12, - 0x04, 0x00, 0x1a, 0x1f, 0x15, 0x3d, 0x10, 0x00, 0x0b, 0x04, 0x25, 0x10, - 0xd4, 0x3c, 0xc4, 0x32, 0xfc, 0x3c, 0xc4, 0x11, 0x12, 0x39, 0x39, 0x11, - 0x12, 0x39, 0x11, 0x12, 0x39, 0x39, 0x11, 0x12, 0x39, 0x39, 0x31, 0x00, - 0x10, 0xfc, 0xec, 0xe4, 0xf4, 0xec, 0x10, 0xee, 0x12, 0x17, 0x39, 0x11, - 0x12, 0x39, 0x39, 0x11, 0x39, 0x11, 0x39, 0x39, 0x11, 0x12, 0x39, 0x30, - 0x17, 0x33, 0x32, 0x36, 0x3d, 0x01, 0x34, 0x36, 0x37, 0x2e, 0x01, 0x3d, - 0x01, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x16, 0x1d, 0x01, 0x14, - 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x06, 0x1d, 0x01, 0x14, 0x06, 0x2b, - 0x01, 0xdd, 0x44, 0x8d, 0x56, 0x5a, 0x6f, 0x6e, 0x5b, 0x56, 0x8d, 0x44, - 0x3e, 0xf9, 0xa8, 0x6b, 0x8d, 0x40, 0x40, 0x8d, 0x6b, 0xa8, 0xf9, 0x3e, - 0xbe, 0x58, 0x8d, 0xf8, 0x9c, 0x8e, 0x1b, 0x19, 0x8e, 0x9d, 0xf8, 0x8d, - 0x58, 0x8f, 0x93, 0xdd, 0xf0, 0x96, 0x72, 0x8f, 0x74, 0x97, 0xef, 0xdd, - 0x94, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x58, 0x01, 0xec, 0x04, 0x79, - 0x03, 0x0c, 0x00, 0x1b, 0x00, 0x26, 0x40, 0x12, 0x01, 0x0b, 0x04, 0x0f, - 0x00, 0x0e, 0x04, 0xa0, 0x19, 0x12, 0x00, 0xa0, 0x0b, 0x1c, 0x00, 0x0e, - 0x27, 0x1c, 0x10, 0xfc, 0xc4, 0x31, 0x00, 0x10, 0xd4, 0xfc, 0x3c, 0xd4, - 0xec, 0x32, 0x12, 0x39, 0x11, 0x12, 0x39, 0x30, 0x01, 0x15, 0x0e, 0x01, - 0x23, 0x22, 0x27, 0x26, 0x27, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x35, - 0x3e, 0x01, 0x33, 0x32, 0x16, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x36, - 0x04, 0x79, 0x4b, 0x8f, 0x4f, 0x5a, 0x71, 0x16, 0x0b, 0x4d, 0x67, 0x33, - 0x4f, 0x8d, 0x49, 0x4e, 0x92, 0x53, 0x35, 0x64, 0x4a, 0x0c, 0x15, 0x74, - 0x5d, 0x46, 0x89, 0x03, 0x0c, 0xae, 0x3b, 0x37, 0x33, 0x0a, 0x04, 0x21, - 0x18, 0x3b, 0x3f, 0xae, 0x3c, 0x36, 0x16, 0x1f, 0x05, 0x0a, 0x37, 0x3d, - 0x00, 0x02, 0x02, 0x04, 0x00, 0x00, 0x02, 0xcf, 0x05, 0xd5, 0x00, 0x03, - 0x00, 0x09, 0x00, 0x1e, 0x40, 0x0e, 0x06, 0x00, 0x86, 0x01, 0x88, 0x04, - 0x07, 0x06, 0x08, 0x02, 0x03, 0x04, 0x00, 0x0a, 0x10, 0xd4, 0x3c, 0xec, - 0x32, 0x39, 0x39, 0x31, 0x00, 0x2f, 0xf4, 0xfc, 0xcc, 0x30, 0x01, 0x35, - 0x33, 0x15, 0x03, 0x11, 0x13, 0x33, 0x13, 0x11, 0x02, 0x04, 0xcb, 0xcb, - 0x15, 0xa1, 0x15, 0x04, 0xd7, 0xfe, 0xfe, 0xfb, 0x29, 0x02, 0x8f, 0x01, - 0x65, 0xfe, 0x9b, 0xfd, 0x71, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xd5, - 0xfe, 0xc7, 0x04, 0x25, 0x05, 0x98, 0x00, 0x1a, 0x00, 0x21, 0x00, 0x4e, - 0x40, 0x2a, 0x1b, 0x08, 0x05, 0x04, 0x1c, 0x00, 0x8b, 0x01, 0x8d, 0x1c, - 0x09, 0x8b, 0x08, 0x8d, 0x05, 0xcb, 0x0c, 0x1c, 0xcb, 0x16, 0x18, 0x15, - 0xbe, 0x0f, 0x0c, 0x99, 0x0d, 0x22, 0x1b, 0x15, 0x0e, 0x07, 0x17, 0x0c, - 0x04, 0x08, 0x00, 0x1f, 0x1e, 0x12, 0x45, 0x22, 0x10, 0xf4, 0xec, 0xd4, - 0x3c, 0xd4, 0x3c, 0x3c, 0xec, 0x32, 0x32, 0x31, 0x00, 0x10, 0xc4, 0xe4, - 0x32, 0xf4, 0x3c, 0xc4, 0xec, 0x10, 0xfe, 0xf4, 0xee, 0x10, 0xf5, 0xee, - 0x11, 0x39, 0x11, 0x12, 0x39, 0x30, 0x01, 0x15, 0x2e, 0x01, 0x27, 0x11, - 0x3e, 0x01, 0x37, 0x15, 0x0e, 0x01, 0x07, 0x11, 0x23, 0x11, 0x26, 0x00, - 0x35, 0x34, 0x00, 0x37, 0x11, 0x33, 0x11, 0x1e, 0x01, 0x01, 0x11, 0x0e, - 0x01, 0x15, 0x14, 0x16, 0x04, 0x25, 0x43, 0x82, 0x3f, 0x3f, 0x83, 0x42, - 0x49, 0x82, 0x39, 0x67, 0xe1, 0xfe, 0xfc, 0x01, 0x07, 0xde, 0x67, 0x39, - 0x82, 0xfe, 0xde, 0x84, 0xa0, 0xa0, 0x04, 0x35, 0xac, 0x28, 0x2c, 0x04, - 0xfc, 0x9a, 0x05, 0x2d, 0x28, 0xac, 0x1f, 0x22, 0x03, 0xfe, 0xe2, 0x01, - 0x1e, 0x16, 0x01, 0x39, 0xfb, 0xfa, 0x01, 0x3d, 0x13, 0x01, 0x1f, 0xfe, - 0xe1, 0x03, 0x22, 0xfc, 0x2b, 0x03, 0x60, 0x0c, 0xec, 0xb8, 0xb8, 0xeb, - 0x00, 0x01, 0x00, 0x8b, 0x00, 0x00, 0x04, 0x58, 0x05, 0xf0, 0x00, 0x1b, - 0x00, 0x3e, 0x40, 0x20, 0x07, 0x16, 0x01, 0x12, 0x0a, 0xb6, 0x14, 0x08, - 0x0c, 0x01, 0x8b, 0x00, 0xa7, 0x04, 0x97, 0x19, 0x96, 0x10, 0x0c, 0x97, - 0x0e, 0x00, 0x0d, 0x09, 0x0b, 0x07, 0x1e, 0x0f, 0x13, 0x15, 0x11, 0x1c, - 0x10, 0xd4, 0x3c, 0xc4, 0xc4, 0xfc, 0x3c, 0xc4, 0xd4, 0xc4, 0x31, 0x00, - 0x2f, 0xec, 0x32, 0xf4, 0xec, 0xf4, 0xec, 0x10, 0xd4, 0x3c, 0xee, 0x32, - 0x12, 0x39, 0x39, 0x30, 0x01, 0x15, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x1d, - 0x01, 0x21, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x35, 0x33, 0x11, 0x23, - 0x35, 0x33, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x04, 0x44, 0x3e, 0x7f, - 0x43, 0x86, 0x7f, 0x01, 0x73, 0xfe, 0x8d, 0x02, 0x19, 0xfc, 0x33, 0xec, - 0xc7, 0xc7, 0xdb, 0xdf, 0x41, 0x89, 0x05, 0xb6, 0xb8, 0x2c, 0x2c, 0xb3, - 0xc0, 0xd9, 0x8f, 0xfe, 0x2f, 0xaa, 0xaa, 0x01, 0xd1, 0x8f, 0xee, 0xfe, - 0xfa, 0x1d, 0x00, 0x00, 0x00, 0x02, 0x00, 0xcd, 0x00, 0xc3, 0x04, 0x4c, - 0x04, 0x42, 0x00, 0x0b, 0x00, 0x2f, 0x00, 0x81, 0x40, 0x1a, 0x20, 0x16, - 0x1b, 0x17, 0x0e, 0x28, 0x2d, 0x0d, 0x18, 0x1e, 0x1b, 0x09, 0x2a, 0x0c, - 0x2d, 0x27, 0x21, 0x15, 0x0f, 0x04, 0x03, 0x09, 0xff, 0x1f, 0x17, 0x1b, - 0xb8, 0x01, 0x00, 0x40, 0x27, 0x03, 0xff, 0x29, 0x0d, 0x2d, 0x30, 0x1f, - 0x29, 0x24, 0x20, 0x0d, 0x17, 0x12, 0x0e, 0x21, 0x27, 0x24, 0x06, 0x0f, - 0x15, 0x12, 0x2a, 0x1e, 0x18, 0x0c, 0x04, 0x06, 0x00, 0x78, 0x16, 0x0e, - 0x12, 0x79, 0x06, 0x78, 0x28, 0x20, 0x24, 0x30, 0x10, 0xd4, 0xc4, 0x32, - 0xec, 0xfc, 0xc4, 0x32, 0xec, 0x11, 0x17, 0x39, 0x11, 0x39, 0x39, 0x11, - 0x12, 0x39, 0x39, 0x11, 0x12, 0x39, 0x39, 0x11, 0x12, 0x39, 0x39, 0x31, - 0x00, 0x10, 0xd4, 0xc4, 0x32, 0xec, 0xfc, 0xc4, 0x32, 0xec, 0x11, 0x17, - 0x39, 0x12, 0x39, 0x39, 0x11, 0x12, 0x39, 0x39, 0x11, 0x12, 0x39, 0x39, - 0x11, 0x12, 0x39, 0x39, 0x30, 0x01, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, - 0x14, 0x16, 0x33, 0x32, 0x36, 0x03, 0x37, 0x17, 0x07, 0x1e, 0x01, 0x15, - 0x14, 0x06, 0x07, 0x17, 0x07, 0x27, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x27, - 0x07, 0x27, 0x37, 0x2e, 0x01, 0x35, 0x34, 0x36, 0x37, 0x27, 0x37, 0x17, - 0x3e, 0x01, 0x33, 0x32, 0x16, 0x03, 0x64, 0x7c, 0x5b, 0x5a, 0x7d, 0x7d, - 0x5a, 0x5b, 0x7c, 0x18, 0xa6, 0x5a, 0xa6, 0x1e, 0x1d, 0x1e, 0x1f, 0xa8, - 0x5e, 0xa6, 0x2e, 0x5b, 0x32, 0x30, 0x60, 0x30, 0xa4, 0x5c, 0xa6, 0x1f, - 0x1d, 0x1f, 0x1f, 0xa8, 0x5e, 0xa6, 0x2e, 0x5b, 0x33, 0x2e, 0x5e, 0x02, - 0x83, 0x5a, 0x7b, 0x7b, 0x5a, 0x5c, 0x7d, 0x7e, 0x01, 0x74, 0xa6, 0x5d, - 0xa6, 0x31, 0x5d, 0x30, 0x32, 0x5b, 0x2d, 0xa6, 0x5e, 0xa7, 0x1f, 0x1e, - 0x1d, 0x1c, 0xa3, 0x5a, 0xa6, 0x33, 0x5d, 0x2e, 0x32, 0x5d, 0x2d, 0xa6, - 0x5f, 0xa8, 0x1f, 0x1e, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x25, - 0x00, 0x00, 0x04, 0xac, 0x05, 0xd5, 0x00, 0x18, 0x00, 0x7f, 0x40, 0x44, - 0x03, 0x25, 0x04, 0x09, 0x04, 0x02, 0x25, 0x01, 0x02, 0x09, 0x09, 0x04, - 0x02, 0x25, 0x03, 0x02, 0x14, 0x00, 0x14, 0x01, 0x25, 0x00, 0x00, 0x14, - 0x42, 0x02, 0x07, 0x05, 0x10, 0x0c, 0xe7, 0x12, 0x0a, 0x17, 0x05, 0xe7, - 0x15, 0x07, 0x03, 0x00, 0x88, 0x0e, 0x18, 0x01, 0x11, 0x02, 0x0f, 0x08, - 0x05, 0x03, 0x03, 0x06, 0x04, 0x3c, 0x0b, 0x06, 0x65, 0x0d, 0x09, 0x1e, - 0x16, 0x11, 0x65, 0x00, 0x3c, 0x13, 0x0f, 0x19, 0x10, 0xd4, 0x3c, 0xec, - 0xec, 0x32, 0xfc, 0x3c, 0xec, 0x32, 0xec, 0x12, 0x17, 0x39, 0x12, 0x39, - 0x11, 0x39, 0x39, 0x31, 0x00, 0x2f, 0xe4, 0x32, 0xd4, 0x3c, 0xec, 0x32, - 0xd4, 0x3c, 0xec, 0x32, 0x11, 0x12, 0x39, 0x30, 0x4b, 0x53, 0x58, 0x07, - 0x10, 0x05, 0xed, 0x07, 0x10, 0x08, 0xed, 0x07, 0x10, 0x08, 0xed, 0x07, - 0x10, 0x05, 0xed, 0x59, 0x22, 0x13, 0x33, 0x09, 0x01, 0x33, 0x01, 0x33, - 0x15, 0x21, 0x07, 0x15, 0x21, 0x15, 0x21, 0x11, 0x23, 0x11, 0x21, 0x35, - 0x21, 0x35, 0x27, 0x21, 0x35, 0x33, 0x25, 0xd7, 0x01, 0x6c, 0x01, 0x6b, - 0xd9, 0xfe, 0xb6, 0xfc, 0xfe, 0xc5, 0x56, 0x01, 0x91, 0xfe, 0x6f, 0xcb, - 0xfe, 0x71, 0x01, 0x8f, 0x5a, 0xfe, 0xcb, 0xf3, 0x05, 0xd5, 0xfd, 0x6d, - 0x02, 0x93, 0xfd, 0xcf, 0x6f, 0x97, 0x23, 0x6f, 0xfd, 0xf4, 0x02, 0x0c, - 0x6f, 0x23, 0x97, 0x6f, 0x00, 0x02, 0x02, 0x12, 0xfe, 0xa2, 0x02, 0xbe, - 0x05, 0x98, 0x00, 0x03, 0x00, 0x07, 0x00, 0x21, 0xbc, 0x00, 0x05, 0x01, - 0x07, 0x00, 0x04, 0x00, 0x00, 0x01, 0x07, 0xb7, 0x01, 0x08, 0x04, 0x00, - 0x04, 0x06, 0x02, 0x08, 0x10, 0xd4, 0x3c, 0xec, 0x32, 0x31, 0x00, 0x10, - 0xd4, 0xec, 0xd4, 0xec, 0x30, 0x01, 0x11, 0x23, 0x11, 0x13, 0x11, 0x23, - 0x11, 0x02, 0xbe, 0xac, 0xac, 0xac, 0x05, 0x98, 0xfd, 0x0a, 0x02, 0xf6, - 0xfc, 0x00, 0xfd, 0x0a, 0x02, 0xf6, 0x00, 0x00, 0x00, 0x02, 0x00, 0xc7, - 0xff, 0x3d, 0x04, 0x0c, 0x05, 0xf0, 0x00, 0x32, 0x00, 0x3e, 0x00, 0x6a, - 0x40, 0x3c, 0x23, 0x24, 0x1e, 0x39, 0x33, 0x0b, 0x11, 0x24, 0x2a, 0x04, - 0x01, 0x1b, 0x8f, 0x1a, 0xce, 0x1e, 0xcf, 0x17, 0x01, 0x8f, 0x00, 0xce, - 0x04, 0xcf, 0x30, 0x96, 0x17, 0x3f, 0x23, 0x07, 0x11, 0x3c, 0x21, 0x2a, - 0x36, 0x0b, 0x24, 0x39, 0x33, 0x04, 0x07, 0x21, 0x55, 0x14, 0x07, 0x55, - 0x2d, 0x14, 0x3c, 0x55, 0x00, 0x26, 0x0e, 0x2d, 0x1a, 0x26, 0x36, 0x55, - 0x27, 0x3f, 0x10, 0xd4, 0xec, 0xe4, 0xc4, 0xd4, 0xe4, 0xec, 0xc4, 0x10, - 0xee, 0x10, 0xee, 0x11, 0x17, 0x39, 0x12, 0x39, 0x11, 0x12, 0x39, 0x12, - 0x39, 0x31, 0x00, 0x10, 0xc4, 0xf4, 0xec, 0xf4, 0xec, 0x10, 0xee, 0xf6, - 0xee, 0x11, 0x17, 0x39, 0x39, 0x39, 0x11, 0x12, 0x39, 0x30, 0x01, 0x15, - 0x2e, 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x1e, 0x01, - 0x15, 0x14, 0x06, 0x07, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, - 0x27, 0x35, 0x1e, 0x01, 0x33, 0x32, 0x36, 0x35, 0x34, 0x2f, 0x01, 0x2e, - 0x01, 0x35, 0x34, 0x36, 0x37, 0x2e, 0x01, 0x35, 0x34, 0x36, 0x33, 0x32, - 0x16, 0x01, 0x0e, 0x01, 0x15, 0x14, 0x16, 0x17, 0x3e, 0x01, 0x35, 0x34, - 0x26, 0x03, 0xa8, 0x53, 0x8f, 0x39, 0x61, 0x6b, 0xcd, 0x1a, 0x0e, 0xd4, - 0x82, 0x5b, 0x5d, 0x3d, 0x3a, 0xcc, 0xad, 0x49, 0x9b, 0x57, 0x57, 0x94, - 0x39, 0x66, 0x71, 0xdd, 0x18, 0xd6, 0x80, 0x5d, 0x5b, 0x3c, 0x3b, 0xc8, - 0xa7, 0x48, 0x99, 0xfe, 0x8d, 0x3e, 0x3d, 0x8d, 0xf7, 0x3e, 0x3c, 0x8f, - 0x05, 0xb6, 0xa4, 0x27, 0x27, 0x50, 0x47, 0x5a, 0x73, 0x0f, 0x08, 0x77, - 0x9a, 0x65, 0x5a, 0x8c, 0x35, 0x34, 0x6d, 0x40, 0x8e, 0xa8, 0x1d, 0x1d, - 0xa4, 0x27, 0x27, 0x54, 0x4c, 0x66, 0x7b, 0x0e, 0x78, 0x99, 0x66, 0x5b, - 0x8f, 0x31, 0x2c, 0x70, 0x45, 0x82, 0x9f, 0x1d, 0xfd, 0xd5, 0x2d, 0x5a, - 0x2f, 0x4c, 0x87, 0x85, 0x2d, 0x5a, 0x2f, 0x4c, 0x88, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x01, 0x3f, 0x05, 0x46, 0x03, 0x91, 0x06, 0x10, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x1d, 0x40, 0x0e, 0x06, 0x02, 0xde, 0x04, 0x00, 0xdd, - 0x08, 0x05, 0x61, 0x04, 0x01, 0x61, 0x00, 0x08, 0x10, 0xd4, 0xfc, 0xd4, - 0xec, 0x31, 0x00, 0x10, 0xf4, 0x3c, 0xec, 0x32, 0x30, 0x01, 0x33, 0x15, - 0x23, 0x25, 0x33, 0x15, 0x23, 0x01, 0x3f, 0xcb, 0xcb, 0x01, 0x88, 0xca, - 0xca, 0x06, 0x10, 0xca, 0xca, 0xca, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, - 0x00, 0x7d, 0x04, 0xd1, 0x05, 0x4e, 0x00, 0x19, 0x00, 0x31, 0x00, 0x49, - 0x00, 0x44, 0x40, 0x27, 0x0d, 0xda, 0x0e, 0x0a, 0xda, 0x11, 0xdc, 0x26, - 0xd4, 0x3e, 0x01, 0xda, 0x00, 0x04, 0xda, 0x17, 0xd9, 0x1a, 0xd4, 0x3e, - 0xd3, 0x32, 0xd1, 0x4a, 0x07, 0x5c, 0x14, 0x0d, 0x00, 0x5e, 0x2c, 0x07, - 0x38, 0x14, 0x20, 0x07, 0x38, 0x59, 0x44, 0x2f, 0xe6, 0xfe, 0xc5, 0x10, - 0xfe, 0xe5, 0x32, 0x10, 0xee, 0x31, 0x00, 0x10, 0xf4, 0xec, 0xfc, 0xf4, - 0xec, 0xd4, 0xec, 0x10, 0xfe, 0xfd, 0xee, 0xd6, 0xee, 0x30, 0x01, 0x15, - 0x2e, 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, - 0x15, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, - 0x27, 0x22, 0x06, 0x07, 0x0e, 0x01, 0x15, 0x14, 0x16, 0x17, 0x1e, 0x01, - 0x33, 0x32, 0x36, 0x37, 0x3e, 0x01, 0x35, 0x34, 0x26, 0x27, 0x2e, 0x01, - 0x27, 0x32, 0x16, 0x17, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x07, 0x0e, 0x01, - 0x23, 0x22, 0x26, 0x27, 0x2e, 0x01, 0x35, 0x34, 0x36, 0x37, 0x3e, 0x01, - 0x03, 0x60, 0x3a, 0x6f, 0x3a, 0x75, 0x87, 0x8c, 0x82, 0x38, 0x67, 0x32, - 0x34, 0x72, 0x3d, 0xb4, 0xcf, 0xd0, 0xb3, 0x3d, 0x72, 0xc4, 0x6a, 0xb5, - 0x4b, 0x4b, 0x4d, 0x4d, 0x4b, 0x4c, 0xb5, 0x69, 0x6a, 0xb5, 0x4c, 0x4c, - 0x4b, 0x4c, 0x4b, 0x4b, 0xb5, 0x6b, 0x7f, 0xda, 0x5a, 0x5a, 0x5c, 0x5b, - 0x5b, 0x5b, 0xda, 0x7e, 0x7d, 0xda, 0x5b, 0x5b, 0x5b, 0x5c, 0x5a, 0x5a, - 0xda, 0x04, 0x2f, 0x6c, 0x1c, 0x1b, 0x95, 0x80, 0x84, 0x8e, 0x19, 0x1a, - 0x68, 0x17, 0x16, 0xc8, 0xac, 0xad, 0xca, 0x16, 0xa1, 0x4a, 0x4b, 0x4b, - 0xb8, 0x6a, 0x68, 0xb7, 0x4b, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0xb5, 0x69, - 0x6a, 0xb8, 0x4b, 0x4b, 0x4a, 0x67, 0x5a, 0x5a, 0x5b, 0xdc, 0x7e, 0x7d, - 0xda, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0xda, 0x7d, 0x7e, 0xdc, 0x5b, - 0x5a, 0x5a, 0x00, 0x00, 0x00, 0x03, 0x01, 0x0e, 0x01, 0xd5, 0x03, 0xc1, - 0x05, 0xf0, 0x00, 0x0a, 0x00, 0x25, 0x00, 0x29, 0x00, 0x64, 0x40, 0x36, - 0x09, 0x06, 0x00, 0x19, 0x1f, 0x0b, 0x17, 0x0e, 0x06, 0x00, 0x28, 0xf3, - 0x26, 0x00, 0xed, 0x17, 0x26, 0xf1, 0x06, 0xed, 0x0c, 0x11, 0x20, 0xef, - 0x1f, 0xee, 0x1c, 0xed, 0x11, 0xf0, 0x23, 0x96, 0x2a, 0x26, 0x1f, 0x14, - 0x00, 0x17, 0x09, 0x03, 0x28, 0x27, 0x18, 0x0d, 0x09, 0x6a, 0x0b, 0x6b, - 0x1f, 0x03, 0x6a, 0x14, 0x69, 0x2a, 0x10, 0xfc, 0xec, 0xc4, 0xfc, 0xec, - 0x32, 0x32, 0xc0, 0xc0, 0x11, 0x12, 0x39, 0x39, 0x11, 0x12, 0x39, 0x31, - 0x00, 0x10, 0xf4, 0xe4, 0xfc, 0xf4, 0xec, 0x10, 0xc4, 0xee, 0xed, 0xd6, - 0xee, 0x10, 0xee, 0x11, 0x12, 0x39, 0x12, 0x39, 0x11, 0x39, 0x11, 0x12, - 0x39, 0x30, 0x01, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x3d, - 0x01, 0x37, 0x11, 0x23, 0x35, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x35, 0x34, - 0x36, 0x3b, 0x01, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, - 0x01, 0x33, 0x32, 0x16, 0x01, 0x21, 0x15, 0x21, 0x02, 0xac, 0x90, 0x7c, - 0x57, 0x48, 0x69, 0x83, 0x8f, 0x8f, 0x31, 0x83, 0x52, 0x81, 0x96, 0xbb, - 0xac, 0xb6, 0x77, 0x75, 0x33, 0x7d, 0x43, 0x44, 0x87, 0x3f, 0xb8, 0xac, - 0xfd, 0x6b, 0x02, 0x9c, 0xfd, 0x64, 0x04, 0x50, 0x44, 0x4e, 0x40, 0x4d, - 0x8f, 0x73, 0x1d, 0x3d, 0xfe, 0x40, 0x70, 0x41, 0x42, 0x88, 0x74, 0x81, - 0x8c, 0x04, 0x5a, 0x5c, 0x23, 0x21, 0x7f, 0x1c, 0x1c, 0xac, 0xfd, 0x0c, - 0x7b, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x77, 0x00, 0x8d, 0x04, 0x12, - 0x04, 0x23, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x2f, 0x40, 0x17, 0x09, 0x02, - 0x0b, 0x04, 0xfc, 0x07, 0x00, 0xac, 0x0e, 0x02, 0x0c, 0x05, 0x09, 0x00, - 0x0a, 0x07, 0x76, 0x0c, 0x03, 0x00, 0x76, 0x05, 0x0e, 0x10, 0xd4, 0xfc, - 0x3c, 0xd4, 0xec, 0x32, 0x11, 0x39, 0x11, 0x12, 0x39, 0x31, 0x00, 0x10, - 0xf4, 0x3c, 0xec, 0x32, 0x39, 0x39, 0x30, 0x01, 0x15, 0x09, 0x01, 0x15, - 0x01, 0x35, 0x01, 0x15, 0x09, 0x01, 0x15, 0x01, 0x35, 0x02, 0x4c, 0xfe, - 0xd3, 0x01, 0x2d, 0xfe, 0x2b, 0x03, 0x9b, 0xfe, 0xd3, 0x01, 0x2d, 0xfe, - 0x2b, 0x04, 0x23, 0xbf, 0xfe, 0xf4, 0xfe, 0xf4, 0xbf, 0x01, 0xa2, 0x52, - 0x01, 0xa2, 0xbf, 0xfe, 0xf4, 0xfe, 0xf4, 0xbf, 0x01, 0xa2, 0x52, 0x00, - 0x00, 0x01, 0x00, 0x58, 0x01, 0x73, 0x04, 0x79, 0x03, 0x5e, 0x00, 0x05, - 0x00, 0x18, 0x40, 0x0b, 0x04, 0xa0, 0x02, 0x00, 0x06, 0x03, 0x1c, 0x01, - 0x00, 0x27, 0x06, 0x10, 0xfc, 0xd4, 0xec, 0x31, 0x00, 0x10, 0xd4, 0xc4, - 0xec, 0x30, 0x13, 0x21, 0x11, 0x23, 0x11, 0x21, 0x58, 0x04, 0x21, 0xa8, - 0xfc, 0x87, 0x03, 0x5e, 0xfe, 0x15, 0x01, 0x3f, 0x00, 0x01, 0x01, 0x64, - 0x01, 0xdf, 0x03, 0x6d, 0x02, 0x83, 0x00, 0x03, 0x00, 0x11, 0xb6, 0x00, - 0xa0, 0x02, 0x04, 0x01, 0x00, 0x04, 0x10, 0xd4, 0xc4, 0x31, 0x00, 0x10, - 0xd4, 0xec, 0x30, 0x01, 0x21, 0x15, 0x21, 0x01, 0x64, 0x02, 0x09, 0xfd, - 0xf7, 0x02, 0x83, 0xa4, 0x00, 0x04, 0x00, 0x00, 0x00, 0x7d, 0x04, 0xd1, - 0x05, 0x4e, 0x00, 0x13, 0x00, 0x1c, 0x00, 0x34, 0x00, 0x4c, 0x00, 0x85, - 0x40, 0x49, 0x0f, 0x0e, 0x0d, 0x03, 0x10, 0x0c, 0x5d, 0x09, 0x0a, 0x09, - 0x0b, 0x5d, 0x0a, 0x0a, 0x09, 0x42, 0x0c, 0x0a, 0x06, 0x16, 0x09, 0x0a, - 0x16, 0xd7, 0x0f, 0x14, 0xd7, 0x00, 0x11, 0x0a, 0xd6, 0x41, 0xd4, 0x29, - 0x00, 0xd5, 0x35, 0xd4, 0x29, 0xd3, 0x1d, 0xd1, 0x4d, 0x17, 0x14, 0x0f, - 0x0c, 0x04, 0x00, 0x06, 0x10, 0x09, 0x1a, 0x03, 0x15, 0x10, 0x5c, 0x12, - 0x1a, 0x5c, 0x0a, 0x03, 0x5b, 0x47, 0x07, 0x23, 0x12, 0x58, 0x3b, 0x07, - 0x23, 0x59, 0x2f, 0x2f, 0xe6, 0xfe, 0xe5, 0x10, 0xfe, 0xf5, 0xc4, 0xee, - 0x10, 0xee, 0x32, 0x11, 0x12, 0x39, 0x11, 0x39, 0x39, 0x17, 0x39, 0x31, - 0x00, 0x10, 0xf4, 0xec, 0xfc, 0xe4, 0x10, 0xfe, 0xed, 0x32, 0x10, 0xee, - 0xd6, 0xee, 0x12, 0x39, 0x12, 0x39, 0x12, 0x39, 0x30, 0x4b, 0x53, 0x58, - 0x07, 0x10, 0x05, 0xed, 0x07, 0x10, 0x04, 0xed, 0x11, 0x17, 0x39, 0x59, - 0x22, 0x01, 0x32, 0x16, 0x15, 0x14, 0x06, 0x07, 0x1e, 0x01, 0x1f, 0x01, - 0x23, 0x27, 0x2e, 0x01, 0x2b, 0x01, 0x11, 0x23, 0x11, 0x17, 0x23, 0x15, - 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x03, 0x32, 0x16, 0x17, 0x1e, 0x01, - 0x15, 0x14, 0x06, 0x07, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x27, 0x2e, 0x01, - 0x35, 0x34, 0x36, 0x37, 0x3e, 0x01, 0x17, 0x22, 0x06, 0x07, 0x0e, 0x01, - 0x15, 0x14, 0x16, 0x17, 0x1e, 0x01, 0x33, 0x32, 0x36, 0x37, 0x3e, 0x01, - 0x35, 0x34, 0x26, 0x27, 0x2e, 0x01, 0x02, 0x58, 0x93, 0x90, 0x58, 0x50, - 0x13, 0x3a, 0x26, 0x72, 0x8f, 0x6b, 0x31, 0x3d, 0x2d, 0x37, 0x82, 0xe8, - 0x66, 0x66, 0x5a, 0x4a, 0x4a, 0x44, 0x7f, 0xda, 0x5a, 0x5a, 0x5c, 0x5b, - 0x5b, 0x5b, 0xda, 0x7e, 0x7d, 0xda, 0x5b, 0x5b, 0x5b, 0x5c, 0x5a, 0x5a, - 0xda, 0x7e, 0x6a, 0xb5, 0x4b, 0x4b, 0x4d, 0x4d, 0x4b, 0x4c, 0xb5, 0x69, - 0x6a, 0xb5, 0x4c, 0x4c, 0x4b, 0x4c, 0x4b, 0x4b, 0xb5, 0x04, 0x4c, 0x62, - 0x65, 0x47, 0x5d, 0x0e, 0x05, 0x43, 0x3b, 0xba, 0xae, 0x50, 0x2a, 0xfe, - 0xd8, 0x02, 0xb6, 0x54, 0xe8, 0x36, 0x3f, 0x3e, 0x35, 0x01, 0x56, 0x5a, - 0x5a, 0x5b, 0xdc, 0x7e, 0x7d, 0xda, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, - 0xda, 0x7d, 0x7e, 0xdc, 0x5b, 0x5a, 0x5a, 0x67, 0x4a, 0x4b, 0x4b, 0xb8, - 0x6a, 0x68, 0xb7, 0x4b, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0xb5, 0x69, 0x6a, - 0xb8, 0x4b, 0x4b, 0x4a, 0x00, 0x01, 0x01, 0x3d, 0x05, 0x62, 0x03, 0x93, - 0x05, 0xf6, 0x00, 0x03, 0x00, 0x11, 0xb6, 0x02, 0xb6, 0x00, 0x04, 0x01, - 0x00, 0x04, 0x10, 0xd4, 0xcc, 0x31, 0x00, 0x10, 0xd4, 0xec, 0x30, 0x01, - 0x21, 0x15, 0x21, 0x01, 0x3d, 0x02, 0x56, 0xfd, 0xaa, 0x05, 0xf6, 0x94, - 0x00, 0x02, 0x01, 0x2b, 0x03, 0x75, 0x03, 0xa6, 0x05, 0xf0, 0x00, 0x0e, - 0x00, 0x1a, 0x00, 0x20, 0x40, 0x11, 0x15, 0xcc, 0x09, 0xcd, 0x0f, 0xcc, - 0x00, 0x96, 0x1b, 0x18, 0x53, 0x06, 0x54, 0x12, 0x53, 0x0c, 0x1b, 0x10, - 0xd4, 0xec, 0xfc, 0xec, 0x31, 0x00, 0x10, 0xf4, 0xec, 0xfc, 0xec, 0x30, - 0x01, 0x32, 0x16, 0x17, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, - 0x35, 0x34, 0x36, 0x17, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, - 0x35, 0x34, 0x26, 0x02, 0x68, 0x41, 0x75, 0x2c, 0x2d, 0x2f, 0xba, 0x86, - 0x87, 0xb4, 0xb8, 0x85, 0x4f, 0x6f, 0x6d, 0x4f, 0x50, 0x71, 0x70, 0x05, - 0xf0, 0x31, 0x2e, 0x2d, 0x72, 0x42, 0x84, 0xb7, 0xb4, 0x87, 0x86, 0xba, - 0x81, 0x6f, 0x50, 0x50, 0x6c, 0x6e, 0x4e, 0x4f, 0x70, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x58, 0x00, 0x00, 0x04, 0x79, 0x04, 0x93, 0x00, 0x03, - 0x00, 0x0f, 0x00, 0x2e, 0x40, 0x18, 0x09, 0xe3, 0x0b, 0x07, 0xa0, 0x04, - 0xe3, 0x0d, 0x05, 0x00, 0xa0, 0x02, 0x06, 0x01, 0x1a, 0x08, 0x04, 0x1c, - 0x0c, 0x00, 0x1a, 0x0e, 0x0a, 0x10, 0x10, 0xd4, 0x3c, 0xec, 0x32, 0xfc, - 0x3c, 0xec, 0x32, 0x31, 0x00, 0x2f, 0xec, 0xd4, 0x3c, 0xec, 0xfc, 0x3c, - 0xec, 0x30, 0x37, 0x21, 0x15, 0x21, 0x01, 0x11, 0x21, 0x15, 0x21, 0x11, - 0x23, 0x11, 0x21, 0x35, 0x21, 0x11, 0x58, 0x04, 0x21, 0xfb, 0xdf, 0x02, - 0x64, 0x01, 0xbd, 0xfe, 0x43, 0xa8, 0xfe, 0x44, 0x01, 0xbc, 0xaa, 0xaa, - 0x04, 0x93, 0xfe, 0xb7, 0xaa, 0xfe, 0xb4, 0x01, 0x4c, 0xaa, 0x01, 0x49, - 0x00, 0x01, 0x01, 0x42, 0x02, 0x9c, 0x03, 0x7d, 0x05, 0xf0, 0x00, 0x18, - 0x00, 0x61, 0x40, 0x13, 0x00, 0x57, 0x04, 0x05, 0x04, 0x16, 0x17, 0x02, - 0x15, 0x18, 0x57, 0x05, 0x05, 0x04, 0x42, 0x05, 0x18, 0x0e, 0x00, 0x41, - 0x09, 0x01, 0x09, 0x00, 0x02, 0x00, 0x0e, 0x01, 0x09, 0x00, 0x0f, 0x00, - 0x02, 0x01, 0x0a, 0x00, 0x0b, 0x01, 0x09, 0x40, 0x0e, 0x12, 0x96, 0x19, - 0x05, 0x00, 0x18, 0x0e, 0x08, 0x7f, 0x01, 0x15, 0x0e, 0x03, 0x19, 0x10, - 0xd4, 0xc4, 0xd4, 0xc4, 0xec, 0x11, 0x39, 0x39, 0x39, 0x31, 0x00, 0x10, - 0xf4, 0xec, 0xe4, 0xd4, 0xec, 0x10, 0xee, 0x11, 0x39, 0x39, 0x30, 0x4b, - 0x53, 0x58, 0x07, 0x10, 0x04, 0xed, 0x11, 0x17, 0x39, 0x07, 0x10, 0x05, - 0xed, 0x59, 0x22, 0x01, 0x21, 0x15, 0x21, 0x35, 0x37, 0x3e, 0x01, 0x35, - 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x16, - 0x15, 0x14, 0x06, 0x07, 0x01, 0xe3, 0x01, 0x9a, 0xfd, 0xc5, 0xe7, 0x65, - 0x51, 0x64, 0x52, 0x31, 0x71, 0x3f, 0x41, 0x79, 0x3b, 0x8e, 0xac, 0x4a, - 0x77, 0x03, 0x0e, 0x72, 0x6e, 0xe2, 0x61, 0x7a, 0x33, 0x3d, 0x4c, 0x24, - 0x24, 0x7d, 0x1c, 0x1c, 0x85, 0x6b, 0x39, 0x77, 0x75, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x46, 0x02, 0x8d, 0x03, 0x9c, 0x05, 0xf0, 0x00, 0x28, - 0x00, 0x5c, 0x41, 0x14, 0x00, 0x00, 0x00, 0x13, 0x01, 0x09, 0x00, 0x15, - 0x00, 0x0a, 0x01, 0x09, 0x00, 0x09, 0x01, 0x0b, 0x00, 0x15, 0x00, 0x0d, - 0x01, 0x09, 0x00, 0x06, 0x00, 0x1f, 0x01, 0x09, 0x00, 0x20, 0x01, 0x0b, - 0x00, 0x06, 0x01, 0x0a, 0x00, 0x1c, 0x01, 0x09, 0x40, 0x13, 0x23, 0x96, - 0x29, 0x16, 0x13, 0x0d, 0x00, 0x03, 0x14, 0x19, 0x7f, 0x26, 0x10, 0x7f, - 0x03, 0x1f, 0x14, 0x09, 0x29, 0x10, 0xd4, 0xc4, 0xc4, 0xd4, 0xec, 0xd4, - 0xec, 0x11, 0x17, 0x39, 0x39, 0x31, 0x00, 0x10, 0xf4, 0xec, 0xe4, 0xf4, - 0xec, 0x10, 0xee, 0xc6, 0xf6, 0xee, 0x10, 0xee, 0x39, 0x30, 0x01, 0x1e, - 0x01, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x27, 0x35, 0x1e, 0x01, 0x33, - 0x32, 0x36, 0x35, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x36, 0x35, - 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x16, - 0x15, 0x14, 0x06, 0x02, 0xdb, 0x5e, 0x63, 0xbe, 0xb1, 0x3a, 0x72, 0x3b, - 0x45, 0x71, 0x2d, 0x65, 0x76, 0x6e, 0x6d, 0x42, 0x4a, 0x5d, 0x62, 0x60, - 0x57, 0x2c, 0x70, 0x3b, 0x45, 0x75, 0x32, 0x91, 0xa8, 0x58, 0x04, 0x60, - 0x15, 0x6c, 0x50, 0x7c, 0x86, 0x15, 0x14, 0x79, 0x1b, 0x1a, 0x51, 0x44, - 0x4a, 0x4c, 0x6c, 0x3f, 0x3c, 0x38, 0x3f, 0x18, 0x17, 0x79, 0x11, 0x12, - 0x76, 0x63, 0x47, 0x5d, 0x00, 0x01, 0x01, 0xdb, 0x04, 0xee, 0x03, 0xba, - 0x06, 0x66, 0x00, 0x03, 0x00, 0x25, 0x40, 0x09, 0x02, 0xba, 0x00, 0xb9, - 0x04, 0x01, 0x3c, 0x03, 0x04, 0x10, 0xd4, 0xec, 0x31, 0x00, 0x10, 0xf4, - 0x4b, 0xb0, 0x09, 0x54, 0x4b, 0xb0, 0x0e, 0x54, 0x5b, 0x58, 0xb9, 0x00, - 0x00, 0x00, 0x40, 0x38, 0x59, 0xec, 0x30, 0x01, 0x33, 0x01, 0x23, 0x02, - 0xf4, 0xc6, 0xfe, 0xbb, 0x9a, 0x06, 0x66, 0xfe, 0x88, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xc3, 0xfe, 0x54, 0x04, 0x9e, 0x04, 0x60, 0x00, 0x20, - 0x00, 0x4c, 0x40, 0x2a, 0x13, 0x19, 0x1f, 0x03, 0x16, 0x06, 0x03, 0x09, - 0x0c, 0x03, 0x01, 0x12, 0x06, 0x8c, 0x0f, 0x8b, 0x1c, 0x16, 0x99, 0x00, - 0xc3, 0x0a, 0x01, 0xc2, 0x21, 0x19, 0x0b, 0x09, 0x20, 0x1f, 0x02, 0x00, - 0x12, 0x09, 0x06, 0x0b, 0x4a, 0x02, 0x06, 0x00, 0x46, 0x21, 0x10, 0xf4, - 0xec, 0xfc, 0xec, 0xc4, 0x11, 0x12, 0x39, 0x39, 0x11, 0x12, 0x39, 0x31, - 0x00, 0x10, 0xe4, 0x32, 0xe4, 0xf4, 0x3c, 0xec, 0xfc, 0xc4, 0x11, 0x17, - 0x39, 0x11, 0x12, 0x17, 0x39, 0x30, 0x13, 0x11, 0x33, 0x11, 0x14, 0x16, - 0x33, 0x32, 0x36, 0x35, 0x11, 0x33, 0x11, 0x14, 0x16, 0x33, 0x32, 0x36, - 0x37, 0x15, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x27, 0x0e, 0x01, 0x23, 0x22, - 0x26, 0x27, 0x11, 0xc3, 0xb8, 0x78, 0x6f, 0x7f, 0x81, 0xb9, 0x20, 0x21, - 0x09, 0x1d, 0x1c, 0x26, 0x44, 0x22, 0x3e, 0x4b, 0x0c, 0x2e, 0x85, 0x59, - 0x5c, 0x7f, 0x2c, 0xfe, 0x54, 0x06, 0x0c, 0xfd, 0x48, 0x8e, 0x97, 0xaa, - 0xa6, 0x02, 0x8d, 0xfc, 0xa0, 0x3b, 0x38, 0x0a, 0x0d, 0x94, 0x17, 0x16, - 0x4f, 0x4f, 0x50, 0x4e, 0x4c, 0x50, 0xfd, 0xd5, 0x00, 0x01, 0x00, 0x6a, - 0xff, 0x3b, 0x04, 0x06, 0x05, 0xd5, 0x00, 0x0d, 0x00, 0x23, 0x40, 0x11, - 0x04, 0x08, 0x00, 0x88, 0x06, 0x02, 0x0e, 0x00, 0x07, 0x57, 0x05, 0x03, - 0x57, 0x01, 0x31, 0x0b, 0x0e, 0x10, 0xdc, 0xfc, 0xfc, 0xd4, 0xec, 0x39, - 0x31, 0x00, 0x10, 0xc4, 0x32, 0xf4, 0xc4, 0xcc, 0x30, 0x01, 0x21, 0x11, - 0x23, 0x11, 0x23, 0x11, 0x23, 0x11, 0x2e, 0x01, 0x35, 0x34, 0x24, 0x02, - 0x46, 0x01, 0xc0, 0x8d, 0xbf, 0x8d, 0xd7, 0xec, 0x01, 0x05, 0x05, 0xd5, - 0xf9, 0x66, 0x06, 0x1f, 0xf9, 0xe1, 0x03, 0x4e, 0x11, 0xdd, 0xb8, 0xbe, - 0xe8, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0xe9, 0x02, 0x2f, 0x02, 0xe5, - 0x03, 0x60, 0x00, 0x03, 0x00, 0x15, 0xb9, 0x00, 0x02, 0x01, 0x01, 0xb5, - 0x00, 0x04, 0x01, 0x1d, 0x00, 0x04, 0x10, 0xd4, 0xec, 0x31, 0x00, 0x10, - 0xd4, 0xec, 0x30, 0x01, 0x33, 0x11, 0x23, 0x01, 0xe9, 0xfc, 0xfc, 0x03, - 0x60, 0xfe, 0xcf, 0x00, 0xff, 0xff, 0x01, 0x8b, 0xfe, 0x75, 0x03, 0x29, - 0x00, 0x00, 0x10, 0x06, 0x02, 0xaf, 0x00, 0x00, 0x00, 0x01, 0x01, 0x58, - 0x02, 0x9c, 0x03, 0x93, 0x05, 0xdf, 0x00, 0x0a, 0x00, 0x39, 0x41, 0x0b, - 0x00, 0x07, 0x00, 0x00, 0x01, 0x09, 0x00, 0x09, 0x00, 0x03, 0x01, 0x09, - 0x00, 0x04, 0x00, 0x09, 0x01, 0x0a, 0x00, 0x02, 0x01, 0x09, 0x40, 0x0d, - 0x05, 0x96, 0x0b, 0x08, 0x61, 0x06, 0x57, 0x03, 0x7d, 0x00, 0x61, 0x01, - 0x0b, 0x10, 0xd4, 0xec, 0xec, 0xfc, 0xec, 0x31, 0x00, 0x10, 0xf4, 0xec, - 0xe4, 0xd4, 0xec, 0x10, 0xee, 0x32, 0x30, 0x01, 0x33, 0x11, 0x07, 0x35, - 0x37, 0x33, 0x11, 0x33, 0x15, 0x21, 0x01, 0x6a, 0xcd, 0xdf, 0xe5, 0x8a, - 0xcc, 0xfd, 0xd7, 0x03, 0x0a, 0x02, 0x63, 0x29, 0x74, 0x27, 0xfd, 0x2b, - 0x6e, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xf4, 0x01, 0xd5, 0x03, 0xdd, - 0x05, 0xf0, 0x00, 0x0b, 0x00, 0x17, 0x00, 0x1b, 0x00, 0x33, 0x40, 0x1c, - 0x1a, 0xf3, 0x18, 0xf1, 0x06, 0xed, 0x12, 0xf0, 0x00, 0xed, 0x0c, 0x96, - 0x1c, 0x19, 0x0f, 0x09, 0x18, 0x15, 0x03, 0x09, 0x6a, 0x0f, 0x6b, 0x03, - 0x6a, 0x15, 0x69, 0x1c, 0x10, 0xfc, 0xec, 0xfc, 0xec, 0x11, 0x12, 0x39, - 0x11, 0x12, 0x39, 0x31, 0x00, 0x10, 0xf4, 0xec, 0xf4, 0xec, 0xfc, 0xec, - 0x30, 0x01, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, - 0x26, 0x27, 0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, - 0x36, 0x03, 0x21, 0x15, 0x21, 0x02, 0x68, 0x66, 0x73, 0x73, 0x66, 0x65, - 0x75, 0x73, 0x67, 0xaa, 0xcb, 0xca, 0xab, 0xaa, 0xca, 0xcb, 0xab, 0x02, - 0xa4, 0xfd, 0x5c, 0x05, 0x7b, 0x9c, 0x8b, 0x8b, 0x9a, 0x9d, 0x88, 0x8b, - 0x9c, 0x75, 0xe0, 0xbc, 0xbb, 0xdf, 0xdf, 0xbb, 0xbc, 0xe0, 0xfc, 0x60, - 0x7b, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xc1, 0x00, 0x8d, 0x04, 0x5c, - 0x04, 0x23, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x2f, 0x40, 0x17, 0x0c, 0x05, - 0x0a, 0x03, 0xfc, 0x07, 0x00, 0xac, 0x0e, 0x05, 0x08, 0x01, 0x0c, 0x07, - 0x01, 0x76, 0x03, 0x00, 0x08, 0x76, 0x0a, 0x07, 0x0e, 0x10, 0xd4, 0x3c, - 0xfc, 0xd4, 0x3c, 0xec, 0x12, 0x39, 0x11, 0x12, 0x39, 0x31, 0x00, 0x10, - 0xf4, 0x3c, 0xec, 0x32, 0x39, 0x39, 0x30, 0x09, 0x01, 0x15, 0x01, 0x35, - 0x09, 0x01, 0x25, 0x01, 0x15, 0x01, 0x35, 0x09, 0x01, 0x02, 0x87, 0x01, - 0xd5, 0xfe, 0x2b, 0x01, 0x2d, 0xfe, 0xd3, 0xfe, 0x3a, 0x01, 0xd5, 0xfe, - 0x2b, 0x01, 0x2d, 0xfe, 0xd3, 0x04, 0x23, 0xfe, 0x5e, 0x52, 0xfe, 0x5e, - 0xbf, 0x01, 0x0c, 0x01, 0x0c, 0xbf, 0xfe, 0x5e, 0x52, 0xfe, 0x5e, 0xbf, - 0x01, 0x0c, 0x01, 0x0c, 0xff, 0xff, 0x00, 0x1b, 0xfe, 0xf2, 0x04, 0x5a, - 0x06, 0x7b, 0x10, 0x27, 0x07, 0x40, 0x00, 0xb8, 0xfc, 0x56, 0x10, 0x27, - 0x00, 0x7b, 0xfe, 0xfe, 0x00, 0x9c, 0x10, 0x06, 0x0c, 0xc4, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x1b, 0xfe, 0xf2, 0x04, 0x5a, 0x06, 0x7b, 0x10, 0x27, - 0x00, 0x7b, 0xfe, 0xfe, 0x00, 0x9c, 0x10, 0x26, 0x0c, 0xc4, 0x00, 0x00, - 0x10, 0x07, 0x00, 0x74, 0x00, 0xc9, 0xfc, 0x56, 0xff, 0xff, 0x00, 0x1b, - 0xfe, 0xf2, 0x04, 0x5a, 0x06, 0x8c, 0x10, 0x27, 0x07, 0x40, 0x00, 0xb8, - 0xfc, 0x56, 0x10, 0x27, 0x00, 0x75, 0xff, 0x1d, 0x00, 0x9c, 0x10, 0x06, - 0x0c, 0xc4, 0x00, 0x00, 0x00, 0x02, 0x00, 0xc1, 0xff, 0xe5, 0x03, 0xdd, - 0x05, 0xd5, 0x00, 0x21, 0x00, 0x25, 0x00, 0x82, 0x40, 0x47, 0x0b, 0x0a, - 0x09, 0x08, 0x07, 0x05, 0x0c, 0x06, 0x25, 0x19, 0x1a, 0x19, 0x03, 0x04, - 0x02, 0x02, 0x05, 0x25, 0x1a, 0x1a, 0x19, 0x42, 0x21, 0x1a, 0x05, 0x02, - 0x04, 0x06, 0x19, 0x00, 0x10, 0x8b, 0x0f, 0x8d, 0x0c, 0x00, 0x22, 0x86, - 0x24, 0x0c, 0x97, 0x13, 0x99, 0x24, 0x88, 0x26, 0x06, 0x23, 0x19, 0x16, - 0x09, 0x1f, 0x05, 0x00, 0x03, 0x1d, 0x01, 0x1a, 0x23, 0x09, 0x29, 0x16, - 0x0f, 0x1d, 0x03, 0x01, 0x0f, 0x22, 0x1e, 0x23, 0x26, 0x10, 0xd4, 0xfc, - 0xc4, 0xd4, 0xec, 0x10, 0xd6, 0xee, 0x11, 0x39, 0x11, 0x12, 0x17, 0x39, - 0x11, 0x12, 0x39, 0x12, 0x39, 0x31, 0x00, 0x10, 0xe4, 0xf4, 0xec, 0x10, - 0xfe, 0xcd, 0x10, 0xf4, 0xee, 0x12, 0x39, 0x39, 0x17, 0x39, 0x30, 0x4b, - 0x53, 0x58, 0x07, 0x10, 0x04, 0xed, 0x11, 0x17, 0x39, 0x07, 0x10, 0x04, - 0xed, 0x11, 0x17, 0x39, 0x59, 0x22, 0x01, 0x33, 0x15, 0x14, 0x06, 0x0f, - 0x01, 0x0e, 0x01, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x15, 0x0e, - 0x01, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x3f, 0x01, 0x3e, 0x01, 0x35, - 0x34, 0x35, 0x36, 0x35, 0x13, 0x23, 0x35, 0x33, 0x02, 0x25, 0xbe, 0x3d, - 0x54, 0x5a, 0x3e, 0x2f, 0x83, 0x6d, 0x4e, 0xb2, 0x62, 0x5e, 0xbf, 0x68, - 0xba, 0xdd, 0x43, 0x5e, 0x58, 0x43, 0x26, 0x02, 0xc4, 0xca, 0xca, 0x04, - 0x44, 0x9a, 0x62, 0x89, 0x52, 0x59, 0x3b, 0x58, 0x31, 0x59, 0x6e, 0x45, - 0x44, 0xbc, 0x39, 0x38, 0xc0, 0xa1, 0x4c, 0x83, 0x5c, 0x56, 0x40, 0x54, - 0x3f, 0x01, 0x04, 0x17, 0x13, 0x01, 0x0e, 0xfe, 0xff, 0xff, 0x00, 0x25, - 0x00, 0x00, 0x04, 0xac, 0x07, 0x6b, 0x10, 0x26, 0x00, 0x24, 0x00, 0x00, - 0x11, 0x07, 0x0c, 0xc1, 0x00, 0x00, 0x01, 0x75, 0x00, 0x07, 0x40, 0x03, - 0x4f, 0x0b, 0x01, 0x5d, 0x31, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, - 0x00, 0x00, 0x04, 0xac, 0x07, 0x6b, 0x10, 0x26, 0x00, 0x24, 0x00, 0x00, - 0x11, 0x07, 0x0c, 0xbf, 0x00, 0x00, 0x01, 0x75, 0x00, 0x07, 0x40, 0x03, - 0x4f, 0x0b, 0x01, 0x5d, 0x31, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, - 0x00, 0x00, 0x04, 0xac, 0x07, 0x6d, 0x10, 0x26, 0x00, 0x24, 0x00, 0x00, - 0x11, 0x07, 0x0c, 0xc2, 0x00, 0x00, 0x01, 0x75, 0x00, 0x14, 0xb4, 0x05, - 0x0d, 0x11, 0x0a, 0x07, 0x2b, 0x40, 0x09, 0x20, 0x11, 0x2f, 0x0d, 0x00, - 0x11, 0x0f, 0x0d, 0x04, 0x5d, 0x31, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, - 0x00, 0x00, 0x04, 0xac, 0x07, 0x5e, 0x10, 0x26, 0x00, 0x24, 0x00, 0x00, - 0x11, 0x07, 0x0c, 0xc0, 0x00, 0x00, 0x01, 0x75, 0x00, 0x10, 0xb4, 0x05, - 0x23, 0x14, 0x0a, 0x07, 0x2b, 0x40, 0x05, 0x4f, 0x23, 0x40, 0x14, 0x02, - 0x5d, 0x31, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, - 0x07, 0x4e, 0x10, 0x26, 0x00, 0x24, 0x00, 0x00, 0x11, 0x07, 0x0c, 0xbe, - 0x00, 0x00, 0x01, 0x75, 0x00, 0x1c, 0xb4, 0x05, 0x11, 0x0e, 0x0a, 0x07, - 0x2b, 0x40, 0x11, 0x70, 0x0e, 0x7f, 0x11, 0x30, 0x0e, 0x3f, 0x11, 0x20, - 0x0e, 0x2f, 0x11, 0x00, 0x0e, 0x0f, 0x11, 0x08, 0x5d, 0x31, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, 0x07, 0x6d, 0x00, 0x0b, - 0x00, 0x0e, 0x00, 0x21, 0x00, 0xc1, 0x40, 0x57, 0x0c, 0x25, 0x0d, 0x0c, - 0x1b, 0x1c, 0x1b, 0x0e, 0x25, 0x1c, 0x1b, 0x1e, 0x25, 0x1c, 0x1b, 0x1d, - 0x25, 0x1c, 0x1c, 0x1b, 0x20, 0x25, 0x0f, 0x21, 0x1f, 0x25, 0x0f, 0x21, - 0x0d, 0x25, 0x21, 0x0f, 0x21, 0x0c, 0x25, 0x0e, 0x0c, 0x0f, 0x0f, 0x21, - 0x42, 0x0c, 0x1b, 0x0f, 0x09, 0x1e, 0x97, 0x0d, 0x03, 0xc8, 0x15, 0x09, - 0x90, 0x0d, 0xc9, 0x20, 0x1c, 0x1d, 0x1c, 0x18, 0x20, 0x21, 0x1f, 0x0d, - 0x12, 0x06, 0x1e, 0x0e, 0x18, 0x0c, 0x06, 0x1b, 0x00, 0x50, 0x18, 0x0f, - 0x06, 0x50, 0x12, 0x18, 0x4b, 0x1c, 0x2f, 0x12, 0x4b, 0x21, 0x22, 0x10, - 0xdc, 0xe4, 0xfc, 0xe4, 0x10, 0xee, 0x32, 0x10, 0xee, 0x32, 0x11, 0x39, - 0x11, 0x39, 0x39, 0x11, 0x12, 0x39, 0x39, 0x11, 0x39, 0x11, 0x12, 0x39, - 0x31, 0x00, 0x2f, 0x3c, 0xe6, 0xe6, 0xd6, 0xee, 0x10, 0xee, 0x12, 0x39, - 0x39, 0x39, 0x30, 0x4b, 0x53, 0x58, 0x07, 0x10, 0x08, 0xed, 0x07, 0x10, - 0x05, 0xed, 0x07, 0x05, 0xed, 0x07, 0x05, 0xed, 0x07, 0x10, 0x05, 0xed, - 0x07, 0x05, 0xed, 0x07, 0x05, 0xed, 0x07, 0x10, 0x08, 0xed, 0x59, 0x22, - 0xb2, 0x80, 0x1f, 0x01, 0x00, 0x5d, 0x40, 0x14, 0x85, 0x0d, 0x8a, 0x0e, - 0x8a, 0x1e, 0x85, 0x1f, 0x04, 0x8f, 0x0c, 0x8f, 0x0c, 0x80, 0x0d, 0x80, - 0x0e, 0x80, 0x1e, 0x05, 0x5d, 0x01, 0x5d, 0x01, 0x34, 0x26, 0x23, 0x22, - 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x07, 0x03, 0x21, 0x01, 0x2e, - 0x01, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x07, 0x01, - 0x23, 0x03, 0x21, 0x03, 0x23, 0x03, 0x00, 0x59, 0x3f, 0x40, 0x57, 0x58, - 0x3f, 0x3f, 0x59, 0x98, 0xd5, 0x01, 0xaa, 0xfe, 0x94, 0x3a, 0x41, 0xa0, - 0x72, 0x72, 0xa1, 0x40, 0x3b, 0x01, 0xac, 0xd1, 0x6e, 0xfd, 0xf5, 0x6c, - 0xd1, 0x06, 0x5a, 0x3f, 0x59, 0x57, 0x41, 0x3f, 0x58, 0x58, 0xfc, 0xfd, - 0x08, 0x03, 0x50, 0x21, 0x79, 0x49, 0x72, 0xa1, 0xa1, 0x72, 0x49, 0x76, - 0x24, 0xfa, 0x89, 0x01, 0x85, 0xfe, 0x7b, 0x00, 0x00, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x04, 0x9c, 0x05, 0xd5, 0x00, 0x0f, 0x00, 0x13, 0x00, 0x67, - 0x40, 0x37, 0x0d, 0x25, 0x0f, 0x0e, 0x0c, 0x25, 0x0f, 0x0e, 0x11, 0x25, - 0x0e, 0x0f, 0x0e, 0x10, 0x25, 0x0f, 0x0f, 0x0e, 0x42, 0x05, 0x97, 0x03, - 0x0b, 0x97, 0x11, 0x10, 0x01, 0x97, 0x00, 0x88, 0x07, 0x97, 0x11, 0xb0, - 0x03, 0xb1, 0x0d, 0x09, 0x11, 0x10, 0x0f, 0x0d, 0x0c, 0x05, 0x0e, 0x0a, - 0x00, 0x04, 0x08, 0x06, 0x02, 0x63, 0x12, 0x0a, 0x0e, 0x2f, 0xd4, 0x3c, - 0xee, 0x32, 0xd6, 0xc4, 0xc4, 0x11, 0x12, 0x17, 0x39, 0x31, 0x00, 0x2f, - 0x3c, 0xee, 0xee, 0xee, 0xf4, 0xee, 0x32, 0x10, 0xee, 0x10, 0xee, 0x30, - 0x4b, 0x53, 0x58, 0x07, 0x10, 0x05, 0xed, 0x07, 0x10, 0x05, 0xed, 0x07, - 0x05, 0xed, 0x07, 0x05, 0xed, 0x59, 0x22, 0x01, 0x15, 0x21, 0x11, 0x21, - 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x11, 0x21, 0x03, 0x23, 0x01, 0x17, - 0x03, 0x21, 0x11, 0x04, 0x89, 0xfe, 0xae, 0x01, 0x33, 0xfe, 0xcd, 0x01, - 0x65, 0xfd, 0xe1, 0xfe, 0xa0, 0x65, 0xb8, 0x01, 0x9a, 0x78, 0xca, 0x01, - 0x35, 0x05, 0xd5, 0xaa, 0xfe, 0x46, 0xaa, 0xfd, 0xe3, 0xaa, 0x01, 0x7f, - 0xfe, 0x81, 0x05, 0xd5, 0xaa, 0xfc, 0xfc, 0x03, 0x04, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x8b, 0xfe, 0x75, 0x04, 0x31, 0x05, 0xf0, 0x10, 0x26, - 0x02, 0xaf, 0x64, 0x00, 0x10, 0x06, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc5, 0x00, 0x00, 0x04, 0x4e, 0x07, 0x6b, 0x10, 0x26, - 0x00, 0x28, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xc1, 0x00, 0x12, 0x01, 0x75, - 0xff, 0xff, 0x00, 0xc5, 0x00, 0x00, 0x04, 0x4e, 0x07, 0x6b, 0x10, 0x26, - 0x00, 0x28, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xbf, 0x00, 0x12, 0x01, 0x75, - 0xff, 0xff, 0x00, 0xc5, 0x00, 0x00, 0x04, 0x4e, 0x07, 0x6d, 0x10, 0x26, - 0x00, 0x28, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xc2, 0x00, 0x12, 0x01, 0x75, - 0xff, 0xff, 0x00, 0xc5, 0x00, 0x00, 0x04, 0x4e, 0x07, 0x4e, 0x10, 0x26, - 0x00, 0x28, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xbe, 0x00, 0x12, 0x01, 0x75, - 0xff, 0xff, 0x00, 0xc9, 0x00, 0x00, 0x04, 0x06, 0x07, 0x6b, 0x10, 0x26, - 0x00, 0x2c, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xc1, 0x00, 0x00, 0x01, 0x75, - 0xff, 0xff, 0x00, 0xc9, 0x00, 0x00, 0x04, 0x06, 0x07, 0x6b, 0x10, 0x26, - 0x00, 0x2c, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xbf, 0x00, 0x00, 0x01, 0x75, - 0xff, 0xff, 0x00, 0xc9, 0x00, 0x00, 0x04, 0x06, 0x07, 0x6d, 0x10, 0x26, - 0x00, 0x2c, 0x00, 0x00, 0x11, 0x07, 0x0c, 0xc2, 0x00, 0x00, 0x01, 0x75, - 0x00, 0x0b, 0xb4, 0x10, 0x20, 0x01, 0x00, 0x00, 0x10, 0x49, 0x63, 0x3a, - 0x31, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc9, 0x00, 0x00, 0x04, 0x06, - 0x07, 0x4e, 0x10, 0x26, 0x00, 0x2c, 0x00, 0x00, 0x11, 0x07, 0x0c, 0xbe, - 0x00, 0x00, 0x01, 0x75, 0x00, 0x08, 0xb4, 0x01, 0x12, 0x0f, 0x00, 0x07, - 0x2b, 0x31, 0x00, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x04, 0x4e, - 0x05, 0xd5, 0x00, 0x0c, 0x00, 0x19, 0x00, 0x3b, 0x40, 0x21, 0x17, 0x08, - 0xb6, 0x0a, 0x13, 0x97, 0x00, 0x88, 0x0d, 0x97, 0x15, 0x0a, 0x06, 0x13, - 0x0d, 0x06, 0x00, 0x04, 0x16, 0x14, 0x10, 0x32, 0x03, 0x31, 0x09, 0x30, - 0x18, 0x14, 0x1e, 0x0b, 0x07, 0x30, 0x1a, 0x10, 0xfc, 0x3c, 0xec, 0x32, - 0xec, 0xfc, 0xec, 0x10, 0xc4, 0x17, 0x39, 0x31, 0x00, 0x2f, 0xc6, 0x32, - 0xee, 0xf6, 0xee, 0x10, 0xee, 0x32, 0x30, 0x01, 0x20, 0x00, 0x11, 0x10, - 0x00, 0x29, 0x01, 0x11, 0x23, 0x35, 0x33, 0x11, 0x01, 0x20, 0x36, 0x11, - 0x10, 0x26, 0x21, 0x23, 0x11, 0x21, 0x15, 0x21, 0x11, 0x01, 0xb4, 0x01, - 0x56, 0x01, 0x44, 0xfe, 0xbb, 0xfe, 0xab, 0xfe, 0xd1, 0x7d, 0x7d, 0x01, - 0x2f, 0x00, 0xff, 0xca, 0xc9, 0xff, 0x00, 0x60, 0x01, 0x08, 0xfe, 0xf8, - 0x05, 0xd5, 0xfe, 0x94, 0xfe, 0x80, 0xfe, 0x82, 0xfe, 0x95, 0x02, 0xc5, - 0x95, 0x02, 0x7b, 0xfa, 0xd1, 0xfb, 0x01, 0x48, 0x01, 0x4b, 0xfb, 0xfe, - 0x2b, 0x95, 0xfd, 0xe1, 0xff, 0xff, 0x00, 0x8b, 0x00, 0x00, 0x04, 0x46, - 0x07, 0x62, 0x10, 0x26, 0x00, 0x31, 0x00, 0x00, 0x11, 0x07, 0x0c, 0xc0, - 0x00, 0x00, 0x01, 0x79, 0x00, 0x10, 0xb4, 0x04, 0x22, 0x13, 0x00, 0x07, - 0x2b, 0x40, 0x05, 0x4f, 0x22, 0x40, 0x13, 0x02, 0x5d, 0x31, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x75, 0xff, 0xe3, 0x04, 0x5c, 0x07, 0x6b, 0x10, 0x26, - 0x00, 0x32, 0x00, 0x00, 0x11, 0x07, 0x0c, 0xc1, 0x00, 0x00, 0x01, 0x75, - 0x00, 0x07, 0x40, 0x03, 0x4f, 0x18, 0x01, 0x5d, 0x31, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x75, 0xff, 0xe3, 0x04, 0x5c, 0x07, 0x6b, 0x10, 0x26, - 0x00, 0x32, 0x00, 0x00, 0x11, 0x07, 0x0c, 0xbf, 0x00, 0x00, 0x01, 0x75, - 0x00, 0x07, 0x40, 0x03, 0x4f, 0x18, 0x01, 0x5d, 0x31, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x75, 0xff, 0xe3, 0x04, 0x5c, 0x07, 0x6d, 0x10, 0x26, - 0x00, 0x32, 0x00, 0x00, 0x11, 0x07, 0x0c, 0xc2, 0x00, 0x00, 0x01, 0x75, - 0x00, 0x14, 0xb4, 0x0c, 0x1a, 0x1e, 0x12, 0x07, 0x2b, 0x40, 0x09, 0x20, - 0x1e, 0x2f, 0x1a, 0x00, 0x1e, 0x0f, 0x1a, 0x04, 0x5d, 0x31, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x75, 0xff, 0xe3, 0x04, 0x5c, 0x07, 0x5e, 0x10, 0x26, - 0x00, 0x32, 0x00, 0x00, 0x11, 0x07, 0x0c, 0xc0, 0x00, 0x00, 0x01, 0x75, - 0x00, 0x10, 0xb4, 0x0c, 0x30, 0x21, 0x12, 0x07, 0x2b, 0x40, 0x05, 0x4f, - 0x30, 0x40, 0x21, 0x02, 0x5d, 0x31, 0x00, 0x00, 0xff, 0xff, 0x00, 0x75, - 0xff, 0xe3, 0x04, 0x5c, 0x07, 0x4e, 0x10, 0x26, 0x00, 0x32, 0x00, 0x00, - 0x11, 0x07, 0x0c, 0xbe, 0x00, 0x00, 0x01, 0x75, 0x00, 0x1c, 0xb4, 0x0c, - 0x1e, 0x1b, 0x12, 0x07, 0x2b, 0x40, 0x11, 0x70, 0x1b, 0x7f, 0x1e, 0x30, - 0x1b, 0x3f, 0x1e, 0x20, 0x1b, 0x2f, 0x1e, 0x00, 0x1b, 0x0f, 0x1e, 0x08, - 0x5d, 0x31, 0x00, 0x00, 0x00, 0x01, 0x00, 0x96, 0x00, 0xae, 0x04, 0x3b, - 0x04, 0x54, 0x00, 0x0b, 0x00, 0x2e, 0x40, 0x1c, 0x0a, 0x08, 0x07, 0x06, - 0x04, 0x02, 0x01, 0x00, 0x08, 0x0b, 0x09, 0x05, 0x03, 0x0c, 0x0b, 0x0a, - 0x09, 0x08, 0x07, 0x05, 0x04, 0x03, 0x01, 0x09, 0x06, 0x02, 0x00, 0x0c, - 0x10, 0xd4, 0x3c, 0xcc, 0x17, 0x39, 0x31, 0x00, 0x10, 0xd4, 0x3c, 0xcc, - 0x32, 0x17, 0x39, 0x30, 0x13, 0x09, 0x01, 0x37, 0x09, 0x01, 0x17, 0x09, - 0x01, 0x07, 0x09, 0x01, 0x96, 0x01, 0x5e, 0xfe, 0xa2, 0x74, 0x01, 0x5e, - 0x01, 0x5f, 0x74, 0xfe, 0xa2, 0x01, 0x5c, 0x74, 0xfe, 0xa3, 0xfe, 0xa4, - 0x01, 0x25, 0x01, 0x5c, 0x01, 0x5e, 0x75, 0xfe, 0xa2, 0x01, 0x5e, 0x75, - 0xfe, 0xa2, 0xfe, 0xa4, 0x77, 0x01, 0x5e, 0xfe, 0xa2, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x08, 0xff, 0xba, 0x04, 0xb0, 0x06, 0x17, 0x00, 0x09, - 0x00, 0x13, 0x00, 0x2b, 0x00, 0x6b, 0x40, 0x3a, 0x2b, 0x29, 0x26, 0x0b, - 0x0a, 0x09, 0x00, 0x04, 0x0e, 0x1d, 0x1f, 0x20, 0x14, 0x0e, 0x03, 0x2a, - 0x26, 0x1e, 0x03, 0x97, 0x1a, 0x0e, 0x97, 0x26, 0x96, 0x1a, 0x99, 0x1f, - 0x1f, 0x1e, 0x2c, 0x20, 0x23, 0x11, 0x2a, 0x14, 0x17, 0x0b, 0x0a, 0x09, - 0x00, 0x04, 0x06, 0x1d, 0x23, 0x11, 0x29, 0x06, 0x2b, 0x06, 0x32, 0x17, - 0x36, 0x11, 0x32, 0x23, 0x35, 0x2c, 0x10, 0xfc, 0xec, 0xfc, 0xec, 0xc0, - 0x12, 0x39, 0x11, 0x12, 0x39, 0x12, 0x17, 0x39, 0x11, 0x39, 0x39, 0x11, - 0x12, 0x39, 0x11, 0x39, 0x39, 0x31, 0x00, 0x2f, 0xe4, 0xf4, 0xec, 0x10, - 0xee, 0xc0, 0x10, 0xc0, 0x11, 0x12, 0x39, 0x39, 0x12, 0x39, 0x12, 0x17, - 0x39, 0x11, 0x39, 0x39, 0x30, 0x01, 0x1e, 0x01, 0x33, 0x32, 0x12, 0x11, - 0x34, 0x26, 0x27, 0x09, 0x01, 0x2e, 0x01, 0x23, 0x22, 0x02, 0x11, 0x14, - 0x16, 0x01, 0x16, 0x12, 0x15, 0x10, 0x02, 0x23, 0x22, 0x26, 0x27, 0x07, - 0x27, 0x37, 0x26, 0x02, 0x35, 0x10, 0x12, 0x33, 0x32, 0x16, 0x17, 0x37, - 0x17, 0x01, 0x73, 0x1e, 0x83, 0x54, 0x9a, 0x87, 0x0a, 0x0a, 0xfd, 0xdd, - 0x01, 0xf8, 0x19, 0x73, 0x56, 0x9d, 0x83, 0x05, 0x02, 0xbb, 0x29, 0x2b, - 0xf7, 0xfd, 0x79, 0xb4, 0x3d, 0x8f, 0x67, 0xb2, 0x20, 0x25, 0xf7, 0xfc, - 0x73, 0xad, 0x39, 0x8b, 0x64, 0x01, 0x2f, 0x4e, 0x5a, 0x01, 0x19, 0x01, - 0x49, 0x6e, 0x88, 0x2d, 0xfd, 0xcb, 0x02, 0xcf, 0x51, 0x55, 0xfe, 0xdc, - 0xfe, 0x86, 0x50, 0x65, 0x02, 0xe6, 0x51, 0xfe, 0xfe, 0xa3, 0xfe, 0x7a, - 0xfe, 0x80, 0x51, 0x51, 0xcb, 0x46, 0xfc, 0x49, 0x01, 0x06, 0x9e, 0x01, - 0x87, 0x01, 0x80, 0x52, 0x50, 0xc9, 0x4a, 0x00, 0xff, 0xff, 0x00, 0x93, - 0xff, 0xe3, 0x04, 0x3d, 0x07, 0x6b, 0x10, 0x26, 0x00, 0x38, 0x00, 0x00, - 0x11, 0x07, 0x0c, 0xc1, 0x00, 0x00, 0x01, 0x75, 0x00, 0x07, 0x40, 0x03, - 0x4f, 0x1f, 0x01, 0x5d, 0x31, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x93, - 0xff, 0xe3, 0x04, 0x3d, 0x07, 0x6b, 0x10, 0x26, 0x00, 0x38, 0x00, 0x00, - 0x11, 0x07, 0x0c, 0xbf, 0x00, 0x00, 0x01, 0x75, 0x00, 0x07, 0x40, 0x03, - 0x4f, 0x1f, 0x01, 0x5d, 0x31, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x93, - 0xff, 0xe3, 0x04, 0x3d, 0x07, 0x6d, 0x10, 0x26, 0x00, 0x38, 0x00, 0x00, - 0x11, 0x07, 0x0c, 0xc2, 0x00, 0x00, 0x01, 0x75, 0x00, 0x14, 0xb4, 0x11, - 0x20, 0x24, 0x01, 0x07, 0x2b, 0x40, 0x09, 0x20, 0x24, 0x2f, 0x20, 0x00, - 0x24, 0x0f, 0x20, 0x04, 0x5d, 0x31, 0x00, 0x00, 0xff, 0xff, 0x00, 0x93, - 0xff, 0xe3, 0x04, 0x3d, 0x07, 0x4e, 0x10, 0x26, 0x00, 0x38, 0x00, 0x00, - 0x11, 0x07, 0x0c, 0xbe, 0x00, 0x00, 0x01, 0x75, 0x00, 0x1c, 0xb4, 0x11, - 0x24, 0x21, 0x01, 0x07, 0x2b, 0x40, 0x11, 0x70, 0x21, 0x7f, 0x24, 0x30, - 0x21, 0x3f, 0x24, 0x20, 0x21, 0x2f, 0x24, 0x00, 0x21, 0x0f, 0x24, 0x08, - 0x5d, 0x31, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, - 0x07, 0x6b, 0x10, 0x26, 0x00, 0x3c, 0x00, 0x00, 0x11, 0x07, 0x0c, 0xbf, - 0x00, 0x00, 0x01, 0x75, 0x00, 0x07, 0x40, 0x03, 0x20, 0x09, 0x01, 0x5d, - 0x31, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xc9, 0x00, 0x00, 0x04, 0x8d, - 0x05, 0xd5, 0x00, 0x08, 0x00, 0x15, 0x00, 0x34, 0xb5, 0x01, 0x97, 0x12, - 0x00, 0x97, 0x0b, 0xb8, 0x01, 0x08, 0x40, 0x13, 0x09, 0x88, 0x14, 0x08, - 0x02, 0x12, 0x0c, 0x00, 0x05, 0x32, 0x0f, 0x38, 0x13, 0x0a, 0x00, 0x1e, - 0x09, 0x33, 0x16, 0x10, 0xfc, 0xec, 0x32, 0x32, 0xfc, 0xec, 0x11, 0x39, - 0x39, 0x39, 0x39, 0x31, 0x00, 0x2f, 0xf4, 0xfc, 0xec, 0xd4, 0xec, 0x30, - 0x01, 0x11, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x01, 0x33, 0x11, - 0x33, 0x20, 0x16, 0x15, 0x14, 0x06, 0x21, 0x23, 0x11, 0x23, 0x01, 0x93, - 0xea, 0x9e, 0x9d, 0x9d, 0x9e, 0xfe, 0x4c, 0xca, 0xfe, 0x01, 0x04, 0xf8, - 0xf8, 0xfe, 0xfc, 0xfe, 0xca, 0x04, 0x21, 0xfd, 0xf3, 0x84, 0x83, 0x83, - 0x83, 0x01, 0xb4, 0xfe, 0xf2, 0xd2, 0xda, 0xdb, 0xd1, 0xfe, 0x91, 0x00, - 0x00, 0x01, 0x00, 0xbc, 0xff, 0xe3, 0x04, 0x7d, 0x06, 0x14, 0x00, 0x2f, - 0x00, 0x56, 0x40, 0x31, 0x2d, 0x27, 0x21, 0x0c, 0x04, 0x06, 0x0d, 0x20, - 0x00, 0x04, 0x2a, 0x16, 0x8b, 0x17, 0x1a, 0x8c, 0x13, 0x2a, 0x8c, 0x03, - 0x9b, 0x13, 0x99, 0x2e, 0x0c, 0x09, 0x0d, 0x1d, 0x20, 0x21, 0x27, 0x09, - 0x01, 0x24, 0x27, 0x06, 0x06, 0x1d, 0x06, 0x24, 0x10, 0x16, 0x2d, 0x06, - 0x10, 0x44, 0x00, 0x46, 0x30, 0x10, 0xf4, 0xec, 0xfc, 0xcc, 0x10, 0xc6, - 0xee, 0xd4, 0xee, 0x10, 0xee, 0x11, 0x39, 0x39, 0x12, 0x39, 0x12, 0x39, - 0x31, 0x00, 0x2f, 0xe4, 0xfe, 0xee, 0x10, 0xfe, 0xd5, 0xee, 0x12, 0x17, - 0x39, 0x17, 0x39, 0x30, 0x13, 0x34, 0x36, 0x33, 0x32, 0x16, 0x17, 0x0e, - 0x01, 0x15, 0x14, 0x16, 0x1f, 0x01, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x23, - 0x22, 0x26, 0x27, 0x35, 0x1e, 0x01, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, - 0x2f, 0x01, 0x2e, 0x01, 0x35, 0x34, 0x36, 0x37, 0x2e, 0x01, 0x23, 0x22, - 0x06, 0x15, 0x11, 0x23, 0xbc, 0xd2, 0xd8, 0xcc, 0xd2, 0x02, 0x9b, 0xa8, - 0x37, 0x43, 0x3a, 0x97, 0x6f, 0xe0, 0xc4, 0x45, 0x87, 0x42, 0x4c, 0x85, - 0x3b, 0x6c, 0x80, 0x41, 0x78, 0x43, 0x5c, 0x5b, 0xa2, 0x9c, 0x02, 0x79, - 0x71, 0x79, 0x72, 0xbb, 0x04, 0x71, 0xd5, 0xce, 0xdd, 0xd8, 0x0e, 0x7c, - 0x64, 0x31, 0x4d, 0x2a, 0x25, 0x5d, 0xa4, 0x74, 0x9a, 0xb2, 0x19, 0x18, - 0xa4, 0x1f, 0x1e, 0x61, 0x51, 0x47, 0x5f, 0x4a, 0x27, 0x38, 0x85, 0x4f, - 0x80, 0xab, 0x23, 0x6b, 0x72, 0x83, 0x8b, 0xfb, 0x93, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x85, 0xff, 0xe3, 0x04, 0x23, 0x06, 0x66, 0x10, 0x26, - 0x00, 0x44, 0x00, 0x00, 0x10, 0x06, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x85, 0xff, 0xe3, 0x04, 0x23, 0x06, 0x66, 0x10, 0x26, - 0x00, 0x44, 0x00, 0x00, 0x10, 0x06, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x85, 0xff, 0xe3, 0x04, 0x23, 0x06, 0x66, 0x10, 0x26, - 0x00, 0x44, 0x00, 0x00, 0x10, 0x06, 0x02, 0x67, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x85, 0xff, 0xe3, 0x04, 0x23, 0x06, 0x37, 0x10, 0x26, - 0x00, 0x44, 0x00, 0x00, 0x10, 0x06, 0x02, 0x79, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x85, 0xff, 0xe3, 0x04, 0x23, 0x06, 0x10, 0x10, 0x26, - 0x00, 0x44, 0x00, 0x00, 0x10, 0x06, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x85, 0xff, 0xe3, 0x04, 0x23, 0x07, 0x06, 0x10, 0x26, - 0x00, 0x44, 0x00, 0x00, 0x10, 0x06, 0x02, 0x77, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x29, 0xff, 0xe3, 0x04, 0xb0, 0x04, 0x7b, 0x00, 0x0a, - 0x00, 0x13, 0x00, 0x43, 0x00, 0x8f, 0x40, 0x49, 0x3d, 0x37, 0x0f, 0x30, - 0x0c, 0x12, 0x03, 0x36, 0x0b, 0x25, 0x08, 0x00, 0x1e, 0x43, 0x0b, 0x01, - 0x1f, 0x8b, 0x1e, 0x8d, 0x1b, 0x08, 0x8c, 0x22, 0x37, 0x8b, 0x36, 0xbf, - 0x0f, 0x2e, 0x0b, 0xb6, 0x14, 0x01, 0xc1, 0x33, 0x0f, 0x8c, 0x40, 0x3a, - 0xbe, 0x28, 0x22, 0x99, 0x44, 0x02, 0x05, 0x00, 0x18, 0x25, 0x3d, 0x03, - 0x2f, 0x12, 0x2e, 0x05, 0x15, 0x12, 0x4d, 0x2f, 0x00, 0x75, 0x1e, 0x0b, - 0x4d, 0x14, 0x43, 0x05, 0x4d, 0x36, 0x2b, 0x73, 0x44, 0x10, 0xf4, 0xc4, - 0xec, 0xfc, 0xec, 0xc4, 0xfc, 0xc4, 0xec, 0x32, 0x12, 0x39, 0x11, 0x12, - 0x17, 0x39, 0x11, 0x12, 0x39, 0x31, 0x00, 0x10, 0xe4, 0x32, 0xf4, 0x3c, - 0xec, 0x32, 0xf4, 0x3c, 0xec, 0x32, 0x10, 0xf4, 0xee, 0x10, 0xfe, 0x3c, - 0xf4, 0xee, 0x11, 0x12, 0x39, 0x12, 0x39, 0x11, 0x39, 0x11, 0x12, 0x17, - 0x39, 0x11, 0x12, 0x39, 0x30, 0x40, 0x09, 0x30, 0x35, 0x30, 0x36, 0x30, - 0x37, 0x30, 0x38, 0x04, 0x5d, 0x01, 0x35, 0x23, 0x22, 0x06, 0x15, 0x14, - 0x16, 0x33, 0x32, 0x36, 0x01, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x1d, - 0x01, 0x05, 0x21, 0x0e, 0x01, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, - 0x15, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x27, 0x0e, 0x01, 0x23, 0x22, 0x26, - 0x35, 0x34, 0x36, 0x3b, 0x01, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, - 0x35, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x17, 0x3e, 0x01, 0x33, 0x32, 0x16, - 0x11, 0x02, 0x1f, 0x31, 0xa9, 0x78, 0x59, 0x53, 0x5c, 0x4a, 0x01, 0xed, - 0x4d, 0x57, 0x57, 0x4c, 0x01, 0xeb, 0xfe, 0x15, 0x01, 0x01, 0x65, 0x70, - 0x4f, 0x81, 0x32, 0x37, 0x84, 0x47, 0x6e, 0x95, 0x20, 0x27, 0x85, 0x61, - 0x9c, 0xa3, 0xc8, 0xbf, 0x75, 0x63, 0x5e, 0x38, 0x84, 0x3e, 0x4d, 0x84, - 0x3c, 0x5b, 0x7c, 0x25, 0x21, 0x84, 0x59, 0xae, 0x91, 0x01, 0xba, 0x48, - 0x5a, 0x71, 0x59, 0x61, 0x85, 0x01, 0x8f, 0x34, 0x97, 0x85, 0x88, 0x9d, - 0x2b, 0x8f, 0x0f, 0x23, 0x22, 0xa1, 0x90, 0x33, 0x33, 0xac, 0x29, 0x2b, - 0x52, 0x4e, 0x50, 0x50, 0xac, 0xa4, 0xab, 0xb3, 0x58, 0x78, 0x80, 0x2b, - 0x27, 0xa8, 0x23, 0x21, 0x3f, 0x40, 0x3d, 0x42, 0xed, 0xfe, 0xce, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x75, 0x04, 0x25, 0x04, 0x7b, 0x10, 0x26, - 0x02, 0xaf, 0x68, 0x00, 0x10, 0x06, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x7b, 0xff, 0xe3, 0x04, 0x58, 0x06, 0x66, 0x10, 0x26, - 0x00, 0x48, 0x00, 0x00, 0x10, 0x06, 0x00, 0x43, 0x0e, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x7b, 0xff, 0xe3, 0x04, 0x58, 0x06, 0x66, 0x10, 0x26, - 0x00, 0x48, 0x00, 0x00, 0x10, 0x06, 0x00, 0x76, 0x0e, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x7b, 0xff, 0xe3, 0x04, 0x58, 0x06, 0x66, 0x10, 0x26, - 0x00, 0x48, 0x00, 0x00, 0x10, 0x06, 0x02, 0x67, 0x0e, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x7b, 0xff, 0xe3, 0x04, 0x58, 0x06, 0x10, 0x10, 0x26, - 0x00, 0x48, 0x00, 0x00, 0x11, 0x06, 0x00, 0x6a, 0x0e, 0x00, 0x00, 0x07, - 0x40, 0x03, 0x40, 0x1d, 0x01, 0x5d, 0x31, 0x00, 0xff, 0xff, 0x00, 0xb2, - 0x00, 0x00, 0x04, 0x44, 0x06, 0x66, 0x10, 0x26, 0x00, 0xf3, 0x00, 0x00, - 0x10, 0x06, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xb2, - 0x00, 0x00, 0x04, 0x44, 0x06, 0x66, 0x10, 0x26, 0x00, 0xf3, 0x00, 0x00, - 0x10, 0x06, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xb2, - 0x00, 0x00, 0x04, 0x44, 0x06, 0x66, 0x10, 0x26, 0x00, 0xf3, 0x00, 0x00, - 0x11, 0x06, 0x02, 0x67, 0x00, 0x00, 0x00, 0x09, 0x40, 0x05, 0x40, 0x0a, - 0x30, 0x0a, 0x02, 0x5d, 0x31, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xb2, - 0x00, 0x00, 0x04, 0x44, 0x06, 0x10, 0x10, 0x26, 0x00, 0xf3, 0x00, 0x00, - 0x11, 0x06, 0x00, 0x6a, 0x18, 0x00, 0x00, 0x08, 0xb4, 0x03, 0x10, 0x0d, - 0x06, 0x07, 0x2b, 0x31, 0x00, 0x02, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, - 0x06, 0x14, 0x00, 0x1a, 0x00, 0x29, 0x00, 0x8b, 0x40, 0x4f, 0x12, 0x17, - 0x13, 0x12, 0x01, 0x00, 0x0d, 0x0e, 0x0f, 0x10, 0x04, 0x11, 0x17, 0x00, - 0x01, 0x00, 0x16, 0x17, 0x17, 0x18, 0x17, 0x15, 0x17, 0x14, 0x15, 0x18, - 0x18, 0x17, 0x42, 0x1a, 0x19, 0x18, 0x15, 0x14, 0x13, 0x06, 0x16, 0x0f, - 0x1e, 0x12, 0x00, 0x16, 0x1e, 0x8c, 0x0c, 0x24, 0x8c, 0x06, 0x99, 0x0c, - 0x16, 0x9b, 0x2a, 0x12, 0x15, 0x18, 0x03, 0x27, 0x14, 0x13, 0x16, 0x03, - 0x21, 0x09, 0x1a, 0x19, 0x03, 0x0f, 0x00, 0x21, 0x27, 0x12, 0x03, 0x44, - 0x21, 0x12, 0x09, 0x3e, 0x2a, 0x10, 0xf4, 0xec, 0xfc, 0xec, 0x11, 0x39, - 0x39, 0x11, 0x39, 0x39, 0x11, 0x12, 0x17, 0x39, 0x11, 0x17, 0x39, 0x31, - 0x00, 0x10, 0xec, 0xcc, 0xf4, 0xec, 0x10, 0xee, 0x12, 0x39, 0x39, 0x12, - 0x39, 0x12, 0x17, 0x39, 0x30, 0x4b, 0x53, 0x58, 0x07, 0x10, 0x08, 0xed, - 0x07, 0x10, 0x05, 0xed, 0x07, 0x10, 0x05, 0xed, 0x17, 0x39, 0x07, 0x08, - 0xed, 0x59, 0x22, 0x01, 0x16, 0x12, 0x15, 0x10, 0x02, 0x23, 0x22, 0x02, - 0x11, 0x10, 0x12, 0x33, 0x32, 0x16, 0x17, 0x2e, 0x01, 0x27, 0x05, 0x27, - 0x37, 0x27, 0x33, 0x17, 0x25, 0x17, 0x03, 0x2e, 0x01, 0x23, 0x22, 0x06, - 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x02, 0xcd, 0xc5, - 0xb6, 0xfb, 0xe5, 0xe4, 0xfb, 0xfb, 0xe0, 0x22, 0x23, 0x0f, 0x21, 0x48, - 0x26, 0xfe, 0xe9, 0x1e, 0xed, 0xb6, 0xdb, 0x7f, 0x01, 0x21, 0x21, 0xae, - 0x23, 0x52, 0x2d, 0x92, 0x99, 0x94, 0x88, 0x89, 0x94, 0x3a, 0x05, 0x2f, - 0xd4, 0xfe, 0x84, 0xc8, 0xfe, 0xf4, 0xfe, 0xd8, 0x01, 0x28, 0x01, 0x0c, - 0x01, 0x09, 0x01, 0x28, 0x02, 0x02, 0x2d, 0x59, 0x2c, 0x5c, 0x62, 0x50, - 0xc8, 0x91, 0x5e, 0x62, 0xfe, 0x17, 0x0d, 0x0d, 0xd2, 0xc7, 0xc4, 0xd4, - 0xd4, 0xc4, 0x6e, 0xcb, 0xff, 0xff, 0x00, 0xc3, 0x00, 0x00, 0x04, 0x1b, - 0x06, 0x37, 0x10, 0x26, 0x00, 0x51, 0x00, 0x00, 0x10, 0x06, 0x02, 0x79, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, - 0x06, 0x66, 0x10, 0x26, 0x00, 0x52, 0x00, 0x00, 0x10, 0x06, 0x00, 0x43, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, - 0x06, 0x66, 0x10, 0x26, 0x00, 0x52, 0x00, 0x00, 0x10, 0x06, 0x00, 0x76, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, - 0x06, 0x66, 0x10, 0x26, 0x00, 0x52, 0x00, 0x00, 0x11, 0x06, 0x02, 0x67, - 0x00, 0x00, 0x00, 0x10, 0xb4, 0x0f, 0x1a, 0x1e, 0x15, 0x07, 0x2b, 0x40, - 0x05, 0x0f, 0x1a, 0x00, 0x1e, 0x02, 0x5d, 0x31, 0xff, 0xff, 0x00, 0x89, - 0xff, 0xe3, 0x04, 0x48, 0x06, 0x37, 0x10, 0x26, 0x00, 0x52, 0x00, 0x00, - 0x11, 0x06, 0x02, 0x79, 0x00, 0x00, 0x00, 0x18, 0xb4, 0x0f, 0x2e, 0x20, - 0x15, 0x07, 0x2b, 0x40, 0x0d, 0x30, 0x20, 0x3f, 0x2e, 0x20, 0x20, 0x2f, - 0x2e, 0x10, 0x20, 0x1f, 0x2e, 0x06, 0x5d, 0x31, 0xff, 0xff, 0x00, 0x89, - 0xff, 0xe3, 0x04, 0x48, 0x06, 0x10, 0x10, 0x26, 0x00, 0x52, 0x00, 0x00, - 0x11, 0x06, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x18, 0xb4, 0x09, 0x1e, 0x1b, - 0x03, 0x07, 0x2b, 0x40, 0x0d, 0x7f, 0x1e, 0x70, 0x1b, 0x5f, 0x1e, 0x50, - 0x1b, 0x4f, 0x1e, 0x40, 0x1b, 0x06, 0x5d, 0x31, 0x00, 0x03, 0x00, 0x58, - 0x00, 0x96, 0x04, 0x79, 0x04, 0x6f, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, - 0x00, 0x27, 0x40, 0x13, 0x02, 0xfe, 0x00, 0x04, 0xfe, 0x06, 0x08, 0xa0, - 0x00, 0x0a, 0x0c, 0x09, 0x05, 0x01, 0x77, 0x08, 0x04, 0x00, 0x0c, 0x10, - 0xd4, 0x3c, 0xc4, 0xfc, 0x3c, 0xc4, 0x31, 0x00, 0x10, 0xd4, 0xc4, 0xfc, - 0xd4, 0xec, 0x10, 0xee, 0x30, 0x01, 0x33, 0x15, 0x23, 0x11, 0x33, 0x15, - 0x23, 0x05, 0x21, 0x15, 0x21, 0x01, 0xee, 0xf5, 0xf5, 0xf5, 0xf5, 0xfe, - 0x6a, 0x04, 0x21, 0xfb, 0xdf, 0x01, 0x8b, 0xf5, 0x03, 0xd9, 0xf6, 0xa2, - 0xaa, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x2f, 0xff, 0xa0, 0x04, 0x96, - 0x04, 0xbc, 0x00, 0x09, 0x00, 0x13, 0x00, 0x2b, 0x00, 0x73, 0x40, 0x3e, - 0x2b, 0x2c, 0x26, 0x1f, 0x1d, 0x1a, 0x13, 0x0a, 0x01, 0x00, 0x04, 0x0d, - 0x29, 0x26, 0x20, 0x14, 0x0d, 0x04, 0x2a, 0x26, 0x1e, 0x1a, 0x04, 0x8c, - 0x26, 0x0d, 0x8c, 0x1a, 0xbe, 0x26, 0x99, 0x2c, 0x2b, 0x2c, 0x2a, 0x14, - 0x17, 0x10, 0x20, 0x1e, 0x23, 0x13, 0x0a, 0x01, 0x00, 0x04, 0x07, 0x29, - 0x17, 0x10, 0x1d, 0x07, 0x1f, 0x07, 0x12, 0x23, 0x44, 0x10, 0x12, 0x17, - 0x3e, 0x2c, 0x10, 0xf4, 0xec, 0xfc, 0xec, 0xc0, 0x12, 0x39, 0x11, 0x12, - 0x39, 0x12, 0x17, 0x39, 0x11, 0x39, 0x39, 0x11, 0x12, 0x39, 0x39, 0x11, - 0x39, 0x31, 0x00, 0x10, 0xe4, 0xf4, 0xec, 0x10, 0xee, 0x10, 0xc0, 0x10, - 0xc0, 0x11, 0x12, 0x39, 0x39, 0x12, 0x39, 0x12, 0x17, 0x39, 0x11, 0x39, - 0x39, 0x11, 0x12, 0x39, 0x30, 0x09, 0x01, 0x1e, 0x01, 0x33, 0x32, 0x36, - 0x35, 0x34, 0x26, 0x27, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, - 0x17, 0x07, 0x2e, 0x01, 0x35, 0x10, 0x12, 0x33, 0x32, 0x16, 0x17, 0x37, - 0x17, 0x07, 0x1e, 0x01, 0x15, 0x10, 0x02, 0x23, 0x22, 0x26, 0x27, 0x07, - 0x27, 0x03, 0x6d, 0xfe, 0x31, 0x24, 0x65, 0x41, 0x8d, 0x90, 0x0c, 0x48, - 0x23, 0x63, 0x43, 0x8b, 0x95, 0x0e, 0x0e, 0x8b, 0x27, 0x29, 0xf6, 0xe9, - 0x64, 0x9e, 0x3c, 0x93, 0x5d, 0xa4, 0x2a, 0x2c, 0xf6, 0xea, 0x67, 0x9d, - 0x39, 0xa0, 0x5c, 0x03, 0x0c, 0xfd, 0xd1, 0x2f, 0x2f, 0xdb, 0xd5, 0x34, - 0x6f, 0xaf, 0x30, 0x2e, 0xd6, 0xca, 0x30, 0x74, 0x47, 0xa0, 0x47, 0xc3, - 0x71, 0x01, 0x1e, 0x01, 0x2e, 0x37, 0x38, 0xb0, 0x4d, 0xc3, 0x42, 0xc1, - 0x7a, 0xfe, 0xe1, 0xfe, 0xd3, 0x3b, 0x3c, 0xba, 0x4c, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xff, 0xe3, 0x04, 0x1b, 0x06, 0x66, 0x10, 0x26, - 0x00, 0x58, 0x00, 0x00, 0x10, 0x06, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xff, 0xe3, 0x04, 0x1b, 0x06, 0x66, 0x10, 0x26, - 0x00, 0x58, 0x00, 0x00, 0x10, 0x06, 0x00, 0x76, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xff, 0xe3, 0x04, 0x1b, 0x06, 0x66, 0x10, 0x26, - 0x00, 0x58, 0x00, 0x00, 0x11, 0x06, 0x02, 0x67, 0x00, 0x00, 0x00, 0x10, - 0xb4, 0x0b, 0x16, 0x1a, 0x01, 0x07, 0x2b, 0x40, 0x05, 0x0f, 0x16, 0x00, - 0x1a, 0x02, 0x5d, 0x31, 0xff, 0xff, 0x00, 0xc3, 0xff, 0xe3, 0x04, 0x1b, - 0x06, 0x10, 0x10, 0x26, 0x00, 0x58, 0x00, 0x00, 0x11, 0x06, 0x00, 0x6a, - 0x00, 0x00, 0x00, 0x18, 0xb4, 0x0a, 0x1a, 0x17, 0x02, 0x07, 0x2b, 0x40, - 0x0d, 0x7f, 0x1a, 0x70, 0x17, 0x5f, 0x1a, 0x50, 0x17, 0x4f, 0x1a, 0x40, - 0x17, 0x06, 0x5d, 0x31, 0xff, 0xff, 0x00, 0x68, 0xfe, 0x56, 0x04, 0x81, - 0x06, 0x66, 0x10, 0x26, 0x00, 0x5c, 0x00, 0x00, 0x10, 0x06, 0x00, 0x76, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xbe, 0xfe, 0x56, 0x04, 0x54, - 0x06, 0x1f, 0x00, 0x10, 0x00, 0x1c, 0x00, 0x33, 0x40, 0x1c, 0x05, 0x00, - 0x1a, 0x14, 0x8c, 0x08, 0x1a, 0x8c, 0x0e, 0x99, 0x08, 0xbe, 0x01, 0xc3, - 0x03, 0xc5, 0x1d, 0x11, 0x12, 0x0b, 0x47, 0x17, 0x04, 0x00, 0x06, 0x02, - 0x46, 0x1d, 0x10, 0xf4, 0xec, 0x32, 0x32, 0xfc, 0xec, 0x31, 0x00, 0x10, - 0xec, 0xe4, 0xe4, 0xf4, 0xec, 0x10, 0xee, 0x11, 0x39, 0x39, 0x30, 0x25, - 0x11, 0x23, 0x11, 0x33, 0x11, 0x3e, 0x01, 0x33, 0x32, 0x12, 0x11, 0x10, - 0x02, 0x23, 0x22, 0x26, 0x01, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, - 0x16, 0x33, 0x32, 0x36, 0x01, 0x77, 0xb9, 0xb9, 0x2e, 0x99, 0x64, 0xcb, - 0xe7, 0xe8, 0xca, 0x66, 0x99, 0x01, 0xf0, 0x87, 0x85, 0x86, 0x8a, 0x8a, - 0x86, 0x85, 0x87, 0x8d, 0xfd, 0xc9, 0x07, 0xc9, 0xfd, 0xb2, 0x53, 0x57, - 0xfe, 0xc6, 0xfe, 0xea, 0xfe, 0xef, 0xfe, 0xc9, 0x57, 0x01, 0xf5, 0xd6, - 0xda, 0xdb, 0xd5, 0xd4, 0xdc, 0xda, 0x00, 0x00, 0xff, 0xff, 0x00, 0x68, - 0xfe, 0x56, 0x04, 0x81, 0x06, 0x10, 0x10, 0x26, 0x00, 0x5c, 0x00, 0x00, - 0x10, 0x06, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, - 0x00, 0x00, 0x04, 0xac, 0x07, 0x30, 0x10, 0x26, 0x0c, 0xcb, 0x00, 0x00, - 0x11, 0x06, 0x00, 0x24, 0x00, 0x00, 0x00, 0x14, 0xb4, 0x09, 0x02, 0x03, - 0x0e, 0x07, 0x2b, 0x40, 0x09, 0x40, 0x03, 0x4f, 0x02, 0x20, 0x03, 0x2f, - 0x02, 0x04, 0x5d, 0x31, 0xff, 0xff, 0x00, 0x85, 0xff, 0xe3, 0x04, 0x23, - 0x05, 0xf6, 0x10, 0x26, 0x02, 0x8c, 0x00, 0x00, 0x10, 0x06, 0x00, 0x44, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, - 0x07, 0x6d, 0x10, 0x26, 0x0c, 0xc6, 0x00, 0x00, 0x11, 0x06, 0x00, 0x24, - 0x00, 0x00, 0x00, 0x18, 0xb4, 0x13, 0x08, 0x00, 0x18, 0x07, 0x2b, 0x40, - 0x0d, 0x5f, 0x08, 0x50, 0x00, 0x4f, 0x08, 0x40, 0x00, 0x2f, 0x08, 0x20, - 0x00, 0x06, 0x5d, 0x31, 0xff, 0xff, 0x00, 0x85, 0xff, 0xe3, 0x04, 0x23, - 0x06, 0x48, 0x10, 0x26, 0x02, 0x8e, 0x00, 0x00, 0x10, 0x06, 0x00, 0x44, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, 0xfe, 0x75, 0x04, 0xe0, - 0x05, 0xd5, 0x10, 0x27, 0x02, 0x78, 0x01, 0xc7, 0x00, 0x00, 0x10, 0x06, - 0x00, 0x24, 0x00, 0x00, 0xff, 0xff, 0x00, 0x85, 0xfe, 0x75, 0x04, 0x72, - 0x04, 0x7b, 0x10, 0x27, 0x02, 0x78, 0x01, 0x59, 0x00, 0x00, 0x10, 0x06, - 0x00, 0x44, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8b, 0xff, 0xe3, 0x04, 0x31, - 0x07, 0x6b, 0x10, 0x26, 0x00, 0x26, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xbf, - 0x00, 0x5a, 0x01, 0x75, 0xff, 0xff, 0x00, 0xc3, 0xff, 0xe3, 0x04, 0x25, - 0x06, 0x66, 0x10, 0x26, 0x00, 0x46, 0x00, 0x00, 0x10, 0x06, 0x00, 0x76, - 0x5a, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8b, 0xff, 0xe3, 0x04, 0x31, - 0x07, 0x74, 0x10, 0x27, 0x0c, 0xc2, 0x00, 0x7e, 0x01, 0x7c, 0x10, 0x06, - 0x00, 0x26, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, 0xff, 0xe3, 0x04, 0x25, - 0x06, 0x66, 0x10, 0x26, 0x02, 0x67, 0x5a, 0x00, 0x10, 0x06, 0x00, 0x46, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8b, 0xff, 0xe3, 0x04, 0x31, - 0x07, 0x50, 0x10, 0x26, 0x0c, 0xc7, 0x4b, 0x00, 0x10, 0x06, 0x00, 0x26, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, 0xff, 0xe3, 0x04, 0x25, - 0x06, 0x10, 0x10, 0x26, 0x02, 0x8f, 0x4b, 0x00, 0x10, 0x06, 0x00, 0x46, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8b, 0xff, 0xe3, 0x04, 0x31, - 0x07, 0x6d, 0x10, 0x26, 0x00, 0x26, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xc3, - 0x00, 0x5a, 0x01, 0x75, 0xff, 0xff, 0x00, 0xc3, 0xff, 0xe3, 0x04, 0x25, - 0x06, 0x66, 0x10, 0x26, 0x00, 0x46, 0x00, 0x00, 0x10, 0x06, 0x02, 0x68, - 0x5a, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0x00, 0x00, 0x04, 0x52, - 0x07, 0x67, 0x10, 0x26, 0x00, 0x27, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xc3, - 0xff, 0xb2, 0x01, 0x6f, 0xff, 0xff, 0x00, 0x7b, 0xff, 0xe3, 0x05, 0x20, - 0x06, 0x15, 0x10, 0x27, 0x0c, 0xbd, 0x02, 0x3a, 0xff, 0xaf, 0x11, 0x06, - 0x00, 0x47, 0x00, 0x00, 0x00, 0x0d, 0xb9, 0x00, 0x00, 0x00, 0x40, 0x38, - 0x40, 0x03, 0x7f, 0x00, 0x01, 0x5d, 0x31, 0x00, 0xff, 0xff, 0x00, 0x08, - 0x00, 0x00, 0x04, 0x4e, 0x05, 0xd5, 0x10, 0x06, 0x00, 0x92, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x7b, 0xff, 0xe3, 0x04, 0xd1, 0x06, 0x14, 0x00, 0x18, - 0x00, 0x24, 0x00, 0x48, 0x40, 0x09, 0x0d, 0x00, 0x22, 0x1c, 0x07, 0x03, - 0xe7, 0x09, 0x01, 0xb8, 0x01, 0x0c, 0x40, 0x1c, 0x22, 0x8c, 0x16, 0x1c, - 0x8c, 0x10, 0x99, 0x16, 0xbe, 0x05, 0x9b, 0x0b, 0x02, 0x1f, 0x0c, 0x04, - 0x03, 0x00, 0x06, 0x08, 0x0a, 0x06, 0x47, 0x19, 0x12, 0x13, 0x48, 0x25, - 0x10, 0xf4, 0xec, 0xfc, 0x3c, 0xc4, 0xfc, 0x17, 0x3c, 0xc4, 0x31, 0x00, - 0x2f, 0xec, 0xe4, 0xf4, 0xec, 0x10, 0xee, 0xfd, 0x3c, 0xee, 0x32, 0x11, - 0x12, 0x39, 0x39, 0x30, 0x01, 0x11, 0x21, 0x35, 0x21, 0x35, 0x33, 0x15, - 0x33, 0x15, 0x23, 0x11, 0x23, 0x35, 0x0e, 0x01, 0x23, 0x22, 0x02, 0x11, - 0x10, 0x12, 0x33, 0x32, 0x16, 0x01, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, - 0x34, 0x26, 0x23, 0x22, 0x06, 0x03, 0x5a, 0xfe, 0xcf, 0x01, 0x31, 0xb8, - 0xbf, 0xbf, 0xb8, 0x2e, 0x99, 0x64, 0xcb, 0xe9, 0xea, 0xca, 0x65, 0x9a, - 0xfe, 0x0f, 0x88, 0x85, 0x85, 0x8b, 0x8b, 0x85, 0x85, 0x88, 0x03, 0xd1, - 0x01, 0x35, 0x79, 0x95, 0x95, 0x79, 0xfa, 0xfa, 0x8d, 0x53, 0x57, 0x01, - 0x3b, 0x01, 0x15, 0x01, 0x11, 0x01, 0x37, 0x57, 0xfe, 0x0b, 0xd6, 0xda, - 0xdc, 0xd4, 0xd5, 0xdb, 0xda, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc5, - 0x00, 0x00, 0x04, 0x4e, 0x07, 0x30, 0x10, 0x26, 0x0c, 0xcb, 0x12, 0x00, - 0x10, 0x06, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, - 0xff, 0xe3, 0x04, 0x58, 0x05, 0xf6, 0x10, 0x26, 0x02, 0x8c, 0x23, 0x00, - 0x10, 0x06, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc5, - 0x00, 0x00, 0x04, 0x4e, 0x07, 0x6d, 0x10, 0x26, 0x0c, 0xc6, 0x12, 0x00, - 0x10, 0x06, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, - 0xff, 0xe3, 0x04, 0x58, 0x06, 0x48, 0x10, 0x26, 0x02, 0x8e, 0x0e, 0x00, - 0x10, 0x06, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc5, - 0x00, 0x00, 0x04, 0x4e, 0x07, 0x50, 0x10, 0x26, 0x0c, 0xc7, 0x12, 0x00, - 0x10, 0x06, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, - 0xff, 0xe3, 0x04, 0x58, 0x06, 0x10, 0x10, 0x26, 0x02, 0x8f, 0x0e, 0x00, - 0x10, 0x06, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc5, - 0xfe, 0x75, 0x04, 0x4e, 0x05, 0xd5, 0x10, 0x27, 0x02, 0x78, 0x01, 0x31, - 0x00, 0x00, 0x10, 0x06, 0x00, 0x28, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, - 0xfe, 0x75, 0x04, 0x58, 0x04, 0x7b, 0x10, 0x27, 0x02, 0x78, 0x00, 0xf6, - 0x00, 0x00, 0x10, 0x06, 0x00, 0x48, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc5, - 0x00, 0x00, 0x04, 0x4e, 0x07, 0x67, 0x10, 0x26, 0x00, 0x28, 0x00, 0x00, - 0x10, 0x07, 0x0c, 0xc3, 0x00, 0x24, 0x01, 0x6f, 0xff, 0xff, 0x00, 0x7b, - 0xff, 0xe3, 0x04, 0x58, 0x06, 0x61, 0x10, 0x26, 0x00, 0x48, 0x00, 0x00, - 0x10, 0x06, 0x02, 0x68, 0x23, 0xfb, 0x00, 0x00, 0xff, 0xff, 0x00, 0x66, - 0xff, 0xe3, 0x04, 0x50, 0x07, 0x6d, 0x10, 0x27, 0x0c, 0xc2, 0x00, 0x00, - 0x01, 0x75, 0x10, 0x06, 0x00, 0x2a, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, - 0xfe, 0x48, 0x04, 0x12, 0x06, 0x66, 0x10, 0x26, 0x02, 0x67, 0x00, 0x00, - 0x10, 0x06, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x66, - 0xff, 0xe3, 0x04, 0x50, 0x07, 0x6d, 0x10, 0x26, 0x0c, 0xc6, 0x32, 0x00, - 0x10, 0x06, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, - 0xfe, 0x48, 0x04, 0x12, 0x06, 0x48, 0x10, 0x26, 0x02, 0x8e, 0x00, 0x00, - 0x10, 0x06, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x66, - 0xff, 0xe3, 0x04, 0x50, 0x07, 0x50, 0x10, 0x26, 0x0c, 0xc7, 0x32, 0x00, - 0x10, 0x06, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, - 0xfe, 0x48, 0x04, 0x12, 0x06, 0x10, 0x10, 0x26, 0x02, 0x8f, 0x00, 0x00, - 0x10, 0x06, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x66, - 0xfd, 0xc3, 0x04, 0x50, 0x05, 0xf0, 0x10, 0x27, 0x02, 0xae, 0x00, 0x80, - 0xff, 0xe1, 0x10, 0x06, 0x00, 0x2a, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, - 0xfe, 0x48, 0x04, 0x12, 0x06, 0x4e, 0x10, 0x27, 0x02, 0x9a, 0x00, 0x11, - 0x01, 0x2e, 0x10, 0x06, 0x00, 0x4a, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, - 0x00, 0x00, 0x04, 0x48, 0x07, 0x6d, 0x10, 0x27, 0x0c, 0xc2, 0x00, 0x00, - 0x01, 0x75, 0x11, 0x06, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x14, 0xb4, 0x0c, - 0x02, 0x06, 0x07, 0x07, 0x2b, 0x40, 0x09, 0x20, 0x06, 0x2f, 0x02, 0x00, - 0x06, 0x0f, 0x02, 0x04, 0x5d, 0x31, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, - 0x00, 0x00, 0x04, 0x1b, 0x07, 0x6d, 0x10, 0x27, 0x0c, 0xc2, 0x00, 0x00, - 0x01, 0x75, 0x11, 0x06, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4b, - 0xb0, 0x12, 0x51, 0x58, 0xb9, 0x00, 0x00, 0x00, 0x40, 0x38, 0x59, 0x40, - 0x07, 0x70, 0x00, 0x60, 0x00, 0x4f, 0x00, 0x03, 0x5d, 0x30, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x03, 0x00, 0x00, 0x04, 0xce, 0x05, 0xd5, 0x00, 0x13, - 0x00, 0x17, 0x00, 0x3f, 0x40, 0x21, 0x06, 0x02, 0x12, 0x97, 0x09, 0x14, - 0x11, 0x0c, 0x97, 0x15, 0xb1, 0x04, 0x00, 0x88, 0x0e, 0x0a, 0x07, 0x0c, - 0x17, 0x04, 0x1e, 0x09, 0x05, 0x31, 0x12, 0x0d, 0x14, 0x01, 0x1e, 0x10, - 0x00, 0x30, 0x18, 0x10, 0xfc, 0x3c, 0xec, 0x32, 0x32, 0xcc, 0xfc, 0x3c, - 0xec, 0x32, 0x32, 0xcc, 0x31, 0x00, 0x2f, 0x3c, 0xe4, 0x32, 0xfc, 0xec, - 0xdc, 0x3c, 0x3c, 0xec, 0x32, 0x32, 0x30, 0x13, 0x33, 0x15, 0x21, 0x35, - 0x33, 0x15, 0x33, 0x15, 0x23, 0x11, 0x23, 0x11, 0x21, 0x11, 0x23, 0x11, - 0x23, 0x35, 0x33, 0x17, 0x15, 0x21, 0x35, 0x89, 0xca, 0x02, 0x2a, 0xca, - 0x87, 0x87, 0xca, 0xfd, 0xd6, 0xca, 0x86, 0x86, 0xca, 0x02, 0x2a, 0x05, - 0xd5, 0xe0, 0xe0, 0xe0, 0xa4, 0xfb, 0xaf, 0x02, 0xc7, 0xfd, 0x39, 0x04, - 0x51, 0xa4, 0xa4, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x46, - 0x00, 0x00, 0x04, 0x1b, 0x06, 0x14, 0x00, 0x1b, 0x00, 0x3f, 0x40, 0x22, - 0x09, 0x16, 0x03, 0x00, 0x03, 0x01, 0x12, 0x0e, 0xb6, 0x15, 0x0d, 0x06, - 0x8c, 0x19, 0xbe, 0x10, 0x9b, 0x0a, 0x01, 0x02, 0x06, 0x00, 0x4a, 0x10, - 0x13, 0x11, 0x15, 0x09, 0x06, 0x0e, 0x10, 0x0b, 0x46, 0x1c, 0x10, 0xf4, - 0x3c, 0xcc, 0xfc, 0x32, 0x32, 0xcc, 0x10, 0xfc, 0xec, 0x31, 0x00, 0x2f, - 0x3c, 0xec, 0xf4, 0xec, 0xdc, 0x3c, 0xec, 0x32, 0x11, 0x17, 0x39, 0x39, - 0x30, 0x01, 0x11, 0x23, 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x11, - 0x23, 0x11, 0x23, 0x35, 0x33, 0x35, 0x33, 0x15, 0x21, 0x15, 0x21, 0x11, - 0x3e, 0x01, 0x33, 0x32, 0x16, 0x04, 0x1b, 0xb9, 0x6a, 0x71, 0x81, 0x8b, - 0xb8, 0x7d, 0x7d, 0xb8, 0x01, 0x61, 0xfe, 0x9f, 0x31, 0xa8, 0x73, 0xab, - 0xa9, 0x02, 0xb6, 0xfd, 0x4a, 0x02, 0xb6, 0x97, 0x8e, 0xb7, 0xab, 0xfd, - 0x87, 0x04, 0xf6, 0xa4, 0x7a, 0x7a, 0xa4, 0xfe, 0xc2, 0x60, 0x63, 0xe1, - 0xff, 0xff, 0x00, 0xc9, 0x00, 0x00, 0x04, 0x06, 0x07, 0x5e, 0x10, 0x27, - 0x0c, 0xc0, 0x00, 0x00, 0x01, 0x75, 0x11, 0x06, 0x00, 0x2c, 0x00, 0x00, - 0x00, 0x18, 0xb4, 0x1f, 0x18, 0x09, 0x1e, 0x07, 0x2b, 0x40, 0x0d, 0x4f, - 0x18, 0x40, 0x09, 0x3f, 0x18, 0x30, 0x09, 0x2f, 0x18, 0x20, 0x09, 0x06, - 0x5d, 0x31, 0x00, 0x00, 0xff, 0xff, 0x00, 0xb2, 0x00, 0x00, 0x04, 0x44, - 0x06, 0x37, 0x10, 0x26, 0x02, 0x79, 0x00, 0x00, 0x10, 0x06, 0x00, 0xf3, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc9, 0x00, 0x00, 0x04, 0x06, - 0x07, 0x30, 0x10, 0x26, 0x0c, 0xcb, 0x00, 0x00, 0x11, 0x06, 0x00, 0x2c, - 0x00, 0x00, 0x00, 0x10, 0xb4, 0x05, 0x02, 0x03, 0x04, 0x07, 0x2b, 0x40, - 0x05, 0x4f, 0x02, 0x40, 0x03, 0x02, 0x5d, 0x31, 0xff, 0xff, 0x00, 0xb2, - 0x00, 0x00, 0x04, 0x44, 0x05, 0xf6, 0x10, 0x26, 0x02, 0x8c, 0x00, 0x00, - 0x10, 0x06, 0x00, 0xf3, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc9, - 0x00, 0x00, 0x04, 0x06, 0x07, 0x6d, 0x10, 0x26, 0x0c, 0xc6, 0x00, 0x00, - 0x11, 0x06, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x10, 0xb4, 0x0f, 0x08, 0x00, - 0x0e, 0x07, 0x2b, 0x40, 0x05, 0x4f, 0x08, 0x40, 0x00, 0x02, 0x5d, 0x31, - 0xff, 0xff, 0x00, 0xb2, 0x00, 0x00, 0x04, 0x44, 0x06, 0x48, 0x10, 0x26, - 0x02, 0x8e, 0x00, 0x00, 0x10, 0x06, 0x00, 0xf3, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc9, 0xfe, 0x75, 0x04, 0x06, 0x05, 0xd5, 0x10, 0x26, - 0x00, 0x2c, 0x00, 0x00, 0x10, 0x06, 0x02, 0x78, 0x46, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xb2, 0xfe, 0x75, 0x04, 0x44, 0x06, 0x14, 0x10, 0x26, - 0x00, 0x4c, 0x00, 0x00, 0x10, 0x06, 0x02, 0x78, 0x50, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc9, 0x00, 0x00, 0x04, 0x06, 0x07, 0x50, 0x10, 0x26, - 0x0c, 0xc7, 0x00, 0x00, 0x10, 0x06, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xb2, 0x00, 0x00, 0x04, 0x44, 0x04, 0x60, 0x00, 0x09, - 0x00, 0x22, 0x40, 0x12, 0x08, 0xb6, 0x00, 0xc2, 0x06, 0x02, 0xb6, 0x04, - 0x03, 0x4c, 0x01, 0x06, 0x05, 0x4c, 0x00, 0x4b, 0x07, 0x0a, 0x10, 0xd4, - 0xe4, 0xec, 0xfc, 0xec, 0x31, 0x00, 0x2f, 0xec, 0x32, 0xf4, 0xec, 0x30, - 0x01, 0x21, 0x11, 0x21, 0x15, 0x21, 0x35, 0x21, 0x11, 0x21, 0x01, 0x00, - 0x01, 0xd7, 0x01, 0x6d, 0xfc, 0x6e, 0x01, 0x6d, 0xfe, 0xe1, 0x04, 0x60, - 0xfc, 0x2f, 0x8f, 0x8f, 0x03, 0x42, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff, - 0xff, 0xe6, 0x04, 0xcc, 0x05, 0xd8, 0x00, 0x14, 0x00, 0x20, 0x00, 0x3d, - 0x40, 0x1f, 0x01, 0x00, 0xb2, 0x04, 0x97, 0x11, 0x99, 0x21, 0x0a, 0x18, - 0x20, 0x97, 0x0b, 0x15, 0x88, 0x19, 0x1d, 0x97, 0x1b, 0x01, 0x0b, 0x09, - 0x0c, 0x22, 0x1a, 0x16, 0x18, 0x1d, 0x15, 0x1f, 0x21, 0x10, 0xd4, 0xcc, - 0x32, 0xdc, 0xcc, 0x32, 0x10, 0xd4, 0xcc, 0xc4, 0xc4, 0x31, 0x00, 0x2f, - 0xec, 0x32, 0xf4, 0x3c, 0xec, 0x32, 0x32, 0x10, 0xf4, 0xec, 0xf4, 0xcc, - 0x30, 0x25, 0x35, 0x1e, 0x01, 0x33, 0x32, 0x37, 0x36, 0x35, 0x11, 0x21, - 0x35, 0x21, 0x11, 0x10, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x01, 0x21, - 0x15, 0x23, 0x11, 0x33, 0x15, 0x21, 0x35, 0x33, 0x11, 0x23, 0x02, 0x8c, - 0x3d, 0x84, 0x47, 0x61, 0x27, 0x26, 0xfe, 0xfd, 0x01, 0x8d, 0x48, 0x48, - 0xa8, 0x41, 0x41, 0x40, 0xfd, 0x2d, 0x02, 0x5d, 0xe4, 0xe4, 0xfd, 0xa3, - 0xe4, 0xe4, 0x40, 0xec, 0x51, 0x51, 0x4a, 0x4b, 0xcb, 0x03, 0x44, 0xaa, - 0xfc, 0x12, 0xfe, 0xe6, 0x75, 0x75, 0x16, 0x16, 0x05, 0xc3, 0xaa, 0xfb, - 0x7f, 0xaa, 0xaa, 0x04, 0x81, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0xfb, - 0xfe, 0x4b, 0x04, 0x8a, 0x06, 0x14, 0x00, 0x0d, 0x00, 0x11, 0x00, 0x1b, - 0x00, 0x1f, 0x00, 0x49, 0x40, 0x26, 0x0a, 0x8c, 0x09, 0xc3, 0x20, 0x02, - 0x1b, 0xb6, 0x12, 0x11, 0x1f, 0xc4, 0x0e, 0x1c, 0x9b, 0x03, 0x12, 0xc2, - 0x14, 0x18, 0xb6, 0x17, 0x0a, 0x03, 0x0e, 0x01, 0x06, 0x0f, 0x04, 0x21, - 0x15, 0x1d, 0x13, 0x18, 0x12, 0x1c, 0x1a, 0x20, 0x10, 0xd4, 0x3c, 0xc4, - 0xcc, 0xdc, 0x3c, 0xcc, 0x10, 0xdc, 0x3c, 0xfc, 0x3c, 0xc4, 0xc4, 0x31, - 0x00, 0x2f, 0xec, 0x32, 0xe4, 0x32, 0xfc, 0x3c, 0xec, 0x32, 0x10, 0xee, - 0x32, 0x10, 0xf4, 0xec, 0x30, 0x05, 0x11, 0x21, 0x35, 0x21, 0x11, 0x14, - 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x36, 0x11, 0x33, 0x15, 0x23, 0x05, - 0x21, 0x11, 0x21, 0x15, 0x21, 0x35, 0x21, 0x11, 0x23, 0x13, 0x33, 0x15, - 0x23, 0x03, 0xd2, 0xfe, 0xc3, 0x01, 0xf5, 0xb3, 0xa5, 0xfe, 0xea, 0x5a, - 0x5a, 0xb8, 0xb8, 0xfc, 0x69, 0x01, 0x82, 0x01, 0x2c, 0xfd, 0x12, 0x01, - 0x2b, 0xeb, 0xeb, 0x97, 0x97, 0x1f, 0x03, 0xe5, 0x8f, 0xfb, 0x8c, 0xc3, - 0xd3, 0x9c, 0x7d, 0x06, 0xa5, 0xe9, 0xc0, 0xfc, 0x2f, 0x8f, 0x8f, 0x03, - 0x42, 0x02, 0x43, 0xe9, 0xff, 0xff, 0x00, 0x6d, 0xff, 0xe3, 0x03, 0xca, - 0x07, 0x6d, 0x10, 0x27, 0x0c, 0xc2, 0x00, 0x30, 0x01, 0x75, 0x10, 0x06, - 0x00, 0x2d, 0x00, 0x00, 0xff, 0xff, 0x00, 0xba, 0xfe, 0x56, 0x03, 0xa8, - 0x06, 0x66, 0x10, 0x26, 0x02, 0x67, 0x00, 0x00, 0x10, 0x06, 0x01, 0xe6, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0xfd, 0xe0, 0x04, 0xc9, - 0x05, 0xd5, 0x10, 0x26, 0x02, 0xae, 0x6a, 0xfe, 0x10, 0x06, 0x00, 0x2e, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xec, 0xfd, 0xe0, 0x04, 0xb2, - 0x06, 0x14, 0x10, 0x27, 0x02, 0xae, 0x00, 0x90, 0xff, 0xfe, 0x10, 0x06, - 0x00, 0x4e, 0x00, 0x00, 0x00, 0x01, 0x00, 0xec, 0x00, 0x00, 0x04, 0xb2, - 0x04, 0x60, 0x00, 0x0b, 0x00, 0xc4, 0x40, 0x39, 0x08, 0x17, 0x09, 0x08, - 0x05, 0x06, 0x05, 0x07, 0x17, 0x06, 0x06, 0x05, 0x09, 0x17, 0x03, 0x02, - 0x08, 0x17, 0x07, 0x08, 0x03, 0x02, 0x05, 0x17, 0x06, 0x05, 0x02, 0x03, - 0x02, 0x04, 0x17, 0x03, 0x03, 0x02, 0x42, 0x08, 0x05, 0x02, 0x03, 0x03, - 0x00, 0xc2, 0x0a, 0x06, 0x08, 0x05, 0x04, 0x03, 0x06, 0x09, 0x01, 0x06, - 0x06, 0x44, 0x00, 0x45, 0x0c, 0x10, 0xf4, 0xec, 0xec, 0x32, 0x11, 0x17, - 0x39, 0x31, 0x00, 0x2f, 0x3c, 0xec, 0x32, 0x17, 0x39, 0x30, 0x4b, 0x53, - 0x58, 0x07, 0x10, 0x05, 0xed, 0x07, 0x10, 0x08, 0xed, 0x07, 0x08, 0xed, - 0x07, 0x04, 0xed, 0x07, 0x10, 0x05, 0xed, 0x07, 0x10, 0x08, 0xed, 0x59, - 0x22, 0xb2, 0x08, 0x07, 0x01, 0x01, 0x5d, 0x40, 0x52, 0x06, 0x02, 0x08, - 0x08, 0x16, 0x02, 0x18, 0x05, 0x18, 0x08, 0x35, 0x02, 0x34, 0x05, 0x36, - 0x08, 0x46, 0x02, 0x66, 0x02, 0x75, 0x02, 0x76, 0x05, 0x0c, 0x09, 0x03, - 0x08, 0x08, 0x19, 0x03, 0x17, 0x04, 0x18, 0x05, 0x19, 0x06, 0x1a, 0x07, - 0x18, 0x08, 0x28, 0x03, 0x27, 0x05, 0x28, 0x07, 0x3b, 0x03, 0x3b, 0x04, - 0x37, 0x05, 0x39, 0x07, 0x37, 0x08, 0x4a, 0x03, 0x49, 0x07, 0x59, 0x06, - 0x59, 0x07, 0x6b, 0x03, 0x69, 0x04, 0x69, 0x06, 0x69, 0x07, 0x79, 0x03, - 0x78, 0x05, 0x79, 0x06, 0x79, 0x07, 0x1c, 0x5d, 0x00, 0x5d, 0x13, 0x33, - 0x11, 0x01, 0x33, 0x09, 0x01, 0x23, 0x01, 0x07, 0x11, 0x23, 0xec, 0xbe, - 0x01, 0xe3, 0xe0, 0xfe, 0x47, 0x01, 0xfe, 0xe1, 0xfe, 0x62, 0x89, 0xbe, - 0x04, 0x60, 0xfe, 0x2f, 0x01, 0xd1, 0xfe, 0x5a, 0xfd, 0x46, 0x02, 0x42, - 0x81, 0xfe, 0x3f, 0x00, 0xff, 0xff, 0x00, 0xc8, 0x00, 0x00, 0x04, 0x73, - 0x07, 0x6c, 0x10, 0x27, 0x0c, 0xbf, 0xfe, 0xed, 0x01, 0x76, 0x11, 0x06, - 0x00, 0x2f, 0x00, 0x00, 0x00, 0x07, 0x40, 0x03, 0x20, 0x00, 0x01, 0x5d, - 0x31, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa0, 0x00, 0x00, 0x04, 0x0a, - 0x07, 0x6c, 0x10, 0x27, 0x0c, 0xbf, 0xff, 0xa1, 0x01, 0x76, 0x11, 0x06, - 0x00, 0x4f, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4b, 0xb0, 0x0e, 0x51, 0x58, - 0xb9, 0x00, 0x00, 0x00, 0x40, 0x38, 0x59, 0x40, 0x07, 0x9f, 0x00, 0x8f, - 0x00, 0x4f, 0x00, 0x03, 0x5d, 0x30, 0x00, 0x00, 0xff, 0xff, 0x00, 0xd7, - 0xfd, 0xe0, 0x04, 0x73, 0x05, 0xd5, 0x10, 0x26, 0x02, 0xae, 0x66, 0xfe, - 0x10, 0x06, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa0, - 0xfd, 0xe0, 0x04, 0x0a, 0x06, 0x1f, 0x10, 0x26, 0x02, 0xae, 0xfb, 0xfe, - 0x10, 0x06, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xd7, - 0x00, 0x00, 0x04, 0x73, 0x05, 0xd5, 0x10, 0x27, 0x0c, 0xbd, 0x00, 0xae, - 0xff, 0x6d, 0x10, 0x06, 0x00, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa0, - 0x00, 0x00, 0x04, 0x86, 0x06, 0x1f, 0x10, 0x27, 0x0c, 0xbd, 0x01, 0xa0, - 0xff, 0xb9, 0x10, 0x06, 0x00, 0x4f, 0x00, 0x00, 0xff, 0xff, 0x00, 0xd7, - 0x00, 0x00, 0x04, 0x73, 0x05, 0xd5, 0x10, 0x27, 0x00, 0x79, 0x01, 0x60, - 0x00, 0x86, 0x10, 0x06, 0x00, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa0, - 0x00, 0x00, 0x04, 0xbc, 0x06, 0x1f, 0x10, 0x27, 0x00, 0x79, 0x01, 0xd7, - 0x00, 0x90, 0x10, 0x06, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf6, - 0x00, 0x00, 0x04, 0x73, 0x05, 0xd5, 0x00, 0x0d, 0x00, 0x37, 0x40, 0x1e, - 0x0c, 0x0b, 0x0a, 0x04, 0x03, 0x02, 0x06, 0x00, 0x06, 0x97, 0x00, 0x88, - 0x08, 0x03, 0x04, 0x07, 0x01, 0x0b, 0x0e, 0x00, 0x0c, 0x05, 0x01, 0x1e, - 0x07, 0x31, 0x09, 0x00, 0x34, 0x0e, 0x10, 0xfc, 0x3c, 0xec, 0xec, 0x32, - 0x2e, 0x11, 0x12, 0x39, 0x11, 0x12, 0x39, 0x39, 0x31, 0x00, 0x2f, 0xe4, - 0xec, 0x11, 0x17, 0x39, 0x30, 0x13, 0x33, 0x11, 0x25, 0x17, 0x01, 0x11, - 0x21, 0x15, 0x21, 0x11, 0x07, 0x27, 0x37, 0xd7, 0xcb, 0x01, 0x3b, 0x4e, - 0xfe, 0x77, 0x02, 0xd1, 0xfc, 0x64, 0x91, 0x50, 0xe1, 0x05, 0xd5, 0xfd, - 0x98, 0xdb, 0x6f, 0xfe, 0xee, 0xfd, 0xe3, 0xaa, 0x02, 0x3b, 0x6a, 0x6e, - 0x9e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x4c, 0x00, 0x00, 0x04, 0x0a, - 0x06, 0x1f, 0x00, 0x15, 0x00, 0x3e, 0x40, 0x21, 0x14, 0x13, 0x12, 0x0c, - 0x0b, 0x0a, 0x06, 0x09, 0x00, 0x03, 0x0e, 0xb6, 0x10, 0xc5, 0x03, 0xb6, - 0x05, 0x0b, 0x0c, 0x16, 0x0f, 0x13, 0x03, 0x06, 0x14, 0x04, 0x11, 0x00, - 0x06, 0x0f, 0x0d, 0x09, 0x16, 0x10, 0xd4, 0x3c, 0xcc, 0xfc, 0x3c, 0xcc, - 0x32, 0x39, 0x39, 0x39, 0x11, 0x12, 0x39, 0x39, 0x31, 0x00, 0x2f, 0xec, - 0xfc, 0xec, 0x11, 0x39, 0x39, 0x17, 0x39, 0x30, 0x01, 0x14, 0x16, 0x3b, - 0x01, 0x15, 0x23, 0x22, 0x26, 0x35, 0x11, 0x05, 0x27, 0x01, 0x11, 0x21, - 0x35, 0x21, 0x11, 0x25, 0x17, 0x01, 0x02, 0x7f, 0x5b, 0x59, 0xd7, 0xe9, - 0xa5, 0xb5, 0xfe, 0xd5, 0x50, 0x01, 0x7b, 0xfe, 0xd9, 0x01, 0xdf, 0x01, - 0x3b, 0x50, 0xfe, 0x75, 0x01, 0x96, 0x7c, 0x7e, 0x9c, 0xd4, 0xc2, 0x01, - 0x24, 0xd1, 0x6f, 0x01, 0x08, 0x02, 0x2f, 0x90, 0xfd, 0xbe, 0xdb, 0x6e, - 0xfe, 0xed, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8b, 0x00, 0x00, 0x04, 0x46, - 0x07, 0x6b, 0x10, 0x27, 0x0c, 0xbf, 0x00, 0x21, 0x01, 0x75, 0x10, 0x06, - 0x00, 0x31, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, 0x00, 0x00, 0x04, 0x1b, - 0x06, 0x6d, 0x10, 0x26, 0x00, 0x76, 0x14, 0x07, 0x10, 0x06, 0x00, 0x51, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8b, 0xfd, 0xe0, 0x04, 0x46, - 0x05, 0xd5, 0x10, 0x26, 0x02, 0xae, 0x2a, 0xfe, 0x10, 0x06, 0x00, 0x31, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, 0xfd, 0xe0, 0x04, 0x1b, - 0x04, 0x7b, 0x10, 0x26, 0x02, 0xae, 0x30, 0xfe, 0x10, 0x06, 0x00, 0x51, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8b, 0x00, 0x00, 0x04, 0x46, - 0x07, 0x6d, 0x10, 0x26, 0x00, 0x31, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xc3, - 0x00, 0x2a, 0x01, 0x75, 0xff, 0xff, 0x00, 0xc3, 0x00, 0x00, 0x04, 0x1b, - 0x06, 0x66, 0x10, 0x26, 0x00, 0x51, 0x00, 0x00, 0x10, 0x06, 0x02, 0x68, - 0xf4, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x18, 0x00, 0x00, 0x04, 0x96, - 0x06, 0x14, 0x10, 0x26, 0x00, 0x51, 0x7b, 0x00, 0x10, 0x07, 0x02, 0x61, - 0xfe, 0x49, 0x00, 0x00, 0x00, 0x01, 0x00, 0x93, 0xfe, 0x56, 0x04, 0x3d, - 0x05, 0xf2, 0x00, 0x1d, 0x00, 0x32, 0x40, 0x1c, 0x18, 0x13, 0x0d, 0x00, - 0x04, 0x15, 0x10, 0x97, 0x1b, 0x96, 0x16, 0x88, 0x15, 0x07, 0x97, 0x06, - 0x15, 0x07, 0x0d, 0x1e, 0x00, 0x31, 0x13, 0x17, 0x1e, 0x16, 0x30, 0x1e, - 0x10, 0xf4, 0xec, 0x32, 0xfc, 0xec, 0xc4, 0x31, 0x00, 0x2f, 0xd4, 0xec, - 0x10, 0xe4, 0xf4, 0xec, 0x11, 0x17, 0x39, 0x30, 0x01, 0x11, 0x14, 0x07, - 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x37, 0x36, 0x35, 0x11, 0x34, 0x26, - 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, 0x15, 0x3e, 0x01, 0x33, - 0x32, 0x12, 0x04, 0x3d, 0x59, 0x5a, 0xa5, 0xcd, 0xa7, 0x5a, 0x2d, 0x2c, - 0x74, 0x7c, 0x8d, 0x98, 0xca, 0xca, 0x36, 0xb8, 0x7e, 0xbb, 0xb9, 0x03, - 0xe7, 0xfc, 0x05, 0xc3, 0x69, 0x6a, 0x9c, 0x3e, 0x3e, 0x92, 0x03, 0xf1, - 0xb4, 0xa9, 0xda, 0xcb, 0xfc, 0x57, 0x05, 0xd5, 0xc6, 0x6f, 0x74, 0xfe, - 0xfb, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc3, 0xfe, 0x56, 0x04, 0x1b, - 0x04, 0x7b, 0x00, 0x20, 0x00, 0x32, 0x40, 0x1c, 0x19, 0x14, 0x0d, 0x00, - 0x04, 0x16, 0x10, 0x8c, 0x1d, 0xbe, 0x17, 0xc2, 0x16, 0x06, 0xb6, 0x07, - 0x16, 0x07, 0x0d, 0x06, 0x00, 0x4a, 0x14, 0x18, 0x06, 0x17, 0x46, 0x21, - 0x10, 0xf4, 0xec, 0x32, 0xfc, 0xec, 0xc4, 0x31, 0x00, 0x2f, 0xd4, 0xec, - 0x10, 0xe4, 0xf4, 0xec, 0x11, 0x17, 0x39, 0x30, 0x01, 0x11, 0x14, 0x07, - 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x37, 0x36, 0x35, 0x11, 0x34, 0x26, - 0x23, 0x22, 0x07, 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, 0x15, 0x36, 0x37, - 0x36, 0x33, 0x32, 0x17, 0x16, 0x04, 0x1b, 0x59, 0x5a, 0xa5, 0xcd, 0xb9, - 0x5a, 0x2d, 0x2c, 0x6a, 0x71, 0x81, 0x46, 0x45, 0xb8, 0xb8, 0x31, 0x54, - 0x54, 0x73, 0xab, 0x54, 0x55, 0x02, 0xb6, 0xfd, 0x36, 0xc3, 0x69, 0x6a, - 0x9c, 0x3e, 0x3e, 0x7e, 0x02, 0xca, 0x97, 0x8e, 0x5b, 0x5c, 0xab, 0xfd, - 0x87, 0x04, 0x60, 0xa8, 0x60, 0x32, 0x31, 0x71, 0x70, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x75, 0xff, 0xe3, 0x04, 0x5c, 0x07, 0x30, 0x10, 0x26, - 0x0c, 0xcb, 0x00, 0x00, 0x11, 0x06, 0x00, 0x32, 0x00, 0x00, 0x00, 0x14, - 0xb4, 0x10, 0x02, 0x03, 0x16, 0x07, 0x2b, 0x40, 0x09, 0x4f, 0x02, 0x40, - 0x03, 0x2f, 0x02, 0x20, 0x03, 0x04, 0x5d, 0x31, 0xff, 0xff, 0x00, 0x89, - 0xff, 0xe3, 0x04, 0x48, 0x05, 0xf6, 0x10, 0x26, 0x02, 0x8c, 0x00, 0x00, - 0x11, 0x06, 0x00, 0x52, 0x00, 0x00, 0x00, 0x08, 0xb4, 0x13, 0x02, 0x03, - 0x19, 0x07, 0x2b, 0x31, 0xff, 0xff, 0x00, 0x75, 0xff, 0xe3, 0x04, 0x5c, - 0x07, 0x6d, 0x10, 0x26, 0x0c, 0xc6, 0x00, 0x00, 0x11, 0x06, 0x00, 0x32, - 0x00, 0x00, 0x00, 0x10, 0xb4, 0x1a, 0x08, 0x00, 0x20, 0x07, 0x2b, 0x40, - 0x05, 0x2f, 0x08, 0x20, 0x00, 0x02, 0x5d, 0x31, 0xff, 0xff, 0x00, 0x89, - 0xff, 0xe3, 0x04, 0x48, 0x06, 0x48, 0x10, 0x26, 0x02, 0x8e, 0x00, 0x00, - 0x11, 0x06, 0x00, 0x52, 0x00, 0x00, 0x00, 0x10, 0xb4, 0x1d, 0x08, 0x00, - 0x23, 0x07, 0x2b, 0x40, 0x05, 0x0f, 0x08, 0x00, 0x00, 0x02, 0x5d, 0x31, - 0xff, 0xff, 0x00, 0x75, 0xff, 0xe3, 0x04, 0x5c, 0x07, 0x6b, 0x10, 0x26, - 0x0c, 0xc8, 0x00, 0x00, 0x10, 0x06, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, 0x06, 0x66, 0x10, 0x26, - 0x02, 0x93, 0x00, 0x00, 0x10, 0x06, 0x00, 0x52, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x48, 0x00, 0x00, 0x04, 0xc1, 0x05, 0xd5, 0x00, 0x10, - 0x00, 0x19, 0x00, 0x3b, 0x40, 0x1f, 0x0e, 0x97, 0x0c, 0x11, 0x0a, 0x97, - 0x08, 0x88, 0x17, 0x00, 0x97, 0x0c, 0xb1, 0x01, 0x17, 0x11, 0x08, 0x02, - 0x14, 0x0f, 0x0b, 0x1e, 0x18, 0x09, 0x0d, 0x00, 0x2d, 0x14, 0x1e, 0x05, - 0x1a, 0x10, 0xdc, 0xec, 0xfc, 0xc4, 0xc4, 0xd4, 0xec, 0x32, 0x12, 0x39, - 0x39, 0x39, 0x39, 0x31, 0x00, 0x2f, 0xec, 0xec, 0x32, 0xf4, 0xec, 0x32, - 0x10, 0xee, 0x30, 0x25, 0x15, 0x21, 0x20, 0x02, 0x11, 0x10, 0x12, 0x29, - 0x01, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x11, 0x01, 0x22, 0x06, 0x11, - 0x10, 0x16, 0x3b, 0x01, 0x11, 0x04, 0xc1, 0xfd, 0xa3, 0xfe, 0xd9, 0xf5, - 0xf4, 0x01, 0x28, 0x02, 0x52, 0xfe, 0x9a, 0x01, 0x48, 0xfe, 0xb8, 0xfe, - 0xfe, 0xb1, 0x8b, 0x8b, 0xb1, 0x3d, 0xaa, 0xaa, 0x01, 0x4d, 0x01, 0x9c, - 0x01, 0xa1, 0x01, 0x4b, 0xaa, 0xfe, 0x46, 0xaa, 0xfd, 0xe3, 0x04, 0x81, - 0xe6, 0xfe, 0xa4, 0xfe, 0xa6, 0xe5, 0x04, 0x81, 0x00, 0x03, 0x00, 0x0e, - 0xff, 0xe3, 0x04, 0xba, 0x04, 0x7b, 0x00, 0x0a, 0x00, 0x16, 0x00, 0x38, - 0x00, 0x69, 0x40, 0x39, 0x32, 0x2f, 0x09, 0x06, 0x00, 0x19, 0x1f, 0x17, - 0x26, 0x20, 0x0b, 0x38, 0x17, 0x00, 0x20, 0x8b, 0x1f, 0x8d, 0x0b, 0x00, - 0xb6, 0x17, 0x1c, 0x0b, 0x8c, 0x23, 0x17, 0xc1, 0x11, 0x06, 0x8c, 0x35, - 0x2f, 0xbe, 0x29, 0x23, 0x99, 0x39, 0x00, 0x03, 0x32, 0x26, 0x18, 0x09, - 0x4d, 0x0e, 0x75, 0x1f, 0x03, 0x4d, 0x17, 0x43, 0x14, 0x4d, 0x2c, 0x73, - 0x39, 0x10, 0xf4, 0xec, 0xfc, 0xec, 0xc4, 0xfc, 0xec, 0x32, 0x39, 0x39, - 0x11, 0x39, 0x31, 0x00, 0x10, 0xe4, 0x32, 0xf4, 0x3c, 0xec, 0x32, 0xe4, - 0x10, 0xee, 0x32, 0x10, 0xee, 0x10, 0xf4, 0xee, 0x11, 0x12, 0x39, 0x11, - 0x12, 0x39, 0x11, 0x12, 0x39, 0x11, 0x12, 0x39, 0x11, 0x39, 0x30, 0x01, - 0x34, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x1d, 0x01, 0x01, 0x32, - 0x36, 0x35, 0x10, 0x26, 0x23, 0x22, 0x06, 0x11, 0x10, 0x16, 0x01, 0x21, - 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x15, 0x0e, 0x01, 0x23, 0x22, - 0x26, 0x27, 0x0e, 0x01, 0x23, 0x22, 0x02, 0x11, 0x10, 0x12, 0x33, 0x32, - 0x16, 0x17, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x11, 0x04, 0x17, 0x02, 0x50, - 0x56, 0x57, 0x4d, 0xfe, 0xa6, 0x66, 0x52, 0x50, 0x68, 0x67, 0x50, 0x50, - 0x03, 0xac, 0xfe, 0x15, 0x63, 0x70, 0x50, 0x83, 0x2f, 0x3b, 0x7d, 0x4a, - 0x62, 0x93, 0x30, 0x34, 0x80, 0x54, 0xbd, 0xaa, 0xaa, 0xbd, 0x59, 0x80, - 0x2f, 0x25, 0x82, 0x57, 0xaf, 0x90, 0x02, 0x91, 0x0b, 0x26, 0x09, 0x91, - 0x87, 0x89, 0x9e, 0x2b, 0xfd, 0xea, 0xa8, 0xef, 0x01, 0x23, 0xae, 0xa7, - 0xfe, 0xf3, 0xfe, 0xf3, 0xa7, 0x01, 0x87, 0x54, 0xa3, 0x90, 0x35, 0x33, - 0xac, 0x2b, 0x29, 0x43, 0x42, 0x44, 0x41, 0x01, 0x14, 0x01, 0x38, 0x01, - 0x38, 0x01, 0x14, 0x3e, 0x41, 0x3e, 0x41, 0xed, 0xfe, 0xce, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x8f, 0x00, 0x00, 0x04, 0xd1, 0x07, 0x6b, 0x10, 0x27, - 0x0c, 0xbf, 0xff, 0xb5, 0x01, 0x75, 0x10, 0x06, 0x00, 0x35, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x6a, 0x00, 0x00, 0x04, 0x88, 0x06, 0x6d, 0x10, 0x27, - 0x00, 0x76, 0x00, 0xce, 0x00, 0x07, 0x10, 0x06, 0x00, 0x55, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x8f, 0xfd, 0xe0, 0x04, 0xd1, 0x05, 0xd5, 0x10, 0x26, - 0x02, 0xae, 0x72, 0xfe, 0x10, 0x06, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x20, 0xfd, 0xe0, 0x04, 0x83, 0x04, 0x7b, 0x10, 0x26, - 0x02, 0xae, 0x88, 0xfe, 0x10, 0x06, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x8f, 0x00, 0x00, 0x04, 0xd1, 0x07, 0x67, 0x10, 0x26, - 0x00, 0x35, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xc3, 0xff, 0xc4, 0x01, 0x6f, - 0xff, 0xff, 0x01, 0x6a, 0x00, 0x00, 0x04, 0x83, 0x06, 0x66, 0x10, 0x26, - 0x00, 0x55, 0x00, 0x00, 0x10, 0x06, 0x02, 0x68, 0x5a, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x8b, 0xff, 0xe3, 0x04, 0x4a, 0x07, 0x6b, 0x10, 0x27, - 0x0c, 0xbf, 0x00, 0x19, 0x01, 0x75, 0x10, 0x06, 0x00, 0x36, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xd5, 0xff, 0xe3, 0x04, 0x06, 0x06, 0x6d, 0x10, 0x26, - 0x00, 0x76, 0x1a, 0x07, 0x10, 0x06, 0x00, 0x56, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x8b, 0xff, 0xe3, 0x04, 0x4a, 0x07, 0x6d, 0x10, 0x27, - 0x0c, 0xc2, 0x00, 0x00, 0x01, 0x75, 0x10, 0x06, 0x00, 0x36, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xd5, 0xff, 0xe3, 0x04, 0x06, 0x06, 0x66, 0x10, 0x26, - 0x02, 0x67, 0x00, 0x00, 0x10, 0x06, 0x00, 0x56, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x8b, 0xfe, 0x75, 0x04, 0x4a, 0x05, 0xf0, 0x10, 0x26, - 0x02, 0xaf, 0x00, 0x00, 0x10, 0x06, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xd5, 0xfe, 0x75, 0x04, 0x06, 0x04, 0x7b, 0x10, 0x26, - 0x02, 0xaf, 0x00, 0x00, 0x10, 0x06, 0x00, 0x56, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x8b, 0xff, 0xe3, 0x04, 0x4a, 0x07, 0x6d, 0x10, 0x26, - 0x00, 0x36, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xc3, 0x00, 0x00, 0x01, 0x75, - 0xff, 0xff, 0x00, 0xd5, 0xff, 0xe3, 0x04, 0x06, 0x06, 0x66, 0x10, 0x26, - 0x00, 0x56, 0x00, 0x00, 0x10, 0x06, 0x02, 0x68, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x2f, 0xfe, 0x75, 0x04, 0xa2, 0x05, 0xd5, 0x10, 0x26, - 0x02, 0xaf, 0x00, 0x00, 0x10, 0x06, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x83, 0xfe, 0x75, 0x04, 0x08, 0x05, 0x9e, 0x10, 0x26, - 0x02, 0xaf, 0x79, 0x00, 0x10, 0x06, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x2f, 0x00, 0x00, 0x04, 0xa2, 0x07, 0x6d, 0x10, 0x26, - 0x00, 0x37, 0x00, 0x00, 0x11, 0x07, 0x0c, 0xc3, 0x00, 0x06, 0x01, 0x75, - 0x00, 0x08, 0xb4, 0x01, 0x0d, 0x09, 0x00, 0x07, 0x2b, 0x31, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x83, 0x00, 0x00, 0x04, 0x08, 0x06, 0x7e, 0x10, 0x26, - 0x00, 0x57, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xbd, 0x01, 0x14, 0x00, 0x18, - 0x00, 0x01, 0x00, 0x2f, 0x00, 0x00, 0x04, 0xa2, 0x05, 0xd5, 0x00, 0x0f, - 0x00, 0x2d, 0x40, 0x17, 0x04, 0x0c, 0x97, 0x07, 0x0b, 0x03, 0x0f, 0x97, - 0x00, 0x88, 0x08, 0x01, 0x3a, 0x05, 0x07, 0x03, 0x1e, 0x0c, 0x00, 0x3a, - 0x0a, 0x0e, 0x10, 0x10, 0xd4, 0x3c, 0xec, 0xcc, 0xfc, 0x3c, 0xcc, 0xec, - 0x31, 0x00, 0x2f, 0xf4, 0xec, 0x32, 0xd4, 0x3c, 0xec, 0x32, 0x30, 0x13, - 0x21, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x11, 0x23, 0x11, 0x21, 0x35, - 0x21, 0x11, 0x21, 0x2f, 0x04, 0x73, 0xfe, 0x2d, 0x01, 0x09, 0xfe, 0xf7, - 0xcb, 0xfe, 0xf7, 0x01, 0x09, 0xfe, 0x2b, 0x05, 0xd5, 0xaa, 0xfd, 0xc0, - 0xaa, 0xfd, 0xbf, 0x02, 0x41, 0xaa, 0x02, 0x40, 0x00, 0x01, 0x00, 0x83, - 0x00, 0x00, 0x04, 0x08, 0x05, 0x9e, 0x00, 0x1b, 0x00, 0x42, 0x40, 0x21, - 0x12, 0x09, 0x0c, 0x05, 0x15, 0xb6, 0x08, 0x14, 0x04, 0x18, 0xb6, 0x1b, - 0x01, 0x19, 0xc2, 0x0c, 0xb6, 0x0f, 0x0c, 0x0f, 0x0d, 0x02, 0x06, 0x08, - 0x04, 0x00, 0x06, 0x15, 0x19, 0x13, 0x17, 0x1b, 0x1c, 0x10, 0xd4, 0x3c, - 0x3c, 0xc4, 0xc4, 0xfc, 0x3c, 0x3c, 0xc4, 0xc4, 0x32, 0x39, 0x39, 0x31, - 0x00, 0x2f, 0xec, 0xf4, 0x3c, 0xc4, 0xec, 0x32, 0xd4, 0x3c, 0xec, 0x32, - 0x11, 0x39, 0x39, 0x30, 0x01, 0x11, 0x21, 0x15, 0x21, 0x15, 0x33, 0x15, - 0x23, 0x15, 0x14, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x26, 0x3d, 0x01, - 0x23, 0x35, 0x33, 0x35, 0x21, 0x35, 0x21, 0x11, 0x02, 0x66, 0x01, 0xa2, - 0xfe, 0x5e, 0xe5, 0xe5, 0x5e, 0x75, 0xcf, 0xe1, 0xcf, 0xaa, 0xe5, 0xe5, - 0xfe, 0xd5, 0x01, 0x2b, 0x05, 0x9e, 0xfe, 0xc2, 0x8f, 0xe9, 0x8e, 0xe9, - 0x7c, 0x62, 0x93, 0xa6, 0xcb, 0xe9, 0x8e, 0xe9, 0x8f, 0x01, 0x3e, 0x00, - 0xff, 0xff, 0x00, 0x93, 0xff, 0xe3, 0x04, 0x3d, 0x07, 0x5e, 0x10, 0x27, - 0x0c, 0xc0, 0x00, 0x00, 0x01, 0x75, 0x11, 0x06, 0x00, 0x38, 0x00, 0x00, - 0x00, 0x10, 0xb4, 0x2f, 0x18, 0x09, 0x1f, 0x07, 0x2b, 0x40, 0x05, 0x4f, - 0x18, 0x40, 0x09, 0x02, 0x5d, 0x31, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, - 0xff, 0xe3, 0x04, 0x1b, 0x06, 0x37, 0x10, 0x26, 0x02, 0x79, 0x00, 0x00, - 0x11, 0x06, 0x00, 0x58, 0x00, 0x00, 0x00, 0x10, 0xb4, 0x27, 0x16, 0x08, - 0x1d, 0x07, 0x2b, 0x40, 0x05, 0x2f, 0x16, 0x20, 0x08, 0x02, 0x5d, 0x31, - 0xff, 0xff, 0x00, 0x93, 0xff, 0xe3, 0x04, 0x3d, 0x07, 0x30, 0x10, 0x26, - 0x0c, 0xcb, 0x00, 0x00, 0x11, 0x06, 0x00, 0x38, 0x00, 0x00, 0x00, 0x14, - 0xb4, 0x15, 0x02, 0x03, 0x05, 0x07, 0x2b, 0x40, 0x09, 0x4f, 0x02, 0x40, - 0x03, 0x2f, 0x02, 0x20, 0x03, 0x04, 0x5d, 0x31, 0xff, 0xff, 0x00, 0xc3, - 0xff, 0xe3, 0x04, 0x1b, 0x05, 0xf6, 0x10, 0x26, 0x02, 0x8c, 0x00, 0x00, - 0x11, 0x06, 0x00, 0x58, 0x00, 0x00, 0x00, 0x08, 0xb4, 0x0f, 0x01, 0x00, - 0x05, 0x07, 0x2b, 0x31, 0xff, 0xff, 0x00, 0x93, 0xff, 0xe3, 0x04, 0x3d, - 0x07, 0x6d, 0x10, 0x26, 0x0c, 0xc6, 0x00, 0x00, 0x11, 0x06, 0x00, 0x38, - 0x00, 0x00, 0x00, 0x10, 0xb4, 0x1f, 0x08, 0x00, 0x0f, 0x07, 0x2b, 0x40, - 0x05, 0x2f, 0x08, 0x20, 0x00, 0x02, 0x5d, 0x31, 0xff, 0xff, 0x00, 0xc3, - 0xff, 0xe3, 0x04, 0x1b, 0x06, 0x48, 0x10, 0x26, 0x02, 0x8e, 0x00, 0x00, - 0x11, 0x06, 0x00, 0x58, 0x00, 0x00, 0x00, 0x10, 0xb4, 0x19, 0x08, 0x00, - 0x0f, 0x07, 0x2b, 0x40, 0x05, 0x0f, 0x08, 0x00, 0x00, 0x02, 0x5d, 0x31, - 0xff, 0xff, 0x00, 0x93, 0xff, 0xe3, 0x04, 0x3d, 0x08, 0x55, 0x10, 0x26, - 0x00, 0x38, 0x00, 0x00, 0x10, 0x07, 0x02, 0x77, 0x00, 0x0a, 0x01, 0x4f, - 0xff, 0xff, 0x00, 0xc3, 0xff, 0xe3, 0x04, 0x1b, 0x06, 0xd9, 0x10, 0x26, - 0x00, 0x58, 0x00, 0x00, 0x10, 0x06, 0x02, 0x77, 0x0f, 0xd3, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x93, 0xff, 0xe3, 0x04, 0x3d, 0x07, 0x6b, 0x10, 0x26, - 0x0c, 0xc8, 0x00, 0x00, 0x10, 0x06, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xff, 0xe3, 0x04, 0x1b, 0x06, 0x66, 0x10, 0x26, - 0x02, 0x93, 0x00, 0x00, 0x10, 0x06, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x93, 0xfe, 0x65, 0x04, 0x3d, 0x05, 0xd5, 0x10, 0x26, - 0x00, 0x38, 0x00, 0x00, 0x10, 0x06, 0x02, 0x78, 0x1c, 0xf0, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x75, 0x04, 0xb0, 0x04, 0x5e, 0x10, 0x26, - 0x00, 0x58, 0x00, 0x00, 0x10, 0x07, 0x02, 0x78, 0x01, 0x97, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd1, 0x07, 0x74, 0x10, 0x27, - 0x0c, 0xc2, 0x00, 0x00, 0x01, 0x7c, 0x11, 0x06, 0x00, 0x3a, 0x00, 0x00, - 0x00, 0x08, 0xb4, 0x0e, 0x02, 0x06, 0x07, 0x07, 0x2b, 0x31, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd1, 0x06, 0x6d, 0x10, 0x26, - 0x02, 0x67, 0x00, 0x07, 0x11, 0x06, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x08, - 0xb4, 0x0e, 0x02, 0x06, 0x07, 0x07, 0x2b, 0x31, 0xff, 0xff, 0x00, 0x25, - 0x00, 0x00, 0x04, 0xac, 0x07, 0x74, 0x10, 0x27, 0x0c, 0xc2, 0x00, 0x00, - 0x01, 0x7c, 0x11, 0x06, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x08, 0xb4, 0x0b, - 0x02, 0x06, 0x07, 0x07, 0x2b, 0x31, 0x00, 0x00, 0xff, 0xff, 0x00, 0x68, - 0xfe, 0x56, 0x04, 0x81, 0x06, 0x6d, 0x10, 0x26, 0x02, 0x67, 0x0c, 0x07, - 0x10, 0x06, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, - 0x00, 0x00, 0x04, 0xac, 0x07, 0x4e, 0x10, 0x26, 0x00, 0x3c, 0x00, 0x00, - 0x11, 0x07, 0x0c, 0xbe, 0x00, 0x00, 0x01, 0x75, 0x00, 0x08, 0xb4, 0x04, - 0x0f, 0x0c, 0x00, 0x07, 0x2b, 0x31, 0x00, 0x00, 0xff, 0xff, 0x00, 0x9c, - 0x00, 0x00, 0x04, 0x91, 0x07, 0x6b, 0x10, 0x27, 0x0c, 0xbf, 0x00, 0x1b, - 0x01, 0x75, 0x10, 0x06, 0x00, 0x3d, 0x00, 0x00, 0xff, 0xff, 0x00, 0xcb, - 0x00, 0x00, 0x04, 0x10, 0x06, 0x6d, 0x10, 0x26, 0x00, 0x76, 0x56, 0x07, - 0x10, 0x06, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x9c, - 0x00, 0x00, 0x04, 0x91, 0x07, 0x50, 0x10, 0x26, 0x0c, 0xc7, 0x32, 0x00, - 0x10, 0x06, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xcb, - 0x00, 0x00, 0x04, 0x10, 0x06, 0x10, 0x10, 0x26, 0x02, 0x8f, 0x00, 0x00, - 0x10, 0x06, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x9c, - 0x00, 0x00, 0x04, 0x91, 0x07, 0x6d, 0x10, 0x26, 0x00, 0x3d, 0x00, 0x00, - 0x10, 0x07, 0x0c, 0xc3, 0x00, 0x00, 0x01, 0x75, 0xff, 0xff, 0x00, 0xcb, - 0x00, 0x00, 0x04, 0x10, 0x06, 0x66, 0x10, 0x26, 0x00, 0x5d, 0x00, 0x00, - 0x10, 0x06, 0x02, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc3, - 0x00, 0x00, 0x04, 0x27, 0x06, 0x14, 0x00, 0x0f, 0x00, 0x2c, 0x40, 0x16, - 0x00, 0x07, 0x0c, 0x04, 0xb6, 0x05, 0x0c, 0x8c, 0x0b, 0x9b, 0x05, 0xc2, - 0x02, 0x0d, 0x0a, 0x0b, 0x00, 0x06, 0x05, 0x03, 0x07, 0x10, 0x10, 0xd4, - 0x3c, 0xc4, 0xfc, 0xc4, 0x39, 0x39, 0x31, 0x00, 0x2f, 0xe4, 0xfc, 0xec, - 0x10, 0xee, 0x12, 0x39, 0x39, 0x30, 0x01, 0x11, 0x23, 0x11, 0x21, 0x35, - 0x21, 0x35, 0x34, 0x36, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x06, 0x02, 0xa6, - 0xb8, 0xfe, 0xd5, 0x01, 0x2b, 0xa9, 0xb3, 0xdd, 0xd1, 0x63, 0x4d, 0x04, - 0xc3, 0xfb, 0x3d, 0x03, 0xd1, 0x8f, 0x4e, 0xb8, 0xae, 0x99, 0x51, 0x00, - 0x00, 0x02, 0x00, 0x46, 0xff, 0xe3, 0x04, 0x58, 0x06, 0x14, 0x00, 0x1a, - 0x00, 0x25, 0x00, 0x00, 0x01, 0x3e, 0x01, 0x33, 0x32, 0x12, 0x11, 0x10, - 0x02, 0x23, 0x22, 0x26, 0x27, 0x15, 0x23, 0x11, 0x23, 0x35, 0x33, 0x35, - 0x33, 0x15, 0x33, 0x21, 0x15, 0x21, 0x23, 0x00, 0x10, 0x26, 0x23, 0x22, - 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x01, 0x79, 0x2c, 0x9b, 0x66, 0xca, - 0xe8, 0xe9, 0xcb, 0x64, 0x99, 0x2e, 0xb8, 0x7b, 0x7b, 0xb8, 0x02, 0x01, - 0x61, 0xfe, 0x9f, 0x02, 0x02, 0x1d, 0x88, 0x85, 0x86, 0x8a, 0x8a, 0x86, - 0x85, 0x03, 0xd1, 0x52, 0x58, 0xfe, 0xc9, 0xfe, 0xef, 0xfe, 0xeb, 0xfe, - 0xc5, 0x57, 0x53, 0x8d, 0x04, 0xf6, 0xa4, 0x7a, 0x7a, 0xa4, 0xfc, 0x63, - 0x01, 0xac, 0xda, 0xdb, 0xd5, 0xd4, 0xdc, 0x00, 0x00, 0x03, 0x00, 0x14, - 0x00, 0x00, 0x04, 0xa5, 0x05, 0xd5, 0x00, 0x08, 0x00, 0x11, 0x00, 0x29, - 0x00, 0x3f, 0x40, 0x24, 0x19, 0x00, 0x97, 0x0a, 0x09, 0x97, 0x12, 0x88, - 0x01, 0x97, 0x0a, 0xb1, 0x1f, 0x11, 0x0b, 0x19, 0x1f, 0x13, 0x08, 0x02, - 0x07, 0x00, 0x0e, 0x1e, 0x16, 0x05, 0x32, 0x1c, 0x09, 0x00, 0x1e, 0x12, - 0x21, 0x24, 0x27, 0x2b, 0x10, 0xd4, 0xdc, 0xd4, 0x39, 0xec, 0x32, 0xdc, - 0xec, 0xd4, 0xec, 0x11, 0x17, 0x39, 0x31, 0x00, 0x2f, 0xec, 0xec, 0xf4, - 0xec, 0x10, 0xee, 0x39, 0x30, 0x01, 0x11, 0x33, 0x32, 0x36, 0x35, 0x34, - 0x26, 0x23, 0x03, 0x11, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x25, - 0x21, 0x32, 0x16, 0x15, 0x14, 0x06, 0x07, 0x1e, 0x01, 0x15, 0x14, 0x04, - 0x29, 0x01, 0x11, 0x22, 0x06, 0x1d, 0x01, 0x23, 0x35, 0x34, 0x36, 0x02, - 0x1c, 0x78, 0xb0, 0x96, 0x9e, 0xa8, 0x78, 0x74, 0x92, 0x83, 0x81, 0x94, - 0xfe, 0xc2, 0x01, 0x42, 0xe5, 0xf8, 0x83, 0x83, 0x93, 0xa7, 0xfe, 0xf6, - 0xfe, 0xf9, 0xfe, 0xbe, 0x3e, 0x64, 0x9c, 0xa9, 0x02, 0xc9, 0xfd, 0xdd, - 0x7b, 0x8d, 0x92, 0x89, 0x02, 0x66, 0xfe, 0x3e, 0x70, 0x7d, 0x71, 0x64, - 0xa6, 0xc6, 0xb5, 0x89, 0x9e, 0x14, 0x16, 0xcf, 0xa0, 0xcb, 0xcf, 0x05, - 0x2f, 0x57, 0x70, 0x31, 0x46, 0x9f, 0xb9, 0x00, 0xff, 0xff, 0x00, 0xa6, - 0x00, 0x00, 0x04, 0x71, 0x05, 0xd5, 0x10, 0x06, 0x03, 0x4a, 0x00, 0x00, - 0x00, 0x02, 0x00, 0xc1, 0xff, 0xe3, 0x04, 0x58, 0x06, 0x14, 0x00, 0x12, - 0x00, 0x1d, 0x00, 0x00, 0x01, 0x3e, 0x01, 0x33, 0x32, 0x12, 0x11, 0x10, - 0x02, 0x23, 0x22, 0x26, 0x27, 0x15, 0x23, 0x11, 0x21, 0x15, 0x21, 0x00, - 0x10, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x01, 0x79, - 0x2c, 0x9b, 0x66, 0xca, 0xe8, 0xe9, 0xcb, 0x64, 0x99, 0x2e, 0xb8, 0x02, - 0xf0, 0xfd, 0xc8, 0x02, 0x1d, 0x88, 0x85, 0x86, 0x8a, 0x8a, 0x86, 0x85, - 0x03, 0xd1, 0x52, 0x58, 0xfe, 0xc9, 0xfe, 0xef, 0xfe, 0xeb, 0xfe, 0xc5, - 0x57, 0x53, 0x8d, 0x06, 0x14, 0xb8, 0xfb, 0xfd, 0x01, 0xac, 0xda, 0xdb, - 0xd5, 0xd4, 0xdc, 0x00, 0x00, 0x02, 0x00, 0x30, 0x00, 0x00, 0x04, 0xa1, - 0x05, 0xd5, 0x00, 0x0a, 0x00, 0x18, 0x00, 0x00, 0x01, 0x11, 0x33, 0x32, - 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x27, 0x33, 0x04, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x06, 0x29, 0x01, 0x11, 0x27, 0x01, 0x01, 0xa1, 0xef, - 0xb0, 0x4b, 0x4b, 0x4f, 0x4f, 0xa8, 0xef, 0xeb, 0x01, 0x7b, 0x65, 0x35, - 0x85, 0x85, 0xfe, 0xf9, 0xfe, 0x46, 0xa6, 0x01, 0x71, 0x02, 0xc9, 0xfd, - 0xdd, 0x3e, 0x3d, 0x8d, 0x92, 0x44, 0x45, 0xa4, 0x0f, 0xbf, 0x64, 0xa1, - 0xcb, 0x67, 0x68, 0x03, 0xb4, 0xe4, 0x01, 0x3d, 0x00, 0x02, 0x00, 0x3c, - 0xff, 0xe3, 0x04, 0x94, 0x06, 0x14, 0x00, 0x0c, 0x00, 0x21, 0x00, 0x00, - 0x00, 0x10, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, - 0x32, 0x01, 0x3e, 0x01, 0x33, 0x32, 0x17, 0x16, 0x11, 0x10, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x27, 0x15, 0x23, 0x11, 0x27, 0x01, 0x03, 0xd2, - 0x88, 0x84, 0x86, 0x46, 0x44, 0x44, 0x46, 0x86, 0x84, 0xfe, 0x6c, 0x2c, - 0x9a, 0x66, 0xca, 0x74, 0x74, 0x74, 0x74, 0xcc, 0x64, 0x4c, 0x4c, 0x2e, - 0xb8, 0xc2, 0x01, 0x7a, 0x01, 0x59, 0x01, 0xac, 0xda, 0x6d, 0x6e, 0xd5, - 0xd4, 0x6e, 0x6e, 0x03, 0x52, 0x52, 0x58, 0x9b, 0x9c, 0xfe, 0xef, 0xfe, - 0xeb, 0x9e, 0x9d, 0x2b, 0x2c, 0x53, 0x8d, 0x03, 0xb4, 0xe4, 0x01, 0x7c, - 0x00, 0x01, 0x00, 0x8b, 0xff, 0xe3, 0x04, 0x31, 0x05, 0xf0, 0x00, 0x19, - 0x00, 0x2f, 0x40, 0x07, 0x13, 0x32, 0x06, 0x31, 0x00, 0x0c, 0x1a, 0x10, - 0xdc, 0x3c, 0xf4, 0xec, 0x31, 0x00, 0x40, 0x12, 0x0d, 0xb3, 0x0c, 0xb2, - 0x10, 0x97, 0x09, 0x19, 0xb3, 0x00, 0xb2, 0x16, 0x97, 0x03, 0x96, 0x09, - 0x99, 0x1a, 0x10, 0xe4, 0xf4, 0xec, 0xf4, 0xec, 0x10, 0xee, 0xf6, 0xee, - 0x30, 0x13, 0x3e, 0x01, 0x33, 0x20, 0x00, 0x11, 0x10, 0x00, 0x21, 0x22, - 0x26, 0x27, 0x35, 0x1e, 0x01, 0x33, 0x32, 0x12, 0x11, 0x10, 0x02, 0x23, - 0x22, 0x06, 0x07, 0x8b, 0x4d, 0xa2, 0x5b, 0x01, 0x1d, 0x01, 0x3f, 0xfe, - 0xc3, 0xfe, 0xe1, 0x5b, 0xa2, 0x4d, 0x49, 0xa9, 0x58, 0xc5, 0xc4, 0xc4, - 0xc5, 0x56, 0xaa, 0x4a, 0x05, 0x9e, 0x29, 0x29, 0xfe, 0x67, 0xfe, 0x92, - 0xfe, 0x90, 0xfe, 0x6a, 0x29, 0x29, 0xcf, 0x3d, 0x40, 0x01, 0x30, 0x01, - 0x32, 0x01, 0x33, 0x01, 0x30, 0x40, 0x3d, 0x00, 0x00, 0x01, 0x00, 0x3c, - 0xff, 0xe3, 0x04, 0x95, 0x06, 0x67, 0x00, 0x22, 0x00, 0x00, 0x25, 0x0e, - 0x01, 0x23, 0x20, 0x00, 0x11, 0x10, 0x00, 0x21, 0x32, 0x17, 0x36, 0x37, - 0x36, 0x3b, 0x01, 0x15, 0x22, 0x07, 0x06, 0x1d, 0x01, 0x2e, 0x01, 0x23, - 0x22, 0x02, 0x15, 0x10, 0x12, 0x33, 0x32, 0x36, 0x37, 0x03, 0xe2, 0x4d, - 0xa2, 0x5b, 0xfe, 0xe1, 0xfe, 0xc3, 0x01, 0x3f, 0x01, 0x1d, 0x5a, 0x4f, - 0x17, 0x2a, 0x5a, 0xa5, 0x14, 0x54, 0x33, 0x2c, 0x4a, 0xaa, 0x56, 0xc5, - 0xc4, 0xc4, 0xc5, 0x58, 0xa9, 0x49, 0x35, 0x29, 0x29, 0x01, 0x96, 0x01, - 0x70, 0x01, 0x2a, 0x01, 0x99, 0x14, 0x33, 0x32, 0x6a, 0x9c, 0x3e, 0x35, - 0x87, 0x46, 0x3d, 0x40, 0xfe, 0xd0, 0xef, 0xfe, 0xce, 0xfe, 0xd0, 0x40, - 0x3d, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x5e, 0xff, 0xe3, 0x04, 0x73, - 0x05, 0x8e, 0x00, 0x21, 0x00, 0x00, 0x25, 0x0e, 0x01, 0x23, 0x20, 0x00, - 0x10, 0x00, 0x21, 0x32, 0x17, 0x36, 0x37, 0x36, 0x3b, 0x01, 0x15, 0x22, - 0x07, 0x06, 0x1d, 0x01, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, - 0x33, 0x32, 0x36, 0x37, 0x03, 0xc0, 0x4a, 0x9d, 0x52, 0xfe, 0xfc, 0xfe, - 0xdb, 0x01, 0x25, 0x01, 0x04, 0x46, 0x43, 0x13, 0x3d, 0x5a, 0xa5, 0x14, - 0x5a, 0x2d, 0x2c, 0x49, 0x93, 0x5d, 0xad, 0xba, 0xbb, 0xac, 0x60, 0x98, - 0x41, 0x39, 0x2b, 0x2b, 0x01, 0x38, 0x02, 0x28, 0x01, 0x38, 0x10, 0x72, - 0x47, 0x6a, 0x9c, 0x3e, 0x3e, 0x7e, 0x94, 0x41, 0x3a, 0xe0, 0xd0, 0xcf, - 0xe1, 0x3b, 0x3e, 0x00, 0xff, 0xff, 0x00, 0x08, 0x00, 0x00, 0x04, 0x4e, - 0x05, 0xd5, 0x10, 0x06, 0x00, 0x92, 0x00, 0x00, 0x00, 0x02, 0x00, 0x08, - 0x00, 0x00, 0x04, 0xc9, 0x05, 0xd5, 0x00, 0x12, 0x00, 0x1b, 0x00, 0x00, - 0x01, 0x33, 0x20, 0x00, 0x11, 0x10, 0x00, 0x21, 0x23, 0x11, 0x22, 0x07, - 0x06, 0x1d, 0x01, 0x23, 0x35, 0x34, 0x36, 0x01, 0x20, 0x36, 0x11, 0x10, - 0x26, 0x21, 0x23, 0x11, 0x01, 0x46, 0xe9, 0x01, 0x56, 0x01, 0x44, 0xfe, - 0xbc, 0xfe, 0xaa, 0xe9, 0x36, 0x3c, 0x30, 0x9c, 0xc0, 0x01, 0x63, 0x00, - 0xff, 0xca, 0xc9, 0xff, 0x00, 0x1a, 0x05, 0xd5, 0xfe, 0x94, 0xfe, 0x80, - 0xfe, 0x82, 0xfe, 0x95, 0x05, 0x2f, 0x2f, 0x26, 0x72, 0x31, 0x46, 0xb5, - 0xa3, 0xfa, 0xd1, 0xfb, 0x01, 0x48, 0x01, 0x4b, 0xfb, 0xfb, 0x77, 0x00, - 0x00, 0x02, 0x00, 0x83, 0x00, 0x00, 0x04, 0x4e, 0x05, 0xd5, 0x00, 0x08, - 0x00, 0x16, 0x00, 0x00, 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x3b, - 0x01, 0x01, 0x35, 0x21, 0x11, 0x21, 0x20, 0x24, 0x35, 0x34, 0x37, 0x36, - 0x25, 0x33, 0x11, 0x03, 0x83, 0xef, 0xa8, 0x9e, 0x96, 0xb0, 0xef, 0xfd, - 0x45, 0x03, 0x86, 0xfe, 0x46, 0xfe, 0xf9, 0xfe, 0xf6, 0x35, 0x65, 0x01, - 0x7b, 0xeb, 0x02, 0xc9, 0x89, 0x92, 0x8d, 0x7b, 0x04, 0x89, 0xa6, 0xfa, - 0x2b, 0xcf, 0xcb, 0xa1, 0x64, 0xbf, 0x0f, 0x01, 0xc2, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x9d, 0xff, 0xe3, 0x04, 0x34, 0x06, 0x14, 0x00, 0x0a, - 0x00, 0x1d, 0x00, 0x00, 0x00, 0x10, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, - 0x26, 0x23, 0x22, 0x03, 0x35, 0x21, 0x11, 0x23, 0x35, 0x0e, 0x01, 0x23, - 0x22, 0x02, 0x11, 0x10, 0x12, 0x33, 0x32, 0x16, 0x17, 0x11, 0x01, 0x5f, - 0x88, 0x85, 0x86, 0x8a, 0x8a, 0x86, 0x85, 0xa3, 0x02, 0xf0, 0xb8, 0x2e, - 0x99, 0x64, 0xcb, 0xe9, 0xe8, 0xca, 0x66, 0x9b, 0x2c, 0x03, 0x05, 0xfe, - 0x54, 0xda, 0xdc, 0xd4, 0xd5, 0xdb, 0x01, 0x7d, 0xb8, 0xf9, 0xec, 0x8d, - 0x53, 0x57, 0x01, 0x3b, 0x01, 0x15, 0x01, 0x11, 0x01, 0x37, 0x58, 0x52, - 0x01, 0x8b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x88, 0xfe, 0x3d, 0x04, 0x47, - 0x04, 0x7b, 0x00, 0x0b, 0x00, 0x37, 0x00, 0x00, 0x25, 0x32, 0x36, 0x35, - 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x05, 0x16, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x2f, 0x01, 0x35, 0x16, 0x17, 0x16, - 0x33, 0x32, 0x33, 0x37, 0x36, 0x3f, 0x01, 0x36, 0x35, 0x34, 0x27, 0x26, - 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x11, 0x10, 0x12, 0x33, 0x32, 0x12, - 0x11, 0x10, 0x07, 0x06, 0x02, 0x68, 0x8c, 0x90, 0x90, 0x8c, 0x8d, 0x90, - 0x90, 0x01, 0xa7, 0x13, 0x28, 0x3e, 0x76, 0x77, 0xc5, 0x66, 0x32, 0x97, - 0x42, 0x46, 0x4b, 0x49, 0x09, 0x0a, 0x20, 0x49, 0x3c, 0x27, 0x1b, 0x0d, - 0x11, 0x29, 0x18, 0x69, 0xeb, 0x79, 0x7c, 0xf6, 0xea, 0xe9, 0xf6, 0x7b, - 0x1f, 0x7f, 0xda, 0xd6, 0xd5, 0xdb, 0xdb, 0xd5, 0xd6, 0xda, 0x4c, 0x09, - 0x28, 0x3d, 0x5c, 0x88, 0x52, 0x52, 0x0c, 0x24, 0xad, 0x18, 0x0f, 0x0f, - 0x01, 0x02, 0x2b, 0x1c, 0x18, 0x2e, 0x21, 0x13, 0x18, 0x15, 0x0d, 0x01, - 0x03, 0x94, 0x97, 0x01, 0x1e, 0x01, 0x1f, 0x01, 0x2d, 0xfe, 0xd3, 0xfe, - 0xe1, 0xfe, 0xe2, 0x97, 0x26, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc5, - 0x00, 0x00, 0x04, 0x4e, 0x05, 0xd5, 0x00, 0x0b, 0x00, 0x2b, 0x40, 0x0a, - 0x08, 0x04, 0x1e, 0x00, 0x31, 0x0b, 0x06, 0x03, 0x33, 0x0c, 0x10, 0xfc, - 0xc4, 0xc4, 0xfc, 0xec, 0x32, 0x31, 0x00, 0x40, 0x0c, 0x06, 0x97, 0x08, - 0x0a, 0x97, 0x00, 0x88, 0x04, 0x97, 0x08, 0xb1, 0x02, 0x2f, 0xec, 0xec, - 0xf4, 0xec, 0x10, 0xee, 0x30, 0x01, 0x11, 0x21, 0x35, 0x21, 0x11, 0x21, - 0x35, 0x21, 0x11, 0x21, 0x35, 0x04, 0x4e, 0xfc, 0x77, 0x02, 0xbf, 0xfd, - 0x72, 0x02, 0x8e, 0xfd, 0x54, 0x05, 0xd5, 0xfa, 0x2b, 0xaa, 0x02, 0x1d, - 0xaa, 0x01, 0xba, 0xaa, 0x00, 0x02, 0x00, 0x75, 0xff, 0xe3, 0x04, 0x5c, - 0x05, 0xf0, 0x00, 0x15, 0x00, 0x1c, 0x00, 0x3d, 0x40, 0x0c, 0x03, 0x02, - 0x1c, 0x32, 0x10, 0x36, 0x09, 0x16, 0x32, 0x00, 0x35, 0x1d, 0x10, 0xf4, - 0xec, 0xc4, 0xf4, 0xec, 0x39, 0x39, 0x31, 0x00, 0x40, 0x14, 0x00, 0x16, - 0x03, 0x01, 0x0a, 0xb3, 0x09, 0x06, 0x97, 0x0d, 0x96, 0x1d, 0x16, 0x97, - 0x01, 0x19, 0x97, 0x13, 0x99, 0x1d, 0x10, 0xf4, 0xec, 0xd4, 0xee, 0x10, - 0xf4, 0xf4, 0xd4, 0xee, 0x12, 0x39, 0x11, 0x39, 0x30, 0x13, 0x35, 0x21, - 0x35, 0x34, 0x02, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, - 0x12, 0x11, 0x10, 0x02, 0x23, 0x22, 0x02, 0x13, 0x14, 0x12, 0x33, 0x32, - 0x12, 0x37, 0x75, 0x03, 0x13, 0x8a, 0x96, 0x56, 0xaa, 0x4a, 0x4d, 0xa2, - 0x5b, 0xfd, 0xf7, 0xf7, 0xfd, 0xfd, 0xf6, 0xd7, 0x8c, 0x94, 0x94, 0x7e, - 0x09, 0x02, 0xe9, 0x53, 0x08, 0xf1, 0x01, 0x17, 0x40, 0x3d, 0xcf, 0x29, - 0x29, 0xfe, 0x80, 0xfe, 0x79, 0xfe, 0x7a, 0xfe, 0x80, 0x01, 0x7e, 0x01, - 0x23, 0xf8, 0xfe, 0xfb, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x01, 0x00, 0x89, - 0xff, 0xe3, 0x04, 0x37, 0x05, 0xf0, 0x00, 0x28, 0x00, 0x3e, 0x40, 0x0b, - 0x14, 0x09, 0x1f, 0x10, 0x32, 0x03, 0x19, 0x32, 0x26, 0x30, 0x29, 0x10, - 0xfc, 0xec, 0xd4, 0xec, 0xd4, 0xc4, 0xc4, 0x31, 0x00, 0x40, 0x16, 0x0a, - 0xb3, 0x09, 0x0d, 0x97, 0x06, 0x96, 0x29, 0x00, 0x16, 0x97, 0x13, 0xb1, - 0x29, 0x1f, 0xb3, 0x20, 0x1c, 0x97, 0x23, 0x99, 0x29, 0x10, 0xf4, 0xec, - 0xd4, 0xec, 0x10, 0xf4, 0xec, 0x39, 0x10, 0xf4, 0xec, 0xd4, 0xec, 0x30, - 0x01, 0x2e, 0x01, 0x35, 0x34, 0x24, 0x33, 0x32, 0x16, 0x17, 0x15, 0x2e, - 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, - 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x15, 0x0e, 0x01, 0x23, - 0x22, 0x24, 0x35, 0x34, 0x36, 0x01, 0xb8, 0x83, 0x89, 0x01, 0x05, 0xda, - 0x49, 0xbd, 0x79, 0x68, 0xbe, 0x59, 0x86, 0x91, 0x9c, 0x8b, 0x9a, 0x9a, - 0x98, 0xb2, 0xb2, 0xa6, 0x62, 0xc6, 0x66, 0x67, 0xd6, 0x67, 0xf5, 0xfe, - 0xeb, 0x9c, 0x03, 0x1f, 0x22, 0xa2, 0x7b, 0xb5, 0xdd, 0x20, 0x20, 0xba, - 0x28, 0x28, 0x7b, 0x73, 0x6d, 0x7a, 0xa6, 0x99, 0x82, 0x8d, 0x96, 0x34, - 0x35, 0xc9, 0x24, 0x26, 0xeb, 0xce, 0x95, 0xc7, 0x00, 0x01, 0x00, 0x3f, - 0xfe, 0x56, 0x04, 0x92, 0x05, 0xd5, 0x00, 0x13, 0x00, 0x00, 0x01, 0x21, - 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x11, 0x14, 0x07, 0x06, 0x2b, 0x01, - 0x35, 0x33, 0x32, 0x37, 0x36, 0x35, 0x01, 0x7c, 0x03, 0x16, 0xfd, 0xb5, - 0x02, 0x0c, 0xfd, 0xf4, 0x59, 0x5a, 0xa5, 0xb0, 0x8a, 0x5a, 0x2d, 0x2c, - 0x05, 0xd5, 0xaa, 0xfe, 0x48, 0xaa, 0xfd, 0x23, 0xc3, 0x69, 0x6a, 0x9c, - 0x3e, 0x3e, 0x7e, 0x00, 0x00, 0x01, 0x00, 0xc3, 0xfe, 0x56, 0x04, 0x27, - 0x06, 0x14, 0x00, 0x24, 0x00, 0x00, 0x01, 0x15, 0x2b, 0x01, 0x22, 0x07, - 0x06, 0x1d, 0x01, 0x21, 0x15, 0x21, 0x11, 0x14, 0x07, 0x06, 0x2b, 0x01, - 0x35, 0x33, 0x32, 0x37, 0x36, 0x35, 0x03, 0x21, 0x35, 0x21, 0x35, 0x34, - 0x37, 0x36, 0x37, 0x36, 0x3b, 0x02, 0x04, 0x27, 0xd1, 0x02, 0x61, 0x27, - 0x26, 0x01, 0x81, 0xfe, 0x7f, 0x51, 0x52, 0xb5, 0x46, 0x31, 0x69, 0x26, - 0x26, 0x02, 0xfe, 0xd7, 0x01, 0x28, 0x57, 0x25, 0x3c, 0x46, 0x61, 0x09, - 0x03, 0x06, 0x14, 0x99, 0x29, 0x28, 0x67, 0x63, 0x8f, 0xfc, 0x1b, 0xd6, - 0x60, 0x60, 0x9c, 0x30, 0x31, 0x99, 0x03, 0xe5, 0x8f, 0x4e, 0xb4, 0x5c, - 0x27, 0x15, 0x1a, 0x00, 0x00, 0x01, 0x00, 0x34, 0xff, 0xe3, 0x04, 0x9d, - 0x06, 0x67, 0x00, 0x28, 0x00, 0x00, 0x25, 0x0e, 0x01, 0x23, 0x20, 0x00, - 0x11, 0x10, 0x00, 0x21, 0x32, 0x17, 0x16, 0x17, 0x36, 0x37, 0x36, 0x3b, - 0x01, 0x15, 0x22, 0x07, 0x06, 0x07, 0x15, 0x2e, 0x01, 0x23, 0x22, 0x02, - 0x11, 0x10, 0x12, 0x33, 0x32, 0x36, 0x37, 0x11, 0x23, 0x35, 0x21, 0x04, - 0x1e, 0x52, 0xca, 0x76, 0xfe, 0xe4, 0xfe, 0xc4, 0x01, 0x40, 0x01, 0x1c, - 0x5e, 0x56, 0x11, 0x11, 0x0f, 0x15, 0x5a, 0xa6, 0x13, 0x54, 0x33, 0x2b, - 0x01, 0x50, 0xaa, 0x60, 0xc4, 0xc6, 0xc0, 0xc6, 0x42, 0x66, 0x28, 0xd8, - 0x01, 0x9a, 0x7b, 0x4b, 0x4d, 0x01, 0x97, 0x01, 0x6f, 0x01, 0x6e, 0x01, - 0x99, 0x1a, 0x06, 0x06, 0x1a, 0x19, 0x6a, 0x9c, 0x3e, 0x36, 0x86, 0x1b, - 0x4d, 0x49, 0xfe, 0xcf, 0xfe, 0xce, 0xfe, 0xc9, 0xfe, 0xd5, 0x1f, 0x21, - 0x01, 0x91, 0xa6, 0x00, 0x00, 0x02, 0x00, 0x1c, 0xfe, 0x52, 0x04, 0xb6, - 0x05, 0x49, 0x00, 0x0d, 0x00, 0x15, 0x00, 0x00, 0x01, 0x00, 0x11, 0x14, - 0x21, 0x20, 0x35, 0x10, 0x09, 0x01, 0x33, 0x09, 0x01, 0x33, 0x01, 0x02, - 0x11, 0x14, 0x33, 0x32, 0x35, 0x10, 0x02, 0xda, 0x01, 0x44, 0xfe, 0x60, - 0xfe, 0x48, 0x01, 0x26, 0xfe, 0x30, 0xd8, 0x01, 0x74, 0x01, 0x74, 0xda, - 0xfd, 0xa2, 0xc6, 0xd8, 0xcc, 0x02, 0x8a, 0xfe, 0x3f, 0xfe, 0x75, 0xec, - 0xec, 0x01, 0x6f, 0x01, 0xe4, 0x02, 0xb8, 0xfd, 0xd5, 0x02, 0x2b, 0xfc, - 0xa6, 0xfe, 0xd3, 0xfe, 0xbc, 0x8a, 0x8a, 0x01, 0x45, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x41, 0x00, 0x00, 0x04, 0x90, 0x06, 0x14, 0x00, 0x26, - 0x00, 0x00, 0x01, 0x11, 0x23, 0x14, 0x17, 0x16, 0x37, 0x36, 0x37, 0x36, - 0x35, 0x11, 0x33, 0x11, 0x14, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x11, - 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, 0x11, 0x36, - 0x37, 0x36, 0x33, 0x32, 0x16, 0x02, 0xf3, 0x01, 0x22, 0x26, 0x37, 0x13, - 0x36, 0x2f, 0xa7, 0x98, 0x9a, 0x7f, 0x4a, 0x49, 0x5f, 0x42, 0x47, 0x7d, - 0xa6, 0xa6, 0x4d, 0x11, 0x4b, 0x55, 0x76, 0x98, 0x02, 0xb6, 0xfe, 0xe0, - 0x99, 0x31, 0x34, 0x04, 0x02, 0x49, 0x42, 0x9c, 0x01, 0x9b, 0xfe, 0x65, - 0xe4, 0xe1, 0x60, 0x60, 0xd6, 0x01, 0x20, 0x97, 0x8e, 0xb7, 0xab, 0xfd, - 0x87, 0x06, 0x14, 0xfd, 0xa4, 0x86, 0x0c, 0x31, 0xe1, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xc9, 0x00, 0x00, 0x04, 0x3a, 0x05, 0xd5, 0x00, 0x11, - 0x00, 0x00, 0x01, 0x21, 0x35, 0x21, 0x15, 0x21, 0x11, 0x14, 0x17, 0x16, - 0x3b, 0x01, 0x17, 0x23, 0x22, 0x27, 0x26, 0x35, 0x02, 0x02, 0xfe, 0xc7, - 0x03, 0x3d, 0xfe, 0xc7, 0x2c, 0x2d, 0x5a, 0xb9, 0x01, 0xd9, 0xaa, 0x5c, - 0x59, 0x05, 0x2b, 0xaa, 0xaa, 0xfc, 0x7a, 0x7f, 0x3d, 0x3e, 0xab, 0x6a, - 0x66, 0xc6, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc9, 0x00, 0x00, 0x04, 0x06, - 0x05, 0xd5, 0x00, 0x15, 0x00, 0x00, 0x13, 0x21, 0x15, 0x21, 0x11, 0x33, - 0x21, 0x15, 0x21, 0x23, 0x11, 0x21, 0x15, 0x21, 0x35, 0x21, 0x11, 0x21, - 0x35, 0x21, 0x11, 0x21, 0xc9, 0x03, 0x3d, 0xfe, 0xc7, 0x02, 0x01, 0x09, - 0xfe, 0xf7, 0x02, 0x01, 0x39, 0xfc, 0xc3, 0x01, 0x39, 0xfe, 0xf9, 0x01, - 0x07, 0xfe, 0xc7, 0x05, 0xd5, 0xaa, 0xfd, 0xc0, 0xaa, 0xfe, 0x69, 0xaa, - 0xaa, 0x01, 0x97, 0xaa, 0x02, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x6e, - 0x00, 0x00, 0x04, 0xc3, 0x05, 0xd5, 0x00, 0x19, 0x00, 0x00, 0x01, 0x36, - 0x37, 0x36, 0x33, 0x32, 0x1f, 0x01, 0x07, 0x27, 0x26, 0x23, 0x22, 0x07, - 0x06, 0x0f, 0x01, 0x01, 0x23, 0x01, 0x07, 0x11, 0x23, 0x11, 0x33, 0x11, - 0x02, 0x87, 0xa1, 0x69, 0x15, 0x14, 0x7e, 0x5c, 0x2f, 0x6a, 0x21, 0x2d, - 0x3c, 0x11, 0x13, 0x42, 0x6d, 0xa4, 0x02, 0x56, 0xf4, 0xfe, 0x19, 0x9a, - 0xcb, 0xcb, 0x04, 0x9c, 0xaa, 0x0c, 0x03, 0x63, 0x33, 0x72, 0x25, 0x33, - 0x04, 0x0f, 0x73, 0xac, 0xfc, 0x8d, 0x02, 0xec, 0xa4, 0xfd, 0xb8, 0x05, - 0xd5, 0xfd, 0x68, 0x00, 0x00, 0x01, 0x00, 0xec, 0x00, 0x00, 0x04, 0xb2, - 0x06, 0x14, 0x00, 0x17, 0x00, 0x00, 0x13, 0x35, 0x34, 0x37, 0x36, 0x3b, - 0x01, 0x15, 0x23, 0x22, 0x07, 0x06, 0x15, 0x33, 0x11, 0x01, 0x33, 0x09, - 0x01, 0x23, 0x01, 0x07, 0x11, 0x23, 0xec, 0x59, 0x5a, 0xa5, 0xcd, 0xb9, - 0x5a, 0x2d, 0x2c, 0x05, 0x01, 0xe3, 0xe0, 0xfe, 0x47, 0x01, 0xfe, 0xe1, - 0xfe, 0x62, 0x89, 0xbe, 0x03, 0xea, 0x94, 0xc3, 0x69, 0x6a, 0x9c, 0x3e, - 0x3e, 0x7e, 0xfe, 0x11, 0x01, 0xd1, 0xfe, 0x5a, 0xfd, 0x46, 0x02, 0x42, - 0x81, 0xfe, 0x3f, 0x00, 0x00, 0x01, 0x00, 0xa0, 0x00, 0x00, 0x04, 0x0a, - 0x06, 0x1f, 0x00, 0x17, 0x00, 0x00, 0x01, 0x14, 0x16, 0x3b, 0x01, 0x15, - 0x23, 0x22, 0x26, 0x3d, 0x01, 0x23, 0x35, 0x33, 0x11, 0x21, 0x35, 0x21, - 0x11, 0x3b, 0x01, 0x15, 0x2b, 0x01, 0x02, 0x7f, 0x5b, 0x59, 0xd7, 0xe9, - 0xa5, 0xb5, 0xe4, 0xe4, 0xfe, 0xd9, 0x01, 0xdf, 0x09, 0xdd, 0xdd, 0x09, - 0x01, 0x96, 0x7c, 0x7e, 0x9c, 0xd4, 0xc2, 0xc4, 0x8e, 0x02, 0xa7, 0x90, - 0xfc, 0xc9, 0x8e, 0x00, 0x00, 0x01, 0x00, 0x31, 0x00, 0x00, 0x04, 0x6d, - 0x05, 0xd5, 0x00, 0x0f, 0x00, 0x00, 0x01, 0x25, 0x17, 0x09, 0x01, 0x23, - 0x09, 0x01, 0x23, 0x01, 0x27, 0x05, 0x27, 0x01, 0x03, 0x33, 0x02, 0x43, - 0x01, 0x5c, 0x50, 0xfe, 0x8d, 0x01, 0xf1, 0xbf, 0xfe, 0xbf, 0xfe, 0xb6, - 0xbf, 0x01, 0xa9, 0x22, 0xfe, 0x96, 0x50, 0x01, 0x81, 0xae, 0xbf, 0x04, - 0xbd, 0xf2, 0x6e, 0xfe, 0xfe, 0xfb, 0xc1, 0x02, 0xc0, 0xfd, 0x40, 0x03, - 0x91, 0x4a, 0xfb, 0x6f, 0x01, 0x0a, 0x01, 0x7c, 0x00, 0x01, 0x00, 0x6d, - 0xff, 0xe5, 0x04, 0x6f, 0x05, 0xd5, 0x00, 0x22, 0x00, 0x00, 0x25, 0x0e, - 0x01, 0x23, 0x22, 0x26, 0x19, 0x01, 0x33, 0x11, 0x14, 0x16, 0x33, 0x32, - 0x36, 0x35, 0x11, 0x33, 0x11, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x11, - 0x33, 0x11, 0x23, 0x35, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x02, 0x38, 0x22, - 0x69, 0x4a, 0x87, 0x6f, 0xa8, 0x35, 0x46, 0x50, 0x3b, 0xa8, 0x39, 0x4a, - 0x49, 0x39, 0xa7, 0xa7, 0x21, 0x63, 0x3f, 0x4c, 0x65, 0x72, 0x48, 0x45, - 0xd1, 0x01, 0x21, 0x03, 0xfe, 0xfc, 0x0a, 0xed, 0x73, 0x7b, 0xe5, 0x03, - 0xf6, 0xfc, 0x0a, 0xf0, 0x70, 0x7b, 0xe5, 0x03, 0xf6, 0xfa, 0x2b, 0x60, - 0x3c, 0x3f, 0x46, 0x00, 0x00, 0x01, 0x00, 0x1d, 0xfe, 0x56, 0x04, 0x19, - 0x05, 0xd5, 0x00, 0x12, 0x00, 0x00, 0x13, 0x33, 0x01, 0x11, 0x33, 0x11, - 0x23, 0x01, 0x11, 0x14, 0x07, 0x06, 0x2b, 0x01, 0x35, 0x32, 0x37, 0x36, - 0x35, 0xbe, 0xe6, 0x01, 0xc6, 0xaf, 0xe6, 0xfe, 0x3b, 0x51, 0x51, 0x94, - 0x1b, 0x51, 0x28, 0x28, 0x05, 0xd5, 0xfb, 0x33, 0x04, 0xcd, 0xfa, 0x2b, - 0x04, 0xcd, 0xfb, 0x1f, 0xc3, 0x69, 0x6a, 0x9c, 0x3e, 0x3d, 0x7f, 0x00, - 0x00, 0x01, 0x00, 0xc3, 0xfe, 0x52, 0x04, 0x1b, 0x04, 0x7b, 0x00, 0x13, - 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, - 0x11, 0x23, 0x11, 0x33, 0x15, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x04, 0x1b, - 0xb9, 0x6a, 0x71, 0x81, 0x8b, 0xb8, 0xb8, 0x31, 0xa8, 0x73, 0xab, 0xa9, - 0x02, 0xb6, 0xfb, 0x9c, 0x04, 0x64, 0x97, 0x8e, 0xb7, 0xab, 0xfd, 0x87, - 0x04, 0x60, 0xa8, 0x60, 0x63, 0xe1, 0x00, 0x00, 0x00, 0x03, 0x00, 0x75, - 0xff, 0xe3, 0x04, 0x5c, 0x05, 0xf0, 0x00, 0x0a, 0x00, 0x13, 0x00, 0x1c, - 0x00, 0x00, 0x01, 0x10, 0x02, 0x20, 0x02, 0x11, 0x10, 0x12, 0x33, 0x32, - 0x12, 0x03, 0x02, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x03, 0x17, 0x16, - 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x04, 0x5c, 0xf7, 0xfe, 0x06, - 0xf6, 0xf7, 0xfc, 0xfd, 0xf7, 0xd4, 0x08, 0x3a, 0x44, 0x9a, 0x99, 0x43, - 0x3b, 0x08, 0x01, 0x09, 0x39, 0x43, 0x99, 0x9a, 0x44, 0x38, 0x09, 0x02, - 0xe9, 0xfe, 0x7a, 0xfe, 0x80, 0x01, 0x7e, 0x01, 0x88, 0x01, 0x87, 0x01, - 0x80, 0xfe, 0x80, 0xfe, 0xcc, 0x01, 0x08, 0x7b, 0x8d, 0x8d, 0x7b, 0xfe, - 0xf8, 0xb8, 0xfa, 0x76, 0x8d, 0x8d, 0x75, 0xfb, 0xff, 0xff, 0x00, 0x06, - 0xff, 0xe3, 0x04, 0xa7, 0x06, 0x15, 0x10, 0x27, 0x02, 0xa3, 0x01, 0x79, - 0x01, 0xa4, 0x10, 0x06, 0x00, 0x32, 0x91, 0x00, 0xff, 0xff, 0x00, 0x20, - 0xff, 0xe3, 0x04, 0xb2, 0x04, 0x7b, 0x10, 0x27, 0x02, 0xa3, 0x01, 0x84, - 0x00, 0x00, 0x10, 0x06, 0x00, 0x52, 0x97, 0x00, 0x00, 0x02, 0x00, 0x2d, - 0xff, 0xe3, 0x04, 0xa4, 0x05, 0xf0, 0x00, 0x10, 0x00, 0x1b, 0x00, 0x00, - 0x13, 0x10, 0x25, 0x36, 0x33, 0x32, 0x17, 0x37, 0x33, 0x11, 0x23, 0x11, - 0x07, 0x11, 0x06, 0x20, 0x02, 0x01, 0x26, 0x23, 0x22, 0x02, 0x11, 0x10, - 0x12, 0x33, 0x32, 0x37, 0x2d, 0x01, 0x4e, 0x35, 0x3e, 0xce, 0x6f, 0x93, - 0xe6, 0xaf, 0xb4, 0x6f, 0xfe, 0x38, 0xdd, 0x02, 0x88, 0x3d, 0x8a, 0x8a, - 0x79, 0x79, 0x8a, 0x8a, 0x3d, 0x02, 0xe9, 0x02, 0xa0, 0x59, 0x0e, 0x9e, - 0x83, 0xfa, 0x2b, 0x04, 0xcd, 0xa0, 0xfc, 0x76, 0xc0, 0x01, 0x7e, 0x03, - 0x5e, 0x8d, 0xfe, 0xe6, 0xfe, 0xb7, 0xfe, 0xb8, 0xfe, 0xe6, 0x8d, 0x00, - 0x00, 0x02, 0x00, 0x56, 0xfe, 0x52, 0x04, 0xab, 0x04, 0x7b, 0x00, 0x13, - 0x00, 0x20, 0x00, 0x00, 0x13, 0x10, 0x37, 0x36, 0x33, 0x32, 0x17, 0x15, - 0x37, 0x33, 0x11, 0x23, 0x11, 0x07, 0x11, 0x06, 0x23, 0x22, 0x27, 0x26, - 0x37, 0x10, 0x17, 0x16, 0x33, 0x32, 0x37, 0x11, 0x26, 0x23, 0x22, 0x03, - 0x06, 0x56, 0xfa, 0x50, 0x65, 0xd2, 0x6f, 0x7e, 0xe7, 0xb0, 0xb5, 0x6e, - 0xd3, 0xea, 0x6f, 0x56, 0xb0, 0xd7, 0x13, 0x15, 0x7f, 0x41, 0x41, 0x7f, - 0xce, 0x28, 0x09, 0x02, 0x2f, 0x01, 0xb4, 0x73, 0x25, 0x97, 0x2b, 0x6e, - 0xfa, 0x2b, 0x04, 0xcd, 0x9d, 0xfd, 0xf8, 0x97, 0xbc, 0x92, 0xfe, 0xfe, - 0x75, 0x22, 0x03, 0x6d, 0x02, 0x86, 0x6d, 0xfe, 0xe2, 0x42, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x38, 0x00, 0x00, 0x04, 0x99, 0x05, 0xd5, 0x00, 0x17, - 0x00, 0x21, 0x00, 0x00, 0x01, 0x10, 0x05, 0x06, 0x2b, 0x01, 0x11, 0x23, - 0x11, 0x22, 0x07, 0x06, 0x1d, 0x01, 0x23, 0x35, 0x34, 0x37, 0x36, 0x33, - 0x21, 0x20, 0x13, 0x16, 0x01, 0x32, 0x37, 0x36, 0x35, 0x34, 0x26, 0x2b, - 0x01, 0x11, 0x04, 0x99, 0xfe, 0xc8, 0x56, 0x6e, 0x5d, 0xca, 0x36, 0x3c, - 0x30, 0x9c, 0x60, 0x60, 0x7e, 0x01, 0x27, 0x01, 0x97, 0x52, 0x13, 0xfe, - 0x04, 0xd3, 0x40, 0x16, 0x9c, 0x8d, 0x5d, 0x04, 0x17, 0xfe, 0xa4, 0x4d, - 0x16, 0xfd, 0xa8, 0x05, 0x2f, 0x2f, 0x26, 0x72, 0x31, 0x46, 0xb5, 0x52, - 0x51, 0xfe, 0xdc, 0x45, 0xfe, 0x92, 0x9d, 0x38, 0x44, 0x85, 0x93, 0xfd, - 0xcf, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xbe, 0xfe, 0x56, 0x04, 0x54, - 0x05, 0x98, 0x00, 0x0e, 0x00, 0x2a, 0x00, 0x00, 0x01, 0x10, 0x17, 0x16, - 0x33, 0x32, 0x36, 0x35, 0x10, 0x27, 0x22, 0x23, 0x22, 0x03, 0x06, 0x11, - 0x36, 0x37, 0x32, 0x33, 0x32, 0x12, 0x11, 0x10, 0x02, 0x23, 0x22, 0x26, - 0x27, 0x11, 0x23, 0x11, 0x10, 0x37, 0x36, 0x3b, 0x01, 0x15, 0x23, 0x22, - 0x07, 0x06, 0x15, 0x01, 0x77, 0xd1, 0x1d, 0x22, 0x85, 0x87, 0xfb, 0x09, - 0x08, 0xd6, 0x2e, 0x0c, 0x5b, 0xc2, 0x07, 0x07, 0xcb, 0xe7, 0xe8, 0xca, - 0x66, 0x99, 0x2c, 0xb9, 0xcb, 0x3f, 0x4e, 0xcd, 0xb9, 0xa9, 0x09, 0x01, - 0x02, 0x2f, 0xfe, 0x89, 0x32, 0x07, 0xda, 0xd6, 0x01, 0xa2, 0x0e, 0xfe, - 0xef, 0x46, 0x01, 0x49, 0xa4, 0x06, 0xfe, 0xc6, 0xfe, 0xea, 0xfe, 0xef, - 0xfe, 0xc9, 0x57, 0x53, 0xfd, 0xc9, 0x05, 0xac, 0x01, 0x2e, 0x4f, 0x19, - 0x9c, 0xdd, 0x0e, 0x0f, 0x00, 0x02, 0x00, 0x8f, 0xfe, 0xf8, 0x04, 0xd1, - 0x05, 0xd5, 0x00, 0x16, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x16, 0x17, 0x16, - 0x17, 0x13, 0x23, 0x03, 0x2e, 0x01, 0x2b, 0x01, 0x11, 0x23, 0x11, 0x33, - 0x11, 0x33, 0x32, 0x04, 0x15, 0x14, 0x06, 0x01, 0x11, 0x33, 0x32, 0x36, - 0x35, 0x34, 0x26, 0x23, 0x02, 0xf8, 0x4e, 0x37, 0x36, 0x53, 0xcb, 0xd9, - 0xb2, 0x4d, 0x7b, 0x63, 0xc1, 0xcb, 0xcb, 0xd5, 0xf6, 0x01, 0x06, 0xa1, - 0xfd, 0xd0, 0xdd, 0x91, 0x8e, 0x97, 0x90, 0x01, 0xb9, 0x14, 0x37, 0x37, - 0xa7, 0xfe, 0x68, 0x01, 0x79, 0xa1, 0x5d, 0xfe, 0x91, 0x05, 0xd5, 0xfe, - 0xf8, 0xde, 0xd2, 0x94, 0xbb, 0x02, 0x59, 0xfd, 0xee, 0x82, 0x86, 0x81, - 0x89, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x8b, 0xff, 0xe3, 0x04, 0x4a, - 0x05, 0xf0, 0x00, 0x27, 0x00, 0x00, 0x13, 0x3e, 0x01, 0x33, 0x32, 0x04, - 0x15, 0x14, 0x06, 0x0f, 0x01, 0x0e, 0x01, 0x15, 0x14, 0x16, 0x33, 0x32, - 0x36, 0x37, 0x15, 0x0e, 0x01, 0x23, 0x22, 0x24, 0x35, 0x34, 0x36, 0x3f, - 0x01, 0x3e, 0x01, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0xe1, 0x69, - 0xbe, 0x56, 0xdf, 0x01, 0x0d, 0xbc, 0xd0, 0x6c, 0x91, 0x75, 0xaa, 0x99, - 0x68, 0xcd, 0x73, 0x6b, 0xd4, 0x69, 0xfc, 0xfe, 0xf8, 0xc0, 0xd2, 0x6a, - 0x95, 0x6d, 0xa6, 0x8f, 0x5e, 0xb9, 0x5c, 0x05, 0xa2, 0x27, 0x27, 0xf1, - 0xc8, 0xa0, 0xbe, 0x2f, 0x19, 0x20, 0x76, 0x70, 0x7b, 0x89, 0x44, 0x49, - 0xd7, 0x2d, 0x2d, 0xe0, 0xd5, 0xb5, 0xd2, 0x31, 0x18, 0x23, 0x68, 0x63, - 0x71, 0x85, 0x3c, 0x3b, 0x00, 0x01, 0x00, 0xd5, 0xff, 0xe3, 0x04, 0x06, - 0x04, 0x7b, 0x00, 0x27, 0x00, 0x00, 0x01, 0x3e, 0x01, 0x33, 0x32, 0x16, - 0x15, 0x14, 0x06, 0x0f, 0x02, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, - 0x37, 0x15, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x3f, 0x01, - 0x3e, 0x01, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x01, 0x0e, 0x50, - 0xa6, 0x5a, 0xca, 0xda, 0x92, 0x9f, 0x45, 0x08, 0xf5, 0x86, 0x7a, 0x54, - 0xbc, 0x67, 0x6a, 0xb6, 0x53, 0xd2, 0xec, 0x8d, 0x89, 0x4a, 0xb7, 0x5c, - 0x7b, 0x7d, 0x53, 0xa0, 0x4f, 0x04, 0x39, 0x21, 0x21, 0xaf, 0xa1, 0x7f, - 0x93, 0x1f, 0x0e, 0x02, 0x31, 0x80, 0x59, 0x63, 0x35, 0x35, 0xbe, 0x23, - 0x23, 0xbb, 0xa6, 0x7d, 0x9c, 0x1a, 0x0e, 0x23, 0x4a, 0x4b, 0x53, 0x51, - 0x2e, 0x2e, 0x00, 0x00, 0xff, 0xff, 0x00, 0x78, 0x00, 0x00, 0x04, 0x6d, - 0x05, 0xd5, 0x10, 0x06, 0x02, 0xeb, 0x00, 0x00, 0x00, 0x02, 0x00, 0x76, - 0xfe, 0x56, 0x04, 0x5b, 0x06, 0x14, 0x00, 0x08, 0x00, 0x21, 0x00, 0x00, - 0x01, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x33, 0x05, 0x03, 0x14, - 0x17, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, 0x26, 0x35, 0x11, 0x23, - 0x20, 0x35, 0x34, 0x21, 0x32, 0x17, 0x16, 0x17, 0x33, 0x15, 0x02, 0x38, - 0x07, 0x12, 0x21, 0x6e, 0x7c, 0x03, 0x03, 0x77, 0x01, 0x78, 0x02, 0x27, - 0x25, 0x64, 0xb0, 0xae, 0xc3, 0x51, 0x57, 0xbe, 0xfe, 0xf2, 0x01, 0x2f, - 0xb5, 0x52, 0x35, 0x12, 0xbf, 0x05, 0x04, 0x2d, 0x17, 0x30, 0x41, 0x33, - 0x9a, 0xfb, 0x3d, 0x67, 0x29, 0x28, 0x99, 0x56, 0x5c, 0xb4, 0x04, 0xae, - 0xd2, 0xd8, 0x60, 0x40, 0x6f, 0x9b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x83, - 0xfe, 0x56, 0x04, 0x08, 0x05, 0x9e, 0x00, 0x20, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x15, 0x21, 0x11, 0x14, 0x16, 0x3b, 0x01, 0x1d, 0x01, 0x14, 0x07, - 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x37, 0x36, 0x3d, 0x01, 0x23, 0x22, - 0x26, 0x35, 0x11, 0x21, 0x35, 0x21, 0x11, 0x02, 0x66, 0x01, 0xa2, 0xfe, - 0x5e, 0x5e, 0x75, 0xcf, 0x59, 0x5a, 0xa5, 0xcd, 0xb9, 0x5a, 0x2d, 0x2c, - 0x28, 0xcf, 0xaa, 0xfe, 0xd5, 0x01, 0x2b, 0x05, 0x9e, 0xfe, 0xc2, 0x8f, - 0xfd, 0xa0, 0x7c, 0x62, 0x93, 0x14, 0xc3, 0x69, 0x6a, 0x9c, 0x3e, 0x3e, - 0x7e, 0x14, 0xa6, 0xcb, 0x02, 0x60, 0x8f, 0x01, 0x3e, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x2f, 0x00, 0x00, 0x04, 0xa2, 0x05, 0xd5, 0x00, 0x10, - 0x00, 0x00, 0x01, 0x26, 0x07, 0x06, 0x1d, 0x01, 0x23, 0x35, 0x34, 0x36, - 0x33, 0x21, 0x15, 0x21, 0x11, 0x23, 0x11, 0x01, 0xc5, 0x83, 0x46, 0x31, - 0x9c, 0xc0, 0xd6, 0x02, 0xdd, 0xfe, 0x2d, 0xcb, 0x05, 0x2f, 0x08, 0x37, - 0x26, 0x72, 0x31, 0x46, 0xb5, 0xa3, 0xaa, 0xfa, 0xd5, 0x05, 0x2b, 0x00, - 0x00, 0x01, 0x00, 0x83, 0x00, 0x00, 0x04, 0x08, 0x06, 0x14, 0x00, 0x1d, - 0x00, 0x00, 0x01, 0x21, 0x15, 0x21, 0x11, 0x14, 0x16, 0x3b, 0x01, 0x15, - 0x23, 0x22, 0x26, 0x35, 0x11, 0x21, 0x35, 0x21, 0x35, 0x34, 0x37, 0x36, - 0x3b, 0x01, 0x15, 0x23, 0x22, 0x07, 0x06, 0x15, 0x02, 0x66, 0x01, 0xa2, - 0xfe, 0x5e, 0x5e, 0x75, 0xcf, 0xe1, 0xcf, 0xaa, 0xfe, 0xd5, 0x01, 0x2a, - 0x59, 0x5a, 0xa5, 0xcd, 0xb9, 0x5a, 0x2d, 0x2c, 0x04, 0x60, 0x8f, 0xfd, - 0xa0, 0x7c, 0x62, 0x93, 0xa6, 0xcb, 0x02, 0x60, 0x8f, 0x1e, 0xc3, 0x69, - 0x6a, 0x9c, 0x3e, 0x3e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x2f, - 0xfe, 0x56, 0x04, 0xa2, 0x05, 0xd5, 0x00, 0x11, 0x00, 0x00, 0x13, 0x21, - 0x15, 0x21, 0x11, 0x14, 0x17, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, - 0x26, 0x35, 0x11, 0x21, 0x2f, 0x04, 0x73, 0xfe, 0x2d, 0x2c, 0x2d, 0x5a, - 0xb9, 0xdf, 0xa5, 0x5a, 0x59, 0xfe, 0x2b, 0x05, 0xd5, 0xaa, 0xfa, 0xc1, - 0x7e, 0x3e, 0x3e, 0x9c, 0x6a, 0x69, 0xc3, 0x05, 0x3f, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x09, 0xff, 0xe3, 0x04, 0xc8, 0x06, 0x19, 0x10, 0x27, - 0x02, 0xa3, 0x01, 0x9a, 0x01, 0xa8, 0x10, 0x07, 0x00, 0x38, 0xff, 0x76, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x27, 0xff, 0xe3, 0x04, 0xaa, - 0x04, 0x71, 0x10, 0x27, 0x02, 0xa3, 0x01, 0x7c, 0x00, 0x00, 0x10, 0x07, - 0x00, 0x58, 0xff, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x4a, - 0x00, 0x00, 0x04, 0x87, 0x05, 0xb4, 0x00, 0x1e, 0x00, 0x00, 0x01, 0x15, - 0x23, 0x16, 0x12, 0x15, 0x10, 0x00, 0x23, 0x22, 0x00, 0x11, 0x34, 0x12, - 0x37, 0x23, 0x35, 0x21, 0x15, 0x06, 0x02, 0x15, 0x14, 0x12, 0x20, 0x12, - 0x35, 0x34, 0x02, 0x27, 0x35, 0x04, 0x87, 0xf5, 0x7b, 0x6e, 0xfe, 0xe0, - 0xf0, 0xf2, 0xfe, 0xdf, 0x6f, 0x7b, 0xf8, 0x01, 0xcf, 0x78, 0x86, 0xb4, - 0x01, 0x34, 0xb3, 0x86, 0x78, 0x05, 0xb4, 0xac, 0x86, 0xfe, 0xe0, 0xbc, - 0xfe, 0xc9, 0xfe, 0x91, 0x01, 0x6e, 0x01, 0x38, 0xbc, 0x01, 0x21, 0x85, - 0xac, 0xac, 0x4c, 0xfe, 0xb7, 0xde, 0xe6, 0xfe, 0xf7, 0x01, 0x09, 0xe6, - 0xde, 0x01, 0x49, 0x4c, 0xac, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x9a, - 0x00, 0x00, 0x04, 0x2a, 0x05, 0xd5, 0x00, 0x18, 0x00, 0x00, 0x21, 0x22, - 0x27, 0x26, 0x35, 0x11, 0x33, 0x11, 0x14, 0x17, 0x16, 0x33, 0x32, 0x12, - 0x35, 0x34, 0x02, 0x27, 0x33, 0x16, 0x12, 0x15, 0x10, 0x07, 0x06, 0x01, - 0xfa, 0xaa, 0x5c, 0x5a, 0xcc, 0x2c, 0x2c, 0x5a, 0x9a, 0xb4, 0x86, 0x78, - 0xda, 0x7a, 0x6e, 0x90, 0x93, 0x6a, 0x66, 0xc6, 0x04, 0x3f, 0xfb, 0xd0, - 0x7e, 0x3e, 0x3e, 0x01, 0x09, 0xe6, 0xde, 0x01, 0x49, 0x4c, 0x86, 0xfe, - 0xe0, 0xbc, 0xfe, 0xc9, 0xb8, 0xbc, 0x00, 0x00, 0x00, 0x01, 0x00, 0x11, - 0x00, 0x00, 0x04, 0xc0, 0x05, 0xd7, 0x00, 0x16, 0x00, 0x00, 0x01, 0x03, - 0x11, 0x23, 0x11, 0x01, 0x33, 0x01, 0x13, 0x36, 0x37, 0x36, 0x33, 0x32, - 0x1f, 0x01, 0x07, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x03, 0x6b, 0xf6, - 0xb7, 0xfe, 0x53, 0xc1, 0x01, 0x48, 0xc7, 0x63, 0x6d, 0x2e, 0x2d, 0x50, - 0x4b, 0x19, 0x47, 0x0a, 0x22, 0x28, 0x1c, 0x1f, 0x33, 0x04, 0x74, 0xfe, - 0x2a, 0xfd, 0x62, 0x02, 0x9e, 0x03, 0x37, 0xfd, 0x6d, 0x01, 0x91, 0xc8, - 0x2a, 0x12, 0x39, 0x13, 0x86, 0x09, 0x1f, 0x10, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x18, 0xfe, 0x56, 0x04, 0xc9, 0x04, 0x6d, 0x00, 0x1c, - 0x00, 0x00, 0x05, 0x06, 0x07, 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x36, - 0x3f, 0x01, 0x01, 0x33, 0x09, 0x01, 0x36, 0x37, 0x36, 0x33, 0x32, 0x1f, - 0x01, 0x07, 0x27, 0x26, 0x23, 0x22, 0x07, 0x02, 0x6e, 0x51, 0x47, 0x4a, - 0x7c, 0x93, 0x6c, 0x4c, 0x54, 0x33, 0x21, 0xfe, 0x3b, 0xc3, 0x01, 0x5e, - 0x01, 0x17, 0x32, 0x51, 0x2b, 0x33, 0x31, 0x37, 0x30, 0x35, 0x1c, 0x1c, - 0x16, 0x2b, 0x10, 0x68, 0xcb, 0x3a, 0x3d, 0x9a, 0x48, 0x86, 0x54, 0x04, - 0x4e, 0xfc, 0x94, 0x02, 0xbb, 0x7e, 0x29, 0x16, 0x14, 0x11, 0x93, 0x0a, - 0x0b, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x9c, 0x00, 0x00, 0x04, 0x91, - 0x05, 0xd5, 0x00, 0x12, 0x00, 0x00, 0x13, 0x21, 0x15, 0x01, 0x33, 0x15, - 0x21, 0x23, 0x01, 0x21, 0x15, 0x21, 0x35, 0x01, 0x23, 0x35, 0x21, 0x01, - 0x21, 0xb2, 0x03, 0xc9, 0xfe, 0x75, 0xe8, 0xfe, 0xf7, 0x50, 0xfe, 0xf0, - 0x03, 0x22, 0xfc, 0x0b, 0x01, 0x13, 0xb4, 0x01, 0x22, 0x01, 0x76, 0xfd, - 0x1f, 0x05, 0xd5, 0x9a, 0xfd, 0xb0, 0xaa, 0xfe, 0x69, 0xaa, 0x9a, 0x01, - 0xa7, 0xaa, 0x02, 0x40, 0x00, 0x01, 0x00, 0x9c, 0x00, 0x00, 0x04, 0x35, - 0x04, 0x62, 0x00, 0x12, 0x00, 0x00, 0x13, 0x21, 0x15, 0x01, 0x21, 0x15, - 0x21, 0x23, 0x03, 0x21, 0x15, 0x21, 0x35, 0x13, 0x21, 0x35, 0x21, 0x01, - 0x21, 0xde, 0x03, 0x2d, 0xfe, 0xf2, 0x01, 0x38, 0xfe, 0x9e, 0x59, 0xf2, - 0x02, 0x83, 0xfc, 0xbb, 0xe1, 0xfe, 0xf5, 0x01, 0x8e, 0x01, 0x1f, 0xfd, - 0x95, 0x04, 0x62, 0xa8, 0xfe, 0xae, 0xa4, 0xfe, 0xd2, 0x96, 0xaa, 0x01, - 0x1a, 0xa4, 0x01, 0x67, 0x00, 0x01, 0x00, 0x1a, 0xff, 0xe4, 0x04, 0xb7, - 0x05, 0xd5, 0x00, 0x1f, 0x00, 0x00, 0x13, 0x14, 0x17, 0x16, 0x20, 0x37, - 0x36, 0x35, 0x34, 0x27, 0x26, 0x2b, 0x01, 0x35, 0x01, 0x21, 0x35, 0x21, - 0x15, 0x01, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x04, 0x21, 0x20, - 0x24, 0x35, 0xe4, 0x64, 0x63, 0x01, 0x7b, 0x64, 0x64, 0x5c, 0x5e, 0xa4, - 0xae, 0x01, 0x72, 0xfd, 0x1e, 0x03, 0xca, 0xfe, 0x88, 0x68, 0x82, 0x62, - 0x56, 0x50, 0xfe, 0xd0, 0xfe, 0xe8, 0xfe, 0xdc, 0xfe, 0xd0, 0x01, 0xb3, - 0x8f, 0x4b, 0x4b, 0x4b, 0x4b, 0x8f, 0x86, 0x49, 0x4a, 0xa6, 0x01, 0xb9, - 0xaa, 0xa8, 0xfe, 0x47, 0x38, 0x2b, 0x6c, 0x68, 0x8a, 0xdd, 0xf2, 0xf2, - 0xdd, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1a, 0xff, 0xe4, 0x04, 0xb7, - 0x05, 0xd5, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x33, 0x14, 0x04, 0x21, 0x20, - 0x24, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x01, 0x35, 0x21, 0x15, - 0x21, 0x01, 0x15, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x20, - 0x37, 0x36, 0x03, 0xee, 0xc8, 0xfe, 0xd0, 0xfe, 0xdc, 0xfe, 0xe8, 0xfe, - 0xd0, 0x52, 0x55, 0x63, 0x81, 0x69, 0xfe, 0x88, 0x03, 0xc8, 0xfd, 0x20, - 0x01, 0x72, 0xae, 0xa6, 0x5c, 0x5c, 0x64, 0x63, 0x01, 0x7b, 0x64, 0x64, - 0x01, 0xb3, 0xdd, 0xf2, 0xf2, 0xdd, 0x8a, 0x68, 0x6c, 0x2b, 0x38, 0x01, - 0xb9, 0xa8, 0xaa, 0xfe, 0x47, 0xa6, 0x4a, 0x49, 0x86, 0x8f, 0x4b, 0x4b, - 0x4b, 0x4b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x7d, 0xfe, 0x4c, 0x04, 0x54, - 0x04, 0x60, 0x00, 0x20, 0x00, 0x00, 0x09, 0x01, 0x35, 0x21, 0x15, 0x21, - 0x01, 0x15, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, - 0x36, 0x37, 0x15, 0x06, 0x07, 0x06, 0x23, 0x20, 0x24, 0x35, 0x34, 0x37, - 0x36, 0x37, 0x36, 0x02, 0x70, 0xfe, 0x65, 0x03, 0x6a, 0xfd, 0x65, 0x01, - 0xae, 0xae, 0xa5, 0x5d, 0x5c, 0x64, 0x63, 0xbe, 0x6d, 0xc8, 0x54, 0x6a, - 0x64, 0x63, 0x5e, 0xfe, 0xe8, 0xfe, 0xd0, 0x51, 0x56, 0x62, 0x80, 0x01, - 0xdc, 0x01, 0xdc, 0xa8, 0x93, 0xfe, 0x0d, 0xa6, 0x4a, 0x4b, 0x84, 0x8f, - 0x4b, 0x4b, 0x32, 0x31, 0xc3, 0x25, 0x13, 0x12, 0xf2, 0xdd, 0x8a, 0x68, - 0x6d, 0x2a, 0x38, 0x00, 0x00, 0x01, 0x00, 0xad, 0xfe, 0x56, 0x04, 0x24, - 0x04, 0x60, 0x00, 0x20, 0x00, 0x00, 0x01, 0x32, 0x37, 0x36, 0x37, 0x15, - 0x06, 0x07, 0x06, 0x23, 0x20, 0x11, 0x34, 0x25, 0x24, 0x35, 0x34, 0x23, - 0x30, 0x21, 0x01, 0x21, 0x35, 0x21, 0x15, 0x01, 0x20, 0x15, 0x10, 0x05, - 0x06, 0x15, 0x14, 0x02, 0xbb, 0x54, 0x4d, 0x4f, 0x51, 0x57, 0x50, 0x56, - 0x61, 0xfe, 0x20, 0x01, 0x96, 0x01, 0x1c, 0xeb, 0xfe, 0xde, 0x01, 0xe5, - 0xfd, 0x65, 0x03, 0x6a, 0xfe, 0x9e, 0x01, 0x6f, 0xfe, 0x30, 0xe2, 0xfe, - 0xee, 0x15, 0x15, 0x2c, 0xb3, 0x20, 0x0d, 0x0e, 0x01, 0x19, 0xee, 0x35, - 0x25, 0x62, 0x7c, 0x02, 0x38, 0x93, 0xa8, 0xfe, 0x64, 0xe5, 0xfe, 0xec, - 0x31, 0x18, 0x61, 0x8b, 0x00, 0x01, 0x00, 0x98, 0x00, 0x00, 0x04, 0x23, - 0x05, 0xf0, 0x00, 0x20, 0x00, 0x00, 0x13, 0x36, 0x33, 0x32, 0x04, 0x15, - 0x14, 0x07, 0x06, 0x07, 0x33, 0x15, 0x23, 0x07, 0x01, 0x21, 0x15, 0x21, - 0x35, 0x01, 0x21, 0x35, 0x21, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, - 0x23, 0x22, 0x07, 0xa4, 0xd0, 0xbf, 0xdb, 0x01, 0x0b, 0x2d, 0x22, 0x42, - 0x50, 0xe6, 0x38, 0xfe, 0xbb, 0x02, 0xae, 0xfc, 0x75, 0x01, 0x7e, 0xfe, - 0xe5, 0x01, 0xb2, 0x69, 0x1e, 0x16, 0x96, 0x39, 0x44, 0xb5, 0xde, 0x05, - 0x8d, 0x63, 0xe9, 0xbd, 0x60, 0x60, 0x4a, 0x55, 0xaa, 0x3f, 0xfe, 0xa8, - 0xaa, 0xaa, 0x01, 0x97, 0xaa, 0x82, 0x54, 0x3c, 0x3e, 0xb9, 0x3c, 0x16, - 0x85, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1a, 0xff, 0xe4, 0x04, 0xb6, - 0x05, 0xd5, 0x00, 0x20, 0x00, 0x00, 0x25, 0x20, 0x37, 0x36, 0x35, 0x34, - 0x27, 0x26, 0x23, 0x21, 0x11, 0x21, 0x15, 0x21, 0x11, 0x21, 0x32, 0x17, - 0x16, 0x17, 0x16, 0x15, 0x14, 0x04, 0x21, 0x20, 0x03, 0x26, 0x35, 0x33, - 0x14, 0x17, 0x16, 0x02, 0x68, 0x01, 0x3c, 0x3d, 0x0d, 0x5c, 0x5e, 0xa4, - 0xfe, 0x47, 0x03, 0x9c, 0xfd, 0x2f, 0x01, 0x22, 0x69, 0x81, 0x63, 0x55, - 0x50, 0xfe, 0xd0, 0xfe, 0xe8, 0xfe, 0x52, 0x7a, 0x2c, 0xca, 0x9e, 0x5b, - 0x8e, 0xc7, 0x2b, 0x33, 0x86, 0x49, 0x4a, 0x03, 0x09, 0xaa, 0xfe, 0x49, - 0x38, 0x2b, 0x6c, 0x65, 0x8d, 0xdd, 0xf2, 0x01, 0x00, 0x5b, 0x74, 0xb5, - 0x47, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x7d, 0xfe, 0x4c, 0x04, 0x54, - 0x04, 0x60, 0x00, 0x1c, 0x00, 0x00, 0x01, 0x20, 0x37, 0x36, 0x35, 0x34, - 0x27, 0x26, 0x23, 0x21, 0x11, 0x21, 0x15, 0x21, 0x11, 0x37, 0x36, 0x17, - 0x16, 0x17, 0x16, 0x15, 0x14, 0x04, 0x21, 0x22, 0x27, 0x35, 0x16, 0x02, - 0x06, 0x01, 0x37, 0x3f, 0x0f, 0x5c, 0x5d, 0xa5, 0xfe, 0xd4, 0x02, 0xf0, - 0xfd, 0xc8, 0xa8, 0x67, 0x83, 0x63, 0x55, 0x51, 0xfe, 0xd0, 0xfe, 0xe8, - 0xbb, 0xd4, 0xaa, 0xfe, 0xf6, 0xc3, 0x2d, 0x35, 0x86, 0x49, 0x4a, 0x03, - 0x2c, 0xb8, 0xfe, 0x33, 0x01, 0x01, 0x39, 0x2b, 0x6c, 0x68, 0x8a, 0xdd, - 0xf2, 0x4a, 0xc3, 0x63, 0x00, 0x01, 0x00, 0xc2, 0xff, 0xe3, 0x04, 0x0f, - 0x05, 0x9e, 0x00, 0x20, 0x00, 0x00, 0x01, 0x34, 0x27, 0x26, 0x2b, 0x01, - 0x11, 0x23, 0x35, 0x33, 0x11, 0x33, 0x11, 0x33, 0x15, 0x23, 0x15, 0x16, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x21, 0x22, 0x27, 0x35, 0x16, 0x33, - 0x32, 0x37, 0x36, 0x03, 0x4d, 0x4a, 0x59, 0xad, 0x3e, 0xe5, 0xe5, 0xca, - 0xe7, 0xe7, 0xa5, 0x6c, 0x75, 0x6e, 0x8a, 0xfe, 0xee, 0xab, 0x98, 0x9c, - 0x9f, 0xb3, 0x63, 0x39, 0x01, 0xb7, 0x72, 0x4f, 0x5f, 0x01, 0x0f, 0xa4, - 0x01, 0x14, 0xfe, 0xec, 0xa4, 0x7d, 0x1d, 0x6e, 0x77, 0xb0, 0xb9, 0x7e, - 0x9d, 0x46, 0xac, 0x56, 0x72, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x7d, - 0xfe, 0x56, 0x04, 0x67, 0x04, 0x7b, 0x00, 0x0e, 0x00, 0x17, 0x00, 0x00, - 0x05, 0x11, 0x23, 0x11, 0x33, 0x15, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, - 0x16, 0x15, 0x10, 0x01, 0x00, 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, - 0x01, 0x36, 0xb9, 0xb9, 0x34, 0x87, 0x51, 0xd2, 0xb8, 0x4d, 0x4e, 0xfc, - 0xcf, 0x02, 0x72, 0x39, 0x38, 0x78, 0xdc, 0xad, 0x7a, 0xfe, 0xd0, 0x06, - 0x0a, 0xaa, 0x42, 0x52, 0x31, 0x70, 0x71, 0x99, 0xfe, 0x57, 0xfe, 0xe4, - 0x01, 0x90, 0xf9, 0x85, 0x42, 0x41, 0xef, 0x00, 0x00, 0x01, 0x02, 0x03, - 0x00, 0x00, 0x02, 0xce, 0x05, 0xd5, 0x00, 0x03, 0x00, 0x00, 0x01, 0x33, - 0x11, 0x23, 0x02, 0x04, 0xca, 0xca, 0x05, 0xd5, 0xfa, 0x2b, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x39, 0x00, 0x00, 0x03, 0x98, 0x05, 0xd5, 0x10, 0x27, - 0x01, 0x82, 0xff, 0x36, 0x00, 0x00, 0x10, 0x07, 0x01, 0x82, 0x00, 0xca, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xa4, 0x00, 0x00, 0x04, 0x2d, - 0x05, 0xd5, 0x00, 0x13, 0x00, 0x00, 0x01, 0x33, 0x11, 0x21, 0x15, 0x21, - 0x15, 0x21, 0x15, 0x21, 0x11, 0x23, 0x11, 0x21, 0x35, 0x21, 0x35, 0x21, - 0x35, 0x21, 0x02, 0x04, 0xca, 0x01, 0x5e, 0xfe, 0xa2, 0x01, 0x5e, 0xfe, - 0xa2, 0xca, 0xfe, 0xa0, 0x01, 0x60, 0xfe, 0xa0, 0x01, 0x60, 0x05, 0xd5, - 0xfe, 0x6c, 0xa8, 0xf0, 0xaa, 0xfe, 0x01, 0x01, 0xff, 0xaa, 0xf0, 0xa8, - 0xff, 0xff, 0x02, 0x03, 0x00, 0x00, 0x02, 0xce, 0x05, 0xd5, 0x10, 0x06, - 0x00, 0x04, 0xff, 0x00, 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, - 0x07, 0x6d, 0x10, 0x26, 0x00, 0x24, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xc3, - 0x00, 0x00, 0x01, 0x75, 0xff, 0xff, 0x00, 0x85, 0xff, 0xe3, 0x04, 0x23, - 0x06, 0x66, 0x10, 0x26, 0x00, 0x44, 0x00, 0x00, 0x10, 0x06, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc9, 0x00, 0x00, 0x04, 0x06, - 0x07, 0x6d, 0x10, 0x26, 0x00, 0x2c, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xc3, - 0x00, 0x00, 0x01, 0x75, 0xff, 0xff, 0x00, 0xb2, 0x00, 0x00, 0x04, 0x44, - 0x06, 0x66, 0x10, 0x26, 0x00, 0xf3, 0x00, 0x00, 0x10, 0x06, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x75, 0xff, 0xe3, 0x04, 0x5c, - 0x07, 0x6d, 0x10, 0x26, 0x00, 0x32, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xc3, - 0x00, 0x00, 0x01, 0x75, 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, - 0x06, 0x66, 0x10, 0x26, 0x00, 0x52, 0x00, 0x00, 0x10, 0x06, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x93, 0xff, 0xe3, 0x04, 0x3d, - 0x07, 0x6d, 0x10, 0x26, 0x00, 0x38, 0x00, 0x00, 0x11, 0x07, 0x0c, 0xc3, - 0x00, 0x00, 0x01, 0x75, 0x00, 0x14, 0xb4, 0x11, 0x23, 0x1f, 0x01, 0x07, - 0x2b, 0x40, 0x09, 0x20, 0x1f, 0x2f, 0x23, 0x00, 0x1f, 0x0f, 0x23, 0x04, - 0x5d, 0x31, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, 0xff, 0xe3, 0x04, 0x1b, - 0x06, 0x66, 0x10, 0x26, 0x00, 0x58, 0x00, 0x00, 0x10, 0x06, 0x02, 0x68, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x93, 0xff, 0xe3, 0x04, 0x3d, - 0x07, 0xa0, 0x10, 0x27, 0x0c, 0xbe, 0x00, 0x00, 0x00, 0xf9, 0x10, 0x26, - 0x00, 0x38, 0x00, 0x00, 0x10, 0x07, 0x02, 0x6a, 0x00, 0x00, 0x01, 0xaa, - 0xff, 0xff, 0x00, 0xc3, 0xff, 0xe3, 0x04, 0x1b, 0x07, 0x32, 0x10, 0x26, - 0x02, 0x90, 0x00, 0x00, 0x10, 0x26, 0x00, 0x58, 0x00, 0x00, 0x10, 0x07, - 0x00, 0x71, 0x00, 0x00, 0x01, 0x3c, 0x00, 0x00, 0xff, 0xff, 0x00, 0x93, - 0xff, 0xe3, 0x04, 0x3d, 0x07, 0xf9, 0x10, 0x27, 0x0c, 0xbe, 0x00, 0x00, - 0x00, 0xf9, 0x10, 0x26, 0x00, 0x38, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xbf, - 0x00, 0x00, 0x02, 0x03, 0xff, 0xff, 0x00, 0xc3, 0xff, 0xe3, 0x04, 0x1b, - 0x07, 0xa2, 0x10, 0x26, 0x02, 0x90, 0x00, 0x00, 0x10, 0x26, 0x00, 0x58, - 0x00, 0x00, 0x10, 0x07, 0x02, 0x89, 0x00, 0x00, 0x01, 0x3c, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x93, 0xff, 0xe3, 0x04, 0x3d, 0x07, 0xfb, 0x10, 0x27, - 0x0c, 0xbe, 0x00, 0x00, 0x00, 0xf9, 0x10, 0x26, 0x00, 0x38, 0x00, 0x00, - 0x10, 0x07, 0x0c, 0xc3, 0x00, 0x00, 0x02, 0x03, 0xff, 0xff, 0x00, 0xc3, - 0xff, 0xe3, 0x04, 0x1b, 0x07, 0xa2, 0x10, 0x26, 0x02, 0x90, 0x00, 0x00, - 0x10, 0x26, 0x00, 0x58, 0x00, 0x00, 0x10, 0x07, 0x02, 0x94, 0x00, 0x00, - 0x01, 0x3c, 0x00, 0x00, 0xff, 0xff, 0x00, 0x93, 0xff, 0xe3, 0x04, 0x3d, - 0x07, 0xf9, 0x10, 0x27, 0x0c, 0xbe, 0x00, 0x00, 0x00, 0xf9, 0x10, 0x26, - 0x00, 0x38, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xc1, 0x00, 0x00, 0x02, 0x03, - 0xff, 0xff, 0x00, 0xc3, 0xff, 0xe3, 0x04, 0x1b, 0x07, 0xa2, 0x10, 0x27, - 0x02, 0x88, 0x00, 0x00, 0x01, 0x3c, 0x10, 0x06, 0x00, 0xbe, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x7a, 0xff, 0xe3, 0x04, 0x57, 0x04, 0x7b, 0x12, 0x06, - 0x01, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, - 0x07, 0xa0, 0x10, 0x27, 0x0c, 0xbe, 0x00, 0x00, 0x00, 0xf9, 0x10, 0x27, - 0x02, 0x6a, 0x00, 0x00, 0x01, 0xaa, 0x10, 0x06, 0x00, 0x24, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x85, 0xff, 0xe3, 0x04, 0x23, 0x07, 0x32, 0x10, 0x27, - 0x00, 0x71, 0x00, 0x00, 0x01, 0x3c, 0x10, 0x06, 0x00, 0xa6, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, 0x07, 0xa0, 0x10, 0x27, - 0x02, 0x6a, 0x00, 0x00, 0x01, 0xaa, 0x10, 0x26, 0x0c, 0xc7, 0x00, 0x84, - 0x10, 0x06, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x85, - 0xff, 0xe3, 0x04, 0x23, 0x07, 0x32, 0x10, 0x27, 0x00, 0x71, 0x00, 0x00, - 0x01, 0x3c, 0x12, 0x06, 0x01, 0xd6, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x04, 0x9c, 0x07, 0x30, 0x10, 0x27, 0x0c, 0xcb, 0x00, 0xaa, - 0x00, 0x00, 0x10, 0x06, 0x00, 0x88, 0x00, 0x00, 0xff, 0xff, 0x00, 0x29, - 0xff, 0xe3, 0x04, 0xb0, 0x05, 0xf6, 0x10, 0x26, 0x02, 0x8c, 0x00, 0x00, - 0x10, 0x06, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x66, - 0xff, 0xe3, 0x04, 0x50, 0x07, 0x6d, 0x10, 0x27, 0x0c, 0xc3, 0x00, 0x00, - 0x01, 0x75, 0x10, 0x06, 0x00, 0x2a, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, - 0xfe, 0x48, 0x04, 0x12, 0x06, 0x66, 0x10, 0x26, 0x02, 0x68, 0x00, 0x00, - 0x10, 0x06, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, - 0x00, 0x00, 0x04, 0xc9, 0x07, 0x6d, 0x10, 0x27, 0x0c, 0xc3, 0x00, 0x00, - 0x01, 0x75, 0x10, 0x06, 0x00, 0x2e, 0x00, 0x00, 0xff, 0xff, 0x00, 0xec, - 0x00, 0x00, 0x04, 0xb2, 0x07, 0x6d, 0x10, 0x27, 0x0c, 0xc3, 0x00, 0x00, - 0x01, 0x75, 0x10, 0x06, 0x00, 0x4e, 0x00, 0x00, 0xff, 0xff, 0x00, 0x75, - 0xfe, 0x65, 0x04, 0x5c, 0x05, 0xf0, 0x10, 0x26, 0x02, 0x78, 0x1c, 0xf0, - 0x10, 0x06, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, - 0xfe, 0x65, 0x04, 0x48, 0x04, 0x7b, 0x10, 0x26, 0x02, 0x78, 0x1c, 0xf0, - 0x10, 0x06, 0x00, 0x52, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x75, - 0xfe, 0x65, 0x04, 0x5c, 0x07, 0x30, 0x10, 0x26, 0x0c, 0xcb, 0x00, 0x00, - 0x10, 0x06, 0x01, 0xa1, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, - 0xfe, 0x65, 0x04, 0x48, 0x05, 0xf6, 0x10, 0x26, 0x02, 0x8c, 0x00, 0x00, - 0x10, 0x06, 0x01, 0xa2, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x1a, - 0xff, 0xe4, 0x04, 0xb7, 0x07, 0x6d, 0x10, 0x27, 0x0c, 0xc3, 0x00, 0x00, - 0x01, 0x75, 0x10, 0x06, 0x01, 0x79, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7d, - 0xfe, 0x4c, 0x04, 0x54, 0x06, 0x66, 0x10, 0x26, 0x02, 0x68, 0x00, 0x00, - 0x10, 0x06, 0x02, 0x38, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xba, - 0xfe, 0x56, 0x03, 0xcb, 0x06, 0x61, 0x10, 0x26, 0x02, 0x68, 0x23, 0xfb, - 0x10, 0x06, 0x01, 0xe6, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x66, - 0xff, 0xe3, 0x04, 0x50, 0x07, 0x6b, 0x10, 0x27, 0x0c, 0xbf, 0x00, 0x5a, - 0x01, 0x75, 0x10, 0x06, 0x00, 0x2a, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, - 0xfe, 0x48, 0x04, 0x12, 0x06, 0x66, 0x10, 0x26, 0x00, 0x76, 0x00, 0x00, - 0x10, 0x06, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x3d, - 0xff, 0xe3, 0x04, 0x94, 0x05, 0xd5, 0x00, 0x1d, 0x00, 0x00, 0x25, 0x32, - 0x37, 0x36, 0x19, 0x01, 0x33, 0x11, 0x10, 0x07, 0x06, 0x23, 0x22, 0x27, - 0x26, 0x11, 0x35, 0x21, 0x11, 0x23, 0x11, 0x33, 0x11, 0x21, 0x11, 0x33, - 0x11, 0x10, 0x17, 0x16, 0x03, 0x6d, 0x36, 0x19, 0x21, 0xb6, 0x68, 0x39, - 0x85, 0x80, 0x48, 0x86, 0xfe, 0xd5, 0xb6, 0xb6, 0x01, 0x2b, 0xb7, 0x52, - 0x17, 0x87, 0x4f, 0x66, 0x01, 0x0e, 0x01, 0x27, 0xfe, 0xc0, 0xfe, 0x8b, - 0x8c, 0x4d, 0x53, 0x99, 0x01, 0x62, 0x96, 0xfd, 0x39, 0x05, 0xd5, 0xfd, - 0x9c, 0x02, 0x64, 0xfc, 0x75, 0xfe, 0xef, 0x8b, 0x27, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x8b, 0x00, 0x00, 0x04, 0x46, 0x07, 0x6b, 0x10, 0x27, - 0x0c, 0xc1, 0x00, 0x00, 0x01, 0x75, 0x10, 0x06, 0x00, 0x31, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0x00, 0x00, 0x04, 0x1b, 0x06, 0x66, 0x10, 0x26, - 0x00, 0x43, 0x00, 0x00, 0x10, 0x06, 0x00, 0x51, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x04, 0x9c, 0x07, 0x6b, 0x10, 0x27, - 0x0c, 0xbf, 0x00, 0xf0, 0x01, 0x75, 0x10, 0x06, 0x00, 0x88, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x29, 0xff, 0xe3, 0x04, 0xb0, 0x06, 0x66, 0x10, 0x26, - 0x00, 0x76, 0x00, 0x00, 0x10, 0x06, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x08, 0xff, 0xba, 0x04, 0xb0, 0x07, 0x6b, 0x10, 0x27, - 0x0c, 0xbf, 0x00, 0x00, 0x01, 0x75, 0x10, 0x06, 0x00, 0x9a, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x2f, 0xff, 0xa0, 0x04, 0x96, 0x06, 0x66, 0x10, 0x26, - 0x00, 0x76, 0x00, 0x00, 0x10, 0x06, 0x00, 0xba, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, 0x07, 0x6b, 0x10, 0x26, - 0x0c, 0xc9, 0x00, 0x00, 0x10, 0x06, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x85, 0xff, 0xe3, 0x04, 0x23, 0x06, 0x66, 0x10, 0x26, - 0x02, 0x97, 0x00, 0x00, 0x10, 0x06, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, 0x07, 0x6d, 0x10, 0x26, - 0x0c, 0xc5, 0x00, 0x00, 0x10, 0x06, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x85, 0xff, 0xe3, 0x04, 0x23, 0x06, 0x48, 0x10, 0x26, - 0x02, 0x99, 0x00, 0x00, 0x10, 0x06, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xbb, 0x00, 0x00, 0x04, 0x4e, 0x07, 0x6b, 0x10, 0x26, - 0x0c, 0xc9, 0x00, 0x00, 0x10, 0x06, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x7b, 0xff, 0xe3, 0x04, 0x58, 0x06, 0x66, 0x10, 0x26, - 0x02, 0x97, 0x0e, 0x00, 0x10, 0x06, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc5, 0x00, 0x00, 0x04, 0x4e, 0x07, 0x6d, 0x10, 0x26, - 0x0c, 0xc5, 0x00, 0x00, 0x10, 0x06, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x7b, 0xff, 0xe3, 0x04, 0x58, 0x06, 0x48, 0x10, 0x26, - 0x02, 0x99, 0x0e, 0x00, 0x10, 0x06, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xbb, 0x00, 0x00, 0x04, 0x06, 0x07, 0x6b, 0x10, 0x26, - 0x0c, 0xc9, 0x00, 0x00, 0x10, 0x06, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xb2, 0x00, 0x00, 0x04, 0x44, 0x06, 0x66, 0x10, 0x26, - 0x02, 0x97, 0x00, 0x00, 0x10, 0x06, 0x00, 0xf3, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc9, 0x00, 0x00, 0x04, 0x06, 0x07, 0x6d, 0x10, 0x26, - 0x0c, 0xc5, 0x00, 0x00, 0x10, 0x06, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xb2, 0x00, 0x00, 0x04, 0x44, 0x06, 0x48, 0x10, 0x26, - 0x02, 0x99, 0x00, 0x00, 0x10, 0x06, 0x00, 0xf3, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x75, 0xff, 0xe3, 0x04, 0x5c, 0x07, 0x6b, 0x10, 0x26, - 0x0c, 0xc9, 0x00, 0x00, 0x10, 0x06, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, 0x06, 0x66, 0x10, 0x26, - 0x02, 0x97, 0x00, 0x00, 0x10, 0x06, 0x00, 0x52, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x75, 0xff, 0xe3, 0x04, 0x5c, 0x07, 0x6d, 0x10, 0x26, - 0x0c, 0xc5, 0x00, 0x00, 0x10, 0x06, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, 0x06, 0x48, 0x10, 0x26, - 0x02, 0x99, 0x00, 0x00, 0x10, 0x06, 0x00, 0x52, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x89, 0x00, 0x00, 0x04, 0xd1, 0x07, 0x6b, 0x10, 0x26, - 0x0c, 0xc9, 0xce, 0x00, 0x10, 0x06, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x68, 0x00, 0x00, 0x04, 0x83, 0x06, 0x66, 0x10, 0x27, - 0x02, 0x97, 0x00, 0x96, 0x00, 0x00, 0x10, 0x06, 0x00, 0x55, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x8f, 0x00, 0x00, 0x04, 0xd1, 0x07, 0x6d, 0x10, 0x26, - 0x0c, 0xc5, 0xce, 0x00, 0x10, 0x06, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x6a, 0x00, 0x00, 0x04, 0x83, 0x06, 0x48, 0x10, 0x27, - 0x02, 0x99, 0x00, 0x96, 0x00, 0x00, 0x10, 0x06, 0x00, 0x55, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x93, 0xff, 0xe3, 0x04, 0x3d, 0x07, 0x6b, 0x10, 0x26, - 0x0c, 0xc9, 0x00, 0x00, 0x10, 0x06, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xff, 0xe3, 0x04, 0x1b, 0x06, 0x66, 0x10, 0x26, - 0x02, 0x97, 0x00, 0x00, 0x10, 0x06, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x93, 0xff, 0xe3, 0x04, 0x3d, 0x07, 0x6d, 0x10, 0x26, - 0x0c, 0xc5, 0x00, 0x00, 0x10, 0x06, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xff, 0xe3, 0x04, 0x1b, 0x06, 0x48, 0x10, 0x26, - 0x02, 0x99, 0x00, 0x00, 0x10, 0x06, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x8b, 0xfd, 0xe2, 0x04, 0x4a, 0x05, 0xf0, 0x10, 0x26, - 0x02, 0xae, 0x00, 0x00, 0x10, 0x06, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xd5, 0xfd, 0xe2, 0x04, 0x06, 0x04, 0x7b, 0x10, 0x26, - 0x02, 0xae, 0x00, 0x00, 0x10, 0x06, 0x00, 0x56, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x2f, 0xfd, 0xe2, 0x04, 0xa2, 0x05, 0xd5, 0x10, 0x26, - 0x02, 0xae, 0x00, 0x00, 0x10, 0x06, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x83, 0xfd, 0xe2, 0x04, 0x08, 0x05, 0x9e, 0x10, 0x26, - 0x02, 0xae, 0x59, 0x00, 0x10, 0x06, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x7d, 0xfe, 0x52, 0x04, 0x54, 0x05, 0xf0, 0x00, 0x2e, - 0x00, 0x00, 0x01, 0x04, 0x11, 0x14, 0x0e, 0x01, 0x0c, 0x01, 0x07, 0x35, - 0x36, 0x24, 0x3e, 0x01, 0x35, 0x34, 0x26, 0x23, 0x22, 0x0f, 0x01, 0x35, - 0x37, 0x3e, 0x03, 0x35, 0x34, 0x2e, 0x03, 0x23, 0x22, 0x07, 0x35, 0x36, - 0x33, 0x32, 0x1e, 0x01, 0x15, 0x14, 0x0e, 0x02, 0x03, 0x20, 0x01, 0x34, - 0x6f, 0xb9, 0xff, 0x00, 0xfe, 0xea, 0x99, 0xc8, 0x01, 0x31, 0xb9, 0x5c, - 0x7d, 0x70, 0x5f, 0x73, 0xa3, 0xf8, 0x3c, 0x66, 0x68, 0x3d, 0x23, 0x37, - 0x4b, 0x48, 0x26, 0xb8, 0xf3, 0xef, 0xce, 0x83, 0xcb, 0x7c, 0x17, 0x3a, - 0x6e, 0x02, 0xa2, 0x43, 0xfe, 0xdb, 0x70, 0xce, 0xa0, 0x88, 0x60, 0x22, - 0xa0, 0x37, 0x8c, 0x99, 0x9d, 0x4f, 0x65, 0x84, 0x33, 0x48, 0xab, 0x6a, - 0x1a, 0x41, 0x63, 0x8b, 0x52, 0x37, 0x56, 0x33, 0x22, 0x0c, 0xb8, 0xbe, - 0xa4, 0x56, 0xb6, 0x80, 0x3c, 0x66, 0x71, 0x74, 0x00, 0x01, 0x00, 0xae, - 0xfe, 0x4f, 0x04, 0x23, 0x04, 0x7b, 0x00, 0x34, 0x00, 0x00, 0x01, 0x1e, - 0x03, 0x15, 0x14, 0x0e, 0x05, 0x07, 0x35, 0x3e, 0x04, 0x35, 0x34, 0x26, - 0x23, 0x22, 0x0f, 0x01, 0x35, 0x37, 0x3e, 0x04, 0x35, 0x34, 0x2e, 0x03, - 0x23, 0x22, 0x06, 0x07, 0x35, 0x24, 0x33, 0x32, 0x1e, 0x01, 0x15, 0x14, - 0x06, 0x03, 0x0e, 0x46, 0x70, 0x3e, 0x21, 0x42, 0x6c, 0x98, 0x9d, 0xb3, - 0x95, 0x4a, 0xa2, 0xf5, 0x9e, 0x63, 0x28, 0x76, 0x5d, 0x3b, 0x3f, 0xd8, - 0xdf, 0x22, 0x41, 0x57, 0x3f, 0x2d, 0x1f, 0x31, 0x43, 0x41, 0x23, 0x45, - 0xa8, 0x93, 0x01, 0x0a, 0x86, 0x70, 0xb8, 0x74, 0x67, 0x01, 0xcd, 0x08, - 0x44, 0x5a, 0x58, 0x25, 0x4b, 0x8a, 0x6c, 0x61, 0x46, 0x3d, 0x27, 0x0f, - 0x82, 0x2e, 0x60, 0x5b, 0x62, 0x5b, 0x33, 0x58, 0x70, 0x19, 0x56, 0x8b, - 0x55, 0x0d, 0x20, 0x3c, 0x45, 0x66, 0x39, 0x2c, 0x46, 0x2a, 0x1b, 0x0a, - 0x3b, 0x5a, 0x9a, 0x85, 0x47, 0x92, 0x61, 0x6e, 0x99, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x89, 0x00, 0x00, 0x04, 0x48, 0x07, 0x6d, 0x10, 0x27, - 0x0c, 0xc3, 0x00, 0x00, 0x01, 0x75, 0x10, 0x06, 0x00, 0x2b, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0x00, 0x00, 0x04, 0x1b, 0x07, 0x6d, 0x10, 0x27, - 0x0c, 0xc3, 0x00, 0x00, 0x01, 0x75, 0x10, 0x06, 0x00, 0x4b, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x93, 0xfe, 0x52, 0x04, 0x3d, 0x05, 0xf2, 0x00, 0x13, - 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, - 0x11, 0x23, 0x11, 0x33, 0x15, 0x3e, 0x01, 0x33, 0x32, 0x12, 0x04, 0x3d, - 0xcb, 0x74, 0x7c, 0x8d, 0x98, 0xca, 0xca, 0x36, 0xb8, 0x7e, 0xbb, 0xb9, - 0x03, 0xe7, 0xfa, 0x6b, 0x05, 0x9f, 0xb4, 0xa9, 0xda, 0xcb, 0xfc, 0x57, - 0x05, 0xd5, 0xc6, 0x6f, 0x74, 0xfe, 0xfb, 0x00, 0x00, 0x03, 0x00, 0x12, - 0xff, 0x6c, 0x04, 0x9f, 0x06, 0x14, 0x00, 0x06, 0x00, 0x28, 0x00, 0x31, - 0x00, 0x00, 0x25, 0x16, 0x37, 0x32, 0x37, 0x36, 0x22, 0x27, 0x14, 0x17, - 0x36, 0x37, 0x36, 0x15, 0x10, 0x23, 0x22, 0x27, 0x06, 0x07, 0x23, 0x37, - 0x26, 0x2f, 0x01, 0x06, 0x07, 0x06, 0x27, 0x26, 0x27, 0x26, 0x11, 0x10, - 0x12, 0x33, 0x32, 0x16, 0x17, 0x11, 0x33, 0x00, 0x10, 0x16, 0x32, 0x36, - 0x35, 0x34, 0x26, 0x22, 0x03, 0x6d, 0x0c, 0x42, 0x7b, 0x03, 0x04, 0x80, - 0xa9, 0x0d, 0x72, 0x68, 0xa4, 0xfa, 0x47, 0x30, 0x1e, 0x14, 0x77, 0x44, - 0x20, 0x26, 0x10, 0x1c, 0x38, 0x4d, 0x64, 0xa3, 0x5c, 0x5d, 0xbb, 0xa1, - 0x50, 0x7b, 0x23, 0xb8, 0xfd, 0x99, 0x6c, 0xd4, 0x6f, 0x6f, 0xd4, 0x90, - 0x12, 0x01, 0x9b, 0x3e, 0x3e, 0x74, 0x23, 0xf4, 0x01, 0x02, 0xda, 0xfe, - 0xc7, 0x11, 0x4f, 0x39, 0xc2, 0x0d, 0x59, 0x25, 0x5a, 0x35, 0x48, 0x01, - 0x02, 0x9b, 0x9e, 0x01, 0x15, 0x01, 0x11, 0x01, 0x37, 0x57, 0x53, 0x02, - 0x43, 0xfc, 0xf1, 0xfe, 0x54, 0xda, 0xdc, 0xd4, 0xd5, 0xdb, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x9c, 0xfe, 0x56, 0x04, 0x92, 0x05, 0xd5, 0x00, 0x17, - 0x00, 0x00, 0x13, 0x21, 0x15, 0x01, 0x21, 0x15, 0x33, 0x15, 0x14, 0x07, - 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x37, 0x36, 0x3d, 0x01, 0x21, 0x35, - 0x01, 0x21, 0xb2, 0x03, 0xc9, 0xfc, 0xf4, 0x03, 0x22, 0x01, 0x59, 0x5a, - 0xa5, 0xcd, 0xb9, 0x5a, 0x2d, 0x2c, 0xfc, 0xc3, 0x02, 0xf7, 0xfd, 0x1f, - 0x05, 0xd5, 0x9a, 0xfb, 0x6f, 0x2a, 0x94, 0xc3, 0x69, 0x6a, 0x9c, 0x3e, - 0x3e, 0x7e, 0x14, 0x9a, 0x04, 0x91, 0x00, 0x00, 0x00, 0x01, 0x00, 0xcb, - 0xfe, 0x56, 0x04, 0x10, 0x04, 0x62, 0x00, 0x17, 0x00, 0x00, 0x13, 0x21, - 0x15, 0x01, 0x21, 0x15, 0x23, 0x15, 0x14, 0x07, 0x06, 0x2b, 0x01, 0x35, - 0x33, 0x32, 0x37, 0x36, 0x3d, 0x01, 0x21, 0x35, 0x01, 0x21, 0xe3, 0x03, - 0x2d, 0xfd, 0x7d, 0x02, 0x83, 0x08, 0x59, 0x5a, 0xa5, 0xcd, 0xb9, 0x5a, - 0x2d, 0x2c, 0xfd, 0x7c, 0x02, 0x83, 0xfd, 0x95, 0x04, 0x62, 0xa8, 0xfc, - 0xdc, 0x96, 0x14, 0xc3, 0x69, 0x6a, 0x9c, 0x3e, 0x3e, 0x7e, 0x14, 0xaa, - 0x03, 0x25, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, - 0x07, 0x50, 0x10, 0x26, 0x0c, 0xc7, 0x00, 0x00, 0x10, 0x06, 0x00, 0x24, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x85, 0xff, 0xe3, 0x04, 0x23, - 0x06, 0x10, 0x10, 0x26, 0x02, 0x8f, 0x00, 0x00, 0x10, 0x06, 0x00, 0x44, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc5, 0xfe, 0x75, 0x04, 0x4e, - 0x05, 0xd5, 0x10, 0x26, 0x02, 0xaf, 0x32, 0x00, 0x10, 0x06, 0x00, 0x28, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, 0xfe, 0x75, 0x04, 0x58, - 0x04, 0x7b, 0x10, 0x26, 0x02, 0xaf, 0x32, 0x00, 0x10, 0x06, 0x00, 0x48, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x75, 0xff, 0xe3, 0x04, 0x5c, - 0x07, 0xa0, 0x10, 0x27, 0x0c, 0xbe, 0x00, 0x00, 0x00, 0xf9, 0x10, 0x27, - 0x02, 0x6a, 0x00, 0x00, 0x01, 0xaa, 0x10, 0x06, 0x00, 0x32, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, 0x07, 0x32, 0x10, 0x27, - 0x00, 0x71, 0x00, 0x00, 0x01, 0x3c, 0x10, 0x06, 0x00, 0xb8, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x75, 0xff, 0xe3, 0x04, 0x5c, 0x07, 0xa0, 0x10, 0x26, - 0x00, 0x32, 0x00, 0x00, 0x10, 0x27, 0x0c, 0xc0, 0x00, 0x00, 0x00, 0xf5, - 0x10, 0x07, 0x02, 0x6a, 0x00, 0x00, 0x01, 0xaa, 0xff, 0xff, 0x00, 0x89, - 0xff, 0xe3, 0x04, 0x48, 0x07, 0x32, 0x10, 0x27, 0x00, 0x71, 0x00, 0x04, - 0x01, 0x3c, 0x10, 0x06, 0x00, 0xb7, 0x00, 0x00, 0xff, 0xff, 0x00, 0x75, - 0xff, 0xe3, 0x04, 0x5c, 0x07, 0x50, 0x10, 0x26, 0x0c, 0xc7, 0x00, 0x00, - 0x10, 0x06, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, - 0xff, 0xe3, 0x04, 0x48, 0x06, 0x10, 0x10, 0x26, 0x02, 0x8f, 0x00, 0x00, - 0x10, 0x06, 0x00, 0x52, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x75, - 0xff, 0xe3, 0x04, 0x5c, 0x07, 0xa0, 0x10, 0x27, 0x02, 0x6a, 0x00, 0x00, - 0x01, 0xaa, 0x10, 0x26, 0x0c, 0xc7, 0x00, 0x84, 0x10, 0x06, 0x00, 0x32, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, - 0x07, 0x32, 0x10, 0x27, 0x00, 0x71, 0x00, 0x00, 0x01, 0x3c, 0x10, 0x06, - 0x01, 0xde, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, - 0x07, 0x30, 0x10, 0x26, 0x0c, 0xcb, 0x00, 0x00, 0x10, 0x06, 0x00, 0x3c, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x68, 0xfe, 0x56, 0x04, 0x81, - 0x05, 0xf6, 0x10, 0x26, 0x02, 0x8c, 0x00, 0x00, 0x10, 0x06, 0x00, 0x5c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xa0, 0xff, 0x6c, 0x04, 0x0a, - 0x06, 0x1f, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x00, 0x25, 0x16, 0x37, 0x32, - 0x37, 0x36, 0x22, 0x03, 0x06, 0x07, 0x23, 0x37, 0x26, 0x27, 0x26, 0x35, - 0x11, 0x21, 0x35, 0x21, 0x11, 0x14, 0x17, 0x36, 0x37, 0x36, 0x15, 0x10, - 0x23, 0x22, 0x02, 0xd8, 0x0c, 0x42, 0x7b, 0x03, 0x04, 0x80, 0x90, 0x1d, - 0x14, 0x77, 0x44, 0x13, 0x33, 0x27, 0xfe, 0xd9, 0x01, 0xdf, 0x0d, 0x72, - 0x68, 0xa4, 0xfa, 0x46, 0x90, 0x12, 0x01, 0x9b, 0x3e, 0xfe, 0x9c, 0x4f, - 0x39, 0xc2, 0x05, 0x61, 0x4a, 0xb8, 0x03, 0xf9, 0x90, 0xfb, 0x77, 0x74, - 0x23, 0xf4, 0x01, 0x02, 0xda, 0xfe, 0xc7, 0x00, 0x00, 0x02, 0x00, 0x6a, - 0xff, 0x6c, 0x04, 0x66, 0x04, 0x7b, 0x00, 0x06, 0x00, 0x2e, 0x00, 0x00, - 0x25, 0x16, 0x37, 0x32, 0x37, 0x36, 0x22, 0x27, 0x14, 0x17, 0x36, 0x37, - 0x36, 0x17, 0x14, 0x15, 0x10, 0x07, 0x22, 0x27, 0x06, 0x07, 0x23, 0x37, - 0x26, 0x27, 0x26, 0x3d, 0x01, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x11, - 0x23, 0x11, 0x33, 0x15, 0x3e, 0x01, 0x33, 0x32, 0x17, 0x16, 0x11, 0x03, - 0x34, 0x0c, 0x42, 0x7b, 0x03, 0x04, 0x80, 0xb9, 0x16, 0x7a, 0x67, 0x9f, - 0x05, 0xfa, 0x47, 0x31, 0x1d, 0x14, 0x77, 0x44, 0x13, 0x33, 0x27, 0x35, - 0x5a, 0x49, 0x39, 0xa7, 0xa7, 0x21, 0x63, 0x3f, 0x85, 0x39, 0x38, 0x90, - 0x12, 0x01, 0x9b, 0x3e, 0x3e, 0x72, 0x2e, 0xfc, 0x02, 0x02, 0xce, 0x06, - 0x06, 0xfe, 0xc8, 0x01, 0x11, 0x4f, 0x39, 0xc2, 0x05, 0x61, 0x4a, 0xb8, - 0xeb, 0xed, 0x73, 0x7b, 0xe5, 0xfd, 0x7f, 0x04, 0x60, 0x60, 0x3c, 0x3f, - 0x69, 0x65, 0xfe, 0xdc, 0x00, 0x02, 0x00, 0x83, 0xff, 0x6c, 0x04, 0x08, - 0x05, 0x9e, 0x00, 0x06, 0x00, 0x23, 0x00, 0x00, 0x25, 0x16, 0x37, 0x32, - 0x37, 0x36, 0x22, 0x27, 0x14, 0x17, 0x36, 0x37, 0x36, 0x15, 0x10, 0x23, - 0x22, 0x27, 0x06, 0x07, 0x23, 0x37, 0x26, 0x27, 0x26, 0x35, 0x11, 0x21, - 0x35, 0x21, 0x11, 0x33, 0x11, 0x21, 0x15, 0x21, 0x02, 0xbf, 0x0c, 0x42, - 0x7b, 0x03, 0x04, 0x80, 0xa9, 0x0d, 0x72, 0x68, 0xa4, 0xfa, 0x47, 0x30, - 0x1e, 0x14, 0x77, 0x44, 0x13, 0x33, 0x27, 0xfe, 0xd5, 0x01, 0x2b, 0xb8, - 0x01, 0xa2, 0xfe, 0x5e, 0x90, 0x12, 0x01, 0x9b, 0x3e, 0x3e, 0x74, 0x23, - 0xf4, 0x01, 0x02, 0xda, 0xfe, 0xc7, 0x11, 0x4f, 0x39, 0xc2, 0x05, 0x61, - 0x4a, 0xb8, 0x02, 0x3b, 0x8f, 0x01, 0x3e, 0xfe, 0xc2, 0x8f, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xba, 0xfe, 0x56, 0x03, 0x10, 0x04, 0x60, 0x00, 0x0d, - 0x00, 0x2c, 0x40, 0x16, 0x05, 0x00, 0x01, 0x0a, 0x8c, 0x08, 0x01, 0xb6, - 0x03, 0xc2, 0x08, 0xc3, 0x0e, 0x0b, 0x08, 0x02, 0x09, 0x02, 0x04, 0x06, - 0x00, 0x0e, 0x10, 0xd4, 0xec, 0xc4, 0xc4, 0x12, 0x39, 0x39, 0x31, 0x00, - 0x10, 0xe4, 0xf4, 0xee, 0x10, 0xee, 0x11, 0x39, 0x39, 0x30, 0x05, 0x11, - 0x21, 0x35, 0x21, 0x11, 0x14, 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x36, - 0x02, 0x58, 0xfe, 0xc3, 0x01, 0xf5, 0xb3, 0xa5, 0xfe, 0xea, 0x5a, 0x5a, - 0x14, 0x03, 0xe5, 0x8f, 0xfb, 0x8c, 0xc3, 0xd3, 0x9c, 0x7d, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x78, 0xff, 0xe3, 0x04, 0x59, 0x06, 0x14, 0x00, 0x08, - 0x00, 0x13, 0x00, 0x31, 0x00, 0x00, 0x12, 0x10, 0x16, 0x32, 0x36, 0x35, - 0x34, 0x26, 0x22, 0x00, 0x10, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, - 0x33, 0x32, 0x03, 0x3e, 0x01, 0x33, 0x32, 0x12, 0x11, 0x10, 0x02, 0x23, - 0x22, 0x26, 0x27, 0x15, 0x23, 0x35, 0x0e, 0x01, 0x23, 0x22, 0x02, 0x11, - 0x10, 0x12, 0x33, 0x32, 0x16, 0x17, 0x11, 0x33, 0xed, 0x51, 0xa0, 0x53, - 0x53, 0xa0, 0x02, 0xa6, 0x51, 0x50, 0x51, 0x52, 0x52, 0x51, 0x50, 0xf3, - 0x1a, 0x5d, 0x3d, 0x7a, 0x8b, 0x8c, 0x7a, 0x3c, 0x5c, 0x1b, 0x6f, 0x1b, - 0x5c, 0x3c, 0x7a, 0x8c, 0x8d, 0x79, 0x3c, 0x5d, 0x1a, 0x6f, 0x03, 0x05, - 0xfe, 0x54, 0xda, 0xdc, 0xd4, 0xd5, 0xdb, 0xfd, 0x7a, 0x01, 0xac, 0xda, - 0xdb, 0xd5, 0xd4, 0xdc, 0x03, 0x52, 0x52, 0x58, 0xfe, 0xc9, 0xfe, 0xef, - 0xfe, 0xeb, 0xfe, 0xc5, 0x57, 0x53, 0x8d, 0x8d, 0x53, 0x57, 0x01, 0x3b, - 0x01, 0x15, 0x01, 0x11, 0x01, 0x37, 0x57, 0x53, 0x02, 0x43, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x78, 0xfe, 0x4a, 0x04, 0x59, 0x04, 0x7b, 0x00, 0x08, - 0x00, 0x13, 0x00, 0x31, 0x00, 0x00, 0x00, 0x10, 0x26, 0x22, 0x06, 0x15, - 0x14, 0x16, 0x32, 0x00, 0x10, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, - 0x23, 0x22, 0x13, 0x0e, 0x01, 0x23, 0x22, 0x02, 0x11, 0x10, 0x12, 0x33, - 0x32, 0x16, 0x17, 0x35, 0x33, 0x15, 0x3e, 0x01, 0x33, 0x32, 0x12, 0x11, - 0x10, 0x02, 0x23, 0x22, 0x26, 0x27, 0x11, 0x23, 0x03, 0xe4, 0x51, 0xa0, - 0x53, 0x53, 0xa0, 0xfd, 0x5a, 0x51, 0x50, 0x50, 0x53, 0x53, 0x50, 0x50, - 0xf3, 0x1a, 0x5d, 0x3d, 0x79, 0x8c, 0x8c, 0x7a, 0x3c, 0x5c, 0x1b, 0x6f, - 0x1b, 0x5c, 0x3c, 0x7a, 0x8c, 0x8d, 0x79, 0x3d, 0x5c, 0x1a, 0x6f, 0x01, - 0x59, 0x01, 0xac, 0xda, 0xdc, 0xd4, 0xd5, 0xdb, 0x02, 0x86, 0xfe, 0x54, - 0xda, 0xdb, 0xd5, 0xd4, 0xdc, 0xfc, 0xae, 0x52, 0x58, 0x01, 0x37, 0x01, - 0x11, 0x01, 0x15, 0x01, 0x3b, 0x57, 0x53, 0x8d, 0x8d, 0x53, 0x57, 0xfe, - 0xc5, 0xfe, 0xeb, 0xfe, 0xef, 0xfe, 0xc9, 0x57, 0x53, 0xfd, 0xbd, 0x00, - 0x00, 0x03, 0x00, 0x08, 0xff, 0xba, 0x04, 0xb0, 0x06, 0x17, 0x00, 0x0f, - 0x00, 0x12, 0x00, 0x15, 0x00, 0x00, 0x01, 0x33, 0x13, 0x01, 0x17, 0x09, - 0x01, 0x23, 0x03, 0x21, 0x0f, 0x01, 0x23, 0x07, 0x27, 0x37, 0x01, 0x21, - 0x03, 0x27, 0x0b, 0x01, 0x01, 0xee, 0xf5, 0x60, 0x01, 0x09, 0x64, 0xfe, - 0xc1, 0x01, 0x3b, 0xd1, 0x6e, 0xfe, 0x43, 0x82, 0x38, 0x56, 0x31, 0x67, - 0x34, 0x01, 0xe6, 0x01, 0x1b, 0x51, 0x2b, 0x59, 0xcf, 0x05, 0xd5, 0xfe, - 0xc7, 0x01, 0x7b, 0x4a, 0xfe, 0x38, 0xfb, 0xfb, 0x01, 0x85, 0xba, 0xcb, - 0x46, 0x46, 0x4a, 0x01, 0xdd, 0x01, 0x21, 0x9b, 0x01, 0x40, 0xfd, 0x19, - 0x00, 0x02, 0x00, 0x08, 0xff, 0xba, 0x04, 0xb0, 0x06, 0x17, 0x00, 0x08, - 0x00, 0x29, 0x00, 0x00, 0x09, 0x01, 0x27, 0x26, 0x23, 0x22, 0x02, 0x11, - 0x14, 0x01, 0x0e, 0x01, 0x23, 0x20, 0x2f, 0x01, 0x07, 0x27, 0x13, 0x26, - 0x11, 0x10, 0x00, 0x21, 0x32, 0x17, 0x16, 0x17, 0x37, 0x17, 0x07, 0x15, - 0x26, 0x27, 0x01, 0x16, 0x17, 0x16, 0x33, 0x32, 0x36, 0x37, 0x01, 0x70, - 0x02, 0x34, 0x12, 0x55, 0x56, 0xc5, 0xc4, 0x02, 0xd3, 0x4d, 0xa2, 0x5b, - 0xfe, 0xe1, 0x9e, 0x09, 0xb2, 0x67, 0xd4, 0x51, 0x01, 0x3f, 0x01, 0x1d, - 0x5b, 0x51, 0x3b, 0x38, 0x46, 0x64, 0x7f, 0x10, 0x11, 0xfd, 0x8b, 0x10, - 0x15, 0x62, 0xc5, 0x58, 0xa9, 0x49, 0x02, 0x02, 0x03, 0x24, 0x06, 0x20, - 0xfe, 0xd0, 0xfe, 0xcd, 0x7e, 0xfd, 0xca, 0x29, 0x29, 0xcb, 0x0b, 0xff, - 0x46, 0x01, 0x2f, 0xb3, 0x01, 0x07, 0x01, 0x6e, 0x01, 0x99, 0x14, 0x0f, - 0x1a, 0x64, 0x4a, 0xb5, 0x49, 0x0d, 0x0c, 0xfc, 0x7e, 0x27, 0x20, 0x98, - 0x40, 0x3d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x2f, 0xff, 0xa0, 0x04, 0x96, - 0x04, 0xbc, 0x00, 0x07, 0x00, 0x28, 0x00, 0x00, 0x09, 0x01, 0x26, 0x23, - 0x22, 0x06, 0x15, 0x14, 0x01, 0x0e, 0x01, 0x23, 0x20, 0x2f, 0x01, 0x07, - 0x27, 0x13, 0x26, 0x35, 0x10, 0x00, 0x21, 0x32, 0x17, 0x16, 0x17, 0x37, - 0x17, 0x07, 0x15, 0x26, 0x27, 0x01, 0x16, 0x17, 0x16, 0x33, 0x32, 0x36, - 0x37, 0x01, 0x95, 0x01, 0xdc, 0x3e, 0x47, 0xad, 0xba, 0x02, 0xa0, 0x4a, - 0x9d, 0x52, 0xfe, 0xfc, 0x92, 0x08, 0xc3, 0x5c, 0xd8, 0x44, 0x01, 0x25, - 0x01, 0x04, 0x51, 0x4d, 0x28, 0x28, 0x5f, 0x5d, 0x71, 0x22, 0x21, 0xfd, - 0xe4, 0x0d, 0x0f, 0x5e, 0xac, 0x60, 0x98, 0x41, 0x01, 0x96, 0x02, 0x37, - 0x12, 0xe0, 0xd0, 0x53, 0xfe, 0x5d, 0x2b, 0x2b, 0x9c, 0x09, 0xe8, 0x4c, - 0x01, 0x02, 0x84, 0xbd, 0x01, 0x14, 0x01, 0x38, 0x15, 0x0b, 0x11, 0x72, - 0x4d, 0x86, 0x85, 0x1e, 0x16, 0xfd, 0x7f, 0x15, 0x12, 0x71, 0x3b, 0x3e, - 0x00, 0x01, 0x00, 0x15, 0x00, 0x00, 0x04, 0xbc, 0x05, 0xd5, 0x00, 0x0d, - 0x00, 0x00, 0x01, 0x33, 0x11, 0x21, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, - 0x11, 0x21, 0x35, 0x21, 0x01, 0x20, 0xcb, 0x01, 0x07, 0xfe, 0xf9, 0x02, - 0xd1, 0xfc, 0x64, 0xfe, 0xf5, 0x01, 0x0b, 0x05, 0xd5, 0xfd, 0x16, 0xaa, - 0xfe, 0x69, 0xaa, 0x02, 0x41, 0xaa, 0x00, 0x00, 0x00, 0x02, 0x00, 0x21, - 0xff, 0xba, 0x04, 0xc9, 0x06, 0x17, 0x00, 0x02, 0x00, 0x12, 0x00, 0x00, - 0x01, 0x13, 0x23, 0x03, 0x11, 0x21, 0x35, 0x21, 0x37, 0x17, 0x07, 0x15, - 0x23, 0x01, 0x11, 0x23, 0x11, 0x01, 0x27, 0x02, 0xcd, 0xf3, 0xf3, 0xcb, - 0xfe, 0x2d, 0x04, 0x08, 0x2e, 0x64, 0x27, 0x4a, 0xfe, 0x75, 0xcb, 0xfe, - 0x86, 0x67, 0x03, 0xd0, 0x01, 0x5b, 0xfd, 0x84, 0x02, 0x7c, 0xaa, 0x42, - 0x4a, 0x38, 0x6a, 0xfd, 0xcd, 0xfd, 0x08, 0x01, 0xd6, 0xfd, 0xe4, 0x46, - 0x00, 0x01, 0x00, 0xd5, 0xfe, 0x10, 0x04, 0x19, 0x04, 0x7b, 0x00, 0x35, - 0x00, 0x00, 0x01, 0x15, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, - 0x1f, 0x01, 0x1e, 0x01, 0x15, 0x14, 0x07, 0x06, 0x07, 0x1f, 0x01, 0x16, - 0x33, 0x15, 0x23, 0x22, 0x27, 0x26, 0x2f, 0x01, 0x26, 0x2f, 0x01, 0x35, - 0x36, 0x17, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x2f, 0x02, 0x26, 0x27, - 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x03, 0xcd, 0x4f, 0xa0, 0x53, - 0x7d, 0x7b, 0x5c, 0xb7, 0x4a, 0x89, 0x8d, 0x76, 0x68, 0xb0, 0x98, 0x93, - 0x2a, 0x4c, 0x27, 0x54, 0x72, 0x47, 0x59, 0xed, 0x33, 0x65, 0x32, 0x7b, - 0x7a, 0x44, 0x3e, 0x7a, 0x86, 0xf5, 0x08, 0x45, 0xa1, 0x47, 0x49, 0xda, - 0xca, 0x5a, 0xa6, 0x04, 0x39, 0xb4, 0x2e, 0x2e, 0x51, 0x53, 0x4b, 0x4a, - 0x23, 0x0e, 0x1a, 0x9c, 0x7d, 0xa6, 0x5e, 0x52, 0x0a, 0x98, 0x7e, 0x24, - 0x9a, 0x3d, 0x26, 0x5b, 0xf3, 0x35, 0x23, 0x10, 0xbe, 0x05, 0x60, 0x0f, - 0x63, 0x59, 0x80, 0x31, 0x02, 0x0e, 0x21, 0x47, 0x4a, 0x7f, 0xa1, 0xaf, - 0x21, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xcb, 0xfe, 0x10, 0x04, 0x10, - 0x04, 0x62, 0x00, 0x17, 0x00, 0x00, 0x13, 0x21, 0x15, 0x01, 0x16, 0x17, - 0x01, 0x17, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, 0x26, 0x2f, 0x01, - 0x26, 0x23, 0x3d, 0x01, 0x01, 0x21, 0xe3, 0x03, 0x2d, 0xfd, 0x6a, 0x31, - 0x20, 0x01, 0x08, 0x93, 0x2a, 0x4c, 0x34, 0x5b, 0x54, 0x72, 0x47, 0x59, - 0xed, 0x3d, 0x5a, 0x02, 0x83, 0xfd, 0x95, 0x04, 0x62, 0xa8, 0xfc, 0xcb, - 0x11, 0x20, 0xfe, 0xf8, 0x7e, 0x24, 0x9a, 0x3d, 0x26, 0x5b, 0xf3, 0x3f, - 0x9c, 0x0e, 0x03, 0x25, 0x00, 0x01, 0x00, 0x37, 0x00, 0x00, 0x04, 0x9a, - 0x05, 0xd5, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x22, 0x07, 0x06, 0x1d, 0x01, - 0x23, 0x35, 0x34, 0x36, 0x33, 0x21, 0x32, 0x04, 0x15, 0x14, 0x04, 0x23, - 0x11, 0x23, 0x11, 0x33, 0x32, 0x36, 0x10, 0x26, 0x23, 0x01, 0x76, 0x36, - 0x3c, 0x30, 0x9c, 0xc0, 0x7e, 0x01, 0x27, 0xfa, 0x01, 0x02, 0xfe, 0xff, - 0xfb, 0xca, 0xca, 0x8c, 0x9d, 0x9c, 0x8d, 0x05, 0x2f, 0x2f, 0x26, 0x72, - 0x31, 0x46, 0xb5, 0xa3, 0xe3, 0xdb, 0xdd, 0xe2, 0xfd, 0xa8, 0x02, 0xfe, - 0x94, 0x01, 0x0a, 0x93, 0x00, 0x03, 0x00, 0x08, 0x00, 0x00, 0x04, 0x71, - 0x05, 0xd5, 0x00, 0x12, 0x00, 0x1b, 0x00, 0x28, 0x00, 0x00, 0x13, 0x21, - 0x32, 0x16, 0x15, 0x14, 0x06, 0x07, 0x1e, 0x01, 0x15, 0x14, 0x04, 0x29, - 0x01, 0x11, 0x23, 0x35, 0x33, 0x13, 0x11, 0x33, 0x32, 0x36, 0x35, 0x34, - 0x26, 0x23, 0x03, 0x15, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x2b, 0x01, - 0x15, 0x33, 0x15, 0xa6, 0x01, 0xba, 0xe5, 0xf8, 0x83, 0x83, 0x93, 0xa7, - 0xfe, 0xf6, 0xfe, 0xf9, 0xfe, 0x46, 0x9e, 0x9e, 0xcb, 0xeb, 0x92, 0x83, - 0x81, 0x94, 0xeb, 0xef, 0xb0, 0x96, 0x9e, 0xa8, 0xef, 0xeb, 0x05, 0xd5, - 0xc6, 0xb5, 0x89, 0x9e, 0x14, 0x16, 0xcf, 0xa0, 0xcb, 0xcf, 0x01, 0x6e, - 0x95, 0x03, 0x2c, 0xfe, 0x3e, 0x70, 0x7d, 0x71, 0x64, 0xfc, 0x3f, 0xc8, - 0x7b, 0x8d, 0x92, 0x89, 0xc6, 0x95, 0x00, 0x00, 0x00, 0x02, 0x00, 0x15, - 0xff, 0xe3, 0x04, 0xbc, 0x05, 0xd5, 0x00, 0x1a, 0x00, 0x29, 0x00, 0x00, - 0x13, 0x35, 0x33, 0x11, 0x33, 0x11, 0x21, 0x11, 0x33, 0x11, 0x33, 0x15, - 0x23, 0x15, 0x14, 0x06, 0x07, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x27, 0x2e, - 0x01, 0x3d, 0x01, 0x29, 0x01, 0x15, 0x14, 0x16, 0x17, 0x1e, 0x01, 0x33, - 0x32, 0x36, 0x37, 0x3e, 0x01, 0x35, 0x15, 0x7e, 0xcb, 0x02, 0x15, 0xca, - 0x7f, 0x7f, 0x39, 0x46, 0x42, 0xaa, 0x6a, 0x69, 0xaa, 0x43, 0x45, 0x3a, - 0x02, 0xe0, 0xfd, 0xeb, 0x0c, 0x0f, 0x20, 0x79, 0x56, 0x57, 0x78, 0x21, - 0x0f, 0x0c, 0x02, 0x41, 0xaa, 0x02, 0xea, 0xfd, 0x16, 0x02, 0xea, 0xfd, - 0x16, 0xaa, 0x04, 0xe5, 0xc1, 0x3f, 0x3b, 0x3a, 0x3a, 0x3b, 0x3e, 0xc5, - 0xe2, 0x04, 0x60, 0x6d, 0x5d, 0x19, 0x3b, 0x3c, 0x3c, 0x3b, 0x19, 0x5c, - 0x6c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x39, 0x00, 0x00, 0x04, 0x98, - 0x05, 0xd5, 0x00, 0x06, 0x00, 0x00, 0x09, 0x01, 0x23, 0x01, 0x33, 0x01, - 0x23, 0x02, 0x69, 0xfe, 0xa1, 0xd1, 0x01, 0xb5, 0xf5, 0x01, 0xb5, 0xd1, - 0x05, 0x2b, 0xfa, 0xd5, 0x05, 0xd5, 0xfa, 0x2b, 0x00, 0x02, 0x00, 0x15, - 0x00, 0x00, 0x04, 0xd1, 0x05, 0xd5, 0x00, 0x18, 0x00, 0x21, 0x00, 0x00, - 0x13, 0x21, 0x32, 0x04, 0x15, 0x14, 0x06, 0x07, 0x16, 0x17, 0x16, 0x17, - 0x13, 0x23, 0x03, 0x2e, 0x01, 0x2b, 0x01, 0x11, 0x23, 0x11, 0x23, 0x35, - 0x33, 0x13, 0x11, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0xe3, 0x01, - 0x4c, 0xf6, 0x01, 0x06, 0xa1, 0x92, 0x4e, 0x37, 0x36, 0x53, 0xcb, 0xd9, - 0xb2, 0x4d, 0x7b, 0x63, 0x6d, 0xcb, 0xce, 0xce, 0xcb, 0x89, 0x91, 0x8e, - 0x97, 0x90, 0x05, 0xd5, 0xde, 0xd2, 0x94, 0xbb, 0x15, 0x14, 0x37, 0x37, - 0xa7, 0xfe, 0x68, 0x01, 0x79, 0xa1, 0x5d, 0xfd, 0x89, 0x02, 0x77, 0xa6, - 0x02, 0x12, 0xfd, 0xee, 0x82, 0x86, 0x81, 0x89, 0x00, 0x01, 0x00, 0x8e, - 0x00, 0x00, 0x04, 0x83, 0x04, 0x7b, 0x00, 0x19, 0x00, 0x00, 0x01, 0x2e, - 0x01, 0x23, 0x22, 0x07, 0x06, 0x07, 0x21, 0x15, 0x21, 0x11, 0x23, 0x11, - 0x23, 0x35, 0x33, 0x11, 0x33, 0x15, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x17, - 0x04, 0x83, 0x3b, 0x7a, 0x49, 0xac, 0x5b, 0x4d, 0x0c, 0x02, 0x01, 0xfd, - 0xfd, 0xb9, 0xdc, 0xdc, 0xb9, 0x2e, 0xbf, 0x83, 0x44, 0x76, 0x36, 0x03, - 0x79, 0x2e, 0x2a, 0x6c, 0x5c, 0xa1, 0xa4, 0xfe, 0x3c, 0x01, 0xc4, 0xa4, - 0x01, 0xf8, 0xdb, 0x77, 0x7f, 0x22, 0x24, 0x00, 0x00, 0x02, 0x00, 0x9a, - 0xff, 0xe3, 0x04, 0x38, 0x04, 0x7b, 0x00, 0x0b, 0x00, 0x29, 0x00, 0x00, - 0x01, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x1d, 0x01, - 0x07, 0x11, 0x33, 0x15, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, - 0x2b, 0x01, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x15, 0x0e, 0x01, - 0x23, 0x22, 0x26, 0x27, 0x2e, 0x01, 0x01, 0xfe, 0x3e, 0xa0, 0xa4, 0x7a, - 0x6c, 0x98, 0xb0, 0xb8, 0xb8, 0x3c, 0xb2, 0x80, 0xac, 0xcc, 0xfc, 0xf2, - 0xf8, 0x88, 0x92, 0x5e, 0xc0, 0x5c, 0x66, 0xbc, 0x58, 0x8a, 0xc6, 0x3c, - 0x26, 0x20, 0x02, 0x2b, 0x71, 0x70, 0x65, 0x70, 0xd3, 0xba, 0x29, 0x4c, - 0x02, 0x7f, 0xa6, 0x64, 0x5f, 0xc1, 0xa2, 0xbb, 0xc2, 0x1d, 0x86, 0x79, - 0x36, 0x34, 0xb8, 0x27, 0x27, 0x52, 0x52, 0x32, 0x93, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x7b, 0xff, 0xe3, 0x04, 0x12, 0x04, 0x7b, 0x00, 0x10, - 0x00, 0x1c, 0x00, 0x30, 0x40, 0x1a, 0x05, 0x00, 0x14, 0x1a, 0x8c, 0x0e, - 0x14, 0x8c, 0x08, 0x99, 0x0e, 0xbe, 0x01, 0xc2, 0x03, 0x17, 0x04, 0x00, - 0x06, 0x02, 0x47, 0x11, 0x12, 0x0b, 0x48, 0x1d, 0x10, 0xf4, 0xec, 0xfc, - 0xec, 0x32, 0x32, 0x31, 0x00, 0x2f, 0xec, 0xe4, 0xf4, 0xec, 0x10, 0xee, - 0x11, 0x39, 0x39, 0x30, 0x01, 0x35, 0x33, 0x11, 0x23, 0x35, 0x0e, 0x01, - 0x23, 0x22, 0x02, 0x11, 0x10, 0x12, 0x33, 0x32, 0x16, 0x01, 0x14, 0x16, - 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x03, 0x5a, 0xb8, - 0xb8, 0x2e, 0x99, 0x64, 0xcb, 0xe9, 0xea, 0xca, 0x65, 0x9a, 0xfe, 0x0f, - 0x88, 0x85, 0x85, 0x8b, 0x8b, 0x85, 0x85, 0x88, 0x03, 0xd1, 0x8d, 0xfb, - 0xa2, 0x8d, 0x53, 0x57, 0x01, 0x3b, 0x01, 0x15, 0x01, 0x11, 0x01, 0x37, - 0x57, 0xfe, 0x0b, 0xd6, 0xda, 0xdc, 0xd4, 0xd5, 0xdb, 0xda, 0x00, 0x00, - 0x00, 0x02, 0x00, 0xc0, 0xff, 0xe1, 0x04, 0x57, 0x04, 0x79, 0x00, 0x0b, - 0x00, 0x1c, 0x00, 0x30, 0x40, 0x1a, 0x18, 0x0c, 0x09, 0x03, 0x8c, 0x0f, - 0x09, 0x8c, 0x15, 0x99, 0x0f, 0xbe, 0x1b, 0xc2, 0x19, 0x00, 0x12, 0x12, - 0x47, 0x18, 0x0c, 0x06, 0x06, 0x1a, 0x46, 0x1d, 0x10, 0xf4, 0xec, 0x32, - 0x32, 0xfc, 0xec, 0x31, 0x00, 0x2f, 0xec, 0xe4, 0xf4, 0xec, 0x10, 0xee, - 0x11, 0x39, 0x39, 0x30, 0x01, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, - 0x16, 0x33, 0x32, 0x36, 0x01, 0x3e, 0x01, 0x33, 0x32, 0x12, 0x11, 0x10, - 0x02, 0x23, 0x22, 0x26, 0x27, 0x15, 0x23, 0x11, 0x33, 0x03, 0x95, 0x88, - 0x85, 0x85, 0x8b, 0x8b, 0x85, 0x85, 0x88, 0xfd, 0xe3, 0x2e, 0x99, 0x64, - 0xcb, 0xe9, 0xea, 0xca, 0x65, 0x9a, 0x2c, 0xb8, 0xb8, 0x02, 0x2d, 0xd6, - 0xda, 0xdc, 0xd4, 0xd5, 0xdb, 0xda, 0x02, 0x78, 0x53, 0x57, 0xfe, 0xc5, - 0xfe, 0xeb, 0xfe, 0xef, 0xfe, 0xc9, 0x57, 0x53, 0x8b, 0x04, 0x5e, 0x00, - 0x00, 0x02, 0x00, 0xc1, 0xff, 0xe3, 0x04, 0x58, 0x06, 0x14, 0x00, 0x0b, - 0x00, 0x24, 0x00, 0x39, 0x40, 0x1f, 0x03, 0x8c, 0x0c, 0x0f, 0x09, 0x8c, - 0x18, 0x15, 0x99, 0x0f, 0xbe, 0x19, 0x21, 0x8c, 0x1e, 0x9b, 0x19, 0x00, - 0x12, 0x12, 0x47, 0x1e, 0x21, 0x1f, 0x18, 0x0c, 0x06, 0x06, 0x1a, 0x46, - 0x25, 0x10, 0xfc, 0xec, 0x32, 0x32, 0xc4, 0x39, 0x39, 0xf4, 0xec, 0x31, - 0x00, 0x2f, 0xfc, 0xec, 0x10, 0xe4, 0xf4, 0xc4, 0xec, 0x10, 0xc6, 0xee, - 0x30, 0x01, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, - 0x36, 0x01, 0x3e, 0x01, 0x33, 0x32, 0x12, 0x11, 0x10, 0x02, 0x23, 0x22, - 0x26, 0x27, 0x15, 0x23, 0x11, 0x34, 0x36, 0x3b, 0x01, 0x15, 0x23, 0x22, - 0x06, 0x15, 0x03, 0x96, 0x88, 0x85, 0x86, 0x8a, 0x8a, 0x86, 0x85, 0x88, - 0xfd, 0xe3, 0x2c, 0x9b, 0x66, 0xca, 0xe8, 0xe9, 0xcb, 0x64, 0x99, 0x2e, - 0xb8, 0xb3, 0xa5, 0xcc, 0xb8, 0x5a, 0x5a, 0x02, 0x2f, 0xd6, 0xda, 0xdb, - 0xd5, 0xd4, 0xdc, 0xda, 0x02, 0x78, 0x52, 0x58, 0xfe, 0xc9, 0xfe, 0xef, - 0xfe, 0xeb, 0xfe, 0xc5, 0x57, 0x53, 0x8d, 0x04, 0x7e, 0xc3, 0xd3, 0x9c, - 0x7d, 0x7d, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb8, 0xff, 0xe3, 0x04, 0x1a, - 0x04, 0x7b, 0x00, 0x19, 0x00, 0x30, 0x40, 0x06, 0x13, 0x12, 0x06, 0x00, - 0x0c, 0x1a, 0x10, 0xdc, 0x3c, 0xd4, 0xec, 0x31, 0x00, 0x40, 0x13, 0x00, - 0x8b, 0x19, 0xc0, 0x16, 0x0c, 0x8b, 0x0d, 0xc0, 0x10, 0x8c, 0x09, 0x16, - 0x8c, 0x03, 0xbe, 0x09, 0x99, 0x1a, 0x10, 0xe4, 0xf4, 0xec, 0x10, 0xfe, - 0xf4, 0xee, 0x10, 0xf5, 0xee, 0x30, 0x13, 0x3e, 0x01, 0x33, 0x20, 0x00, - 0x11, 0x10, 0x00, 0x21, 0x22, 0x26, 0x27, 0x35, 0x1e, 0x01, 0x33, 0x32, - 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0xb8, 0x4a, 0x9c, 0x52, - 0x01, 0x04, 0x01, 0x26, 0xfe, 0xda, 0xfe, 0xfc, 0x50, 0x9a, 0x4e, 0x48, - 0x94, 0x5c, 0xae, 0xba, 0xbc, 0xac, 0x60, 0x98, 0x40, 0x04, 0x25, 0x2b, - 0x2b, 0xfe, 0xc8, 0xfe, 0xec, 0xfe, 0xec, 0xfe, 0xc8, 0x2a, 0x2c, 0xc1, - 0x41, 0x3a, 0xe0, 0xd0, 0xcf, 0xe1, 0x3b, 0x3e, 0x00, 0x02, 0x00, 0xc3, - 0xff, 0x73, 0x04, 0x3a, 0x04, 0x7b, 0x00, 0x21, 0x00, 0x29, 0x00, 0x00, - 0x05, 0x34, 0x37, 0x26, 0x27, 0x26, 0x11, 0x10, 0x00, 0x21, 0x32, 0x16, - 0x17, 0x15, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, - 0x36, 0x33, 0x20, 0x15, 0x14, 0x21, 0x22, 0x27, 0x06, 0x15, 0x13, 0x16, - 0x33, 0x32, 0x35, 0x34, 0x23, 0x22, 0x01, 0xb4, 0x0d, 0x39, 0x30, 0x95, - 0x01, 0x25, 0x01, 0x04, 0x51, 0x9a, 0x4e, 0x49, 0x93, 0x5d, 0xad, 0xba, - 0x63, 0x07, 0x06, 0x55, 0xc3, 0x01, 0x2d, 0xfe, 0xb2, 0x52, 0x47, 0x06, - 0x2b, 0x3c, 0x4a, 0x92, 0x84, 0x65, 0x8d, 0x68, 0x51, 0x23, 0x33, 0xa1, - 0x01, 0x0c, 0x01, 0x14, 0x01, 0x38, 0x2a, 0x2c, 0xc1, 0x41, 0x3a, 0xe0, - 0xd0, 0xdc, 0x63, 0x07, 0x07, 0xb0, 0xf6, 0xbd, 0x11, 0x39, 0x44, 0x01, - 0x1f, 0x13, 0x39, 0x4b, 0x00, 0x02, 0x00, 0x7b, 0xfe, 0x56, 0x04, 0x38, - 0x06, 0x14, 0x00, 0x08, 0x00, 0x24, 0x00, 0x00, 0x00, 0x10, 0x16, 0x32, - 0x36, 0x35, 0x34, 0x26, 0x22, 0x05, 0x11, 0x33, 0x11, 0x14, 0x17, 0x16, - 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, 0x26, 0x3d, 0x01, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x02, 0x11, 0x10, 0x12, 0x33, 0x32, 0x16, 0x01, 0x3c, 0x6d, - 0xd5, 0x70, 0x70, 0xd5, 0x01, 0x45, 0xb5, 0x23, 0x24, 0x48, 0x06, 0x38, - 0x84, 0x48, 0x47, 0x25, 0x3d, 0x3d, 0x50, 0xb4, 0xcf, 0xd0, 0xb3, 0x51, - 0x7b, 0x03, 0x05, 0xfe, 0x54, 0xda, 0xdc, 0xd4, 0xd5, 0xdb, 0x0e, 0x02, - 0x43, 0xf9, 0xd8, 0x7e, 0x3e, 0x3e, 0x9c, 0x6a, 0x69, 0xc3, 0xa1, 0x53, - 0x2c, 0x2b, 0x01, 0x3b, 0x01, 0x15, 0x01, 0x11, 0x01, 0x37, 0x57, 0x00, - 0x00, 0x02, 0x00, 0x7b, 0xff, 0xe3, 0x04, 0x37, 0x06, 0x14, 0x00, 0x0a, - 0x00, 0x26, 0x00, 0x00, 0x00, 0x10, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, - 0x26, 0x23, 0x22, 0x25, 0x35, 0x34, 0x37, 0x36, 0x3b, 0x01, 0x15, 0x23, - 0x22, 0x07, 0x06, 0x15, 0x11, 0x23, 0x35, 0x0e, 0x01, 0x23, 0x22, 0x02, - 0x11, 0x10, 0x12, 0x33, 0x32, 0x16, 0x17, 0x01, 0x3b, 0x6d, 0x6a, 0x6b, - 0x6f, 0x6f, 0x6b, 0x6a, 0x01, 0x44, 0x47, 0x48, 0x84, 0x38, 0x05, 0x48, - 0x24, 0x23, 0xb7, 0x24, 0x7b, 0x50, 0xb4, 0xce, 0xcf, 0xb3, 0x51, 0x7b, - 0x23, 0x03, 0x05, 0xfe, 0x54, 0xda, 0xdc, 0xd4, 0xd5, 0xdb, 0x0b, 0x94, - 0xc3, 0x69, 0x6a, 0x9c, 0x3e, 0x3e, 0x7e, 0xfb, 0x82, 0x8d, 0x53, 0x57, - 0x01, 0x3b, 0x01, 0x15, 0x01, 0x11, 0x01, 0x37, 0x57, 0x53, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x7a, 0xff, 0xe3, 0x04, 0x57, 0x04, 0x7b, 0x00, 0x15, - 0x00, 0x1c, 0x00, 0x00, 0x13, 0x34, 0x12, 0x33, 0x32, 0x00, 0x11, 0x10, - 0x00, 0x21, 0x22, 0x26, 0x27, 0x35, 0x1e, 0x01, 0x33, 0x32, 0x36, 0x3d, - 0x01, 0x21, 0x37, 0x21, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x7a, 0xf7, 0xd6, - 0xf0, 0x01, 0x20, 0xfe, 0xda, 0xfe, 0xfb, 0x5b, 0xc3, 0x69, 0x6d, 0xc0, - 0x58, 0xae, 0xbf, 0xfc, 0xe3, 0xb8, 0x02, 0x5e, 0x10, 0xac, 0x85, 0x88, - 0x95, 0x02, 0x5e, 0xfb, 0x01, 0x22, 0xfe, 0xc0, 0xfe, 0xf4, 0xfe, 0xed, - 0xfe, 0xc7, 0x2b, 0x2b, 0xb7, 0x39, 0x38, 0xc8, 0xb7, 0x06, 0x8f, 0x9c, - 0xb0, 0xaa, 0x00, 0x00, 0x00, 0x02, 0x00, 0x7a, 0xff, 0xe3, 0x04, 0x57, - 0x04, 0x7b, 0x00, 0x15, 0x00, 0x1c, 0x00, 0x3f, 0x40, 0x0c, 0x03, 0x02, - 0x1c, 0x12, 0x10, 0x49, 0x09, 0x16, 0x06, 0x00, 0x48, 0x1d, 0x10, 0xf4, - 0xec, 0xc4, 0xf4, 0xec, 0x39, 0x39, 0x31, 0x00, 0x40, 0x16, 0x00, 0x16, - 0x03, 0x01, 0x0a, 0x8b, 0x09, 0x8d, 0x06, 0x8c, 0x0d, 0xbe, 0x1d, 0x16, - 0xb6, 0x01, 0xc1, 0x19, 0x8c, 0x13, 0x99, 0x1d, 0x10, 0xf4, 0xec, 0xf4, - 0xee, 0x10, 0xf4, 0xf4, 0xf4, 0xee, 0x12, 0x39, 0x11, 0x39, 0x30, 0x13, - 0x35, 0x21, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, - 0x33, 0x20, 0x00, 0x11, 0x10, 0x00, 0x23, 0x22, 0x02, 0x37, 0x14, 0x16, - 0x33, 0x32, 0x36, 0x37, 0x7a, 0x03, 0x1d, 0xbf, 0xae, 0x58, 0xc0, 0x6d, - 0x69, 0xc3, 0x5b, 0x01, 0x05, 0x01, 0x26, 0xfe, 0xe0, 0xf0, 0xd6, 0xf7, - 0xb8, 0x95, 0x88, 0x85, 0xac, 0x10, 0x02, 0x00, 0x5a, 0x06, 0xb7, 0xc8, - 0x38, 0x39, 0xb7, 0x2b, 0x2b, 0xfe, 0xc7, 0xfe, 0xed, 0xfe, 0xf4, 0xfe, - 0xc0, 0x01, 0x22, 0xc6, 0xa2, 0xaa, 0xb0, 0x9c, 0x00, 0x02, 0x00, 0x1e, - 0xff, 0xe3, 0x04, 0xb3, 0x04, 0x7b, 0x00, 0x09, 0x00, 0x29, 0x00, 0x00, - 0x25, 0x36, 0x35, 0x34, 0x27, 0x01, 0x16, 0x17, 0x16, 0x32, 0x03, 0x32, - 0x17, 0x37, 0x33, 0x15, 0x14, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x26, - 0x35, 0x07, 0x16, 0x15, 0x10, 0x02, 0x20, 0x27, 0x26, 0x27, 0x01, 0x26, - 0x27, 0x26, 0x20, 0x07, 0x35, 0x36, 0x02, 0x42, 0x4c, 0x07, 0xfe, 0x2b, - 0x17, 0x19, 0x3e, 0xe7, 0x97, 0xfc, 0x77, 0x9a, 0x8c, 0x39, 0x50, 0x21, - 0x31, 0x84, 0x81, 0x6a, 0x17, 0xe2, 0xfe, 0x94, 0x63, 0x47, 0x14, 0x02, - 0x46, 0x0f, 0x14, 0x3a, 0xfe, 0xc2, 0x93, 0x9a, 0xd6, 0x8a, 0xcf, 0x3e, - 0x38, 0xfe, 0x9c, 0x45, 0x23, 0x5a, 0x03, 0xfc, 0xe8, 0x75, 0x94, 0x99, - 0x61, 0x9c, 0xba, 0xc8, 0x51, 0x60, 0x76, 0xfe, 0xed, 0xfe, 0xbd, 0x91, - 0x67, 0x9c, 0x01, 0xbb, 0x28, 0x22, 0x63, 0x68, 0xae, 0x56, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xa9, 0xff, 0xea, 0x04, 0x28, 0x04, 0x7b, 0x00, 0x30, - 0x00, 0x39, 0x40, 0x1f, 0x0b, 0x8c, 0x0c, 0x10, 0x8c, 0x07, 0xbe, 0x32, - 0x1b, 0xb6, 0x17, 0x32, 0x26, 0x8c, 0x25, 0x21, 0x8c, 0x2a, 0x99, 0x32, - 0x18, 0x0b, 0x26, 0x13, 0x12, 0x04, 0x1d, 0x12, 0x2e, 0x46, 0x31, 0x10, - 0xfc, 0xec, 0xd4, 0xec, 0xd4, 0xc4, 0xc4, 0x31, 0x00, 0x10, 0xf4, 0xec, - 0xd4, 0xec, 0x10, 0xd4, 0xec, 0x10, 0xf4, 0xec, 0xd4, 0xec, 0x30, 0x01, - 0x26, 0x27, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x15, - 0x26, 0x27, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x17, 0x16, 0x3b, 0x01, - 0x15, 0x23, 0x22, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, - 0x37, 0x15, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x36, - 0x01, 0xc1, 0x77, 0x41, 0x40, 0xf4, 0xd1, 0x51, 0x5b, 0x5c, 0x69, 0x68, - 0x57, 0x56, 0x4c, 0x8a, 0x94, 0x48, 0x48, 0x87, 0xa6, 0x9f, 0x96, 0xa8, - 0x5a, 0x5b, 0xad, 0x63, 0x5b, 0x5b, 0x4d, 0x61, 0x5a, 0x5b, 0x56, 0xfe, - 0x8b, 0x8a, 0x94, 0x02, 0x5f, 0x19, 0x41, 0x40, 0x5e, 0x86, 0x9e, 0x0c, - 0x0c, 0x18, 0xa7, 0x1b, 0x0d, 0x0c, 0x56, 0x4a, 0x3d, 0x2b, 0x2c, 0x90, - 0x6e, 0x51, 0x62, 0x35, 0x34, 0x12, 0x11, 0x22, 0xad, 0x1c, 0x0e, 0x0e, - 0x5b, 0x5c, 0xa6, 0x6d, 0x94, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xa9, - 0xff, 0xea, 0x04, 0x28, 0x04, 0x7b, 0x00, 0x28, 0x00, 0x3c, 0x40, 0x21, - 0x20, 0x8b, 0x1f, 0xc0, 0x1c, 0x8c, 0x23, 0xbe, 0x29, 0x00, 0x14, 0xb6, - 0x15, 0x29, 0x09, 0x8b, 0x0a, 0xc0, 0x0d, 0x8c, 0x06, 0x99, 0x29, 0x19, - 0x12, 0x26, 0x10, 0x12, 0x03, 0x15, 0x20, 0x0a, 0x29, 0x10, 0xdc, 0xc4, - 0xc4, 0xd4, 0xec, 0xd4, 0xec, 0x31, 0x00, 0x10, 0xf4, 0xfc, 0xfc, 0xec, - 0x10, 0xd4, 0xec, 0x39, 0x10, 0xf4, 0xfc, 0xfd, 0xee, 0x30, 0x01, 0x1e, - 0x01, 0x15, 0x14, 0x04, 0x23, 0x22, 0x26, 0x27, 0x35, 0x1e, 0x01, 0x33, - 0x32, 0x36, 0x35, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x36, 0x35, - 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x16, - 0x15, 0x14, 0x06, 0x03, 0x0f, 0x84, 0x95, 0xfe, 0xeb, 0xff, 0x55, 0xb6, - 0x60, 0x4c, 0xb6, 0x64, 0xad, 0xb5, 0xa9, 0x96, 0x9e, 0xa5, 0x88, 0x90, - 0x95, 0x8a, 0x4b, 0xad, 0x68, 0x69, 0xb7, 0x50, 0xd2, 0xf4, 0x82, 0x02, - 0x5f, 0x17, 0x94, 0x6d, 0xa6, 0xb7, 0x1c, 0x1c, 0xad, 0x22, 0x23, 0x69, - 0x62, 0x51, 0x6e, 0x90, 0x57, 0x3d, 0x4a, 0x56, 0x19, 0x1b, 0xa7, 0x18, - 0x18, 0x9e, 0x86, 0x5e, 0x81, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x38, - 0xff, 0xea, 0x04, 0x99, 0x04, 0x7b, 0x00, 0x42, 0x00, 0x00, 0x01, 0x16, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x26, 0x27, 0x35, 0x16, - 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x2b, 0x01, - 0x35, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, - 0x06, 0x07, 0x35, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x37, - 0x33, 0x15, 0x14, 0x17, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, 0x26, - 0x35, 0x07, 0x35, 0x07, 0x06, 0x02, 0x05, 0x63, 0x38, 0x38, 0x68, 0x68, - 0xbf, 0x40, 0x88, 0x48, 0x39, 0x44, 0x44, 0x4b, 0x82, 0x43, 0x45, 0x40, - 0x3f, 0x71, 0x76, 0x7c, 0x66, 0x36, 0x36, 0x38, 0x38, 0x68, 0x38, 0x41, - 0x41, 0x4e, 0x4f, 0x44, 0x45, 0x3c, 0x9e, 0x5b, 0x4b, 0x0e, 0xa9, 0x8a, - 0x1d, 0x1c, 0x4f, 0x20, 0x30, 0x83, 0x41, 0x3d, 0xd3, 0x05, 0x31, 0x02, - 0x5f, 0x17, 0x4a, 0x4a, 0x6d, 0xa6, 0x5c, 0x5b, 0x1c, 0x1c, 0xad, 0x22, - 0x11, 0x12, 0x34, 0x35, 0x62, 0x51, 0x37, 0x37, 0x90, 0x2c, 0x2b, 0x3d, - 0x4a, 0x2b, 0x2b, 0x0c, 0x0d, 0x1b, 0xa7, 0x18, 0x0c, 0x0c, 0x4f, 0x41, - 0x66, 0x83, 0x94, 0x99, 0x31, 0x30, 0x9c, 0x60, 0x5a, 0xc8, 0xa2, 0x01, - 0x06, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0xb0, 0xff, 0xd5, 0x04, 0x22, - 0x04, 0x79, 0x00, 0x14, 0x00, 0x28, 0x00, 0x00, 0x01, 0x20, 0x11, 0x10, - 0x21, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x2b, 0x01, 0x35, 0x33, - 0x32, 0x37, 0x36, 0x34, 0x26, 0x25, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, - 0x06, 0x07, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x23, 0x22, 0x27, 0x24, 0x11, - 0x10, 0x02, 0x9e, 0xfe, 0xad, 0x01, 0x53, 0x76, 0x3c, 0x3b, 0x3b, 0x21, - 0x8b, 0x88, 0x88, 0x8b, 0x21, 0x3b, 0x79, 0xfe, 0xb1, 0x55, 0xa1, 0xa0, - 0xc9, 0x6b, 0x62, 0x62, 0x6b, 0xcb, 0xa0, 0x9f, 0x55, 0xfe, 0xed, 0x03, - 0xd8, 0xfe, 0x5e, 0xfe, 0x41, 0x3b, 0x3b, 0x4c, 0x4c, 0x36, 0x1e, 0x9d, - 0x1e, 0x37, 0x9a, 0x73, 0x73, 0x2e, 0xad, 0x94, 0x67, 0x8e, 0x1b, 0x1c, - 0x8e, 0x67, 0x94, 0xae, 0x3d, 0xc2, 0x01, 0x58, 0x01, 0x8a, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xba, 0xfe, 0x56, 0x04, 0x71, 0x04, 0x5e, 0x00, 0x15, - 0x00, 0x00, 0x01, 0x15, 0x21, 0x11, 0x14, 0x06, 0x2b, 0x01, 0x35, 0x33, - 0x32, 0x36, 0x35, 0x11, 0x21, 0x35, 0x21, 0x11, 0x21, 0x35, 0x21, 0x11, - 0x04, 0x71, 0xfe, 0x9f, 0xb3, 0xa5, 0xfe, 0xea, 0x5a, 0x5a, 0xfe, 0x81, - 0x01, 0x7f, 0xfe, 0xc3, 0x01, 0xf5, 0x02, 0x68, 0xa4, 0xfe, 0x28, 0xc3, - 0xd3, 0x9c, 0x7d, 0x7d, 0x01, 0xd8, 0xa4, 0x01, 0x67, 0x8f, 0xfe, 0x0a, - 0x00, 0x02, 0x00, 0x7b, 0xfe, 0x48, 0x04, 0x34, 0x06, 0x14, 0x00, 0x26, - 0x00, 0x30, 0x00, 0x00, 0x01, 0x35, 0x34, 0x37, 0x36, 0x3b, 0x01, 0x15, - 0x23, 0x22, 0x07, 0x06, 0x15, 0x11, 0x14, 0x07, 0x06, 0x23, 0x22, 0x26, - 0x27, 0x35, 0x1e, 0x01, 0x33, 0x32, 0x36, 0x3d, 0x02, 0x0e, 0x01, 0x23, - 0x22, 0x02, 0x11, 0x34, 0x12, 0x33, 0x13, 0x11, 0x23, 0x22, 0x06, 0x10, - 0x16, 0x33, 0x32, 0x36, 0x02, 0xed, 0x48, 0x48, 0x86, 0x31, 0x1a, 0x3a, - 0x1d, 0x1c, 0x68, 0x68, 0xce, 0x3e, 0x86, 0x43, 0x4f, 0x82, 0x36, 0x78, - 0x6e, 0x23, 0x7b, 0x58, 0xae, 0xd0, 0xd0, 0xae, 0xf7, 0xd6, 0x6d, 0x73, - 0x73, 0x6e, 0x67, 0x6e, 0x04, 0x5e, 0x20, 0xc3, 0x69, 0x6a, 0x9c, 0x3e, - 0x3e, 0x7e, 0xfb, 0xca, 0xfb, 0x83, 0x82, 0x1c, 0x1b, 0xb6, 0x2e, 0x2c, - 0xa2, 0xb0, 0x08, 0x7d, 0x5e, 0x5c, 0x01, 0x3a, 0x01, 0x07, 0xe9, 0x01, - 0x3c, 0xfd, 0xdb, 0x01, 0xa7, 0xd8, 0xfe, 0x62, 0xd9, 0xda, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x9d, 0xfe, 0x48, 0x04, 0x34, 0x04, 0x5e, 0x00, 0x09, - 0x00, 0x24, 0x00, 0x00, 0x01, 0x11, 0x21, 0x22, 0x06, 0x10, 0x16, 0x33, - 0x32, 0x36, 0x13, 0x14, 0x02, 0x23, 0x22, 0x26, 0x27, 0x35, 0x1e, 0x01, - 0x33, 0x32, 0x36, 0x3d, 0x02, 0x0e, 0x01, 0x23, 0x22, 0x02, 0x11, 0x34, - 0x37, 0x36, 0x33, 0x21, 0x03, 0x7c, 0xfe, 0xf8, 0x87, 0x8e, 0x8f, 0x88, - 0x7f, 0x87, 0xb8, 0xee, 0xe7, 0x4c, 0xa6, 0x53, 0x62, 0xa0, 0x43, 0x95, - 0x88, 0x2c, 0x98, 0x6d, 0xc4, 0xea, 0x75, 0x71, 0xc8, 0x01, 0xe9, 0x02, - 0x39, 0x01, 0xa7, 0xd8, 0xfe, 0x62, 0xd9, 0xda, 0xfe, 0xdd, 0xfc, 0xfe, - 0xfc, 0x1c, 0x1b, 0xb6, 0x2e, 0x2c, 0xa2, 0xb0, 0x08, 0x7d, 0x5e, 0x5c, - 0x01, 0x3a, 0x01, 0x07, 0xe1, 0xa5, 0x9f, 0x00, 0x00, 0x01, 0x00, 0x7a, - 0x00, 0x00, 0x04, 0x58, 0x04, 0x98, 0x00, 0x20, 0x00, 0x00, 0x25, 0x11, - 0x23, 0x35, 0x21, 0x11, 0x06, 0x07, 0x06, 0x23, 0x22, 0x00, 0x11, 0x10, - 0x00, 0x21, 0x32, 0x17, 0x16, 0x17, 0x15, 0x26, 0x27, 0x26, 0x23, 0x22, - 0x07, 0x06, 0x10, 0x17, 0x16, 0x33, 0x32, 0x03, 0xb2, 0x9c, 0x01, 0x42, - 0x48, 0x58, 0x4e, 0xca, 0xfc, 0xfe, 0xd6, 0x01, 0x2c, 0x01, 0x06, 0x3e, - 0x68, 0x68, 0x80, 0x78, 0x70, 0x56, 0x48, 0xb2, 0x64, 0x62, 0x62, 0x64, - 0xb2, 0xae, 0xb2, 0x01, 0x1a, 0x8c, 0xfd, 0xf0, 0x22, 0x14, 0x12, 0x01, - 0x3e, 0x01, 0x0e, 0x01, 0x12, 0x01, 0x3a, 0x12, 0x11, 0x4b, 0xac, 0x4d, - 0x1b, 0x16, 0x72, 0x71, 0xfe, 0x66, 0x71, 0x72, 0x00, 0x02, 0x00, 0x66, - 0xfe, 0x51, 0x04, 0x6b, 0x04, 0x5e, 0x00, 0x12, 0x00, 0x1b, 0x00, 0x00, - 0x01, 0x00, 0x11, 0x14, 0x0e, 0x02, 0x22, 0x2e, 0x02, 0x35, 0x10, 0x09, - 0x01, 0x33, 0x09, 0x01, 0x33, 0x00, 0x32, 0x36, 0x35, 0x10, 0x03, 0x02, - 0x11, 0x14, 0x02, 0xe2, 0x01, 0x1c, 0x2b, 0x5d, 0x9f, 0xdc, 0x9e, 0x5e, - 0x2b, 0x01, 0x20, 0xfe, 0x72, 0xda, 0x01, 0x2e, 0x01, 0x24, 0xd8, 0xfd, - 0x87, 0xe3, 0x61, 0xcb, 0xdb, 0x02, 0x3c, 0xfe, 0x54, 0xfe, 0xb3, 0x38, - 0x56, 0x41, 0x22, 0x22, 0x41, 0x56, 0x38, 0x01, 0x54, 0x01, 0xac, 0x02, - 0x1b, 0xfe, 0x72, 0x01, 0x8e, 0xfa, 0x96, 0x4c, 0x45, 0x01, 0x22, 0x01, - 0x1d, 0xfe, 0xd0, 0xfe, 0xf1, 0x45, 0x00, 0x00, 0x00, 0x02, 0x00, 0x66, - 0x00, 0x00, 0x04, 0x6a, 0x04, 0x5e, 0x00, 0x0c, 0x00, 0x14, 0x00, 0x00, - 0x01, 0x16, 0x10, 0x21, 0x20, 0x35, 0x34, 0x37, 0x01, 0x33, 0x09, 0x01, - 0x33, 0x01, 0x06, 0x15, 0x14, 0x33, 0x32, 0x35, 0x34, 0x02, 0xd6, 0xb2, - 0xfe, 0xe3, 0xfe, 0xd1, 0xb8, 0xfe, 0x72, 0xda, 0x01, 0x28, 0x01, 0x2a, - 0xd8, 0xfd, 0xf6, 0x75, 0x7b, 0x71, 0x02, 0x3f, 0xf1, 0xfe, 0xb2, 0xa7, - 0xb1, 0xf2, 0x02, 0x14, 0xfe, 0x73, 0x01, 0x8d, 0xfd, 0x5a, 0x9e, 0x3b, - 0x68, 0x68, 0x3f, 0x00, 0x00, 0x01, 0x00, 0xbc, 0xfe, 0x52, 0x04, 0x15, - 0x04, 0x5e, 0x00, 0x13, 0x00, 0x00, 0x13, 0x11, 0x33, 0x11, 0x14, 0x16, - 0x33, 0x32, 0x36, 0x35, 0x11, 0x33, 0x11, 0x23, 0x11, 0x0e, 0x01, 0x23, - 0x22, 0x26, 0xbc, 0xb8, 0x6c, 0x70, 0x82, 0x8a, 0xb8, 0xb8, 0x32, 0xa8, - 0x72, 0xac, 0xa8, 0x01, 0xa8, 0x02, 0xb6, 0xfd, 0x4a, 0x97, 0x8e, 0xb7, - 0xab, 0x02, 0x79, 0xf9, 0xf4, 0x02, 0x56, 0x61, 0x64, 0xe1, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xc3, 0x00, 0x00, 0x04, 0x1b, 0x06, 0x14, 0x00, 0x1e, - 0x00, 0x00, 0x01, 0x07, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x15, 0x11, 0x23, - 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, 0x11, 0x35, 0x34, - 0x37, 0x36, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x06, 0x15, 0x01, 0x7d, 0x02, - 0x32, 0xa8, 0x72, 0xac, 0xa8, 0xb8, 0x6a, 0x72, 0x80, 0x8c, 0xb8, 0x5a, - 0x5a, 0xa4, 0xce, 0xba, 0x5a, 0x58, 0x03, 0xc2, 0x0a, 0x60, 0x63, 0xe1, - 0xe4, 0xfd, 0x4a, 0x02, 0xb6, 0x97, 0x8e, 0xb7, 0xab, 0xfd, 0x87, 0x03, - 0xea, 0x94, 0xc3, 0x69, 0x6a, 0x9c, 0x7c, 0x7e, 0x00, 0x01, 0x00, 0xc3, - 0xfe, 0x56, 0x04, 0x1b, 0x06, 0x14, 0x00, 0x28, 0x00, 0x00, 0x01, 0x07, - 0x3e, 0x01, 0x33, 0x32, 0x16, 0x15, 0x11, 0x14, 0x07, 0x06, 0x2b, 0x01, - 0x35, 0x33, 0x32, 0x37, 0x36, 0x35, 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, - 0x15, 0x11, 0x23, 0x11, 0x35, 0x34, 0x37, 0x36, 0x3b, 0x01, 0x15, 0x23, - 0x22, 0x06, 0x15, 0x01, 0x7d, 0x02, 0x31, 0xa9, 0x72, 0xab, 0xa9, 0x58, - 0x5b, 0xa5, 0xcc, 0xb8, 0x5b, 0x2d, 0x2c, 0x6a, 0x72, 0x80, 0x8c, 0xb8, - 0x5a, 0x5a, 0xa4, 0xce, 0xba, 0x5a, 0x58, 0x03, 0xc2, 0x0a, 0x60, 0x63, - 0xe1, 0xe4, 0xfd, 0x36, 0xc3, 0x69, 0x6a, 0x9c, 0x3e, 0x3e, 0x7e, 0x02, - 0xca, 0x97, 0x8e, 0xb7, 0xab, 0xfd, 0x87, 0x03, 0xea, 0x94, 0xc3, 0x69, - 0x6a, 0x9c, 0x7c, 0x7e, 0x00, 0x02, 0x00, 0x8e, 0x00, 0x00, 0x04, 0x32, - 0x06, 0x14, 0x00, 0x03, 0x00, 0x15, 0x00, 0x00, 0x01, 0x33, 0x15, 0x23, - 0x05, 0x21, 0x11, 0x21, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x35, 0x21, - 0x11, 0x21, 0x35, 0x21, 0x11, 0x21, 0x02, 0x0c, 0xb8, 0xb8, 0xfe, 0xe2, - 0x01, 0xd6, 0x01, 0x62, 0xfe, 0x9e, 0x01, 0x6e, 0xfc, 0x6e, 0x01, 0x6c, - 0xfe, 0x82, 0x01, 0x7e, 0xfe, 0xe2, 0x06, 0x14, 0xe9, 0xcd, 0xfe, 0x0a, - 0xa4, 0xfe, 0xcb, 0x8f, 0x8f, 0x01, 0x35, 0xa4, 0x01, 0x69, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xc6, 0x00, 0x00, 0x04, 0x0a, 0x04, 0x5e, 0x00, 0x0e, - 0x00, 0x00, 0x21, 0x23, 0x22, 0x27, 0x26, 0x35, 0x11, 0x21, 0x35, 0x21, - 0x11, 0x14, 0x16, 0x3b, 0x01, 0x04, 0x0a, 0xcc, 0xa6, 0x5a, 0x58, 0xfe, - 0xe0, 0x01, 0xd8, 0x58, 0x5a, 0xba, 0x6a, 0x66, 0xc6, 0x02, 0x3b, 0x8d, - 0xfd, 0x38, 0x7e, 0x7c, 0x00, 0x01, 0x00, 0xa0, 0x00, 0x00, 0x04, 0x32, - 0x04, 0x5e, 0x00, 0x0b, 0x00, 0x00, 0x13, 0x21, 0x15, 0x21, 0x11, 0x21, - 0x15, 0x21, 0x35, 0x21, 0x11, 0x21, 0xa0, 0x03, 0x92, 0xfe, 0x92, 0x01, - 0x6e, 0xfc, 0x6e, 0x01, 0x6c, 0xfe, 0x94, 0x04, 0x5e, 0x8d, 0xfc, 0xbe, - 0x8f, 0x8f, 0x03, 0x42, 0x00, 0x01, 0x00, 0x58, 0x00, 0x00, 0x04, 0x79, - 0x06, 0x1f, 0x00, 0x26, 0x00, 0x00, 0x01, 0x14, 0x17, 0x16, 0x3b, 0x01, - 0x15, 0x23, 0x22, 0x26, 0x3d, 0x01, 0x26, 0x23, 0x22, 0x06, 0x07, 0x35, - 0x3e, 0x01, 0x33, 0x32, 0x17, 0x11, 0x21, 0x35, 0x21, 0x11, 0x16, 0x33, - 0x32, 0x36, 0x37, 0x15, 0x0e, 0x01, 0x23, 0x22, 0x27, 0x02, 0x92, 0x2e, - 0x48, 0x3e, 0xd8, 0xea, 0xa4, 0xb6, 0x2e, 0x2f, 0x4f, 0x8d, 0x49, 0x4e, - 0x92, 0x53, 0x29, 0x26, 0xfe, 0xda, 0x01, 0xde, 0x72, 0x5c, 0x46, 0x89, - 0x4a, 0x4b, 0x8f, 0x4f, 0x55, 0x69, 0x01, 0x96, 0x93, 0x28, 0x3f, 0x9c, - 0xd4, 0xc2, 0xc6, 0x0a, 0x3b, 0x3f, 0xae, 0x3c, 0x36, 0x06, 0x02, 0x89, - 0x90, 0xfc, 0xa7, 0x35, 0x3d, 0x3e, 0xae, 0x3b, 0x37, 0x2d, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x9d, 0x00, 0x00, 0x04, 0x34, 0x06, 0x1f, 0x00, 0x19, - 0x00, 0x20, 0x00, 0x00, 0x01, 0x14, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, - 0x26, 0x3d, 0x01, 0x23, 0x20, 0x35, 0x34, 0x33, 0x32, 0x17, 0x11, 0x21, - 0x35, 0x21, 0x11, 0x33, 0x15, 0x23, 0x27, 0x26, 0x23, 0x22, 0x15, 0x14, - 0x33, 0x02, 0xaa, 0x5b, 0x59, 0xd6, 0xe8, 0xa5, 0xb5, 0x3e, 0xfe, 0xe9, - 0xf6, 0x35, 0x2a, 0xfe, 0xd9, 0x01, 0xdf, 0xfa, 0xfa, 0xb8, 0x17, 0x47, - 0x4e, 0x5c, 0x01, 0x96, 0x7c, 0x7e, 0x9c, 0xd4, 0xc2, 0xdc, 0xbd, 0xf6, - 0x19, 0x01, 0x83, 0x90, 0xfc, 0xf3, 0xa0, 0xa0, 0x84, 0x4b, 0x39, 0x00, - 0x00, 0x01, 0x00, 0xa0, 0xfe, 0x56, 0x04, 0x0a, 0x06, 0x1f, 0x00, 0x0d, - 0x00, 0x00, 0x05, 0x14, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x26, 0x35, - 0x11, 0x21, 0x35, 0x21, 0x02, 0x7f, 0x5b, 0x59, 0xd7, 0xe9, 0xa5, 0xb5, - 0xfe, 0xd9, 0x01, 0xdf, 0x14, 0x7c, 0x7e, 0x9c, 0xd4, 0xc2, 0x05, 0xa3, - 0x90, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x28, 0xfe, 0x4c, 0x04, 0xa8, - 0x06, 0x1f, 0x00, 0x2d, 0x00, 0x00, 0x01, 0x14, 0x16, 0x3b, 0x01, 0x15, - 0x23, 0x22, 0x26, 0x35, 0x11, 0x23, 0x35, 0x21, 0x11, 0x21, 0x15, 0x01, - 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x27, 0x26, - 0x27, 0x35, 0x1e, 0x01, 0x33, 0x32, 0x36, 0x35, 0x34, 0x27, 0x26, 0x2b, - 0x01, 0x35, 0x01, 0x21, 0x01, 0xa8, 0x48, 0x48, 0xac, 0xbb, 0x84, 0x91, - 0xec, 0x01, 0x80, 0x02, 0xba, 0xfe, 0xb7, 0x54, 0x67, 0x4f, 0x45, 0x40, - 0xf3, 0xe0, 0x4b, 0x4f, 0x50, 0x55, 0x43, 0xa0, 0x57, 0x98, 0xa0, 0x4a, - 0x4a, 0x84, 0x8c, 0x01, 0x58, 0xfd, 0xec, 0x01, 0x96, 0x7c, 0x7e, 0x9c, - 0xd4, 0xc2, 0x03, 0xf9, 0x90, 0xfe, 0x41, 0xa8, 0xfe, 0x24, 0x38, 0x2b, - 0x6c, 0x68, 0x8a, 0xdd, 0xf2, 0x12, 0x13, 0x25, 0xc3, 0x31, 0x32, 0x96, - 0x8f, 0x84, 0x4b, 0x4a, 0xa6, 0x01, 0xf3, 0x00, 0x00, 0x01, 0x00, 0x68, - 0x00, 0x00, 0x04, 0x6a, 0x04, 0x7b, 0x00, 0x21, 0x00, 0x00, 0x25, 0x0e, - 0x01, 0x23, 0x22, 0x26, 0x19, 0x01, 0x33, 0x11, 0x14, 0x16, 0x33, 0x32, - 0x36, 0x35, 0x11, 0x33, 0x11, 0x14, 0x16, 0x32, 0x36, 0x35, 0x11, 0x33, - 0x11, 0x23, 0x35, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x02, 0x32, 0x22, 0x68, - 0x4a, 0x88, 0x6e, 0xa8, 0x34, 0x46, 0x50, 0x3c, 0xa8, 0x38, 0x94, 0x38, - 0xa8, 0xa8, 0x20, 0x64, 0x3e, 0x4c, 0x66, 0x8d, 0x48, 0x45, 0xd1, 0x01, - 0x21, 0x02, 0x89, 0xfd, 0x7f, 0xed, 0x73, 0x7b, 0xe5, 0x02, 0x81, 0xfd, - 0x7f, 0xf0, 0x70, 0x7b, 0xe5, 0x02, 0x81, 0xfb, 0xa0, 0x60, 0x3c, 0x3f, - 0x46, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x68, 0xfe, 0x52, 0x04, 0x6a, - 0x04, 0x7b, 0x00, 0x21, 0x00, 0x00, 0x25, 0x0e, 0x01, 0x23, 0x22, 0x26, - 0x19, 0x01, 0x33, 0x11, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x11, 0x33, - 0x11, 0x14, 0x16, 0x32, 0x36, 0x35, 0x11, 0x33, 0x11, 0x23, 0x11, 0x0e, - 0x01, 0x23, 0x22, 0x26, 0x02, 0x32, 0x22, 0x68, 0x4a, 0x88, 0x6e, 0xa8, - 0x34, 0x46, 0x50, 0x3c, 0xa8, 0x38, 0x94, 0x38, 0xa8, 0xa8, 0x20, 0x64, - 0x3e, 0x4c, 0x66, 0x8d, 0x48, 0x45, 0xd1, 0x01, 0x21, 0x02, 0x89, 0xfd, - 0x7f, 0xed, 0x73, 0x7b, 0xe5, 0x02, 0x81, 0xfd, 0x7f, 0xf0, 0x70, 0x7b, - 0xe5, 0x02, 0x81, 0xf9, 0xd7, 0x02, 0x29, 0x3c, 0x3f, 0x46, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x67, 0xfe, 0x56, 0x04, 0x69, 0x04, 0x7b, 0x00, 0x2b, - 0x00, 0x00, 0x01, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x19, 0x01, 0x14, 0x06, - 0x2b, 0x01, 0x35, 0x33, 0x32, 0x36, 0x35, 0x11, 0x34, 0x26, 0x23, 0x22, - 0x06, 0x15, 0x11, 0x23, 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x11, - 0x23, 0x11, 0x33, 0x15, 0x3e, 0x01, 0x33, 0x32, 0x17, 0x16, 0x02, 0x9e, - 0x22, 0x69, 0x4a, 0x87, 0x6f, 0xa1, 0x96, 0xba, 0xa8, 0x53, 0x4e, 0x35, - 0x46, 0x50, 0x3b, 0xa8, 0x39, 0x4a, 0x49, 0x39, 0xa7, 0xa7, 0x21, 0x63, - 0x3f, 0x53, 0x2c, 0x35, 0x03, 0xee, 0x48, 0x45, 0xd1, 0xfe, 0xdf, 0xfd, - 0x63, 0xc2, 0xd4, 0x9c, 0x7c, 0x7e, 0x02, 0x95, 0xed, 0x73, 0x7b, 0xe5, - 0xfd, 0x7f, 0x02, 0x81, 0xf0, 0x70, 0x7b, 0xe5, 0xfd, 0x7f, 0x04, 0x5e, - 0x5e, 0x40, 0x3b, 0x23, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb2, - 0xfe, 0x56, 0x04, 0x4d, 0x04, 0x7b, 0x00, 0x1f, 0x00, 0x00, 0x05, 0x14, - 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x37, 0x36, 0x35, 0x11, 0x33, 0x15, - 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x11, 0x23, 0x11, 0x34, - 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x01, 0xea, 0x7b, 0x88, 0x35, 0x02, - 0x44, 0x1c, 0x1c, 0xba, 0x31, 0x44, 0x43, 0x57, 0xa8, 0x56, 0x56, 0xb9, - 0x5c, 0x5e, 0x6f, 0x41, 0x40, 0x14, 0xd6, 0xc0, 0x9c, 0x30, 0x31, 0x99, - 0x04, 0x72, 0xac, 0x65, 0x32, 0x32, 0x77, 0x78, 0xe8, 0xfd, 0x5c, 0x02, - 0x9e, 0x9f, 0x9e, 0x5f, 0x5f, 0xa4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x88, - 0xfe, 0x56, 0x04, 0x1e, 0x04, 0x7b, 0x00, 0x20, 0x00, 0x00, 0x05, 0x11, - 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, - 0x15, 0x3e, 0x01, 0x33, 0x32, 0x17, 0x16, 0x15, 0x11, 0x14, 0x17, 0x16, - 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, 0x26, 0x02, 0xe8, 0x2e, 0x2f, 0x5d, - 0x70, 0x40, 0x41, 0xb5, 0xb5, 0x32, 0x86, 0x58, 0xa8, 0x56, 0x56, 0x1d, - 0x1d, 0x3f, 0x04, 0x34, 0x88, 0x3c, 0x3e, 0x14, 0x02, 0xb2, 0x9f, 0x4f, - 0x4f, 0x5f, 0x5f, 0xa4, 0xfd, 0x87, 0x04, 0x5e, 0xac, 0x65, 0x64, 0x77, - 0x78, 0xe8, 0xfd, 0x48, 0x99, 0x31, 0x30, 0x9c, 0x60, 0x60, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x90, 0x00, 0x00, 0x04, 0x41, 0x04, 0x7b, 0x00, 0x09, - 0x00, 0x00, 0x13, 0x21, 0x01, 0x11, 0x33, 0x11, 0x21, 0x01, 0x11, 0x23, - 0x90, 0x01, 0x10, 0x01, 0xdd, 0xc4, 0xfe, 0xf0, 0xfe, 0x23, 0xc4, 0x04, - 0x7b, 0xfc, 0x79, 0x03, 0x87, 0xfb, 0x85, 0x03, 0x87, 0xfc, 0x79, 0x00, - 0x00, 0x03, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, 0x04, 0x7b, 0x00, 0x0a, - 0x00, 0x13, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x20, 0x12, 0x11, 0x10, 0x02, - 0x23, 0x22, 0x02, 0x11, 0x10, 0x25, 0x22, 0x07, 0x06, 0x07, 0x21, 0x26, - 0x27, 0x26, 0x13, 0x21, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x01, - 0x7f, 0x01, 0xd2, 0xf7, 0xf6, 0xea, 0xe9, 0xf6, 0x01, 0xdf, 0x8c, 0x48, - 0x3f, 0x08, 0x02, 0x37, 0x08, 0x3f, 0x48, 0x8a, 0xfd, 0xd3, 0x0e, 0x34, - 0x48, 0x8c, 0x8d, 0x48, 0x34, 0x04, 0x7b, 0xfe, 0xd2, 0xfe, 0xe2, 0xfe, - 0xe1, 0xfe, 0xd3, 0x01, 0x2d, 0x01, 0x1f, 0x01, 0x1e, 0x92, 0x6d, 0x5f, - 0xb0, 0xb0, 0x5f, 0x6d, 0xfd, 0xe0, 0x84, 0x4f, 0x6d, 0x6d, 0x4f, 0x00, - 0x00, 0x02, 0x00, 0x45, 0x00, 0x00, 0x04, 0x8c, 0x04, 0x60, 0x00, 0x12, - 0x00, 0x1d, 0x00, 0x00, 0x01, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x11, - 0x21, 0x15, 0x21, 0x22, 0x27, 0x26, 0x11, 0x10, 0x37, 0x36, 0x33, 0x17, - 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x3b, 0x01, 0x04, 0x81, - 0xfe, 0x8b, 0x01, 0x64, 0xfe, 0x9c, 0x01, 0x80, 0xfd, 0xa8, 0xf3, 0x7e, - 0x7e, 0x7e, 0x7e, 0xf3, 0x20, 0x17, 0x97, 0x4b, 0x4b, 0x4b, 0x4b, 0x97, - 0x17, 0x04, 0x60, 0xaa, 0xfe, 0xed, 0x9b, 0xfe, 0xa4, 0xac, 0x8e, 0x8f, - 0x01, 0x14, 0x01, 0x12, 0x8e, 0x8f, 0x93, 0x68, 0x67, 0xcf, 0xd0, 0x68, - 0x69, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xaa, 0xff, 0xe2, 0x04, 0x26, - 0x04, 0x7b, 0x00, 0x16, 0x00, 0x2e, 0x00, 0x00, 0x01, 0x34, 0x27, 0x26, - 0x23, 0x22, 0x07, 0x06, 0x15, 0x10, 0x33, 0x32, 0x37, 0x36, 0x3d, 0x01, - 0x33, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x13, 0x14, 0x07, 0x06, 0x23, - 0x22, 0x27, 0x26, 0x27, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, - 0x10, 0x37, 0x12, 0x21, 0x32, 0x17, 0x16, 0x03, 0x80, 0x39, 0x50, 0x91, - 0x83, 0x48, 0x4a, 0x7c, 0x22, 0x29, 0x16, 0x75, 0x17, 0x29, 0x20, 0x7d, - 0xa6, 0x30, 0x37, 0x89, 0x5f, 0x43, 0x1b, 0x10, 0x10, 0x1b, 0x43, 0x5f, - 0x76, 0x44, 0x38, 0x40, 0x6a, 0x01, 0x15, 0xeb, 0x78, 0x5a, 0x01, 0xfe, - 0x9c, 0x71, 0xa1, 0x6f, 0x73, 0xe7, 0xfe, 0xc8, 0x4f, 0x2b, 0xb9, 0xb6, - 0xb6, 0xb9, 0x2b, 0x4f, 0x01, 0x08, 0xab, 0x88, 0x9e, 0x7a, 0x32, 0x65, - 0x65, 0x32, 0x7a, 0x9a, 0x7c, 0xb7, 0x00, 0xff, 0xad, 0x01, 0x20, 0xed, - 0xb0, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x89, 0xfe, 0x56, 0x04, 0x48, - 0x06, 0x13, 0x00, 0x1d, 0x00, 0x26, 0x00, 0x2f, 0x00, 0x00, 0x01, 0x23, - 0x35, 0x21, 0x15, 0x23, 0x15, 0x16, 0x17, 0x16, 0x11, 0x10, 0x07, 0x06, - 0x07, 0x15, 0x33, 0x15, 0x21, 0x35, 0x33, 0x35, 0x26, 0x27, 0x26, 0x11, - 0x10, 0x37, 0x36, 0x37, 0x17, 0x11, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, - 0x26, 0x03, 0x11, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x02, 0x14, - 0xf0, 0x02, 0x98, 0xf0, 0xa1, 0x5f, 0x7c, 0x7b, 0x5f, 0xa2, 0xf0, 0xfd, - 0x68, 0xf0, 0xac, 0x64, 0x7b, 0x7b, 0x64, 0xac, 0xb8, 0x45, 0x2c, 0x48, - 0x48, 0x2c, 0xfd, 0x4f, 0x31, 0x48, 0x48, 0x31, 0x05, 0x6f, 0xa4, 0xa4, - 0xfc, 0x1a, 0x75, 0x97, 0xfe, 0xe2, 0xfe, 0xe1, 0x96, 0x75, 0x1a, 0xf0, - 0xa5, 0xa5, 0xed, 0x17, 0x7b, 0x96, 0x01, 0x1f, 0x01, 0x1e, 0x97, 0x7b, - 0x17, 0xa8, 0xfc, 0xc2, 0x1a, 0x42, 0x6e, 0xd5, 0xd6, 0x6d, 0x42, 0xfc, - 0xd7, 0x03, 0x48, 0x18, 0x49, 0x6d, 0xd6, 0xd5, 0x6e, 0x49, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x98, 0xff, 0xe5, 0x03, 0xb1, 0x04, 0x5e, 0x00, 0x11, - 0x00, 0x00, 0x37, 0x1e, 0x01, 0x33, 0x32, 0x36, 0x35, 0x11, 0x33, 0x11, - 0x23, 0x35, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x27, 0x98, 0x3b, 0x7a, 0x49, - 0xac, 0xb6, 0xb9, 0xb9, 0x2e, 0xbf, 0x83, 0x44, 0x76, 0x36, 0xe7, 0x2e, - 0x2a, 0xd8, 0xcc, 0x02, 0x2b, 0xfb, 0xa2, 0xdb, 0x77, 0x7f, 0x22, 0x24, - 0x00, 0x01, 0x00, 0x98, 0xff, 0xe5, 0x03, 0xb1, 0x06, 0x1f, 0x00, 0x11, - 0x00, 0x00, 0x37, 0x1e, 0x01, 0x33, 0x32, 0x36, 0x35, 0x11, 0x33, 0x11, - 0x23, 0x35, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x27, 0x98, 0x3b, 0x7a, 0x49, - 0xac, 0xb6, 0xb9, 0xb9, 0x2e, 0xbf, 0x83, 0x44, 0x76, 0x36, 0xe7, 0x2e, - 0x2a, 0xd8, 0xcc, 0x03, 0xec, 0xf9, 0xe1, 0xdb, 0x77, 0x7f, 0x22, 0x24, - 0x00, 0x01, 0x00, 0x66, 0xfe, 0x56, 0x04, 0x80, 0x04, 0x5e, 0x00, 0x19, - 0x00, 0x00, 0x05, 0x14, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x26, 0x3d, - 0x01, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x27, 0x35, 0x1e, 0x01, 0x33, 0x32, - 0x36, 0x35, 0x11, 0x33, 0x03, 0x7f, 0x59, 0x5a, 0x4e, 0x62, 0xa5, 0xb3, - 0x2e, 0xbf, 0x83, 0x44, 0x76, 0x36, 0x3b, 0x7a, 0x49, 0xac, 0xb6, 0xb9, - 0x14, 0x7d, 0x7d, 0x9c, 0xd3, 0xc3, 0xef, 0x77, 0x7f, 0x22, 0x24, 0xbc, - 0x2e, 0x2a, 0xd8, 0xcc, 0x02, 0x2b, 0x00, 0x00, 0x00, 0x01, 0x01, 0x6a, - 0xfe, 0x56, 0x04, 0x83, 0x04, 0x7b, 0x00, 0x11, 0x00, 0x00, 0x01, 0x2e, - 0x01, 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, 0x15, 0x3e, 0x01, - 0x33, 0x32, 0x16, 0x17, 0x04, 0x83, 0x3b, 0x7a, 0x49, 0xac, 0xb6, 0xb9, - 0xb9, 0x2e, 0xbf, 0x83, 0x44, 0x76, 0x36, 0x03, 0x79, 0x2e, 0x2a, 0xd8, - 0xcc, 0xfc, 0x29, 0x06, 0x08, 0xd9, 0x77, 0x7f, 0x22, 0x24, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x6a, 0xfe, 0x56, 0x04, 0x83, 0x04, 0x7b, 0x00, 0x1b, - 0x00, 0x00, 0x05, 0x14, 0x17, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x26, - 0x35, 0x11, 0x33, 0x15, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x17, 0x15, 0x2e, - 0x01, 0x23, 0x22, 0x07, 0x06, 0x15, 0x02, 0x23, 0x2c, 0x2c, 0x5b, 0xea, - 0xfe, 0xa5, 0xb3, 0xb9, 0x2e, 0xbf, 0x83, 0x44, 0x76, 0x36, 0x3b, 0x7a, - 0x49, 0xac, 0x5b, 0x5b, 0x14, 0x7d, 0x3f, 0x3e, 0x9c, 0xd3, 0xc3, 0x04, - 0x72, 0xd9, 0x77, 0x7f, 0x22, 0x24, 0xbc, 0x2e, 0x2a, 0x6c, 0x6c, 0xcc, - 0x00, 0x01, 0x00, 0xa0, 0x00, 0x00, 0x04, 0x32, 0x04, 0x7b, 0x00, 0x11, - 0x00, 0x00, 0x01, 0x34, 0x37, 0x36, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x07, - 0x06, 0x15, 0x11, 0x21, 0x15, 0x21, 0x35, 0x21, 0x02, 0x08, 0x52, 0x52, - 0xb4, 0xd2, 0xbc, 0x6a, 0x26, 0x24, 0x01, 0x70, 0xfc, 0x6e, 0x01, 0x68, - 0x02, 0xe5, 0xd4, 0x62, 0x60, 0x9c, 0x30, 0x32, 0x98, 0xfd, 0xaa, 0x8f, - 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xa0, 0x00, 0x00, 0x04, 0x32, - 0x04, 0x7b, 0x00, 0x10, 0x00, 0x00, 0x01, 0x11, 0x21, 0x15, 0x21, 0x35, - 0x21, 0x11, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x17, 0x16, 0x02, - 0xc8, 0x01, 0x6a, 0xfc, 0x6e, 0x01, 0x6e, 0x48, 0x6c, 0xba, 0xd0, 0xb4, - 0x52, 0x52, 0x02, 0xe5, 0xfd, 0xaa, 0x8f, 0x8f, 0x02, 0x56, 0x9a, 0x60, - 0x9c, 0x60, 0x62, 0x00, 0x00, 0x02, 0x00, 0x7a, 0x00, 0x00, 0x04, 0x57, - 0x04, 0x5e, 0x00, 0x16, 0x00, 0x21, 0x00, 0x00, 0x01, 0x16, 0x17, 0x16, - 0x17, 0x13, 0x23, 0x03, 0x26, 0x27, 0x26, 0x2b, 0x01, 0x11, 0x23, 0x11, - 0x21, 0x32, 0x17, 0x16, 0x15, 0x14, 0x06, 0x01, 0x11, 0x33, 0x32, 0x37, - 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x02, 0xd4, 0x37, 0x35, 0x34, 0x35, - 0xae, 0xc3, 0xa2, 0x3f, 0x3b, 0x3b, 0x61, 0xa9, 0xb9, 0x01, 0x84, 0xd9, - 0x6c, 0x6b, 0x70, 0xfd, 0xf5, 0xc6, 0x77, 0x3f, 0x40, 0x40, 0x3f, 0x77, - 0x02, 0x0d, 0x11, 0x36, 0x36, 0x5e, 0xfe, 0xce, 0x01, 0x1f, 0x71, 0x24, - 0x25, 0xfe, 0x27, 0x04, 0x5e, 0x4e, 0x4d, 0xa6, 0x69, 0x8c, 0x01, 0x9d, - 0xfe, 0xaf, 0x2b, 0x2b, 0x53, 0x54, 0x2a, 0x2a, 0x00, 0x02, 0x00, 0x7a, - 0x00, 0x00, 0x04, 0x57, 0x04, 0x5e, 0x00, 0x16, 0x00, 0x21, 0x00, 0x00, - 0x01, 0x1e, 0x01, 0x15, 0x14, 0x07, 0x06, 0x23, 0x21, 0x11, 0x33, 0x11, - 0x33, 0x32, 0x37, 0x36, 0x37, 0x13, 0x33, 0x03, 0x06, 0x07, 0x06, 0x01, - 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x2b, 0x01, 0x02, 0xd4, - 0x6a, 0x70, 0x6b, 0x6c, 0xd9, 0xfe, 0x7c, 0xb9, 0xa9, 0x61, 0x3b, 0x3b, - 0x3f, 0xa2, 0xc3, 0xae, 0x35, 0x34, 0x35, 0xfe, 0x28, 0xc6, 0x77, 0x3f, - 0x40, 0x40, 0x3f, 0x77, 0xc6, 0x02, 0x53, 0x1b, 0x8c, 0x69, 0xa2, 0x51, - 0x50, 0x04, 0x5e, 0xfe, 0x29, 0x25, 0x24, 0x71, 0x01, 0x1d, 0xfe, 0xd0, - 0x5e, 0x36, 0x36, 0xfe, 0x37, 0x2a, 0x2a, 0x54, 0x53, 0x2b, 0x2b, 0x00, - 0x00, 0x01, 0x00, 0xbc, 0xfe, 0x56, 0x04, 0x14, 0x04, 0x7b, 0x00, 0x38, - 0x00, 0x00, 0x01, 0x15, 0x2e, 0x01, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, - 0x17, 0x16, 0x1f, 0x01, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, - 0x22, 0x27, 0x14, 0x17, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x26, 0x3d, - 0x01, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, - 0x2f, 0x01, 0x26, 0x27, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x03, - 0xd8, 0x4e, 0xa7, 0x5b, 0x88, 0x44, 0x46, 0x32, 0x30, 0x94, 0x40, 0xc4, - 0x52, 0x52, 0x7a, 0x7c, 0xd8, 0x68, 0x6a, 0x26, 0x22, 0x6e, 0xe8, 0xfe, - 0xb4, 0xa4, 0x66, 0x64, 0x62, 0x62, 0x82, 0x46, 0x46, 0x32, 0x34, 0xaa, - 0x40, 0xac, 0x4c, 0x4c, 0xe0, 0xce, 0x66, 0xb5, 0x04, 0x3f, 0xae, 0x28, - 0x28, 0x2a, 0x2a, 0x54, 0x40, 0x25, 0x24, 0x21, 0x0e, 0x2a, 0x4d, 0x4c, - 0x89, 0x9d, 0x5a, 0x5b, 0x15, 0x9f, 0x37, 0x30, 0x9c, 0xc0, 0xd6, 0xfb, - 0x35, 0x1a, 0x1b, 0x2d, 0x2c, 0x51, 0x4b, 0x28, 0x28, 0x25, 0x0f, 0x24, - 0x4a, 0x4b, 0x82, 0x9e, 0xac, 0x1e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x7d, - 0xfe, 0x56, 0x04, 0x54, 0x06, 0x14, 0x00, 0x13, 0x00, 0x00, 0x05, 0x14, - 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x36, 0x35, 0x11, 0x34, 0x36, 0x3b, - 0x01, 0x15, 0x23, 0x22, 0x06, 0x15, 0x02, 0xd3, 0xb3, 0xa5, 0xfe, 0xea, - 0x5a, 0x5a, 0xa9, 0xb3, 0xdd, 0xd1, 0x63, 0x4d, 0x14, 0xc3, 0xd3, 0x9c, - 0x7d, 0x7d, 0x04, 0xc2, 0xb8, 0xae, 0x99, 0x51, 0x67, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x7d, 0xfe, 0x56, 0x04, 0x54, 0x06, 0x14, 0x00, 0x1f, - 0x00, 0x00, 0x01, 0x15, 0x21, 0x11, 0x14, 0x06, 0x2b, 0x01, 0x35, 0x33, - 0x32, 0x36, 0x35, 0x11, 0x21, 0x35, 0x21, 0x11, 0x21, 0x35, 0x21, 0x35, - 0x34, 0x36, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x06, 0x15, 0x11, 0x04, 0x34, - 0xfe, 0x9f, 0xb3, 0xa5, 0xfe, 0xea, 0x5a, 0x5a, 0xfe, 0x81, 0x01, 0x7f, - 0xfe, 0xc3, 0x01, 0x3d, 0xa9, 0xb3, 0xdd, 0xd1, 0x63, 0x4d, 0x02, 0x68, - 0xa4, 0xfe, 0x28, 0xc3, 0xd3, 0x9c, 0x7d, 0x7d, 0x01, 0xd8, 0xa4, 0x01, - 0x69, 0x8d, 0x50, 0xb8, 0xae, 0x99, 0x51, 0x67, 0xfd, 0xa5, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x7d, 0xfe, 0x56, 0x04, 0x54, 0x04, 0x5e, 0x00, 0x15, - 0x00, 0x00, 0x01, 0x11, 0x14, 0x17, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, - 0x26, 0x35, 0x11, 0x34, 0x27, 0x26, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x16, - 0x02, 0xd3, 0x27, 0x26, 0x63, 0xd1, 0xdd, 0xb3, 0xa9, 0x2d, 0x2d, 0x5a, - 0xea, 0xfe, 0xa5, 0xb3, 0x02, 0xc8, 0xfc, 0xdf, 0x67, 0x28, 0x29, 0x99, - 0xae, 0xb8, 0x03, 0x0c, 0x7c, 0x40, 0x3e, 0x9c, 0xd3, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x76, 0xfe, 0x56, 0x04, 0x5b, 0x06, 0x14, 0x00, 0x08, - 0x00, 0x21, 0x00, 0x00, 0x05, 0x23, 0x22, 0x15, 0x14, 0x33, 0x32, 0x37, - 0x36, 0x37, 0x33, 0x15, 0x23, 0x06, 0x07, 0x06, 0x23, 0x20, 0x35, 0x34, - 0x21, 0x33, 0x11, 0x34, 0x37, 0x36, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x07, - 0x06, 0x15, 0x02, 0x38, 0xb3, 0x74, 0x7f, 0x6e, 0x21, 0x12, 0xca, 0xb7, - 0xbf, 0x12, 0x35, 0x52, 0xb5, 0xfe, 0xd1, 0x01, 0x0e, 0xbe, 0x57, 0x51, - 0xc3, 0xae, 0xb0, 0x64, 0x25, 0x27, 0x9a, 0x33, 0x41, 0x30, 0x17, 0xc7, - 0x9b, 0x6f, 0x40, 0x60, 0xd8, 0xd2, 0x04, 0xae, 0xb4, 0x5c, 0x56, 0x99, - 0x28, 0x29, 0x67, 0x00, 0x00, 0x01, 0x00, 0xa6, 0xfe, 0xc2, 0x04, 0x2b, - 0x04, 0x60, 0x00, 0x13, 0x00, 0x00, 0x01, 0x11, 0x21, 0x35, 0x21, 0x11, - 0x34, 0x26, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x16, 0x15, 0x11, 0x21, 0x15, - 0x21, 0x11, 0x02, 0x48, 0xfe, 0x5e, 0x01, 0xa2, 0x5e, 0x75, 0xcf, 0xe1, - 0xcf, 0xaa, 0x01, 0x2b, 0xfe, 0xd5, 0xfe, 0xc2, 0x01, 0x3e, 0x8f, 0x02, - 0x60, 0x7c, 0x62, 0x93, 0xa6, 0xcb, 0xfd, 0xa0, 0x8f, 0xfe, 0xc2, 0x00, - 0x00, 0x01, 0x00, 0x83, 0xfe, 0x57, 0x04, 0x08, 0x05, 0x9e, 0x00, 0x13, - 0x00, 0x00, 0x01, 0x11, 0x21, 0x15, 0x21, 0x11, 0x14, 0x16, 0x3b, 0x01, - 0x15, 0x23, 0x22, 0x26, 0x35, 0x11, 0x21, 0x35, 0x21, 0x11, 0x02, 0x66, - 0x01, 0xa2, 0xfe, 0x5e, 0x5e, 0x75, 0xcf, 0xe1, 0xcf, 0xaa, 0xfe, 0xd5, - 0x01, 0x2b, 0x05, 0x9e, 0xfe, 0xc2, 0x8f, 0xfb, 0xf7, 0x7c, 0x62, 0x93, - 0xa6, 0xcb, 0x04, 0x09, 0x8f, 0x01, 0x3e, 0x00, 0x00, 0x02, 0x00, 0x00, - 0xff, 0xe3, 0x04, 0xd1, 0x04, 0x60, 0x00, 0x17, 0x00, 0x21, 0x00, 0x00, - 0x11, 0x35, 0x33, 0x11, 0x33, 0x11, 0x21, 0x11, 0x33, 0x11, 0x33, 0x15, - 0x23, 0x11, 0x23, 0x35, 0x06, 0x07, 0x06, 0x23, 0x22, 0x26, 0x3d, 0x01, - 0x29, 0x01, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x8e, 0xb8, - 0x02, 0x3a, 0xb8, 0x99, 0x99, 0xb8, 0x43, 0x59, 0x59, 0x75, 0xc1, 0xc7, - 0x02, 0xf1, 0xfd, 0xc7, 0x3e, 0x3e, 0x7c, 0x95, 0x57, 0x4d, 0x01, 0xc4, - 0xa4, 0x01, 0xf8, 0xfe, 0x08, 0x01, 0xf8, 0xfe, 0x08, 0xa4, 0xfe, 0x3c, - 0xac, 0x66, 0x32, 0x31, 0xf0, 0xe7, 0x0a, 0x03, 0x9f, 0x50, 0x4f, 0x5f, - 0x55, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x5f, 0xff, 0xe2, 0x04, 0x72, - 0x04, 0x60, 0x00, 0x23, 0x00, 0x00, 0x13, 0x35, 0x21, 0x15, 0x06, 0x07, - 0x06, 0x15, 0x14, 0x16, 0x20, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, - 0x35, 0x21, 0x15, 0x23, 0x16, 0x17, 0x16, 0x15, 0x14, 0x00, 0x20, 0x27, - 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x5f, 0x01, 0xba, 0x6d, 0x3f, 0x42, - 0xb0, 0x01, 0x20, 0x58, 0x58, 0x42, 0x47, 0x64, 0x01, 0xb4, 0xec, 0x72, - 0x38, 0x36, 0xfe, 0xe4, 0xfe, 0x3e, 0x8e, 0x8e, 0x34, 0x35, 0x77, 0x03, - 0xbc, 0xa4, 0xdc, 0x45, 0x69, 0x6f, 0x87, 0x9f, 0xc2, 0x61, 0x62, 0x9e, - 0x92, 0x64, 0x6f, 0x3f, 0xdc, 0xa4, 0x64, 0x71, 0x6e, 0x88, 0xeb, 0xfe, - 0xdc, 0x91, 0x92, 0xe4, 0x93, 0x6b, 0x6d, 0x68, 0x00, 0x01, 0x00, 0x41, - 0x00, 0x00, 0x04, 0x77, 0x04, 0x60, 0x00, 0x20, 0x00, 0x00, 0x01, 0x21, - 0x16, 0x17, 0x16, 0x15, 0x14, 0x00, 0x2b, 0x01, 0x22, 0x27, 0x26, 0x35, - 0x11, 0x23, 0x35, 0x21, 0x11, 0x14, 0x17, 0x16, 0x3f, 0x01, 0x32, 0x37, - 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x02, 0x55, 0x01, 0x42, 0x72, - 0x38, 0x36, 0xfe, 0xe4, 0xe1, 0x46, 0xb5, 0x52, 0x51, 0x9b, 0x01, 0x53, - 0x26, 0x28, 0x67, 0x33, 0x90, 0x58, 0x58, 0x42, 0x4f, 0x5c, 0x4c, 0x03, - 0xda, 0x64, 0x71, 0x6e, 0x88, 0xeb, 0xfe, 0xdc, 0x60, 0x60, 0xd6, 0x02, - 0x3b, 0x8f, 0xfd, 0x36, 0x99, 0x31, 0x32, 0x02, 0x01, 0x61, 0x62, 0x9e, - 0x92, 0x64, 0x77, 0x37, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x48, - 0x00, 0x00, 0x04, 0x8a, 0x04, 0x60, 0x00, 0x06, 0x00, 0x00, 0x21, 0x23, - 0x09, 0x01, 0x23, 0x01, 0x33, 0x04, 0x8a, 0xc4, 0xfe, 0xa2, 0xfe, 0xa2, - 0xc2, 0x01, 0xa4, 0xfa, 0x03, 0xac, 0xfc, 0x54, 0x04, 0x60, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x04, 0xc2, 0x04, 0x60, 0x00, 0x0c, - 0x00, 0x00, 0x21, 0x23, 0x0b, 0x01, 0x23, 0x0b, 0x01, 0x23, 0x13, 0x33, - 0x1b, 0x01, 0x33, 0x04, 0xc2, 0x94, 0xb8, 0xb7, 0xad, 0xb8, 0xb8, 0x93, - 0xeb, 0xad, 0xc1, 0xc2, 0xad, 0x03, 0x6a, 0xfc, 0x96, 0x03, 0x6a, 0xfc, - 0x96, 0x04, 0x60, 0xfc, 0x6a, 0x03, 0x96, 0x00, 0x00, 0x01, 0x00, 0x48, - 0x00, 0x00, 0x04, 0x8a, 0x06, 0x0a, 0x00, 0x0f, 0x00, 0x00, 0x01, 0x3e, - 0x01, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x06, 0x0f, 0x01, 0x01, 0x23, 0x09, - 0x01, 0x23, 0x02, 0x34, 0x4e, 0x94, 0x7c, 0x92, 0x6c, 0x4c, 0x54, 0x32, - 0x22, 0x01, 0xc6, 0xc4, 0xfe, 0xa2, 0xfe, 0xa2, 0xc2, 0x04, 0xc8, 0xc8, - 0x7a, 0x9a, 0x48, 0x86, 0x54, 0xfb, 0xb2, 0x03, 0x6c, 0xfc, 0x94, 0x00, - 0x00, 0x01, 0x00, 0x66, 0x00, 0x00, 0x04, 0x6b, 0x04, 0x7d, 0x00, 0x08, - 0x00, 0x00, 0x13, 0x33, 0x09, 0x01, 0x33, 0x01, 0x11, 0x23, 0x11, 0x66, - 0xd9, 0x01, 0x25, 0x01, 0x2e, 0xd9, 0xfe, 0x5d, 0xcb, 0x04, 0x7d, 0xfe, - 0x38, 0x01, 0xc8, 0xfd, 0x90, 0xfd, 0xf3, 0x02, 0x0d, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xc2, 0xfe, 0x56, 0x04, 0x0f, 0x04, 0x60, 0x00, 0x14, - 0x00, 0x00, 0x13, 0x21, 0x15, 0x01, 0x21, 0x17, 0x14, 0x17, 0x16, 0x3b, - 0x01, 0x15, 0x23, 0x22, 0x26, 0x3d, 0x01, 0x21, 0x35, 0x01, 0x21, 0xd5, - 0x02, 0xa7, 0xfd, 0xf9, 0x02, 0x19, 0x01, 0x15, 0x15, 0x3b, 0x1b, 0x34, - 0x88, 0x7a, 0xfd, 0xe9, 0x02, 0x07, 0xfe, 0x0c, 0x04, 0x60, 0xa8, 0xfc, - 0xdb, 0xa7, 0x99, 0x31, 0x30, 0x9c, 0xc0, 0xd6, 0x14, 0xa8, 0x03, 0x25, - 0x00, 0x02, 0x00, 0xa7, 0xff, 0x91, 0x04, 0x2a, 0x04, 0x60, 0x00, 0x14, - 0x00, 0x1b, 0x00, 0x00, 0x21, 0x06, 0x15, 0x23, 0x34, 0x37, 0x21, 0x35, - 0x01, 0x21, 0x35, 0x21, 0x15, 0x01, 0x33, 0x12, 0x33, 0x32, 0x17, 0x16, - 0x21, 0x27, 0x33, 0x32, 0x35, 0x34, 0x23, 0x06, 0x02, 0xaa, 0x03, 0x99, - 0x03, 0xfe, 0x96, 0x02, 0xb4, 0xfd, 0x65, 0x03, 0x6a, 0xfd, 0x4c, 0xaf, - 0x3c, 0xdb, 0xe3, 0x01, 0x01, 0xfe, 0xb2, 0x14, 0x14, 0xae, 0x46, 0x58, - 0x33, 0x3c, 0x3b, 0x34, 0xa8, 0x03, 0x25, 0x93, 0xa8, 0xfc, 0xdb, 0x01, - 0x20, 0xf6, 0xbd, 0x93, 0x36, 0x5b, 0x02, 0x00, 0x00, 0x01, 0x00, 0x7d, - 0xfe, 0x4c, 0x04, 0x54, 0x04, 0x60, 0x00, 0x20, 0x00, 0x00, 0x01, 0x32, - 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x04, 0x21, 0x22, 0x27, 0x26, 0x27, - 0x35, 0x1e, 0x01, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x2b, - 0x01, 0x35, 0x01, 0x21, 0x35, 0x21, 0x15, 0x02, 0x61, 0x6a, 0x80, 0x62, - 0x56, 0x51, 0xfe, 0xd0, 0xfe, 0xe8, 0x5e, 0x63, 0x64, 0x6a, 0x54, 0xc8, - 0x6d, 0xbe, 0x63, 0x64, 0x5c, 0x5d, 0xa5, 0xae, 0x01, 0xae, 0xfd, 0x65, - 0x03, 0x6a, 0x01, 0xdc, 0x38, 0x2a, 0x6d, 0x68, 0x8a, 0xdd, 0xf2, 0x12, - 0x13, 0x25, 0xc3, 0x31, 0x32, 0x4b, 0x4b, 0x8f, 0x84, 0x4b, 0x4a, 0xa6, - 0x01, 0xf3, 0x93, 0xa8, 0x00, 0x02, 0x00, 0x69, 0xfe, 0x4c, 0x04, 0x68, - 0x04, 0x60, 0x00, 0x24, 0x00, 0x2d, 0x00, 0x00, 0x01, 0x20, 0x37, 0x36, - 0x05, 0x16, 0x17, 0x36, 0x35, 0x34, 0x27, 0x26, 0x2b, 0x01, 0x35, 0x01, - 0x21, 0x35, 0x21, 0x15, 0x01, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x16, 0x15, 0x23, 0x34, 0x27, 0x30, 0x07, 0x06, 0x37, 0x26, 0x23, - 0x22, 0x07, 0x14, 0x33, 0x32, 0x37, 0x01, 0xe3, 0xfe, 0xb1, 0x02, 0x02, - 0x01, 0x2a, 0xf6, 0x9e, 0x0c, 0x5c, 0x5e, 0xa4, 0xae, 0x01, 0xae, 0xfd, - 0x65, 0x03, 0x6a, 0xfe, 0x65, 0x69, 0x81, 0x64, 0x54, 0x51, 0x27, 0x64, - 0x99, 0x28, 0x14, 0x97, 0x09, 0x7d, 0xc5, 0x83, 0x01, 0x9e, 0xbe, 0x63, - 0xfe, 0x4c, 0xbd, 0xfb, 0x05, 0x04, 0x3b, 0x2a, 0x31, 0x85, 0x4a, 0x4a, - 0xa6, 0x01, 0xf3, 0x93, 0xa8, 0xfe, 0x24, 0x38, 0x2b, 0x6c, 0x67, 0x8b, - 0x71, 0x55, 0x65, 0xa4, 0x52, 0x38, 0x11, 0x79, 0xfa, 0x2a, 0x4b, 0x2f, - 0x4b, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc2, 0x00, 0x00, 0x04, 0x0f, - 0x06, 0x12, 0x00, 0x1c, 0x00, 0x00, 0x01, 0x33, 0x32, 0x37, 0x36, 0x35, - 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x35, 0x36, 0x37, 0x36, - 0x33, 0x20, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x11, 0x23, 0x01, - 0xbe, 0x3f, 0xbf, 0x57, 0x3a, 0x3a, 0x66, 0xb0, 0x50, 0x4f, 0x4e, 0x4e, - 0x4c, 0x51, 0x51, 0x55, 0x01, 0x13, 0x8a, 0x6d, 0x6c, 0x70, 0xaa, 0xcb, - 0x03, 0x1e, 0x72, 0x4c, 0x62, 0x85, 0x41, 0x72, 0x16, 0x15, 0x2b, 0xac, - 0x23, 0x11, 0x12, 0x9d, 0x7d, 0xba, 0xaa, 0x73, 0x77, 0x1e, 0xfd, 0x74, - 0x00, 0x01, 0x00, 0xc2, 0x00, 0x00, 0x04, 0x0f, 0x06, 0x12, 0x00, 0x1c, - 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, - 0x36, 0x21, 0x32, 0x17, 0x16, 0x17, 0x15, 0x26, 0x27, 0x26, 0x23, 0x22, - 0x07, 0x06, 0x07, 0x14, 0x17, 0x16, 0x33, 0x03, 0x12, 0xca, 0xaa, 0x70, - 0x6c, 0x6e, 0x89, 0x01, 0x13, 0x55, 0x51, 0x51, 0x4c, 0x4e, 0x4f, 0x4e, - 0x50, 0xb3, 0x63, 0x39, 0x01, 0x3a, 0x56, 0xc0, 0x03, 0x1e, 0xfc, 0xe2, - 0x02, 0x8c, 0x1e, 0x77, 0x73, 0xaa, 0xba, 0x7d, 0x9d, 0x12, 0x11, 0x23, - 0xac, 0x2b, 0x15, 0x16, 0x72, 0x41, 0x85, 0x62, 0x4c, 0x72, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xc2, 0x00, 0x00, 0x04, 0x0f, 0x06, 0x12, 0x00, 0x1c, - 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, - 0x06, 0x21, 0x22, 0x27, 0x26, 0x27, 0x35, 0x16, 0x17, 0x16, 0x33, 0x32, - 0x37, 0x36, 0x37, 0x34, 0x27, 0x26, 0x23, 0x01, 0xbe, 0xcb, 0xaa, 0x70, - 0x6c, 0x6d, 0x8a, 0xfe, 0xed, 0x55, 0x51, 0x51, 0x4c, 0x4e, 0x4e, 0x4f, - 0x50, 0xb3, 0x63, 0x39, 0x01, 0x3a, 0x56, 0xc0, 0x02, 0xf4, 0x03, 0x1e, - 0xfd, 0x74, 0x1e, 0x77, 0x73, 0xaa, 0xba, 0x7d, 0x9d, 0x12, 0x11, 0x23, - 0xac, 0x2b, 0x15, 0x16, 0x72, 0x41, 0x85, 0x62, 0x4c, 0x72, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xc2, 0xfe, 0x4a, 0x04, 0x0f, 0x06, 0x12, 0x00, 0x23, - 0x00, 0x00, 0x13, 0x34, 0x37, 0x36, 0x21, 0x32, 0x17, 0x16, 0x17, 0x15, - 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x11, 0x16, 0x17, 0x16, - 0x33, 0x32, 0x37, 0x36, 0x37, 0x15, 0x06, 0x07, 0x06, 0x23, 0x20, 0x27, - 0x26, 0x35, 0xc2, 0x6e, 0x89, 0x01, 0x13, 0x55, 0x51, 0x51, 0x4c, 0x4e, - 0x4f, 0x4e, 0x50, 0xb3, 0x63, 0x39, 0x01, 0x01, 0x39, 0x63, 0xb3, 0x50, - 0x4e, 0x4f, 0x4e, 0x4c, 0x51, 0x51, 0x55, 0xfe, 0xed, 0x89, 0x6e, 0x04, - 0x3e, 0xba, 0x7d, 0x9d, 0x12, 0x11, 0x23, 0xac, 0x2b, 0x15, 0x16, 0x72, - 0x41, 0x85, 0xfb, 0xe0, 0x85, 0x41, 0x72, 0x16, 0x15, 0x2b, 0xac, 0x23, - 0x11, 0x12, 0x9d, 0x7d, 0xba, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x5f, - 0x00, 0x2d, 0x04, 0x73, 0x04, 0x42, 0x00, 0x0c, 0x00, 0x1a, 0x00, 0x28, - 0x00, 0x00, 0x13, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, - 0x00, 0x20, 0x00, 0x37, 0x14, 0x17, 0x16, 0x20, 0x36, 0x35, 0x34, 0x27, - 0x26, 0x23, 0x22, 0x07, 0x06, 0x17, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, - 0x16, 0x15, 0x14, 0x06, 0x22, 0x27, 0x26, 0x5f, 0x9a, 0x9a, 0xd8, 0xd4, - 0x9a, 0x9a, 0xfe, 0xd1, 0xfe, 0x4f, 0xfe, 0xcc, 0xb5, 0x65, 0x64, 0x01, - 0x1a, 0xc6, 0x64, 0x65, 0x8a, 0x8d, 0x64, 0x65, 0xe3, 0x22, 0x21, 0x2f, - 0x2e, 0x22, 0x21, 0x42, 0x5e, 0x21, 0x22, 0x02, 0x35, 0xd4, 0x9c, 0x9d, - 0x9d, 0x9c, 0xd4, 0xd8, 0xfe, 0xd0, 0x01, 0x30, 0xd9, 0x8d, 0x63, 0x63, - 0xc6, 0x8d, 0x8a, 0x66, 0x66, 0x66, 0x66, 0x89, 0x2e, 0x22, 0x22, 0x22, - 0x22, 0x2e, 0x2f, 0x42, 0x21, 0x21, 0x00, 0x00, 0x00, 0x03, 0x00, 0xd1, - 0x00, 0x00, 0x04, 0x00, 0x04, 0x7d, 0x00, 0x08, 0x00, 0x11, 0x00, 0x20, - 0x00, 0x2d, 0x40, 0x18, 0x19, 0x00, 0xb6, 0x0a, 0x20, 0x09, 0xb6, 0x12, - 0xc2, 0x01, 0xb6, 0x20, 0x0e, 0x12, 0x16, 0x05, 0x12, 0x1c, 0x00, 0x09, - 0x06, 0x12, 0x46, 0x21, 0x10, 0xfc, 0xec, 0x32, 0xd4, 0xec, 0xd4, 0xec, - 0x31, 0x00, 0x2f, 0xec, 0xf4, 0xec, 0x10, 0xd4, 0xec, 0x39, 0x30, 0x01, - 0x11, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x03, 0x11, 0x33, 0x32, - 0x36, 0x35, 0x34, 0x26, 0x23, 0x25, 0x21, 0x32, 0x16, 0x15, 0x14, 0x06, - 0x07, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x23, 0x21, 0x01, 0x9b, 0xdd, 0x5d, - 0x5f, 0x5a, 0x5e, 0xe1, 0xd2, 0x55, 0x54, 0x54, 0x56, 0xfe, 0x65, 0x01, - 0x8d, 0xb2, 0xc0, 0x62, 0x60, 0x73, 0x7f, 0xd1, 0xc1, 0xfe, 0x63, 0x02, - 0x12, 0xfe, 0x98, 0x69, 0x3f, 0x5c, 0x64, 0x01, 0xc2, 0xfe, 0xe8, 0x55, - 0x3f, 0x2e, 0x56, 0xa9, 0x94, 0x88, 0x69, 0x7d, 0x0f, 0x19, 0x9c, 0x75, - 0x9a, 0xa8, 0x00, 0x00, 0x00, 0x02, 0x00, 0xb0, 0xff, 0xd6, 0x04, 0x22, - 0x04, 0x79, 0x00, 0x15, 0x00, 0x2b, 0x00, 0x00, 0x01, 0x22, 0x07, 0x06, - 0x14, 0x17, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, - 0x17, 0x16, 0x33, 0x24, 0x11, 0x10, 0x27, 0x04, 0x11, 0x10, 0x05, 0x06, - 0x27, 0x22, 0x27, 0x26, 0x35, 0x34, 0x36, 0x37, 0x2e, 0x01, 0x35, 0x34, - 0x37, 0x36, 0x33, 0x32, 0x02, 0x32, 0x73, 0x39, 0x40, 0x3c, 0x20, 0x8a, - 0x89, 0x89, 0x8a, 0x20, 0x3c, 0x40, 0x37, 0x75, 0x01, 0x54, 0x78, 0x01, - 0x14, 0xfe, 0xec, 0x56, 0x93, 0xad, 0x64, 0x64, 0x6a, 0x62, 0x62, 0x6a, - 0x64, 0x64, 0xad, 0x96, 0x03, 0xd8, 0x36, 0x3d, 0x9a, 0x37, 0x1e, 0x9d, - 0x1e, 0x36, 0x4e, 0x4a, 0x40, 0x36, 0x01, 0x01, 0xbe, 0x01, 0xa2, 0x73, - 0x97, 0xfe, 0x78, 0xfe, 0xa8, 0xc2, 0x3e, 0x02, 0x57, 0x56, 0x94, 0x67, - 0x8e, 0x1c, 0x1b, 0x8e, 0x67, 0x94, 0x57, 0x56, 0x00, 0x01, 0x00, 0x36, - 0x00, 0x00, 0x04, 0x6c, 0x06, 0x12, 0x00, 0x30, 0x00, 0x00, 0x25, 0x11, - 0x23, 0x35, 0x21, 0x11, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x11, - 0x10, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x35, 0x34, 0x37, 0x36, - 0x3b, 0x01, 0x15, 0x23, 0x22, 0x07, 0x06, 0x1d, 0x01, 0x23, 0x15, 0x26, - 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x10, 0x17, 0x16, 0x33, 0x32, 0x02, - 0xce, 0x74, 0x01, 0x1e, 0x01, 0xa3, 0x3a, 0x98, 0xd4, 0x7b, 0x7d, 0x7f, - 0x7c, 0xdb, 0x33, 0x48, 0x18, 0x0d, 0x3e, 0x3c, 0x88, 0xbe, 0x81, 0x4e, - 0x1e, 0x1c, 0x02, 0x1d, 0xbd, 0x3f, 0x37, 0x86, 0x4b, 0x4a, 0x4a, 0x4b, - 0x86, 0x82, 0xb2, 0x01, 0x1a, 0x8c, 0xfd, 0xf0, 0x04, 0x32, 0x12, 0x9f, - 0xa0, 0x01, 0x0d, 0x01, 0x0f, 0xa0, 0x9d, 0x12, 0x06, 0x05, 0x01, 0xd8, - 0x5e, 0x60, 0x9c, 0x30, 0x33, 0x97, 0x94, 0x6a, 0x26, 0x42, 0x16, 0x72, - 0x71, 0xfe, 0x66, 0x71, 0x72, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x90, - 0x00, 0x00, 0x04, 0x41, 0x04, 0x7b, 0x00, 0x0b, 0x00, 0x00, 0x13, 0x33, - 0x11, 0x21, 0x11, 0x33, 0x11, 0x23, 0x11, 0x21, 0x11, 0x23, 0x90, 0xca, - 0x02, 0x1d, 0xca, 0xca, 0xfd, 0xe3, 0xca, 0x04, 0x7b, 0xfe, 0x41, 0x01, - 0xbf, 0xfb, 0x85, 0x02, 0x12, 0xfd, 0xee, 0x00, 0x00, 0x03, 0x00, 0xca, - 0xfe, 0x56, 0x04, 0x07, 0x06, 0x14, 0x00, 0x03, 0x00, 0x14, 0x00, 0x1d, - 0x00, 0x00, 0x01, 0x33, 0x15, 0x23, 0x17, 0x11, 0x33, 0x15, 0x23, 0x06, - 0x07, 0x06, 0x23, 0x20, 0x35, 0x34, 0x21, 0x33, 0x11, 0x21, 0x35, 0x01, - 0x23, 0x22, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x02, 0x9a, 0xb8, 0xb8, - 0xb8, 0xb4, 0xbe, 0x13, 0x35, 0x51, 0xb5, 0xfe, 0xd0, 0x01, 0x0e, 0xc2, - 0xfe, 0xc2, 0x01, 0x33, 0xb5, 0x77, 0x03, 0x03, 0x7b, 0x6a, 0x26, 0x11, - 0x06, 0x14, 0xe9, 0xcb, 0xfb, 0xa0, 0x9b, 0x70, 0x3f, 0x60, 0xdd, 0xcd, - 0x03, 0xd1, 0x8f, 0xfb, 0x06, 0x33, 0x41, 0x30, 0x17, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x77, 0xfe, 0x4c, 0x04, 0x5a, 0x04, 0x60, 0x00, 0x0a, - 0x00, 0x00, 0x01, 0x23, 0x11, 0x01, 0x23, 0x09, 0x01, 0x33, 0x01, 0x11, - 0x33, 0x04, 0x5a, 0xba, 0xfd, 0xdc, 0xec, 0x02, 0x52, 0xfd, 0x96, 0xf0, - 0x02, 0x38, 0xba, 0xfe, 0x4c, 0x03, 0x97, 0xfe, 0x1d, 0x02, 0x0c, 0x02, - 0x54, 0xfd, 0xdd, 0x02, 0x23, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf5, - 0x00, 0x00, 0x03, 0xdc, 0x04, 0x7b, 0x00, 0x05, 0x00, 0x00, 0x13, 0x33, - 0x11, 0x21, 0x15, 0x21, 0xf5, 0xca, 0x02, 0x1d, 0xfd, 0x19, 0x04, 0x7b, - 0xfc, 0x2f, 0xaa, 0x00, 0x00, 0x02, 0x00, 0x23, 0xfe, 0x56, 0x04, 0x7c, - 0x06, 0x12, 0x00, 0x1d, 0x00, 0x29, 0x00, 0x00, 0x25, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x10, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, - 0x35, 0x34, 0x37, 0x36, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x07, 0x06, 0x15, - 0x11, 0x23, 0x00, 0x10, 0x17, 0x16, 0x32, 0x37, 0x36, 0x10, 0x27, 0x26, - 0x22, 0x07, 0x02, 0xbb, 0x2c, 0x42, 0x43, 0x5d, 0xae, 0x6e, 0x6d, 0x6d, - 0x6e, 0xae, 0x5d, 0x43, 0x42, 0x2c, 0x3d, 0x3d, 0x88, 0xbe, 0x7f, 0x4f, - 0x1d, 0x1c, 0xb9, 0xfe, 0x29, 0x3f, 0x3f, 0xdb, 0x3f, 0x3f, 0x3f, 0x3f, - 0xdb, 0x3f, 0xa8, 0x64, 0x30, 0x31, 0xa2, 0xa2, 0x02, 0x10, 0xa2, 0xa2, - 0x31, 0x30, 0x64, 0xc6, 0xd6, 0x60, 0x60, 0x9c, 0x30, 0x31, 0x99, 0xf9, - 0xda, 0x04, 0xa4, 0xfe, 0x6a, 0x74, 0x73, 0x73, 0x74, 0x01, 0x96, 0x74, - 0x73, 0x73, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc2, 0x00, 0x00, 0x04, 0x0f, - 0x06, 0x12, 0x00, 0x24, 0x00, 0x00, 0x01, 0x33, 0x32, 0x37, 0x36, 0x35, - 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x35, 0x36, 0x37, 0x36, - 0x33, 0x20, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x15, 0x33, 0x15, - 0x23, 0x11, 0x23, 0x11, 0x23, 0x35, 0x33, 0x01, 0xbe, 0x3f, 0xbf, 0x57, - 0x3a, 0x3a, 0x66, 0xb0, 0x50, 0x4f, 0x4e, 0x4e, 0x4c, 0x51, 0x51, 0x55, - 0x01, 0x13, 0x8a, 0x6d, 0x6c, 0x70, 0xaa, 0xe7, 0xe7, 0xca, 0xe5, 0xe4, - 0x03, 0x1e, 0x72, 0x4c, 0x62, 0x85, 0x41, 0x72, 0x16, 0x15, 0x2b, 0xac, - 0x23, 0x11, 0x12, 0x9d, 0x7d, 0xba, 0xaa, 0x73, 0x77, 0x1e, 0xd4, 0xa4, - 0xfe, 0xec, 0x01, 0x14, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc2, - 0x00, 0x00, 0x04, 0x0f, 0x06, 0x12, 0x00, 0x24, 0x00, 0x00, 0x01, 0x35, - 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x21, 0x32, 0x17, 0x16, 0x17, - 0x15, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, - 0x3b, 0x01, 0x11, 0x33, 0x15, 0x23, 0x11, 0x23, 0x11, 0x23, 0x35, 0x02, - 0x48, 0xaa, 0x70, 0x6c, 0x6e, 0x89, 0x01, 0x13, 0x55, 0x51, 0x51, 0x4c, - 0x4e, 0x4f, 0x4e, 0x50, 0xb0, 0x66, 0x3a, 0x3a, 0x57, 0xbf, 0x3e, 0xe5, - 0xe5, 0xca, 0xe7, 0x01, 0xb8, 0xd4, 0x1e, 0x77, 0x73, 0xaa, 0xba, 0x7d, - 0x9d, 0x12, 0x11, 0x23, 0xac, 0x2b, 0x15, 0x16, 0x72, 0x41, 0x85, 0x62, - 0x4c, 0x72, 0xfe, 0x9a, 0xa4, 0xfe, 0xec, 0x01, 0x14, 0xa4, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x1d, 0xff, 0xe3, 0x04, 0x9a, 0x06, 0x14, 0x00, 0x07, - 0x00, 0x20, 0x00, 0x23, 0x00, 0x00, 0x12, 0x10, 0x16, 0x32, 0x36, 0x10, - 0x26, 0x22, 0x05, 0x11, 0x33, 0x11, 0x21, 0x15, 0x01, 0x21, 0x15, 0x21, - 0x2b, 0x01, 0x35, 0x06, 0x07, 0x06, 0x23, 0x22, 0x02, 0x10, 0x12, 0x33, - 0x32, 0x17, 0x16, 0x17, 0x11, 0x01, 0xa8, 0x64, 0xaf, 0x65, 0x65, 0xaf, - 0x01, 0x14, 0x6e, 0x02, 0x0b, 0xfe, 0x61, 0x01, 0x9f, 0xfd, 0xf5, 0x10, - 0x5e, 0x21, 0x3b, 0x38, 0x4e, 0x80, 0xa1, 0xa1, 0x80, 0x4e, 0x38, 0x3a, - 0x90, 0x01, 0x8f, 0x02, 0xfa, 0xfe, 0x6a, 0xe7, 0xe7, 0x01, 0x96, 0xe7, - 0x2b, 0x02, 0x5e, 0xfe, 0x4c, 0xa8, 0xfc, 0xdb, 0x93, 0xa8, 0x61, 0x33, - 0x31, 0x01, 0x44, 0x02, 0x10, 0x01, 0x44, 0x31, 0x30, 0x4d, 0xfc, 0xfb, - 0x03, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1b, 0xfe, 0x4c, 0x04, 0xb4, - 0x06, 0x14, 0x00, 0x0d, 0x00, 0x43, 0x00, 0x00, 0x12, 0x10, 0x17, 0x16, - 0x33, 0x32, 0x37, 0x36, 0x10, 0x27, 0x26, 0x23, 0x22, 0x07, 0x25, 0x13, - 0x23, 0x35, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x10, 0x37, 0x36, - 0x33, 0x32, 0x17, 0x16, 0x17, 0x11, 0x33, 0x03, 0x21, 0x15, 0x03, 0x32, - 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, - 0x35, 0x1e, 0x01, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x2b, - 0x01, 0x35, 0x01, 0x21, 0x8d, 0x32, 0x32, 0x58, 0x57, 0x33, 0x32, 0x32, - 0x33, 0x57, 0x58, 0x32, 0x01, 0xb4, 0x01, 0x6f, 0x23, 0x35, 0x35, 0x4a, - 0x7a, 0x4c, 0x4d, 0x4d, 0x4c, 0x7a, 0x4a, 0x35, 0x35, 0x23, 0x6f, 0x01, - 0x02, 0x0c, 0xf6, 0x3f, 0x4d, 0x3b, 0x33, 0x31, 0xb6, 0xa8, 0x39, 0x3b, - 0x3c, 0x40, 0x33, 0x78, 0x41, 0x72, 0x3b, 0x3c, 0x37, 0x38, 0x63, 0x68, - 0x01, 0x02, 0xfe, 0x71, 0x02, 0xfa, 0xfe, 0x6a, 0x74, 0x73, 0x73, 0x74, - 0x01, 0x96, 0x74, 0x73, 0x73, 0x5f, 0xfc, 0x33, 0xa8, 0x64, 0x30, 0x31, - 0xa2, 0xa2, 0x02, 0x10, 0xa2, 0xa2, 0x31, 0x30, 0x64, 0x02, 0x5e, 0xfe, - 0x4c, 0xa8, 0xfe, 0x24, 0x38, 0x2a, 0x6d, 0x68, 0x8a, 0xdd, 0xf2, 0x12, - 0x13, 0x25, 0xc3, 0x31, 0x32, 0x4b, 0x4b, 0x8f, 0x84, 0x4b, 0x4a, 0xa6, - 0x01, 0xf3, 0x00, 0x00, 0x00, 0x04, 0x00, 0x36, 0xff, 0x91, 0x04, 0x99, - 0x06, 0x14, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x2c, 0x00, 0x33, 0x00, 0x00, - 0x12, 0x10, 0x16, 0x32, 0x36, 0x10, 0x26, 0x22, 0x05, 0x13, 0x01, 0x21, - 0x35, 0x21, 0x15, 0x01, 0x33, 0x12, 0x33, 0x32, 0x15, 0x16, 0x2b, 0x01, - 0x06, 0x15, 0x23, 0x34, 0x37, 0x27, 0x23, 0x35, 0x0e, 0x01, 0x23, 0x22, - 0x02, 0x10, 0x12, 0x33, 0x32, 0x16, 0x17, 0x11, 0x33, 0x01, 0x33, 0x32, - 0x35, 0x34, 0x23, 0x06, 0xa9, 0x64, 0xaf, 0x65, 0x65, 0xaf, 0x01, 0x7f, - 0x03, 0x01, 0x8d, 0xfe, 0x73, 0x02, 0x09, 0xfe, 0x61, 0x69, 0x24, 0x84, - 0x88, 0x01, 0xc8, 0x19, 0x02, 0x5c, 0x01, 0xd8, 0x5c, 0x23, 0x6a, 0x4b, - 0x79, 0x99, 0x99, 0x79, 0x4b, 0x6a, 0x23, 0x6e, 0x01, 0x30, 0x0c, 0x68, - 0x2a, 0x35, 0x02, 0xfa, 0xfe, 0x6a, 0xe7, 0xe7, 0x01, 0x96, 0xe7, 0x14, - 0xfc, 0xfe, 0x03, 0x02, 0x93, 0xa8, 0xfc, 0xdb, 0x01, 0x20, 0xf6, 0xbd, - 0x33, 0x3c, 0x53, 0x1b, 0x01, 0xa8, 0x64, 0x61, 0x01, 0x44, 0x02, 0x10, - 0x01, 0x44, 0x61, 0x64, 0x02, 0x5e, 0xfa, 0x7f, 0x36, 0x5b, 0x02, 0x00, - 0x00, 0x01, 0x00, 0x99, 0xff, 0xe3, 0x04, 0x38, 0x05, 0x9e, 0x00, 0x3e, - 0x00, 0x00, 0x01, 0x15, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, - 0x1f, 0x01, 0x16, 0x17, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x27, 0x26, - 0x27, 0x15, 0x23, 0x22, 0x26, 0x35, 0x11, 0x23, 0x35, 0x33, 0x11, 0x33, - 0x11, 0x33, 0x15, 0x23, 0x11, 0x14, 0x16, 0x3b, 0x01, 0x35, 0x1e, 0x01, - 0x33, 0x32, 0x36, 0x35, 0x34, 0x27, 0x26, 0x2f, 0x01, 0x2e, 0x01, 0x35, - 0x34, 0x36, 0x33, 0x32, 0x16, 0x04, 0x14, 0x2f, 0x65, 0x36, 0x52, 0x52, - 0x3b, 0x59, 0x25, 0x77, 0x30, 0x32, 0x94, 0x82, 0x36, 0x3a, 0x38, 0x3e, - 0x71, 0x80, 0x61, 0x51, 0x51, 0x6f, 0xe3, 0xe3, 0x2d, 0x45, 0x6b, 0x3e, - 0x76, 0x3b, 0x4e, 0x54, 0x1f, 0x1b, 0x6a, 0x26, 0x67, 0x5b, 0x87, 0x7b, - 0x3d, 0x6c, 0x04, 0x3f, 0xae, 0x28, 0x28, 0x54, 0x54, 0x40, 0x49, 0x21, - 0x0e, 0x2c, 0x4b, 0x4c, 0x89, 0x9c, 0xb6, 0x11, 0x11, 0x21, 0x26, 0x9f, - 0xd2, 0x02, 0x60, 0x8f, 0x01, 0x3e, 0xfe, 0xc2, 0x8f, 0xfd, 0xa0, 0x89, - 0x4e, 0x4d, 0x35, 0x35, 0x59, 0x51, 0x4b, 0x28, 0x24, 0x29, 0x0f, 0x24, - 0x95, 0x82, 0x9e, 0xac, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x99, - 0xfe, 0x56, 0x04, 0x34, 0x06, 0x14, 0x00, 0x25, 0x00, 0x2e, 0x00, 0x00, - 0x01, 0x11, 0x21, 0x35, 0x34, 0x37, 0x36, 0x3b, 0x01, 0x15, 0x23, 0x22, - 0x07, 0x06, 0x15, 0x13, 0x14, 0x07, 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, - 0x37, 0x36, 0x3d, 0x01, 0x23, 0x22, 0x27, 0x26, 0x35, 0x11, 0x23, 0x35, - 0x33, 0x11, 0x01, 0x02, 0x11, 0x21, 0x11, 0x14, 0x17, 0x16, 0x33, 0x01, - 0x89, 0x01, 0x19, 0x41, 0x3c, 0x93, 0x82, 0x84, 0x4a, 0x1c, 0x1e, 0x02, - 0x3d, 0x3d, 0x88, 0x35, 0x25, 0x4e, 0x1d, 0x1d, 0x8d, 0xa1, 0x3b, 0x3d, - 0x65, 0x65, 0x01, 0xa5, 0x01, 0xfe, 0xe7, 0x1c, 0x1d, 0x55, 0x05, 0x9e, - 0xfe, 0xc2, 0x4e, 0xb6, 0x5a, 0x56, 0x99, 0x28, 0x29, 0x67, 0xfb, 0x29, - 0xd7, 0x5f, 0x60, 0x9c, 0x30, 0x32, 0x98, 0x14, 0x50, 0x4d, 0xd4, 0x02, - 0x60, 0x8f, 0x01, 0x3e, 0xfa, 0xfc, 0x01, 0x17, 0x02, 0x20, 0xfd, 0xa0, - 0x8a, 0x26, 0x27, 0x00, 0x00, 0x03, 0x00, 0xb5, 0xff, 0x70, 0x04, 0x12, - 0x05, 0x9e, 0x00, 0x2e, 0x00, 0x36, 0x00, 0x40, 0x00, 0x00, 0x01, 0x11, - 0x33, 0x15, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x15, 0x26, 0x27, 0x26, - 0x23, 0x22, 0x07, 0x06, 0x10, 0x17, 0x16, 0x17, 0x36, 0x33, 0x32, 0x17, - 0x14, 0x23, 0x22, 0x27, 0x06, 0x15, 0x07, 0x34, 0x37, 0x26, 0x27, 0x15, - 0x23, 0x22, 0x26, 0x35, 0x11, 0x23, 0x35, 0x33, 0x11, 0x01, 0x16, 0x33, - 0x32, 0x35, 0x34, 0x23, 0x22, 0x07, 0x26, 0x35, 0x10, 0x37, 0x23, 0x11, - 0x14, 0x16, 0x33, 0x01, 0x75, 0xe4, 0x5a, 0x9d, 0x33, 0x31, 0x30, 0x2e, - 0x2f, 0x2f, 0x2f, 0x30, 0x6c, 0x3b, 0x3b, 0x3b, 0x04, 0x04, 0x32, 0x76, - 0xb3, 0x01, 0xc8, 0x31, 0x2b, 0x03, 0x5c, 0x07, 0x21, 0x1c, 0x72, 0x80, - 0x61, 0x51, 0x51, 0x01, 0xfe, 0x24, 0x2d, 0x57, 0x4f, 0x3d, 0xd5, 0x4d, - 0x54, 0xdd, 0x2d, 0x45, 0x05, 0x9e, 0xfe, 0xc2, 0x82, 0x9d, 0x11, 0x12, - 0x23, 0xac, 0x2b, 0x16, 0x15, 0x71, 0x72, 0xfe, 0x66, 0x72, 0x07, 0x07, - 0xb0, 0xf6, 0xbd, 0x11, 0x39, 0x44, 0x03, 0x68, 0x54, 0x22, 0x32, 0x80, - 0x9f, 0xd2, 0x02, 0x60, 0x8f, 0x01, 0x3e, 0xfa, 0xf4, 0x13, 0x39, 0x4b, - 0x69, 0x9d, 0xf8, 0x01, 0x07, 0x9b, 0xfd, 0xa0, 0x89, 0x4e, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x87, 0xfe, 0x56, 0x04, 0x48, 0x06, 0x14, 0x00, 0x33, - 0x00, 0x00, 0x01, 0x11, 0x14, 0x07, 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, - 0x37, 0x36, 0x35, 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, - 0x11, 0x23, 0x11, 0x23, 0x11, 0x23, 0x35, 0x33, 0x35, 0x34, 0x36, 0x3b, - 0x01, 0x15, 0x23, 0x22, 0x06, 0x1d, 0x01, 0x3b, 0x02, 0x15, 0x36, 0x37, - 0x36, 0x33, 0x32, 0x17, 0x16, 0x04, 0x47, 0x31, 0x31, 0x6c, 0x99, 0x8c, - 0x3f, 0x17, 0x17, 0x4b, 0x4a, 0x59, 0x68, 0x6f, 0xb4, 0x6e, 0x6a, 0x6a, - 0x68, 0x71, 0x69, 0x6a, 0x3b, 0x2f, 0xb4, 0x02, 0x6d, 0x28, 0x35, 0x36, - 0x46, 0x74, 0x3c, 0x3b, 0x02, 0xa4, 0xfd, 0x48, 0xd6, 0x60, 0x60, 0x9c, - 0x30, 0x31, 0x99, 0x02, 0xb2, 0x9f, 0x9e, 0xbe, 0xa4, 0xfd, 0x87, 0x03, - 0xd1, 0xfc, 0x2f, 0x03, 0xd1, 0x8f, 0x4e, 0xbb, 0xab, 0x99, 0x50, 0x68, - 0x63, 0xae, 0x65, 0x32, 0x32, 0x77, 0x78, 0x00, 0x00, 0x02, 0x00, 0xe6, - 0xff, 0xe3, 0x03, 0xeb, 0x06, 0x14, 0x00, 0x25, 0x00, 0x37, 0x00, 0x00, - 0x01, 0x15, 0x26, 0x27, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x17, 0x16, - 0x1f, 0x01, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, - 0x26, 0x27, 0x15, 0x23, 0x11, 0x33, 0x11, 0x36, 0x37, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x01, 0x11, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, - 0x34, 0x27, 0x26, 0x2f, 0x01, 0x26, 0x27, 0x26, 0x03, 0xbe, 0x3b, 0x3e, - 0x41, 0x42, 0x67, 0x66, 0x24, 0x26, 0x6e, 0x2f, 0x95, 0x3c, 0x3e, 0x5d, - 0x5b, 0xa3, 0x41, 0x4c, 0x4f, 0x44, 0x8a, 0x8a, 0x08, 0x4b, 0x54, 0x9b, - 0x4c, 0x44, 0x43, 0xfd, 0xeb, 0x4b, 0x45, 0x4a, 0x49, 0x61, 0x35, 0x34, - 0x25, 0x22, 0x85, 0x30, 0x80, 0x39, 0x32, 0x04, 0x3f, 0xae, 0x29, 0x13, - 0x14, 0x54, 0x54, 0x3f, 0x26, 0x24, 0x21, 0x0e, 0x2c, 0x4b, 0x4c, 0x89, - 0x9b, 0x5c, 0x5b, 0x11, 0x15, 0x1d, 0x26, 0x06, 0x14, 0xfd, 0x3a, 0x8a, - 0x4d, 0x56, 0x0f, 0x0f, 0xfe, 0xb7, 0xfd, 0xce, 0x33, 0x17, 0x1b, 0x2d, - 0x2b, 0x52, 0x4b, 0x28, 0x23, 0x2a, 0x0f, 0x24, 0x4a, 0x41, 0x00, 0x00, - 0x00, 0x02, 0x00, 0xdb, 0x00, 0x00, 0x03, 0xf4, 0x06, 0x14, 0x00, 0x0a, - 0x00, 0x0d, 0x00, 0x00, 0x13, 0x33, 0x11, 0x21, 0x15, 0x01, 0x21, 0x15, - 0x21, 0x2b, 0x01, 0x13, 0x11, 0x01, 0xdb, 0x8a, 0x02, 0x8f, 0xfd, 0xf9, - 0x02, 0x07, 0xfd, 0x71, 0x14, 0x76, 0x8a, 0x01, 0xf3, 0x06, 0x14, 0xfe, - 0x4c, 0xa8, 0xfc, 0xdb, 0x93, 0x03, 0xcd, 0xfc, 0xfa, 0x03, 0x06, 0x00, - 0x00, 0x02, 0x00, 0x8f, 0xff, 0xe2, 0x04, 0x42, 0x05, 0x20, 0x00, 0x0c, - 0x00, 0x19, 0x00, 0x00, 0x13, 0x33, 0x1b, 0x01, 0x33, 0x1b, 0x01, 0x33, - 0x03, 0x23, 0x0b, 0x01, 0x23, 0x03, 0x33, 0x1b, 0x01, 0x33, 0x1b, 0x01, - 0x33, 0x03, 0x23, 0x0b, 0x01, 0x23, 0x8f, 0x74, 0x91, 0x90, 0x89, 0x91, - 0x90, 0x74, 0xb9, 0x88, 0x98, 0x99, 0x88, 0xb9, 0x74, 0x91, 0x90, 0x89, - 0x91, 0x90, 0x74, 0xb9, 0x88, 0x98, 0x99, 0x88, 0x02, 0x55, 0xfe, 0x17, - 0x01, 0xe9, 0xfe, 0x17, 0x01, 0xe9, 0xfd, 0x8d, 0x02, 0x02, 0xfd, 0xfe, - 0x05, 0x3d, 0xfe, 0x17, 0x01, 0xe9, 0xfe, 0x17, 0x01, 0xe9, 0xfd, 0x8d, - 0x02, 0x02, 0xfd, 0xfe, 0x00, 0x02, 0x00, 0x8f, 0x00, 0xad, 0x04, 0x42, - 0x05, 0x1f, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x00, 0x13, 0x21, 0x11, 0x23, - 0x11, 0x21, 0x11, 0x23, 0x11, 0x21, 0x11, 0x23, 0x11, 0x21, 0x11, 0x23, - 0x8f, 0x03, 0xb3, 0x8f, 0xfd, 0x6b, 0x8f, 0x03, 0xb3, 0x8f, 0xfd, 0x6b, - 0x8f, 0x02, 0x55, 0xfe, 0x58, 0x01, 0x05, 0xfe, 0xfb, 0x04, 0x72, 0xfe, - 0x58, 0x01, 0x05, 0xfe, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb2, - 0xfe, 0x4a, 0x04, 0x1f, 0x06, 0x14, 0x00, 0x18, 0x00, 0x00, 0x05, 0x20, - 0x19, 0x01, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x16, 0x15, 0x11, - 0x10, 0x33, 0x32, 0x36, 0x35, 0x11, 0x33, 0x11, 0x23, 0x11, 0x06, 0x02, - 0x84, 0xfe, 0xdb, 0x39, 0x4f, 0x25, 0x35, 0x88, 0x7a, 0xba, 0x70, 0x81, - 0x8a, 0x8a, 0x63, 0x1d, 0x01, 0xd7, 0x02, 0xc4, 0x99, 0x61, 0x9c, 0xc0, - 0xd6, 0xfd, 0x42, 0xfe, 0xc3, 0xbe, 0xa4, 0x02, 0x79, 0xf9, 0xec, 0x02, - 0x62, 0xc9, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc5, 0xfe, 0x56, 0x04, 0x0c, - 0x06, 0x14, 0x00, 0x22, 0x00, 0x00, 0x01, 0x10, 0x33, 0x32, 0x36, 0x35, - 0x11, 0x33, 0x11, 0x06, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, 0x26, - 0x27, 0x35, 0x06, 0x23, 0x22, 0x19, 0x01, 0x34, 0x27, 0x26, 0x2b, 0x01, - 0x35, 0x33, 0x32, 0x16, 0x15, 0x01, 0xbe, 0x94, 0x5a, 0x67, 0x6f, 0x02, - 0x30, 0x3e, 0x1e, 0x2a, 0x6d, 0x2f, 0x32, 0x01, 0x4f, 0x8a, 0xeb, 0x17, - 0x17, 0x3f, 0x1d, 0x2a, 0x6d, 0x62, 0x01, 0xc0, 0xfe, 0xc3, 0xbe, 0xa4, - 0x02, 0x79, 0xfb, 0x8e, 0x94, 0x66, 0x9c, 0x5c, 0x67, 0xe7, 0xac, 0xc9, - 0x01, 0xd7, 0x02, 0xc4, 0x99, 0x31, 0x30, 0x9c, 0xc0, 0xd6, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x41, 0x02, 0x9c, 0x03, 0x90, 0x06, 0x04, 0x00, 0x13, - 0x00, 0x20, 0x40, 0x06, 0x00, 0x03, 0x0e, 0x0a, 0x0b, 0x14, 0x10, 0xd4, - 0xdc, 0x3c, 0x2f, 0xcc, 0x4b, 0x31, 0x00, 0x40, 0x06, 0x06, 0x11, 0x0c, - 0x02, 0x0b, 0x14, 0x10, 0xd4, 0x3c, 0xc4, 0xd4, 0xcc, 0x30, 0x01, 0x11, - 0x23, 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, - 0x11, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x03, 0x90, 0x74, 0x4e, 0x4e, 0x5e, - 0x6c, 0x75, 0x75, 0x29, 0x71, 0x4a, 0x79, 0x7d, 0x04, 0x17, 0xfe, 0x85, - 0x01, 0x77, 0x59, 0x59, 0x6b, 0x5c, 0xfe, 0x9e, 0x03, 0x67, 0xfe, 0xab, - 0x38, 0x38, 0x86, 0x00, 0x00, 0x01, 0x01, 0x41, 0x02, 0x9a, 0x03, 0x90, - 0x06, 0x02, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x33, 0x3e, 0x01, 0x33, 0x32, - 0x16, 0x15, 0x11, 0x23, 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x11, - 0x23, 0x11, 0x35, 0x34, 0x37, 0x36, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x07, - 0x06, 0x15, 0x01, 0xb5, 0x01, 0x29, 0x71, 0x4a, 0x79, 0x7d, 0x74, 0x4e, - 0x4e, 0x5e, 0x6c, 0x75, 0x34, 0x33, 0x72, 0xa0, 0x93, 0x42, 0x18, 0x18, - 0x04, 0xac, 0x39, 0x38, 0x86, 0x82, 0xfe, 0x86, 0x01, 0x77, 0x59, 0x58, - 0x6a, 0x5c, 0xfe, 0x9e, 0x02, 0x31, 0x53, 0x77, 0x36, 0x36, 0x57, 0x1b, - 0x1c, 0x55, 0x00, 0x00, 0x00, 0x02, 0x01, 0xe6, 0x01, 0xad, 0x02, 0xeb, - 0x06, 0x04, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x00, 0x01, 0x33, 0x11, 0x14, - 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x36, 0x35, 0x11, 0x33, 0x15, 0x23, - 0x02, 0x77, 0x74, 0x67, 0x72, 0x2c, 0x1f, 0x42, 0x30, 0x74, 0x74, 0x05, - 0x0f, 0xfd, 0x82, 0x78, 0x6c, 0x58, 0x36, 0x56, 0x03, 0x72, 0x82, 0x00, - 0x00, 0x01, 0x01, 0x99, 0x02, 0x9c, 0x03, 0x38, 0x05, 0x1f, 0x00, 0x11, - 0x00, 0x00, 0x01, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, 0x11, - 0x33, 0x15, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x17, 0x03, 0x37, 0x13, 0x2e, - 0x1c, 0x62, 0x6a, 0x74, 0x74, 0x25, 0x75, 0x54, 0x0c, 0x1d, 0x12, 0x04, - 0xaf, 0x0a, 0x09, 0x71, 0x6b, 0xfe, 0xb6, 0x02, 0x73, 0x61, 0x39, 0x37, - 0x02, 0x03, 0x00, 0x00, 0x00, 0x01, 0x01, 0x99, 0x02, 0x8c, 0x03, 0x38, - 0x05, 0x10, 0x00, 0x11, 0x00, 0x00, 0x01, 0x1e, 0x01, 0x33, 0x32, 0x36, - 0x35, 0x11, 0x33, 0x11, 0x23, 0x35, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x27, - 0x01, 0x9a, 0x13, 0x2e, 0x1c, 0x62, 0x6a, 0x74, 0x74, 0x25, 0x75, 0x54, - 0x0c, 0x1d, 0x12, 0x02, 0xfc, 0x0a, 0x09, 0x71, 0x6b, 0x01, 0x4a, 0xfd, - 0x8d, 0x61, 0x39, 0x37, 0x03, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01, 0x51, - 0x01, 0xad, 0x03, 0x80, 0x05, 0x10, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x1e, - 0x01, 0x33, 0x32, 0x36, 0x35, 0x11, 0x33, 0x11, 0x1d, 0x01, 0x14, 0x17, - 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, 0x26, 0x3d, 0x01, 0x23, 0x35, - 0x0e, 0x01, 0x23, 0x22, 0x26, 0x27, 0x01, 0x51, 0x14, 0x2e, 0x1c, 0x62, - 0x69, 0x75, 0x18, 0x18, 0x42, 0x1f, 0x2d, 0x72, 0x33, 0x33, 0x01, 0x24, - 0x76, 0x53, 0x0c, 0x1d, 0x12, 0x02, 0xfc, 0x0a, 0x09, 0x71, 0x6b, 0x01, - 0x4a, 0xfd, 0xd5, 0x48, 0x0b, 0x56, 0x1b, 0x1b, 0x58, 0x36, 0x36, 0x78, - 0x0b, 0x61, 0x39, 0x37, 0x03, 0x02, 0x00, 0x00, 0x00, 0x02, 0x01, 0x30, - 0x02, 0x9c, 0x03, 0xa1, 0x05, 0x10, 0x00, 0x16, 0x00, 0x21, 0x00, 0x00, - 0x01, 0x1e, 0x01, 0x15, 0x14, 0x07, 0x06, 0x2b, 0x01, 0x11, 0x33, 0x11, - 0x33, 0x32, 0x37, 0x36, 0x3f, 0x01, 0x33, 0x07, 0x06, 0x07, 0x06, 0x01, - 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x2b, 0x01, 0x02, 0xac, - 0x43, 0x47, 0x44, 0x44, 0x89, 0xf4, 0x75, 0x6a, 0x3d, 0x25, 0x25, 0x28, - 0x66, 0x7b, 0x6e, 0x21, 0x21, 0x21, 0xfe, 0xd7, 0x7c, 0x4b, 0x28, 0x28, - 0x28, 0x28, 0x4b, 0x7c, 0x03, 0xe9, 0x0f, 0x4e, 0x3b, 0x5b, 0x2d, 0x2d, - 0x02, 0x73, 0xfe, 0xf7, 0x15, 0x14, 0x3f, 0xa1, 0xab, 0x35, 0x1e, 0x1e, - 0xff, 0x00, 0x17, 0x18, 0x2f, 0x2e, 0x18, 0x19, 0x00, 0x01, 0x00, 0x8f, - 0x02, 0x9c, 0x04, 0x42, 0x05, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x13, 0x33, - 0x1b, 0x01, 0x33, 0x1b, 0x01, 0x33, 0x03, 0x23, 0x0b, 0x01, 0x23, 0x8f, - 0x74, 0x91, 0x90, 0x89, 0x91, 0x90, 0x74, 0xb9, 0x88, 0x98, 0x99, 0x88, - 0x05, 0x0f, 0xfe, 0x17, 0x01, 0xe9, 0xfe, 0x17, 0x01, 0xe9, 0xfd, 0x8d, - 0x02, 0x02, 0xfd, 0xfe, 0x00, 0x01, 0x01, 0x11, 0x01, 0xad, 0x03, 0xc0, - 0x05, 0x10, 0x00, 0x0f, 0x00, 0x00, 0x01, 0x0e, 0x01, 0x2b, 0x01, 0x35, - 0x33, 0x32, 0x36, 0x3f, 0x01, 0x01, 0x33, 0x1b, 0x01, 0x33, 0x02, 0x8a, - 0x31, 0x5d, 0x4f, 0x5c, 0x44, 0x30, 0x35, 0x20, 0x15, 0xfe, 0xe2, 0x7b, - 0xdc, 0xdd, 0x7b, 0x02, 0x62, 0x70, 0x45, 0x57, 0x28, 0x4b, 0x2f, 0x02, - 0x69, 0xfe, 0x16, 0x01, 0xea, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0xec, - 0x04, 0x74, 0x02, 0xeb, 0x06, 0x66, 0x10, 0x06, 0x02, 0xcb, 0x00, 0x00, - 0xff, 0xff, 0x01, 0xcf, 0x03, 0xc7, 0x03, 0x2d, 0x06, 0x14, 0x10, 0x06, - 0x07, 0x1c, 0x00, 0x00, 0xff, 0xff, 0x01, 0xcf, 0x03, 0xc7, 0x03, 0x2d, - 0x06, 0x14, 0x10, 0x06, 0x07, 0x1d, 0x00, 0x00, 0xff, 0xff, 0x01, 0xf0, - 0x04, 0xc2, 0x02, 0xe1, 0x06, 0xc1, 0x10, 0x06, 0x02, 0x9c, 0x00, 0x00, - 0x00, 0x01, 0x01, 0xdf, 0x03, 0xef, 0x02, 0xf2, 0x06, 0x14, 0x00, 0x10, - 0x00, 0x00, 0x01, 0x34, 0x35, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x34, - 0x35, 0x32, 0x17, 0x16, 0x14, 0x07, 0x06, 0x01, 0xe0, 0x40, 0x58, 0x58, - 0x40, 0x72, 0x50, 0x50, 0x50, 0x50, 0x03, 0xef, 0x3d, 0x3e, 0x58, 0x40, - 0x3f, 0x58, 0x3d, 0x3e, 0x50, 0x4f, 0xe6, 0x50, 0x50, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0xdf, 0x03, 0xef, 0x02, 0xf2, 0x06, 0x14, 0x00, 0x10, - 0x00, 0x00, 0x01, 0x22, 0x27, 0x26, 0x34, 0x37, 0x36, 0x33, 0x14, 0x15, - 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x14, 0x02, 0xf2, 0x74, 0x50, 0x4e, - 0x4e, 0x50, 0x74, 0x40, 0x58, 0x58, 0x40, 0x03, 0xef, 0x50, 0x50, 0xe6, - 0x4f, 0x50, 0x3e, 0x3d, 0x58, 0x3f, 0x40, 0x58, 0x3e, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x5e, 0x03, 0x8e, 0x03, 0x73, 0x06, 0xf5, 0x00, 0x1c, - 0x00, 0x00, 0x01, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, - 0x22, 0x07, 0x06, 0x07, 0x35, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x06, 0x07, 0x11, 0x23, 0x01, 0xfd, 0x28, 0x79, 0x36, - 0x24, 0x24, 0x3e, 0x71, 0x33, 0x31, 0x32, 0x31, 0x30, 0x33, 0x33, 0x36, - 0xad, 0x57, 0x45, 0x44, 0x47, 0x6b, 0x7f, 0x05, 0x4d, 0x40, 0x2a, 0x37, - 0x4b, 0x24, 0x40, 0x0c, 0x0c, 0x18, 0x60, 0x14, 0x09, 0x0a, 0x58, 0x46, - 0x68, 0x5f, 0x40, 0x43, 0x11, 0xfe, 0x93, 0x00, 0x00, 0x01, 0x01, 0x5e, - 0x03, 0x8e, 0x03, 0x73, 0x06, 0xf5, 0x00, 0x1c, 0x00, 0x00, 0x01, 0x11, - 0x23, 0x11, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, - 0x16, 0x17, 0x15, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, - 0x17, 0x16, 0x33, 0x02, 0xd3, 0x7f, 0x6b, 0x47, 0x44, 0x46, 0x56, 0xad, - 0x36, 0x33, 0x33, 0x30, 0x31, 0x32, 0x31, 0x33, 0x71, 0x3e, 0x24, 0x24, - 0x36, 0x79, 0x05, 0x4d, 0xfe, 0x41, 0x01, 0x6d, 0x11, 0x43, 0x40, 0x5f, - 0x68, 0x46, 0x58, 0x0a, 0x09, 0x14, 0x60, 0x18, 0x0c, 0x0c, 0x40, 0x24, - 0x4b, 0x37, 0x2a, 0x40, 0x00, 0x01, 0x01, 0x29, 0x04, 0xee, 0x03, 0xa8, - 0x06, 0x66, 0x00, 0x06, 0x00, 0x37, 0x40, 0x0c, 0x04, 0x05, 0x02, 0xba, - 0x00, 0xb9, 0x07, 0x04, 0x02, 0x0b, 0x06, 0x07, 0x10, 0xd4, 0xec, 0x39, - 0x31, 0x00, 0x10, 0xf4, 0xec, 0x32, 0x39, 0x30, 0x00, 0x4b, 0xb0, 0x09, - 0x54, 0x4b, 0xb0, 0x0e, 0x54, 0x5b, 0x58, 0xbd, 0x00, 0x07, 0xff, 0xc0, - 0x00, 0x01, 0x00, 0x07, 0x00, 0x07, 0x00, 0x40, 0x38, 0x11, 0x37, 0x38, - 0x59, 0x01, 0x33, 0x13, 0x23, 0x27, 0x07, 0x23, 0x02, 0x1f, 0x93, 0xf6, - 0x8b, 0xb5, 0xb4, 0x8b, 0x06, 0x66, 0xfe, 0x88, 0xf5, 0xf5, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x29, 0x04, 0xee, 0x03, 0xa8, 0x06, 0x66, 0x00, 0x06, - 0x00, 0x37, 0x40, 0x0c, 0x03, 0x00, 0xba, 0x04, 0x01, 0xb9, 0x07, 0x03, - 0x05, 0x0b, 0x01, 0x07, 0x10, 0xd4, 0xec, 0x39, 0x31, 0x00, 0x10, 0xf4, - 0x3c, 0xec, 0x39, 0x30, 0x00, 0x4b, 0xb0, 0x09, 0x54, 0x4b, 0xb0, 0x0e, - 0x54, 0x5b, 0x58, 0xbd, 0x00, 0x07, 0xff, 0xc0, 0x00, 0x01, 0x00, 0x07, - 0x00, 0x07, 0x00, 0x40, 0x38, 0x11, 0x37, 0x38, 0x59, 0x01, 0x03, 0x33, - 0x17, 0x37, 0x33, 0x03, 0x02, 0x1f, 0xf6, 0x8b, 0xb4, 0xb5, 0x8b, 0xf6, - 0x04, 0xee, 0x01, 0x78, 0xf5, 0xf5, 0xfe, 0x88, 0x00, 0x01, 0x02, 0x24, - 0x03, 0xe7, 0x02, 0xad, 0x06, 0x12, 0x00, 0x03, 0x00, 0x13, 0x40, 0x03, - 0x00, 0x03, 0x04, 0x10, 0xd4, 0xcc, 0x31, 0x00, 0x40, 0x03, 0x03, 0x02, - 0x04, 0x10, 0xd4, 0xc4, 0x30, 0x01, 0x11, 0x23, 0x11, 0x02, 0xac, 0x88, - 0x06, 0x12, 0xfd, 0xd5, 0x02, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x01, 0x3d, - 0x05, 0x62, 0x03, 0x93, 0x05, 0xf6, 0x10, 0x06, 0x02, 0x8c, 0x00, 0x00, - 0x00, 0x01, 0x02, 0x24, 0xfe, 0xd1, 0x02, 0xad, 0x00, 0xfc, 0x00, 0x03, - 0x00, 0x13, 0x40, 0x03, 0x00, 0x03, 0x04, 0x10, 0xd4, 0xcc, 0x31, 0x00, - 0x40, 0x03, 0x03, 0x02, 0x04, 0x10, 0xd4, 0xc4, 0x30, 0x25, 0x11, 0x23, - 0x11, 0x02, 0xac, 0x88, 0xfc, 0xfd, 0xd5, 0x02, 0x2b, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x3d, 0xfe, 0x9b, 0x03, 0x94, 0xff, 0x2f, 0x10, 0x06, - 0x02, 0xb9, 0x00, 0x00, 0xff, 0xff, 0x01, 0x79, 0xfd, 0xb8, 0x03, 0x58, - 0xff, 0x30, 0x10, 0x07, 0x00, 0x43, 0x00, 0x62, 0xf8, 0xca, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x79, 0xfd, 0xb8, 0x03, 0x58, 0xff, 0x30, 0x10, 0x07, - 0x00, 0x76, 0xff, 0x9e, 0xf8, 0xca, 0x00, 0x00, 0x00, 0x02, 0x01, 0xb6, - 0x00, 0x00, 0x03, 0x1b, 0x04, 0x23, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, - 0x01, 0x03, 0x21, 0x03, 0x13, 0x21, 0x02, 0x68, 0xb2, 0x01, 0x65, 0xb3, - 0xb3, 0xfe, 0x9b, 0x02, 0xd9, 0x01, 0x4a, 0xfd, 0x27, 0xfe, 0xb6, 0x00, - 0x00, 0x01, 0x01, 0xb6, 0x02, 0xd8, 0x03, 0x1b, 0x04, 0x23, 0x00, 0x02, - 0x00, 0x00, 0x01, 0x03, 0x21, 0x02, 0x68, 0xb2, 0x01, 0x65, 0x02, 0xd9, - 0x01, 0x4a, 0x00, 0x00, 0xff, 0xff, 0x01, 0xdf, 0x01, 0xfe, 0x02, 0xf2, - 0x04, 0x23, 0x10, 0x07, 0x02, 0x63, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, - 0xff, 0xff, 0x01, 0xdf, 0x01, 0xfe, 0x02, 0xf2, 0x04, 0x23, 0x10, 0x07, - 0x02, 0x64, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0x00, 0x01, 0x01, 0x3e, - 0x00, 0xff, 0x03, 0x94, 0x03, 0x55, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x35, - 0x33, 0x15, 0x33, 0x15, 0x23, 0x15, 0x23, 0x35, 0x23, 0x35, 0x02, 0x1e, - 0x96, 0xe0, 0xe0, 0x96, 0xe0, 0x02, 0x75, 0xe0, 0xe0, 0x96, 0xe0, 0xe0, - 0x96, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x88, 0x01, 0xdf, 0x03, 0x4a, - 0x02, 0x75, 0x00, 0x03, 0x00, 0x00, 0x01, 0x21, 0x35, 0x21, 0x03, 0x4a, - 0xfe, 0x3e, 0x01, 0xc2, 0x01, 0xdf, 0x96, 0x00, 0xff, 0xff, 0x01, 0x2f, - 0x05, 0x29, 0x03, 0xa2, 0x06, 0x48, 0x10, 0x06, 0x02, 0x8e, 0x00, 0x00, - 0xff, 0xff, 0x02, 0x01, 0x05, 0x44, 0x02, 0xce, 0x06, 0x10, 0x10, 0x06, - 0x02, 0x8f, 0x00, 0x00, 0x00, 0x02, 0x01, 0x56, 0x04, 0xe1, 0x03, 0x7b, - 0x07, 0x06, 0x00, 0x0b, 0x00, 0x17, 0x00, 0x57, 0xb2, 0x0f, 0xc8, 0x09, - 0xb8, 0x01, 0x04, 0x40, 0x0c, 0x15, 0xc8, 0x03, 0x18, 0x0c, 0x50, 0x00, - 0x7b, 0x12, 0x50, 0x06, 0x18, 0x10, 0xd4, 0xec, 0xf4, 0xec, 0x31, 0x00, - 0x10, 0xd4, 0xec, 0xf4, 0xec, 0x30, 0x00, 0x4b, 0xb0, 0x09, 0x54, 0x4b, - 0xb0, 0x0c, 0x54, 0x5b, 0x58, 0xbd, 0x00, 0x18, 0xff, 0xc0, 0x00, 0x01, - 0x00, 0x18, 0x00, 0x18, 0x00, 0x40, 0x38, 0x11, 0x37, 0x38, 0x59, 0x01, - 0x4b, 0xb0, 0x09, 0x54, 0x58, 0xbd, 0x00, 0x18, 0x00, 0x40, 0x00, 0x01, - 0x00, 0x18, 0x00, 0x18, 0xff, 0xc0, 0x38, 0x11, 0x37, 0x38, 0x59, 0x01, - 0x14, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x07, - 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x03, - 0x7b, 0x9f, 0x74, 0x73, 0x9f, 0x9f, 0x73, 0x74, 0x9f, 0x7b, 0x58, 0x40, - 0x40, 0x57, 0x57, 0x40, 0x40, 0x58, 0x05, 0xf4, 0x73, 0xa0, 0xa0, 0x73, - 0x73, 0x9f, 0x9f, 0x73, 0x3f, 0x58, 0x57, 0x40, 0x41, 0x57, 0x58, 0x00, - 0x00, 0x01, 0x01, 0xa4, 0xfe, 0x75, 0x03, 0x19, 0x00, 0x00, 0x00, 0x13, - 0x00, 0x22, 0xb3, 0x0b, 0x0e, 0x0a, 0x07, 0xb8, 0x01, 0x06, 0x40, 0x09, - 0x0e, 0x00, 0x01, 0x00, 0x0a, 0x04, 0x7c, 0x11, 0x14, 0x10, 0xd4, 0xec, - 0xc4, 0xd4, 0xcc, 0x31, 0x00, 0x2f, 0xd4, 0xfc, 0xc4, 0x12, 0x39, 0x30, - 0x21, 0x33, 0x0e, 0x01, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x15, - 0x0e, 0x01, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x02, 0x10, 0x77, 0x2d, - 0x2b, 0x37, 0x36, 0x20, 0x3e, 0x1f, 0x26, 0x44, 0x1e, 0x7a, 0x73, 0x35, - 0x3d, 0x58, 0x1f, 0x2e, 0x2e, 0x0f, 0x0f, 0x85, 0x0a, 0x0a, 0x57, 0x5d, - 0x30, 0x69, 0x00, 0x00, 0x00, 0x01, 0x01, 0x1f, 0x05, 0x1d, 0x03, 0xb2, - 0x06, 0x37, 0x00, 0x1b, 0x00, 0xbb, 0x40, 0x21, 0x00, 0x12, 0x07, 0x0e, - 0x0b, 0x04, 0x01, 0x12, 0x07, 0x0f, 0x0b, 0x04, 0x12, 0xcc, 0x19, 0x07, - 0x04, 0xcc, 0x15, 0x0b, 0x1c, 0x0f, 0x01, 0x0e, 0x00, 0x07, 0x15, 0x50, - 0x16, 0x07, 0x50, 0x08, 0x1c, 0x10, 0xd4, 0xec, 0xd4, 0xec, 0x11, 0x39, - 0x39, 0x39, 0x39, 0x31, 0x00, 0x10, 0xd4, 0x3c, 0xfc, 0xd4, 0x3c, 0xec, - 0x11, 0x12, 0x39, 0x11, 0x12, 0x39, 0x11, 0x12, 0x39, 0x11, 0x12, 0x39, - 0x30, 0x00, 0x4b, 0xb0, 0x09, 0x54, 0x4b, 0xb0, 0x0c, 0x54, 0x5b, 0x58, - 0xbd, 0x00, 0x1c, 0xff, 0xc0, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x1c, 0x00, - 0x40, 0x38, 0x11, 0x37, 0x38, 0x59, 0x00, 0x4b, 0xb0, 0x0f, 0x54, 0x58, - 0xbd, 0x00, 0x1c, 0x00, 0x40, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x1c, 0xff, - 0xc0, 0x38, 0x11, 0x37, 0x38, 0x59, 0x40, 0x3f, 0x09, 0x00, 0x0c, 0x0a, - 0x0c, 0x0b, 0x0c, 0x0c, 0x0b, 0x0f, 0x0b, 0x10, 0x0f, 0x11, 0x0f, 0x12, - 0x0f, 0x13, 0x0f, 0x14, 0x0f, 0x15, 0x0f, 0x16, 0x0f, 0x17, 0x09, 0x1b, - 0x19, 0x00, 0x19, 0x01, 0x1b, 0x0a, 0x1b, 0x0b, 0x1b, 0x0c, 0x1b, 0x0d, - 0x1b, 0x0e, 0x1b, 0x0f, 0x1b, 0x10, 0x1b, 0x11, 0x1b, 0x12, 0x1b, 0x13, - 0x1f, 0x14, 0x1f, 0x15, 0x1f, 0x16, 0x1a, 0x17, 0x19, 0x1b, 0x1f, 0x01, - 0x5d, 0x01, 0x27, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x23, 0x3e, 0x01, - 0x33, 0x32, 0x16, 0x1f, 0x01, 0x1e, 0x01, 0x33, 0x32, 0x36, 0x37, 0x33, - 0x0e, 0x01, 0x23, 0x22, 0x26, 0x02, 0x64, 0x39, 0x15, 0x21, 0x0e, 0x26, - 0x24, 0x02, 0x7c, 0x01, 0x66, 0x5b, 0x27, 0x40, 0x25, 0x39, 0x15, 0x21, - 0x0d, 0x27, 0x24, 0x01, 0x7d, 0x01, 0x66, 0x5b, 0x27, 0x40, 0x05, 0x5a, - 0x37, 0x14, 0x13, 0x4a, 0x51, 0x86, 0x94, 0x1c, 0x21, 0x37, 0x14, 0x13, - 0x4a, 0x51, 0x86, 0x94, 0x1c, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x58, - 0x04, 0xee, 0x04, 0x17, 0x06, 0x66, 0x10, 0x06, 0x02, 0x93, 0x00, 0x00, - 0x00, 0x01, 0xfe, 0xa1, 0x01, 0xde, 0x03, 0x73, 0x04, 0x08, 0x00, 0x0f, - 0x00, 0x00, 0x01, 0x25, 0x33, 0x15, 0x14, 0x17, 0x16, 0x3b, 0x01, 0x15, - 0x21, 0x22, 0x27, 0x26, 0x35, 0x05, 0xfe, 0xa1, 0x02, 0x6b, 0xb8, 0x26, - 0x26, 0x69, 0xfa, 0xfe, 0xf1, 0xaf, 0x57, 0x52, 0xfd, 0x96, 0x03, 0x64, - 0xa4, 0x94, 0x99, 0x31, 0x30, 0x9c, 0x60, 0x5a, 0xc8, 0xa2, 0x00, 0x00, - 0x00, 0x02, 0x01, 0x25, 0x01, 0xab, 0x03, 0xac, 0x05, 0x0f, 0x00, 0x0d, - 0x00, 0x15, 0x00, 0x00, 0x01, 0x16, 0x15, 0x14, 0x07, 0x04, 0x27, 0x26, - 0x37, 0x03, 0x33, 0x17, 0x37, 0x33, 0x01, 0x06, 0x17, 0x16, 0x33, 0x32, - 0x35, 0x36, 0x02, 0xb5, 0xb2, 0xf2, 0xfe, 0xf6, 0x01, 0x01, 0xb6, 0xfa, - 0x88, 0xbf, 0xb8, 0x88, 0xfe, 0xbc, 0x8b, 0x03, 0x01, 0x87, 0x80, 0x01, - 0x03, 0xdc, 0xf9, 0xb4, 0x81, 0x03, 0x03, 0x87, 0xc0, 0xf1, 0x01, 0x2f, - 0xe0, 0xe0, 0xfe, 0x8a, 0xae, 0x98, 0x4d, 0x4d, 0x8c, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x56, 0x02, 0x9c, 0x03, 0x7c, 0x06, 0x0a, 0x00, 0x0d, - 0x00, 0x00, 0x01, 0x14, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x26, 0x35, - 0x11, 0x23, 0x35, 0x21, 0x02, 0x84, 0x38, 0x38, 0x88, 0x92, 0x68, 0x72, - 0xba, 0x01, 0x2e, 0x03, 0x7f, 0x45, 0x47, 0x57, 0x77, 0x6c, 0x02, 0x3a, - 0x51, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x5b, 0x02, 0x9c, 0x03, 0x76, - 0x05, 0x2f, 0x00, 0x29, 0x00, 0x00, 0x01, 0x15, 0x2e, 0x01, 0x23, 0x22, - 0x06, 0x15, 0x14, 0x16, 0x1f, 0x01, 0x16, 0x17, 0x16, 0x15, 0x14, 0x06, - 0x23, 0x22, 0x26, 0x27, 0x35, 0x1e, 0x01, 0x33, 0x32, 0x36, 0x35, 0x34, - 0x27, 0x26, 0x2f, 0x01, 0x2e, 0x01, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, - 0x03, 0x50, 0x31, 0x6a, 0x38, 0x57, 0x56, 0x3e, 0x5d, 0x28, 0x7d, 0x32, - 0x34, 0x9b, 0x89, 0x38, 0x7b, 0x44, 0x40, 0x7d, 0x3d, 0x52, 0x58, 0x20, - 0x1c, 0x6f, 0x29, 0x6b, 0x60, 0x8d, 0x82, 0x40, 0x71, 0x05, 0x0d, 0x61, - 0x16, 0x16, 0x2f, 0x2f, 0x24, 0x29, 0x12, 0x08, 0x18, 0x2a, 0x2b, 0x4d, - 0x57, 0x66, 0x14, 0x13, 0x6b, 0x1e, 0x1e, 0x32, 0x2d, 0x2a, 0x17, 0x14, - 0x17, 0x08, 0x15, 0x53, 0x49, 0x58, 0x61, 0x11, 0x00, 0x01, 0x01, 0x12, - 0x02, 0x9c, 0x03, 0xbf, 0x05, 0x0f, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x03, - 0x01, 0x23, 0x27, 0x07, 0x23, 0x01, 0x03, 0x33, 0x17, 0x37, 0x03, 0xb1, - 0xff, 0x01, 0x0d, 0x89, 0xce, 0xcd, 0x89, 0x01, 0x12, 0xfa, 0x88, 0xbc, - 0xbb, 0x05, 0x0f, 0xfe, 0xcf, 0xfe, 0xbe, 0xf6, 0xf6, 0x01, 0x48, 0x01, - 0x2b, 0xdf, 0xdf, 0x00, 0x00, 0x01, 0x01, 0x5e, 0x02, 0x9c, 0x03, 0x73, - 0x06, 0x02, 0x00, 0x1c, 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x26, 0x27, - 0x26, 0x35, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x15, 0x26, - 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x02, - 0xd3, 0x7f, 0x6b, 0x47, 0x44, 0x46, 0x56, 0xad, 0x36, 0x33, 0x33, 0x30, - 0x31, 0x32, 0x31, 0x33, 0x71, 0x3e, 0x24, 0x24, 0x36, 0x79, 0x04, 0x5b, - 0xfe, 0x41, 0x01, 0x6d, 0x11, 0x43, 0x40, 0x5f, 0x68, 0x46, 0x58, 0x0a, - 0x09, 0x14, 0x60, 0x18, 0x0c, 0x0c, 0x40, 0x24, 0x4b, 0x37, 0x2a, 0x40, - 0x00, 0x01, 0x01, 0x2c, 0x00, 0x00, 0x03, 0xa5, 0x05, 0x58, 0x00, 0x05, - 0x00, 0x00, 0x21, 0x11, 0x21, 0x35, 0x21, 0x11, 0x03, 0x1d, 0xfe, 0x0f, - 0x02, 0x79, 0x04, 0xd0, 0x88, 0xfa, 0xa8, 0x00, 0x00, 0x01, 0x01, 0x2c, - 0x00, 0x00, 0x03, 0xa5, 0x05, 0x58, 0x00, 0x07, 0x00, 0x00, 0x21, 0x11, - 0x21, 0x35, 0x21, 0x11, 0x33, 0x11, 0x03, 0x1d, 0xfe, 0x0f, 0x01, 0xf1, - 0x88, 0x03, 0x9c, 0x88, 0x01, 0x34, 0xfa, 0xa8, 0x00, 0x01, 0x01, 0x2c, - 0x00, 0x00, 0x03, 0xa5, 0x05, 0x58, 0x00, 0x07, 0x00, 0x00, 0x01, 0x11, - 0x33, 0x11, 0x23, 0x11, 0x21, 0x35, 0x03, 0x1d, 0x88, 0x88, 0xfe, 0x0f, - 0x02, 0xf0, 0x02, 0x68, 0xfa, 0xa8, 0x02, 0x68, 0x88, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x2c, 0x00, 0x00, 0x03, 0xa5, 0x05, 0x58, 0x00, 0x07, - 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, 0x23, 0x11, 0x21, 0x35, 0x03, 0x1d, - 0x88, 0x88, 0xfe, 0x0f, 0x01, 0xbc, 0x03, 0x9c, 0xfa, 0xa8, 0x01, 0x34, - 0x88, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x2c, 0x00, 0x00, 0x03, 0xa5, - 0x05, 0x58, 0x00, 0x05, 0x00, 0x00, 0x25, 0x11, 0x33, 0x11, 0x21, 0x35, - 0x03, 0x1d, 0x88, 0xfd, 0x87, 0x88, 0x04, 0xd0, 0xfa, 0xa8, 0x88, 0x00, - 0xff, 0xff, 0x00, 0xd3, 0x03, 0xc7, 0x03, 0xfc, 0x06, 0x14, 0x12, 0x06, - 0x07, 0x21, 0x00, 0x00, 0xff, 0xff, 0x01, 0x8d, 0xfe, 0x0a, 0x03, 0x44, - 0xff, 0xc1, 0x10, 0x06, 0x02, 0xad, 0x00, 0x00, 0xff, 0xff, 0x01, 0x17, - 0x04, 0xee, 0x02, 0xf6, 0x06, 0x66, 0x10, 0x06, 0x00, 0x43, 0x00, 0x00, - 0xff, 0xff, 0x01, 0xdb, 0x04, 0xee, 0x03, 0xba, 0x06, 0x66, 0x10, 0x06, - 0x00, 0x76, 0x00, 0x00, 0xff, 0xff, 0x01, 0x29, 0x04, 0xee, 0x03, 0xa8, - 0x06, 0x66, 0x10, 0x06, 0x02, 0x67, 0x00, 0x00, 0xff, 0xff, 0x01, 0x1f, - 0x05, 0x1d, 0x03, 0xb2, 0x06, 0x37, 0x10, 0x06, 0x02, 0x79, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x3d, 0x05, 0x62, 0x03, 0x93, 0x05, 0xf6, 0x00, 0x03, - 0x00, 0x11, 0xb6, 0x02, 0xb6, 0x00, 0x04, 0x01, 0x00, 0x04, 0x10, 0xd4, - 0xcc, 0x31, 0x00, 0x10, 0xd4, 0xec, 0x30, 0x01, 0x21, 0x15, 0x21, 0x01, - 0x3d, 0x02, 0x56, 0xfd, 0xaa, 0x05, 0xf6, 0x94, 0xff, 0xff, 0x00, 0x00, - 0x05, 0xbb, 0x04, 0xd1, 0x06, 0x0b, 0x10, 0x06, 0x07, 0x36, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x2f, 0x05, 0x29, 0x03, 0xa2, 0x06, 0x48, 0x00, 0x0d, - 0x00, 0x20, 0xb9, 0x00, 0x0b, 0x01, 0x03, 0x40, 0x0c, 0x04, 0x07, 0x00, - 0xb9, 0x0e, 0x07, 0x50, 0x08, 0x01, 0x50, 0x00, 0x0e, 0x10, 0xd4, 0xec, - 0xdc, 0xec, 0x31, 0x00, 0x10, 0xf4, 0x3c, 0xd4, 0xec, 0x30, 0x01, 0x33, - 0x1e, 0x01, 0x33, 0x32, 0x36, 0x37, 0x33, 0x0e, 0x01, 0x23, 0x22, 0x26, - 0x01, 0x2f, 0x77, 0x0b, 0x60, 0x57, 0x55, 0x60, 0x0e, 0x77, 0x0b, 0x9e, - 0x91, 0x90, 0x9e, 0x06, 0x48, 0x4c, 0x4a, 0x4a, 0x4c, 0x8f, 0x90, 0x90, - 0x00, 0x01, 0x02, 0x01, 0x05, 0x44, 0x02, 0xce, 0x06, 0x10, 0x00, 0x03, - 0x00, 0x14, 0x40, 0x09, 0x02, 0xde, 0x00, 0xdd, 0x04, 0x01, 0x61, 0x00, - 0x04, 0x10, 0xd4, 0xec, 0x31, 0x00, 0x10, 0xf4, 0xec, 0x30, 0x01, 0x33, - 0x15, 0x23, 0x02, 0x01, 0xcd, 0xcd, 0x06, 0x10, 0xcc, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x3f, 0x05, 0x46, 0x03, 0x91, 0x06, 0x10, 0x10, 0x06, - 0x00, 0x6a, 0x00, 0x00, 0x00, 0x01, 0x01, 0x99, 0x04, 0xf2, 0x03, 0x38, - 0x06, 0xc6, 0x00, 0x15, 0x00, 0x00, 0x01, 0x32, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x06, 0x07, 0x15, 0x23, 0x35, 0x36, 0x37, 0x36, 0x35, 0x34, 0x23, - 0x22, 0x07, 0x35, 0x36, 0x02, 0x4a, 0xe6, 0x07, 0x01, 0x1c, 0x32, 0x34, - 0x94, 0x43, 0x31, 0x16, 0x78, 0x5a, 0x40, 0x56, 0x06, 0xc6, 0xaa, 0x05, - 0x05, 0x40, 0x24, 0x43, 0x21, 0x58, 0x6c, 0x16, 0x30, 0x14, 0x35, 0x5e, - 0x20, 0x83, 0x18, 0x00, 0xff, 0xff, 0x01, 0x56, 0x04, 0xe1, 0x03, 0x7b, - 0x07, 0x06, 0x10, 0x06, 0x02, 0x77, 0x00, 0x00, 0x00, 0x02, 0x01, 0x58, - 0x04, 0xee, 0x04, 0x17, 0x06, 0x66, 0x00, 0x03, 0x00, 0x07, 0x00, 0x25, - 0x40, 0x11, 0x06, 0x02, 0xba, 0x04, 0x00, 0xb9, 0x08, 0x00, 0x07, 0x03, - 0x04, 0x01, 0x05, 0x07, 0x01, 0x03, 0x08, 0x10, 0xd4, 0xdc, 0xd4, 0xcc, - 0x11, 0x39, 0x11, 0x12, 0x39, 0x31, 0x00, 0x10, 0xf4, 0x3c, 0xec, 0x32, - 0x30, 0x01, 0x33, 0x03, 0x23, 0x01, 0x33, 0x03, 0x23, 0x02, 0x17, 0xaa, - 0xe0, 0x89, 0x02, 0x0c, 0xb3, 0xf8, 0x87, 0x06, 0x66, 0xfe, 0x88, 0x01, - 0x78, 0xfe, 0x88, 0x00, 0xff, 0xff, 0x01, 0x29, 0x04, 0xee, 0x03, 0xa8, - 0x06, 0x66, 0x10, 0x06, 0x02, 0x68, 0x00, 0x00, 0x00, 0x01, 0x02, 0x22, - 0x04, 0xee, 0x02, 0xaa, 0x06, 0xaa, 0x00, 0x03, 0x00, 0x00, 0x01, 0x11, - 0x23, 0x11, 0x02, 0xaa, 0x88, 0x06, 0xaa, 0xfe, 0x44, 0x01, 0xbc, 0x00, - 0xff, 0xff, 0x01, 0x56, 0x04, 0xee, 0x03, 0x76, 0x06, 0xaa, 0x10, 0x27, - 0x02, 0x95, 0x00, 0xcc, 0x00, 0x00, 0x10, 0x07, 0x02, 0x95, 0xff, 0x34, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xd2, 0x04, 0xee, 0x03, 0x90, - 0x06, 0x66, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x01, 0x13, 0x23, 0x03, - 0x21, 0x13, 0x23, 0x03, 0x01, 0x84, 0xcd, 0x87, 0xf8, 0x02, 0x00, 0xbe, - 0x89, 0xdf, 0x06, 0x66, 0xfe, 0x88, 0x01, 0x78, 0xfe, 0x88, 0x01, 0x78, - 0xff, 0xff, 0x01, 0x2f, 0x05, 0x29, 0x03, 0xa2, 0x06, 0xdc, 0x10, 0x27, - 0x02, 0x76, 0x00, 0x00, 0x00, 0xcc, 0x10, 0x06, 0x02, 0x75, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x2f, 0x05, 0x29, 0x03, 0xa2, 0x06, 0x48, 0x00, 0x0d, - 0x00, 0x00, 0x01, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x17, 0x23, 0x2e, 0x01, - 0x23, 0x22, 0x06, 0x07, 0x01, 0x2f, 0x0b, 0x9e, 0x90, 0x91, 0x9e, 0x0b, - 0x77, 0x0e, 0x60, 0x55, 0x57, 0x60, 0x0b, 0x05, 0x29, 0x8f, 0x90, 0x90, - 0x8f, 0x4c, 0x4a, 0x4a, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0xd5, - 0x03, 0xc7, 0x03, 0x22, 0x05, 0x20, 0x00, 0x03, 0x00, 0x00, 0x01, 0x23, - 0x13, 0x33, 0x02, 0xc4, 0xef, 0xbb, 0x92, 0x03, 0xc7, 0x01, 0x59, 0x00, - 0x00, 0x01, 0x01, 0xef, 0x04, 0xc2, 0x02, 0xe2, 0x06, 0xc1, 0x00, 0x08, - 0x00, 0x00, 0x01, 0x10, 0x23, 0x35, 0x16, 0x35, 0x23, 0x35, 0x33, 0x02, - 0xe1, 0xf1, 0x70, 0x70, 0xf1, 0x05, 0xc3, 0xfe, 0xff, 0x7b, 0x03, 0x89, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0xf0, 0x04, 0xc2, 0x02, 0xe1, - 0x06, 0xc1, 0x00, 0x08, 0x00, 0x00, 0x01, 0x35, 0x33, 0x15, 0x23, 0x14, - 0x33, 0x15, 0x22, 0x01, 0xf0, 0xf1, 0x70, 0x70, 0xf1, 0x05, 0xc3, 0xfe, - 0xfe, 0x86, 0x7b, 0x00, 0x00, 0x01, 0x01, 0xdb, 0x04, 0xee, 0x02, 0xe6, - 0x06, 0x66, 0x00, 0x03, 0x00, 0x00, 0x01, 0x33, 0x03, 0x23, 0x02, 0x20, - 0xc6, 0x71, 0x9a, 0x06, 0x66, 0xfe, 0x88, 0x00, 0xff, 0xff, 0x01, 0x79, - 0xfd, 0xb8, 0x03, 0x58, 0xff, 0x30, 0x10, 0x07, 0x00, 0x43, 0x00, 0x62, - 0xf8, 0xca, 0x00, 0x00, 0xff, 0xff, 0x01, 0x79, 0xfd, 0xb8, 0x03, 0x58, - 0xff, 0x30, 0x10, 0x07, 0x00, 0x76, 0xff, 0x9e, 0xf8, 0xca, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x9c, 0xfd, 0x01, 0x02, 0xd4, 0xfe, 0xeb, 0x00, 0x07, - 0x00, 0x00, 0x01, 0x35, 0x33, 0x11, 0x23, 0x35, 0x23, 0x35, 0x02, 0x4c, - 0x88, 0x88, 0xb0, 0xfe, 0x3a, 0xb1, 0xfe, 0x16, 0xb1, 0x88, 0x00, 0x00, - 0x00, 0x01, 0x01, 0xcc, 0xfd, 0x01, 0x03, 0x04, 0xfe, 0xeb, 0x00, 0x07, - 0x00, 0x00, 0x01, 0x15, 0x23, 0x11, 0x33, 0x15, 0x33, 0x15, 0x02, 0x54, - 0x88, 0x88, 0xb0, 0xfd, 0xb2, 0xb1, 0x01, 0xea, 0xb1, 0x88, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x73, 0x05, 0x86, 0x03, 0x5e, 0x07, 0x70, 0x00, 0x05, - 0x00, 0x00, 0x01, 0x21, 0x35, 0x21, 0x11, 0x23, 0x02, 0xd6, 0xfe, 0x9e, - 0x01, 0xea, 0x88, 0x06, 0xe8, 0x88, 0xfe, 0x16, 0x00, 0x01, 0x01, 0xa3, - 0x02, 0xfc, 0x03, 0x2e, 0x04, 0x71, 0x00, 0x13, 0x00, 0x00, 0x01, 0x35, - 0x1e, 0x01, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x27, 0x33, 0x1e, 0x01, - 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x01, 0xa3, 0x3d, 0x58, 0x1f, 0x2e, - 0x2e, 0x0f, 0x0f, 0x85, 0x0a, 0x0a, 0x57, 0x5d, 0x30, 0x69, 0x03, 0x68, - 0x77, 0x2d, 0x2b, 0x37, 0x36, 0x20, 0x3e, 0x1f, 0x26, 0x44, 0x1e, 0x7a, - 0x73, 0x35, 0x00, 0x00, 0x00, 0x01, 0x01, 0xfa, 0xfe, 0x0a, 0x02, 0xd6, - 0xff, 0xc1, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x15, 0x22, 0x26, 0x34, 0x36, - 0x33, 0x15, 0x22, 0x06, 0x15, 0x14, 0x16, 0x02, 0xd6, 0x5d, 0x7f, 0x7f, - 0x5d, 0x33, 0x47, 0x47, 0xfe, 0x6c, 0x62, 0x80, 0xb8, 0x7f, 0x62, 0x47, - 0x32, 0x33, 0x47, 0x00, 0x00, 0x01, 0x01, 0x62, 0xfd, 0xb2, 0x03, 0x4c, - 0xfe, 0xeb, 0x00, 0x07, 0x00, 0x00, 0x01, 0x33, 0x15, 0x21, 0x35, 0x33, - 0x35, 0x33, 0x02, 0x9b, 0xb1, 0xfe, 0x16, 0xb1, 0x88, 0xfe, 0x3a, 0x88, - 0x88, 0xb1, 0x00, 0x00, 0x00, 0x01, 0x01, 0x5e, 0xfd, 0xb2, 0x03, 0x48, - 0xfe, 0xeb, 0x00, 0x07, 0x00, 0x00, 0x01, 0x23, 0x35, 0x21, 0x15, 0x23, - 0x15, 0x23, 0x02, 0x0f, 0xb1, 0x01, 0xea, 0xb1, 0x88, 0xfe, 0x63, 0x88, - 0x88, 0xb1, 0x00, 0x00, 0x00, 0x01, 0x01, 0x5f, 0xfd, 0x01, 0x03, 0x49, - 0xfe, 0xeb, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x23, 0x35, 0x33, 0x35, 0x33, - 0x15, 0x33, 0x15, 0x23, 0x15, 0x23, 0x02, 0x10, 0xb1, 0xb1, 0x88, 0xb1, - 0xb1, 0x88, 0xfd, 0xb2, 0x88, 0xb1, 0xb1, 0x88, 0xb1, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x73, 0xfe, 0x63, 0x03, 0x5e, 0xfe, 0xeb, 0x00, 0x03, - 0x00, 0x00, 0x01, 0x35, 0x21, 0x15, 0x01, 0x74, 0x01, 0xea, 0xfe, 0x63, - 0x88, 0x88, 0x00, 0x00, 0x00, 0x01, 0x01, 0xf6, 0xfe, 0x56, 0x04, 0x1b, - 0x00, 0x80, 0x00, 0x0d, 0x00, 0x00, 0x25, 0x15, 0x14, 0x07, 0x06, 0x2b, - 0x01, 0x35, 0x33, 0x32, 0x37, 0x36, 0x3d, 0x01, 0x04, 0x1b, 0x59, 0x5a, - 0xa5, 0xcd, 0xb9, 0x5a, 0x2d, 0x2c, 0x80, 0x94, 0xc3, 0x69, 0x6a, 0x9c, - 0x3e, 0x3e, 0x7e, 0x94, 0x00, 0x01, 0x00, 0xb6, 0xfe, 0x56, 0x02, 0xdb, - 0x00, 0x80, 0x00, 0x0d, 0x00, 0x00, 0x37, 0x33, 0x15, 0x14, 0x17, 0x16, - 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, 0x26, 0x35, 0xb6, 0xb9, 0x2c, 0x2d, - 0x5a, 0xb9, 0xcd, 0xa5, 0x5a, 0x59, 0x80, 0x94, 0x7e, 0x3e, 0x3e, 0x9c, - 0x6a, 0x69, 0xc3, 0x00, 0x00, 0x01, 0x02, 0x01, 0xfe, 0x63, 0x02, 0xce, - 0xff, 0x2f, 0x00, 0x03, 0x00, 0x13, 0x40, 0x08, 0x02, 0xde, 0x00, 0x04, - 0x01, 0x61, 0x00, 0x04, 0x10, 0xd4, 0xec, 0x31, 0x00, 0x10, 0xd4, 0xec, - 0x30, 0x05, 0x33, 0x15, 0x23, 0x02, 0x01, 0xcd, 0xcd, 0xd1, 0xcc, 0x00, - 0x00, 0x02, 0x01, 0x3f, 0xfe, 0x64, 0x03, 0x92, 0xff, 0x2e, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x1c, 0x40, 0x0d, 0x06, 0x02, 0xde, 0x04, 0x00, 0x08, - 0x05, 0x61, 0x04, 0x01, 0x61, 0x00, 0x08, 0x10, 0xd4, 0xfc, 0xd4, 0xec, - 0x31, 0x00, 0x10, 0xd4, 0x3c, 0xec, 0x32, 0x30, 0x05, 0x33, 0x15, 0x23, - 0x25, 0x33, 0x15, 0x23, 0x01, 0x40, 0xca, 0xca, 0x01, 0x88, 0xca, 0xca, - 0xd2, 0xca, 0xca, 0xca, 0x00, 0x02, 0x01, 0x8d, 0xfe, 0x0a, 0x03, 0x44, - 0xff, 0xc1, 0x00, 0x0b, 0x00, 0x17, 0x00, 0x1d, 0xb5, 0x0c, 0x00, 0x12, - 0x00, 0x06, 0x18, 0x10, 0xd4, 0xcc, 0xcc, 0x10, 0xcc, 0x31, 0x00, 0xb5, - 0x0f, 0x09, 0x15, 0x09, 0x03, 0x18, 0x10, 0xd4, 0xcc, 0xcc, 0x10, 0xcc, - 0x30, 0x01, 0x14, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, - 0x16, 0x07, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, - 0x36, 0x03, 0x44, 0x7f, 0x5d, 0x5c, 0x7f, 0x7f, 0x5c, 0x5d, 0x7f, 0x62, - 0x47, 0x33, 0x33, 0x46, 0x46, 0x33, 0x33, 0x47, 0xfe, 0xe6, 0x5c, 0x80, - 0x80, 0x5c, 0x5c, 0x7f, 0x7f, 0x5c, 0x32, 0x47, 0x46, 0x33, 0x34, 0x46, - 0x47, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x98, 0xfd, 0xe2, 0x02, 0xe5, - 0xff, 0x3b, 0x00, 0x03, 0x00, 0x11, 0x40, 0x06, 0x00, 0x03, 0x04, 0x01, - 0x03, 0x04, 0x10, 0xd4, 0xcc, 0x31, 0x00, 0x10, 0xd4, 0xcc, 0x30, 0x05, - 0x33, 0x03, 0x23, 0x01, 0xf6, 0xef, 0xbb, 0x92, 0xc5, 0xfe, 0xa7, 0x00, - 0x00, 0x01, 0x01, 0x8b, 0xfe, 0x75, 0x03, 0x29, 0x00, 0x00, 0x00, 0x13, - 0x00, 0x38, 0xb3, 0x09, 0x06, 0x0a, 0x0d, 0xba, 0x01, 0x06, 0x00, 0x06, - 0x01, 0x05, 0x40, 0x09, 0x00, 0x09, 0x10, 0x13, 0x00, 0x10, 0x7c, 0x03, - 0x14, 0x10, 0xd4, 0xec, 0xd4, 0xcc, 0x10, 0xc4, 0x31, 0x00, 0x2f, 0xf6, - 0xfe, 0xc5, 0x12, 0x39, 0x30, 0x01, 0x40, 0x0d, 0x49, 0x01, 0x59, 0x01, - 0x69, 0x01, 0x79, 0x01, 0x89, 0x01, 0x99, 0x01, 0x06, 0x5d, 0x21, 0x1e, - 0x01, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x27, 0x35, 0x1e, 0x01, 0x33, - 0x32, 0x36, 0x35, 0x34, 0x26, 0x27, 0x02, 0xbc, 0x38, 0x35, 0x78, 0x76, - 0x2d, 0x57, 0x2c, 0x22, 0x4b, 0x2f, 0x3a, 0x3d, 0x2c, 0x2c, 0x3e, 0x69, - 0x30, 0x59, 0x5b, 0x0c, 0x0c, 0x83, 0x11, 0x0f, 0x30, 0x2e, 0x1e, 0x57, - 0x3d, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0xae, 0xfe, 0x75, 0x03, 0x23, - 0x00, 0x00, 0x10, 0x06, 0x02, 0x78, 0x0a, 0x00, 0x00, 0x01, 0x02, 0x24, - 0xfd, 0x73, 0x02, 0xad, 0xff, 0x2f, 0x00, 0x03, 0x00, 0x00, 0x05, 0x11, - 0x23, 0x11, 0x02, 0xac, 0x88, 0xd1, 0xfe, 0x44, 0x01, 0xbc, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x55, 0xfd, 0xe5, 0x03, 0x7c, 0xff, 0x2f, 0x00, 0x07, - 0x00, 0x00, 0x05, 0x11, 0x23, 0x35, 0x21, 0x15, 0x23, 0x11, 0x03, 0x7c, - 0x89, 0xfe, 0xeb, 0x89, 0xd1, 0xfe, 0xb6, 0xc2, 0xc2, 0x01, 0x4a, 0x00, - 0x00, 0x01, 0x00, 0xce, 0xfe, 0x39, 0x04, 0x03, 0xff, 0x58, 0x00, 0x14, - 0x00, 0x00, 0x01, 0x06, 0x23, 0x22, 0x03, 0x34, 0x35, 0x33, 0x16, 0x33, - 0x32, 0x37, 0x33, 0x16, 0x17, 0x32, 0x37, 0x33, 0x02, 0x07, 0x22, 0x02, - 0x68, 0x3b, 0x74, 0xda, 0x11, 0x76, 0x0d, 0x67, 0x66, 0x10, 0x76, 0x0b, - 0x69, 0x66, 0x0f, 0x76, 0x0f, 0xdc, 0x74, 0xfe, 0x8b, 0x52, 0x01, 0x1a, - 0x02, 0x03, 0x96, 0x96, 0x95, 0x01, 0x96, 0xfe, 0xe2, 0x01, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x29, 0xfe, 0x1b, 0x03, 0xa8, 0xff, 0x93, 0x00, 0x06, - 0x00, 0x19, 0x40, 0x0b, 0x03, 0x00, 0xba, 0x04, 0x01, 0x07, 0x03, 0x05, - 0x0b, 0x01, 0x07, 0x10, 0xd4, 0xec, 0x39, 0x31, 0x00, 0x10, 0xd4, 0x3c, - 0xec, 0x39, 0x30, 0x01, 0x03, 0x33, 0x17, 0x37, 0x33, 0x03, 0x02, 0x1f, - 0xf6, 0x8b, 0xb4, 0xb5, 0x8b, 0xf6, 0xfe, 0x1b, 0x01, 0x78, 0xf5, 0xf5, - 0xfe, 0x88, 0x00, 0x00, 0x00, 0x01, 0x01, 0x29, 0xfe, 0x1b, 0x03, 0xa8, - 0xff, 0x93, 0x00, 0x06, 0x00, 0x19, 0x40, 0x0b, 0x04, 0x05, 0x02, 0xba, - 0x00, 0x07, 0x04, 0x02, 0x0b, 0x06, 0x07, 0x10, 0xd4, 0xec, 0x39, 0x31, - 0x00, 0x10, 0xd4, 0xec, 0x32, 0x39, 0x30, 0x05, 0x33, 0x13, 0x23, 0x27, - 0x07, 0x23, 0x02, 0x1f, 0x93, 0xf6, 0x8b, 0xb5, 0xb4, 0x8b, 0x6d, 0xfe, - 0x88, 0xf5, 0xf5, 0x00, 0x00, 0x01, 0x01, 0x2f, 0xfe, 0x19, 0x03, 0xa2, - 0xff, 0x38, 0x00, 0x0d, 0x00, 0x20, 0xb9, 0x00, 0x0b, 0x01, 0x03, 0x40, - 0x0c, 0x04, 0x07, 0x00, 0xb9, 0x0e, 0x07, 0x50, 0x08, 0x01, 0x50, 0x00, - 0x0e, 0x10, 0xd4, 0xec, 0xdc, 0xec, 0x31, 0x00, 0x10, 0xf4, 0x3c, 0xd4, - 0xec, 0x30, 0x05, 0x33, 0x1e, 0x01, 0x33, 0x32, 0x36, 0x37, 0x33, 0x0e, - 0x01, 0x23, 0x22, 0x26, 0x01, 0x2f, 0x77, 0x0b, 0x60, 0x57, 0x55, 0x60, - 0x0e, 0x77, 0x0b, 0x9e, 0x91, 0x90, 0x9e, 0xc8, 0x4c, 0x4a, 0x4a, 0x4c, - 0x8f, 0x90, 0x90, 0x00, 0x00, 0x01, 0x01, 0x2f, 0xfe, 0x1b, 0x03, 0xa2, - 0xff, 0x3a, 0x00, 0x0d, 0x00, 0x00, 0x01, 0x23, 0x2e, 0x01, 0x23, 0x22, - 0x06, 0x07, 0x23, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x03, 0xa2, 0x77, 0x0b, - 0x60, 0x57, 0x55, 0x60, 0x0e, 0x77, 0x0b, 0x9e, 0x91, 0x90, 0x9e, 0xfe, - 0x1b, 0x4c, 0x4a, 0x4a, 0x4c, 0x8f, 0x90, 0x90, 0x00, 0x01, 0x01, 0x1f, - 0xfe, 0x1b, 0x03, 0xb2, 0xff, 0x35, 0x00, 0x1b, 0x00, 0x86, 0x40, 0x21, - 0x00, 0x12, 0x07, 0x0e, 0x0b, 0x04, 0x01, 0x12, 0x07, 0x0f, 0x0b, 0x04, - 0x12, 0xcc, 0x19, 0x07, 0x04, 0xcc, 0x15, 0x0b, 0x1c, 0x0f, 0x01, 0x0e, - 0x00, 0x07, 0x15, 0x50, 0x16, 0x07, 0x50, 0x08, 0x1c, 0x10, 0xd4, 0xec, - 0xd4, 0xec, 0x11, 0x39, 0x39, 0x39, 0x39, 0x31, 0x00, 0x10, 0xd4, 0x3c, - 0xfc, 0xd4, 0x3c, 0xec, 0x11, 0x12, 0x39, 0x11, 0x12, 0x39, 0x11, 0x12, - 0x39, 0x11, 0x12, 0x39, 0x30, 0x40, 0x3f, 0x09, 0x00, 0x0c, 0x0a, 0x0c, - 0x0b, 0x0c, 0x0c, 0x0b, 0x0f, 0x0b, 0x10, 0x0f, 0x11, 0x0f, 0x12, 0x0f, - 0x13, 0x0f, 0x14, 0x0f, 0x15, 0x0f, 0x16, 0x0f, 0x17, 0x09, 0x1b, 0x19, - 0x00, 0x19, 0x01, 0x1b, 0x0a, 0x1b, 0x0b, 0x1b, 0x0c, 0x1b, 0x0d, 0x1b, - 0x0e, 0x1b, 0x0f, 0x1b, 0x10, 0x1b, 0x11, 0x1b, 0x12, 0x1b, 0x13, 0x1f, - 0x14, 0x1f, 0x15, 0x1f, 0x16, 0x1a, 0x17, 0x19, 0x1b, 0x1f, 0x01, 0x5d, - 0x01, 0x27, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x23, 0x3e, 0x01, 0x33, - 0x32, 0x16, 0x1f, 0x01, 0x1e, 0x01, 0x33, 0x32, 0x36, 0x37, 0x33, 0x0e, - 0x01, 0x23, 0x22, 0x26, 0x02, 0x64, 0x39, 0x15, 0x21, 0x0e, 0x26, 0x24, - 0x02, 0x7c, 0x01, 0x66, 0x5b, 0x27, 0x40, 0x25, 0x39, 0x15, 0x21, 0x0d, - 0x27, 0x24, 0x01, 0x7d, 0x01, 0x66, 0x5b, 0x27, 0x40, 0xfe, 0x58, 0x37, - 0x14, 0x13, 0x4a, 0x51, 0x86, 0x94, 0x1c, 0x21, 0x37, 0x14, 0x13, 0x4a, - 0x51, 0x86, 0x94, 0x1c, 0x00, 0x01, 0x01, 0x3d, 0xfe, 0x9b, 0x03, 0x94, - 0xff, 0x2f, 0x00, 0x03, 0x00, 0x11, 0xb6, 0x02, 0xb6, 0x00, 0x04, 0x01, - 0x00, 0x04, 0x10, 0xd4, 0xcc, 0x31, 0x00, 0x10, 0xdc, 0xec, 0x30, 0x05, - 0x21, 0x15, 0x21, 0x01, 0x3e, 0x02, 0x56, 0xfd, 0xaa, 0xd1, 0x94, 0x00, - 0xff, 0xff, 0x00, 0x00, 0xfe, 0x1d, 0x04, 0xd1, 0xfe, 0x6d, 0x10, 0x06, - 0x00, 0x42, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0x1d, 0x04, 0xd1, - 0xff, 0x5d, 0x10, 0x06, 0x07, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x00, 0x58, - 0x01, 0xec, 0x04, 0x79, 0x03, 0x0c, 0x10, 0x06, 0x00, 0x61, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x8d, 0x01, 0xc4, 0x04, 0x26, 0x02, 0x68, 0x00, 0x03, - 0x00, 0x00, 0x01, 0x15, 0x21, 0x35, 0x04, 0x26, 0xfc, 0x68, 0x02, 0x68, - 0xa4, 0xa4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0xc4, 0x04, 0xd1, - 0x02, 0x68, 0x00, 0x03, 0x00, 0x00, 0x11, 0x35, 0x21, 0x15, 0x04, 0xd1, - 0x01, 0xc4, 0xa4, 0xa4, 0x00, 0x01, 0x00, 0x2f, 0xff, 0xa0, 0x04, 0x96, - 0x04, 0xbc, 0x00, 0x03, 0x00, 0x00, 0x17, 0x27, 0x01, 0x17, 0x8b, 0x5c, - 0x04, 0x0a, 0x5d, 0x60, 0x4c, 0x04, 0xd0, 0x4d, 0x00, 0x01, 0x00, 0x08, - 0xff, 0xba, 0x04, 0xb0, 0x06, 0x17, 0x00, 0x03, 0x00, 0x00, 0x17, 0x27, - 0x01, 0x17, 0x6f, 0x67, 0x04, 0x44, 0x64, 0x46, 0x46, 0x06, 0x17, 0x4a, - 0x00, 0x01, 0x01, 0xfa, 0xfe, 0x0a, 0x02, 0xd6, 0xff, 0xc1, 0x00, 0x0c, - 0x00, 0x00, 0x01, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x35, 0x32, 0x16, - 0x14, 0x06, 0x23, 0x01, 0xfa, 0x33, 0x47, 0x47, 0x33, 0x5d, 0x7f, 0x7f, - 0x5d, 0xfe, 0x6c, 0x47, 0x33, 0x32, 0x47, 0x62, 0x7f, 0xb8, 0x80, 0x00, - 0x00, 0x01, 0x01, 0x55, 0xfe, 0x80, 0x03, 0x7c, 0xff, 0xca, 0x00, 0x07, - 0x00, 0x00, 0x01, 0x11, 0x33, 0x15, 0x21, 0x35, 0x33, 0x11, 0x01, 0x55, - 0x89, 0x01, 0x15, 0x89, 0xfe, 0x80, 0x01, 0x4a, 0xc2, 0xc2, 0xfe, 0xb6, - 0x00, 0x02, 0x01, 0x55, 0xfd, 0x09, 0x03, 0x7c, 0xff, 0x2f, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x00, 0x05, 0x11, 0x21, 0x11, 0x01, 0x11, 0x21, 0x11, - 0x03, 0x7c, 0xfd, 0xd9, 0x01, 0x9e, 0xfe, 0xeb, 0xd1, 0xfd, 0xda, 0x02, - 0x26, 0xfe, 0x62, 0x01, 0x16, 0xfe, 0xea, 0x00, 0x00, 0x01, 0x00, 0xce, - 0xfe, 0x39, 0x04, 0x03, 0xff, 0x58, 0x00, 0x14, 0x00, 0x00, 0x05, 0x36, - 0x33, 0x32, 0x13, 0x14, 0x15, 0x23, 0x26, 0x23, 0x22, 0x07, 0x23, 0x26, - 0x27, 0x22, 0x07, 0x23, 0x12, 0x37, 0x32, 0x02, 0x68, 0x3c, 0x74, 0xda, - 0x11, 0x75, 0x0e, 0x68, 0x65, 0x0f, 0x76, 0x0c, 0x69, 0x66, 0x0f, 0x76, - 0x0f, 0xdc, 0x74, 0xfa, 0x52, 0xfe, 0xe6, 0x02, 0x03, 0x96, 0x96, 0x95, - 0x01, 0x96, 0x01, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x8b, - 0x04, 0xcb, 0x03, 0x46, 0x06, 0x87, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x07, - 0x27, 0x37, 0x27, 0x37, 0x17, 0x37, 0x17, 0x07, 0x17, 0x07, 0x02, 0x68, - 0x7d, 0x60, 0x7d, 0x7d, 0x60, 0x7d, 0x7e, 0x60, 0x7d, 0x7d, 0x60, 0x05, - 0x49, 0x7d, 0x60, 0x7d, 0x7d, 0x61, 0x7e, 0x7e, 0x61, 0x7d, 0x7d, 0x60, - 0x00, 0x01, 0x01, 0xdb, 0x04, 0xc2, 0x02, 0xf6, 0x06, 0xd2, 0x00, 0x1d, - 0x00, 0x00, 0x01, 0x2e, 0x01, 0x35, 0x34, 0x36, 0x37, 0x15, 0x0e, 0x01, - 0x15, 0x14, 0x17, 0x16, 0x1f, 0x01, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x07, - 0x35, 0x3e, 0x01, 0x35, 0x34, 0x27, 0x26, 0x27, 0x02, 0x18, 0x20, 0x1c, - 0x92, 0x88, 0x52, 0x4a, 0x0a, 0x0b, 0x13, 0x36, 0x22, 0x1c, 0x94, 0x86, - 0x52, 0x48, 0x09, 0x0b, 0x12, 0x05, 0xc7, 0x1c, 0x30, 0x1c, 0x50, 0x51, - 0x02, 0x6e, 0x02, 0x1b, 0x1c, 0x0a, 0x0c, 0x0f, 0x0e, 0x2b, 0x1c, 0x30, - 0x1c, 0x50, 0x51, 0x02, 0x6e, 0x02, 0x1b, 0x1c, 0x0a, 0x0c, 0x0f, 0x0e, - 0xff, 0xff, 0x00, 0x00, 0x04, 0xcb, 0x04, 0xd1, 0x06, 0x0b, 0x10, 0x26, - 0x07, 0x36, 0x00, 0x00, 0x10, 0x07, 0x07, 0x36, 0x00, 0x00, 0xff, 0x10, - 0xff, 0xff, 0x01, 0xef, 0x04, 0xc2, 0x02, 0xe2, 0x06, 0xc1, 0x10, 0x06, - 0x02, 0x9b, 0x00, 0x00, 0xff, 0xff, 0x04, 0x02, 0x05, 0x44, 0x04, 0xcf, - 0x06, 0x10, 0x10, 0x07, 0x02, 0x76, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0xff, 0x13, 0x05, 0xf0, 0x05, 0xbe, 0x07, 0x37, 0x00, 0x0f, - 0x00, 0x00, 0x00, 0x22, 0x05, 0x04, 0x07, 0x23, 0x34, 0x25, 0x36, 0x32, - 0x17, 0x04, 0x15, 0x23, 0x26, 0x25, 0x02, 0xa0, 0x6e, 0xfe, 0xe2, 0xfe, - 0xf4, 0x7e, 0x76, 0x01, 0xfc, 0xe4, 0xe9, 0xe5, 0x01, 0xfc, 0x76, 0x7f, - 0xfe, 0xf3, 0x06, 0xae, 0x19, 0x17, 0x8e, 0xf0, 0x3c, 0x1b, 0x1b, 0x3c, - 0xf0, 0x8e, 0x17, 0x00, 0x00, 0x01, 0x01, 0xec, 0x04, 0x74, 0x02, 0xeb, - 0x06, 0x66, 0x00, 0x03, 0x00, 0x00, 0x01, 0x13, 0x33, 0x03, 0x01, 0xec, - 0x41, 0xbe, 0x6e, 0x04, 0x74, 0x01, 0xf2, 0xfe, 0x0e, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0xe6, 0xfe, 0x56, 0x02, 0xe5, 0x00, 0x48, 0x00, 0x03, - 0x00, 0x00, 0x25, 0x03, 0x23, 0x13, 0x02, 0xe5, 0x41, 0xbe, 0x6e, 0x48, - 0xfe, 0x0e, 0x01, 0xf2, 0x00, 0x01, 0x02, 0x1e, 0xfe, 0x56, 0x02, 0xfa, - 0xff, 0xa4, 0x00, 0x09, 0x00, 0x00, 0x01, 0x23, 0x22, 0x3d, 0x01, 0x33, - 0x15, 0x14, 0x3b, 0x01, 0x02, 0xfa, 0x84, 0x58, 0x95, 0x33, 0x14, 0xfe, - 0x56, 0xb7, 0x97, 0xa4, 0x68, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x93, - 0xfe, 0xe1, 0x02, 0xf2, 0x04, 0x27, 0x10, 0x06, 0x00, 0x1e, 0x00, 0x00, - 0xff, 0xff, 0x01, 0xdb, 0x04, 0xee, 0x03, 0xba, 0x06, 0x66, 0x10, 0x06, - 0x00, 0x76, 0x00, 0x00, 0xff, 0xff, 0x01, 0x3f, 0x05, 0x46, 0x03, 0xba, - 0x07, 0xd8, 0x10, 0x26, 0x00, 0x6a, 0x00, 0x00, 0x10, 0x07, 0x02, 0xcf, - 0x00, 0x00, 0x01, 0x72, 0xff, 0xff, 0x00, 0x19, 0x00, 0x00, 0x04, 0xac, - 0x06, 0x66, 0x10, 0x26, 0x02, 0xda, 0x00, 0x00, 0x10, 0x07, 0x02, 0xcf, - 0xfe, 0x3e, 0x00, 0x00, 0xff, 0xff, 0x01, 0xe9, 0x02, 0x2f, 0x02, 0xe5, - 0x03, 0x60, 0x10, 0x06, 0x00, 0x79, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f, - 0x00, 0x00, 0x04, 0x4e, 0x06, 0x66, 0x10, 0x26, 0x02, 0xde, 0x00, 0x00, - 0x10, 0x07, 0x02, 0xcf, 0xfd, 0x44, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xed, - 0x00, 0x00, 0x04, 0x48, 0x06, 0x66, 0x10, 0x26, 0x02, 0xe0, 0x00, 0x00, - 0x10, 0x07, 0x02, 0xcf, 0xfd, 0x12, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f, - 0x00, 0x00, 0x04, 0x06, 0x06, 0x66, 0x10, 0x26, 0x02, 0xe2, 0x00, 0x00, - 0x10, 0x07, 0x02, 0xcf, 0xfd, 0x44, 0x00, 0x00, 0xff, 0xff, 0xff, 0xb5, - 0xff, 0xe3, 0x04, 0x5c, 0x06, 0x66, 0x10, 0x26, 0x02, 0xe8, 0x00, 0x00, - 0x10, 0x07, 0x02, 0xcf, 0xfd, 0xda, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x70, - 0x00, 0x00, 0x04, 0xac, 0x06, 0x66, 0x10, 0x26, 0x02, 0xed, 0x00, 0x00, - 0x10, 0x07, 0x02, 0xcf, 0xfc, 0x95, 0x00, 0x00, 0xff, 0xff, 0xff, 0xce, - 0x00, 0x00, 0x04, 0x87, 0x06, 0x66, 0x10, 0x26, 0x02, 0xf1, 0x00, 0x00, - 0x10, 0x07, 0x02, 0xcf, 0xfd, 0xf3, 0x00, 0x00, 0xff, 0xff, 0x01, 0x36, - 0x00, 0x00, 0x03, 0xcf, 0x07, 0xd8, 0x10, 0x26, 0x03, 0x01, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xd0, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, - 0x00, 0x00, 0x04, 0xac, 0x05, 0xd5, 0x10, 0x06, 0x00, 0x24, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xa6, 0x00, 0x00, 0x04, 0x71, 0x05, 0xd5, 0x10, 0x06, - 0x00, 0x25, 0x00, 0x00, 0xff, 0xff, 0x00, 0xd7, 0x00, 0x00, 0x04, 0x73, - 0x05, 0xd5, 0x10, 0x06, 0x03, 0x4c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x25, - 0x00, 0x00, 0x04, 0xac, 0x05, 0xd5, 0x00, 0x02, 0x00, 0x06, 0x00, 0x31, - 0xb4, 0x03, 0x2f, 0x04, 0x30, 0x07, 0x10, 0xf4, 0xe4, 0x31, 0x00, 0xb4, - 0x05, 0xb4, 0x02, 0x97, 0x04, 0x2f, 0xec, 0xe4, 0x30, 0x05, 0x40, 0x10, - 0x01, 0x25, 0x05, 0x04, 0x00, 0x25, 0x03, 0x06, 0x03, 0x02, 0x25, 0x01, - 0x25, 0x04, 0x05, 0x04, 0x07, 0x10, 0xec, 0xec, 0x07, 0x10, 0xec, 0x08, - 0xec, 0x25, 0x09, 0x01, 0x05, 0x21, 0x01, 0x33, 0x03, 0xaa, 0xfe, 0xbe, - 0xfe, 0xbe, 0x03, 0x86, 0xfb, 0x79, 0x01, 0xc9, 0xf5, 0xaa, 0x04, 0x79, - 0xfb, 0x87, 0xaa, 0x05, 0xd5, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc5, - 0x00, 0x00, 0x04, 0x4e, 0x05, 0xd5, 0x10, 0x06, 0x00, 0x28, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x9c, 0x00, 0x00, 0x04, 0x91, 0x05, 0xd5, 0x10, 0x06, - 0x00, 0x3d, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0x00, 0x00, 0x04, 0x48, - 0x05, 0xd5, 0x10, 0x06, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x75, - 0xff, 0xe3, 0x04, 0x5c, 0x05, 0xf0, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x1b, - 0x00, 0x36, 0x40, 0x0b, 0x03, 0x04, 0x32, 0x10, 0x36, 0x02, 0x0a, 0x32, - 0x16, 0x35, 0x1c, 0x10, 0xfc, 0xec, 0xc4, 0xfc, 0xec, 0xc4, 0xb2, 0x80, - 0x03, 0x01, 0x5d, 0x31, 0x00, 0x40, 0x0f, 0x07, 0x97, 0x19, 0x96, 0x1c, - 0x01, 0x97, 0x02, 0xb1, 0x1c, 0x0d, 0x97, 0x13, 0x99, 0x1c, 0x10, 0xf4, - 0xec, 0x10, 0xf4, 0xec, 0x10, 0xf4, 0xec, 0x30, 0x01, 0x21, 0x35, 0x21, - 0x17, 0x10, 0x02, 0x23, 0x22, 0x02, 0x11, 0x10, 0x12, 0x33, 0x32, 0x12, - 0x13, 0x10, 0x02, 0x23, 0x22, 0x02, 0x11, 0x10, 0x12, 0x33, 0x32, 0x12, - 0x03, 0x30, 0xfe, 0x71, 0x01, 0x8f, 0x59, 0x87, 0x9a, 0x99, 0x87, 0x87, - 0x99, 0x9a, 0x87, 0xd3, 0xf7, 0xfd, 0xfd, 0xf6, 0xf7, 0xfc, 0xfd, 0xf7, - 0x02, 0xc7, 0xaa, 0x88, 0x01, 0x49, 0x01, 0x1a, 0xfe, 0xe6, 0xfe, 0xb7, - 0xfe, 0xb8, 0xfe, 0xe6, 0x01, 0x19, 0x01, 0x49, 0xfe, 0x7a, 0xfe, 0x80, - 0x01, 0x7e, 0x01, 0x88, 0x01, 0x87, 0x01, 0x80, 0xfe, 0x80, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc9, 0x00, 0x00, 0x04, 0x06, 0x05, 0xd5, 0x10, 0x06, - 0x00, 0x2c, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0x00, 0x00, 0x04, 0xc9, - 0x05, 0xd5, 0x10, 0x06, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x25, - 0x00, 0x00, 0x04, 0xac, 0x05, 0xd5, 0x00, 0x06, 0x00, 0x30, 0xb4, 0x04, - 0x2f, 0x01, 0x30, 0x07, 0x10, 0xf4, 0xe4, 0x31, 0x00, 0xb3, 0x02, 0xb4, - 0x05, 0x01, 0x2f, 0x3c, 0xe4, 0x30, 0x05, 0x40, 0x10, 0x06, 0x25, 0x02, - 0x01, 0x05, 0x25, 0x03, 0x04, 0x03, 0x06, 0x25, 0x00, 0x25, 0x01, 0x02, - 0x01, 0x07, 0x10, 0xec, 0xec, 0x07, 0x10, 0xec, 0x08, 0xec, 0x33, 0x23, - 0x01, 0x33, 0x01, 0x23, 0x01, 0xf6, 0xd1, 0x01, 0xc9, 0xf5, 0x01, 0xc9, - 0xd1, 0xfe, 0x8d, 0x05, 0xd5, 0xfa, 0x2b, 0x05, 0x23, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x56, 0x00, 0x00, 0x04, 0x79, 0x05, 0xd5, 0x10, 0x06, - 0x00, 0x30, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8b, 0x00, 0x00, 0x04, 0x46, - 0x05, 0xd5, 0x10, 0x06, 0x00, 0x31, 0x00, 0x00, 0x00, 0x03, 0x00, 0x89, - 0x00, 0x00, 0x04, 0x48, 0x05, 0xd5, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, - 0x00, 0x28, 0xb7, 0x07, 0x08, 0x00, 0x31, 0x06, 0x0b, 0x03, 0x0c, 0x10, - 0xd4, 0x3c, 0xc4, 0xf4, 0x3c, 0xc4, 0x31, 0x00, 0x40, 0x0c, 0x02, 0x97, - 0x03, 0x88, 0x0a, 0x05, 0x97, 0x06, 0xb1, 0x0b, 0x97, 0x0a, 0x2f, 0xec, - 0xf4, 0xec, 0x10, 0xf4, 0xec, 0x30, 0x01, 0x15, 0x21, 0x35, 0x01, 0x21, - 0x35, 0x21, 0x13, 0x15, 0x21, 0x35, 0x04, 0x48, 0xfc, 0x41, 0x02, 0xf4, - 0xfd, 0xd7, 0x02, 0x29, 0xcb, 0xfc, 0x41, 0x05, 0xd5, 0xaa, 0xaa, 0xfc, - 0xf2, 0xaa, 0xfd, 0x39, 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x00, 0x75, - 0xff, 0xe3, 0x04, 0x5c, 0x05, 0xf0, 0x10, 0x06, 0x00, 0x32, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x89, 0x00, 0x00, 0x04, 0x48, 0x05, 0xd5, 0x10, 0x06, - 0x03, 0x58, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc5, 0x00, 0x00, 0x04, 0x75, - 0x05, 0xd5, 0x10, 0x06, 0x00, 0x33, 0x00, 0x00, 0x00, 0x01, 0x00, 0x78, - 0x00, 0x00, 0x04, 0x6d, 0x05, 0xd5, 0x00, 0x0b, 0x00, 0x3c, 0xb5, 0x02, - 0x09, 0x31, 0x05, 0x08, 0x0c, 0x10, 0xd4, 0x3c, 0xe4, 0x32, 0x31, 0x00, - 0x40, 0x09, 0x0b, 0x07, 0x97, 0x08, 0x88, 0x01, 0x05, 0x97, 0x04, 0x2f, - 0xec, 0x32, 0xf4, 0xec, 0x32, 0x30, 0x05, 0x40, 0x10, 0x00, 0x25, 0x06, - 0x05, 0x0b, 0x25, 0x06, 0x07, 0x06, 0x00, 0x25, 0x01, 0x25, 0x05, 0x06, - 0x05, 0x07, 0x10, 0xec, 0xec, 0x07, 0x10, 0xec, 0x08, 0xec, 0x09, 0x01, - 0x21, 0x15, 0x21, 0x35, 0x09, 0x01, 0x35, 0x21, 0x15, 0x21, 0x03, 0x12, - 0xfe, 0x39, 0x03, 0x22, 0xfc, 0x0b, 0x01, 0xc6, 0xfe, 0x3a, 0x03, 0xf5, - 0xfc, 0xde, 0x02, 0xeb, 0xfd, 0xbf, 0xaa, 0xaa, 0x02, 0x41, 0x02, 0x40, - 0xaa, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x00, 0x2f, 0x00, 0x00, 0x04, 0xa2, - 0x05, 0xd5, 0x10, 0x06, 0x00, 0x37, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, - 0x00, 0x00, 0x04, 0xac, 0x05, 0xd5, 0x10, 0x06, 0x00, 0x3c, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x75, 0x00, 0x00, 0x04, 0x5a, 0x05, 0xd5, 0x00, 0x1d, - 0x00, 0x26, 0x00, 0x2f, 0x00, 0x4d, 0x40, 0x13, 0x22, 0x32, 0x05, 0x0b, - 0x1c, 0x09, 0x26, 0x00, 0x1e, 0x0e, 0x1b, 0x19, 0x2c, 0x32, 0x14, 0x10, - 0x28, 0x19, 0x30, 0x10, 0xd4, 0x3c, 0x3c, 0xdc, 0xec, 0x10, 0xc4, 0x32, - 0xfc, 0x3c, 0x3c, 0xc4, 0x32, 0xdc, 0xec, 0x31, 0x00, 0x40, 0x14, 0x26, - 0x28, 0x97, 0x01, 0x18, 0x00, 0x1a, 0x97, 0x1b, 0x88, 0x0d, 0x1e, 0x27, - 0x97, 0x09, 0x10, 0x0a, 0x0e, 0x97, 0x0d, 0x2f, 0xfc, 0x3c, 0xdc, 0x3c, - 0xec, 0x32, 0x10, 0xf4, 0xfc, 0x3c, 0xdc, 0x3c, 0xec, 0x32, 0x30, 0x01, - 0x15, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x15, 0x33, 0x15, - 0x21, 0x35, 0x33, 0x35, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, - 0x35, 0x23, 0x35, 0x21, 0x15, 0x03, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, - 0x26, 0x27, 0x03, 0x11, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x02, - 0xcd, 0xb0, 0x61, 0x7c, 0x7b, 0x61, 0xb1, 0x93, 0xfe, 0x0f, 0x93, 0xb1, - 0x61, 0x7b, 0x7b, 0x62, 0xb0, 0x93, 0x01, 0xf1, 0x93, 0x4c, 0x2b, 0x43, - 0x43, 0x2b, 0x4c, 0xcb, 0x4c, 0x2a, 0x44, 0x44, 0x2a, 0x05, 0x2b, 0x76, - 0x13, 0x5b, 0x73, 0xeb, 0xeb, 0x73, 0x5a, 0x13, 0x74, 0xaa, 0xaa, 0x74, - 0x13, 0x5a, 0x73, 0xeb, 0xeb, 0x73, 0x5b, 0x13, 0x76, 0xaa, 0xaa, 0xfc, - 0xa3, 0x10, 0x2a, 0x44, 0x9d, 0x9e, 0x44, 0x2a, 0x10, 0xfd, 0xc9, 0x02, - 0x37, 0x10, 0x2a, 0x44, 0x9e, 0x9d, 0x44, 0x2a, 0xff, 0xff, 0x00, 0x12, - 0x00, 0x00, 0x04, 0xbe, 0x05, 0xd5, 0x10, 0x06, 0x00, 0x3b, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x75, 0x00, 0x00, 0x04, 0x5a, 0x05, 0xd5, 0x00, 0x1f, - 0x00, 0x39, 0x40, 0x0f, 0x06, 0x1e, 0x07, 0x0e, 0x0c, 0x00, 0x1e, 0x11, - 0x1f, 0x19, 0x1e, 0x18, 0x13, 0x1f, 0x20, 0x10, 0xd4, 0x3c, 0xd4, 0xec, - 0x10, 0xc4, 0xfc, 0x3c, 0xc4, 0xd4, 0xec, 0x31, 0x00, 0x40, 0x0d, 0x01, - 0x1e, 0x97, 0x0c, 0x13, 0x0d, 0x11, 0x97, 0x06, 0x1f, 0x18, 0x88, 0x10, - 0x2f, 0xe4, 0x32, 0x32, 0xfc, 0x3c, 0xdc, 0x3c, 0xec, 0x32, 0x30, 0x01, - 0x11, 0x36, 0x37, 0x36, 0x19, 0x01, 0x33, 0x11, 0x10, 0x07, 0x06, 0x07, - 0x15, 0x33, 0x15, 0x21, 0x35, 0x33, 0x35, 0x26, 0x27, 0x26, 0x19, 0x01, - 0x33, 0x11, 0x10, 0x17, 0x16, 0x17, 0x11, 0x02, 0xcd, 0x49, 0x2e, 0x4b, - 0xcb, 0x7b, 0x62, 0xb0, 0x93, 0xfe, 0x0f, 0x93, 0xb0, 0x62, 0x7b, 0xcb, - 0x4c, 0x2d, 0x49, 0x05, 0xd5, 0xfc, 0x5b, 0x22, 0x57, 0x91, 0x01, 0x44, - 0x01, 0x57, 0xfe, 0xa9, 0xfe, 0x78, 0xbf, 0x97, 0x20, 0xd6, 0xaa, 0xaa, - 0xd6, 0x20, 0x97, 0xbf, 0x01, 0x88, 0x01, 0x57, 0xfe, 0xa9, 0xfe, 0xbc, - 0x91, 0x57, 0x22, 0x03, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x4a, - 0x00, 0x00, 0x04, 0x87, 0x05, 0xb4, 0x00, 0x1f, 0x00, 0x40, 0x40, 0x17, - 0x02, 0x1e, 0x1b, 0x0e, 0x11, 0x71, 0x15, 0x1e, 0x71, 0x1b, 0x0f, 0x72, - 0x15, 0x6f, 0x0b, 0x70, 0x00, 0x72, 0x1b, 0x6f, 0x05, 0x6c, 0x20, 0x10, - 0xf4, 0xec, 0xe4, 0xf4, 0xec, 0xe4, 0x10, 0xe4, 0x10, 0xe4, 0x39, 0x11, - 0x12, 0x39, 0x31, 0x00, 0x40, 0x0c, 0x18, 0xf8, 0x08, 0xf7, 0x1e, 0x12, - 0x0e, 0x03, 0x01, 0xf9, 0x10, 0x00, 0x2f, 0x3c, 0xee, 0x17, 0x32, 0xf6, - 0xee, 0x30, 0x33, 0x35, 0x33, 0x26, 0x02, 0x35, 0x10, 0x00, 0x33, 0x32, - 0x00, 0x11, 0x14, 0x02, 0x07, 0x33, 0x15, 0x21, 0x35, 0x36, 0x12, 0x35, - 0x34, 0x02, 0x23, 0x22, 0x02, 0x15, 0x14, 0x12, 0x17, 0x15, 0x4a, 0xf5, - 0x7b, 0x6e, 0x01, 0x20, 0xf0, 0xf2, 0x01, 0x21, 0x6f, 0x7b, 0xf8, 0xfe, - 0x31, 0x78, 0x86, 0xb4, 0x9a, 0x9a, 0xb3, 0x86, 0x78, 0xac, 0x86, 0x01, - 0x20, 0xbc, 0x01, 0x37, 0x01, 0x6f, 0xfe, 0x92, 0xfe, 0xc8, 0xbc, 0xfe, - 0xdf, 0x85, 0xac, 0xac, 0x4c, 0x01, 0x49, 0xde, 0xe6, 0x01, 0x09, 0xfe, - 0xf7, 0xe6, 0xde, 0xfe, 0xb7, 0x4c, 0xac, 0x00, 0xff, 0xff, 0x00, 0xc9, - 0x00, 0x00, 0x04, 0x06, 0x07, 0x4e, 0x10, 0x27, 0x0c, 0xbe, 0x00, 0x00, - 0x01, 0x75, 0x10, 0x06, 0x02, 0xe2, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, - 0x00, 0x00, 0x04, 0xac, 0x07, 0x4e, 0x10, 0x27, 0x0c, 0xbe, 0x00, 0x00, - 0x01, 0x75, 0x10, 0x06, 0x02, 0xed, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xff, 0xe7, 0x04, 0x95, 0x06, 0x66, 0x10, 0x26, 0x02, 0xf9, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa9, - 0xff, 0xea, 0x04, 0x28, 0x06, 0x66, 0x10, 0x26, 0x02, 0xfd, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, - 0xfe, 0x56, 0x04, 0x1b, 0x06, 0x66, 0x10, 0x26, 0x02, 0xff, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x36, - 0x00, 0x00, 0x03, 0xcf, 0x06, 0x66, 0x10, 0x26, 0x03, 0x01, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x33, - 0x00, 0x00, 0x04, 0x69, 0x07, 0xd8, 0x10, 0x26, 0x03, 0x0d, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x46, - 0xff, 0xe7, 0x04, 0x95, 0x04, 0x79, 0x00, 0x0d, 0x00, 0x2a, 0x00, 0x00, - 0x01, 0x27, 0x26, 0x27, 0x26, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, - 0x32, 0x37, 0x12, 0x1b, 0x01, 0x33, 0x03, 0x17, 0x16, 0x17, 0x16, 0x3b, - 0x01, 0x15, 0x23, 0x22, 0x27, 0x26, 0x27, 0x06, 0x07, 0x06, 0x27, 0x26, - 0x27, 0x26, 0x11, 0x10, 0x37, 0x36, 0x37, 0x02, 0xfe, 0x2c, 0x2d, 0xb1, - 0x62, 0x3d, 0x4d, 0x4a, 0x4d, 0x55, 0x85, 0x48, 0x69, 0x3b, 0x63, 0xa4, - 0xcd, 0x28, 0x09, 0x23, 0x29, 0x20, 0x58, 0x6e, 0x5e, 0x54, 0x29, 0x11, - 0x2e, 0x5c, 0x2d, 0x8f, 0xc6, 0x72, 0x76, 0x7e, 0x8f, 0xa1, 0x02, 0x09, - 0xe7, 0xec, 0x01, 0x01, 0x6f, 0x89, 0xb7, 0xdc, 0x69, 0x6b, 0xd5, 0x03, - 0x2a, 0xfe, 0xbd, 0x01, 0x25, 0xfd, 0xa1, 0xdb, 0x31, 0x29, 0x30, 0x9c, - 0x54, 0x2a, 0x58, 0x6d, 0x59, 0x2a, 0x01, 0x02, 0x96, 0x9c, 0x01, 0x14, - 0x01, 0x29, 0x87, 0x97, 0x03, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x97, - 0xfe, 0x56, 0x04, 0x61, 0x06, 0x21, 0x00, 0x0e, 0x00, 0x1c, 0x00, 0x00, - 0x25, 0x11, 0x23, 0x11, 0x10, 0x05, 0x04, 0x11, 0x02, 0x07, 0x04, 0x13, - 0x12, 0x05, 0x06, 0x03, 0x16, 0x17, 0x04, 0x11, 0x10, 0x05, 0x35, 0x04, - 0x11, 0x34, 0x27, 0x24, 0x11, 0x01, 0x51, 0xb9, 0x01, 0xcd, 0x01, 0x8f, - 0x01, 0xab, 0x01, 0x16, 0x02, 0x04, 0xfe, 0x1a, 0x82, 0xab, 0x51, 0xe3, - 0x01, 0x20, 0xfe, 0x30, 0x01, 0x6b, 0xea, 0xfe, 0xfb, 0x45, 0xfe, 0x11, - 0x06, 0x03, 0x01, 0xe7, 0x1f, 0x1b, 0xfe, 0x9a, 0xfe, 0xec, 0x62, 0x36, - 0xfe, 0xd1, 0xfe, 0x3d, 0x17, 0x06, 0x01, 0x71, 0x8d, 0x15, 0x19, 0x01, - 0x27, 0x01, 0x1a, 0x16, 0xaa, 0x06, 0x01, 0x30, 0xbd, 0x0d, 0x0f, 0xfe, - 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, 0xfe, 0x56, 0x04, 0x6d, - 0x04, 0x60, 0x00, 0x0e, 0x00, 0x00, 0x13, 0x26, 0x2b, 0x01, 0x35, 0x33, - 0x32, 0x17, 0x09, 0x01, 0x33, 0x01, 0x11, 0x23, 0x11, 0xdc, 0x2d, 0x5e, - 0x31, 0x46, 0xc2, 0x41, 0x00, 0xff, 0x01, 0x46, 0xbf, 0xfe, 0x5b, 0xbe, - 0x03, 0x44, 0x7e, 0x9e, 0xb0, 0xfd, 0x53, 0x03, 0x5d, 0xfb, 0xa0, 0xfe, - 0x56, 0x01, 0xaa, 0x00, 0x00, 0x02, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, - 0x06, 0x22, 0x00, 0x0b, 0x00, 0x34, 0x00, 0x00, 0x01, 0x22, 0x06, 0x15, - 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x25, 0x26, 0x27, 0x26, - 0x35, 0x34, 0x36, 0x33, 0x32, 0x1f, 0x01, 0x15, 0x26, 0x27, 0x26, 0x0f, - 0x01, 0x06, 0x0f, 0x01, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x17, - 0x16, 0x17, 0x16, 0x11, 0x10, 0x02, 0x23, 0x22, 0x02, 0x11, 0x10, 0x37, - 0x36, 0x02, 0x68, 0x8c, 0x90, 0x90, 0x8c, 0x8d, 0x90, 0x90, 0xfe, 0x59, - 0x13, 0x28, 0x3e, 0xed, 0xc5, 0x66, 0x32, 0x97, 0x42, 0x46, 0x55, 0x52, - 0x20, 0x49, 0x3c, 0x27, 0x1b, 0x0d, 0x11, 0x29, 0x18, 0x69, 0xeb, 0x79, - 0x7c, 0xf6, 0xea, 0xe9, 0xf6, 0x7b, 0x1f, 0x03, 0xdf, 0xda, 0xd6, 0xd5, - 0xdb, 0xdb, 0xd5, 0xd6, 0xda, 0x4c, 0x09, 0x28, 0x3d, 0x5c, 0x88, 0xa4, - 0x0c, 0x24, 0xad, 0x18, 0x0f, 0x11, 0x02, 0x01, 0x02, 0x2b, 0x1c, 0x18, - 0x2e, 0x21, 0x13, 0x18, 0x15, 0x0d, 0x01, 0x03, 0x94, 0x97, 0xfe, 0xe2, - 0xfe, 0xe1, 0xfe, 0xd3, 0x01, 0x2d, 0x01, 0x1f, 0x01, 0x1e, 0x97, 0x26, - 0xff, 0xff, 0x00, 0xa9, 0xff, 0xea, 0x04, 0x28, 0x04, 0x7b, 0x10, 0x06, - 0x02, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x99, 0xfe, 0x52, 0x04, 0x26, - 0x06, 0x14, 0x00, 0x1d, 0x00, 0x00, 0x25, 0x16, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x06, 0x23, 0x34, 0x35, 0x16, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, - 0x23, 0x20, 0x03, 0x02, 0x01, 0x21, 0x35, 0x21, 0x15, 0x00, 0x13, 0x12, - 0x02, 0xf8, 0x84, 0x4f, 0x54, 0x4a, 0x50, 0xa3, 0x45, 0x2a, 0x20, 0x20, - 0x1f, 0x3a, 0xfd, 0xb5, 0x14, 0x11, 0x02, 0x4c, 0xfd, 0xec, 0x03, 0x66, - 0xfc, 0xfe, 0x2e, 0x2c, 0x7f, 0x01, 0x4b, 0x4f, 0x78, 0x73, 0x50, 0x57, - 0x4b, 0x4c, 0x05, 0x2c, 0x23, 0x25, 0x35, 0x2c, 0x2a, 0x02, 0x33, 0x01, - 0xe0, 0x01, 0x65, 0xb9, 0xb9, 0xfe, 0x61, 0xfe, 0x5a, 0xfe, 0x69, 0x00, - 0x00, 0x01, 0x00, 0xc3, 0xfe, 0x56, 0x04, 0x1b, 0x04, 0x7b, 0x00, 0x13, - 0x00, 0x2e, 0x40, 0x0a, 0x02, 0x06, 0x00, 0x4a, 0x0d, 0x09, 0x06, 0x0b, - 0x46, 0x14, 0x10, 0xf4, 0xec, 0x32, 0xfc, 0xec, 0x31, 0x40, 0x0f, 0x09, - 0x0e, 0x03, 0x00, 0x04, 0x0a, 0x06, 0x8c, 0x11, 0xbe, 0x0c, 0xc2, 0x01, - 0xc3, 0x0a, 0x00, 0x2f, 0xe4, 0xe4, 0xf4, 0xec, 0x11, 0x17, 0x39, 0x30, - 0x01, 0x11, 0x23, 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, - 0x11, 0x33, 0x15, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x04, 0x1b, 0xb9, 0x6a, - 0x71, 0x81, 0x8b, 0xb8, 0xb8, 0x31, 0xa8, 0x73, 0xab, 0xa9, 0x02, 0xb6, - 0xfb, 0xa0, 0x04, 0x60, 0x97, 0x8e, 0xb7, 0xab, 0xfd, 0x87, 0x04, 0x60, - 0xa8, 0x60, 0x63, 0xe1, 0x00, 0x03, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, - 0x05, 0xdc, 0x00, 0x08, 0x00, 0x11, 0x00, 0x1d, 0x00, 0x39, 0x40, 0x0b, - 0x09, 0x00, 0x12, 0x15, 0x44, 0x0a, 0x08, 0x12, 0x1b, 0x3e, 0x1e, 0x10, - 0xf4, 0xec, 0x32, 0xfc, 0xec, 0x32, 0x31, 0x40, 0x0e, 0x09, 0xb6, 0x00, - 0x0e, 0x8c, 0x18, 0x00, 0x04, 0x8c, 0x12, 0x9b, 0x18, 0x99, 0x1e, 0x00, - 0x10, 0xe4, 0xf4, 0xec, 0xc4, 0x10, 0xec, 0xb6, 0xef, 0x00, 0xbf, 0x00, - 0x40, 0x00, 0x03, 0x5d, 0x10, 0xec, 0x30, 0x01, 0x26, 0x27, 0x26, 0x23, - 0x22, 0x07, 0x06, 0x07, 0x05, 0x21, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, - 0x36, 0x01, 0x32, 0x12, 0x11, 0x10, 0x02, 0x23, 0x22, 0x02, 0x11, 0x10, - 0x12, 0x03, 0x83, 0x07, 0x3f, 0x48, 0x8d, 0x8c, 0x48, 0x3f, 0x07, 0x02, - 0x35, 0xfd, 0xcb, 0x06, 0x40, 0x48, 0x8c, 0x8d, 0x48, 0x40, 0xfe, 0xeb, - 0xe9, 0xf7, 0xf6, 0xea, 0xe9, 0xf6, 0xf6, 0x03, 0x3c, 0xe2, 0x87, 0x99, - 0x99, 0x87, 0xe2, 0xb8, 0xe0, 0x89, 0x9a, 0x9a, 0x89, 0x04, 0x38, 0xfe, - 0x77, 0xfe, 0x8d, 0xfe, 0x8a, 0xfe, 0x79, 0x01, 0x87, 0x01, 0x76, 0x01, - 0x73, 0x01, 0x89, 0x00, 0x00, 0x01, 0x01, 0x36, 0x00, 0x00, 0x03, 0xcf, - 0x04, 0x60, 0x00, 0x0f, 0x00, 0x1d, 0x40, 0x06, 0x06, 0x00, 0x06, 0x0f, - 0x0d, 0x10, 0x10, 0xd4, 0xcc, 0xfc, 0xcc, 0x31, 0x40, 0x07, 0x0d, 0xb6, - 0x00, 0xc2, 0x06, 0xb6, 0x07, 0x00, 0x2f, 0xec, 0xf4, 0xec, 0x30, 0x01, - 0x11, 0x14, 0x17, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, 0x26, 0x27, - 0x11, 0x23, 0x35, 0x02, 0xc4, 0x22, 0x24, 0x6c, 0x59, 0x6f, 0xb4, 0x52, - 0x51, 0x01, 0xd2, 0x04, 0x60, 0xfd, 0x2b, 0x91, 0x2e, 0x30, 0x9c, 0x60, - 0x62, 0xd4, 0x02, 0x3b, 0x8f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xec, - 0x00, 0x00, 0x04, 0xb2, 0x04, 0x60, 0x12, 0x06, 0x00, 0xfa, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x44, 0x00, 0x00, 0x04, 0x86, 0x06, 0x15, 0x00, 0x0d, - 0x00, 0x00, 0x09, 0x01, 0x23, 0x09, 0x01, 0x23, 0x01, 0x27, 0x26, 0x07, - 0x23, 0x35, 0x17, 0x04, 0x02, 0x82, 0x02, 0x04, 0xc3, 0xfe, 0xc6, 0xfe, - 0x7e, 0xc3, 0x01, 0xeb, 0x4a, 0x2f, 0x9a, 0x31, 0x46, 0x01, 0x12, 0x05, - 0x65, 0xfa, 0x9b, 0x03, 0x3c, 0xfc, 0xc4, 0x04, 0x32, 0xc6, 0x7f, 0x01, - 0x9e, 0x02, 0x07, 0x00, 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x54, 0x04, 0x9e, - 0x04, 0x60, 0x10, 0x06, 0x00, 0x77, 0x00, 0x00, 0x00, 0x01, 0x00, 0x74, - 0x00, 0x00, 0x04, 0x42, 0x04, 0x60, 0x00, 0x14, 0x00, 0x00, 0x21, 0x01, - 0x33, 0x01, 0x36, 0x37, 0x36, 0x37, 0x36, 0x27, 0x26, 0x27, 0x33, 0x16, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x01, 0xca, 0xfe, 0xaa, 0xc6, - 0x01, 0x21, 0x78, 0x64, 0x4c, 0x04, 0x02, 0x18, 0x1c, 0x6a, 0xba, 0x45, - 0x2e, 0x2a, 0x88, 0xb1, 0x7b, 0x04, 0x60, 0xfc, 0x54, 0x7c, 0xac, 0x81, - 0x70, 0x35, 0x64, 0x77, 0x83, 0x59, 0x7c, 0x72, 0x4e, 0xc4, 0xaf, 0xe4, - 0x74, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xa2, 0xfe, 0x52, 0x04, 0x38, - 0x06, 0x14, 0x00, 0x26, 0x00, 0x00, 0x25, 0x16, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x06, 0x23, 0x34, 0x35, 0x16, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, - 0x23, 0x20, 0x03, 0x34, 0x25, 0x24, 0x11, 0x34, 0x37, 0x23, 0x35, 0x21, - 0x15, 0x20, 0x11, 0x14, 0x05, 0x15, 0x04, 0x17, 0x12, 0x03, 0x11, 0x84, - 0x4f, 0x54, 0x4a, 0x50, 0xa3, 0x45, 0x2a, 0x20, 0x20, 0x20, 0x39, 0xfd, - 0x92, 0x01, 0x01, 0x4d, 0xfe, 0xe8, 0xdc, 0xd0, 0x03, 0x15, 0xfd, 0x8b, - 0x02, 0x10, 0xfd, 0xc7, 0x01, 0x02, 0x7f, 0x01, 0x4b, 0x4f, 0x78, 0x73, - 0x50, 0x57, 0x4b, 0x4c, 0x05, 0x2c, 0x23, 0x25, 0x35, 0x2c, 0x2a, 0x01, - 0xe1, 0xe8, 0x70, 0x24, 0x01, 0x04, 0xc5, 0x52, 0xb9, 0xb9, 0xfe, 0xdd, - 0xbf, 0x09, 0xaa, 0x26, 0xdc, 0xfe, 0xbf, 0x00, 0xff, 0xff, 0x00, 0x89, - 0xff, 0xe3, 0x04, 0x48, 0x04, 0x7b, 0x10, 0x06, 0x00, 0x52, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x50, 0xff, 0xd9, 0x04, 0x9e, 0x04, 0x60, 0x00, 0x17, - 0x00, 0x00, 0x13, 0x21, 0x15, 0x23, 0x11, 0x14, 0x16, 0x33, 0x32, 0x36, - 0x37, 0x15, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x35, 0x11, 0x21, 0x11, 0x23, - 0x11, 0x23, 0x50, 0x04, 0x31, 0x8d, 0x31, 0x37, 0x0f, 0x2c, 0x07, 0x23, - 0x4a, 0x25, 0x71, 0x5c, 0xfe, 0x54, 0xb4, 0x8f, 0x04, 0x60, 0xb8, 0xfd, - 0x50, 0x48, 0x3f, 0x05, 0x01, 0x85, 0x0d, 0x0c, 0x83, 0xb0, 0x02, 0x9c, - 0xfc, 0x58, 0x03, 0xa8, 0x00, 0x02, 0x00, 0xbe, 0xfe, 0x56, 0x04, 0x54, - 0x04, 0x7b, 0x00, 0x10, 0x00, 0x1c, 0x00, 0x2e, 0x40, 0x0a, 0x11, 0x12, - 0x04, 0x47, 0x17, 0x0a, 0x06, 0x0c, 0x46, 0x1d, 0x10, 0xf4, 0xec, 0x32, - 0xfc, 0xec, 0x31, 0x40, 0x0e, 0x0a, 0x14, 0x1a, 0x8c, 0x07, 0x14, 0x8c, - 0x00, 0xbe, 0x07, 0x99, 0x0b, 0xc3, 0x1d, 0x00, 0x10, 0xe4, 0xe4, 0xf4, - 0xec, 0x10, 0xee, 0x11, 0x39, 0x30, 0x01, 0x36, 0x17, 0x16, 0x11, 0x10, - 0x02, 0x23, 0x22, 0x26, 0x27, 0x11, 0x23, 0x11, 0x10, 0x37, 0x36, 0x01, - 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x02, - 0x84, 0xe8, 0x74, 0x74, 0xe8, 0xca, 0x66, 0x99, 0x2c, 0xb9, 0x6e, 0x83, - 0x01, 0xe4, 0x87, 0x85, 0x86, 0x8a, 0x8a, 0x86, 0x85, 0x87, 0x04, 0x7b, - 0x01, 0x9e, 0x9d, 0xfe, 0xea, 0xfe, 0xef, 0xfe, 0xc9, 0x57, 0x53, 0xfd, - 0xc9, 0x03, 0xc6, 0x01, 0x3c, 0x86, 0x9d, 0xfd, 0xb4, 0xd6, 0xda, 0xdb, - 0xd5, 0xd4, 0xdc, 0xda, 0x00, 0x01, 0x00, 0xc3, 0xfe, 0x52, 0x04, 0x25, - 0x04, 0x7b, 0x00, 0x24, 0x00, 0x00, 0x25, 0x16, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x06, 0x23, 0x34, 0x35, 0x16, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, - 0x23, 0x20, 0x00, 0x10, 0x00, 0x21, 0x32, 0x16, 0x17, 0x15, 0x2e, 0x01, - 0x23, 0x22, 0x06, 0x15, 0x14, 0x17, 0x16, 0x02, 0xec, 0x84, 0x4f, 0x54, - 0x4a, 0x50, 0xa3, 0x45, 0x2a, 0x20, 0x20, 0x1f, 0x3a, 0xfe, 0xfc, 0xfe, - 0xdb, 0x01, 0x25, 0x01, 0x04, 0x51, 0x9a, 0x4e, 0x49, 0x93, 0x5d, 0xad, - 0xba, 0x5d, 0x5e, 0x7f, 0x01, 0x4b, 0x4f, 0x78, 0x73, 0x50, 0x57, 0x4b, - 0x4c, 0x05, 0x2c, 0x23, 0x25, 0x35, 0x2c, 0x2a, 0x01, 0x38, 0x02, 0x28, - 0x01, 0x38, 0x2a, 0x2c, 0xc1, 0x41, 0x3a, 0xe0, 0xd0, 0xd1, 0x6e, 0x6f, - 0x00, 0x02, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x6b, 0x04, 0x60, 0x00, 0x0d, - 0x00, 0x1d, 0x00, 0x32, 0x40, 0x0a, 0x1d, 0x0a, 0x12, 0x10, 0x44, 0x04, - 0x12, 0x17, 0x3e, 0x1e, 0x10, 0xf4, 0xec, 0xf4, 0xec, 0xc4, 0xb3, 0x0e, - 0x1b, 0x17, 0x10, 0x11, 0x12, 0x39, 0x39, 0x31, 0x40, 0x0b, 0x07, 0x8c, - 0x14, 0x00, 0x0e, 0xb6, 0x1b, 0xc2, 0x14, 0x99, 0x1e, 0x00, 0x10, 0xe4, - 0xf4, 0xec, 0x32, 0x10, 0xec, 0x30, 0x01, 0x22, 0x07, 0x06, 0x15, 0x14, - 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x27, 0x26, 0x37, 0x16, 0x11, 0x14, - 0x07, 0x06, 0x27, 0x22, 0x02, 0x11, 0x10, 0x37, 0x36, 0x33, 0x21, 0x15, - 0x02, 0x61, 0x87, 0x46, 0x48, 0x90, 0x8c, 0x8d, 0x90, 0xac, 0x3c, 0xdd, - 0xce, 0x97, 0x72, 0xd7, 0xe9, 0xf6, 0x7b, 0x73, 0xf1, 0x02, 0x03, 0x03, - 0xa7, 0x50, 0x53, 0xd5, 0xd5, 0xdb, 0xdb, 0x92, 0xf9, 0x81, 0x2d, 0x15, - 0xa2, 0xfe, 0xe6, 0xe4, 0xa7, 0x7f, 0x01, 0x01, 0x2d, 0x01, 0x1f, 0x01, - 0x09, 0x99, 0x8f, 0xb8, 0x00, 0x01, 0x00, 0x9f, 0x00, 0x00, 0x04, 0x32, - 0x04, 0x5e, 0x00, 0x11, 0x00, 0x21, 0x40, 0x07, 0x0d, 0x03, 0x0f, 0x06, - 0x0c, 0x0a, 0x12, 0x10, 0xd4, 0xcc, 0xfc, 0xc4, 0xcc, 0x31, 0x00, 0x40, - 0x08, 0x0f, 0x0b, 0x8c, 0x0c, 0xc2, 0x03, 0xb6, 0x04, 0x2f, 0xec, 0xf4, - 0xec, 0x32, 0x30, 0x25, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, 0x26, - 0x35, 0x11, 0x21, 0x35, 0x21, 0x15, 0x21, 0x11, 0x14, 0x02, 0xe6, 0x24, - 0x6c, 0x59, 0x6f, 0xb4, 0x52, 0x52, 0xfe, 0x98, 0x03, 0x92, 0xfe, 0x92, - 0xcc, 0x30, 0x9c, 0x60, 0x62, 0xd4, 0x02, 0x12, 0xb6, 0xb6, 0xfd, 0xe3, - 0x91, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x33, 0x00, 0x00, 0x04, 0x69, - 0x04, 0x60, 0x00, 0x1d, 0x00, 0x00, 0x25, 0x32, 0x37, 0x36, 0x37, 0x36, - 0x27, 0x26, 0x27, 0x33, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x25, - 0x22, 0x27, 0x26, 0x35, 0x03, 0x23, 0x35, 0x21, 0x11, 0x14, 0x17, 0x16, - 0x02, 0x74, 0x96, 0x5a, 0x3b, 0x0f, 0x08, 0x1e, 0x1c, 0x6a, 0xba, 0x46, - 0x2d, 0x2a, 0x80, 0x85, 0xfe, 0xfa, 0xb4, 0x52, 0x52, 0x01, 0xd2, 0x01, - 0x8f, 0x22, 0x24, 0x9c, 0xb3, 0x76, 0xbb, 0x66, 0x80, 0x77, 0x83, 0x5a, - 0x7b, 0x73, 0x9a, 0xe1, 0xcb, 0xd3, 0x01, 0x60, 0x62, 0xd4, 0x02, 0x3b, - 0x8f, 0xfd, 0x2b, 0x91, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x02, 0x00, 0x4c, - 0xfe, 0x56, 0x04, 0x85, 0x04, 0x68, 0x00, 0x0a, 0x00, 0x29, 0x00, 0x4f, - 0x40, 0x0d, 0x07, 0x12, 0x0f, 0x13, 0x03, 0x06, 0x1e, 0x16, 0x27, 0x23, - 0x12, 0x1a, 0x2a, 0x10, 0xb0, 0x0a, 0x4b, 0x51, 0x58, 0xdc, 0x1b, 0xd4, - 0x59, 0xec, 0xd4, 0xb4, 0x30, 0x27, 0x80, 0x27, 0x02, 0x5d, 0x3c, 0xc4, - 0xfc, 0x3c, 0xd4, 0xb4, 0x30, 0x0f, 0x80, 0x0f, 0x02, 0x5d, 0xec, 0x31, - 0x40, 0x10, 0x03, 0x27, 0x8c, 0x16, 0x1f, 0x00, 0x8c, 0x1e, 0x0b, 0xbe, - 0x13, 0x16, 0x99, 0x15, 0xc3, 0x2a, 0x00, 0x10, 0xec, 0xe4, 0x32, 0xf4, - 0x3c, 0xec, 0x32, 0x10, 0xec, 0x32, 0x30, 0x01, 0x22, 0x15, 0x11, 0x32, - 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x32, 0x17, 0x16, 0x11, 0x10, - 0x07, 0x06, 0x23, 0x11, 0x23, 0x11, 0x22, 0x27, 0x26, 0x11, 0x10, 0x37, - 0x36, 0x37, 0x15, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x11, - 0x10, 0x03, 0x05, 0x41, 0x5c, 0x56, 0x4d, 0x4d, 0x47, 0x2a, 0x8a, 0x77, - 0x7f, 0x7f, 0x81, 0xc1, 0xb7, 0xc7, 0x7c, 0x7e, 0x7e, 0x68, 0x9a, 0x41, - 0x31, 0x4c, 0x4c, 0x4e, 0x65, 0x03, 0xcb, 0x91, 0xfd, 0x52, 0x68, 0x5d, - 0xdf, 0xdd, 0x63, 0x5b, 0x9d, 0x84, 0x8d, 0xfe, 0xd9, 0xfe, 0xe6, 0x96, - 0x98, 0xfe, 0x6e, 0x01, 0x91, 0x99, 0x9b, 0x01, 0x14, 0x01, 0x2c, 0x84, - 0x6d, 0x1c, 0xa3, 0x1a, 0x4b, 0x73, 0xbe, 0xd8, 0x65, 0x67, 0x02, 0xaf, - 0x01, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x59, 0xfe, 0x56, 0x04, 0x78, - 0x04, 0x60, 0x00, 0x17, 0x00, 0x00, 0x05, 0x03, 0x01, 0x23, 0x01, 0x03, - 0x26, 0x2b, 0x01, 0x35, 0x33, 0x20, 0x17, 0x13, 0x01, 0x33, 0x01, 0x13, - 0x16, 0x3b, 0x01, 0x15, 0x23, 0x20, 0x02, 0xee, 0x8e, 0xfe, 0xf7, 0xbf, - 0x01, 0x74, 0xb7, 0x2f, 0x9c, 0x31, 0x46, 0x01, 0x00, 0x43, 0x8f, 0x01, - 0x0a, 0xbf, 0xfe, 0x8b, 0xb6, 0x2f, 0x9d, 0x31, 0x46, 0xfe, 0xff, 0xfa, - 0x01, 0x7a, 0xfd, 0xd6, 0x03, 0x09, 0x01, 0xe5, 0x7e, 0x9e, 0xb0, 0xfe, - 0x84, 0x02, 0x2c, 0xfc, 0xf4, 0xfe, 0x1e, 0x7e, 0x9e, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x83, 0xfe, 0x56, 0x04, 0x4e, 0x04, 0x60, 0x00, 0x1b, - 0x00, 0x00, 0x25, 0x36, 0x37, 0x36, 0x35, 0x11, 0x33, 0x11, 0x14, 0x07, - 0x06, 0x07, 0x11, 0x23, 0x11, 0x26, 0x27, 0x26, 0x35, 0x11, 0x33, 0x11, - 0x14, 0x17, 0x16, 0x17, 0x11, 0x33, 0x02, 0xc4, 0x3f, 0x3e, 0x54, 0xb9, - 0x82, 0x79, 0x8f, 0xb7, 0x8f, 0x79, 0x82, 0xb9, 0x54, 0x3e, 0x3f, 0xb7, - 0x8c, 0x16, 0x40, 0x57, 0xa6, 0x02, 0x81, 0xfd, 0x78, 0xd8, 0x91, 0x87, - 0x01, 0xfe, 0x6f, 0x01, 0x91, 0x01, 0x87, 0x91, 0xd8, 0x02, 0x88, 0xfd, - 0x7f, 0xa6, 0x57, 0x40, 0x16, 0x03, 0xd4, 0x00, 0x00, 0x01, 0x00, 0x46, - 0xff, 0xe3, 0x04, 0x8c, 0x04, 0x60, 0x00, 0x26, 0x00, 0x00, 0x01, 0x12, - 0x10, 0x07, 0x06, 0x23, 0x22, 0x26, 0x27, 0x0e, 0x01, 0x23, 0x22, 0x27, - 0x26, 0x10, 0x13, 0x33, 0x02, 0x11, 0x06, 0x17, 0x16, 0x37, 0x36, 0x37, - 0x36, 0x11, 0x33, 0x10, 0x17, 0x16, 0x17, 0x16, 0x37, 0x36, 0x27, 0x10, - 0x03, 0x04, 0x09, 0x83, 0x32, 0x4b, 0xba, 0x55, 0x82, 0x15, 0x14, 0x80, - 0x58, 0xba, 0x4b, 0x32, 0x83, 0xbe, 0x7e, 0x01, 0x12, 0x29, 0x40, 0x56, - 0x22, 0x19, 0xaa, 0x19, 0x22, 0x56, 0x40, 0x29, 0x12, 0x01, 0x7e, 0x04, - 0x60, 0xfe, 0xf8, 0xfd, 0xbf, 0x7b, 0xb9, 0x67, 0x4c, 0x48, 0x6b, 0xb9, - 0x7b, 0x02, 0x41, 0x01, 0x08, 0xfe, 0xed, 0xfe, 0xe1, 0xe2, 0x3e, 0x91, - 0x02, 0x02, 0x6f, 0x52, 0x01, 0x79, 0xfe, 0x87, 0x52, 0x6f, 0x02, 0x02, - 0x91, 0x3e, 0xe2, 0x01, 0x1f, 0x01, 0x13, 0x00, 0xff, 0xff, 0x01, 0x36, - 0x00, 0x00, 0x03, 0xcf, 0x06, 0x10, 0x10, 0x26, 0x03, 0x01, 0x00, 0x00, - 0x10, 0x06, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x33, - 0x00, 0x00, 0x04, 0x69, 0x06, 0x10, 0x10, 0x26, 0x03, 0x0d, 0x00, 0x00, - 0x10, 0x06, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, - 0xff, 0xe3, 0x04, 0x48, 0x06, 0x66, 0x10, 0x26, 0x03, 0x07, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x33, - 0x00, 0x00, 0x04, 0x69, 0x06, 0x66, 0x10, 0x26, 0x03, 0x0d, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xff, 0xe3, 0x04, 0x8c, 0x06, 0x66, 0x10, 0x26, 0x03, 0x11, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x96, - 0xff, 0xe9, 0x04, 0x02, 0x06, 0x24, 0x00, 0x09, 0x00, 0x19, 0x00, 0x23, - 0x00, 0x00, 0x01, 0x20, 0x37, 0x36, 0x27, 0x26, 0x07, 0x06, 0x07, 0x06, - 0x05, 0x04, 0x03, 0x06, 0x25, 0x24, 0x27, 0x26, 0x03, 0x02, 0x37, 0x36, - 0x33, 0x20, 0x13, 0x16, 0x05, 0x06, 0x27, 0x12, 0x17, 0x16, 0x37, 0x36, - 0x37, 0x36, 0x01, 0x5d, 0x01, 0x0c, 0x4e, 0x93, 0x1a, 0x1f, 0xac, 0x8e, - 0x49, 0x35, 0x01, 0xed, 0x01, 0x7c, 0xc0, 0x75, 0xff, 0x00, 0xfe, 0xed, - 0x74, 0x66, 0x0a, 0x09, 0x80, 0x86, 0xd2, 0x01, 0x4d, 0x32, 0x1b, 0xfe, - 0x8e, 0x43, 0xf0, 0x06, 0x36, 0x52, 0xa5, 0xaf, 0x36, 0x57, 0x03, 0x70, - 0x41, 0x7b, 0x89, 0xa1, 0x06, 0x05, 0xa5, 0x7a, 0xfd, 0xfa, 0xfe, 0x89, - 0xe1, 0x0c, 0x0f, 0xc6, 0xb2, 0x01, 0x97, 0x01, 0x7f, 0xca, 0xd4, 0xfe, - 0x82, 0xcd, 0xff, 0x1e, 0x0a, 0xfe, 0xfd, 0x69, 0xa1, 0x04, 0x04, 0x98, - 0xf5, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x74, 0xff, 0xe9, 0x04, 0x52, - 0x06, 0x24, 0x00, 0x09, 0x00, 0x24, 0x00, 0x00, 0x01, 0x36, 0x27, 0x26, - 0x27, 0x26, 0x07, 0x06, 0x17, 0x16, 0x17, 0x04, 0x27, 0x26, 0x37, 0x12, - 0x21, 0x32, 0x17, 0x16, 0x03, 0x02, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, - 0x13, 0x17, 0x12, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x03, 0x8b, 0x04, - 0x35, 0x4a, 0x67, 0xac, 0x1f, 0x1a, 0x93, 0x4e, 0xe9, 0xfe, 0xdd, 0x6e, - 0xf0, 0x1d, 0x2d, 0x01, 0x52, 0xab, 0x87, 0x80, 0x09, 0x09, 0x80, 0x89, - 0xe4, 0xc1, 0x9f, 0x95, 0x0d, 0xc3, 0x07, 0x4e, 0x72, 0x5e, 0x79, 0x64, - 0x50, 0x03, 0x70, 0xbf, 0x77, 0xa6, 0x04, 0x06, 0xa1, 0x89, 0x7b, 0x41, - 0xaa, 0x0a, 0x4b, 0xa4, 0xfb, 0x01, 0x7e, 0xd4, 0xc8, 0xfe, 0x7f, 0xfe, - 0x7d, 0xc6, 0xd5, 0xd5, 0xc8, 0x01, 0xeb, 0x01, 0xfe, 0x53, 0x6a, 0x9c, - 0x9d, 0x7e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x22, 0x00, 0x00, 0x04, 0xa7, - 0x05, 0xd5, 0x00, 0x1b, 0x00, 0x00, 0x01, 0x06, 0x03, 0x06, 0x15, 0x11, - 0x23, 0x11, 0x34, 0x27, 0x02, 0x27, 0x26, 0x07, 0x35, 0x36, 0x17, 0x04, - 0x13, 0x12, 0x37, 0x36, 0x17, 0x16, 0x07, 0x06, 0x27, 0x26, 0x03, 0xad, - 0x71, 0x4f, 0x2a, 0xcb, 0x2a, 0x64, 0x5c, 0x74, 0x78, 0x4c, 0x97, 0x01, - 0x0f, 0x4a, 0x73, 0xe5, 0x6f, 0x40, 0x7a, 0x38, 0x20, 0x76, 0x56, 0x05, - 0x11, 0x4f, 0xfe, 0xfa, 0x8d, 0xa5, 0xfd, 0x76, 0x02, 0x8a, 0xb4, 0x7e, - 0x01, 0x2a, 0x2b, 0x34, 0x1a, 0xaa, 0x18, 0x1b, 0x30, 0xfe, 0x72, 0x01, - 0x89, 0x35, 0x1a, 0x31, 0x5f, 0x94, 0x54, 0x18, 0x12, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xfe, 0x70, 0x00, 0x00, 0x04, 0xa7, 0x06, 0x66, 0x10, 0x26, - 0x03, 0x19, 0x00, 0x00, 0x10, 0x07, 0x02, 0xcf, 0xfc, 0x95, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x22, 0x00, 0x00, 0x04, 0xa7, 0x07, 0x4e, 0x10, 0x26, - 0x03, 0x19, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xbe, 0x00, 0x00, 0x01, 0x75, - 0x00, 0x03, 0x00, 0x6d, 0xfe, 0x56, 0x04, 0x64, 0x05, 0xd5, 0x00, 0x15, - 0x00, 0x1e, 0x00, 0x27, 0x00, 0x00, 0x01, 0x23, 0x11, 0x26, 0x27, 0x26, - 0x11, 0x10, 0x37, 0x36, 0x37, 0x11, 0x33, 0x11, 0x16, 0x17, 0x16, 0x11, - 0x10, 0x07, 0x06, 0x07, 0x35, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, - 0x27, 0x03, 0x11, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x02, 0xc4, - 0xb8, 0xb3, 0x68, 0x84, 0x84, 0x5d, 0xbe, 0xb8, 0xb2, 0x69, 0x85, 0x85, - 0x5e, 0xbd, 0x56, 0x35, 0x52, 0x52, 0x2a, 0x61, 0xb8, 0x57, 0x34, 0x51, - 0x51, 0x28, 0xfe, 0x56, 0x01, 0x93, 0x18, 0x79, 0x96, 0x01, 0x1f, 0x01, - 0x0e, 0xa7, 0x76, 0x1a, 0x01, 0x61, 0xfe, 0x9f, 0x18, 0x78, 0x97, 0xfe, - 0xe2, 0xfe, 0xf2, 0xa7, 0x78, 0x19, 0xa5, 0x17, 0x47, 0x6e, 0xd5, 0xbc, - 0x87, 0x46, 0x19, 0xfc, 0xbd, 0x03, 0x43, 0x16, 0x49, 0x6d, 0xd6, 0xb9, - 0x8a, 0x44, 0x00, 0x00, 0x00, 0x02, 0x00, 0x39, 0x00, 0x00, 0x04, 0x98, - 0x04, 0x60, 0x00, 0x0d, 0x00, 0x1e, 0x00, 0x00, 0x01, 0x21, 0x06, 0x07, - 0x02, 0x33, 0x32, 0x03, 0x33, 0x02, 0x37, 0x36, 0x03, 0x26, 0x37, 0x16, - 0x17, 0x12, 0x25, 0x26, 0x03, 0x02, 0x23, 0x20, 0x13, 0x36, 0x37, 0x23, - 0x35, 0x21, 0x15, 0x03, 0x92, 0xfd, 0xb0, 0x27, 0x03, 0x04, 0x54, 0xb1, - 0x05, 0xaa, 0x03, 0xaf, 0x51, 0x01, 0x01, 0x9d, 0x30, 0x06, 0x0e, 0xfe, - 0xe4, 0xee, 0x27, 0x28, 0xed, 0xfe, 0xe7, 0x0b, 0x04, 0x30, 0x41, 0x04, - 0x5f, 0x03, 0xa8, 0x90, 0xfd, 0xfe, 0xab, 0x01, 0xd3, 0xfe, 0x2b, 0x02, - 0x01, 0x01, 0x54, 0xfd, 0x90, 0x91, 0xf7, 0xfd, 0xdf, 0x01, 0x01, 0x01, - 0x33, 0xfe, 0xcc, 0x02, 0x20, 0xef, 0x99, 0xb8, 0xb8, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x34, 0xfe, 0x7f, 0x04, 0x91, 0x04, 0x60, 0x00, 0x2f, - 0x00, 0x00, 0x05, 0x26, 0x27, 0x26, 0x37, 0x07, 0x02, 0x07, 0x06, 0x27, - 0x26, 0x37, 0x36, 0x37, 0x36, 0x27, 0x26, 0x23, 0x22, 0x07, 0x35, 0x36, - 0x17, 0x16, 0x17, 0x16, 0x07, 0x37, 0x12, 0x37, 0x36, 0x17, 0x16, 0x07, - 0x06, 0x07, 0x06, 0x17, 0x16, 0x33, 0x32, 0x37, 0x02, 0x07, 0x06, 0x27, - 0x35, 0x04, 0x03, 0xbd, 0xf6, 0x21, 0x15, 0x18, 0xbd, 0x60, 0xc8, 0x8d, - 0x03, 0x01, 0x3d, 0x60, 0x88, 0x5b, 0x2b, 0x1a, 0x8e, 0x39, 0x5b, 0x52, - 0x7e, 0xf6, 0x21, 0x13, 0x2a, 0xbd, 0x60, 0xc8, 0x8d, 0x03, 0x01, 0x3d, - 0x60, 0x88, 0x5b, 0x2b, 0x1a, 0x8e, 0x39, 0x5b, 0x26, 0xcd, 0x98, 0xad, - 0x01, 0x37, 0x0a, 0x20, 0xf0, 0x9c, 0x63, 0x6c, 0xfe, 0xf7, 0x7c, 0x59, - 0x91, 0x44, 0x54, 0x84, 0x7c, 0xcb, 0xa9, 0x68, 0x6c, 0xe0, 0x3d, 0x11, - 0x22, 0xee, 0x8c, 0x70, 0x6c, 0x01, 0x09, 0x7c, 0x59, 0x91, 0x44, 0x54, - 0x84, 0x7c, 0xcb, 0xa9, 0x68, 0x6c, 0xfd, 0xe0, 0x66, 0x4d, 0x5a, 0xa0, - 0xa0, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x75, 0xfe, 0x56, 0x04, 0x5c, - 0x05, 0xf0, 0x00, 0x0a, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x10, 0x02, 0x23, - 0x22, 0x02, 0x11, 0x10, 0x12, 0x33, 0x32, 0x01, 0x11, 0x26, 0x27, 0x26, - 0x11, 0x10, 0x12, 0x33, 0x32, 0x12, 0x11, 0x10, 0x07, 0x06, 0x07, 0x11, - 0x03, 0x89, 0x87, 0x9a, 0x99, 0x87, 0x87, 0x99, 0x9a, 0xff, 0x00, 0xb3, - 0x5f, 0x7b, 0xf7, 0xfc, 0xfd, 0xf7, 0x7c, 0x5e, 0xb5, 0x01, 0xa0, 0x02, - 0x92, 0x01, 0x1a, 0xfe, 0xe6, 0xfe, 0xb7, 0xfe, 0xb8, 0xfe, 0xe6, 0xfd, - 0xcf, 0x01, 0x96, 0x22, 0x94, 0xbf, 0x01, 0x88, 0x01, 0x87, 0x01, 0x80, - 0xfe, 0x80, 0xfe, 0x79, 0xfe, 0x7c, 0xc2, 0x95, 0x22, 0xfe, 0x6a, 0x00, - 0x00, 0x02, 0x00, 0x89, 0xfe, 0x56, 0x04, 0x48, 0x04, 0x7b, 0x00, 0x0b, - 0x00, 0x1b, 0x00, 0x00, 0x01, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, - 0x36, 0x35, 0x34, 0x26, 0x03, 0x11, 0x23, 0x11, 0x26, 0x27, 0x26, 0x11, - 0x10, 0x12, 0x20, 0x12, 0x11, 0x10, 0x07, 0x06, 0x02, 0x68, 0x8c, 0x90, - 0x90, 0x8c, 0x8d, 0x90, 0x90, 0x31, 0xb8, 0xa8, 0x60, 0x7b, 0xf6, 0x01, - 0xd2, 0xf7, 0x7b, 0x5f, 0x03, 0xdf, 0xda, 0xd6, 0xd5, 0xdb, 0xdb, 0xd5, - 0xd6, 0xda, 0xfc, 0x0a, 0xfe, 0x6d, 0x01, 0x93, 0x1a, 0x77, 0x96, 0x01, - 0x1f, 0x01, 0x1e, 0x01, 0x2e, 0xfe, 0xd2, 0xfe, 0xe2, 0xfe, 0xe1, 0x96, - 0x76, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x8b, 0xfe, 0x52, 0x04, 0x4c, - 0x05, 0xd5, 0x00, 0x23, 0x00, 0x00, 0x01, 0x22, 0x07, 0x06, 0x11, 0x10, - 0x12, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x34, 0x35, - 0x16, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, 0x27, 0x26, 0x11, - 0x10, 0x37, 0x36, 0x29, 0x01, 0x15, 0x02, 0xe7, 0xda, 0x4d, 0x62, 0xb0, - 0x81, 0x7a, 0x59, 0x54, 0x4a, 0x50, 0xa3, 0x45, 0x2a, 0x20, 0x20, 0x20, - 0x39, 0xea, 0x9f, 0x7b, 0x9f, 0x8b, 0x01, 0x32, 0x01, 0x65, 0x05, 0x2b, - 0x77, 0x98, 0xfe, 0xcd, 0xfe, 0xce, 0xfe, 0xd0, 0x54, 0x4f, 0x78, 0x73, - 0x50, 0x57, 0x4b, 0x4c, 0x05, 0x2c, 0x23, 0x25, 0x35, 0x2c, 0x2a, 0xcb, - 0x9e, 0x01, 0x9d, 0x01, 0x6e, 0xcd, 0xb1, 0xaa, 0x00, 0x01, 0x00, 0x9b, - 0xfe, 0x52, 0x04, 0x29, 0x04, 0x60, 0x00, 0x23, 0x00, 0x00, 0x01, 0x21, - 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, - 0x14, 0x07, 0x06, 0x23, 0x34, 0x35, 0x16, 0x37, 0x36, 0x35, 0x34, 0x27, - 0x26, 0x23, 0x22, 0x00, 0x11, 0x10, 0x37, 0x36, 0x29, 0x01, 0x04, 0x29, - 0xfe, 0x9b, 0xc1, 0x49, 0x5d, 0x5d, 0x5f, 0x62, 0x85, 0x4e, 0x54, 0x4a, - 0x50, 0xa3, 0x45, 0x2a, 0x20, 0x20, 0x20, 0x39, 0xbb, 0xfe, 0xdb, 0x93, - 0x8a, 0x01, 0x0c, 0x01, 0x65, 0x03, 0xc4, 0x55, 0x6c, 0xd4, 0xd1, 0x6e, - 0x6f, 0x02, 0x02, 0x4a, 0x4f, 0x78, 0x73, 0x50, 0x57, 0x4b, 0x4c, 0x05, - 0x2c, 0x23, 0x25, 0x35, 0x2c, 0x2a, 0x01, 0x38, 0x01, 0x14, 0x01, 0x28, - 0x88, 0x81, 0x00, 0x00, 0xff, 0xff, 0x00, 0xe9, 0x00, 0x00, 0x04, 0x58, - 0x05, 0xd5, 0x12, 0x06, 0x00, 0x29, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0xfe, 0x56, 0x04, 0x06, 0x06, 0x14, 0x00, 0x23, 0x00, 0x00, 0x21, 0x11, - 0x34, 0x37, 0x36, 0x33, 0x32, 0x16, 0x17, 0x15, 0x2e, 0x01, 0x23, 0x22, - 0x07, 0x06, 0x15, 0x11, 0x21, 0x15, 0x21, 0x11, 0x14, 0x07, 0x06, 0x23, - 0x22, 0x26, 0x27, 0x35, 0x1e, 0x01, 0x33, 0x32, 0x37, 0x36, 0x01, 0xae, - 0x88, 0x60, 0xa9, 0x31, 0x63, 0x33, 0x24, 0x52, 0x2c, 0x78, 0x3a, 0x4b, - 0x01, 0x41, 0xfe, 0xbf, 0x8b, 0x62, 0xad, 0x39, 0x66, 0x2e, 0x31, 0x64, - 0x30, 0x57, 0x40, 0x52, 0x04, 0x82, 0xa0, 0x8e, 0x64, 0x12, 0x12, 0xa4, - 0x1c, 0x1d, 0x3e, 0x51, 0x6f, 0xfe, 0xc9, 0x8f, 0xfd, 0x3f, 0x92, 0xa5, - 0x73, 0x15, 0x16, 0xa4, 0x1f, 0x21, 0x4b, 0x5f, 0x00, 0x01, 0x00, 0x60, - 0xff, 0xfc, 0x04, 0x81, 0x05, 0xd5, 0x00, 0x17, 0x00, 0x00, 0x01, 0x03, - 0x01, 0x03, 0x06, 0x17, 0x16, 0x37, 0x15, 0x22, 0x27, 0x26, 0x37, 0x13, - 0x01, 0x13, 0x36, 0x27, 0x26, 0x07, 0x35, 0x32, 0x17, 0x16, 0x01, 0xe3, - 0x6e, 0x03, 0x0c, 0xea, 0x27, 0x1b, 0x42, 0x83, 0xe6, 0x51, 0x5f, 0x13, - 0x9a, 0xfd, 0x06, 0xac, 0x27, 0x1b, 0x42, 0x83, 0xe6, 0x51, 0x5f, 0x04, - 0x87, 0xfe, 0x5b, 0x01, 0x7e, 0xfd, 0x2c, 0x60, 0x2a, 0x6c, 0x23, 0xbd, - 0x46, 0x52, 0xb6, 0x01, 0xda, 0xfe, 0x91, 0x02, 0x90, 0x60, 0x2a, 0x6c, - 0x23, 0xbd, 0x46, 0x52, 0x00, 0x01, 0x00, 0x84, 0x00, 0x00, 0x04, 0x4d, - 0x06, 0x13, 0x00, 0x07, 0x00, 0x00, 0x09, 0x01, 0x23, 0x13, 0x21, 0x01, - 0x33, 0x03, 0x04, 0x4d, 0xfe, 0xe7, 0xb8, 0xe2, 0xfd, 0x26, 0x01, 0x19, - 0xb8, 0xe2, 0x03, 0x70, 0xfc, 0x90, 0x02, 0xc6, 0x03, 0x4d, 0xfd, 0x5d, - 0x00, 0x01, 0x00, 0x21, 0xfe, 0x56, 0x04, 0x9a, 0x05, 0xf0, 0x00, 0x21, - 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x06, 0x07, 0x35, 0x36, 0x05, 0x04, - 0x13, 0x12, 0x11, 0x10, 0x03, 0x23, 0x12, 0x11, 0x10, 0x27, 0x30, 0x07, - 0x06, 0x15, 0x11, 0x23, 0x30, 0x11, 0x10, 0x3f, 0x01, 0x26, 0x27, 0x26, - 0x01, 0x81, 0xaa, 0x62, 0x54, 0x9b, 0x01, 0x05, 0x01, 0x42, 0xd7, 0xc0, - 0xe0, 0xe1, 0xee, 0x3c, 0x66, 0x5a, 0xcb, 0xd0, 0x70, 0x8c, 0x9d, 0x4b, - 0x05, 0x4b, 0xfd, 0x8c, 0x02, 0x49, 0x0a, 0x4d, 0xc6, 0x66, 0x05, 0x07, - 0xfe, 0xd5, 0xfe, 0xf1, 0xfd, 0xbd, 0xfe, 0x37, 0xfe, 0xb3, 0x01, 0x4c, - 0x01, 0xca, 0x01, 0xf3, 0x5b, 0x4f, 0x46, 0xeb, 0xfd, 0xc6, 0x02, 0x35, - 0x01, 0x02, 0xb1, 0x60, 0xb6, 0x34, 0x19, 0x00, 0x00, 0x01, 0x00, 0x59, - 0xfe, 0x90, 0x04, 0x78, 0x04, 0x78, 0x00, 0x16, 0x00, 0x00, 0x01, 0x03, - 0x23, 0x01, 0x26, 0x27, 0x01, 0x23, 0x01, 0x26, 0x27, 0x26, 0x23, 0x35, - 0x20, 0x17, 0x16, 0x13, 0x12, 0x11, 0x23, 0x10, 0x27, 0x03, 0x50, 0xef, - 0xb9, 0x01, 0x64, 0x0e, 0x32, 0xfe, 0x46, 0xb9, 0x02, 0x1f, 0x62, 0x2e, - 0xbc, 0xd3, 0x01, 0x2d, 0xf2, 0xe0, 0xac, 0x74, 0xa8, 0x60, 0x01, 0x34, - 0xfe, 0xcc, 0x01, 0xc0, 0x23, 0x4d, 0xfd, 0xd0, 0x02, 0xb0, 0x7f, 0x21, - 0x84, 0xa4, 0xd8, 0xc8, 0xfe, 0x50, 0xfe, 0xdf, 0xfe, 0x89, 0x01, 0x5e, - 0xf6, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x34, 0xff, 0xf2, 0x04, 0x91, - 0x04, 0x67, 0x00, 0x33, 0x00, 0x00, 0x01, 0x02, 0x07, 0x06, 0x23, 0x22, - 0x35, 0x34, 0x01, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x35, - 0x36, 0x33, 0x32, 0x17, 0x04, 0x11, 0x14, 0x07, 0x37, 0x12, 0x37, 0x36, - 0x33, 0x32, 0x15, 0x14, 0x01, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, - 0x37, 0x15, 0x06, 0x23, 0x22, 0x27, 0x24, 0x11, 0x34, 0x37, 0x01, 0xec, - 0x60, 0xc8, 0x37, 0x22, 0x37, 0x01, 0x24, 0x3e, 0x0e, 0x1a, 0x8e, 0x39, - 0x5b, 0x40, 0x5b, 0x1a, 0x1b, 0x01, 0x1d, 0x1d, 0xbd, 0x60, 0xc8, 0x37, - 0x22, 0x37, 0xfe, 0xdc, 0x3e, 0x0e, 0x1a, 0x8e, 0x39, 0x5b, 0x40, 0x5b, - 0x1a, 0x1b, 0xfe, 0xe3, 0x1d, 0x01, 0x99, 0xfe, 0xf7, 0x7c, 0x22, 0x4f, - 0x9a, 0x01, 0x09, 0x8a, 0x7a, 0x3a, 0x36, 0x68, 0x6c, 0xe0, 0x30, 0x04, - 0x25, 0xfe, 0xc1, 0x5b, 0x4d, 0x6c, 0x01, 0x09, 0x7c, 0x22, 0x4f, 0x9a, - 0xfe, 0xf7, 0x8a, 0x7a, 0x3a, 0x36, 0x68, 0x6c, 0xe0, 0x30, 0x04, 0x25, - 0x01, 0x3f, 0x5b, 0x4d, 0x00, 0x02, 0x00, 0xbe, 0xfe, 0x56, 0x04, 0x54, - 0x04, 0x7b, 0x00, 0x15, 0x00, 0x20, 0x00, 0x00, 0x13, 0x10, 0x37, 0x36, - 0x33, 0x36, 0x17, 0x16, 0x11, 0x10, 0x02, 0x23, 0x22, 0x26, 0x27, 0x12, - 0x29, 0x01, 0x15, 0x21, 0x20, 0x11, 0x24, 0x10, 0x26, 0x23, 0x22, 0x06, - 0x15, 0x14, 0x16, 0x33, 0x32, 0xbe, 0x6e, 0x81, 0xd7, 0xe8, 0x74, 0x74, - 0xe8, 0xca, 0x66, 0x99, 0x2c, 0x05, 0x01, 0x1c, 0x01, 0xa8, 0xfe, 0x68, - 0xfe, 0x16, 0x02, 0xd5, 0x87, 0x85, 0x86, 0x8a, 0x8a, 0x86, 0x85, 0x02, - 0x1c, 0x01, 0x3c, 0x86, 0x9d, 0x01, 0x9e, 0x9d, 0xfe, 0xea, 0xfe, 0xef, - 0xfe, 0xc9, 0x57, 0x53, 0xfe, 0x73, 0xaa, 0x02, 0xda, 0x29, 0x01, 0xac, - 0xda, 0xdb, 0xd5, 0xd4, 0xdc, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, - 0xff, 0xe3, 0x04, 0x25, 0x04, 0x7b, 0x12, 0x06, 0x00, 0x46, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xba, 0xfe, 0x56, 0x03, 0x10, 0x06, 0x14, 0x12, 0x06, - 0x00, 0x4d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x75, 0xff, 0xe3, 0x04, 0x5c, - 0x05, 0xf0, 0x00, 0x08, 0x00, 0x11, 0x00, 0x1c, 0x00, 0x00, 0x01, 0x26, - 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x05, 0x21, 0x12, 0x17, 0x16, - 0x33, 0x32, 0x37, 0x36, 0x13, 0x10, 0x02, 0x20, 0x02, 0x11, 0x10, 0x12, - 0x33, 0x32, 0x12, 0x03, 0x86, 0x0b, 0x35, 0x44, 0x9a, 0x99, 0x43, 0x36, - 0x0b, 0x02, 0x3e, 0xfd, 0xbf, 0x02, 0x42, 0x43, 0x99, 0x9a, 0x44, 0x40, - 0xd6, 0xf7, 0xfe, 0x06, 0xf6, 0xf7, 0xfc, 0xfd, 0xf7, 0x03, 0x71, 0xdf, - 0x6f, 0x8d, 0x8d, 0x70, 0xde, 0xaa, 0xfe, 0xd5, 0x88, 0x8d, 0x8d, 0x86, - 0x01, 0x4f, 0xfe, 0x7a, 0xfe, 0x80, 0x01, 0x7e, 0x01, 0x88, 0x01, 0x87, - 0x01, 0x80, 0xfe, 0x80, 0x00, 0x01, 0x00, 0xa2, 0xff, 0xe3, 0x04, 0x09, - 0x04, 0x7b, 0x00, 0x21, 0x00, 0x00, 0x01, 0x26, 0x27, 0x26, 0x23, 0x22, - 0x07, 0x06, 0x07, 0x21, 0x15, 0x21, 0x16, 0x17, 0x16, 0x33, 0x32, 0x3f, - 0x01, 0x15, 0x07, 0x06, 0x23, 0x20, 0x27, 0x26, 0x10, 0x37, 0x36, 0x21, - 0x32, 0x17, 0x16, 0x17, 0x04, 0x09, 0x25, 0x25, 0x63, 0x6a, 0xb7, 0x66, - 0x5f, 0x12, 0x02, 0xa5, 0xfd, 0x5b, 0x12, 0x5f, 0x66, 0xb7, 0x80, 0x4d, - 0x4a, 0x4f, 0x68, 0x6b, 0xfe, 0xf4, 0x9c, 0x9d, 0x9d, 0x9c, 0x01, 0x0c, - 0x65, 0x6e, 0x28, 0x27, 0x03, 0xae, 0x0d, 0x0a, 0x1a, 0x63, 0x5c, 0xa9, - 0x90, 0xa9, 0x5c, 0x63, 0x1a, 0x19, 0xa7, 0x12, 0x16, 0x9c, 0x9c, 0x02, - 0x28, 0x9c, 0x9c, 0x16, 0x08, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0xa2, - 0xff, 0xe3, 0x04, 0x09, 0x04, 0x7b, 0x00, 0x22, 0x00, 0x00, 0x13, 0x30, - 0x35, 0x36, 0x37, 0x36, 0x33, 0x20, 0x17, 0x16, 0x10, 0x07, 0x06, 0x21, - 0x22, 0x2f, 0x01, 0x35, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x21, - 0x35, 0x21, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0xa2, 0x27, 0x28, - 0x6e, 0x65, 0x01, 0x0c, 0x9c, 0x9d, 0x9d, 0x9c, 0xfe, 0xf4, 0x6b, 0x68, - 0x4f, 0x4a, 0x4d, 0x80, 0xb7, 0x66, 0x5f, 0x12, 0xfd, 0x5b, 0x02, 0xa5, - 0x12, 0x5f, 0x66, 0xb7, 0x6a, 0x63, 0x25, 0x03, 0xae, 0xa3, 0x0c, 0x08, - 0x16, 0x9c, 0x9c, 0xfd, 0xd8, 0x9c, 0x9c, 0x16, 0x12, 0xa7, 0x19, 0x1a, - 0x63, 0x5c, 0xa9, 0x90, 0xa9, 0x5c, 0x63, 0x1a, 0x0a, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc9, 0x00, 0x00, 0x04, 0x8d, 0x05, 0xd5, 0x12, 0x06, - 0x00, 0xa0, 0x00, 0x00, 0xff, 0xff, 0x00, 0xbe, 0xfe, 0x56, 0x04, 0x54, - 0x06, 0x1f, 0x12, 0x06, 0x00, 0xc0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8b, - 0xff, 0xe3, 0x04, 0x31, 0x05, 0xf0, 0x12, 0x06, 0x00, 0x26, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x56, 0x00, 0x00, 0x04, 0x79, 0x05, 0xd5, 0x00, 0x0c, - 0x00, 0x00, 0x13, 0x21, 0x09, 0x01, 0x21, 0x11, 0x23, 0x11, 0x01, 0x23, - 0x01, 0x11, 0x23, 0x56, 0x01, 0x0e, 0x01, 0x02, 0x01, 0x04, 0x01, 0x0f, - 0xbb, 0xfe, 0xf6, 0x99, 0xfe, 0xf5, 0xba, 0x05, 0xd5, 0xfe, 0x7b, 0x01, - 0x85, 0xfa, 0x2b, 0x05, 0x27, 0xfe, 0x60, 0x01, 0xa0, 0xfa, 0xd9, 0x00, - 0x00, 0x01, 0x00, 0x7f, 0xfe, 0x56, 0x04, 0x4f, 0x04, 0x60, 0x00, 0x0c, - 0x00, 0x00, 0x13, 0x21, 0x1b, 0x01, 0x21, 0x11, 0x23, 0x11, 0x03, 0x23, - 0x03, 0x11, 0x23, 0x7f, 0x01, 0x1b, 0xcc, 0xce, 0x01, 0x1b, 0xb9, 0xe2, - 0x99, 0xe3, 0xb9, 0x04, 0x60, 0xfe, 0x7b, 0x01, 0x85, 0xfb, 0xa0, 0x03, - 0xb2, 0xfe, 0x60, 0x01, 0xa0, 0xfa, 0xa4, 0x00, 0x00, 0x02, 0x00, 0x55, - 0xfe, 0x56, 0x04, 0x54, 0x04, 0x7b, 0x00, 0x18, 0x00, 0x23, 0x00, 0x00, - 0x01, 0x15, 0x23, 0x35, 0x23, 0x35, 0x33, 0x11, 0x10, 0x37, 0x36, 0x33, - 0x36, 0x17, 0x16, 0x11, 0x10, 0x02, 0x23, 0x22, 0x26, 0x27, 0x11, 0x21, - 0x15, 0x12, 0x10, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, - 0x01, 0x77, 0xb9, 0x69, 0x69, 0x6e, 0x83, 0xd5, 0xe8, 0x74, 0x74, 0xe8, - 0xca, 0x66, 0x99, 0x2c, 0x01, 0xe1, 0x3b, 0x87, 0x85, 0x86, 0x8a, 0x8a, - 0x86, 0x85, 0xfe, 0xc6, 0x70, 0x70, 0xaa, 0x02, 0xac, 0x01, 0x3e, 0x84, - 0x9d, 0x01, 0x9e, 0x9d, 0xfe, 0xea, 0xfe, 0xef, 0xfe, 0xc9, 0x57, 0x53, - 0xfe, 0xe3, 0xaa, 0x02, 0x93, 0x01, 0xac, 0xda, 0xdb, 0xd5, 0xd4, 0xdc, - 0x00, 0x01, 0x00, 0x8b, 0xff, 0xe3, 0x04, 0x31, 0x05, 0xf0, 0x00, 0x19, - 0x00, 0x00, 0x37, 0x35, 0x1e, 0x01, 0x33, 0x32, 0x12, 0x11, 0x10, 0x02, - 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x20, 0x00, 0x11, 0x10, - 0x00, 0x21, 0x22, 0x26, 0x8b, 0x49, 0xa9, 0x58, 0xc5, 0xc4, 0xc4, 0xc5, - 0x56, 0xaa, 0x4a, 0x4d, 0xa2, 0x5b, 0x01, 0x1d, 0x01, 0x3f, 0xfe, 0xc3, - 0xfe, 0xe1, 0x5b, 0xa2, 0x35, 0xcf, 0x3d, 0x40, 0x01, 0x30, 0x01, 0x32, - 0x01, 0x33, 0x01, 0x30, 0x40, 0x3d, 0xcf, 0x29, 0x29, 0xfe, 0x67, 0xfe, - 0x92, 0xfe, 0x90, 0xfe, 0x6a, 0x29, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8b, - 0xff, 0xe3, 0x04, 0x31, 0x05, 0xf0, 0x12, 0x26, 0x03, 0x32, 0x00, 0x00, - 0x10, 0x07, 0x00, 0x79, 0x00, 0x8b, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8b, - 0xff, 0xe3, 0x04, 0x31, 0x05, 0xf0, 0x10, 0x27, 0x00, 0x79, 0xff, 0x63, - 0x00, 0x00, 0x10, 0x06, 0x03, 0x36, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc5, - 0x00, 0x00, 0x04, 0x4e, 0x07, 0x6b, 0x10, 0x27, 0x0c, 0xc1, 0x00, 0x00, - 0x01, 0x75, 0x10, 0x06, 0x03, 0x4e, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc5, - 0x00, 0x00, 0x04, 0x4e, 0x07, 0x4e, 0x10, 0x27, 0x0c, 0xbe, 0x00, 0x38, - 0x01, 0x75, 0x10, 0x06, 0x03, 0x4e, 0x00, 0x00, 0x00, 0x01, 0xff, 0xbe, - 0xfe, 0x2a, 0x04, 0x6f, 0x05, 0xd7, 0x00, 0x2f, 0x00, 0x00, 0x01, 0x17, - 0x16, 0x33, 0x32, 0x36, 0x35, 0x11, 0x34, 0x26, 0x23, 0x22, 0x07, 0x06, - 0x07, 0x06, 0x15, 0x11, 0x23, 0x11, 0x23, 0x35, 0x21, 0x15, 0x21, 0x11, - 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, - 0x16, 0x15, 0x11, 0x10, 0x07, 0x06, 0x23, 0x22, 0x27, 0x34, 0x02, 0x3d, - 0x4e, 0x0d, 0x0c, 0x8f, 0x71, 0x6a, 0x71, 0x6a, 0x57, 0x2e, 0x16, 0x45, - 0xcb, 0xf6, 0x03, 0x7e, 0xfe, 0x43, 0x25, 0x30, 0x22, 0x0e, 0x40, 0x95, - 0x1a, 0x16, 0xa0, 0x58, 0x0e, 0x0b, 0x55, 0x6b, 0x69, 0xf7, 0x53, 0x11, - 0xfe, 0xe1, 0x11, 0x02, 0x95, 0xcb, 0x01, 0xa0, 0x97, 0x8e, 0x2a, 0x15, - 0x1c, 0x5c, 0xab, 0xfe, 0x6f, 0x05, 0x2d, 0xaa, 0xaa, 0xfd, 0xf3, 0x2a, - 0x18, 0x11, 0x09, 0x25, 0x0a, 0x02, 0x54, 0x0d, 0x10, 0x70, 0xe4, 0xfe, - 0x46, 0xfe, 0xe8, 0x77, 0x75, 0x02, 0x02, 0x00, 0xff, 0xff, 0x00, 0xd7, - 0x00, 0x00, 0x04, 0x73, 0x07, 0x6b, 0x10, 0x27, 0x0c, 0xbf, 0x00, 0x48, - 0x01, 0x75, 0x10, 0x06, 0x03, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x8b, - 0xff, 0xe3, 0x04, 0x31, 0x05, 0xf0, 0x00, 0x18, 0x00, 0x4c, 0x40, 0x21, - 0x00, 0x97, 0x16, 0xb1, 0x19, 0x05, 0xb3, 0x06, 0xb2, 0x03, 0x97, 0x08, - 0x11, 0xb3, 0x10, 0xb2, 0x13, 0x97, 0x0e, 0x96, 0x08, 0x99, 0x19, 0x17, - 0x00, 0x16, 0x32, 0x11, 0x06, 0x31, 0x0b, 0x30, 0x19, 0x10, 0xfc, 0xec, - 0x32, 0xfc, 0x32, 0xcc, 0x31, 0x00, 0x10, 0xe4, 0xf4, 0xec, 0xf4, 0xec, - 0x10, 0xee, 0xf6, 0xee, 0x10, 0xfc, 0xee, 0xb1, 0x16, 0x13, 0x49, 0xb1, - 0x03, 0x00, 0x49, 0x50, 0x58, 0xb3, 0x16, 0x00, 0x40, 0x02, 0x17, 0x38, - 0x59, 0x30, 0x01, 0x16, 0x12, 0x33, 0x32, 0x37, 0x15, 0x06, 0x23, 0x20, - 0x00, 0x11, 0x10, 0x00, 0x21, 0x32, 0x17, 0x15, 0x26, 0x23, 0x22, 0x02, - 0x03, 0x21, 0x15, 0x01, 0x5e, 0x04, 0xc0, 0xbd, 0xbc, 0x96, 0x9a, 0xb0, - 0xfe, 0xe1, 0xfe, 0xc3, 0x01, 0x3f, 0x01, 0x1d, 0xb0, 0x9a, 0x98, 0xbe, - 0xbe, 0xa3, 0x17, 0x02, 0x73, 0x02, 0x95, 0xe4, 0xfe, 0xd6, 0x7d, 0xcf, - 0x52, 0x01, 0x96, 0x01, 0x6f, 0x01, 0x6f, 0x01, 0x99, 0x52, 0xcf, 0x7d, - 0xfe, 0xf4, 0xfe, 0xff, 0xaa, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8b, - 0xff, 0xe3, 0x04, 0x4a, 0x05, 0xf0, 0x10, 0x06, 0x00, 0x36, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc9, 0x00, 0x00, 0x04, 0x06, 0x05, 0xd5, 0x10, 0x06, - 0x00, 0x2c, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc9, 0x00, 0x00, 0x04, 0x06, - 0x07, 0x4e, 0x10, 0x26, 0x03, 0x3f, 0x00, 0x00, 0x11, 0x07, 0x0c, 0xbe, - 0x00, 0x00, 0x01, 0x75, 0x00, 0x08, 0xb4, 0x01, 0x12, 0x0f, 0x00, 0x07, - 0x2b, 0x31, 0x00, 0x00, 0xff, 0xff, 0x00, 0x6d, 0xff, 0xe3, 0x03, 0xbc, - 0x05, 0xd5, 0x10, 0x06, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x02, 0xff, 0xed, - 0x00, 0x00, 0x04, 0xc7, 0x05, 0xd5, 0x00, 0x07, 0x00, 0x1d, 0x00, 0x00, - 0x25, 0x33, 0x32, 0x36, 0x10, 0x26, 0x2b, 0x01, 0x19, 0x01, 0x33, 0x32, - 0x04, 0x10, 0x04, 0x2b, 0x01, 0x11, 0x23, 0x15, 0x10, 0x02, 0x06, 0x23, - 0x35, 0x32, 0x36, 0x12, 0x19, 0x01, 0x03, 0x21, 0x15, 0x5a, 0x7d, 0x79, - 0x5e, 0x15, 0x15, 0x90, 0x01, 0x01, 0xfe, 0xfe, 0x8f, 0xcf, 0xac, 0x18, - 0xca, 0xec, 0x8a, 0x76, 0x14, 0xa6, 0x8e, 0x01, 0x0e, 0x95, 0x02, 0xfe, - 0xfd, 0xa8, 0xe2, 0xfe, 0x48, 0xe3, 0x05, 0x2b, 0xfa, 0xfe, 0xc6, 0xfd, - 0xf7, 0xee, 0xa4, 0x8f, 0x01, 0xa1, 0x01, 0x57, 0x01, 0xaa, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x22, 0x00, 0x00, 0x04, 0xc7, 0x05, 0xd5, 0x00, 0x08, - 0x00, 0x1c, 0x00, 0x00, 0x25, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x2b, - 0x01, 0x03, 0x11, 0x21, 0x11, 0x23, 0x11, 0x33, 0x11, 0x21, 0x11, 0x33, - 0x11, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x04, 0x23, 0x03, 0x21, 0x15, - 0x5a, 0x7d, 0x78, 0x5f, 0x15, 0xba, 0xfe, 0x75, 0xba, 0xba, 0x01, 0x8b, - 0xba, 0x15, 0xb3, 0x77, 0x67, 0xfe, 0xfe, 0x8f, 0xa6, 0x8e, 0x82, 0x8c, - 0x95, 0xfd, 0x29, 0x02, 0xc7, 0xfd, 0x39, 0x05, 0xd5, 0xfd, 0x9c, 0x02, - 0x64, 0xfd, 0xa8, 0x71, 0x63, 0xea, 0xdc, 0xe3, 0x00, 0x01, 0xff, 0xbe, - 0x00, 0x00, 0x04, 0x6f, 0x05, 0xd7, 0x00, 0x22, 0x00, 0x00, 0x01, 0x11, - 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, - 0x16, 0x15, 0x11, 0x23, 0x11, 0x34, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, - 0x06, 0x15, 0x11, 0x23, 0x11, 0x23, 0x35, 0x21, 0x15, 0x01, 0x7f, 0x25, - 0x30, 0x22, 0x0e, 0x40, 0x95, 0x1a, 0x16, 0xa0, 0x58, 0x0e, 0x0b, 0x55, - 0xcb, 0x6a, 0x71, 0x6a, 0x57, 0x2e, 0x16, 0x45, 0xcb, 0xf6, 0x03, 0x7e, - 0x05, 0x2d, 0xfd, 0xf3, 0x2a, 0x18, 0x11, 0x09, 0x25, 0x0a, 0x02, 0x54, - 0x0d, 0x10, 0x70, 0xe4, 0xfe, 0x18, 0x01, 0xce, 0x97, 0x8e, 0x2a, 0x15, - 0x1c, 0x5c, 0xab, 0xfe, 0x6f, 0x05, 0x2d, 0xaa, 0xaa, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x89, 0x00, 0x00, 0x04, 0xc9, 0x07, 0x6b, 0x10, 0x27, - 0x0c, 0xbf, 0x00, 0x1b, 0x01, 0x75, 0x10, 0x06, 0x03, 0x53, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x8b, 0x00, 0x00, 0x04, 0x46, 0x07, 0x6b, 0x10, 0x27, - 0x0c, 0xc1, 0x00, 0x00, 0x01, 0x75, 0x10, 0x06, 0x03, 0x51, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x68, 0x00, 0x00, 0x04, 0x81, 0x07, 0x6d, 0x10, 0x26, - 0x0c, 0xc6, 0x00, 0x00, 0x10, 0x06, 0x03, 0x5c, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x89, 0xfe, 0xbe, 0x04, 0x48, 0x05, 0xd5, 0x00, 0x0b, - 0x00, 0x00, 0x33, 0x11, 0x33, 0x11, 0x21, 0x11, 0x33, 0x11, 0x21, 0x11, - 0x23, 0x11, 0x89, 0xcb, 0x02, 0x29, 0xcb, 0xfe, 0x76, 0xab, 0x05, 0xd5, - 0xfa, 0xd5, 0x05, 0x2b, 0xfa, 0x2b, 0xfe, 0xbe, 0x01, 0x42, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, 0x05, 0xd5, 0x10, 0x06, - 0x00, 0x24, 0x00, 0x00, 0x00, 0x02, 0x00, 0xa6, 0x00, 0x00, 0x04, 0x71, - 0x05, 0xd5, 0x00, 0x08, 0x00, 0x17, 0x00, 0x32, 0x40, 0x1c, 0x00, 0x97, - 0x0c, 0x09, 0x97, 0x16, 0x88, 0x01, 0x97, 0x0c, 0x14, 0x14, 0x0c, 0x08, - 0x02, 0x04, 0x00, 0x17, 0x05, 0x32, 0x10, 0x31, 0x0a, 0x00, 0x1e, 0x16, - 0x30, 0x18, 0x10, 0xfc, 0xec, 0x32, 0xfc, 0xec, 0xc4, 0x11, 0x17, 0x39, - 0x31, 0x00, 0x2f, 0xcc, 0xec, 0xf4, 0xec, 0x10, 0xec, 0x30, 0x01, 0x11, - 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x01, 0x21, 0x11, 0x33, 0x04, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x29, 0x01, 0x11, 0x21, 0x01, 0x71, - 0xef, 0xb0, 0x96, 0x9e, 0xa8, 0x01, 0xcc, 0xfd, 0x45, 0xeb, 0x01, 0x7b, - 0x65, 0x35, 0x85, 0x85, 0xfe, 0xf9, 0xfe, 0x46, 0x03, 0x86, 0x02, 0xc9, - 0xfd, 0xdd, 0x7b, 0x8d, 0x92, 0x89, 0x02, 0x66, 0xfe, 0x3e, 0x0f, 0xbf, - 0x64, 0xa1, 0xcb, 0x67, 0x68, 0x05, 0xd5, 0x00, 0xff, 0xff, 0x00, 0xa6, - 0x00, 0x00, 0x04, 0x71, 0x05, 0xd5, 0x10, 0x06, 0x00, 0x25, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xd7, 0x00, 0x00, 0x04, 0x73, 0x05, 0xd5, 0x00, 0x05, - 0x00, 0x18, 0xb6, 0x02, 0x31, 0x04, 0x1e, 0x01, 0x34, 0x06, 0x10, 0xfc, - 0xec, 0xec, 0x31, 0x00, 0xb4, 0x03, 0x97, 0x01, 0x88, 0x05, 0x2f, 0xf4, - 0xec, 0x30, 0x33, 0x11, 0x21, 0x15, 0x21, 0x11, 0xd7, 0x03, 0x9c, 0xfd, - 0x2f, 0x05, 0xd5, 0xaa, 0xfa, 0xd5, 0x00, 0x00, 0x00, 0x02, 0x00, 0x21, - 0xfe, 0xbe, 0x04, 0xb0, 0x05, 0xd5, 0x00, 0x0f, 0x00, 0x1a, 0x00, 0x30, - 0x40, 0x0d, 0x04, 0x1e, 0x01, 0x10, 0x1e, 0x0f, 0x12, 0x1e, 0x0d, 0x05, - 0x1e, 0x08, 0x1b, 0x10, 0xd4, 0xec, 0xdc, 0xec, 0xd4, 0xec, 0xdc, 0xec, - 0x31, 0x00, 0x40, 0x0b, 0x11, 0x97, 0x0e, 0x88, 0x01, 0x1a, 0x08, 0x97, - 0x03, 0x07, 0x05, 0x2f, 0xcc, 0x32, 0xec, 0x32, 0x32, 0xf4, 0xec, 0x30, - 0x25, 0x33, 0x11, 0x23, 0x11, 0x21, 0x11, 0x23, 0x11, 0x33, 0x32, 0x13, - 0x12, 0x19, 0x01, 0x21, 0x07, 0x21, 0x11, 0x14, 0x03, 0x02, 0x06, 0x15, - 0x14, 0x33, 0x21, 0x04, 0x37, 0x79, 0xaa, 0xfc, 0xc5, 0xaa, 0x4d, 0x30, - 0x27, 0x1e, 0x03, 0x54, 0xcb, 0xfe, 0x42, 0x1c, 0x1b, 0x0b, 0x2f, 0x01, - 0xd1, 0xaa, 0xfe, 0x14, 0x01, 0x42, 0xfe, 0xbe, 0x01, 0xec, 0x01, 0x4c, - 0x01, 0x00, 0x01, 0x0d, 0x01, 0xd2, 0xaa, 0xfe, 0xd7, 0xe0, 0xfe, 0xe1, - 0xfe, 0xe1, 0x1c, 0x08, 0x16, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc5, - 0x00, 0x00, 0x04, 0x4e, 0x05, 0xd5, 0x10, 0x06, 0x00, 0x28, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x04, 0xc2, 0x05, 0xd5, 0x00, 0x13, - 0x00, 0x78, 0x40, 0x0b, 0x08, 0x05, 0x04, 0x03, 0x06, 0x09, 0x01, 0x1e, - 0x0c, 0x00, 0x14, 0x10, 0xdc, 0x3c, 0xfc, 0x3c, 0xc0, 0x17, 0x39, 0x31, - 0x00, 0x40, 0x0c, 0x42, 0x08, 0x05, 0x02, 0x03, 0x11, 0x03, 0x00, 0xb4, - 0x0f, 0x0a, 0x06, 0x2f, 0x3c, 0x3c, 0xec, 0x32, 0x32, 0x17, 0x39, 0x30, - 0x4b, 0x53, 0x58, 0x40, 0x09, 0x08, 0x25, 0x09, 0x08, 0x05, 0x07, 0x25, - 0x06, 0x05, 0x07, 0x05, 0xed, 0x10, 0x08, 0xed, 0x59, 0x01, 0x40, 0x13, - 0x0d, 0x00, 0x08, 0x0e, 0x00, 0x07, 0x0f, 0x00, 0x06, 0x10, 0x00, 0x05, - 0x11, 0x00, 0x04, 0x12, 0x00, 0x03, 0x01, 0x10, 0x49, 0x3a, 0x49, 0x3a, - 0x49, 0x3a, 0x49, 0x3a, 0x49, 0x3a, 0x49, 0x3a, 0x00, 0xb7, 0x0c, 0x09, - 0x0d, 0x08, 0x10, 0x05, 0x13, 0x02, 0x10, 0x3c, 0x10, 0x3c, 0x10, 0x3c, - 0x10, 0x3c, 0x01, 0x33, 0x11, 0x01, 0x33, 0x09, 0x01, 0x23, 0x03, 0x07, - 0x11, 0x23, 0x11, 0x27, 0x03, 0x23, 0x09, 0x01, 0x33, 0x01, 0x02, 0x0b, - 0xbb, 0x01, 0x1c, 0xcf, 0xfe, 0xe1, 0x01, 0x30, 0xc5, 0xde, 0x59, 0xbb, - 0x59, 0xde, 0xc5, 0x01, 0x30, 0xfe, 0xe1, 0xcf, 0x01, 0x1c, 0x05, 0xd5, - 0xfd, 0xad, 0x02, 0x53, 0xfd, 0xa6, 0xfc, 0x85, 0x02, 0x8a, 0xba, 0xfe, - 0x30, 0x01, 0xd0, 0xba, 0xfd, 0x76, 0x03, 0x7b, 0x02, 0x5a, 0xfd, 0xad, - 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x37, 0x05, 0xf0, 0x10, 0x06, - 0x00, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x8b, 0x00, 0x00, 0x04, 0x46, - 0x05, 0xd5, 0x00, 0x09, 0x00, 0x3c, 0x40, 0x1c, 0x08, 0x04, 0x03, 0x04, - 0x03, 0x09, 0x08, 0x09, 0x42, 0x08, 0x02, 0x03, 0x05, 0xb4, 0x07, 0x00, - 0x09, 0x04, 0x03, 0x08, 0x11, 0x06, 0x31, 0x03, 0x11, 0x01, 0x30, 0x0a, - 0x10, 0xfc, 0xec, 0xfc, 0xec, 0x11, 0x39, 0x39, 0x31, 0x00, 0x2f, 0x3c, - 0xec, 0x32, 0x39, 0x39, 0x30, 0x4b, 0x53, 0x58, 0x07, 0x10, 0x04, 0xc9, - 0x07, 0x10, 0x04, 0xc9, 0x59, 0x22, 0x33, 0x11, 0x33, 0x11, 0x01, 0x21, - 0x11, 0x23, 0x11, 0x01, 0x8b, 0xc3, 0x01, 0xf8, 0x01, 0x00, 0xc3, 0xfe, - 0x08, 0x05, 0xd5, 0xfb, 0x33, 0x04, 0xcd, 0xfa, 0x2b, 0x04, 0xcd, 0xfb, - 0x33, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8b, 0x00, 0x00, 0x04, 0x46, - 0x07, 0x6d, 0x10, 0x26, 0x0c, 0xc6, 0x00, 0x00, 0x10, 0x06, 0x03, 0x51, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0x00, 0x00, 0x04, 0xc9, - 0x05, 0xd5, 0x10, 0x06, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, - 0x00, 0x00, 0x04, 0x46, 0x05, 0xd5, 0x00, 0x0f, 0x00, 0x24, 0x40, 0x08, - 0x0f, 0x1e, 0x0c, 0x01, 0x1e, 0x0a, 0x06, 0x10, 0x10, 0xd4, 0xdc, 0xec, - 0xd4, 0xec, 0x31, 0x00, 0x40, 0x09, 0x06, 0x97, 0x05, 0x00, 0x97, 0x0b, - 0x88, 0x0e, 0x05, 0x2f, 0x3c, 0xf4, 0xec, 0x10, 0xec, 0x30, 0x01, 0x15, - 0x10, 0x02, 0x06, 0x23, 0x35, 0x32, 0x36, 0x12, 0x19, 0x01, 0x21, 0x11, - 0x23, 0x11, 0x01, 0xe3, 0x17, 0xcb, 0xfd, 0x8a, 0x76, 0x14, 0x03, 0x2e, - 0xcb, 0x05, 0x2b, 0xfa, 0xfe, 0xbb, 0xfe, 0x02, 0xee, 0xa4, 0x8f, 0x01, - 0xa1, 0x01, 0x57, 0x01, 0xaa, 0xfa, 0x2b, 0x05, 0x2b, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x56, 0x00, 0x00, 0x04, 0x79, 0x05, 0xd5, 0x10, 0x06, - 0x00, 0x30, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0x00, 0x00, 0x04, 0x48, - 0x05, 0xd5, 0x10, 0x06, 0x00, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x00, 0x75, - 0xff, 0xe3, 0x04, 0x5c, 0x05, 0xf0, 0x10, 0x06, 0x00, 0x32, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x89, 0x00, 0x00, 0x04, 0x48, 0x05, 0xd5, 0x00, 0x07, - 0x00, 0x1e, 0x40, 0x09, 0x04, 0x1e, 0x01, 0x31, 0x05, 0x1e, 0x00, 0x30, - 0x08, 0x10, 0xfc, 0xec, 0xfc, 0xec, 0x31, 0x00, 0xb5, 0x04, 0x97, 0x00, - 0x88, 0x06, 0x02, 0x2f, 0x3c, 0xf4, 0xec, 0x30, 0x13, 0x21, 0x11, 0x23, - 0x11, 0x21, 0x11, 0x23, 0x89, 0x03, 0xbf, 0xcb, 0xfd, 0xd7, 0xcb, 0x05, - 0xd5, 0xfa, 0x2b, 0x05, 0x2b, 0xfa, 0xd5, 0x00, 0xff, 0xff, 0x00, 0xc5, - 0x00, 0x00, 0x04, 0x75, 0x05, 0xd5, 0x10, 0x06, 0x00, 0x33, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x8b, 0xff, 0xe3, 0x04, 0x31, 0x05, 0xf0, 0x10, 0x06, - 0x00, 0x26, 0x00, 0x00, 0xff, 0xff, 0x00, 0x2f, 0x00, 0x00, 0x04, 0xa2, - 0x05, 0xd5, 0x10, 0x06, 0x00, 0x37, 0x00, 0x00, 0x00, 0x01, 0x00, 0x68, - 0x00, 0x00, 0x04, 0x81, 0x05, 0xd5, 0x00, 0x14, 0x00, 0x3f, 0x40, 0x0d, - 0x42, 0x08, 0x97, 0x07, 0x99, 0x13, 0x10, 0x88, 0x15, 0x14, 0x08, 0x10, - 0x15, 0x10, 0xd4, 0xc4, 0xc4, 0x31, 0x00, 0x10, 0xe4, 0x32, 0xf4, 0xec, - 0x30, 0x4b, 0x53, 0x58, 0x40, 0x12, 0x12, 0x25, 0x00, 0x10, 0x0f, 0x13, - 0x25, 0x14, 0x14, 0x00, 0x12, 0x25, 0x0f, 0x11, 0x25, 0x10, 0x10, 0x0f, - 0x05, 0x07, 0x10, 0xec, 0x10, 0xec, 0x07, 0x10, 0xec, 0x08, 0x10, 0xec, - 0x59, 0x01, 0x06, 0x07, 0x06, 0x07, 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, - 0x37, 0x36, 0x37, 0x36, 0x37, 0x01, 0x33, 0x09, 0x01, 0x33, 0x02, 0xe5, - 0x3b, 0x45, 0x2c, 0x4c, 0x45, 0x5c, 0x94, 0x6d, 0x51, 0x2e, 0x2d, 0x22, - 0x0e, 0x0f, 0xfe, 0x58, 0xd9, 0x01, 0x37, 0x01, 0x34, 0xd5, 0x01, 0xa9, - 0x9e, 0x6f, 0x4a, 0x2b, 0x27, 0xac, 0x2f, 0x2e, 0x4d, 0x20, 0x2a, 0x04, - 0x35, 0xfc, 0xc2, 0x03, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x42, - 0x00, 0x00, 0x04, 0x8f, 0x05, 0xd5, 0x00, 0x06, 0x00, 0x18, 0x00, 0x1f, - 0x00, 0x67, 0x40, 0x0f, 0x1c, 0x32, 0x0c, 0x0f, 0x1f, 0x09, 0x1e, 0x18, - 0x04, 0x32, 0x15, 0x12, 0x01, 0x18, 0x20, 0x10, 0xd4, 0x3c, 0x3c, 0xd4, - 0xec, 0x10, 0xfc, 0x3c, 0x3c, 0xd4, 0xec, 0x31, 0x00, 0x40, 0x0e, 0x1f, - 0x01, 0x97, 0x09, 0x18, 0x07, 0x88, 0x11, 0x19, 0x00, 0x97, 0x0f, 0x12, - 0x11, 0x2f, 0xdc, 0x3c, 0xec, 0x32, 0x10, 0xf4, 0xdc, 0x3c, 0xec, 0x32, - 0x30, 0x01, 0xb0, 0x0d, 0x4b, 0x54, 0xb0, 0x10, 0x4b, 0x54, 0x5b, 0xb0, - 0x15, 0x4b, 0x54, 0x5b, 0xb0, 0x19, 0x4b, 0x54, 0x5b, 0x58, 0xbf, 0x00, - 0x21, 0x00, 0x20, 0xff, 0xc0, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x40, 0x38, 0x12, 0x36, 0x17, 0x38, 0x59, 0x01, 0x11, 0x0e, - 0x01, 0x15, 0x14, 0x16, 0x13, 0x33, 0x15, 0x04, 0x12, 0x11, 0x10, 0x02, - 0x05, 0x15, 0x23, 0x35, 0x26, 0x02, 0x11, 0x10, 0x12, 0x25, 0x13, 0x3e, - 0x01, 0x35, 0x34, 0x26, 0x27, 0x02, 0x03, 0xa5, 0x49, 0x49, 0xa5, 0xcb, - 0x01, 0x0b, 0xb6, 0xb6, 0xfe, 0xf5, 0xcb, 0xfa, 0xc7, 0xb8, 0x01, 0x09, - 0xcb, 0xa5, 0x49, 0x49, 0xa5, 0x01, 0x3c, 0x03, 0x7b, 0x1a, 0xdc, 0xc7, - 0xc8, 0xdc, 0x04, 0x7f, 0x7a, 0x0a, 0xfe, 0xaa, 0xfe, 0xff, 0xfe, 0xfc, - 0xfe, 0xac, 0x0a, 0x98, 0x98, 0x0a, 0x01, 0x57, 0x01, 0x01, 0x01, 0x04, - 0x01, 0x53, 0x0a, 0xfb, 0xe1, 0x1a, 0xdc, 0xc8, 0xc7, 0xdc, 0x1a, 0x00, - 0xff, 0xff, 0x00, 0x12, 0x00, 0x00, 0x04, 0xbe, 0x05, 0xd5, 0x10, 0x06, - 0x00, 0x3b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x50, 0xfe, 0xbe, 0x04, 0x95, - 0x05, 0xd5, 0x00, 0x0b, 0x00, 0x24, 0x40, 0x12, 0x06, 0x02, 0x88, 0x0a, - 0x08, 0x04, 0x97, 0x0b, 0x0b, 0x1e, 0x08, 0x04, 0x1e, 0x06, 0x03, 0x1e, - 0x00, 0x0c, 0x10, 0xd4, 0xec, 0xd4, 0xec, 0xdc, 0xec, 0x31, 0x00, 0x2f, - 0xec, 0x32, 0xcc, 0xec, 0x32, 0x30, 0x33, 0x11, 0x33, 0x11, 0x21, 0x11, - 0x33, 0x11, 0x33, 0x11, 0x23, 0x11, 0x50, 0xcb, 0x02, 0x29, 0xcb, 0x86, - 0xaa, 0x05, 0xd5, 0xfa, 0xd5, 0x05, 0x2b, 0xfa, 0xd5, 0xfe, 0x14, 0x01, - 0x42, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x89, 0x00, 0x00, 0x04, 0x44, - 0x05, 0xd5, 0x00, 0x13, 0x00, 0x20, 0x40, 0x10, 0x11, 0x97, 0x06, 0x01, - 0x0a, 0x88, 0x0d, 0x0e, 0x09, 0x1e, 0x0b, 0x03, 0x1e, 0x00, 0x30, 0x14, - 0x10, 0xfc, 0xec, 0xd4, 0xec, 0x32, 0x31, 0x00, 0x2f, 0xec, 0x32, 0xdc, - 0xec, 0x30, 0x13, 0x11, 0x33, 0x11, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, - 0x11, 0x33, 0x11, 0x23, 0x11, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x89, 0xcb, - 0x6e, 0x6d, 0x75, 0x7a, 0x5b, 0xcb, 0xcb, 0x76, 0x96, 0x7e, 0xb7, 0xaf, - 0x03, 0xd4, 0x02, 0x01, 0xfe, 0x19, 0xa3, 0x50, 0x1d, 0x45, 0x02, 0x78, - 0xfa, 0x2b, 0x02, 0x92, 0x3a, 0x17, 0xc4, 0x00, 0x00, 0x01, 0x00, 0x72, - 0x00, 0x00, 0x04, 0x60, 0x05, 0xd5, 0x00, 0x0b, 0x00, 0x26, 0x40, 0x0a, - 0x0b, 0x1e, 0x0a, 0x08, 0x1e, 0x06, 0x03, 0x1e, 0x01, 0x0c, 0x10, 0xd4, - 0xec, 0xdc, 0xec, 0xdc, 0xec, 0x31, 0x00, 0x40, 0x08, 0x06, 0x0b, 0x02, - 0x88, 0x08, 0x04, 0x97, 0x01, 0x2f, 0xec, 0x32, 0xfc, 0x3c, 0x3c, 0x30, - 0x29, 0x01, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, - 0x04, 0x60, 0xfc, 0x12, 0xba, 0xe0, 0xba, 0xe0, 0xba, 0x05, 0xd5, 0xfa, - 0xd5, 0x05, 0x2b, 0xfa, 0xd5, 0x05, 0x2b, 0x00, 0x00, 0x01, 0x00, 0x3c, - 0xfe, 0xbe, 0x04, 0xb0, 0x05, 0xd5, 0x00, 0x0f, 0x00, 0x2f, 0x40, 0x0d, - 0x0f, 0x1e, 0x0c, 0x0b, 0x1e, 0x09, 0x07, 0x1e, 0x05, 0x03, 0x1e, 0x01, - 0x10, 0x10, 0xd4, 0xec, 0xdc, 0xec, 0xdc, 0xfc, 0xdc, 0xec, 0x31, 0x00, - 0x40, 0x0a, 0x06, 0x09, 0x02, 0x88, 0x0b, 0x08, 0x04, 0x97, 0x0e, 0x00, - 0x2f, 0xcc, 0xec, 0x32, 0x32, 0xfc, 0x3c, 0x3c, 0x30, 0x33, 0x11, 0x33, - 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x23, - 0x11, 0x3c, 0xba, 0xe0, 0xba, 0xe0, 0xba, 0x86, 0xaa, 0x05, 0xd5, 0xfa, - 0xd5, 0x05, 0x2b, 0xfa, 0xd5, 0x05, 0x2b, 0xfa, 0xd5, 0xfe, 0x14, 0x01, - 0x42, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x20, 0x00, 0x00, 0x04, 0x75, - 0x05, 0xd5, 0x00, 0x08, 0x00, 0x15, 0x00, 0x2a, 0x40, 0x09, 0x04, 0x32, - 0x12, 0x0e, 0x00, 0x1e, 0x09, 0x0b, 0x16, 0x10, 0xd4, 0xdc, 0xec, 0x32, - 0x2f, 0xec, 0x31, 0x00, 0x40, 0x0c, 0x0e, 0x97, 0x08, 0xb1, 0x16, 0x0a, - 0xb6, 0x0d, 0x88, 0x00, 0x97, 0x09, 0x2f, 0xec, 0xf4, 0xec, 0x10, 0xf4, - 0xec, 0x30, 0x25, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x2b, 0x01, 0x03, - 0x11, 0x21, 0x35, 0x21, 0x11, 0x33, 0x32, 0x04, 0x15, 0x14, 0x04, 0x23, - 0x01, 0xef, 0x8a, 0x8d, 0x9c, 0x9d, 0x8c, 0x8a, 0xca, 0xfe, 0xfb, 0x01, - 0xcf, 0x8a, 0xfb, 0x01, 0x01, 0xfe, 0xfe, 0xfa, 0xa6, 0x93, 0x85, 0x85, - 0x94, 0xfd, 0x29, 0x05, 0x2b, 0xaa, 0xfd, 0xa8, 0xe2, 0xdd, 0xdb, 0xe3, - 0x00, 0x03, 0x00, 0x41, 0x00, 0x00, 0x04, 0x6e, 0x05, 0xd5, 0x00, 0x03, - 0x00, 0x0d, 0x00, 0x18, 0x00, 0x2c, 0x40, 0x0b, 0x03, 0x1e, 0x00, 0x09, - 0x32, 0x15, 0x11, 0x04, 0x1e, 0x0e, 0x19, 0x10, 0xd4, 0xec, 0x32, 0x2f, - 0xec, 0xdc, 0xec, 0x31, 0x00, 0x40, 0x0b, 0x11, 0x97, 0x0d, 0xb1, 0x04, - 0x97, 0x01, 0x0f, 0x88, 0x0e, 0x00, 0x2f, 0x3c, 0xe4, 0x32, 0xec, 0xf4, - 0xec, 0x30, 0x21, 0x11, 0x33, 0x11, 0x25, 0x33, 0x32, 0x37, 0x36, 0x35, - 0x34, 0x26, 0x2b, 0x01, 0x03, 0x11, 0x33, 0x11, 0x33, 0x32, 0x04, 0x15, - 0x14, 0x04, 0x23, 0x03, 0xa3, 0xcb, 0xfc, 0x9d, 0x5b, 0x66, 0x4e, 0x3c, - 0x79, 0x77, 0x5b, 0xca, 0xca, 0x5b, 0xc2, 0x01, 0x01, 0xfe, 0xfe, 0xc1, - 0x05, 0xd5, 0xfa, 0x2b, 0xa6, 0x4a, 0x38, 0x96, 0x85, 0x94, 0xfd, 0x29, - 0x05, 0xd5, 0xfd, 0xa8, 0xe2, 0xdd, 0xdb, 0xe3, 0x00, 0x02, 0x00, 0xc5, - 0x00, 0x00, 0x04, 0x75, 0x05, 0xd5, 0x00, 0x08, 0x00, 0x15, 0x00, 0x2b, - 0x40, 0x18, 0x08, 0x97, 0x0c, 0x00, 0x97, 0x0a, 0x88, 0x09, 0x15, 0x0d, - 0x01, 0x07, 0x04, 0x00, 0x04, 0x32, 0x11, 0x38, 0x00, 0x0c, 0x1e, 0x0a, - 0x33, 0x16, 0x10, 0xfc, 0xec, 0x32, 0xfc, 0xec, 0x11, 0x17, 0x39, 0x31, - 0x00, 0x2f, 0xe4, 0xec, 0xd4, 0xec, 0x30, 0x25, 0x33, 0x32, 0x36, 0x35, - 0x34, 0x26, 0x2b, 0x01, 0x03, 0x11, 0x33, 0x11, 0x33, 0x32, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x06, 0x23, 0x01, 0x8f, 0xea, 0x8d, 0x9c, 0x9d, 0x8c, - 0xea, 0xca, 0xca, 0xea, 0xfb, 0x80, 0x81, 0x81, 0x81, 0xfa, 0xa6, 0x93, - 0x85, 0x85, 0x94, 0xfd, 0x29, 0x05, 0xd5, 0xfd, 0xa8, 0x71, 0x71, 0xdd, - 0xdb, 0x71, 0x72, 0x00, 0x00, 0x01, 0x00, 0x8b, 0xff, 0xe3, 0x04, 0x31, - 0x05, 0xf0, 0x00, 0x1b, 0x00, 0x4d, 0x40, 0x09, 0x0b, 0x09, 0x0c, 0x32, - 0x19, 0x31, 0x13, 0x02, 0x1d, 0x10, 0xdc, 0x3c, 0xf4, 0xec, 0x32, 0xc4, - 0x31, 0x00, 0x40, 0x17, 0x09, 0x97, 0x0c, 0xb1, 0x1d, 0x03, 0xb3, 0x02, - 0xb2, 0x05, 0x97, 0x00, 0x12, 0xb3, 0x13, 0xb2, 0x10, 0x97, 0x15, 0x96, - 0x00, 0x99, 0x1c, 0x10, 0xe4, 0xf4, 0xec, 0xf4, 0xec, 0x10, 0xee, 0xf6, - 0xee, 0x10, 0xfc, 0xee, 0xb1, 0x0c, 0x10, 0x49, 0xb1, 0x05, 0x09, 0x49, - 0x50, 0x58, 0xb3, 0x09, 0x0c, 0x40, 0x02, 0x17, 0x38, 0x59, 0x30, 0x05, - 0x22, 0x27, 0x35, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x21, 0x35, 0x21, - 0x02, 0x27, 0x26, 0x23, 0x22, 0x07, 0x35, 0x36, 0x33, 0x20, 0x17, 0x16, - 0x10, 0x07, 0x06, 0x01, 0xd5, 0xb0, 0x9a, 0x96, 0xbc, 0xbd, 0x60, 0x5f, - 0x05, 0xfd, 0x88, 0x02, 0x73, 0x1e, 0x3f, 0x62, 0xbc, 0xbb, 0x98, 0x9a, - 0xb0, 0x01, 0x1d, 0xa0, 0x9f, 0x9f, 0x9e, 0x1d, 0x52, 0xcf, 0x7d, 0x93, - 0x94, 0xe7, 0xaa, 0x01, 0x14, 0x61, 0x98, 0x7d, 0xcf, 0x52, 0xcc, 0xcd, - 0xfd, 0x22, 0xcb, 0xcb, 0x00, 0x02, 0x00, 0x3c, 0xff, 0xe3, 0x04, 0x95, - 0x05, 0xf0, 0x00, 0x0b, 0x00, 0x1e, 0x00, 0x48, 0x40, 0x24, 0x18, 0x17, - 0x0f, 0x0e, 0x04, 0x10, 0x16, 0x03, 0x97, 0x10, 0x96, 0x09, 0x97, 0x16, - 0x99, 0x1c, 0x1a, 0x97, 0x0c, 0xb1, 0x1e, 0x88, 0x1c, 0x00, 0x1e, 0x13, - 0x20, 0x05, 0x1e, 0x19, 0x0d, 0x1a, 0x0c, 0x1e, 0x1c, 0x1f, 0x10, 0xdc, - 0xec, 0x32, 0xd4, 0x32, 0xec, 0x10, 0x4b, 0xb0, 0x0e, 0x51, 0x58, 0xd4, - 0x1b, 0xdc, 0x59, 0xec, 0x31, 0x00, 0x2f, 0xe4, 0xfc, 0xee, 0x10, 0xe4, - 0xee, 0xf4, 0xec, 0x11, 0x12, 0x17, 0x39, 0x30, 0x01, 0x10, 0x02, 0x23, - 0x22, 0x02, 0x11, 0x10, 0x12, 0x33, 0x32, 0x12, 0x01, 0x33, 0x1a, 0x01, - 0x33, 0x32, 0x12, 0x11, 0x10, 0x02, 0x23, 0x22, 0x02, 0x03, 0x23, 0x11, - 0x23, 0x11, 0x33, 0x03, 0xcf, 0x5f, 0x6b, 0x6b, 0x5f, 0x5f, 0x6b, 0x6b, - 0x5f, 0xfd, 0x38, 0x6f, 0x0a, 0xbb, 0xca, 0xca, 0xc6, 0xc6, 0xca, 0xcb, - 0xba, 0x0a, 0x6f, 0xcb, 0xcb, 0x02, 0xe9, 0x01, 0x49, 0x01, 0x1a, 0xfe, - 0xe6, 0xfe, 0xb7, 0xfe, 0xb8, 0xfe, 0xe6, 0x01, 0x19, 0x01, 0xa4, 0x01, - 0x43, 0x01, 0x69, 0xfe, 0x80, 0xfe, 0x79, 0xfe, 0x7a, 0xfe, 0x80, 0x01, - 0x6a, 0x01, 0x4d, 0xfd, 0x66, 0x05, 0xd5, 0x00, 0x00, 0x02, 0x00, 0x4c, - 0x00, 0x00, 0x04, 0x6d, 0x05, 0xd5, 0x00, 0x08, 0x00, 0x16, 0x00, 0x43, - 0x40, 0x0d, 0x0a, 0x14, 0x00, 0x05, 0x14, 0x1e, 0x11, 0x31, 0x00, 0x32, - 0x0d, 0x09, 0x17, 0x10, 0xd4, 0xd4, 0xec, 0xf4, 0xec, 0x32, 0x12, 0x11, - 0x39, 0x31, 0x00, 0x40, 0x0b, 0x42, 0x0a, 0x04, 0x97, 0x15, 0x05, 0x97, - 0x11, 0x88, 0x13, 0x09, 0x2f, 0x3c, 0xf4, 0xec, 0xd4, 0xec, 0x39, 0x30, - 0x4b, 0x53, 0x58, 0xb7, 0x15, 0x25, 0x0a, 0x16, 0x25, 0x09, 0x09, 0x0a, - 0x07, 0x10, 0x05, 0xed, 0x10, 0xed, 0x59, 0x01, 0x14, 0x16, 0x33, 0x21, - 0x11, 0x21, 0x22, 0x06, 0x09, 0x01, 0x2e, 0x01, 0x35, 0x34, 0x24, 0x33, - 0x21, 0x11, 0x23, 0x11, 0x21, 0x01, 0x01, 0x74, 0x8e, 0x91, 0x01, 0x0f, - 0xfe, 0xf9, 0x90, 0x97, 0xfe, 0xd8, 0x01, 0x71, 0x6c, 0xb2, 0x01, 0x06, - 0xf6, 0x01, 0xd2, 0xcb, 0xfe, 0xde, 0xfe, 0xa2, 0x04, 0x25, 0x86, 0x82, - 0x02, 0x12, 0x89, 0xfb, 0x5a, 0x02, 0x9a, 0x27, 0xb2, 0xb2, 0xd2, 0xde, - 0xfa, 0x2b, 0x02, 0x77, 0xfd, 0x89, 0x00, 0x00, 0xff, 0xff, 0x00, 0x85, - 0xff, 0xe3, 0x04, 0x23, 0x04, 0x7b, 0x10, 0x06, 0x00, 0x44, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x7d, 0xff, 0xe3, 0x04, 0x48, 0x06, 0x37, 0x00, 0x08, - 0x00, 0x2a, 0x00, 0x36, 0x40, 0x0d, 0x22, 0x23, 0x00, 0x12, 0x0e, 0x44, - 0x04, 0x12, 0x09, 0x06, 0x14, 0x3e, 0x2b, 0x10, 0xf4, 0xec, 0xec, 0xfc, - 0xec, 0xd4, 0xc4, 0x31, 0x00, 0x40, 0x10, 0x07, 0x8c, 0x11, 0x22, 0xb6, - 0x23, 0x1e, 0xb6, 0x28, 0x02, 0x8c, 0x0b, 0xbe, 0x11, 0x99, 0x2b, 0x10, - 0xe4, 0xf4, 0xec, 0xdc, 0xec, 0xd4, 0xec, 0x10, 0xee, 0x30, 0x01, 0x10, - 0x21, 0x20, 0x11, 0x14, 0x16, 0x33, 0x20, 0x01, 0x36, 0x33, 0x32, 0x12, - 0x11, 0x10, 0x02, 0x23, 0x22, 0x02, 0x13, 0x36, 0x2f, 0x01, 0x26, 0x34, - 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x25, 0x36, 0x37, 0x17, 0x06, 0x0f, - 0x01, 0x06, 0x07, 0x06, 0x07, 0x03, 0x85, 0xfe, 0xe3, 0xfe, 0xe4, 0x90, - 0x8c, 0x01, 0x1d, 0xfd, 0x98, 0x78, 0xde, 0xde, 0xf7, 0xf6, 0xea, 0xe9, - 0xfb, 0x05, 0x01, 0x01, 0x07, 0x05, 0x02, 0x14, 0x24, 0x5b, 0xa7, 0x80, - 0x01, 0x1c, 0x33, 0x23, 0x46, 0x23, 0x33, 0xf0, 0x62, 0x4a, 0xc5, 0x15, - 0x02, 0x2f, 0x01, 0xb0, 0xfe, 0x50, 0xd5, 0xdb, 0x03, 0x81, 0x7b, 0xfe, - 0xd2, 0xfe, 0xe1, 0xfe, 0xe2, 0xfe, 0xd3, 0x01, 0x33, 0x01, 0x19, 0x2d, - 0x11, 0xa7, 0x77, 0x52, 0x0f, 0x95, 0x49, 0xb9, 0x55, 0x41, 0x0c, 0x02, - 0x10, 0x8e, 0x0d, 0x05, 0x18, 0x0a, 0x2b, 0x74, 0x9a, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0xd1, 0x00, 0x00, 0x04, 0x00, 0x04, 0x60, 0x00, 0x08, - 0x00, 0x11, 0x00, 0x20, 0x00, 0x2d, 0x40, 0x18, 0x19, 0x00, 0xb6, 0x0a, - 0x20, 0x09, 0xb6, 0x12, 0xc2, 0x01, 0xb6, 0x20, 0x0e, 0x12, 0x16, 0x05, - 0x12, 0x1c, 0x00, 0x09, 0x06, 0x12, 0x46, 0x21, 0x10, 0xfc, 0xec, 0x32, - 0xd4, 0xec, 0xd4, 0xec, 0x31, 0x00, 0x2f, 0xec, 0xf4, 0xec, 0x10, 0xd4, - 0xec, 0x39, 0x30, 0x01, 0x11, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, - 0x03, 0x11, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x25, 0x21, 0x32, - 0x16, 0x15, 0x14, 0x06, 0x07, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x23, 0x21, - 0x01, 0x89, 0xef, 0x5f, 0x65, 0x55, 0x6b, 0xf3, 0xe4, 0x55, 0x54, 0x54, - 0x56, 0xfe, 0x65, 0x01, 0x8d, 0xaa, 0xc8, 0x5f, 0x63, 0x85, 0x6d, 0xd1, - 0xc1, 0xfe, 0x63, 0x02, 0x03, 0xfe, 0x93, 0x70, 0x50, 0x4f, 0x5e, 0x01, - 0xc7, 0xfe, 0xcf, 0x55, 0x43, 0x43, 0x56, 0x96, 0x9a, 0x70, 0x6f, 0x81, - 0x0e, 0x19, 0x88, 0x75, 0x9a, 0xa8, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, - 0x00, 0x00, 0x03, 0xf1, 0x04, 0x60, 0x00, 0x05, 0x00, 0x16, 0x40, 0x0a, - 0x00, 0xb6, 0x03, 0xc2, 0x01, 0x04, 0x00, 0x06, 0x02, 0x06, 0x10, 0xdc, - 0xec, 0xc4, 0x31, 0x00, 0x2f, 0xfc, 0xec, 0x30, 0x01, 0x11, 0x23, 0x11, - 0x21, 0x15, 0x01, 0xb9, 0xb8, 0x02, 0xf0, 0x03, 0xca, 0xfc, 0x36, 0x04, - 0x60, 0x96, 0x00, 0x00, 0x00, 0x02, 0x00, 0x69, 0xfe, 0xe2, 0x04, 0x68, - 0x04, 0x60, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x30, 0x40, 0x0d, 0x04, 0x06, - 0x02, 0x0f, 0x06, 0x0e, 0x11, 0x06, 0x0c, 0x05, 0x06, 0x08, 0x19, 0x10, - 0xd4, 0xec, 0xdc, 0xec, 0xd4, 0xec, 0xdc, 0xec, 0x31, 0x00, 0x40, 0x0b, - 0x10, 0xb6, 0x0d, 0xc2, 0x01, 0x0f, 0x08, 0xb6, 0x03, 0x07, 0x05, 0x2f, - 0xcc, 0x32, 0xec, 0x32, 0x32, 0xf4, 0xec, 0x30, 0x25, 0x33, 0x11, 0x23, - 0x11, 0x21, 0x11, 0x23, 0x11, 0x33, 0x32, 0x12, 0x35, 0x11, 0x21, 0x03, - 0x11, 0x21, 0x11, 0x14, 0x07, 0x0e, 0x01, 0x14, 0x33, 0x03, 0xef, 0x79, - 0x96, 0xfd, 0x2d, 0x96, 0x43, 0x37, 0x20, 0x02, 0xec, 0xb9, 0xfe, 0x84, - 0x14, 0x08, 0x0e, 0x22, 0x96, 0xfe, 0x4c, 0x01, 0x1e, 0xfe, 0xe2, 0x01, - 0xb4, 0x01, 0xc6, 0x64, 0x01, 0xa0, 0xfc, 0x36, 0x03, 0x34, 0xfe, 0xf2, - 0x64, 0xf7, 0x90, 0x21, 0x1a, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, - 0xff, 0xe3, 0x04, 0x58, 0x04, 0x7b, 0x10, 0x06, 0x00, 0x48, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x3b, 0x00, 0x00, 0x04, 0x97, 0x04, 0x60, 0x00, 0x13, - 0x00, 0x78, 0x40, 0x0b, 0x08, 0x05, 0x04, 0x03, 0x06, 0x09, 0x01, 0x1e, - 0x06, 0x00, 0x14, 0x10, 0xdc, 0x3c, 0xfc, 0x3c, 0xc0, 0x17, 0x39, 0x31, - 0x00, 0x40, 0x0c, 0x42, 0x08, 0x05, 0x02, 0x03, 0x11, 0x03, 0x00, 0xc2, - 0x0f, 0x0a, 0x06, 0x2f, 0x3c, 0x3c, 0xec, 0x32, 0x32, 0x17, 0x39, 0x30, - 0x4b, 0x53, 0x58, 0x40, 0x09, 0x08, 0x17, 0x09, 0x08, 0x05, 0x07, 0x17, - 0x06, 0x05, 0x07, 0x05, 0xed, 0x10, 0x08, 0xed, 0x59, 0x01, 0x40, 0x13, - 0x0d, 0x00, 0x08, 0x0e, 0x00, 0x07, 0x0f, 0x00, 0x06, 0x10, 0x00, 0x05, - 0x11, 0x00, 0x04, 0x12, 0x00, 0x03, 0x01, 0x10, 0x49, 0x3a, 0x49, 0x3a, - 0x49, 0x3a, 0x49, 0x3a, 0x49, 0x3a, 0x49, 0x3a, 0x00, 0xb7, 0x0c, 0x09, - 0x0d, 0x08, 0x10, 0x05, 0x13, 0x02, 0x10, 0x3c, 0x10, 0x3c, 0x10, 0x3c, - 0x10, 0x3c, 0x01, 0x33, 0x11, 0x01, 0x33, 0x03, 0x01, 0x23, 0x03, 0x07, - 0x11, 0x23, 0x11, 0x27, 0x03, 0x23, 0x01, 0x03, 0x33, 0x01, 0x02, 0x15, - 0xa8, 0x00, 0xff, 0xc7, 0xef, 0x01, 0x03, 0xb3, 0xbf, 0x68, 0xa8, 0x68, - 0xbf, 0xb3, 0x01, 0x03, 0xef, 0xc7, 0x00, 0xff, 0x04, 0x60, 0xfe, 0x50, - 0x01, 0xb0, 0xfe, 0x6c, 0xfd, 0x34, 0x02, 0x10, 0xb1, 0xfe, 0xa1, 0x01, - 0x5f, 0xb1, 0xfd, 0xf0, 0x02, 0xcc, 0x01, 0x94, 0xfe, 0x50, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xa9, 0xff, 0xea, 0x04, 0x28, 0x04, 0x7b, 0x10, 0x06, - 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc3, 0x00, 0x00, 0x04, 0x1a, - 0x04, 0x60, 0x00, 0x09, 0x00, 0x3d, 0x40, 0x0a, 0x06, 0x00, 0x06, 0x08, - 0x01, 0x05, 0x06, 0x02, 0x46, 0x0a, 0x10, 0xfc, 0xec, 0x32, 0xd4, 0xec, - 0x32, 0x31, 0x00, 0x40, 0x08, 0x42, 0x00, 0x05, 0x07, 0x03, 0xc2, 0x09, - 0x02, 0x2f, 0x3c, 0xec, 0x32, 0x39, 0x39, 0x30, 0x4b, 0x53, 0x58, 0x40, - 0x0a, 0x00, 0x17, 0x06, 0x05, 0x06, 0x05, 0x17, 0x01, 0x00, 0x01, 0x07, - 0x00, 0x10, 0xe9, 0x07, 0x10, 0xe9, 0x59, 0x09, 0x01, 0x23, 0x11, 0x33, - 0x11, 0x01, 0x33, 0x11, 0x23, 0x03, 0x62, 0xfe, 0x19, 0xb8, 0xb8, 0x01, - 0xe7, 0xb8, 0xb8, 0x03, 0x29, 0xfc, 0xd7, 0x04, 0x60, 0xfc, 0xd7, 0x03, - 0x29, 0xfb, 0xa0, 0x00, 0xff, 0xff, 0x00, 0xc3, 0x00, 0x00, 0x04, 0x1a, - 0x06, 0x48, 0x10, 0x26, 0x02, 0x8e, 0x00, 0x00, 0x10, 0x06, 0x03, 0x71, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xec, 0x00, 0x00, 0x04, 0xb2, - 0x04, 0x60, 0x12, 0x06, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1e, - 0x00, 0x00, 0x04, 0x1a, 0x04, 0x60, 0x00, 0x11, 0x00, 0x22, 0x40, 0x08, - 0x04, 0x06, 0x01, 0x05, 0x06, 0x11, 0x0b, 0x12, 0x10, 0xd4, 0xdc, 0xec, - 0xd4, 0xec, 0x31, 0x00, 0x40, 0x08, 0x05, 0xb6, 0x00, 0xc2, 0x0c, 0xb6, - 0x0b, 0x02, 0x2f, 0x3c, 0xec, 0xf4, 0xec, 0x30, 0x01, 0x21, 0x11, 0x23, - 0x11, 0x21, 0x15, 0x14, 0x02, 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x36, - 0x12, 0x35, 0x01, 0x09, 0x03, 0x11, 0xb8, 0xfe, 0x5f, 0x1b, 0x97, 0xba, - 0x37, 0x23, 0x55, 0x5e, 0x15, 0x04, 0x60, 0xfb, 0xa0, 0x03, 0xca, 0xf5, - 0xbd, 0xfe, 0xd1, 0xe9, 0x96, 0x76, 0x01, 0x18, 0xae, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x3d, 0x00, 0x00, 0x04, 0x9b, 0x04, 0x60, 0x00, 0x0c, - 0x00, 0x4e, 0x40, 0x15, 0x42, 0x0a, 0x07, 0x02, 0x08, 0x03, 0x00, 0xc2, - 0x09, 0x06, 0x0c, 0x03, 0x07, 0x06, 0x04, 0x0d, 0x01, 0x0a, 0x06, 0x00, - 0x0d, 0x10, 0xdc, 0xec, 0x32, 0x10, 0xdc, 0xec, 0x32, 0x31, 0x00, 0x2f, - 0x3c, 0xc4, 0xec, 0x32, 0x11, 0x17, 0x39, 0x30, 0x4b, 0x53, 0x58, 0x40, - 0x10, 0x08, 0x17, 0x03, 0x07, 0x17, 0x03, 0x02, 0x03, 0x09, 0x17, 0x02, - 0x0a, 0x17, 0x02, 0x02, 0x01, 0x04, 0x07, 0x10, 0xed, 0x10, 0x05, 0xed, - 0x04, 0x07, 0x10, 0xed, 0x10, 0x05, 0xed, 0x59, 0x13, 0x33, 0x09, 0x01, - 0x33, 0x11, 0x23, 0x11, 0x01, 0x23, 0x01, 0x11, 0x23, 0x3d, 0xb8, 0x01, - 0x77, 0x01, 0x77, 0xb8, 0xb8, 0xfe, 0xe5, 0xb8, 0xfe, 0xe5, 0xb8, 0x04, - 0x60, 0xfd, 0x4d, 0x02, 0xb3, 0xfb, 0xa0, 0x02, 0xe5, 0xfe, 0x1f, 0x01, - 0xe1, 0xfd, 0x1b, 0x00, 0x00, 0x01, 0x00, 0xc3, 0x00, 0x00, 0x04, 0x1a, - 0x04, 0x60, 0x00, 0x0b, 0x00, 0x24, 0x40, 0x12, 0x01, 0xb6, 0x06, 0x09, - 0x04, 0xc2, 0x0a, 0x02, 0x00, 0x08, 0x06, 0x09, 0x01, 0x05, 0x06, 0x03, - 0x46, 0x0c, 0x10, 0xfc, 0xec, 0x32, 0xd4, 0xec, 0x32, 0x31, 0x00, 0x2f, - 0x3c, 0xe4, 0x32, 0xd4, 0xec, 0x30, 0x01, 0x21, 0x11, 0x23, 0x11, 0x33, - 0x11, 0x21, 0x11, 0x33, 0x11, 0x23, 0x03, 0x62, 0xfe, 0x19, 0xb8, 0xb8, - 0x01, 0xe7, 0xb8, 0xb8, 0x02, 0x03, 0xfd, 0xfd, 0x04, 0x60, 0xfe, 0x39, - 0x01, 0xc7, 0xfb, 0xa0, 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, - 0x04, 0x7b, 0x10, 0x06, 0x00, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc3, - 0x00, 0x00, 0x04, 0x1a, 0x04, 0x60, 0x00, 0x07, 0x00, 0x1c, 0x40, 0x0e, - 0x01, 0xb6, 0x04, 0xc2, 0x06, 0x02, 0x00, 0x06, 0x05, 0x01, 0x06, 0x03, - 0x46, 0x08, 0x10, 0xfc, 0xec, 0xd4, 0xec, 0x31, 0x00, 0x2f, 0x3c, 0xf4, - 0xec, 0x30, 0x01, 0x21, 0x11, 0x23, 0x11, 0x21, 0x11, 0x23, 0x03, 0x62, - 0xfe, 0x19, 0xb8, 0x03, 0x57, 0xb8, 0x03, 0xca, 0xfc, 0x36, 0x04, 0x60, - 0xfb, 0xa0, 0x00, 0x00, 0xff, 0xff, 0x00, 0xbe, 0xfe, 0x56, 0x04, 0x54, - 0x04, 0x7b, 0x10, 0x06, 0x00, 0x53, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, - 0xff, 0xe3, 0x04, 0x25, 0x04, 0x7b, 0x10, 0x06, 0x00, 0x46, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xe1, 0x00, 0x00, 0x04, 0x07, 0x04, 0x60, 0x00, 0x07, - 0x00, 0x1c, 0x40, 0x0d, 0x00, 0x03, 0xb6, 0x05, 0xc2, 0x01, 0x07, 0x01, - 0x04, 0x03, 0x06, 0x01, 0x08, 0x10, 0xdc, 0xfc, 0xcc, 0x10, 0xcc, 0x31, - 0x00, 0x2f, 0xfc, 0xfc, 0x3c, 0x30, 0x01, 0x11, 0x23, 0x11, 0x21, 0x35, - 0x21, 0x15, 0x02, 0xd0, 0xb8, 0xfe, 0xc9, 0x03, 0x26, 0x03, 0xca, 0xfc, - 0x36, 0x03, 0xca, 0x96, 0x96, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x68, - 0xfe, 0x56, 0x04, 0x81, 0x04, 0x60, 0x10, 0x06, 0x00, 0x5c, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x63, 0xfe, 0x56, 0x04, 0x65, 0x06, 0x14, 0x00, 0x06, - 0x00, 0x18, 0x00, 0x1f, 0x00, 0x63, 0x40, 0x11, 0x1d, 0x12, 0x13, 0x0d, - 0x0a, 0x16, 0x19, 0x10, 0x06, 0x0d, 0x03, 0x12, 0x0a, 0x07, 0x00, 0x0d, - 0x20, 0x10, 0xd4, 0x3c, 0x3c, 0xd4, 0xec, 0x10, 0xfc, 0x3c, 0x3c, 0x49, - 0x3b, 0xec, 0x31, 0x00, 0x40, 0x11, 0x19, 0x00, 0x8c, 0x10, 0x0d, 0xbe, - 0x1a, 0x06, 0x8c, 0x16, 0x07, 0x99, 0x18, 0xc3, 0x0e, 0x9b, 0x20, 0x10, - 0xec, 0xec, 0xf4, 0x3c, 0xec, 0x32, 0xf4, 0x3c, 0xec, 0x32, 0x30, 0x01, - 0xb0, 0x0d, 0x4b, 0x54, 0xb0, 0x10, 0x4b, 0x54, 0x5b, 0x58, 0xbf, 0x00, - 0x21, 0x00, 0x20, 0xff, 0xc0, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, - 0x20, 0x00, 0x40, 0x38, 0x12, 0x36, 0x17, 0x38, 0x59, 0x01, 0x0e, 0x01, - 0x15, 0x14, 0x16, 0x17, 0x15, 0x26, 0x02, 0x11, 0x10, 0x12, 0x37, 0x11, - 0x33, 0x11, 0x16, 0x12, 0x11, 0x10, 0x02, 0x07, 0x11, 0x23, 0x13, 0x11, - 0x3e, 0x01, 0x35, 0x34, 0x26, 0x02, 0x08, 0x78, 0x6a, 0x6a, 0x78, 0xdc, - 0xc9, 0xc7, 0xde, 0xb8, 0xde, 0xc7, 0xc9, 0xdc, 0xb8, 0xb8, 0x78, 0x6a, - 0x6a, 0x03, 0xd6, 0x19, 0x99, 0xf5, 0xf5, 0xa2, 0x19, 0x9c, 0x16, 0x01, - 0x0b, 0x01, 0x2b, 0x01, 0x2b, 0x01, 0x0b, 0x16, 0x01, 0x99, 0xfe, 0x67, - 0x16, 0xfe, 0xf5, 0xfe, 0xd5, 0xfe, 0xd5, 0xfe, 0xf5, 0x16, 0xfe, 0x73, - 0x05, 0x80, 0xfc, 0xa9, 0x19, 0xa2, 0xf5, 0xf5, 0x99, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x4c, 0x00, 0x00, 0x04, 0x85, 0x04, 0x60, 0x10, 0x06, - 0x00, 0x5b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x7c, 0xfe, 0xe2, 0x04, 0x5e, - 0x04, 0x60, 0x00, 0x0b, 0x00, 0x24, 0x40, 0x12, 0x09, 0x05, 0xc2, 0x02, - 0x00, 0x08, 0xb6, 0x03, 0x03, 0x06, 0x00, 0x08, 0x06, 0x0a, 0x07, 0x06, - 0x05, 0x0c, 0x10, 0xdc, 0xec, 0xd4, 0xec, 0xdc, 0xec, 0x31, 0x00, 0x2f, - 0xec, 0x32, 0xcc, 0xec, 0x32, 0x30, 0x25, 0x11, 0x23, 0x11, 0x21, 0x11, - 0x33, 0x11, 0x21, 0x11, 0x33, 0x11, 0x04, 0x5e, 0x96, 0xfc, 0xb4, 0xb8, - 0x01, 0xe6, 0xb8, 0x96, 0xfe, 0x4c, 0x01, 0x1e, 0x04, 0x60, 0xfc, 0x36, - 0x03, 0xca, 0xfc, 0x36, 0x00, 0x01, 0x00, 0xc3, 0x00, 0x00, 0x04, 0x1b, - 0x04, 0x62, 0x00, 0x13, 0x00, 0x21, 0x40, 0x09, 0x0e, 0x09, 0x06, 0x0b, - 0x03, 0x06, 0x00, 0x46, 0x14, 0x10, 0xfc, 0xec, 0xd4, 0xec, 0x32, 0x31, - 0x00, 0xb6, 0x11, 0xb6, 0x06, 0x0a, 0x01, 0xc2, 0x0d, 0x2f, 0xec, 0x32, - 0xdc, 0xec, 0x30, 0x13, 0x11, 0x33, 0x11, 0x14, 0x16, 0x33, 0x32, 0x36, - 0x37, 0x11, 0x33, 0x11, 0x23, 0x11, 0x0e, 0x01, 0x23, 0x22, 0x26, 0xc3, - 0xb8, 0x6b, 0x6e, 0x58, 0x72, 0x45, 0xb8, 0xb8, 0x35, 0x8c, 0x8b, 0x8c, - 0xc8, 0x02, 0xf3, 0x01, 0x6f, 0xfe, 0x91, 0x64, 0x5d, 0x14, 0x27, 0x01, - 0xf5, 0xfb, 0x9e, 0x01, 0xd2, 0x15, 0x2b, 0xa3, 0x00, 0x01, 0x00, 0x7d, - 0x00, 0x00, 0x04, 0x55, 0x04, 0x60, 0x00, 0x0b, 0x00, 0x24, 0x40, 0x12, - 0x06, 0x0b, 0x02, 0xc2, 0x08, 0x04, 0xb6, 0x01, 0x0b, 0x06, 0x0a, 0x08, - 0x06, 0x06, 0x03, 0x06, 0x01, 0x0c, 0x10, 0xdc, 0xec, 0xdc, 0xec, 0xdc, - 0xec, 0x31, 0x00, 0x2f, 0xec, 0x32, 0xfc, 0x3c, 0xc4, 0x30, 0x29, 0x01, - 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x04, 0x55, - 0xfc, 0x28, 0xa8, 0xf0, 0xa8, 0xf0, 0xa8, 0x04, 0x60, 0xfc, 0x36, 0x03, - 0xca, 0xfc, 0x36, 0x03, 0xca, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x50, - 0xfe, 0xe2, 0x04, 0xb8, 0x04, 0x60, 0x00, 0x0f, 0x00, 0x2d, 0x40, 0x0d, - 0x00, 0x06, 0x0d, 0x0b, 0x06, 0x0a, 0x08, 0x06, 0x06, 0x03, 0x06, 0x01, - 0x10, 0x10, 0xdc, 0xec, 0xdc, 0xec, 0xdc, 0xfc, 0xdc, 0xec, 0x31, 0x00, - 0x40, 0x09, 0x06, 0x0b, 0x02, 0xc2, 0x08, 0x04, 0xb6, 0x0f, 0x01, 0x2f, - 0xcc, 0xec, 0x32, 0xfc, 0x3c, 0xc4, 0x30, 0x29, 0x01, 0x11, 0x33, 0x11, - 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x23, 0x04, - 0x22, 0xfc, 0x2e, 0xa8, 0xf0, 0xa8, 0xf0, 0xa8, 0x90, 0x96, 0x04, 0x60, - 0xfc, 0x36, 0x03, 0xca, 0xfc, 0x36, 0x03, 0xca, 0xfc, 0x36, 0xfe, 0x4c, - 0x00, 0x02, 0x00, 0x1e, 0x00, 0x00, 0x04, 0x8c, 0x04, 0x60, 0x00, 0x08, - 0x00, 0x15, 0x00, 0x29, 0x40, 0x09, 0x04, 0x12, 0x12, 0x0e, 0x00, 0x06, - 0x09, 0x0b, 0x16, 0x10, 0xd4, 0xdc, 0xec, 0x32, 0x2f, 0xec, 0x31, 0x00, - 0x40, 0x0b, 0x08, 0xb6, 0x0e, 0x16, 0x0a, 0xb6, 0x0d, 0xc2, 0x00, 0xb6, - 0x09, 0x2f, 0xec, 0xf4, 0xec, 0x10, 0xd4, 0xec, 0x30, 0x25, 0x33, 0x32, - 0x36, 0x35, 0x34, 0x26, 0x2b, 0x01, 0x03, 0x11, 0x23, 0x35, 0x21, 0x11, - 0x21, 0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x01, 0xce, 0xf8, 0x7c, 0x86, - 0x89, 0x79, 0xf8, 0xb8, 0xf8, 0x01, 0xb0, 0x01, 0x00, 0xd1, 0xed, 0xe8, - 0xd6, 0x9c, 0x58, 0x5a, 0x5a, 0x5a, 0xfd, 0xfe, 0x03, 0xca, 0x96, 0xfe, - 0x3b, 0xa7, 0xa8, 0xa8, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x68, - 0x00, 0x00, 0x04, 0x69, 0x04, 0x60, 0x00, 0x03, 0x00, 0x0c, 0x00, 0x17, - 0x00, 0x2b, 0x40, 0x0b, 0x03, 0x06, 0x00, 0x09, 0x12, 0x15, 0x10, 0x04, - 0x06, 0x0d, 0x18, 0x10, 0xd4, 0xec, 0x32, 0x2f, 0xec, 0xdc, 0xec, 0x31, - 0x00, 0x40, 0x0a, 0x0c, 0xb6, 0x10, 0x04, 0xb6, 0x01, 0x0e, 0xc2, 0x0d, - 0x00, 0x2f, 0x3c, 0xe4, 0x32, 0xec, 0xd4, 0xec, 0x30, 0x21, 0x11, 0x33, - 0x11, 0x25, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x2b, 0x01, 0x03, 0x11, - 0x33, 0x11, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x03, 0xb1, 0xb8, - 0xfc, 0xb5, 0x53, 0x7c, 0x86, 0x89, 0x79, 0x53, 0xb6, 0xb6, 0x5b, 0xd1, - 0xed, 0xe8, 0xd6, 0x04, 0x60, 0xfb, 0xa0, 0x9a, 0x59, 0x5b, 0x5b, 0x5b, - 0xfd, 0xfc, 0x04, 0x60, 0xfe, 0x3b, 0xa7, 0xa8, 0xa8, 0xa4, 0x00, 0x00, - 0x00, 0x02, 0x00, 0xc3, 0x00, 0x00, 0x04, 0x38, 0x04, 0x60, 0x00, 0x08, - 0x00, 0x13, 0x00, 0x2a, 0x40, 0x17, 0x08, 0xb6, 0x0c, 0x00, 0xb6, 0x0a, - 0xc2, 0x09, 0x13, 0x0d, 0x01, 0x07, 0x04, 0x00, 0x04, 0x12, 0x10, 0x00, - 0x0c, 0x06, 0x0a, 0x46, 0x14, 0x10, 0xfc, 0xec, 0x32, 0xdc, 0xec, 0x11, - 0x17, 0x39, 0x31, 0x00, 0x2f, 0xe4, 0xec, 0xd4, 0xec, 0x30, 0x25, 0x33, - 0x32, 0x36, 0x35, 0x34, 0x26, 0x2b, 0x01, 0x03, 0x11, 0x33, 0x11, 0x21, - 0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x01, 0x7b, 0xf8, 0x81, 0x80, 0x81, - 0x80, 0xf8, 0xb8, 0xb8, 0x01, 0x00, 0xd0, 0xed, 0xe7, 0xd6, 0x99, 0x59, - 0x5a, 0x5e, 0x58, 0xfd, 0xfe, 0x04, 0x60, 0xfe, 0x3b, 0xa7, 0xa8, 0xa8, - 0xa4, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc3, 0xff, 0xe3, 0x04, 0x25, - 0x04, 0x7b, 0x00, 0x1f, 0x00, 0x4b, 0x40, 0x08, 0x0a, 0x0b, 0x08, 0x12, - 0x19, 0x13, 0x00, 0x20, 0x10, 0xdc, 0x3c, 0xd4, 0xec, 0x32, 0xc4, 0x31, - 0x00, 0x40, 0x16, 0x13, 0x8b, 0x12, 0xc0, 0x0f, 0x00, 0x8b, 0x01, 0xc0, - 0x04, 0x8c, 0x1d, 0x0a, 0xb6, 0x08, 0x0f, 0x8c, 0x16, 0xbe, 0x1d, 0x99, - 0x20, 0x10, 0xe4, 0xf4, 0xec, 0xdc, 0xee, 0x10, 0xfe, 0xf4, 0xee, 0x10, - 0xf5, 0xee, 0xb1, 0x0a, 0x0f, 0x49, 0xb1, 0x04, 0x08, 0x49, 0x50, 0x58, - 0xb3, 0x0a, 0x08, 0x40, 0x02, 0x17, 0x38, 0x59, 0x30, 0x37, 0x35, 0x1e, - 0x01, 0x33, 0x32, 0x37, 0x36, 0x37, 0x21, 0x35, 0x21, 0x26, 0x27, 0x26, - 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x20, 0x00, 0x11, 0x10, - 0x07, 0x06, 0x21, 0x22, 0x26, 0xc3, 0x41, 0x98, 0x60, 0xac, 0x5e, 0x53, - 0x09, 0xfd, 0xe2, 0x02, 0x19, 0x12, 0x45, 0x5e, 0xac, 0x5d, 0x93, 0x49, - 0x4e, 0x9a, 0x51, 0x01, 0x04, 0x01, 0x25, 0x93, 0x92, 0xfe, 0xfc, 0x52, - 0x9d, 0x39, 0xbf, 0x3e, 0x3b, 0x71, 0x64, 0xb0, 0x90, 0x89, 0x52, 0x70, - 0x3a, 0x41, 0xc1, 0x2c, 0x2a, 0xfe, 0xc8, 0xfe, 0xec, 0xfe, 0xec, 0x9c, - 0x9c, 0x2b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x4e, 0xff, 0xe3, 0x04, 0x90, - 0x04, 0x7b, 0x00, 0x0b, 0x00, 0x1e, 0x00, 0x3f, 0x40, 0x23, 0x18, 0x17, - 0x0f, 0x0e, 0x04, 0x10, 0x16, 0x03, 0x8c, 0x10, 0xbe, 0x09, 0x8c, 0x16, - 0x99, 0x1c, 0x1a, 0xb6, 0x0c, 0x1e, 0xc2, 0x1c, 0x00, 0x06, 0x13, 0x1c, - 0x05, 0x06, 0x19, 0x0d, 0x1a, 0x0c, 0x06, 0x1c, 0x1f, 0x10, 0xdc, 0xec, - 0x32, 0xd4, 0x32, 0xec, 0x10, 0xd4, 0xec, 0x31, 0x00, 0x2f, 0xe4, 0xdc, - 0xee, 0x10, 0xe4, 0xee, 0xf4, 0xec, 0x11, 0x12, 0x17, 0x39, 0x30, 0x01, - 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x37, 0x32, 0x36, 0x01, - 0x33, 0x1a, 0x01, 0x33, 0x32, 0x12, 0x11, 0x10, 0x02, 0x23, 0x22, 0x02, - 0x27, 0x23, 0x11, 0x23, 0x11, 0x33, 0x03, 0xcd, 0x70, 0x4c, 0x4c, 0x71, - 0x6a, 0x55, 0x55, 0x65, 0xfd, 0x39, 0x8e, 0x11, 0xd2, 0x9d, 0x9d, 0xdf, - 0xe6, 0x9a, 0x99, 0xd3, 0x10, 0x8e, 0xb8, 0xb8, 0x02, 0x3f, 0xc6, 0xd9, - 0xf4, 0xc1, 0xc1, 0xea, 0x01, 0xfa, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, - 0xfe, 0xdc, 0xfe, 0xd3, 0xfe, 0xd2, 0xfe, 0xe7, 0x01, 0x14, 0xed, 0xfe, - 0x1c, 0x04, 0x60, 0x00, 0x00, 0x02, 0x00, 0xa8, 0x00, 0x00, 0x03, 0xd8, - 0x04, 0x60, 0x00, 0x08, 0x00, 0x16, 0x00, 0x42, 0x40, 0x0c, 0x0a, 0x14, - 0x00, 0x05, 0x14, 0x08, 0x11, 0x00, 0x12, 0x0d, 0x09, 0x17, 0x10, 0xdc, - 0xd4, 0xec, 0xd4, 0xec, 0x32, 0x12, 0x11, 0x39, 0x31, 0x00, 0x40, 0x0b, - 0x42, 0x0a, 0x04, 0xb6, 0x15, 0x05, 0xb6, 0x11, 0xc2, 0x13, 0x09, 0x2f, - 0x3c, 0xf4, 0xec, 0xd4, 0xec, 0x39, 0x30, 0x4b, 0x53, 0x58, 0xb7, 0x15, - 0x17, 0x0a, 0x16, 0x17, 0x09, 0x09, 0x0a, 0x07, 0x10, 0x05, 0xed, 0x10, - 0xed, 0x59, 0x01, 0x14, 0x16, 0x3b, 0x01, 0x11, 0x23, 0x22, 0x06, 0x03, - 0x01, 0x2e, 0x01, 0x35, 0x34, 0x36, 0x33, 0x21, 0x11, 0x23, 0x11, 0x23, - 0x01, 0x01, 0x93, 0x72, 0x37, 0xe4, 0xe3, 0x38, 0x72, 0xeb, 0x01, 0x10, - 0x35, 0xaa, 0xdc, 0x96, 0x01, 0x8d, 0xb8, 0xc1, 0xfe, 0xfe, 0x03, 0x13, - 0x61, 0x55, 0x01, 0x6d, 0x56, 0xfc, 0x8c, 0x01, 0xdf, 0x16, 0x82, 0xa7, - 0xa8, 0x9a, 0xfb, 0xa0, 0x01, 0xc7, 0xfe, 0x39, 0xff, 0xff, 0x00, 0x7b, - 0xff, 0xe3, 0x04, 0x58, 0x06, 0x6d, 0x10, 0x26, 0x03, 0x6e, 0x00, 0x00, - 0x10, 0x06, 0x00, 0x43, 0xe2, 0x07, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, - 0xff, 0xe3, 0x04, 0x58, 0x05, 0xbf, 0x10, 0x26, 0x03, 0x6e, 0x00, 0x00, - 0x10, 0x06, 0x00, 0x6a, 0x23, 0xaf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x23, - 0xfe, 0x56, 0x04, 0x54, 0x06, 0x14, 0x00, 0x1f, 0x00, 0x00, 0x13, 0x35, - 0x33, 0x11, 0x33, 0x11, 0x21, 0x15, 0x21, 0x11, 0x3e, 0x01, 0x33, 0x32, - 0x16, 0x15, 0x10, 0x02, 0x07, 0x35, 0x36, 0x12, 0x11, 0x34, 0x26, 0x23, - 0x22, 0x06, 0x15, 0x11, 0x23, 0x11, 0x23, 0xbe, 0xb8, 0x01, 0xc0, 0xfe, - 0x40, 0x31, 0xa8, 0x7c, 0xb0, 0xb6, 0xfa, 0xed, 0x79, 0xad, 0x6a, 0x7b, - 0x8a, 0x8b, 0xb8, 0x03, 0xd1, 0x8f, 0x01, 0xb4, 0xfe, 0x4c, 0x8f, 0xfe, - 0x73, 0x60, 0x63, 0xe6, 0xdf, 0xfe, 0xb4, 0xfe, 0x8e, 0x2e, 0xa5, 0x19, - 0x01, 0x18, 0x01, 0x16, 0x98, 0x8d, 0xb7, 0xab, 0xfe, 0xfb, 0x03, 0xd1, - 0xff, 0xff, 0x01, 0x01, 0x00, 0x00, 0x04, 0x0b, 0x06, 0x6d, 0x10, 0x26, - 0x03, 0x6c, 0x00, 0x00, 0x10, 0x06, 0x00, 0x76, 0x51, 0x07, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xc3, 0xff, 0xe3, 0x04, 0x25, 0x04, 0x7b, 0x00, 0x1f, - 0x00, 0x4c, 0x40, 0x20, 0x0d, 0x8b, 0x0e, 0xc0, 0x11, 0x00, 0x8b, 0x1f, - 0xc0, 0x1c, 0x8c, 0x03, 0x16, 0xb6, 0x18, 0x11, 0x8c, 0x0a, 0xbe, 0x03, - 0x99, 0x20, 0x16, 0x00, 0x15, 0x18, 0x12, 0x0d, 0x00, 0x07, 0x46, 0x20, - 0x10, 0xf4, 0xc4, 0x32, 0xfc, 0x32, 0x10, 0xc4, 0x31, 0x00, 0x10, 0xe4, - 0xf4, 0xec, 0xdc, 0xee, 0x10, 0xfe, 0xf4, 0xee, 0x10, 0xf5, 0xee, 0xb1, - 0x16, 0x11, 0x49, 0xb1, 0x1c, 0x18, 0x49, 0x50, 0x58, 0xb3, 0x16, 0x18, - 0x40, 0x02, 0x17, 0x38, 0x59, 0x30, 0x25, 0x0e, 0x01, 0x23, 0x20, 0x27, - 0x26, 0x11, 0x10, 0x00, 0x21, 0x32, 0x16, 0x17, 0x15, 0x2e, 0x01, 0x23, - 0x22, 0x07, 0x06, 0x07, 0x25, 0x15, 0x21, 0x16, 0x17, 0x16, 0x33, 0x32, - 0x36, 0x37, 0x04, 0x25, 0x4a, 0x9d, 0x52, 0xfe, 0xfc, 0x92, 0x93, 0x01, - 0x25, 0x01, 0x04, 0x51, 0x9a, 0x4e, 0x49, 0x93, 0x5d, 0xad, 0x5d, 0x45, - 0x12, 0x02, 0x19, 0xfd, 0xe2, 0x09, 0x53, 0x5e, 0xac, 0x60, 0x98, 0x41, - 0x39, 0x2b, 0x2b, 0x9c, 0x9c, 0x01, 0x14, 0x01, 0x14, 0x01, 0x38, 0x2a, - 0x2c, 0xc1, 0x41, 0x3a, 0x70, 0x53, 0x89, 0x01, 0x90, 0xb0, 0x64, 0x71, - 0x3b, 0x3e, 0x00, 0x00, 0xff, 0xff, 0x00, 0xd5, 0xff, 0xe3, 0x04, 0x06, - 0x04, 0x7b, 0x10, 0x06, 0x00, 0x56, 0x00, 0x00, 0xff, 0xff, 0x00, 0xb2, - 0x00, 0x00, 0x04, 0x44, 0x06, 0x14, 0x10, 0x06, 0x00, 0x4c, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xb2, 0x00, 0x00, 0x04, 0x44, 0x06, 0x10, 0x10, 0x26, - 0x00, 0xf3, 0x00, 0x00, 0x11, 0x06, 0x00, 0x6a, 0x18, 0x00, 0x00, 0x08, - 0xb4, 0x03, 0x10, 0x0d, 0x06, 0x07, 0x2b, 0x31, 0xff, 0xff, 0x00, 0xba, - 0xfe, 0x56, 0x03, 0x10, 0x06, 0x14, 0x10, 0x06, 0x00, 0x4d, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x04, 0xcb, 0x04, 0x60, 0x00, 0x05, - 0x00, 0x1e, 0x00, 0x00, 0x25, 0x32, 0x10, 0x2b, 0x01, 0x11, 0x17, 0x23, - 0x11, 0x23, 0x15, 0x14, 0x02, 0x07, 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, - 0x36, 0x12, 0x35, 0x11, 0x21, 0x11, 0x33, 0x32, 0x16, 0x10, 0x06, 0x03, - 0x37, 0xd0, 0xd0, 0x0d, 0x15, 0xbd, 0xe5, 0x1b, 0x52, 0x43, 0xbc, 0x27, - 0x23, 0x55, 0x5e, 0x15, 0x02, 0x35, 0x15, 0x9f, 0xed, 0xe8, 0x99, 0x01, - 0x69, 0xfe, 0x97, 0x99, 0x03, 0xca, 0xf5, 0xbd, 0xfe, 0xd1, 0x80, 0x69, - 0x96, 0x76, 0x01, 0x18, 0xae, 0x01, 0x8e, 0xfe, 0x3b, 0xa7, 0xfe, 0xb0, - 0xa4, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x41, 0x00, 0x00, 0x04, 0x9e, - 0x04, 0x60, 0x00, 0x06, 0x00, 0x18, 0x00, 0x00, 0x25, 0x32, 0x35, 0x34, - 0x2b, 0x01, 0x19, 0x01, 0x33, 0x32, 0x16, 0x10, 0x06, 0x2b, 0x01, 0x11, - 0x21, 0x11, 0x23, 0x11, 0x33, 0x11, 0x21, 0x11, 0x33, 0x03, 0x0a, 0xd0, - 0xd0, 0x0d, 0x15, 0x9f, 0xed, 0xe8, 0xa4, 0xbd, 0xfe, 0x94, 0xa8, 0xa8, - 0x01, 0x6c, 0xa8, 0x99, 0xb5, 0xb4, 0xfe, 0x97, 0x02, 0x02, 0xa7, 0xfe, - 0xb0, 0xa4, 0x02, 0x03, 0xfd, 0xfd, 0x04, 0x60, 0xfe, 0x39, 0x01, 0xc7, - 0x00, 0x01, 0x00, 0x23, 0x00, 0x00, 0x04, 0x39, 0x06, 0x14, 0x00, 0x1b, - 0x00, 0x00, 0x13, 0x35, 0x33, 0x11, 0x33, 0x11, 0x21, 0x15, 0x21, 0x11, - 0x3e, 0x01, 0x33, 0x32, 0x16, 0x15, 0x11, 0x23, 0x11, 0x34, 0x26, 0x23, - 0x22, 0x06, 0x15, 0x11, 0x23, 0x11, 0x23, 0xbe, 0xb8, 0x01, 0xc0, 0xfe, - 0x40, 0x31, 0xa8, 0x73, 0xab, 0xa9, 0xb9, 0x6a, 0x71, 0x81, 0x8b, 0xb8, - 0x03, 0xd1, 0x8f, 0x01, 0xb4, 0xfe, 0x4c, 0x8f, 0xfe, 0x73, 0x60, 0x63, - 0xe1, 0xe4, 0xfe, 0xbe, 0x01, 0x42, 0x97, 0x8e, 0xb7, 0xab, 0xfe, 0xfb, - 0x03, 0xd1, 0x00, 0x00, 0xff, 0xff, 0x00, 0xec, 0x00, 0x00, 0x04, 0xb2, - 0x06, 0x6d, 0x10, 0x26, 0x03, 0x73, 0x00, 0x00, 0x10, 0x06, 0x00, 0x76, - 0x30, 0x07, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, 0x00, 0x00, 0x04, 0x1a, - 0x06, 0x6d, 0x10, 0x26, 0x03, 0x71, 0x00, 0x00, 0x10, 0x06, 0x00, 0x43, - 0x40, 0x07, 0x00, 0x00, 0xff, 0xff, 0x00, 0x68, 0xfe, 0x56, 0x04, 0x81, - 0x06, 0x48, 0x10, 0x26, 0x02, 0x8e, 0x00, 0x00, 0x10, 0x06, 0x03, 0x7c, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc3, 0xfe, 0xe2, 0x04, 0x1a, - 0x04, 0x60, 0x00, 0x0b, 0x00, 0x00, 0x33, 0x11, 0x33, 0x11, 0x21, 0x11, - 0x33, 0x11, 0x21, 0x11, 0x23, 0x11, 0xc3, 0xb8, 0x01, 0xe7, 0xb8, 0xfe, - 0xa0, 0x97, 0x04, 0x60, 0xfc, 0x36, 0x03, 0xca, 0xfb, 0xa0, 0xfe, 0xe2, - 0x01, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x20, 0x00, 0x00, 0x04, 0x75, - 0x05, 0xd5, 0x00, 0x07, 0x00, 0x1a, 0x00, 0x00, 0x25, 0x33, 0x32, 0x36, - 0x10, 0x26, 0x2b, 0x01, 0x11, 0x15, 0x33, 0x32, 0x04, 0x15, 0x14, 0x04, - 0x23, 0x21, 0x11, 0x21, 0x35, 0x21, 0x35, 0x33, 0x15, 0x21, 0x15, 0x01, - 0xef, 0x8a, 0x8d, 0x9c, 0x9d, 0x8c, 0x8a, 0x8a, 0xfb, 0x01, 0x01, 0xfe, - 0xfe, 0xfa, 0xfe, 0xac, 0xfe, 0xfb, 0x01, 0x05, 0xca, 0x01, 0x71, 0xa6, - 0x93, 0x01, 0x0a, 0x94, 0x01, 0x7a, 0xd4, 0xe2, 0xdd, 0xdb, 0xe3, 0x04, - 0x51, 0xa4, 0xe0, 0xe0, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1e, - 0x00, 0x00, 0x04, 0x8c, 0x06, 0x14, 0x00, 0x11, 0x00, 0x19, 0x00, 0x00, - 0x13, 0x35, 0x33, 0x11, 0x33, 0x11, 0x21, 0x15, 0x21, 0x11, 0x21, 0x32, - 0x16, 0x10, 0x06, 0x23, 0x21, 0x11, 0x13, 0x33, 0x32, 0x36, 0x34, 0x26, - 0x2b, 0x01, 0x1e, 0xf8, 0xb8, 0x01, 0xa9, 0xfe, 0x57, 0x01, 0x00, 0xd1, - 0xed, 0xe8, 0xd6, 0xfe, 0x48, 0xb8, 0xf8, 0x7c, 0x86, 0x89, 0x79, 0xf8, - 0x03, 0xcd, 0x93, 0x01, 0xb4, 0xfe, 0x4c, 0x93, 0xfe, 0xce, 0xa7, 0xfe, - 0xb0, 0xa4, 0x03, 0xcd, 0xfc, 0xcf, 0x58, 0xb4, 0x5a, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x75, 0xff, 0xe3, 0x04, 0x5c, 0x05, 0xf0, 0x12, 0x06, - 0x01, 0x61, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, - 0x04, 0x7b, 0x12, 0x06, 0x02, 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0xd7, - 0x00, 0x00, 0x04, 0x73, 0x07, 0x07, 0x00, 0x07, 0x00, 0x1c, 0x40, 0x0e, - 0x03, 0x05, 0x97, 0x01, 0x88, 0x07, 0x03, 0x04, 0x31, 0x06, 0x1e, 0x01, - 0x34, 0x08, 0x10, 0xfc, 0xec, 0xfc, 0xcc, 0x31, 0x00, 0x2f, 0xf4, 0xec, - 0xcc, 0x30, 0x33, 0x11, 0x21, 0x13, 0x33, 0x11, 0x21, 0x11, 0xd7, 0x02, - 0xf2, 0x03, 0xa7, 0xfd, 0x2f, 0x05, 0xd5, 0x01, 0x32, 0xfe, 0x24, 0xfa, - 0xd5, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x03, 0xf2, - 0x05, 0x9a, 0x00, 0x07, 0x00, 0x1a, 0x40, 0x0c, 0x05, 0x00, 0xb6, 0x03, - 0xc2, 0x01, 0x04, 0x07, 0x00, 0x06, 0x02, 0x08, 0x10, 0xdc, 0xec, 0xdc, - 0xcc, 0x31, 0x00, 0x2f, 0xfc, 0xec, 0xcc, 0x30, 0x01, 0x11, 0x23, 0x11, - 0x21, 0x11, 0x33, 0x03, 0x01, 0xb9, 0xb8, 0x02, 0x38, 0xb9, 0x01, 0x03, - 0xa8, 0xfc, 0x58, 0x04, 0x60, 0x01, 0x3a, 0xfe, 0x0e, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x55, 0x00, 0x00, 0x04, 0x73, 0x05, 0xd5, 0x00, 0x0d, - 0x00, 0x00, 0x13, 0x33, 0x11, 0x21, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, - 0x11, 0x23, 0x11, 0x23, 0x55, 0x82, 0x03, 0x9c, 0xfd, 0x2f, 0x02, 0x23, - 0xfd, 0xdd, 0xcb, 0x82, 0x03, 0xe8, 0x01, 0xed, 0xaa, 0xfe, 0xbd, 0xaa, - 0xfc, 0xc2, 0x03, 0x3e, 0x00, 0x01, 0x00, 0x7f, 0x00, 0x00, 0x03, 0xf1, - 0x04, 0x60, 0x00, 0x0d, 0x00, 0x00, 0x21, 0x11, 0x23, 0x35, 0x33, 0x11, - 0x21, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x11, 0x01, 0x01, 0x82, 0x82, - 0x02, 0xf0, 0xfd, 0xc8, 0x01, 0xa0, 0xfe, 0x60, 0x01, 0xf4, 0xaa, 0x01, - 0xc2, 0xb8, 0xfe, 0xf6, 0xaa, 0xfe, 0x0c, 0x00, 0x00, 0x01, 0x00, 0xd7, - 0xfe, 0x66, 0x04, 0x73, 0x05, 0xd5, 0x00, 0x1c, 0x00, 0x00, 0x01, 0x11, - 0x23, 0x11, 0x21, 0x15, 0x21, 0x11, 0x21, 0x32, 0x17, 0x16, 0x15, 0x11, - 0x10, 0x07, 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x37, 0x36, 0x35, 0x11, - 0x34, 0x26, 0x23, 0x01, 0xa2, 0xcb, 0x03, 0x9c, 0xfd, 0x2f, 0x01, 0x37, - 0xba, 0x71, 0x6f, 0x68, 0x66, 0xe4, 0x4c, 0x3e, 0x86, 0x38, 0x37, 0x7c, - 0x7c, 0x02, 0xc7, 0xfd, 0x39, 0x05, 0xd5, 0xaa, 0xfe, 0x46, 0x77, 0x72, - 0xee, 0xfe, 0xce, 0xfe, 0xf4, 0x7c, 0x7a, 0xaa, 0x4b, 0x4b, 0xc2, 0x01, - 0x22, 0x9f, 0x9e, 0x00, 0x00, 0x01, 0x01, 0x01, 0xfe, 0x56, 0x04, 0x52, - 0x04, 0x60, 0x00, 0x1d, 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x21, 0x15, - 0x21, 0x11, 0x33, 0x20, 0x17, 0x16, 0x15, 0x11, 0x14, 0x07, 0x06, 0x2b, - 0x01, 0x35, 0x33, 0x32, 0x37, 0x36, 0x35, 0x11, 0x34, 0x27, 0x26, 0x23, - 0x01, 0xb9, 0xb8, 0x02, 0xf0, 0xfd, 0xc8, 0xfa, 0x01, 0x05, 0x48, 0x52, - 0x52, 0x51, 0xb5, 0xc1, 0xac, 0x6e, 0x21, 0x26, 0x26, 0x31, 0x86, 0x01, - 0xe7, 0xfe, 0x19, 0x04, 0x60, 0xb8, 0xfe, 0xcf, 0x47, 0x51, 0xe5, 0xfe, - 0xf2, 0xd6, 0x60, 0x60, 0x9c, 0x30, 0x37, 0x93, 0x01, 0x08, 0xaa, 0x20, - 0x29, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0f, 0xfe, 0xbe, 0x04, 0xc2, - 0x05, 0xd5, 0x00, 0x17, 0x00, 0x00, 0x33, 0x09, 0x01, 0x33, 0x01, 0x11, - 0x33, 0x11, 0x01, 0x33, 0x01, 0x13, 0x33, 0x11, 0x23, 0x11, 0x23, 0x03, - 0x07, 0x11, 0x23, 0x11, 0x27, 0x03, 0x0f, 0x01, 0x30, 0xfe, 0xe1, 0xcf, - 0x01, 0x1c, 0xbb, 0x01, 0x1c, 0xcf, 0xfe, 0xe1, 0xf6, 0x3a, 0xaa, 0x1b, - 0xde, 0x59, 0xbb, 0x59, 0xde, 0x03, 0x7b, 0x02, 0x5a, 0xfd, 0xad, 0x02, - 0x53, 0xfd, 0xad, 0x02, 0x53, 0xfd, 0xa6, 0xfd, 0x2f, 0xfe, 0x14, 0x01, - 0x42, 0x02, 0x8a, 0xba, 0xfe, 0x30, 0x01, 0xd0, 0xba, 0xfd, 0x76, 0x00, - 0x00, 0x01, 0x00, 0x3b, 0xfe, 0xe2, 0x04, 0xae, 0x04, 0x60, 0x00, 0x17, - 0x00, 0x00, 0x33, 0x01, 0x03, 0x33, 0x01, 0x11, 0x33, 0x11, 0x01, 0x33, - 0x03, 0x13, 0x33, 0x11, 0x23, 0x11, 0x23, 0x03, 0x07, 0x11, 0x23, 0x11, - 0x27, 0x03, 0x3b, 0x01, 0x03, 0xef, 0xc7, 0x00, 0xff, 0xa8, 0x00, 0xff, - 0xc7, 0xef, 0xcd, 0x4d, 0x96, 0x34, 0xbf, 0x68, 0xa8, 0x68, 0xbf, 0x02, - 0xcc, 0x01, 0x94, 0xfe, 0x50, 0x01, 0xb0, 0xfe, 0x50, 0x01, 0xb0, 0xfe, - 0x6c, 0xfd, 0xca, 0xfe, 0x4c, 0x01, 0x1e, 0x02, 0x10, 0xb1, 0xfe, 0xa1, - 0x01, 0x5f, 0xb1, 0xfd, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, - 0xfe, 0x75, 0x04, 0x37, 0x05, 0xf0, 0x10, 0x26, 0x02, 0xaf, 0xb7, 0x00, - 0x10, 0x06, 0x03, 0x50, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa9, - 0xfe, 0x75, 0x04, 0x28, 0x04, 0x7b, 0x10, 0x26, 0x02, 0xaf, 0xbd, 0x00, - 0x10, 0x06, 0x03, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x89, - 0xfe, 0xbe, 0x04, 0xc9, 0x05, 0xd5, 0x00, 0x0f, 0x00, 0x00, 0x25, 0x33, - 0x11, 0x23, 0x11, 0x23, 0x01, 0x07, 0x11, 0x23, 0x11, 0x33, 0x11, 0x01, - 0x33, 0x01, 0x04, 0x56, 0x72, 0xd4, 0x1f, 0xfe, 0x19, 0x9a, 0xcb, 0xcb, - 0x02, 0x77, 0xed, 0xfd, 0xbb, 0xaa, 0xfe, 0x14, 0x01, 0x42, 0x02, 0xec, - 0xa4, 0xfd, 0xb8, 0x05, 0xd5, 0xfd, 0x68, 0x02, 0x98, 0xfd, 0x9e, 0x00, - 0x00, 0x01, 0x00, 0xec, 0xfe, 0xe2, 0x04, 0xb2, 0x04, 0x60, 0x00, 0x0f, - 0x00, 0x00, 0x25, 0x33, 0x11, 0x23, 0x11, 0x23, 0x01, 0x07, 0x11, 0x23, - 0x11, 0x33, 0x11, 0x01, 0x33, 0x01, 0x04, 0x2c, 0x86, 0xc4, 0x1d, 0xfe, - 0x62, 0x89, 0xbe, 0xbe, 0x01, 0xe3, 0xe0, 0xfe, 0x47, 0xb8, 0xfe, 0x2a, - 0x01, 0x1e, 0x02, 0x42, 0x81, 0xfe, 0x3f, 0x04, 0x60, 0xfe, 0x2f, 0x01, - 0xd1, 0xfe, 0x5a, 0x00, 0x00, 0x01, 0x00, 0x1f, 0xfe, 0xbe, 0x04, 0xb3, - 0x05, 0xd5, 0x00, 0x0f, 0x00, 0x00, 0x25, 0x33, 0x11, 0x23, 0x11, 0x23, - 0x11, 0x21, 0x11, 0x23, 0x11, 0x33, 0x11, 0x21, 0x11, 0x33, 0x03, 0xde, - 0xd5, 0xd5, 0xcb, 0xfd, 0xd7, 0xcb, 0xcb, 0x02, 0x29, 0xcb, 0xaa, 0xfe, - 0x14, 0x01, 0x42, 0x02, 0xc7, 0xfd, 0x39, 0x05, 0xd5, 0xfd, 0x9c, 0x02, - 0x64, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x62, 0xfe, 0xe2, 0x04, 0x7c, - 0x04, 0x60, 0x00, 0x0f, 0x00, 0x00, 0x25, 0x33, 0x11, 0x23, 0x11, 0x23, - 0x11, 0x21, 0x11, 0x23, 0x11, 0x33, 0x11, 0x21, 0x11, 0x33, 0x03, 0xb9, - 0xc3, 0xc3, 0xb8, 0xfe, 0x19, 0xb8, 0xb8, 0x01, 0xe7, 0xb8, 0xb8, 0xfe, - 0x2a, 0x01, 0x1e, 0x01, 0xf9, 0xfe, 0x07, 0x04, 0x60, 0xfe, 0x43, 0x01, - 0xbd, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x71, 0x00, 0x00, 0x04, 0xb9, - 0x05, 0xd5, 0x00, 0x0d, 0x00, 0x00, 0x33, 0x11, 0x33, 0x11, 0x21, 0x11, - 0x21, 0x15, 0x21, 0x11, 0x23, 0x11, 0x21, 0x11, 0x71, 0xba, 0x01, 0x6c, - 0x02, 0x22, 0xfe, 0x98, 0xba, 0xfe, 0x94, 0x05, 0xd5, 0xfd, 0x9c, 0x02, - 0x64, 0xaa, 0xfa, 0xd5, 0x02, 0xc7, 0xfd, 0x39, 0x00, 0x01, 0x00, 0x7d, - 0x00, 0x00, 0x04, 0xaf, 0x04, 0x60, 0x00, 0x0d, 0x00, 0x00, 0x33, 0x11, - 0x33, 0x11, 0x21, 0x11, 0x21, 0x15, 0x21, 0x11, 0x23, 0x11, 0x21, 0x11, - 0x7d, 0xa8, 0x01, 0x9a, 0x01, 0xf0, 0xfe, 0xb8, 0xa8, 0xfe, 0x66, 0x04, - 0x60, 0xfe, 0x39, 0x01, 0xc7, 0x96, 0xfc, 0x36, 0x02, 0x03, 0xfd, 0xfd, - 0xff, 0xff, 0x00, 0x8b, 0xfe, 0x75, 0x04, 0x31, 0x05, 0xf0, 0x10, 0x26, - 0x02, 0xaf, 0x64, 0x00, 0x10, 0x06, 0x03, 0x5a, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x75, 0x04, 0x25, 0x04, 0x7b, 0x10, 0x26, - 0x02, 0xaf, 0x68, 0x00, 0x10, 0x06, 0x03, 0x7a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x2f, 0xfe, 0xbe, 0x04, 0xa2, 0x05, 0xd5, 0x00, 0x0b, - 0x00, 0x00, 0x25, 0x33, 0x11, 0x23, 0x11, 0x23, 0x11, 0x21, 0x35, 0x21, - 0x15, 0x21, 0x02, 0xcf, 0xd5, 0xd5, 0xcb, 0xfe, 0x2b, 0x04, 0x73, 0xfe, - 0x2d, 0xaa, 0xfe, 0x14, 0x01, 0x42, 0x05, 0x2b, 0xaa, 0xaa, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xe1, 0xfe, 0xe2, 0x04, 0x07, 0x04, 0x60, 0x00, 0x0b, - 0x00, 0x00, 0x25, 0x33, 0x11, 0x23, 0x11, 0x23, 0x11, 0x21, 0x35, 0x21, - 0x15, 0x21, 0x02, 0xd0, 0xc3, 0xc3, 0xb8, 0xfe, 0xc9, 0x03, 0x26, 0xfe, - 0xc9, 0xb8, 0xfe, 0x2a, 0x01, 0x1e, 0x03, 0xae, 0xb2, 0xb2, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, 0x05, 0xd5, 0x10, 0x06, - 0x00, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x5c, 0xfe, 0x56, 0x04, 0x74, - 0x04, 0x60, 0x00, 0x08, 0x00, 0x00, 0x13, 0x33, 0x09, 0x01, 0x33, 0x01, - 0x11, 0x23, 0x11, 0x5c, 0xc3, 0x01, 0x49, 0x01, 0x49, 0xc3, 0xfe, 0x54, - 0xc0, 0x04, 0x60, 0xfc, 0x94, 0x03, 0x6c, 0xfb, 0xb2, 0xfe, 0x44, 0x01, - 0xbc, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, - 0x05, 0xd5, 0x00, 0x10, 0x00, 0x00, 0x13, 0x33, 0x09, 0x01, 0x33, 0x01, - 0x15, 0x21, 0x15, 0x21, 0x11, 0x23, 0x11, 0x21, 0x35, 0x21, 0x35, 0x25, - 0xd7, 0x01, 0x6c, 0x01, 0x6b, 0xd9, 0xfe, 0x21, 0x01, 0x0a, 0xfe, 0xf6, - 0xcb, 0xfe, 0xf8, 0x01, 0x08, 0x05, 0xd5, 0xfd, 0x6d, 0x02, 0x93, 0xfc, - 0xc9, 0x50, 0xaa, 0xfe, 0x5c, 0x01, 0xa4, 0xaa, 0x50, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x5c, 0xfe, 0x56, 0x04, 0x74, 0x04, 0x60, 0x00, 0x10, - 0x00, 0x00, 0x13, 0x33, 0x09, 0x01, 0x33, 0x01, 0x15, 0x33, 0x15, 0x23, - 0x15, 0x23, 0x35, 0x23, 0x35, 0x33, 0x35, 0x5c, 0xc3, 0x01, 0x49, 0x01, - 0x49, 0xc3, 0xfe, 0x54, 0xc8, 0xc8, 0xc0, 0xc8, 0xc8, 0x04, 0x60, 0xfc, - 0x94, 0x03, 0x6c, 0xfb, 0xb2, 0x35, 0x96, 0xf1, 0xf1, 0x96, 0x35, 0x00, - 0x00, 0x01, 0x00, 0x12, 0xfe, 0xbe, 0x04, 0xbf, 0x05, 0xd5, 0x00, 0x0f, - 0x00, 0x00, 0x25, 0x33, 0x11, 0x23, 0x11, 0x23, 0x09, 0x01, 0x23, 0x09, - 0x01, 0x33, 0x09, 0x01, 0x33, 0x01, 0x04, 0x58, 0x66, 0xd4, 0x05, 0xfe, - 0x92, 0xfe, 0x75, 0xda, 0x01, 0xf4, 0xfe, 0x50, 0xd9, 0x01, 0x48, 0x01, - 0x4e, 0xd9, 0xfe, 0x41, 0xaa, 0xfe, 0x14, 0x01, 0x42, 0x02, 0x83, 0xfd, - 0x7d, 0x03, 0x17, 0x02, 0xbe, 0xfd, 0xcd, 0x02, 0x33, 0xfd, 0x42, 0x00, - 0x00, 0x01, 0x00, 0x4c, 0xfe, 0xe2, 0x04, 0x86, 0x04, 0x60, 0x00, 0x0f, - 0x00, 0x00, 0x25, 0x33, 0x11, 0x23, 0x11, 0x23, 0x09, 0x01, 0x23, 0x09, - 0x01, 0x33, 0x09, 0x01, 0x33, 0x01, 0x03, 0xfa, 0x8c, 0xc4, 0x12, 0xfe, - 0xb8, 0xfe, 0xb9, 0xd5, 0x01, 0xb8, 0xfe, 0x6f, 0xcc, 0x01, 0x29, 0x01, - 0x27, 0xcf, 0xfe, 0x6f, 0xb8, 0xfe, 0x2a, 0x01, 0x1e, 0x01, 0xc1, 0xfe, - 0x3f, 0x02, 0x48, 0x02, 0x18, 0xfe, 0x6b, 0x01, 0x95, 0xfd, 0xe8, 0x00, - 0x00, 0x01, 0x00, 0x8c, 0x00, 0x00, 0x04, 0x47, 0x05, 0xd7, 0x00, 0x1c, - 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x34, 0x26, 0x23, 0x22, 0x07, 0x06, - 0x07, 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, 0x11, 0x36, 0x3f, 0x01, 0x36, - 0x3f, 0x01, 0x32, 0x17, 0x16, 0x17, 0x16, 0x04, 0x47, 0xcb, 0x6a, 0x71, - 0x6a, 0x57, 0x2e, 0x16, 0x45, 0xcb, 0xcb, 0x23, 0x32, 0x30, 0x40, 0x95, - 0x30, 0xa0, 0x58, 0x0e, 0x0b, 0x55, 0x01, 0xf4, 0xfe, 0x0c, 0x01, 0xda, - 0x97, 0x8e, 0x2a, 0x15, 0x1c, 0x5c, 0xab, 0xfe, 0x63, 0x05, 0xd7, 0xfd, - 0x55, 0x27, 0x1b, 0x1a, 0x25, 0x0a, 0x02, 0x54, 0x0d, 0x10, 0x70, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0x00, 0x00, 0x04, 0x1b, 0x06, 0x14, 0x10, 0x06, - 0x00, 0x4b, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc9, 0x00, 0x00, 0x04, 0x06, - 0x05, 0xd5, 0x10, 0x06, 0x00, 0x2c, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, - 0x00, 0x00, 0x04, 0xc2, 0x07, 0x6d, 0x10, 0x26, 0x0c, 0xc6, 0x00, 0x00, - 0x10, 0x06, 0x03, 0x4f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x3b, - 0x00, 0x00, 0x04, 0x97, 0x06, 0x48, 0x10, 0x26, 0x02, 0x8e, 0x00, 0x00, - 0x10, 0x06, 0x03, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x89, - 0xfe, 0x66, 0x04, 0xb8, 0x05, 0xd5, 0x00, 0x1e, 0x00, 0x00, 0x01, 0x33, - 0x32, 0x17, 0x16, 0x15, 0x11, 0x10, 0x07, 0x06, 0x2b, 0x01, 0x35, 0x33, - 0x32, 0x37, 0x36, 0x35, 0x11, 0x34, 0x26, 0x2b, 0x01, 0x07, 0x11, 0x23, - 0x11, 0x33, 0x11, 0x01, 0x33, 0x02, 0x73, 0x18, 0xb7, 0x74, 0x6f, 0x68, - 0x66, 0xe4, 0x4c, 0x3e, 0x86, 0x38, 0x37, 0x7c, 0x7c, 0x97, 0x77, 0xcb, - 0xcb, 0x02, 0x77, 0xed, 0x03, 0x71, 0x77, 0x72, 0xee, 0xfe, 0xce, 0xfe, - 0xf4, 0x7c, 0x7a, 0xaa, 0x4b, 0x4b, 0xc2, 0x01, 0x22, 0x9f, 0x9e, 0x7f, - 0xfd, 0xb8, 0x05, 0xd5, 0xfd, 0x68, 0x02, 0x98, 0x00, 0x01, 0x00, 0xec, - 0xfe, 0x56, 0x04, 0x6d, 0x04, 0x60, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x33, - 0x20, 0x17, 0x16, 0x15, 0x11, 0x14, 0x07, 0x06, 0x2b, 0x01, 0x35, 0x33, - 0x32, 0x37, 0x36, 0x35, 0x11, 0x34, 0x27, 0x26, 0x2b, 0x01, 0x07, 0x11, - 0x23, 0x11, 0x33, 0x11, 0x01, 0x33, 0x02, 0x6a, 0x3a, 0x01, 0x05, 0x48, - 0x52, 0x52, 0x51, 0xb5, 0xc1, 0xac, 0x6e, 0x21, 0x26, 0x26, 0x31, 0x86, - 0xdd, 0x27, 0xbe, 0xbe, 0x01, 0xe3, 0xe0, 0x02, 0x77, 0x47, 0x51, 0xe5, - 0xfe, 0xf2, 0xd6, 0x60, 0x60, 0x9c, 0x30, 0x37, 0x93, 0x01, 0x08, 0xaa, - 0x20, 0x29, 0x26, 0xfe, 0x3f, 0x04, 0x60, 0xfe, 0x2f, 0x01, 0xd1, 0x00, - 0x00, 0x01, 0x00, 0x89, 0xfe, 0x66, 0x04, 0x48, 0x05, 0xd5, 0x00, 0x15, - 0x00, 0x00, 0x25, 0x10, 0x07, 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x37, - 0x36, 0x35, 0x11, 0x21, 0x11, 0x23, 0x11, 0x33, 0x11, 0x21, 0x11, 0x33, - 0x04, 0x48, 0x68, 0x67, 0xe3, 0x4c, 0x3e, 0x86, 0x38, 0x37, 0xfd, 0xd7, - 0xcb, 0xcb, 0x02, 0x29, 0xcb, 0x68, 0xfe, 0xf2, 0x7a, 0x7a, 0xaa, 0x4b, - 0x4b, 0xc2, 0x02, 0x5f, 0xfd, 0x39, 0x05, 0xd5, 0xfd, 0x9c, 0x02, 0x64, - 0x00, 0x01, 0x00, 0xc3, 0xfe, 0x56, 0x04, 0x1a, 0x04, 0x60, 0x00, 0x15, - 0x00, 0x00, 0x05, 0x14, 0x07, 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x37, - 0x36, 0x35, 0x11, 0x21, 0x11, 0x23, 0x11, 0x33, 0x11, 0x21, 0x11, 0x33, - 0x04, 0x1a, 0x52, 0x51, 0xb5, 0xc1, 0xac, 0x6e, 0x21, 0x26, 0xfe, 0x19, - 0xb8, 0xb8, 0x01, 0xe7, 0xb8, 0x14, 0xd6, 0x60, 0x60, 0x9c, 0x30, 0x37, - 0x93, 0x02, 0x0d, 0xfe, 0x07, 0x04, 0x60, 0xfe, 0x43, 0x01, 0xbd, 0x00, - 0x00, 0x01, 0x00, 0x8c, 0xfe, 0xbe, 0x04, 0x47, 0x05, 0xd7, 0x00, 0x20, - 0x00, 0x00, 0x25, 0x11, 0x06, 0x0f, 0x01, 0x06, 0x0f, 0x01, 0x22, 0x27, - 0x26, 0x27, 0x26, 0x35, 0x11, 0x33, 0x11, 0x14, 0x16, 0x33, 0x32, 0x37, - 0x36, 0x37, 0x36, 0x35, 0x11, 0x33, 0x11, 0x23, 0x11, 0x23, 0x11, 0x03, - 0x7c, 0x23, 0x33, 0x2f, 0x40, 0x95, 0x30, 0xa0, 0x58, 0x0e, 0x0c, 0x54, - 0xcb, 0x6a, 0x71, 0x6a, 0x57, 0x2e, 0x15, 0x46, 0xcb, 0xcb, 0xd5, 0xaa, - 0x02, 0x24, 0x27, 0x1b, 0x1a, 0x25, 0x0a, 0x02, 0x54, 0x0d, 0x10, 0x70, - 0xe4, 0x01, 0xd1, 0xfe, 0x49, 0x97, 0x8e, 0x2a, 0x15, 0x1c, 0x5c, 0xab, - 0x01, 0x7a, 0xfa, 0x29, 0xfe, 0xbe, 0x01, 0xec, 0x00, 0x01, 0x00, 0xc3, - 0xfe, 0xe2, 0x04, 0x1b, 0x04, 0x62, 0x00, 0x1a, 0x00, 0x00, 0x25, 0x11, - 0x06, 0x07, 0x36, 0x07, 0x06, 0x23, 0x22, 0x26, 0x35, 0x11, 0x33, 0x11, - 0x14, 0x16, 0x33, 0x32, 0x36, 0x3d, 0x01, 0x33, 0x11, 0x23, 0x11, 0x23, - 0x11, 0x03, 0x63, 0x1b, 0x3c, 0x03, 0x31, 0x54, 0x73, 0xab, 0xa9, 0xb9, - 0x6a, 0x71, 0x81, 0x8b, 0xb8, 0xb8, 0xc3, 0xb8, 0x01, 0x7e, 0x33, 0x24, - 0x01, 0x1c, 0x32, 0xe1, 0xe4, 0x01, 0x0b, 0xfe, 0xf5, 0x97, 0x8e, 0xb7, - 0xab, 0xce, 0xfb, 0x9e, 0xfe, 0xe2, 0x01, 0xd6, 0x00, 0x01, 0x01, 0xc7, - 0x00, 0x00, 0x02, 0x7f, 0x06, 0x1f, 0x00, 0x03, 0x00, 0x00, 0x01, 0x11, - 0x23, 0x11, 0x02, 0x7f, 0xb8, 0x06, 0x1f, 0xf9, 0xe1, 0x06, 0x1f, 0x00, - 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, 0x07, 0x6d, 0x10, 0x26, - 0x0c, 0xc6, 0x00, 0x00, 0x11, 0x06, 0x03, 0x49, 0x00, 0x00, 0x00, 0x18, - 0xb4, 0x13, 0x08, 0x00, 0x18, 0x07, 0x2b, 0x40, 0x0d, 0x5f, 0x08, 0x50, - 0x00, 0x4f, 0x08, 0x40, 0x00, 0x2f, 0x08, 0x20, 0x00, 0x06, 0x5d, 0x31, - 0xff, 0xff, 0x00, 0x85, 0xff, 0xe3, 0x04, 0x23, 0x06, 0x48, 0x10, 0x26, - 0x02, 0x8e, 0x00, 0x00, 0x10, 0x06, 0x03, 0x69, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, 0x07, 0x4e, 0x10, 0x26, - 0x03, 0x49, 0x00, 0x00, 0x11, 0x07, 0x0c, 0xbe, 0x00, 0x00, 0x01, 0x75, - 0x00, 0x1c, 0xb4, 0x05, 0x11, 0x0e, 0x0a, 0x07, 0x2b, 0x40, 0x11, 0x70, - 0x0e, 0x7f, 0x11, 0x30, 0x0e, 0x3f, 0x11, 0x20, 0x0e, 0x2f, 0x11, 0x00, - 0x0e, 0x0f, 0x11, 0x08, 0x5d, 0x31, 0x00, 0x00, 0xff, 0xff, 0x00, 0x85, - 0xff, 0xe3, 0x04, 0x23, 0x06, 0x10, 0x10, 0x26, 0x00, 0x6a, 0x00, 0x00, - 0x10, 0x06, 0x03, 0x69, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x04, 0x9c, 0x05, 0xd5, 0x10, 0x06, 0x00, 0x88, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x29, 0xff, 0xe3, 0x04, 0xb0, 0x04, 0x7b, 0x10, 0x06, - 0x00, 0xa8, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc5, 0x00, 0x00, 0x04, 0x4e, - 0x07, 0x6d, 0x10, 0x26, 0x0c, 0xc6, 0x12, 0x00, 0x10, 0x06, 0x03, 0x4e, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, 0xff, 0xe3, 0x04, 0x58, - 0x06, 0x48, 0x10, 0x26, 0x02, 0x8e, 0x0e, 0x00, 0x10, 0x06, 0x03, 0x6e, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x75, 0xff, 0xe3, 0x04, 0x5c, - 0x05, 0xf0, 0x12, 0x06, 0x01, 0x51, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7a, - 0xff, 0xe3, 0x04, 0x57, 0x04, 0x7b, 0x12, 0x06, 0x01, 0xff, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x75, 0xff, 0xe3, 0x04, 0x5c, 0x07, 0x4e, 0x10, 0x27, - 0x0c, 0xbe, 0x00, 0x00, 0x01, 0x75, 0x10, 0x06, 0x03, 0xcb, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x7a, 0xff, 0xe3, 0x04, 0x57, 0x06, 0x10, 0x10, 0x26, - 0x00, 0x6a, 0x00, 0x00, 0x10, 0x06, 0x03, 0xcc, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x0f, 0x00, 0x00, 0x04, 0xc2, 0x07, 0x4e, 0x10, 0x27, - 0x0c, 0xbe, 0x00, 0x00, 0x01, 0x75, 0x10, 0x06, 0x03, 0x4f, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x3b, 0x00, 0x00, 0x04, 0x97, 0x06, 0x10, 0x10, 0x26, - 0x00, 0x6a, 0x00, 0x00, 0x10, 0x06, 0x03, 0x6f, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x37, 0x07, 0x4e, 0x10, 0x27, - 0x0c, 0xbe, 0xff, 0xef, 0x01, 0x75, 0x10, 0x06, 0x03, 0x50, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xa9, 0xff, 0xea, 0x04, 0x28, 0x06, 0x10, 0x10, 0x26, - 0x00, 0x6a, 0xf1, 0x00, 0x10, 0x06, 0x03, 0x70, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x1a, 0xff, 0xe4, 0x04, 0xb7, 0x05, 0xd5, 0x10, 0x06, - 0x01, 0x79, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7d, 0xfe, 0x4c, 0x04, 0x54, - 0x04, 0x60, 0x10, 0x06, 0x02, 0x38, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8b, - 0x00, 0x00, 0x04, 0x46, 0x07, 0x30, 0x10, 0x26, 0x0c, 0xcb, 0x00, 0x00, - 0x10, 0x06, 0x03, 0x51, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, - 0x00, 0x00, 0x04, 0x1a, 0x05, 0xf6, 0x10, 0x26, 0x02, 0x8c, 0x00, 0x00, - 0x10, 0x06, 0x03, 0x71, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8b, - 0x00, 0x00, 0x04, 0x46, 0x07, 0x4e, 0x10, 0x27, 0x0c, 0xbe, 0x00, 0x00, - 0x01, 0x75, 0x10, 0x06, 0x03, 0x51, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, - 0x00, 0x00, 0x04, 0x1a, 0x06, 0x10, 0x10, 0x26, 0x00, 0x6a, 0x00, 0x00, - 0x10, 0x06, 0x03, 0x71, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x75, - 0xff, 0xe3, 0x04, 0x5c, 0x07, 0x4e, 0x10, 0x26, 0x03, 0x57, 0x00, 0x00, - 0x11, 0x07, 0x0c, 0xbe, 0x00, 0x00, 0x01, 0x75, 0x00, 0x1c, 0xb4, 0x0c, - 0x1e, 0x1b, 0x12, 0x07, 0x2b, 0x40, 0x11, 0x70, 0x1b, 0x7f, 0x1e, 0x30, - 0x1b, 0x3f, 0x1e, 0x20, 0x1b, 0x2f, 0x1e, 0x00, 0x1b, 0x0f, 0x1e, 0x08, - 0x5d, 0x31, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, - 0x06, 0x10, 0x10, 0x26, 0x03, 0x77, 0x00, 0x00, 0x11, 0x06, 0x00, 0x6a, - 0x00, 0x00, 0x00, 0x14, 0xb4, 0x0f, 0x1e, 0x1b, 0x15, 0x07, 0x2b, 0x40, - 0x09, 0x7f, 0x1e, 0x70, 0x1b, 0x4f, 0x1e, 0x40, 0x1b, 0x04, 0x5d, 0x31, - 0xff, 0xff, 0x00, 0x75, 0xff, 0xe3, 0x04, 0x5c, 0x05, 0xf0, 0x10, 0x06, - 0x03, 0x2d, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, - 0x04, 0x7b, 0x10, 0x06, 0x02, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x00, 0x75, - 0xff, 0xe3, 0x04, 0x5c, 0x07, 0x4e, 0x10, 0x27, 0x0c, 0xbe, 0x00, 0x00, - 0x01, 0x75, 0x10, 0x06, 0x03, 0xdb, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, - 0xff, 0xe3, 0x04, 0x48, 0x06, 0x10, 0x10, 0x26, 0x00, 0x6a, 0x00, 0x00, - 0x10, 0x06, 0x03, 0xdc, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8b, - 0xff, 0xe3, 0x04, 0x31, 0x07, 0x4e, 0x10, 0x27, 0x0c, 0xbe, 0xff, 0xdf, - 0x01, 0x75, 0x10, 0x06, 0x03, 0x66, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, - 0xff, 0xe3, 0x04, 0x25, 0x06, 0x10, 0x10, 0x26, 0x00, 0x6a, 0xec, 0x00, - 0x10, 0x06, 0x03, 0x86, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x68, - 0x00, 0x00, 0x04, 0x81, 0x07, 0x30, 0x10, 0x26, 0x0c, 0xcb, 0x00, 0x00, - 0x10, 0x06, 0x03, 0x5c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x68, - 0xfe, 0x56, 0x04, 0x81, 0x05, 0xf6, 0x10, 0x26, 0x02, 0x8c, 0x00, 0x00, - 0x10, 0x06, 0x03, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x68, - 0x00, 0x00, 0x04, 0x81, 0x07, 0x4e, 0x10, 0x27, 0x0c, 0xbe, 0x00, 0x00, - 0x01, 0x75, 0x10, 0x06, 0x03, 0x5c, 0x00, 0x00, 0xff, 0xff, 0x00, 0x68, - 0xfe, 0x56, 0x04, 0x81, 0x06, 0x10, 0x10, 0x26, 0x00, 0x6a, 0x00, 0x00, - 0x10, 0x06, 0x03, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x68, - 0x00, 0x00, 0x04, 0x81, 0x07, 0x6b, 0x10, 0x26, 0x0c, 0xc8, 0x00, 0x00, - 0x10, 0x06, 0x03, 0x5c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x68, - 0xfe, 0x56, 0x04, 0x81, 0x06, 0x66, 0x10, 0x26, 0x02, 0x93, 0x00, 0x00, - 0x10, 0x06, 0x03, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, - 0x00, 0x00, 0x04, 0x44, 0x07, 0x4e, 0x10, 0x27, 0x0c, 0xbe, 0x00, 0x00, - 0x01, 0x75, 0x10, 0x06, 0x03, 0x60, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, - 0x00, 0x00, 0x04, 0x1b, 0x06, 0x10, 0x10, 0x26, 0x00, 0x6a, 0x00, 0x00, - 0x10, 0x06, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xd7, - 0xfe, 0xbe, 0x04, 0x73, 0x05, 0xd5, 0x00, 0x09, 0x00, 0x00, 0x25, 0x33, - 0x11, 0x23, 0x11, 0x23, 0x11, 0x21, 0x15, 0x21, 0x01, 0xa2, 0xd5, 0xd5, - 0xcb, 0x03, 0x9c, 0xfd, 0x2f, 0xaa, 0xfe, 0x14, 0x01, 0x42, 0x05, 0xd5, - 0xaa, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0xfe, 0xe2, 0x03, 0xf1, - 0x04, 0x60, 0x00, 0x09, 0x00, 0x00, 0x25, 0x33, 0x11, 0x23, 0x11, 0x23, - 0x11, 0x21, 0x15, 0x21, 0x01, 0xb9, 0xc3, 0xc3, 0xb8, 0x02, 0xf0, 0xfd, - 0xc8, 0xb8, 0xfe, 0x2a, 0x01, 0x1e, 0x04, 0x60, 0xb8, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x41, 0x00, 0x00, 0x04, 0x6e, 0x07, 0x4e, 0x10, 0x27, - 0x0c, 0xbe, 0x00, 0x00, 0x01, 0x75, 0x10, 0x06, 0x03, 0x64, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x68, 0x00, 0x00, 0x04, 0x69, 0x06, 0x10, 0x10, 0x26, - 0x00, 0x6a, 0x00, 0x00, 0x10, 0x06, 0x03, 0x84, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x37, 0x05, 0xf0, 0x12, 0x06, - 0x01, 0x52, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa9, 0xff, 0xea, 0x04, 0x28, - 0x04, 0x7b, 0x12, 0x06, 0x02, 0xfd, 0x00, 0x00, 0xff, 0xff, 0x00, 0x75, - 0xfe, 0xf2, 0x04, 0x5c, 0x05, 0xf0, 0x10, 0x06, 0x00, 0x34, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x89, 0xfe, 0x52, 0x04, 0x1f, 0x04, 0x77, 0x10, 0x06, - 0x00, 0x54, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd1, - 0x05, 0xd5, 0x10, 0x06, 0x00, 0x3a, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x04, 0xd1, 0x04, 0x60, 0x10, 0x06, 0x00, 0x5a, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x77, 0xff, 0xc4, 0x04, 0x5a, 0x05, 0xd5, 0x00, 0x27, - 0x00, 0x00, 0x01, 0x1e, 0x01, 0x17, 0x3e, 0x01, 0x35, 0x11, 0x33, 0x11, - 0x14, 0x06, 0x07, 0x1e, 0x01, 0x17, 0x07, 0x2e, 0x01, 0x27, 0x06, 0x23, - 0x22, 0x2e, 0x02, 0x35, 0x11, 0x33, 0x11, 0x14, 0x1e, 0x02, 0x33, 0x32, - 0x37, 0x2e, 0x01, 0x27, 0x02, 0x9d, 0x1c, 0x53, 0x35, 0x0d, 0x09, 0xca, - 0x23, 0x22, 0x1f, 0x3f, 0x20, 0x46, 0x2c, 0x58, 0x2c, 0x70, 0xa8, 0x6e, - 0xae, 0x79, 0x40, 0xca, 0x13, 0x3a, 0x68, 0x56, 0x4c, 0x34, 0x3d, 0x5f, - 0x1c, 0x01, 0xca, 0x33, 0x5f, 0x2c, 0x1f, 0x40, 0x20, 0x04, 0x4a, 0xfb, - 0xf4, 0x5c, 0x92, 0x39, 0x12, 0x20, 0x0e, 0x9e, 0x14, 0x32, 0x1d, 0x44, - 0x3b, 0x78, 0xb7, 0x7c, 0x04, 0x0c, 0xfb, 0xb6, 0x2c, 0x5c, 0x4c, 0x30, - 0x14, 0x36, 0x6b, 0x32, 0x00, 0x01, 0x00, 0x80, 0x00, 0x00, 0x04, 0x50, - 0x05, 0xf0, 0x00, 0x1c, 0x00, 0x00, 0x01, 0x23, 0x35, 0x34, 0x2e, 0x02, - 0x23, 0x22, 0x0e, 0x02, 0x15, 0x11, 0x21, 0x15, 0x21, 0x11, 0x23, 0x11, - 0x34, 0x3e, 0x02, 0x32, 0x1e, 0x02, 0x15, 0x04, 0x2a, 0xca, 0x13, 0x3a, - 0x69, 0x55, 0x56, 0x68, 0x3a, 0x13, 0x03, 0x06, 0xfc, 0xfa, 0xca, 0x40, - 0x79, 0xae, 0xdc, 0xae, 0x79, 0x40, 0x03, 0x6b, 0xdf, 0x2c, 0x5b, 0x4b, - 0x30, 0x30, 0x4b, 0x5b, 0x2c, 0xfe, 0x23, 0xaa, 0xfe, 0x3d, 0x04, 0x0c, - 0x7c, 0xb6, 0x78, 0x3a, 0x3a, 0x78, 0xb6, 0x7c, 0x00, 0x02, 0x00, 0x55, - 0x00, 0x00, 0x04, 0x7c, 0x05, 0xf0, 0x00, 0x16, 0x00, 0x26, 0x00, 0x00, - 0x01, 0x15, 0x23, 0x11, 0x23, 0x11, 0x21, 0x22, 0x2e, 0x02, 0x35, 0x34, - 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x11, 0x03, 0x34, 0x2e, 0x02, - 0x23, 0x22, 0x0e, 0x02, 0x14, 0x1e, 0x02, 0x33, 0x21, 0x04, 0x7c, 0x7d, - 0xca, 0xfe, 0xf3, 0x6a, 0xad, 0x7a, 0x42, 0x3f, 0x78, 0xad, 0x6f, 0x6e, - 0xaf, 0x79, 0x41, 0xca, 0x14, 0x3a, 0x6a, 0x55, 0x56, 0x68, 0x38, 0x13, - 0x13, 0x38, 0x68, 0x56, 0x01, 0x0d, 0x02, 0x6d, 0xaa, 0xfe, 0x3d, 0x01, - 0xc3, 0x3e, 0x83, 0xcb, 0x8d, 0x8f, 0xca, 0x80, 0x3b, 0x3b, 0x80, 0xca, - 0x8f, 0xfe, 0x91, 0x01, 0xb5, 0x37, 0x6b, 0x54, 0x34, 0x36, 0x62, 0x87, - 0xa2, 0x87, 0x61, 0x36, 0x00, 0x01, 0x00, 0x36, 0x00, 0x00, 0x04, 0x9b, - 0x05, 0xf0, 0x00, 0x1c, 0x00, 0x00, 0x13, 0x34, 0x3e, 0x02, 0x32, 0x1e, - 0x02, 0x15, 0x11, 0x33, 0x15, 0x23, 0x11, 0x23, 0x11, 0x34, 0x2e, 0x02, - 0x23, 0x22, 0x0e, 0x02, 0x1d, 0x01, 0x23, 0x36, 0x40, 0x79, 0xae, 0xdc, - 0xae, 0x79, 0x40, 0xbb, 0xbb, 0xca, 0x13, 0x3a, 0x69, 0x55, 0x56, 0x68, - 0x3a, 0x13, 0xca, 0x04, 0x0c, 0x7c, 0xb6, 0x78, 0x3a, 0x3a, 0x78, 0xb6, - 0x7c, 0xfe, 0x61, 0xaa, 0xfe, 0x3d, 0x04, 0x4a, 0x2c, 0x5b, 0x4b, 0x30, - 0x30, 0x4b, 0x5b, 0x2c, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, - 0xff, 0xe3, 0x04, 0x50, 0x05, 0xd5, 0x00, 0x1c, 0x00, 0x00, 0x01, 0x14, - 0x0e, 0x02, 0x22, 0x2e, 0x02, 0x35, 0x11, 0x33, 0x11, 0x21, 0x15, 0x21, - 0x11, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x3e, 0x02, 0x3d, 0x01, 0x33, 0x04, - 0x2a, 0x40, 0x79, 0xae, 0xdc, 0xae, 0x79, 0x40, 0xca, 0x03, 0x06, 0xfc, - 0xfa, 0x13, 0x3a, 0x68, 0x56, 0x55, 0x69, 0x3a, 0x13, 0xca, 0x01, 0xc9, - 0x7c, 0xb7, 0x78, 0x3b, 0x3b, 0x78, 0xb7, 0x7c, 0x04, 0x0c, 0xfe, 0x8b, - 0xaa, 0xfd, 0xd5, 0x2c, 0x5c, 0x4c, 0x30, 0x30, 0x4c, 0x5c, 0x2c, 0xdf, - 0x00, 0x01, 0x00, 0x60, 0x00, 0x00, 0x04, 0x71, 0x05, 0xf0, 0x00, 0x29, - 0x00, 0x00, 0x01, 0x14, 0x0e, 0x04, 0x07, 0x21, 0x15, 0x21, 0x11, 0x33, - 0x15, 0x33, 0x32, 0x3e, 0x04, 0x35, 0x34, 0x2e, 0x02, 0x22, 0x0e, 0x02, - 0x1d, 0x01, 0x23, 0x35, 0x34, 0x3e, 0x02, 0x32, 0x1e, 0x02, 0x04, 0x71, - 0x27, 0x40, 0x54, 0x58, 0x58, 0x24, 0x01, 0x67, 0xfc, 0x43, 0xcb, 0x33, - 0x32, 0x76, 0x76, 0x6e, 0x55, 0x33, 0x25, 0x4d, 0x76, 0xa2, 0x76, 0x4e, - 0x25, 0xcb, 0x50, 0x8a, 0xbc, 0xd8, 0xc0, 0x8f, 0x54, 0x03, 0x7f, 0x5e, - 0xad, 0x99, 0x80, 0x63, 0x41, 0x0d, 0xaa, 0x01, 0x4b, 0xa1, 0x31, 0x5c, - 0x82, 0xa1, 0xbc, 0x69, 0x7f, 0xb0, 0x6e, 0x30, 0x30, 0x6e, 0xb0, 0x7f, - 0x14, 0x14, 0xac, 0xef, 0x94, 0x42, 0x42, 0x94, 0xef, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x78, 0x00, 0x00, 0x04, 0x59, 0x05, 0xd5, 0x00, 0x09, - 0x00, 0x00, 0x25, 0x21, 0x15, 0x21, 0x11, 0x33, 0x11, 0x21, 0x15, 0x21, - 0x01, 0x43, 0x02, 0x8b, 0xfc, 0xaa, 0xcb, 0x03, 0x16, 0xfc, 0xea, 0xaa, - 0xaa, 0x05, 0xd5, 0xfe, 0x8b, 0xaa, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, - 0x00, 0x00, 0x04, 0x50, 0x05, 0xf2, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x23, - 0x35, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x11, 0x21, 0x15, - 0x21, 0x11, 0x34, 0x3e, 0x02, 0x32, 0x1e, 0x02, 0x15, 0x04, 0x2a, 0xca, - 0x13, 0x3a, 0x69, 0x55, 0x56, 0x68, 0x3a, 0x13, 0x03, 0x06, 0xfc, 0x30, - 0x40, 0x79, 0xae, 0xdc, 0xae, 0x79, 0x40, 0x03, 0x6b, 0xdf, 0x2c, 0x5c, - 0x4c, 0x30, 0x30, 0x4c, 0x5c, 0x2c, 0xfc, 0x60, 0xaa, 0x04, 0x0c, 0x7c, - 0xb7, 0x78, 0x3b, 0x3b, 0x78, 0xb7, 0x7c, 0x00, 0x00, 0x02, 0x00, 0x2b, - 0xff, 0xe3, 0x04, 0xa6, 0x05, 0xf0, 0x00, 0x2a, 0x00, 0x3a, 0x00, 0x00, - 0x00, 0x22, 0x0e, 0x02, 0x15, 0x11, 0x23, 0x11, 0x34, 0x3e, 0x02, 0x33, - 0x32, 0x1e, 0x02, 0x1d, 0x01, 0x33, 0x15, 0x23, 0x11, 0x14, 0x0e, 0x02, - 0x23, 0x22, 0x2e, 0x02, 0x34, 0x3e, 0x02, 0x3b, 0x01, 0x35, 0x34, 0x2e, - 0x01, 0x02, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x11, 0x23, - 0x22, 0x0e, 0x01, 0x02, 0x85, 0xb8, 0x79, 0x48, 0x1d, 0xc4, 0x45, 0x83, - 0xbd, 0x78, 0x77, 0xbc, 0x83, 0x45, 0x83, 0x83, 0x32, 0x59, 0x7b, 0x49, - 0x48, 0x7a, 0x59, 0x32, 0x32, 0x59, 0x7a, 0x48, 0x8a, 0x1b, 0x46, 0xb0, - 0x10, 0x22, 0x32, 0x23, 0x22, 0x34, 0x23, 0x11, 0x8a, 0x24, 0x33, 0x21, - 0x05, 0x4c, 0x31, 0x6a, 0xab, 0x79, 0xfc, 0x73, 0x03, 0xa6, 0x93, 0xdc, - 0x92, 0x49, 0x4b, 0x95, 0xde, 0x93, 0x34, 0xaf, 0xfe, 0xe3, 0x6b, 0xa5, - 0x71, 0x3b, 0x33, 0x6c, 0xa8, 0xea, 0xad, 0x72, 0x38, 0x18, 0x7b, 0xad, - 0x6e, 0xfc, 0xda, 0xa8, 0x6d, 0x3f, 0x18, 0x1c, 0x41, 0x6b, 0x50, 0x01, - 0x1d, 0x1a, 0x40, 0x00, 0x00, 0x02, 0x00, 0x55, 0xff, 0xe3, 0x04, 0x7c, - 0x05, 0xd5, 0x00, 0x16, 0x00, 0x26, 0x00, 0x00, 0x01, 0x33, 0x11, 0x33, - 0x15, 0x23, 0x11, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, - 0x3e, 0x02, 0x33, 0x21, 0x05, 0x22, 0x0e, 0x02, 0x14, 0x1e, 0x02, 0x33, - 0x32, 0x3e, 0x02, 0x35, 0x11, 0x03, 0x35, 0xca, 0x7d, 0x7d, 0x41, 0x79, - 0xaf, 0x6e, 0x6f, 0xad, 0x78, 0x3f, 0x42, 0x7a, 0xad, 0x6a, 0x01, 0x0d, - 0xfe, 0xf3, 0x56, 0x68, 0x38, 0x13, 0x13, 0x38, 0x68, 0x56, 0x55, 0x6a, - 0x3a, 0x14, 0x05, 0xd5, 0xfe, 0x8b, 0xaa, 0xfe, 0x42, 0x8f, 0xca, 0x81, - 0x3b, 0x48, 0x8f, 0xd6, 0x8f, 0x8d, 0xd8, 0x91, 0x4b, 0xaa, 0x42, 0x71, - 0x93, 0xa2, 0x94, 0x70, 0x43, 0x34, 0x54, 0x6b, 0x37, 0x02, 0x05, 0x00, - 0x00, 0x01, 0x00, 0x93, 0x00, 0x00, 0x04, 0x3d, 0x05, 0xd5, 0x00, 0x19, - 0x00, 0x00, 0x01, 0x23, 0x35, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x0e, 0x02, - 0x15, 0x11, 0x23, 0x11, 0x33, 0x11, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x02, - 0x15, 0x04, 0x3d, 0xca, 0x13, 0x3a, 0x69, 0x55, 0x56, 0x68, 0x3a, 0x13, - 0xca, 0xca, 0x36, 0x86, 0x4f, 0x6e, 0xae, 0x79, 0x40, 0x01, 0xee, 0xdf, - 0x2c, 0x5c, 0x4c, 0x30, 0x30, 0x4c, 0x5c, 0x2c, 0xfd, 0x33, 0x05, 0xd5, - 0xfe, 0x50, 0x26, 0x2a, 0x3b, 0x78, 0xb7, 0x7c, 0x00, 0x01, 0x00, 0x9a, - 0x00, 0x00, 0x04, 0x36, 0x05, 0xd5, 0x00, 0x05, 0x00, 0x00, 0x13, 0x33, - 0x11, 0x21, 0x15, 0x21, 0x9a, 0xcb, 0x02, 0xd1, 0xfc, 0x64, 0x05, 0xd5, - 0xfa, 0xd5, 0xaa, 0x00, 0x00, 0x01, 0x00, 0x5d, 0xff, 0xe3, 0x04, 0x74, - 0x05, 0xd5, 0x00, 0x1d, 0x00, 0x00, 0x01, 0x11, 0x14, 0x1e, 0x02, 0x32, - 0x3e, 0x02, 0x35, 0x11, 0x33, 0x11, 0x14, 0x0e, 0x02, 0x22, 0x2e, 0x02, - 0x35, 0x11, 0x23, 0x11, 0x23, 0x11, 0x33, 0x11, 0x02, 0x88, 0x0d, 0x24, - 0x3d, 0x60, 0x3a, 0x1f, 0x0b, 0xba, 0x1a, 0x49, 0x82, 0xd2, 0x85, 0x4d, - 0x1d, 0xb7, 0xba, 0xba, 0x04, 0x60, 0xfd, 0x31, 0x4b, 0x66, 0x3e, 0x1b, - 0x1b, 0x3e, 0x66, 0x4b, 0x02, 0xcf, 0xfd, 0x49, 0x77, 0xab, 0x6f, 0x35, - 0x35, 0x6f, 0xab, 0x77, 0x02, 0x08, 0xfc, 0x4f, 0x05, 0xd5, 0xfe, 0x8b, - 0x00, 0x02, 0x00, 0x36, 0xff, 0xe3, 0x04, 0x9a, 0x05, 0xf0, 0x00, 0x29, - 0x00, 0x41, 0x00, 0x00, 0x13, 0x33, 0x15, 0x33, 0x3e, 0x03, 0x33, 0x32, - 0x1e, 0x02, 0x17, 0x15, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x1e, 0x03, - 0x15, 0x14, 0x0e, 0x04, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x36, 0x37, - 0x23, 0x13, 0x14, 0x1e, 0x04, 0x32, 0x3e, 0x04, 0x35, 0x34, 0x2e, 0x04, - 0x2b, 0x01, 0x0e, 0x01, 0x36, 0xb7, 0x34, 0x2f, 0x73, 0x86, 0x96, 0x52, - 0x3c, 0x5d, 0x51, 0x4e, 0x2d, 0x6b, 0xb9, 0x4f, 0x61, 0x94, 0x38, 0xa1, - 0xfb, 0xad, 0x5b, 0x16, 0x34, 0x53, 0x7a, 0xa4, 0x6a, 0x9f, 0xcd, 0x77, - 0x2e, 0x2f, 0x2d, 0x8a, 0xfd, 0x02, 0x11, 0x25, 0x48, 0x71, 0xa6, 0x73, - 0x4b, 0x2a, 0x14, 0x04, 0x0b, 0x26, 0x4a, 0x7f, 0xbc, 0x85, 0x0c, 0x2b, - 0x25, 0x05, 0xd5, 0xf5, 0x3f, 0x65, 0x47, 0x25, 0x09, 0x12, 0x1b, 0x12, - 0xd7, 0x46, 0x36, 0x3a, 0x34, 0x04, 0x54, 0xa1, 0xef, 0x9e, 0x53, 0x9d, - 0x8c, 0x76, 0x54, 0x30, 0x64, 0xaf, 0xee, 0x89, 0x80, 0xe7, 0x65, 0xfe, - 0x34, 0x3f, 0x79, 0x6c, 0x5b, 0x42, 0x25, 0x23, 0x3f, 0x57, 0x67, 0x75, - 0x3d, 0x40, 0x79, 0x6b, 0x58, 0x40, 0x24, 0x61, 0xeb, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x93, 0x00, 0x00, 0x04, 0x3d, 0x05, 0xd5, 0x00, 0x19, - 0x00, 0x00, 0x21, 0x23, 0x11, 0x0e, 0x01, 0x23, 0x22, 0x2e, 0x02, 0x35, - 0x11, 0x33, 0x11, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x11, - 0x33, 0x04, 0x3d, 0xca, 0x36, 0x86, 0x4f, 0x6e, 0xae, 0x79, 0x40, 0xca, - 0x13, 0x3a, 0x68, 0x56, 0x55, 0x69, 0x3a, 0x13, 0xca, 0x01, 0xaf, 0x25, - 0x2a, 0x3b, 0x78, 0xb7, 0x7c, 0x02, 0x8f, 0xfd, 0x33, 0x2c, 0x5c, 0x4c, - 0x30, 0x30, 0x4c, 0x5c, 0x2c, 0x01, 0x58, 0x00, 0x00, 0x01, 0x00, 0x5b, - 0xff, 0xca, 0x04, 0x76, 0x05, 0xd5, 0x00, 0x1a, 0x00, 0x00, 0x25, 0x15, - 0x01, 0x2e, 0x03, 0x35, 0x34, 0x36, 0x37, 0x36, 0x24, 0x37, 0x03, 0x33, - 0x13, 0x0e, 0x05, 0x15, 0x14, 0x16, 0x17, 0x04, 0x76, 0xfc, 0xde, 0x34, - 0x5b, 0x43, 0x27, 0x68, 0x7b, 0x75, 0x01, 0x0f, 0x9f, 0xb5, 0xee, 0xd9, - 0x6b, 0xcb, 0xb5, 0x98, 0x6e, 0x3e, 0x37, 0x3c, 0x96, 0xcc, 0x01, 0x40, - 0x15, 0x2f, 0x37, 0x42, 0x28, 0x3d, 0x9d, 0x67, 0x62, 0xb2, 0x56, 0x01, - 0x3b, 0xfe, 0x89, 0x33, 0x71, 0x71, 0x6d, 0x60, 0x4d, 0x18, 0x1a, 0x2d, - 0x19, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x5f, 0xff, 0xd0, 0x04, 0x72, - 0x05, 0xf0, 0x00, 0x2e, 0x00, 0x39, 0x00, 0x00, 0x01, 0x14, 0x02, 0x07, - 0x16, 0x17, 0x07, 0x2e, 0x01, 0x27, 0x0e, 0x01, 0x23, 0x22, 0x2e, 0x02, - 0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, 0x17, 0x3e, 0x01, 0x10, 0x2e, 0x02, - 0x22, 0x0e, 0x02, 0x1d, 0x01, 0x23, 0x35, 0x34, 0x3e, 0x02, 0x32, 0x1e, - 0x02, 0x01, 0x22, 0x06, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x2e, 0x01, - 0x04, 0x70, 0x5e, 0x51, 0x65, 0x4c, 0x9c, 0x23, 0x48, 0x24, 0x58, 0xcd, - 0x70, 0x48, 0x78, 0x55, 0x2f, 0x2f, 0x55, 0x78, 0x48, 0x67, 0xc0, 0x58, - 0x32, 0x3a, 0x25, 0x4d, 0x76, 0xa2, 0x76, 0x4e, 0x25, 0xcb, 0x50, 0x8a, - 0xbc, 0xd8, 0xc0, 0x8f, 0x54, 0xfd, 0x42, 0x3d, 0x49, 0x47, 0x3f, 0x4c, - 0x8f, 0x3e, 0x44, 0x8b, 0x03, 0x7f, 0xa9, 0xfe, 0xcd, 0x7c, 0x6e, 0x83, - 0x66, 0x36, 0x61, 0x2d, 0x53, 0x5e, 0x26, 0x4a, 0x6e, 0x90, 0x71, 0x4f, - 0x29, 0x4d, 0x42, 0x61, 0xe9, 0x01, 0x04, 0xb4, 0x6e, 0x31, 0x30, 0x6e, - 0xb0, 0x7f, 0x16, 0x16, 0xac, 0xef, 0x94, 0x42, 0x41, 0x93, 0xef, 0xfd, - 0x6b, 0x49, 0x82, 0x48, 0x4d, 0x45, 0x3c, 0x45, 0x00, 0x01, 0x00, 0x36, - 0x00, 0x00, 0x04, 0x9b, 0x05, 0xf0, 0x00, 0x1a, 0x00, 0x00, 0x13, 0x34, - 0x3e, 0x02, 0x32, 0x1e, 0x02, 0x15, 0x11, 0x33, 0x15, 0x21, 0x11, 0x34, - 0x2e, 0x02, 0x23, 0x22, 0x0e, 0x02, 0x1d, 0x01, 0x23, 0x36, 0x40, 0x79, - 0xae, 0xdc, 0xae, 0x79, 0x40, 0xbb, 0xfe, 0x7b, 0x13, 0x3a, 0x69, 0x55, - 0x56, 0x68, 0x3a, 0x13, 0xca, 0x04, 0x0c, 0x7c, 0xb6, 0x78, 0x3a, 0x3a, - 0x78, 0xb6, 0x7c, 0xfc, 0x9e, 0xaa, 0x04, 0x4a, 0x2c, 0x5b, 0x4b, 0x30, - 0x30, 0x4b, 0x5b, 0x2c, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x56, - 0x00, 0x00, 0x04, 0x7a, 0x05, 0xf0, 0x00, 0x16, 0x00, 0x21, 0x00, 0x00, - 0x01, 0x22, 0x06, 0x07, 0x01, 0x15, 0x21, 0x22, 0x2e, 0x02, 0x35, 0x34, - 0x36, 0x37, 0x36, 0x37, 0x01, 0x33, 0x13, 0x36, 0x24, 0x33, 0x01, 0x0e, - 0x01, 0x15, 0x14, 0x16, 0x33, 0x21, 0x01, 0x0e, 0x01, 0x04, 0x7a, 0x6d, - 0xef, 0x82, 0x01, 0xd9, 0xfc, 0xf6, 0x3c, 0x66, 0x49, 0x2a, 0x4f, 0x5a, - 0x61, 0x5b, 0xfe, 0xdb, 0xe4, 0xc2, 0x8d, 0x01, 0x18, 0x99, 0xfd, 0x33, - 0x42, 0x3d, 0x64, 0x59, 0x01, 0xa2, 0xfe, 0x93, 0x1d, 0x39, 0x05, 0x41, - 0xb7, 0xae, 0xfc, 0xc8, 0xa4, 0x1a, 0x38, 0x59, 0x3e, 0x50, 0xe2, 0x95, - 0xa3, 0x84, 0x01, 0xfe, 0xfe, 0xae, 0xaf, 0xbe, 0xfc, 0x7a, 0x73, 0x9e, - 0x33, 0x44, 0x33, 0x02, 0x79, 0x2d, 0x5e, 0x00, 0x00, 0x01, 0x00, 0x36, - 0xff, 0xe3, 0x04, 0x9b, 0x05, 0xd5, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x21, - 0x15, 0x23, 0x11, 0x14, 0x0e, 0x02, 0x22, 0x2e, 0x02, 0x35, 0x11, 0x33, - 0x11, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x03, 0x16, 0x01, - 0x85, 0xbb, 0x40, 0x79, 0xae, 0xdc, 0xae, 0x79, 0x40, 0xca, 0x13, 0x3a, - 0x68, 0x56, 0x55, 0x69, 0x3a, 0x13, 0x05, 0xd5, 0xaa, 0xfc, 0x9e, 0x7c, - 0xb7, 0x78, 0x3b, 0x3b, 0x78, 0xb7, 0x7c, 0x04, 0x0c, 0xfb, 0xb6, 0x2c, - 0x5c, 0x4c, 0x30, 0x30, 0x4c, 0x5c, 0x2c, 0x00, 0x00, 0x01, 0x00, 0x40, - 0xff, 0xe3, 0x04, 0x91, 0x05, 0xf0, 0x00, 0x39, 0x00, 0x00, 0x01, 0x14, - 0x0e, 0x02, 0x20, 0x2e, 0x02, 0x35, 0x33, 0x14, 0x1e, 0x02, 0x32, 0x3e, - 0x02, 0x35, 0x34, 0x2e, 0x02, 0x23, 0x21, 0x35, 0x21, 0x32, 0x3e, 0x02, - 0x35, 0x34, 0x26, 0x22, 0x06, 0x15, 0x23, 0x34, 0x3e, 0x02, 0x33, 0x32, - 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, 0x07, 0x1e, 0x03, 0x04, 0x91, 0x3c, - 0x7d, 0xc2, 0xfe, 0xf4, 0xc0, 0x7c, 0x3b, 0xd2, 0x21, 0x48, 0x72, 0xa0, - 0x73, 0x49, 0x23, 0x28, 0x4d, 0x71, 0x49, 0xfd, 0xb0, 0x02, 0x50, 0x42, - 0x5d, 0x3b, 0x1a, 0x7e, 0xec, 0x79, 0xd2, 0x41, 0x76, 0xa5, 0x65, 0x64, - 0xa7, 0x78, 0x43, 0x1d, 0x34, 0x4c, 0x2e, 0x44, 0x63, 0x40, 0x1f, 0x01, - 0xbc, 0x5f, 0xab, 0x82, 0x4d, 0x4d, 0x83, 0xac, 0x60, 0x41, 0x71, 0x55, - 0x31, 0x2e, 0x51, 0x6c, 0x3e, 0x3f, 0x66, 0x46, 0x26, 0xaa, 0x2a, 0x47, - 0x5a, 0x30, 0x76, 0x70, 0x71, 0x7b, 0x5b, 0x94, 0x69, 0x38, 0x38, 0x67, - 0x91, 0x5a, 0x3b, 0x68, 0x53, 0x3c, 0x0f, 0x11, 0x47, 0x60, 0x73, 0x00, - 0x00, 0x01, 0x00, 0x36, 0xff, 0xe3, 0x04, 0x9b, 0x05, 0xd5, 0x00, 0x1a, - 0x00, 0x00, 0x01, 0x14, 0x0e, 0x02, 0x22, 0x2e, 0x02, 0x35, 0x11, 0x23, - 0x35, 0x21, 0x11, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x3e, 0x02, 0x3d, 0x01, - 0x33, 0x04, 0x9b, 0x40, 0x79, 0xae, 0xdc, 0xae, 0x79, 0x40, 0xbb, 0x01, - 0x85, 0x13, 0x3a, 0x68, 0x56, 0x55, 0x69, 0x3a, 0x13, 0xca, 0x01, 0xc9, - 0x7c, 0xb7, 0x78, 0x3b, 0x3b, 0x78, 0xb7, 0x7c, 0x03, 0x62, 0xaa, 0xfb, - 0xb6, 0x2c, 0x5c, 0x4c, 0x30, 0x30, 0x4c, 0x5c, 0x2c, 0xdf, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x60, 0xff, 0xe3, 0x04, 0x71, 0x05, 0xd5, 0x00, 0x2f, - 0x00, 0x00, 0x00, 0x14, 0x1e, 0x02, 0x32, 0x3e, 0x02, 0x3d, 0x01, 0x33, - 0x15, 0x14, 0x0e, 0x02, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, 0x37, - 0x27, 0x2e, 0x01, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x16, 0x17, 0x05, 0x15, - 0x27, 0x2e, 0x03, 0x23, 0x22, 0x0e, 0x01, 0x01, 0x33, 0x26, 0x4e, 0x77, - 0xa2, 0x75, 0x4d, 0x24, 0xcb, 0x50, 0x8a, 0xbc, 0xd8, 0xc0, 0x8f, 0x54, - 0x4b, 0x75, 0x8b, 0x41, 0x5a, 0x38, 0x6e, 0x25, 0x2d, 0x7b, 0x33, 0x7e, - 0x48, 0x01, 0xfb, 0xf4, 0x0d, 0x28, 0x2d, 0x2f, 0x15, 0x48, 0x75, 0x53, - 0x02, 0xd2, 0xfc, 0xaf, 0x6e, 0x32, 0x30, 0x6e, 0xaf, 0x80, 0x16, 0x16, - 0xad, 0xee, 0x94, 0x42, 0x45, 0x96, 0xed, 0xa9, 0xa5, 0xf2, 0x9d, 0x4e, - 0x02, 0x28, 0x19, 0x12, 0xaa, 0x1a, 0x1e, 0xd5, 0xd4, 0x67, 0x06, 0x0b, - 0x09, 0x06, 0x4e, 0x90, 0x00, 0x01, 0x00, 0x93, 0x00, 0x00, 0x04, 0x3d, - 0x05, 0xf2, 0x00, 0x18, 0x00, 0x00, 0x21, 0x23, 0x11, 0x34, 0x2e, 0x02, - 0x23, 0x22, 0x0e, 0x02, 0x15, 0x11, 0x23, 0x11, 0x34, 0x3e, 0x02, 0x32, - 0x1e, 0x02, 0x15, 0x04, 0x3d, 0xca, 0x13, 0x3a, 0x69, 0x55, 0x56, 0x68, - 0x3a, 0x13, 0xca, 0x40, 0x79, 0xae, 0xdc, 0xae, 0x79, 0x40, 0x04, 0x4a, - 0x2c, 0x5c, 0x4c, 0x30, 0x30, 0x4c, 0x5c, 0x2c, 0xfb, 0xb6, 0x04, 0x0c, - 0x7c, 0xb7, 0x78, 0x3b, 0x3b, 0x78, 0xb7, 0x7c, 0x00, 0x01, 0x00, 0x60, - 0xff, 0xc6, 0x04, 0x71, 0x05, 0xf0, 0x00, 0x27, 0x00, 0x00, 0x00, 0x34, - 0x2e, 0x02, 0x22, 0x0e, 0x02, 0x1d, 0x01, 0x23, 0x35, 0x34, 0x3e, 0x02, - 0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x04, 0x23, 0x17, 0x15, 0x01, 0x35, - 0x17, 0x1e, 0x01, 0x33, 0x32, 0x3e, 0x01, 0x03, 0x9e, 0x26, 0x4e, 0x77, - 0xa2, 0x75, 0x4d, 0x24, 0xcb, 0x50, 0x8a, 0xbc, 0xd8, 0xc0, 0x8f, 0x54, - 0x24, 0x3e, 0x50, 0x58, 0x5a, 0x28, 0xe8, 0xfc, 0xfb, 0xee, 0x20, 0x5e, - 0x2e, 0x48, 0x75, 0x53, 0x03, 0x01, 0xfc, 0xaf, 0x6e, 0x32, 0x30, 0x6e, - 0xb0, 0x7f, 0x16, 0x16, 0xac, 0xef, 0x94, 0x42, 0x45, 0x96, 0xed, 0xa9, - 0x71, 0xb6, 0x90, 0x68, 0x44, 0x21, 0x63, 0xd2, 0x01, 0x45, 0xd4, 0x65, - 0x0e, 0x14, 0x4e, 0x90, 0x00, 0x01, 0x00, 0x41, 0x00, 0x00, 0x04, 0x90, - 0x05, 0xf0, 0x00, 0x1c, 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x0e, 0x03, - 0x1d, 0x01, 0x23, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x15, - 0x11, 0x23, 0x11, 0x34, 0x2e, 0x02, 0x02, 0xc7, 0xbe, 0x56, 0x69, 0x39, - 0x12, 0xbe, 0x3e, 0x86, 0xd0, 0x93, 0x9d, 0xd3, 0x81, 0x37, 0xbe, 0x12, - 0x39, 0x69, 0x05, 0x47, 0xfc, 0x94, 0x03, 0x6c, 0x0c, 0x49, 0x70, 0x95, - 0x58, 0x2a, 0x39, 0x82, 0xd8, 0x9c, 0x56, 0x56, 0x9c, 0xd8, 0x82, 0xfc, - 0x5c, 0x03, 0x95, 0x4f, 0x95, 0x76, 0x4f, 0x00, 0x00, 0x02, 0x00, 0x60, - 0x00, 0x00, 0x04, 0x70, 0x05, 0xf0, 0x00, 0x29, 0x00, 0x44, 0x00, 0x00, - 0x01, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x2e, 0x04, 0x35, 0x34, 0x3e, 0x04, - 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, 0x07, 0x21, 0x15, 0x21, - 0x11, 0x33, 0x15, 0x33, 0x32, 0x36, 0x37, 0x3e, 0x01, 0x01, 0x34, 0x2e, - 0x02, 0x23, 0x22, 0x0e, 0x04, 0x15, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x1e, - 0x02, 0x15, 0x14, 0x07, 0x3e, 0x01, 0x02, 0x86, 0x16, 0x31, 0x4e, 0x37, - 0x56, 0x76, 0x4d, 0x2a, 0x14, 0x03, 0x15, 0x30, 0x4e, 0x72, 0x99, 0x63, - 0x94, 0xca, 0x7b, 0x36, 0x44, 0x6f, 0x90, 0x4c, 0x01, 0x67, 0xfc, 0x43, - 0xcb, 0x28, 0x3c, 0x79, 0x39, 0x0c, 0x0e, 0x01, 0x17, 0x1a, 0x45, 0x7a, - 0x60, 0x3e, 0x5e, 0x45, 0x2f, 0x1b, 0x0c, 0x0b, 0x25, 0x48, 0x3e, 0x4c, - 0x70, 0x4a, 0x25, 0x06, 0x43, 0x52, 0x01, 0xbf, 0x32, 0x52, 0x39, 0x1f, - 0x1e, 0x31, 0x41, 0x47, 0x48, 0x20, 0x38, 0x7b, 0x76, 0x6c, 0x51, 0x30, - 0x65, 0xac, 0xe2, 0x7e, 0x79, 0xe5, 0xc1, 0x91, 0x25, 0xaa, 0x01, 0x4c, - 0xa2, 0x2e, 0x2b, 0x34, 0x5e, 0x01, 0xea, 0x64, 0xaa, 0x7a, 0x45, 0x20, - 0x35, 0x47, 0x4f, 0x50, 0x25, 0x29, 0x3d, 0x28, 0x14, 0x34, 0x5b, 0x7b, - 0x47, 0x28, 0x2a, 0x61, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x36, - 0x00, 0x00, 0x04, 0x9b, 0x05, 0xf0, 0x00, 0x1c, 0x00, 0x00, 0x13, 0x34, - 0x3e, 0x02, 0x32, 0x1e, 0x02, 0x15, 0x11, 0x33, 0x15, 0x23, 0x11, 0x23, - 0x11, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x11, 0x23, 0x36, - 0x40, 0x79, 0xae, 0xdc, 0xae, 0x79, 0x40, 0xbb, 0xbb, 0xca, 0x13, 0x3a, - 0x69, 0x55, 0x56, 0x68, 0x3a, 0x13, 0xca, 0x04, 0x0c, 0x7c, 0xb6, 0x78, - 0x3a, 0x3a, 0x78, 0xb6, 0x7c, 0xfe, 0x61, 0xaa, 0xfe, 0x3d, 0x04, 0x4a, - 0x2c, 0x5b, 0x4b, 0x30, 0x30, 0x4b, 0x5b, 0x2c, 0xfb, 0xb6, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x93, 0xff, 0xe3, 0x04, 0x3d, 0x05, 0xd5, 0x00, 0x18, - 0x00, 0x00, 0x13, 0x33, 0x11, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x3e, 0x02, - 0x35, 0x11, 0x33, 0x11, 0x14, 0x0e, 0x02, 0x22, 0x2e, 0x02, 0x35, 0x93, - 0xca, 0x13, 0x3a, 0x68, 0x56, 0x55, 0x69, 0x3a, 0x13, 0xca, 0x40, 0x79, - 0xae, 0xdc, 0xae, 0x79, 0x40, 0x05, 0xd5, 0xfb, 0xb6, 0x2c, 0x5c, 0x4c, - 0x30, 0x30, 0x4c, 0x5c, 0x2c, 0x04, 0x4a, 0xfb, 0xf4, 0x7c, 0xb7, 0x78, - 0x3b, 0x3b, 0x78, 0xb7, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x21, - 0x00, 0x00, 0x04, 0xaf, 0x05, 0xd5, 0x00, 0x1b, 0x00, 0x00, 0x13, 0x33, - 0x11, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x11, 0x33, 0x11, - 0x33, 0x15, 0x21, 0x11, 0x0e, 0x01, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x21, - 0xca, 0x13, 0x3a, 0x68, 0x56, 0x55, 0x69, 0x3a, 0x13, 0xca, 0xe4, 0xfe, - 0x52, 0x36, 0x86, 0x4f, 0x6e, 0xae, 0x79, 0x40, 0x04, 0x60, 0xfe, 0xa8, - 0x2c, 0x5c, 0x4c, 0x30, 0x30, 0x4c, 0x5c, 0x2c, 0x02, 0xcd, 0xfa, 0xd5, - 0xaa, 0x01, 0xaf, 0x25, 0x2a, 0x3b, 0x78, 0xb7, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x69, 0xff, 0xe3, 0x04, 0x67, 0x05, 0xf0, 0x00, 0x3d, - 0x00, 0x00, 0x13, 0x33, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x3e, 0x02, 0x35, - 0x34, 0x2e, 0x06, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x15, - 0x23, 0x34, 0x2e, 0x02, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x1e, 0x08, - 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, 0x02, 0x69, 0xd2, 0x30, 0x55, - 0x74, 0x44, 0x41, 0x6d, 0x4e, 0x2c, 0x42, 0x6b, 0x89, 0x90, 0x89, 0x6b, - 0x42, 0x35, 0x6f, 0xa8, 0x74, 0x73, 0xac, 0x71, 0x38, 0xd2, 0x1c, 0x3c, - 0x5d, 0x41, 0x40, 0x5d, 0x3d, 0x1e, 0x2b, 0x49, 0x62, 0x6e, 0x73, 0x6e, - 0x62, 0x49, 0x2b, 0x41, 0x7e, 0xb9, 0x77, 0x7b, 0xc4, 0x88, 0x48, 0x01, - 0xbf, 0x4b, 0x75, 0x4f, 0x29, 0x26, 0x49, 0x6a, 0x45, 0x48, 0x60, 0x42, - 0x2e, 0x30, 0x3a, 0x59, 0x81, 0x5f, 0x51, 0x91, 0x6e, 0x40, 0x40, 0x6e, - 0x91, 0x51, 0x34, 0x57, 0x3e, 0x22, 0x21, 0x3b, 0x53, 0x32, 0x35, 0x4b, - 0x38, 0x29, 0x25, 0x26, 0x31, 0x41, 0x5b, 0x7a, 0x52, 0x60, 0xa5, 0x79, - 0x44, 0x45, 0x7d, 0xaf, 0x00, 0x01, 0x00, 0x93, 0x00, 0x00, 0x04, 0x3d, - 0x05, 0xf2, 0x00, 0x18, 0x00, 0x00, 0x01, 0x23, 0x35, 0x34, 0x2e, 0x02, - 0x23, 0x22, 0x0e, 0x02, 0x15, 0x11, 0x23, 0x11, 0x34, 0x3e, 0x02, 0x32, - 0x1e, 0x02, 0x15, 0x04, 0x3d, 0xca, 0x13, 0x3a, 0x69, 0x55, 0x56, 0x68, - 0x3a, 0x13, 0xca, 0x40, 0x79, 0xae, 0xdc, 0xae, 0x79, 0x40, 0x03, 0x6b, - 0xdf, 0x2c, 0x5c, 0x4c, 0x30, 0x30, 0x4c, 0x5c, 0x2c, 0xfb, 0xb6, 0x04, - 0x0c, 0x7c, 0xb7, 0x78, 0x3b, 0x3b, 0x78, 0xb7, 0x7c, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x40, 0xff, 0xe3, 0x04, 0x91, 0x05, 0xf0, 0x00, 0x10, - 0x00, 0x44, 0x00, 0x00, 0x00, 0x22, 0x0e, 0x02, 0x14, 0x1e, 0x02, 0x33, - 0x32, 0x3e, 0x02, 0x34, 0x2e, 0x01, 0x27, 0x32, 0x1e, 0x02, 0x15, 0x14, - 0x0e, 0x02, 0x07, 0x1e, 0x03, 0x15, 0x14, 0x0e, 0x02, 0x20, 0x2e, 0x02, - 0x35, 0x33, 0x14, 0x1e, 0x02, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, 0x02, - 0x23, 0x21, 0x35, 0x21, 0x2e, 0x03, 0x35, 0x34, 0x3e, 0x02, 0x02, 0xda, - 0x90, 0x5e, 0x36, 0x16, 0x15, 0x36, 0x5e, 0x49, 0x42, 0x5d, 0x39, 0x1a, - 0x16, 0x36, 0xa6, 0x6a, 0xa8, 0x75, 0x3d, 0x1d, 0x34, 0x4c, 0x2e, 0x44, - 0x63, 0x40, 0x1f, 0x3b, 0x7d, 0xc1, 0xfe, 0xf4, 0xc1, 0x7d, 0x3b, 0xd2, - 0x20, 0x47, 0x73, 0xa6, 0x73, 0x47, 0x20, 0x28, 0x4c, 0x70, 0x49, 0xfd, - 0xae, 0x01, 0x11, 0x20, 0x31, 0x21, 0x11, 0x3d, 0x75, 0xa7, 0x05, 0x4c, - 0x26, 0x41, 0x55, 0x60, 0x59, 0x43, 0x29, 0x29, 0x43, 0x59, 0x60, 0x56, - 0x40, 0xca, 0x3a, 0x69, 0x94, 0x59, 0x3b, 0x66, 0x51, 0x3a, 0x0f, 0x11, - 0x49, 0x62, 0x71, 0x39, 0x5f, 0xac, 0x83, 0x4e, 0x4d, 0x83, 0xac, 0x60, - 0x41, 0x71, 0x55, 0x31, 0x33, 0x56, 0x71, 0x3e, 0x3a, 0x5f, 0x44, 0x25, - 0xaa, 0x11, 0x39, 0x44, 0x48, 0x1f, 0x59, 0x93, 0x6a, 0x3a, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x87, 0x00, 0x00, 0x04, 0x4a, 0x05, 0xd5, 0x00, 0x07, - 0x00, 0x00, 0x01, 0x11, 0x21, 0x15, 0x21, 0x11, 0x23, 0x11, 0x01, 0x52, - 0x02, 0xf8, 0xfd, 0x08, 0xcb, 0x05, 0xd5, 0xfe, 0x8b, 0xaf, 0xfc, 0x4f, - 0x05, 0xd5, 0x00, 0x00, 0x00, 0x03, 0x00, 0x46, 0x00, 0x00, 0x04, 0x8a, - 0x05, 0xd5, 0x00, 0x09, 0x00, 0x13, 0x00, 0x2b, 0x00, 0x00, 0x01, 0x0e, - 0x03, 0x14, 0x1e, 0x02, 0x17, 0x33, 0x3e, 0x03, 0x34, 0x2e, 0x02, 0x27, - 0x03, 0x2e, 0x03, 0x10, 0x3e, 0x02, 0x37, 0x35, 0x33, 0x15, 0x1e, 0x03, - 0x10, 0x0e, 0x02, 0x07, 0x15, 0x23, 0x02, 0x06, 0x49, 0x61, 0x3b, 0x18, - 0x19, 0x3b, 0x61, 0x48, 0xc1, 0x49, 0x62, 0x3a, 0x18, 0x18, 0x3a, 0x62, - 0x49, 0xc1, 0x87, 0xae, 0x65, 0x26, 0x27, 0x65, 0xad, 0x87, 0xc1, 0x87, - 0xae, 0x66, 0x28, 0x28, 0x66, 0xae, 0x87, 0xc1, 0x04, 0xb3, 0x03, 0x2f, - 0x67, 0xa5, 0xf0, 0xa9, 0x6b, 0x32, 0x03, 0x03, 0x33, 0x6b, 0xa8, 0xf0, - 0xa5, 0x67, 0x2f, 0x03, 0xfb, 0xeb, 0x06, 0x57, 0x9b, 0xdc, 0x01, 0x16, - 0xdc, 0x9c, 0x56, 0x05, 0x7a, 0x7a, 0x05, 0x56, 0x9c, 0xdc, 0xfe, 0xea, - 0xdd, 0x9c, 0x57, 0x05, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x33, - 0x00, 0x00, 0x04, 0x9d, 0x05, 0xf0, 0x00, 0x1d, 0x00, 0x2e, 0x00, 0x00, - 0x13, 0x11, 0x34, 0x3e, 0x02, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, - 0x23, 0x22, 0x2e, 0x02, 0x27, 0x11, 0x21, 0x15, 0x21, 0x15, 0x23, 0x35, - 0x23, 0x35, 0x00, 0x22, 0x0e, 0x02, 0x14, 0x1e, 0x02, 0x32, 0x3e, 0x02, - 0x35, 0x34, 0x2e, 0x01, 0xf2, 0x37, 0x73, 0xb2, 0xf6, 0xb1, 0x72, 0x36, - 0x36, 0x72, 0xb1, 0x7b, 0x20, 0x4a, 0x4a, 0x42, 0x17, 0x02, 0xd4, 0xfd, - 0x2c, 0xca, 0xbf, 0x02, 0xe4, 0x9c, 0x67, 0x3e, 0x19, 0x1d, 0x40, 0x69, - 0x98, 0x64, 0x3b, 0x18, 0x18, 0x3c, 0x01, 0xa3, 0x02, 0x95, 0x5f, 0xa1, - 0x76, 0x42, 0x44, 0x76, 0xa2, 0x5e, 0x60, 0xa2, 0x77, 0x43, 0x0d, 0x1b, - 0x2a, 0x1d, 0xfe, 0xba, 0xaf, 0xf4, 0xf4, 0xaf, 0x03, 0xa9, 0x28, 0x48, - 0x66, 0x7c, 0x67, 0x4b, 0x2a, 0x27, 0x48, 0x68, 0x41, 0x3e, 0x66, 0x4a, - 0xff, 0xff, 0x00, 0x75, 0xff, 0xe3, 0x04, 0x5c, 0x05, 0xf0, 0x12, 0x06, - 0x00, 0x32, 0x00, 0x00, 0x00, 0x03, 0x00, 0x47, 0xff, 0xe3, 0x04, 0x8a, - 0x05, 0xd5, 0x00, 0x29, 0x00, 0x33, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x14, - 0x0e, 0x02, 0x07, 0x0e, 0x03, 0x23, 0x22, 0x26, 0x27, 0x2e, 0x03, 0x3d, - 0x01, 0x33, 0x15, 0x14, 0x1e, 0x02, 0x33, 0x11, 0x22, 0x26, 0x35, 0x34, - 0x3e, 0x02, 0x3b, 0x01, 0x11, 0x1e, 0x03, 0x01, 0x35, 0x22, 0x0e, 0x02, - 0x14, 0x1e, 0x02, 0x01, 0x34, 0x2e, 0x02, 0x23, 0x11, 0x32, 0x3e, 0x02, - 0x04, 0x8a, 0x11, 0x2f, 0x50, 0x3f, 0x1f, 0x45, 0x53, 0x62, 0x3b, 0x6c, - 0xa8, 0x3c, 0x43, 0x52, 0x2c, 0x0f, 0xc2, 0x0f, 0x35, 0x64, 0x55, 0xc5, - 0xb4, 0x2c, 0x5e, 0x93, 0x67, 0xb6, 0x7d, 0xac, 0x6b, 0x2f, 0xfd, 0x7c, - 0x2f, 0x43, 0x2a, 0x14, 0x14, 0x2a, 0x43, 0x01, 0xed, 0x11, 0x36, 0x64, - 0x52, 0x52, 0x64, 0x36, 0x11, 0x02, 0x19, 0x54, 0x9d, 0x86, 0x69, 0x21, - 0x10, 0x15, 0x0c, 0x04, 0x18, 0x1d, 0x20, 0x69, 0x87, 0x9d, 0x54, 0x13, - 0x13, 0x5f, 0x96, 0x67, 0x38, 0x03, 0x33, 0x84, 0x8b, 0x45, 0x66, 0x43, - 0x20, 0xfe, 0x8b, 0x06, 0x42, 0x89, 0xd9, 0x01, 0xaa, 0xd1, 0x07, 0x16, - 0x2a, 0x46, 0x29, 0x15, 0x06, 0xfd, 0xb9, 0x6d, 0x9c, 0x64, 0x2f, 0xfc, - 0xd0, 0x35, 0x66, 0x96, 0xff, 0xff, 0x01, 0xdf, 0x03, 0xef, 0x02, 0xf2, - 0x06, 0x14, 0x12, 0x06, 0x02, 0x64, 0x00, 0x00, 0x00, 0x01, 0x01, 0xd6, - 0x03, 0xfe, 0x02, 0xfb, 0x05, 0xd5, 0x00, 0x05, 0x00, 0x00, 0x01, 0x33, - 0x15, 0x03, 0x23, 0x13, 0x02, 0x28, 0xd3, 0xa4, 0x81, 0x52, 0x05, 0xd5, - 0x98, 0xfe, 0xc1, 0x01, 0x3f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x7a, - 0x04, 0xf5, 0x03, 0x59, 0x06, 0x6d, 0x12, 0x06, 0x00, 0x76, 0x9f, 0x07, - 0x00, 0x01, 0x00, 0xe1, 0x04, 0xf1, 0x03, 0xef, 0x07, 0x25, 0x00, 0x15, - 0x00, 0x00, 0x01, 0x23, 0x34, 0x3e, 0x02, 0x37, 0x3e, 0x03, 0x37, 0x33, - 0x14, 0x0e, 0x02, 0x07, 0x0e, 0x03, 0x01, 0x79, 0x98, 0x29, 0x4a, 0x67, - 0x3d, 0x32, 0x79, 0x6a, 0x48, 0x02, 0x98, 0x27, 0x46, 0x5f, 0x37, 0x44, - 0x84, 0x6a, 0x41, 0x04, 0xf1, 0x3c, 0x6c, 0x57, 0x3e, 0x0f, 0x0c, 0x1c, - 0x31, 0x4f, 0x40, 0x3b, 0x6a, 0x56, 0x3e, 0x0f, 0x13, 0x1a, 0x2c, 0x4d, - 0xff, 0xff, 0x01, 0x79, 0x04, 0xee, 0x03, 0x58, 0x06, 0x66, 0x12, 0x06, - 0x00, 0x43, 0x62, 0x00, 0x00, 0x01, 0x00, 0xb2, 0x04, 0xe8, 0x04, 0x1e, - 0x07, 0x15, 0x00, 0x2a, 0x00, 0x00, 0x01, 0x23, 0x34, 0x3e, 0x02, 0x37, - 0x36, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x2e, - 0x02, 0x27, 0x33, 0x1e, 0x01, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, - 0x02, 0x23, 0x22, 0x0f, 0x01, 0x0e, 0x01, 0x01, 0x50, 0x9e, 0x37, 0x64, - 0x8d, 0x56, 0x3d, 0x42, 0x43, 0x84, 0x68, 0x40, 0x22, 0x43, 0x62, 0x40, - 0x2a, 0x51, 0x47, 0x35, 0x0d, 0xa5, 0x06, 0x36, 0x1e, 0x1c, 0x26, 0x17, - 0x0a, 0x1e, 0x34, 0x47, 0x29, 0x32, 0x30, 0x02, 0x82, 0x7d, 0x04, 0xf1, - 0x73, 0xb3, 0x83, 0x56, 0x16, 0x0f, 0x24, 0x4d, 0x76, 0x52, 0x33, 0x59, - 0x42, 0x26, 0x15, 0x30, 0x4b, 0x36, 0x20, 0x1d, 0x11, 0x1c, 0x25, 0x14, - 0x2a, 0x3f, 0x2a, 0x15, 0x0d, 0x01, 0x20, 0xc3, 0x00, 0x01, 0x00, 0xbc, - 0x04, 0xf1, 0x04, 0x14, 0x06, 0x14, 0x00, 0x05, 0x00, 0x00, 0x13, 0x11, - 0x33, 0x15, 0x21, 0x15, 0xbc, 0x8c, 0x02, 0xcc, 0x04, 0xf1, 0x01, 0x23, - 0xa9, 0x7a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x67, 0xff, 0xe5, 0x04, 0x69, - 0x04, 0x60, 0x00, 0x27, 0x00, 0x00, 0x25, 0x0e, 0x01, 0x23, 0x22, 0x2e, - 0x02, 0x35, 0x11, 0x33, 0x11, 0x14, 0x16, 0x17, 0x16, 0x33, 0x32, 0x36, - 0x35, 0x11, 0x33, 0x11, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, - 0x11, 0x33, 0x11, 0x23, 0x35, 0x0e, 0x01, 0x23, 0x22, 0x02, 0x32, 0x22, - 0x68, 0x4b, 0x44, 0x5d, 0x3b, 0x1a, 0xa8, 0x0c, 0x0e, 0x19, 0x48, 0x4f, - 0x3c, 0xa8, 0x1c, 0x1d, 0x4a, 0x49, 0x1c, 0x1d, 0xa7, 0xa7, 0x21, 0x63, - 0x3f, 0x96, 0x72, 0x48, 0x45, 0x2e, 0x71, 0xc0, 0x93, 0x02, 0x89, 0xfd, - 0x7f, 0x77, 0x93, 0x1d, 0x39, 0x7a, 0xe6, 0x02, 0x81, 0xfd, 0x7f, 0xf1, - 0x37, 0x38, 0x3d, 0x3f, 0xe4, 0x02, 0x81, 0xfb, 0xa0, 0x60, 0x3c, 0x3f, - 0x00, 0x01, 0x00, 0xb7, 0xfe, 0x56, 0x04, 0x19, 0x04, 0x7b, 0x00, 0x17, - 0x00, 0x00, 0x01, 0x15, 0x23, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, - 0x11, 0x21, 0x15, 0x21, 0x11, 0x23, 0x11, 0x33, 0x15, 0x3e, 0x01, 0x33, - 0x32, 0x16, 0x04, 0x0f, 0xb9, 0x6a, 0x71, 0x82, 0x8a, 0x02, 0xaa, 0xfd, - 0x56, 0xb8, 0xb8, 0x31, 0xa8, 0x73, 0xac, 0xa8, 0x02, 0xb6, 0xf4, 0xf4, - 0x97, 0x8e, 0xb6, 0xac, 0xfe, 0x16, 0x8f, 0xfe, 0x56, 0x06, 0x0a, 0xa8, - 0x61, 0x62, 0xe0, 0x00, 0x00, 0x02, 0x00, 0x49, 0xfe, 0x56, 0x04, 0x87, - 0x04, 0x77, 0x00, 0x18, 0x00, 0x20, 0x00, 0x00, 0x25, 0x0e, 0x01, 0x23, - 0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x16, 0x17, 0x35, - 0x33, 0x11, 0x33, 0x15, 0x23, 0x11, 0x23, 0x00, 0x10, 0x16, 0x20, 0x36, - 0x10, 0x26, 0x20, 0x03, 0x26, 0x2d, 0x98, 0x66, 0x65, 0xa1, 0x70, 0x3c, - 0x3c, 0x70, 0xa1, 0x65, 0x64, 0x99, 0x2e, 0xb9, 0xa8, 0xa8, 0xb9, 0xfd, - 0xe6, 0x86, 0x01, 0x0c, 0x88, 0x88, 0xfe, 0xf4, 0x8b, 0x54, 0x58, 0x51, - 0x97, 0xd8, 0x88, 0x8a, 0xdb, 0x99, 0x52, 0x56, 0x54, 0x93, 0xfc, 0x2f, - 0x8f, 0xfe, 0x56, 0x04, 0xac, 0xfe, 0x52, 0xd9, 0xda, 0x01, 0xac, 0xda, - 0x00, 0x01, 0x00, 0x72, 0xfe, 0x56, 0x04, 0x5e, 0x04, 0x7b, 0x00, 0x17, - 0x00, 0x00, 0x01, 0x11, 0x33, 0x15, 0x23, 0x11, 0x23, 0x11, 0x34, 0x26, - 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, 0x15, 0x3e, 0x01, 0x33, - 0x32, 0x16, 0x03, 0xca, 0x94, 0x94, 0xb9, 0x6a, 0x71, 0x82, 0x8a, 0xb8, - 0xb8, 0x31, 0xa8, 0x73, 0xac, 0xa8, 0x02, 0xb6, 0xfd, 0xd9, 0x8f, 0xfe, - 0x56, 0x04, 0x60, 0x97, 0x8e, 0xb6, 0xac, 0xfd, 0x87, 0x04, 0x60, 0xa8, - 0x61, 0x62, 0xe0, 0x00, 0x00, 0x01, 0x00, 0xa4, 0xff, 0xe3, 0x04, 0x2d, - 0x06, 0x14, 0x00, 0x17, 0x00, 0x00, 0x13, 0x11, 0x33, 0x11, 0x21, 0x15, - 0x21, 0x11, 0x14, 0x16, 0x33, 0x32, 0x36, 0x3d, 0x01, 0x33, 0x11, 0x23, - 0x35, 0x0e, 0x01, 0x23, 0x22, 0x26, 0xa4, 0xb8, 0x02, 0xd1, 0xfd, 0x2f, - 0x6b, 0x70, 0x83, 0x89, 0xb9, 0xb9, 0x31, 0xa8, 0x72, 0xad, 0xa7, 0x01, - 0xa8, 0x04, 0x6c, 0xfe, 0x4c, 0x8f, 0xfd, 0xd7, 0x97, 0x8e, 0xb6, 0xac, - 0xeb, 0xfd, 0x30, 0xa8, 0x61, 0x64, 0xe0, 0x00, 0x00, 0x02, 0x00, 0x49, - 0xfe, 0x56, 0x04, 0x87, 0x04, 0x77, 0x00, 0x16, 0x00, 0x1e, 0x00, 0x00, - 0x25, 0x0e, 0x01, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, 0x33, - 0x32, 0x16, 0x17, 0x35, 0x33, 0x11, 0x33, 0x15, 0x21, 0x00, 0x10, 0x16, - 0x20, 0x36, 0x10, 0x26, 0x20, 0x03, 0x26, 0x2d, 0x98, 0x66, 0x65, 0xa1, - 0x70, 0x3c, 0x3c, 0x70, 0xa1, 0x65, 0x64, 0x99, 0x2e, 0xb9, 0xa8, 0xfe, - 0x9f, 0xfd, 0xe6, 0x86, 0x01, 0x0c, 0x88, 0x88, 0xfe, 0xf4, 0x8b, 0x54, - 0x58, 0x51, 0x97, 0xd8, 0x88, 0x8a, 0xdb, 0x99, 0x52, 0x56, 0x54, 0x93, - 0xfa, 0x87, 0x91, 0x04, 0xac, 0xfe, 0x52, 0xd9, 0xda, 0x01, 0xac, 0xda, - 0x00, 0x01, 0x00, 0xcf, 0x00, 0x00, 0x04, 0x01, 0x06, 0x14, 0x00, 0x09, - 0x00, 0x00, 0x29, 0x01, 0x11, 0x33, 0x11, 0x21, 0x15, 0x21, 0x11, 0x21, - 0x03, 0xac, 0xfd, 0x23, 0xb8, 0x02, 0x7a, 0xfd, 0x86, 0x02, 0x25, 0x06, - 0x14, 0xfe, 0x4c, 0x8f, 0xfc, 0xc3, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb7, - 0xfe, 0x56, 0x04, 0x19, 0x04, 0x7b, 0x00, 0x15, 0x00, 0x00, 0x01, 0x11, - 0x23, 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x11, 0x21, 0x15, 0x21, - 0x11, 0x33, 0x15, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x04, 0x0f, 0xb9, 0x6a, - 0x71, 0x82, 0x8a, 0x02, 0xaa, 0xfc, 0x9e, 0xb8, 0x31, 0xa8, 0x73, 0xac, - 0xa8, 0x02, 0xb6, 0xfd, 0x4a, 0x02, 0xb6, 0x97, 0x8e, 0xb6, 0xac, 0xfc, - 0x6c, 0x8f, 0x06, 0x0a, 0xa8, 0x61, 0x62, 0xe0, 0x00, 0x02, 0x00, 0x42, - 0xfe, 0x56, 0x04, 0x8e, 0x04, 0x7b, 0x00, 0x2b, 0x00, 0x3b, 0x00, 0x00, - 0x01, 0x2e, 0x03, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x11, 0x23, 0x11, 0x33, - 0x15, 0x3e, 0x03, 0x33, 0x32, 0x1e, 0x02, 0x17, 0x33, 0x15, 0x23, 0x0e, - 0x03, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x11, 0x32, - 0x3e, 0x02, 0x37, 0x23, 0x22, 0x0e, 0x02, 0x15, 0x14, 0x1e, 0x02, 0x03, - 0x7f, 0x02, 0x2c, 0x55, 0x7d, 0x52, 0x4d, 0x73, 0x4c, 0x27, 0xb8, 0xb8, - 0x22, 0x49, 0x55, 0x64, 0x3d, 0x66, 0xa7, 0x77, 0x45, 0x05, 0x65, 0x68, - 0x0b, 0x47, 0x66, 0x7a, 0x3e, 0x48, 0x73, 0x52, 0x2c, 0x35, 0x57, 0x71, - 0x3c, 0x25, 0x41, 0x33, 0x24, 0x07, 0xc4, 0x1a, 0x32, 0x28, 0x19, 0x10, - 0x22, 0x35, 0x02, 0x2f, 0x66, 0xa1, 0x71, 0x3c, 0x2a, 0x5a, 0x8f, 0x65, - 0xfb, 0xeb, 0x06, 0x0a, 0xaa, 0x3a, 0x4c, 0x2d, 0x12, 0x53, 0x99, 0xda, - 0x86, 0x8f, 0x83, 0xab, 0x66, 0x29, 0x27, 0x4a, 0x69, 0x41, 0x4e, 0x73, - 0x4b, 0x25, 0xfe, 0x3c, 0x20, 0x49, 0x76, 0x56, 0x14, 0x29, 0x3d, 0x28, - 0x1e, 0x35, 0x29, 0x17, 0x00, 0x02, 0x00, 0x49, 0xff, 0xe3, 0x04, 0x87, - 0x06, 0x14, 0x00, 0x0f, 0x00, 0x25, 0x00, 0x00, 0x01, 0x21, 0x22, 0x0e, - 0x02, 0x15, 0x14, 0x1e, 0x02, 0x32, 0x3e, 0x02, 0x35, 0x13, 0x11, 0x14, - 0x0e, 0x02, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x21, 0x11, - 0x33, 0x11, 0x33, 0x15, 0x03, 0x26, 0xfe, 0xed, 0x3b, 0x60, 0x46, 0x26, - 0x20, 0x42, 0x65, 0x8a, 0x66, 0x43, 0x20, 0xb9, 0x36, 0x71, 0xaf, 0xf0, - 0xad, 0x6f, 0x34, 0x32, 0x6e, 0xad, 0x7b, 0x01, 0x15, 0xb9, 0xa8, 0x03, - 0xd1, 0x3a, 0x6c, 0x9b, 0x61, 0x65, 0xa0, 0x70, 0x3b, 0x3c, 0x6f, 0xa0, - 0x65, 0x01, 0xa2, 0xfe, 0x28, 0x73, 0xc3, 0x8f, 0x51, 0x58, 0x9d, 0xd7, - 0x80, 0x71, 0xcb, 0x9a, 0x5b, 0x01, 0xb4, 0xfe, 0x4c, 0x8f, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xbc, 0xfe, 0x56, 0x04, 0x14, 0x06, 0x14, 0x00, 0x13, - 0x00, 0x00, 0x21, 0x23, 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x11, - 0x23, 0x11, 0x33, 0x11, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x15, 0x04, 0x14, - 0xb9, 0x6a, 0x71, 0x82, 0x8a, 0xb8, 0xb8, 0x31, 0xa8, 0x73, 0xac, 0xa8, - 0x02, 0xb6, 0x97, 0x8e, 0xb6, 0xac, 0xfb, 0xdd, 0x07, 0xbe, 0xfd, 0xa4, - 0x61, 0x62, 0xe0, 0xe5, 0x00, 0x01, 0x01, 0x47, 0xfe, 0x56, 0x03, 0x8a, - 0x04, 0x60, 0x00, 0x05, 0x00, 0x00, 0x01, 0x21, 0x15, 0x21, 0x11, 0x33, - 0x01, 0xff, 0x01, 0x8b, 0xfd, 0xbd, 0xb8, 0xfe, 0xe5, 0x8f, 0x06, 0x0a, - 0x00, 0x01, 0x00, 0x68, 0xfe, 0x56, 0x04, 0x68, 0x06, 0x14, 0x00, 0x2b, - 0x00, 0x00, 0x01, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x11, - 0x33, 0x11, 0x23, 0x35, 0x0e, 0x01, 0x23, 0x22, 0x2e, 0x02, 0x3d, 0x01, - 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, - 0x11, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x02, 0xbc, 0x1c, 0x1d, - 0x4a, 0x49, 0x1c, 0x1d, 0xa7, 0xa7, 0x21, 0x63, 0x3f, 0x48, 0x5c, 0x33, - 0x13, 0x1c, 0x1d, 0x4a, 0x49, 0x1c, 0x1d, 0xa7, 0xa7, 0x21, 0x63, 0x3f, - 0x48, 0x5c, 0x33, 0x13, 0x01, 0xdf, 0xf1, 0x37, 0x38, 0x3d, 0x3f, 0xe4, - 0x02, 0x81, 0xfb, 0xa0, 0x60, 0x3c, 0x3f, 0x38, 0x6a, 0x9b, 0x63, 0xfc, - 0xf1, 0x37, 0x38, 0x3d, 0x3f, 0xe4, 0xfb, 0xd5, 0x07, 0xbe, 0xfd, 0xec, - 0x3c, 0x3f, 0x38, 0x6a, 0x9b, 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x89, - 0xff, 0xe3, 0x04, 0x48, 0x06, 0x2b, 0x00, 0x1a, 0x00, 0x2f, 0x00, 0x00, - 0x01, 0x15, 0x23, 0x1e, 0x03, 0x15, 0x14, 0x0e, 0x02, 0x22, 0x2e, 0x02, - 0x35, 0x34, 0x3e, 0x02, 0x37, 0x25, 0x13, 0x17, 0x07, 0x05, 0x01, 0x14, - 0x1e, 0x02, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, 0x2e, 0x02, 0x27, 0x23, - 0x22, 0x0e, 0x02, 0x04, 0x45, 0x5a, 0x21, 0x25, 0x13, 0x04, 0x39, 0x77, - 0xb5, 0xf6, 0xb5, 0x76, 0x39, 0x3d, 0x69, 0x8c, 0x50, 0xfe, 0xf1, 0xcf, - 0x94, 0x6a, 0x01, 0x41, 0xfe, 0x14, 0x1e, 0x43, 0x6d, 0x50, 0x4f, 0x6d, - 0x44, 0x1d, 0x06, 0x1b, 0x35, 0x2e, 0x99, 0x4e, 0x6d, 0x44, 0x1f, 0x04, - 0x60, 0xaa, 0x32, 0x6f, 0x6e, 0x66, 0x2a, 0x7a, 0xce, 0x97, 0x55, 0x55, - 0x97, 0xce, 0x7a, 0x87, 0xcb, 0x8d, 0x52, 0x0f, 0xb3, 0x01, 0x21, 0x62, - 0x97, 0xd2, 0xfd, 0xb7, 0x53, 0x95, 0x6f, 0x41, 0x41, 0x6f, 0x95, 0x53, - 0x33, 0x6f, 0x6d, 0x66, 0x2a, 0x42, 0x71, 0x97, 0x00, 0x01, 0x00, 0xbc, - 0xfe, 0x56, 0x04, 0x14, 0x06, 0x14, 0x00, 0x13, 0x00, 0x00, 0x13, 0x33, - 0x11, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x11, 0x33, 0x11, 0x23, 0x11, - 0x0e, 0x01, 0x23, 0x22, 0x26, 0x35, 0xbc, 0xb8, 0x6b, 0x70, 0x83, 0x89, - 0xb9, 0xb9, 0x31, 0xa8, 0x72, 0xad, 0xa7, 0x06, 0x14, 0xfb, 0x94, 0x97, - 0x8e, 0xb6, 0xac, 0x02, 0x7b, 0xf9, 0xf6, 0x02, 0x52, 0x61, 0x64, 0xe0, - 0xe5, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xbd, 0x00, 0x00, 0x04, 0x15, - 0x06, 0x14, 0x12, 0x06, 0x00, 0x4b, 0xfa, 0x00, 0x00, 0x02, 0x00, 0xab, - 0xff, 0xe2, 0x04, 0x25, 0x06, 0x14, 0x00, 0x2f, 0x00, 0x44, 0x00, 0x00, - 0x01, 0x15, 0x0e, 0x01, 0x07, 0x1e, 0x03, 0x15, 0x11, 0x23, 0x35, 0x0e, - 0x03, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x12, 0x37, 0x2e, 0x03, 0x35, - 0x34, 0x36, 0x3f, 0x01, 0x33, 0x07, 0x06, 0x15, 0x14, 0x1e, 0x02, 0x33, - 0x32, 0x37, 0x3e, 0x01, 0x01, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x3e, 0x02, - 0x3d, 0x01, 0x34, 0x2e, 0x02, 0x27, 0x0e, 0x03, 0x03, 0x44, 0x15, 0x29, - 0x15, 0x5a, 0x77, 0x47, 0x1c, 0xb8, 0x14, 0x3f, 0x55, 0x68, 0x3b, 0x59, - 0x8b, 0x60, 0x33, 0xc4, 0xb6, 0x39, 0x54, 0x38, 0x1b, 0x11, 0x12, 0x33, - 0xc7, 0x39, 0x20, 0x14, 0x24, 0x32, 0x1f, 0x22, 0x20, 0x1b, 0x38, 0xfe, - 0x43, 0x1b, 0x39, 0x57, 0x3d, 0x4d, 0x6c, 0x43, 0x1f, 0x14, 0x36, 0x5f, - 0x4b, 0x39, 0x63, 0x49, 0x2a, 0x05, 0x2c, 0xb1, 0x0d, 0x1b, 0x0e, 0x35, - 0x7e, 0x92, 0xa4, 0x5b, 0xfd, 0xff, 0xac, 0x2c, 0x4a, 0x36, 0x1e, 0x42, - 0x76, 0xa6, 0x65, 0xc1, 0x01, 0x60, 0x9b, 0x07, 0x2d, 0x3f, 0x4e, 0x28, - 0x20, 0x3f, 0x1c, 0x4f, 0x55, 0x30, 0x31, 0x1b, 0x30, 0x24, 0x15, 0x0b, - 0x12, 0x24, 0xfc, 0xaa, 0x45, 0x76, 0x56, 0x31, 0x37, 0x5d, 0x7b, 0x44, - 0x56, 0x33, 0x79, 0x77, 0x6c, 0x27, 0x35, 0x7b, 0x89, 0x95, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x72, 0xfe, 0x56, 0x04, 0x5f, 0x04, 0x7b, 0x00, 0x15, - 0x00, 0x00, 0x01, 0x11, 0x33, 0x15, 0x21, 0x11, 0x34, 0x26, 0x23, 0x22, - 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, 0x15, 0x3e, 0x01, 0x33, 0x32, 0x16, - 0x03, 0xca, 0x95, 0xfe, 0xb2, 0x6a, 0x71, 0x82, 0x8a, 0xb8, 0xb8, 0x31, - 0xa8, 0x73, 0xac, 0xa8, 0x02, 0xb6, 0xfc, 0x2f, 0x8f, 0x04, 0x60, 0x97, - 0x8e, 0xb6, 0xac, 0xfd, 0x87, 0x04, 0x60, 0xa8, 0x61, 0x62, 0xe0, 0x00, - 0x00, 0x02, 0x00, 0x9f, 0xff, 0xe3, 0x04, 0x32, 0x06, 0x14, 0x00, 0x2a, - 0x00, 0x3d, 0x00, 0x00, 0x01, 0x32, 0x1e, 0x02, 0x17, 0x15, 0x2e, 0x01, - 0x23, 0x22, 0x0e, 0x02, 0x07, 0x1e, 0x03, 0x15, 0x11, 0x23, 0x35, 0x0e, - 0x03, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x12, 0x37, 0x23, 0x35, 0x33, - 0x3e, 0x03, 0x01, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x3e, 0x02, 0x3d, 0x01, - 0x34, 0x2e, 0x02, 0x27, 0x06, 0x02, 0x03, 0xc5, 0x0a, 0x19, 0x18, 0x13, - 0x06, 0x14, 0x38, 0x1a, 0x36, 0x6a, 0x64, 0x5d, 0x28, 0x78, 0xc0, 0x87, - 0x49, 0xb8, 0x18, 0x3f, 0x51, 0x66, 0x3e, 0x5c, 0x88, 0x5b, 0x2d, 0x38, - 0x36, 0x91, 0xd2, 0x32, 0x7d, 0x96, 0xad, 0xfe, 0x18, 0x27, 0x43, 0x58, - 0x30, 0x4b, 0x67, 0x3f, 0x1c, 0x2d, 0x62, 0x9a, 0x6d, 0x31, 0x38, 0x06, - 0x14, 0x02, 0x03, 0x04, 0x02, 0x97, 0x09, 0x0a, 0x2a, 0x4d, 0x6e, 0x44, - 0x0a, 0x4f, 0x86, 0xb7, 0x72, 0xfd, 0xac, 0xa8, 0x2c, 0x48, 0x34, 0x1d, - 0x40, 0x71, 0x9a, 0x5a, 0x92, 0x01, 0x2b, 0x8c, 0x8f, 0x5e, 0xa0, 0x75, - 0x41, 0xfb, 0x9f, 0x58, 0x75, 0x46, 0x1d, 0x3c, 0x61, 0x79, 0x3d, 0x8b, - 0x4c, 0x81, 0x60, 0x3a, 0x07, 0x76, 0xfe, 0xee, 0x00, 0x01, 0x00, 0x68, - 0xff, 0xe3, 0x04, 0x68, 0x06, 0x14, 0x00, 0x15, 0x00, 0x00, 0x13, 0x11, - 0x33, 0x11, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x11, 0x21, 0x15, 0x23, - 0x11, 0x23, 0x35, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x68, 0xb8, 0x6b, 0x70, - 0x83, 0x89, 0x01, 0x61, 0xa8, 0xb9, 0x31, 0xa8, 0x72, 0xad, 0xa7, 0x01, - 0xa8, 0x02, 0xb8, 0xfd, 0x48, 0x97, 0x8e, 0xb6, 0xac, 0x04, 0x2f, 0x8f, - 0xfa, 0x7b, 0xa8, 0x61, 0x64, 0xe0, 0x00, 0x00, 0x00, 0x01, 0x01, 0x3d, - 0xfe, 0x56, 0x03, 0x93, 0x04, 0x60, 0x00, 0x0a, 0x00, 0x00, 0x01, 0x33, - 0x11, 0x14, 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x35, 0x02, 0xdb, 0xb8, - 0xb2, 0xa6, 0xfe, 0xea, 0xb4, 0x04, 0x60, 0xfb, 0x8c, 0xc4, 0xd2, 0x9c, - 0xfa, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x68, 0xff, 0xe3, 0x04, 0x68, - 0x06, 0x14, 0x00, 0x15, 0x00, 0x00, 0x01, 0x11, 0x23, 0x35, 0x21, 0x11, - 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x11, 0x33, 0x11, 0x23, 0x35, 0x0e, - 0x01, 0x23, 0x22, 0x26, 0x01, 0x10, 0xa8, 0x01, 0x60, 0x6b, 0x70, 0x83, - 0x89, 0xb9, 0xb9, 0x31, 0xa8, 0x72, 0xad, 0xa7, 0x01, 0xa8, 0x03, 0xdd, - 0x8f, 0xfb, 0x94, 0x97, 0x8e, 0xb6, 0xac, 0x02, 0x7b, 0xfb, 0xa0, 0xa8, - 0x61, 0x64, 0xe0, 0x00, 0x00, 0x01, 0x00, 0xad, 0xfe, 0x56, 0x04, 0x23, - 0x04, 0x7c, 0x00, 0x31, 0x00, 0x00, 0x05, 0x14, 0x1e, 0x02, 0x33, 0x21, - 0x15, 0x21, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x06, 0x35, 0x34, 0x2e, - 0x02, 0x23, 0x22, 0x0e, 0x02, 0x07, 0x27, 0x3e, 0x01, 0x33, 0x32, 0x1e, - 0x02, 0x15, 0x14, 0x0e, 0x06, 0x01, 0x81, 0x07, 0x14, 0x20, 0x1a, 0x02, - 0x1b, 0xfd, 0x74, 0x2a, 0x44, 0x30, 0x1a, 0x3c, 0x63, 0x7e, 0x84, 0x7e, - 0x63, 0x3c, 0x27, 0x4b, 0x6d, 0x47, 0x23, 0x49, 0x45, 0x3d, 0x16, 0x88, - 0x45, 0xce, 0x81, 0x6a, 0xae, 0x7b, 0x43, 0x3a, 0x5f, 0x79, 0x7e, 0x79, - 0x5f, 0x3a, 0xcf, 0x08, 0x1a, 0x18, 0x12, 0x8f, 0x1b, 0x2f, 0x3f, 0x24, - 0x32, 0x6d, 0x73, 0x7a, 0x7e, 0x83, 0x85, 0x87, 0x44, 0x3b, 0x60, 0x43, - 0x24, 0x13, 0x25, 0x36, 0x22, 0x65, 0x5a, 0x6b, 0x37, 0x69, 0x99, 0x63, - 0x4b, 0x95, 0x90, 0x89, 0x7e, 0x71, 0x60, 0x4c, 0xff, 0xff, 0x00, 0xbd, - 0x00, 0x00, 0x04, 0x15, 0x04, 0x7b, 0x12, 0x06, 0x00, 0x51, 0xfa, 0x00, - 0x00, 0x01, 0x00, 0xf2, 0xfe, 0x56, 0x03, 0xde, 0x04, 0x92, 0x00, 0x2f, - 0x00, 0x00, 0x01, 0x21, 0x15, 0x21, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, - 0x04, 0x37, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x36, 0x3f, 0x01, 0x17, 0x07, - 0x0e, 0x01, 0x15, 0x14, 0x1e, 0x02, 0x33, 0x32, 0x36, 0x37, 0x17, 0x0e, - 0x03, 0x15, 0x14, 0x1e, 0x02, 0x02, 0x0f, 0x01, 0xcf, 0xfd, 0xbe, 0x23, - 0x3d, 0x2f, 0x1b, 0x22, 0x3c, 0x52, 0x60, 0x6b, 0x36, 0x2d, 0x6d, 0x60, - 0x41, 0x31, 0x37, 0x5f, 0x7b, 0x1f, 0x2d, 0x3d, 0x29, 0x42, 0x51, 0x27, - 0x23, 0x3e, 0x17, 0x3f, 0x70, 0xbd, 0x8a, 0x4d, 0x0c, 0x17, 0x20, 0xfe, - 0xe5, 0x8f, 0x15, 0x2b, 0x41, 0x2c, 0x3a, 0x88, 0x90, 0x93, 0x8b, 0x80, - 0x34, 0x20, 0x45, 0x6c, 0x4c, 0x3c, 0x7b, 0x37, 0x60, 0x71, 0x1e, 0x2c, - 0x60, 0x2f, 0x27, 0x38, 0x25, 0x11, 0x0b, 0x09, 0x71, 0x5a, 0xd7, 0xd5, - 0xbe, 0x41, 0x15, 0x27, 0x1e, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x67, - 0xfe, 0x56, 0x04, 0x69, 0x04, 0x60, 0x00, 0x27, 0x00, 0x00, 0x25, 0x0e, - 0x01, 0x23, 0x22, 0x2e, 0x02, 0x35, 0x11, 0x33, 0x11, 0x14, 0x16, 0x17, - 0x16, 0x33, 0x32, 0x36, 0x35, 0x11, 0x33, 0x11, 0x14, 0x17, 0x16, 0x33, - 0x32, 0x37, 0x36, 0x35, 0x11, 0x33, 0x11, 0x23, 0x11, 0x0e, 0x01, 0x23, - 0x22, 0x02, 0x32, 0x22, 0x68, 0x4b, 0x44, 0x5d, 0x3b, 0x1a, 0xa8, 0x0c, - 0x0e, 0x19, 0x48, 0x4f, 0x3c, 0xa8, 0x1c, 0x1d, 0x4a, 0x49, 0x1c, 0x1d, - 0xa7, 0xa7, 0x21, 0x63, 0x3f, 0x96, 0x72, 0x48, 0x45, 0x2e, 0x71, 0xc0, - 0x93, 0x02, 0x89, 0xfd, 0x7f, 0x77, 0x93, 0x1d, 0x39, 0x7a, 0xe6, 0x02, - 0x81, 0xfd, 0x7f, 0xf1, 0x37, 0x38, 0x3d, 0x3f, 0xe4, 0x02, 0x81, 0xf9, - 0xf6, 0x02, 0x0a, 0x3c, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xa8, - 0xfe, 0x56, 0x04, 0x29, 0x04, 0x7c, 0x00, 0x2e, 0x00, 0x46, 0x00, 0x00, - 0x01, 0x14, 0x0e, 0x06, 0x15, 0x14, 0x1e, 0x02, 0x33, 0x21, 0x15, 0x21, - 0x22, 0x2e, 0x02, 0x35, 0x34, 0x36, 0x37, 0x3e, 0x03, 0x35, 0x34, 0x2e, - 0x04, 0x35, 0x34, 0x3e, 0x02, 0x33, 0x32, 0x1e, 0x02, 0x25, 0x22, 0x0e, - 0x02, 0x15, 0x14, 0x1e, 0x04, 0x15, 0x14, 0x07, 0x3e, 0x03, 0x35, 0x34, - 0x2e, 0x02, 0x04, 0x29, 0x3a, 0x5f, 0x79, 0x7e, 0x79, 0x5f, 0x3a, 0x13, - 0x1a, 0x1d, 0x0b, 0x02, 0x1b, 0xfd, 0x74, 0x26, 0x43, 0x31, 0x1d, 0x52, - 0x48, 0x1d, 0x20, 0x10, 0x03, 0x24, 0x37, 0x40, 0x37, 0x24, 0x49, 0x78, - 0x9a, 0x50, 0x66, 0xad, 0x7d, 0x46, 0xfe, 0x2a, 0x2b, 0x56, 0x44, 0x2a, - 0x1f, 0x2d, 0x36, 0x2d, 0x1f, 0x32, 0x3f, 0x83, 0x6b, 0x44, 0x29, 0x4b, - 0x69, 0x02, 0xeb, 0x4f, 0x9a, 0x91, 0x89, 0x7d, 0x70, 0x5f, 0x4e, 0x1d, - 0x16, 0x1d, 0x12, 0x07, 0x8f, 0x19, 0x2b, 0x39, 0x20, 0x42, 0x90, 0x49, - 0x1d, 0x3b, 0x3d, 0x40, 0x23, 0x35, 0x5a, 0x52, 0x4c, 0x51, 0x59, 0x34, - 0x4f, 0x86, 0x60, 0x36, 0x35, 0x67, 0x95, 0x97, 0x1b, 0x34, 0x4e, 0x33, - 0x21, 0x41, 0x44, 0x46, 0x4c, 0x52, 0x2c, 0x51, 0x4f, 0x3d, 0x82, 0x89, - 0x91, 0x4b, 0x3f, 0x60, 0x42, 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x84, - 0x00, 0x00, 0x04, 0x4d, 0x04, 0x7b, 0x00, 0x24, 0x00, 0x00, 0x01, 0x22, - 0x0e, 0x02, 0x15, 0x11, 0x23, 0x11, 0x33, 0x15, 0x3e, 0x01, 0x33, 0x32, - 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, 0x07, 0x21, 0x15, 0x21, 0x35, 0x3e, - 0x03, 0x35, 0x34, 0x2e, 0x02, 0x02, 0x3b, 0x3e, 0x60, 0x40, 0x21, 0xb8, - 0xb8, 0x31, 0xa2, 0x79, 0x63, 0x8e, 0x5a, 0x2b, 0x1c, 0x37, 0x52, 0x35, - 0x01, 0x29, 0xfd, 0xfd, 0x3f, 0x5c, 0x3c, 0x1d, 0x1a, 0x3d, 0x63, 0x03, - 0xdb, 0x34, 0x5a, 0x7a, 0x46, 0xfd, 0x73, 0x04, 0x60, 0xac, 0x64, 0x63, - 0x46, 0x7d, 0xae, 0x67, 0x53, 0x90, 0x82, 0x76, 0x39, 0x8f, 0x84, 0x34, - 0x6d, 0x79, 0x8a, 0x50, 0x49, 0x81, 0x61, 0x38, 0xff, 0xff, 0x00, 0xbd, - 0xff, 0xe3, 0x04, 0x15, 0x04, 0x5e, 0x12, 0x06, 0x00, 0x58, 0xfa, 0x00, - 0x00, 0x01, 0x00, 0x66, 0xfe, 0x56, 0x04, 0x6a, 0x06, 0x14, 0x00, 0x15, - 0x00, 0x00, 0x13, 0x11, 0x33, 0x11, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, - 0x11, 0x33, 0x11, 0x33, 0x15, 0x21, 0x11, 0x0e, 0x01, 0x23, 0x22, 0x26, - 0x66, 0xb8, 0x6b, 0x70, 0x83, 0x89, 0xb9, 0xac, 0xfe, 0x9b, 0x31, 0xa8, - 0x72, 0xad, 0xa7, 0x01, 0xa8, 0x02, 0xb8, 0xfd, 0x48, 0x97, 0x8e, 0xb6, - 0xac, 0x04, 0x2f, 0xf8, 0xd3, 0x91, 0x02, 0x52, 0x61, 0x64, 0xe0, 0x00, - 0x00, 0x01, 0x00, 0x68, 0xff, 0xe5, 0x04, 0x69, 0x04, 0x7b, 0x00, 0x2c, - 0x00, 0x00, 0x21, 0x23, 0x11, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x0e, - 0x01, 0x15, 0x11, 0x23, 0x35, 0x0e, 0x01, 0x23, 0x22, 0x2e, 0x02, 0x35, - 0x11, 0x33, 0x11, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x11, - 0x33, 0x15, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x02, 0x15, 0x04, 0x69, 0xa8, - 0x1c, 0x1d, 0x4a, 0x49, 0x1c, 0x0d, 0x10, 0xa7, 0x21, 0x63, 0x3f, 0x47, - 0x5b, 0x34, 0x14, 0xa8, 0x1c, 0x1d, 0x4a, 0x49, 0x1c, 0x1d, 0xa7, 0x21, - 0x63, 0x3f, 0x47, 0x5b, 0x34, 0x14, 0x02, 0x81, 0xf1, 0x37, 0x38, 0x3d, - 0x1d, 0x80, 0x65, 0xfd, 0x5e, 0x60, 0x3c, 0x3f, 0x36, 0x6a, 0x9d, 0x67, - 0x02, 0xd7, 0xfd, 0x7f, 0xf1, 0x37, 0x38, 0x3d, 0x3f, 0xe4, 0x02, 0x81, - 0x60, 0x3c, 0x3f, 0x36, 0x6a, 0x9d, 0x67, 0x00, 0x00, 0x01, 0x00, 0xbc, - 0xfe, 0x56, 0x04, 0x14, 0x04, 0x7b, 0x00, 0x13, 0x00, 0x00, 0x01, 0x11, - 0x23, 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, - 0x15, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x04, 0x14, 0xb9, 0x6a, 0x71, 0x82, - 0x8a, 0xb8, 0xb8, 0x31, 0xa8, 0x73, 0xac, 0xa8, 0x02, 0xb6, 0xfd, 0x4a, - 0x02, 0xb6, 0x97, 0x8e, 0xb6, 0xac, 0xfb, 0xdd, 0x06, 0x0a, 0xa8, 0x61, - 0x62, 0xe0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x9d, 0xfe, 0x48, 0x04, 0x34, - 0x04, 0x7b, 0x12, 0x06, 0x00, 0x4a, 0x22, 0x00, 0x00, 0x01, 0x00, 0xf9, - 0x00, 0x00, 0x03, 0xd7, 0x04, 0x60, 0x00, 0x05, 0x00, 0x00, 0x25, 0x21, - 0x15, 0x21, 0x11, 0x33, 0x01, 0xb1, 0x02, 0x26, 0xfd, 0x22, 0xb8, 0x8f, - 0x8f, 0x04, 0x60, 0x00, 0x00, 0x01, 0x00, 0x68, 0xfe, 0x56, 0x04, 0x69, - 0x06, 0x14, 0x00, 0x2c, 0x00, 0x00, 0x21, 0x23, 0x11, 0x34, 0x27, 0x26, - 0x23, 0x22, 0x07, 0x0e, 0x01, 0x15, 0x11, 0x23, 0x11, 0x0e, 0x01, 0x23, - 0x22, 0x2e, 0x02, 0x35, 0x11, 0x33, 0x11, 0x14, 0x17, 0x16, 0x33, 0x32, - 0x37, 0x36, 0x35, 0x11, 0x33, 0x11, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x02, - 0x15, 0x04, 0x69, 0xa8, 0x1c, 0x1d, 0x4a, 0x49, 0x1c, 0x0d, 0x10, 0xa7, - 0x21, 0x63, 0x3f, 0x47, 0x5b, 0x34, 0x14, 0xa8, 0x1c, 0x1d, 0x4a, 0x49, - 0x1c, 0x1d, 0xa7, 0x21, 0x63, 0x3f, 0x47, 0x5b, 0x34, 0x14, 0x02, 0x81, - 0xf1, 0x37, 0x38, 0x3d, 0x1d, 0x80, 0x65, 0xfb, 0xb4, 0x02, 0x0a, 0x3c, - 0x3f, 0x36, 0x6a, 0x9d, 0x67, 0x02, 0xd7, 0xfd, 0x7f, 0xf1, 0x37, 0x38, - 0x3d, 0x3f, 0xe4, 0x04, 0x35, 0xfd, 0xec, 0x3c, 0x3f, 0x36, 0x6a, 0x9d, - 0x67, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x57, 0xfe, 0x56, 0x04, 0x7a, - 0x04, 0x7b, 0x00, 0x1c, 0x00, 0x26, 0x00, 0x00, 0x25, 0x11, 0x21, 0x15, - 0x21, 0x15, 0x23, 0x35, 0x23, 0x35, 0x33, 0x11, 0x33, 0x15, 0x3e, 0x01, - 0x33, 0x32, 0x1e, 0x02, 0x15, 0x14, 0x0e, 0x02, 0x23, 0x22, 0x26, 0x00, - 0x10, 0x26, 0x23, 0x22, 0x06, 0x10, 0x16, 0x33, 0x32, 0x01, 0x88, 0x02, - 0xf2, 0xfd, 0x0e, 0xb9, 0x78, 0x78, 0xb9, 0x2e, 0x99, 0x64, 0x65, 0xa1, - 0x70, 0x3c, 0x3b, 0x70, 0xa1, 0x66, 0x67, 0x97, 0x01, 0xef, 0x86, 0x86, - 0x87, 0x89, 0x89, 0x87, 0x86, 0x8d, 0xfe, 0xbb, 0x8f, 0x63, 0x63, 0x8f, - 0x05, 0x18, 0x8f, 0x54, 0x56, 0x52, 0x99, 0xdb, 0x8a, 0x87, 0xd9, 0x97, - 0x51, 0x56, 0x01, 0x1f, 0x01, 0xae, 0xd9, 0xda, 0xfe, 0x54, 0xda, 0x00, - 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, 0x04, 0x7b, 0x12, 0x06, - 0x00, 0x52, 0x00, 0x00, 0x00, 0x03, 0x00, 0x28, 0xfe, 0x56, 0x04, 0xa8, - 0x06, 0x14, 0x00, 0x24, 0x00, 0x2b, 0x00, 0x36, 0x00, 0x00, 0x01, 0x14, - 0x0e, 0x02, 0x23, 0x11, 0x23, 0x11, 0x22, 0x2e, 0x02, 0x27, 0x37, 0x1e, - 0x03, 0x33, 0x11, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x3e, 0x02, 0x3b, 0x01, - 0x11, 0x32, 0x1e, 0x02, 0x01, 0x11, 0x22, 0x06, 0x15, 0x14, 0x16, 0x01, - 0x34, 0x2e, 0x02, 0x23, 0x11, 0x32, 0x3e, 0x02, 0x04, 0xa8, 0x38, 0x7a, - 0xc3, 0x8b, 0xb8, 0x4b, 0x80, 0x6e, 0x62, 0x2d, 0x7b, 0x21, 0x47, 0x50, - 0x5d, 0x38, 0x62, 0x9b, 0x6e, 0x3a, 0x3a, 0x6f, 0x9f, 0x66, 0xaf, 0x8a, - 0xc2, 0x7b, 0x39, 0xfd, 0x48, 0x7d, 0x74, 0x7b, 0x02, 0x79, 0x1d, 0x4b, - 0x80, 0x63, 0x5e, 0x7f, 0x4d, 0x21, 0x02, 0x43, 0x82, 0xd7, 0x9a, 0x55, - 0xfe, 0x5b, 0x01, 0xa5, 0x1e, 0x37, 0x50, 0x32, 0x80, 0x2c, 0x4a, 0x35, - 0x1d, 0x03, 0x2e, 0x2d, 0x50, 0x70, 0x43, 0x48, 0x70, 0x4d, 0x27, 0xfe, - 0x47, 0x48, 0x89, 0xc8, 0x01, 0x99, 0x01, 0x2b, 0x4f, 0x48, 0x42, 0x52, - 0xfd, 0xe5, 0x5a, 0x8c, 0x60, 0x32, 0xfc, 0xd2, 0x42, 0x75, 0xa1, 0x00, - 0x00, 0x01, 0x00, 0x48, 0xff, 0xe3, 0x04, 0x88, 0x06, 0x14, 0x00, 0x15, - 0x00, 0x00, 0x13, 0x11, 0x33, 0x11, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, - 0x11, 0x33, 0x11, 0x33, 0x15, 0x21, 0x35, 0x0e, 0x01, 0x23, 0x22, 0x26, - 0x48, 0xb8, 0x6b, 0x70, 0x83, 0x89, 0xb9, 0xe8, 0xfe, 0x5f, 0x31, 0xa8, - 0x72, 0xad, 0xa7, 0x01, 0xa8, 0x04, 0x6c, 0xfb, 0x94, 0x97, 0x8e, 0xb6, - 0xac, 0x02, 0x7b, 0xfc, 0x2f, 0x8f, 0xa8, 0x61, 0x64, 0xe0, 0x00, 0x00, - 0x00, 0x02, 0x01, 0xff, 0x00, 0x00, 0x02, 0xd2, 0x03, 0x52, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x00, 0x25, 0x33, 0x15, 0x23, 0x11, 0x33, 0x15, 0x23, - 0x01, 0xff, 0xd3, 0xd3, 0xd3, 0xd3, 0xfe, 0xfe, 0x03, 0x52, 0xfe, 0x00, - 0x00, 0x01, 0x01, 0x64, 0x01, 0xa4, 0x03, 0x6d, 0x02, 0x83, 0x00, 0x07, - 0x00, 0x00, 0x01, 0x16, 0x24, 0x37, 0x15, 0x06, 0x04, 0x27, 0x01, 0x64, - 0x83, 0x01, 0x02, 0x84, 0x83, 0xfe, 0xfc, 0x82, 0x02, 0x83, 0x3f, 0x06, - 0x39, 0xa4, 0x38, 0x06, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x31, - 0xff, 0xd9, 0x04, 0x96, 0x07, 0x22, 0x00, 0x24, 0x00, 0x2f, 0x00, 0x00, - 0x01, 0x16, 0x17, 0x16, 0x15, 0x23, 0x34, 0x27, 0x26, 0x27, 0x33, 0x16, - 0x17, 0x16, 0x37, 0x36, 0x37, 0x36, 0x35, 0x33, 0x14, 0x17, 0x16, 0x17, - 0x16, 0x36, 0x35, 0x33, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x06, 0x07, - 0x06, 0x01, 0x27, 0x03, 0x23, 0x01, 0x23, 0x35, 0x33, 0x01, 0x13, 0x05, - 0x02, 0x97, 0x0f, 0x0a, 0x15, 0x72, 0x18, 0x1f, 0x61, 0x7b, 0x1e, 0x19, - 0x0c, 0x1e, 0x2e, 0x05, 0x03, 0x72, 0x09, 0x0d, 0x1d, 0x26, 0x12, 0x71, - 0x19, 0x2c, 0x62, 0x53, 0x15, 0x20, 0x21, 0x1d, 0x01, 0xbf, 0x9e, 0xf6, - 0x7f, 0xfe, 0x06, 0x2f, 0x94, 0x01, 0xd3, 0xdb, 0x01, 0x23, 0x06, 0x16, - 0x31, 0x32, 0x6a, 0xff, 0xee, 0x7b, 0xa2, 0xcd, 0x40, 0x45, 0x23, 0x04, - 0x07, 0x24, 0x1c, 0x5d, 0x7c, 0x0e, 0x15, 0x01, 0x01, 0x30, 0x71, 0xab, - 0x21, 0x3c, 0x22, 0x1c, 0x07, 0x05, 0xfc, 0xc9, 0x35, 0xfc, 0xc7, 0x06, - 0x44, 0x83, 0xfa, 0x41, 0x02, 0xdb, 0x62, 0x00, 0x00, 0x02, 0x00, 0x31, - 0xff, 0xd9, 0x04, 0x96, 0x07, 0x29, 0x00, 0x2a, 0x00, 0x35, 0x00, 0x00, - 0x01, 0x15, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x15, 0x22, - 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x15, - 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, - 0x26, 0x27, 0x26, 0x27, 0x26, 0x37, 0x36, 0x01, 0x27, 0x03, 0x23, 0x01, - 0x23, 0x35, 0x33, 0x01, 0x13, 0x05, 0x03, 0x7c, 0x4c, 0x41, 0x56, 0x3a, - 0x32, 0x31, 0x38, 0x55, 0x47, 0x1e, 0x26, 0x2f, 0x3d, 0x38, 0x4f, 0x36, - 0x2d, 0x4e, 0x40, 0x3f, 0x5f, 0x46, 0x3f, 0x44, 0x28, 0x37, 0x2d, 0x1c, - 0x22, 0x01, 0x01, 0x8e, 0x47, 0x01, 0x71, 0x9e, 0xf6, 0x7f, 0xfe, 0x06, - 0x2f, 0x94, 0x01, 0xd3, 0xdb, 0x01, 0x23, 0x07, 0x29, 0x5e, 0x0a, 0x1d, - 0x25, 0x24, 0x14, 0x20, 0x1b, 0x02, 0x5c, 0x2a, 0x24, 0x40, 0x2e, 0x21, - 0x2a, 0x0d, 0x12, 0x18, 0x6e, 0x14, 0x10, 0x0d, 0x46, 0x3f, 0x5c, 0x4b, - 0x48, 0x2a, 0x0e, 0x12, 0x1b, 0x20, 0x23, 0x54, 0x48, 0x23, 0xfb, 0xc3, - 0x35, 0xfc, 0xc7, 0x06, 0x44, 0x83, 0xfa, 0x41, 0x02, 0xdb, 0x62, 0x00, - 0x00, 0x04, 0x00, 0x5a, 0x00, 0x00, 0x04, 0x77, 0x05, 0x14, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x00, 0x25, 0x33, 0x15, 0x23, - 0x25, 0x33, 0x15, 0x23, 0x01, 0x33, 0x15, 0x23, 0x25, 0x33, 0x01, 0x23, - 0x03, 0xc3, 0xb4, 0xb4, 0xfe, 0x98, 0xb4, 0xb4, 0xfe, 0x0d, 0xb4, 0xb4, - 0x02, 0x94, 0xa0, 0xfd, 0x5e, 0xa0, 0xfa, 0xfa, 0xfa, 0xfa, 0x05, 0x14, - 0xfa, 0xfa, 0xfa, 0xec, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd1, - 0x05, 0x14, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x13, - 0x00, 0x00, 0x25, 0x33, 0x15, 0x23, 0x25, 0x33, 0x15, 0x23, 0x25, 0x33, - 0x15, 0x23, 0x01, 0x33, 0x15, 0x23, 0x25, 0x33, 0x01, 0x23, 0x04, 0x1d, - 0xb4, 0xb4, 0xfe, 0xb6, 0xb4, 0xb4, 0xfe, 0xb6, 0xb4, 0xb4, 0xfe, 0x85, - 0xb4, 0xb4, 0x01, 0xcc, 0xa0, 0xfe, 0x26, 0xa0, 0xfa, 0xfa, 0xfa, 0xfa, - 0xfa, 0xfa, 0x05, 0x14, 0xfa, 0xfa, 0xfa, 0xec, 0x00, 0x01, 0x01, 0xd6, - 0x00, 0x00, 0x02, 0xfb, 0x01, 0xec, 0x00, 0x05, 0x00, 0x00, 0x21, 0x23, - 0x35, 0x13, 0x33, 0x03, 0x02, 0xa9, 0xd3, 0xa4, 0x81, 0x52, 0xac, 0x01, - 0x40, 0xfe, 0xc0, 0x00, 0x00, 0x02, 0x01, 0x64, 0x04, 0xfd, 0x03, 0x6d, - 0x06, 0xf1, 0x00, 0x0a, 0x00, 0x1b, 0x00, 0x00, 0x01, 0x33, 0x32, 0x37, - 0x36, 0x35, 0x34, 0x27, 0x06, 0x07, 0x06, 0x17, 0x2b, 0x01, 0x35, 0x33, - 0x11, 0x33, 0x11, 0x36, 0x37, 0x36, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, - 0x02, 0x35, 0x37, 0x4d, 0x17, 0x35, 0x1e, 0x0f, 0x39, 0x33, 0x17, 0xaf, - 0x70, 0x51, 0x66, 0x24, 0x68, 0x3f, 0x46, 0x41, 0x40, 0x36, 0x05, 0x62, - 0x0d, 0x21, 0x15, 0x1f, 0x10, 0x04, 0x16, 0x14, 0xa9, 0x65, 0x01, 0x8f, - 0xfe, 0xbf, 0x49, 0x28, 0x18, 0x1a, 0x19, 0x52, 0x5b, 0x32, 0x2a, 0x00, - 0x00, 0x02, 0x01, 0xd6, 0x00, 0x00, 0x02, 0xfb, 0x05, 0x11, 0x00, 0x05, - 0x00, 0x09, 0x00, 0x00, 0x01, 0x23, 0x35, 0x13, 0x33, 0x0b, 0x01, 0x33, - 0x15, 0x23, 0x02, 0xa9, 0xd3, 0xa4, 0x81, 0x52, 0xd3, 0xd3, 0xd3, 0x03, - 0x25, 0xac, 0x01, 0x40, 0xfe, 0xc0, 0xfd, 0x2d, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0xda, 0x00, 0x00, 0x03, 0xf7, 0x05, 0xf0, 0x00, 0x03, - 0x00, 0x24, 0x00, 0x00, 0x25, 0x15, 0x23, 0x35, 0x37, 0x35, 0x34, 0x26, - 0x27, 0x2e, 0x01, 0x2f, 0x01, 0x2e, 0x01, 0x35, 0x34, 0x36, 0x33, 0x32, - 0x16, 0x17, 0x15, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x1f, - 0x01, 0x1e, 0x01, 0x1d, 0x01, 0x03, 0x03, 0xcb, 0x06, 0x06, 0x06, 0x08, - 0x27, 0x2f, 0x58, 0x5a, 0x48, 0xdf, 0xb8, 0x67, 0xc1, 0x5e, 0x61, 0xb3, - 0x4f, 0x6c, 0x83, 0x33, 0x39, 0x5a, 0x5a, 0x38, 0xfe, 0xfe, 0xfe, 0x93, - 0x7b, 0x34, 0x3c, 0x15, 0x19, 0x35, 0x2f, 0x56, 0x56, 0x89, 0x4c, 0x9f, - 0xc2, 0x38, 0x39, 0xbc, 0x43, 0x46, 0x6e, 0x59, 0x31, 0x5e, 0x35, 0x59, - 0x56, 0x82, 0x65, 0x9a, 0x00, 0x01, 0x01, 0xb2, 0x00, 0x55, 0x04, 0x2d, - 0x03, 0xde, 0x00, 0x22, 0x00, 0x00, 0x25, 0x35, 0x36, 0x37, 0x36, 0x37, - 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, - 0x15, 0x26, 0x07, 0x06, 0x07, 0x06, 0x17, 0x14, 0x17, 0x16, 0x37, 0x36, - 0x37, 0x15, 0x06, 0x07, 0x06, 0x01, 0xb2, 0x2f, 0x53, 0x44, 0x34, 0x8e, - 0x33, 0x35, 0x15, 0x1e, 0x67, 0x63, 0x62, 0x6e, 0x5a, 0x64, 0x46, 0x33, - 0x31, 0x60, 0x01, 0xc8, 0x39, 0x3a, 0x48, 0x3a, 0x5a, 0xcd, 0xe7, 0x55, - 0xb0, 0x06, 0x19, 0x14, 0x21, 0x18, 0x4c, 0x4f, 0x54, 0x41, 0x4b, 0x76, - 0x3f, 0x3d, 0x16, 0xb9, 0x1f, 0x02, 0x01, 0x1a, 0x30, 0x70, 0x73, 0x32, - 0x0e, 0x0f, 0x13, 0x23, 0xb9, 0x3c, 0x50, 0x5a, 0xff, 0xff, 0x01, 0x00, - 0x00, 0x00, 0x03, 0xd0, 0x07, 0x83, 0x10, 0x26, 0x04, 0x57, 0x00, 0x00, - 0x10, 0x07, 0x04, 0x7e, 0x00, 0x00, 0x01, 0xc2, 0xff, 0xff, 0x01, 0xbd, - 0x00, 0x00, 0x03, 0x14, 0x07, 0xfd, 0x10, 0x26, 0x04, 0x57, 0x00, 0x00, - 0x10, 0x07, 0x04, 0x7f, 0x00, 0x00, 0x01, 0x86, 0xff, 0xff, 0x00, 0x4c, - 0xfe, 0x0c, 0x04, 0x33, 0x04, 0xb5, 0x10, 0x26, 0x04, 0x73, 0x00, 0x00, - 0x10, 0x07, 0x04, 0x7f, 0x00, 0x63, 0xfe, 0x3e, 0xff, 0xff, 0x01, 0xbd, - 0xfe, 0x0c, 0x03, 0x14, 0x06, 0x14, 0x10, 0x26, 0x04, 0x57, 0x00, 0x00, - 0x10, 0x06, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x19, - 0xfe, 0xf3, 0x04, 0xd1, 0x04, 0x5b, 0x10, 0x26, 0x04, 0x74, 0x00, 0x00, - 0x10, 0x07, 0x04, 0x7f, 0xff, 0x72, 0xfd, 0xe4, 0x00, 0x01, 0x02, 0x0c, - 0x00, 0x00, 0x02, 0xc4, 0x06, 0x14, 0x00, 0x03, 0x00, 0x00, 0x01, 0x33, - 0x11, 0x23, 0x02, 0x0c, 0xb8, 0xb8, 0x06, 0x14, 0xf9, 0xec, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x45, 0xfe, 0xc8, 0x04, 0xb0, 0x02, 0x1b, 0x10, 0x27, - 0x0c, 0xd1, 0x02, 0x2c, 0xfe, 0xc8, 0x10, 0x06, 0x0c, 0xe0, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xde, 0xff, 0xc6, 0x03, 0xf3, 0x04, 0x1a, 0x10, 0x27, - 0x0c, 0xd2, 0x01, 0x71, 0x03, 0x84, 0x10, 0x06, 0x04, 0x72, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x45, 0xff, 0xec, 0x04, 0xb0, 0x03, 0x20, 0x10, 0x27, - 0x0c, 0xd2, 0x01, 0xb8, 0x02, 0x8a, 0x10, 0x06, 0x0c, 0xe0, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x45, 0xff, 0xec, 0x04, 0xb0, 0x04, 0x1a, 0x10, 0x27, - 0x0c, 0xd3, 0x01, 0xa4, 0x02, 0x8a, 0x10, 0x06, 0x0c, 0xe0, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x58, 0xfe, 0x0c, 0x04, 0xad, 0x03, 0x66, 0x10, 0x27, - 0x0c, 0xd1, 0x02, 0x97, 0x00, 0x0d, 0x10, 0x06, 0x04, 0x5d, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x58, 0xfe, 0x0c, 0x04, 0xad, 0x03, 0x66, 0x00, 0x1e, - 0x00, 0x00, 0x13, 0x24, 0x17, 0x04, 0x17, 0x15, 0x24, 0x07, 0x06, 0x15, - 0x14, 0x17, 0x16, 0x05, 0x32, 0x37, 0x15, 0x06, 0x07, 0x04, 0x27, 0x26, - 0x35, 0x10, 0x37, 0x36, 0x37, 0x26, 0x07, 0x06, 0x07, 0x58, 0x01, 0x14, - 0xc3, 0x01, 0x24, 0xc4, 0xfe, 0xda, 0xd7, 0xe0, 0x4a, 0x81, 0x01, 0x13, - 0xc1, 0xd4, 0x96, 0xfa, 0xfe, 0x94, 0xa9, 0x83, 0xd4, 0x60, 0x89, 0x65, - 0x9f, 0x87, 0x5f, 0x03, 0x27, 0x40, 0x01, 0x01, 0x35, 0x9a, 0x0d, 0xb4, - 0xbc, 0xf7, 0x89, 0x5e, 0xa3, 0x01, 0x76, 0xb8, 0x62, 0x01, 0x02, 0xc4, - 0x98, 0xde, 0x01, 0x02, 0xdf, 0x65, 0x34, 0x03, 0x16, 0x13, 0x29, 0x00, - 0xff, 0xff, 0x00, 0x58, 0xfe, 0x0c, 0x04, 0xad, 0x04, 0xb0, 0x10, 0x27, - 0x0c, 0xd1, 0x01, 0xca, 0x04, 0x1a, 0x10, 0x06, 0x04, 0x5d, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xe8, 0xff, 0xda, 0x03, 0xe8, 0x03, 0x6a, 0x00, 0x19, - 0x00, 0x00, 0x25, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x33, - 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x05, 0x06, 0x23, 0x22, 0x27, - 0x35, 0x16, 0x33, 0x32, 0x02, 0x54, 0xae, 0x21, 0x08, 0x3c, 0x49, 0xa6, - 0xe3, 0x6b, 0x48, 0x52, 0x20, 0x50, 0xfe, 0xfa, 0x2e, 0x5e, 0x97, 0x67, - 0x73, 0x85, 0x52, 0x97, 0x32, 0x6f, 0x1b, 0x2a, 0x5b, 0x67, 0x78, 0xb3, - 0x6c, 0x83, 0x98, 0x69, 0x63, 0x4b, 0xc3, 0x28, 0x07, 0x26, 0xb8, 0x2a, - 0xff, 0xff, 0x00, 0xe8, 0xff, 0xda, 0x03, 0xe8, 0x04, 0xc8, 0x10, 0x27, - 0x0c, 0xd1, 0x02, 0x1c, 0x04, 0x32, 0x10, 0x06, 0x04, 0x5f, 0x00, 0x00, - 0x00, 0x01, 0xff, 0xcc, 0xfe, 0x08, 0x04, 0x44, 0x02, 0x22, 0x00, 0x11, - 0x00, 0x00, 0x25, 0x36, 0x35, 0x34, 0x27, 0x33, 0x16, 0x15, 0x14, 0x07, - 0x02, 0x05, 0x04, 0x05, 0x35, 0x20, 0x37, 0x24, 0x03, 0x85, 0x0a, 0x35, - 0xb8, 0x32, 0x08, 0x29, 0xfe, 0xb5, 0xfe, 0xef, 0xfe, 0x15, 0x01, 0xbc, - 0xdc, 0x00, 0xff, 0x9a, 0x3a, 0x48, 0x7e, 0x88, 0x76, 0x84, 0x52, 0x3e, - 0xfe, 0xb5, 0xad, 0x8f, 0x09, 0xb8, 0x80, 0x92, 0xff, 0xff, 0xff, 0xcc, - 0xfe, 0x08, 0x04, 0x44, 0x03, 0xb6, 0x10, 0x27, 0x0c, 0xd1, 0x03, 0x55, - 0x03, 0x20, 0x10, 0x06, 0x04, 0x61, 0x00, 0x00, 0x00, 0x01, 0xff, 0x24, - 0xfe, 0x14, 0x04, 0x98, 0x02, 0xee, 0x00, 0x3f, 0x00, 0x00, 0x25, 0x06, - 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x37, 0x36, 0x37, 0x33, - 0x06, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x36, 0x27, - 0x34, 0x2f, 0x01, 0x33, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x37, 0x36, - 0x35, 0x33, 0x06, 0x17, 0x16, 0x33, 0x32, 0x19, 0x01, 0x33, 0x11, 0x14, - 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x06, 0x07, 0x06, - 0x07, 0x06, 0x01, 0x8c, 0x09, 0x1d, 0x26, 0x3c, 0x47, 0x72, 0x5f, 0x65, - 0x75, 0x12, 0x13, 0x3d, 0xa4, 0x58, 0x06, 0x07, 0x21, 0x2f, 0x2f, 0x36, - 0x32, 0x22, 0x1a, 0x18, 0x02, 0x10, 0x2a, 0xa0, 0x12, 0x10, 0x16, 0x30, - 0x28, 0x2e, 0x2e, 0x24, 0xa4, 0x04, 0x26, 0x1f, 0x2b, 0x68, 0xa4, 0x3e, - 0x21, 0x55, 0x16, 0x4e, 0x42, 0x18, 0x41, 0x19, 0x1f, 0x45, 0x33, 0x49, - 0x30, 0x3c, 0xa8, 0x5e, 0x79, 0x4d, 0x5c, 0x64, 0x73, 0xd5, 0xe8, 0x82, - 0xe1, 0x89, 0xac, 0x2b, 0x3b, 0x48, 0x32, 0x7a, 0x6d, 0xa5, 0x5e, 0x5c, - 0xea, 0x9c, 0x91, 0x23, 0x50, 0x03, 0x03, 0x7d, 0x67, 0xc2, 0xa3, 0x8d, - 0x78, 0x01, 0x18, 0x01, 0x26, 0xfe, 0xaa, 0x9f, 0x99, 0x52, 0x22, 0x09, - 0x19, 0x43, 0x7e, 0x6d, 0x38, 0x28, 0x02, 0x02, 0xff, 0xff, 0xff, 0x24, - 0xfe, 0x14, 0x04, 0x98, 0x04, 0xb0, 0x10, 0x27, 0x0c, 0xd3, 0x01, 0x63, - 0x03, 0x20, 0x10, 0x06, 0x04, 0x63, 0x00, 0x00, 0x00, 0x02, 0xff, 0x10, - 0xfe, 0x14, 0x04, 0xc0, 0x02, 0x8f, 0x00, 0x0c, 0x00, 0x3d, 0x00, 0x00, - 0x25, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, - 0x06, 0x07, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, - 0x06, 0x2b, 0x01, 0x22, 0x27, 0x26, 0x35, 0x14, 0x07, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x33, 0x06, 0x15, 0x14, 0x17, - 0x16, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x33, 0x14, - 0x17, 0x16, 0x02, 0x48, 0x80, 0x8d, 0x49, 0x6a, 0x28, 0x24, 0x40, 0x47, - 0x67, 0x4c, 0xc4, 0x4b, 0x31, 0x8e, 0x9a, 0xac, 0x5a, 0x58, 0xb8, 0x7f, - 0x7f, 0xda, 0x25, 0x35, 0x2c, 0x30, 0x2e, 0x33, 0x63, 0x4d, 0x82, 0x5b, - 0x7c, 0x64, 0xac, 0x68, 0x3c, 0x32, 0x3d, 0x42, 0x25, 0x41, 0x09, 0x21, - 0x0d, 0xaa, 0x0e, 0x0a, 0xb8, 0x2e, 0x44, 0x46, 0x2d, 0x25, 0x21, 0x6d, - 0x4e, 0x06, 0x80, 0x3c, 0xb1, 0x52, 0x4e, 0x79, 0xbe, 0x6d, 0x4b, 0x1e, - 0x1a, 0x10, 0xaf, 0x83, 0x81, 0x2b, 0x56, 0x5a, 0x7f, 0xcb, 0xbc, 0xac, - 0xcc, 0x9c, 0x91, 0x32, 0x29, 0x03, 0x04, 0x3b, 0x6a, 0x88, 0x68, 0x3e, - 0xd4, 0x48, 0x0f, 0x37, 0x28, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x10, - 0xfe, 0x14, 0x04, 0xc0, 0x03, 0x4d, 0x10, 0x27, 0x0c, 0xd1, 0x01, 0x4f, - 0x02, 0xb7, 0x10, 0x06, 0x04, 0x65, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0a, - 0x00, 0x00, 0x04, 0xa4, 0x06, 0x14, 0x00, 0x0c, 0x00, 0x1f, 0x00, 0x00, - 0x25, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, - 0x06, 0x13, 0x21, 0x23, 0x35, 0x33, 0x11, 0x33, 0x11, 0x36, 0x37, 0x36, - 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x02, 0x2c, 0x81, 0x8c, - 0x49, 0x6a, 0x28, 0x24, 0x3f, 0x47, 0x68, 0x4b, 0x88, 0xfd, 0xfb, 0xe0, - 0xe0, 0xb8, 0x4c, 0x31, 0x8e, 0x9a, 0xab, 0x5b, 0x57, 0xb8, 0x7e, 0xb8, - 0x2e, 0x44, 0x46, 0x2d, 0x25, 0x21, 0x6d, 0x4e, 0xfe, 0xd8, 0xb8, 0x05, - 0x5c, 0xfb, 0x0e, 0x80, 0x3c, 0xb1, 0x52, 0x4e, 0x79, 0xbe, 0x6d, 0x4b, - 0xff, 0xff, 0x00, 0x0a, 0x00, 0x00, 0x04, 0xa4, 0x06, 0x14, 0x10, 0x27, - 0x0c, 0xd1, 0x02, 0x59, 0x03, 0x16, 0x10, 0x06, 0x04, 0x67, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x7a, 0xfe, 0x0c, 0x04, 0xb7, 0x04, 0x2a, 0x00, 0x2a, - 0x00, 0x00, 0x05, 0x16, 0x21, 0x32, 0x37, 0x15, 0x06, 0x23, 0x20, 0x27, - 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, - 0x36, 0x33, 0x15, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, - 0x37, 0x36, 0x37, 0x15, 0x04, 0x07, 0x06, 0x15, 0x14, 0x01, 0x58, 0x77, - 0x01, 0x53, 0xc1, 0xd4, 0x96, 0xfa, 0xfe, 0x5b, 0xa6, 0x62, 0x57, 0x71, - 0x4d, 0x33, 0x2f, 0x58, 0xcc, 0x7c, 0xfc, 0xc3, 0x74, 0x5d, 0x30, 0x2d, - 0x2e, 0x28, 0x29, 0x9e, 0xfe, 0xfe, 0xef, 0xec, 0xd1, 0xb1, 0x9e, 0x76, - 0xb8, 0x63, 0xbc, 0x6f, 0xc9, 0xb1, 0x65, 0x83, 0x19, 0x04, 0x1e, 0x38, - 0x82, 0xd0, 0x7f, 0x4d, 0xa9, 0x41, 0x34, 0x68, 0x4b, 0x19, 0x18, 0x12, - 0x45, 0x1d, 0xb8, 0x1a, 0x95, 0x83, 0xb9, 0x75, 0xff, 0xff, 0x00, 0x7a, - 0xfe, 0x0c, 0x04, 0xb7, 0x05, 0x46, 0x10, 0x27, 0x0c, 0xd1, 0x01, 0x7d, - 0x04, 0xb0, 0x10, 0x06, 0x04, 0x69, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, - 0x00, 0x00, 0x04, 0xe5, 0x00, 0xb8, 0x00, 0x03, 0x00, 0x00, 0x23, 0x35, - 0x21, 0x15, 0x14, 0x04, 0xf9, 0xb8, 0xb8, 0x00, 0xff, 0xff, 0xff, 0xb6, - 0xff, 0xa4, 0x04, 0x8c, 0x04, 0xcc, 0x10, 0x27, 0x0c, 0xd1, 0x02, 0xfc, - 0x04, 0x36, 0x10, 0x06, 0x0c, 0xe8, 0x00, 0x00, 0xff, 0xff, 0x00, 0x1f, - 0xfe, 0x7d, 0x04, 0x74, 0x05, 0x14, 0x10, 0x27, 0x0c, 0xd2, 0x02, 0x53, - 0x04, 0x7e, 0x10, 0x06, 0x0c, 0xe1, 0x00, 0x00, 0x00, 0x02, 0x00, 0x08, - 0xff, 0xc9, 0x04, 0x9f, 0x06, 0x14, 0x00, 0x21, 0x00, 0x3d, 0x00, 0x00, - 0x01, 0x15, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x15, - 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x35, 0x16, 0x33, 0x32, 0x37, 0x36, - 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x37, 0x36, 0x37, 0x36, 0x01, 0x36, - 0x19, 0x01, 0x33, 0x11, 0x10, 0x07, 0x06, 0x07, 0x06, 0x23, 0x06, 0x27, - 0x26, 0x35, 0x34, 0x37, 0x33, 0x06, 0x15, 0x16, 0x17, 0x16, 0x33, 0x32, - 0x37, 0x36, 0x02, 0x7b, 0x4a, 0x26, 0x50, 0x0e, 0x0c, 0x44, 0x66, 0x58, - 0x52, 0x4e, 0x42, 0x38, 0x44, 0x2d, 0x3c, 0x39, 0x3c, 0x4e, 0x4a, 0x12, - 0x20, 0x01, 0x02, 0x4b, 0x55, 0x01, 0xab, 0x34, 0xb8, 0x56, 0x82, 0x43, - 0x9b, 0xb8, 0xad, 0xa3, 0xd9, 0x10, 0xb8, 0x0e, 0x02, 0x98, 0x79, 0x57, - 0x7f, 0x3e, 0x77, 0x04, 0x4c, 0x52, 0x04, 0x0e, 0x1e, 0x21, 0x1c, 0x12, - 0x10, 0x0a, 0x0f, 0x58, 0x6e, 0x2a, 0x27, 0x0b, 0x58, 0x0a, 0x1a, 0x1a, - 0x1e, 0x26, 0x11, 0x10, 0x1c, 0x2f, 0x2e, 0x51, 0x26, 0x2b, 0xfc, 0xd1, - 0x38, 0x01, 0x12, 0x03, 0xb1, 0xfc, 0x4f, 0xfe, 0x9a, 0x5c, 0x88, 0x19, - 0x37, 0x02, 0x39, 0x4c, 0xb8, 0x4b, 0x35, 0x3a, 0x2c, 0x5d, 0x2d, 0x23, - 0x1b, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x43, 0xfe, 0xc8, 0x04, 0x4b, - 0x06, 0x14, 0x00, 0x1b, 0x00, 0x00, 0x25, 0x36, 0x19, 0x01, 0x33, 0x11, - 0x10, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x03, 0x26, 0x37, - 0x33, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x03, 0x75, - 0x1e, 0xb8, 0x32, 0x6c, 0x65, 0x96, 0xa2, 0x63, 0x77, 0xf2, 0x01, 0x01, - 0x40, 0xb8, 0x41, 0xa6, 0x28, 0x49, 0x69, 0x54, 0x63, 0x49, 0x39, 0x01, - 0x28, 0x04, 0x6a, 0xfb, 0x96, 0xfe, 0x7a, 0x47, 0x9c, 0x31, 0x48, 0x2a, - 0x56, 0x01, 0x03, 0x8a, 0x5c, 0x73, 0x73, 0x7e, 0x42, 0x10, 0x22, 0x29, - 0x00, 0x02, 0x00, 0x82, 0xfe, 0x14, 0x04, 0x54, 0x02, 0xf3, 0x00, 0x11, - 0x00, 0x2e, 0x00, 0x00, 0x01, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, - 0x27, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, 0x07, 0x26, - 0x07, 0x06, 0x15, 0x11, 0x23, 0x11, 0x34, 0x37, 0x36, 0x33, 0x26, 0x35, - 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, - 0x06, 0x23, 0x06, 0x02, 0x58, 0x7a, 0x4c, 0x2c, 0x15, 0x35, 0x06, 0x15, - 0x3b, 0x28, 0x2e, 0x3b, 0x1b, 0x44, 0x6e, 0x32, 0x4b, 0x19, 0xc8, 0x78, - 0x41, 0x5a, 0x02, 0xa2, 0x4d, 0x5c, 0x4d, 0x4f, 0xb6, 0x1c, 0x08, 0x62, - 0x78, 0x58, 0xb2, 0x01, 0x27, 0x2a, 0x16, 0x39, 0x3a, 0x18, 0x14, 0x58, - 0x11, 0x0c, 0x1b, 0x44, 0x44, 0x28, 0xc1, 0x1c, 0x4e, 0x1a, 0x4f, 0xfe, - 0x14, 0x01, 0xec, 0xad, 0x66, 0x37, 0x2a, 0x28, 0x94, 0x84, 0x3f, 0x24, - 0x53, 0xa7, 0x2d, 0x38, 0x92, 0x41, 0x50, 0x02, 0xff, 0xff, 0x00, 0x36, - 0xfe, 0xb5, 0x04, 0x8d, 0x03, 0x60, 0x10, 0x27, 0x0c, 0xd1, 0x01, 0xea, - 0x02, 0xca, 0x10, 0x06, 0x0c, 0xea, 0x00, 0x00, 0x00, 0x02, 0x00, 0xde, - 0xff, 0xc6, 0x03, 0xf3, 0x02, 0xde, 0x00, 0x0f, 0x00, 0x1f, 0x00, 0x00, - 0x01, 0x22, 0x07, 0x06, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, - 0x35, 0x34, 0x27, 0x26, 0x27, 0x32, 0x17, 0x16, 0x15, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x02, 0x0e, 0x42, 0x21, - 0x1a, 0x01, 0x01, 0x37, 0x39, 0x39, 0x5b, 0x5d, 0x4b, 0x42, 0x7b, 0x98, - 0xc6, 0xb6, 0x8d, 0x01, 0x93, 0xa5, 0x84, 0x60, 0x51, 0xa7, 0x25, 0x54, - 0x02, 0x2a, 0x57, 0x45, 0x7b, 0x52, 0x2c, 0x2c, 0x39, 0x2e, 0x55, 0x4d, - 0x41, 0x78, 0xb3, 0xa0, 0x7c, 0x94, 0xc8, 0x4b, 0x55, 0x23, 0x4a, 0xef, - 0xb5, 0x4e, 0xb9, 0x00, 0x00, 0x02, 0x00, 0x4c, 0xfe, 0x0c, 0x04, 0x33, - 0x02, 0x86, 0x00, 0x0b, 0x00, 0x26, 0x00, 0x00, 0x01, 0x22, 0x07, 0x06, - 0x15, 0x14, 0x17, 0x16, 0x17, 0x34, 0x27, 0x26, 0x01, 0x10, 0x07, 0x06, - 0x07, 0x06, 0x21, 0x35, 0x20, 0x37, 0x36, 0x37, 0x26, 0x27, 0x26, 0x27, - 0x26, 0x35, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x02, - 0xe1, 0x3f, 0x2c, 0x18, 0x33, 0x2f, 0xc0, 0x56, 0x25, 0x01, 0x2e, 0xac, - 0x2d, 0xba, 0xbe, 0xfe, 0x6a, 0x01, 0x73, 0xa1, 0xe0, 0x31, 0x76, 0x2d, - 0x8b, 0x33, 0x74, 0xd3, 0x39, 0x3e, 0x59, 0x48, 0x83, 0x18, 0x11, 0x01, - 0xc4, 0x39, 0x21, 0x24, 0x37, 0x2b, 0x28, 0x04, 0xb8, 0x3b, 0x19, 0xfe, - 0xf4, 0xfe, 0xda, 0xae, 0x2e, 0x54, 0x56, 0xb8, 0x4c, 0x68, 0x8b, 0x03, - 0x07, 0x18, 0x2b, 0x62, 0x89, 0xd9, 0x5a, 0x18, 0x33, 0x5b, 0x8e, 0x66, - 0x00, 0x01, 0x00, 0x19, 0xfe, 0xf3, 0x04, 0xd1, 0x03, 0x1c, 0x00, 0x35, - 0x00, 0x00, 0x25, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x24, 0x11, 0x34, - 0x37, 0x33, 0x06, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, - 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x37, 0x36, 0x37, 0x36, 0x33, - 0x32, 0x17, 0x16, 0x17, 0x23, 0x34, 0x27, 0x26, 0x07, 0x06, 0x07, 0x06, - 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x04, 0x79, 0x84, 0xe0, - 0xb1, 0x5d, 0x81, 0x48, 0xfe, 0xdb, 0x3f, 0xb8, 0x42, 0x01, 0x02, 0xa4, - 0x4b, 0x53, 0x78, 0x6c, 0x6b, 0x41, 0x3b, 0x1b, 0x22, 0x84, 0x62, 0x01, - 0x01, 0x5e, 0x4d, 0x60, 0x8f, 0x37, 0x32, 0x11, 0xb8, 0x13, 0x1b, 0x27, - 0x14, 0x18, 0x23, 0x7d, 0x5b, 0x37, 0x1f, 0x01, 0x01, 0x0c, 0xc3, 0x30, - 0x26, 0x1a, 0x68, 0x01, 0x05, 0x75, 0x71, 0x83, 0x63, 0x93, 0x2d, 0x14, - 0x23, 0x23, 0x4e, 0x47, 0x22, 0x2e, 0x2a, 0x33, 0x3a, 0x2c, 0x83, 0x96, - 0x3d, 0x32, 0x49, 0x42, 0x89, 0x3d, 0x19, 0x22, 0x04, 0x02, 0x14, 0x1e, - 0x39, 0x29, 0x2c, 0x20, 0x67, 0x3a, 0x5e, 0x4d, 0xff, 0xff, 0x00, 0x19, - 0xfe, 0x0c, 0x04, 0xd1, 0x03, 0x1c, 0x10, 0x27, 0x0c, 0xd2, 0x01, 0x72, - 0xfe, 0x0c, 0x10, 0x06, 0x04, 0x74, 0x00, 0x00, 0x00, 0x02, 0x01, 0x44, - 0x04, 0xba, 0x03, 0x8c, 0x06, 0x9a, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, - 0x01, 0x35, 0x25, 0x15, 0x01, 0x35, 0x25, 0x15, 0x01, 0x44, 0x02, 0x48, - 0xfd, 0xb8, 0x02, 0x48, 0x05, 0xaa, 0x6e, 0x82, 0x6e, 0xfe, 0x8e, 0x6e, - 0x82, 0x6e, 0x00, 0x00, 0x00, 0x02, 0x01, 0x44, 0x04, 0xba, 0x03, 0x8c, - 0x06, 0xfd, 0x00, 0x26, 0x00, 0x35, 0x00, 0x00, 0x01, 0x36, 0x37, 0x26, - 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x16, 0x33, 0x16, 0x33, 0x15, 0x22, 0x2f, 0x01, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x35, 0x33, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, - 0x36, 0x37, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, - 0x17, 0x16, 0x02, 0x74, 0x24, 0x16, 0x21, 0x17, 0x6c, 0x44, 0x1d, 0x3f, - 0x49, 0x27, 0x38, 0x0d, 0x13, 0x0e, 0x13, 0x13, 0x2e, 0x14, 0x34, 0x1a, - 0x4c, 0x54, 0x5e, 0x73, 0x37, 0x10, 0x5a, 0x0c, 0x24, 0x30, 0x38, 0x9e, - 0x04, 0x02, 0x0a, 0x22, 0x14, 0x18, 0x0a, 0x12, 0x2c, 0x14, 0x05, 0x64, - 0x24, 0x2a, 0x07, 0x0d, 0x39, 0x5e, 0x57, 0x34, 0x15, 0x27, 0x36, 0x4f, - 0x27, 0x26, 0x01, 0x01, 0x6e, 0x02, 0x05, 0x3d, 0x4e, 0x56, 0x9a, 0x29, - 0x71, 0x61, 0x1a, 0x4b, 0xee, 0x07, 0x07, 0x15, 0x18, 0x22, 0x1c, 0x09, - 0x0d, 0x1c, 0x25, 0x12, 0x08, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x44, - 0xfe, 0x16, 0x03, 0x8c, 0xff, 0xf6, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, - 0x01, 0x35, 0x25, 0x15, 0x25, 0x35, 0x25, 0x15, 0x01, 0x44, 0x02, 0x48, - 0xfd, 0xb8, 0x02, 0x48, 0xfe, 0x16, 0x6e, 0x82, 0x6e, 0x6e, 0x6e, 0x82, - 0x6e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x44, 0x04, 0xba, 0x03, 0x8c, - 0x05, 0xaa, 0x00, 0x03, 0x00, 0x00, 0x01, 0x35, 0x25, 0x15, 0x01, 0x44, - 0x02, 0x48, 0x04, 0xba, 0x6e, 0x82, 0x6e, 0x00, 0x00, 0x02, 0x01, 0x44, - 0x04, 0xb9, 0x03, 0x8c, 0x06, 0xfd, 0x00, 0x1f, 0x00, 0x2f, 0x00, 0x00, - 0x01, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x16, 0x33, 0x16, 0x33, 0x15, 0x22, 0x27, 0x26, 0x27, - 0x06, 0x07, 0x06, 0x23, 0x35, 0x32, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, - 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, - 0x02, 0x92, 0x09, 0x13, 0x6c, 0x44, 0x1d, 0x3f, 0x49, 0x27, 0x38, 0x0f, - 0x11, 0x12, 0x13, 0x13, 0x22, 0x20, 0x1f, 0x1b, 0x2b, 0x45, 0xc9, 0x93, - 0x99, 0x8b, 0x16, 0x56, 0x04, 0x02, 0x0a, 0x12, 0x10, 0x14, 0x18, 0x0a, - 0x12, 0x2c, 0x14, 0x05, 0xba, 0x02, 0x0a, 0x38, 0x5f, 0x57, 0x34, 0x15, - 0x27, 0x36, 0x4f, 0x20, 0x2d, 0x01, 0x01, 0x6e, 0x02, 0x02, 0x03, 0x3d, - 0x2a, 0x7b, 0x6e, 0x6d, 0x12, 0x70, 0x07, 0x07, 0x15, 0x18, 0x22, 0x0e, - 0x0e, 0x09, 0x0d, 0x1c, 0x25, 0x12, 0x08, 0x00, 0x00, 0x01, 0x01, 0x44, - 0xfe, 0xe8, 0x03, 0x8c, 0xff, 0xd8, 0x00, 0x03, 0x00, 0x00, 0x01, 0x35, - 0x25, 0x15, 0x01, 0x44, 0x02, 0x48, 0xfe, 0xe8, 0x6e, 0x82, 0x6e, 0x00, - 0x00, 0x01, 0x01, 0x30, 0x04, 0xcb, 0x03, 0xa0, 0x06, 0xf4, 0x00, 0x28, - 0x00, 0x00, 0x01, 0x06, 0x07, 0x06, 0x07, 0x06, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x33, 0x06, 0x17, 0x16, 0x17, 0x16, 0x37, 0x36, 0x37, 0x36, 0x35, - 0x33, 0x14, 0x17, 0x16, 0x37, 0x36, 0x35, 0x34, 0x27, 0x33, 0x16, 0x07, - 0x06, 0x07, 0x06, 0x07, 0x06, 0x27, 0x26, 0x02, 0x78, 0x0f, 0x21, 0x39, - 0x45, 0x4f, 0x29, 0x22, 0x10, 0x61, 0x0c, 0x01, 0x03, 0x16, 0x13, 0x32, - 0x3d, 0x04, 0x02, 0x60, 0x03, 0x0e, 0x4b, 0x47, 0x0d, 0x67, 0x0f, 0x03, - 0x03, 0x18, 0x26, 0x5a, 0x47, 0x1f, 0x1b, 0x05, 0x84, 0x4d, 0x27, 0x44, - 0x01, 0x02, 0x41, 0x32, 0x6f, 0x6d, 0x62, 0x7d, 0x38, 0x54, 0x22, 0x1c, - 0x17, 0x1a, 0xa8, 0x52, 0x59, 0x24, 0x36, 0xc5, 0x02, 0x01, 0xad, 0x73, - 0x39, 0x49, 0x74, 0x85, 0x36, 0x58, 0x0b, 0x09, 0x21, 0x1e, 0x00, 0x00, - 0x00, 0x02, 0x01, 0x56, 0x04, 0xe1, 0x03, 0x7a, 0x07, 0x06, 0x00, 0x09, - 0x00, 0x13, 0x00, 0x00, 0x01, 0x34, 0x26, 0x22, 0x06, 0x15, 0x14, 0x16, - 0x32, 0x3e, 0x01, 0x14, 0x06, 0x23, 0x22, 0x26, 0x34, 0x36, 0x33, 0x32, - 0x03, 0x00, 0x58, 0x80, 0x58, 0x58, 0x80, 0x58, 0x7a, 0x9e, 0x74, 0x72, - 0xa0, 0xa0, 0x72, 0x74, 0x05, 0xf4, 0x3f, 0x58, 0x57, 0x40, 0x41, 0x57, - 0x58, 0xb3, 0xe6, 0xa0, 0xa0, 0xe6, 0x9f, 0x00, 0x00, 0x01, 0x01, 0x00, - 0x04, 0xb9, 0x03, 0xd0, 0x05, 0xc1, 0x00, 0x12, 0x00, 0x00, 0x01, 0x37, - 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x15, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x26, 0x27, 0x07, 0x01, 0x00, 0xa0, 0x67, 0x43, 0x2a, 0x36, - 0x3a, 0x2a, 0x6b, 0x57, 0x5a, 0x5a, 0x42, 0x36, 0x22, 0x98, 0x44, 0xa6, - 0x05, 0x36, 0x7b, 0x53, 0x15, 0x0d, 0x10, 0x29, 0x4c, 0x7d, 0x40, 0x1d, - 0x16, 0x22, 0x46, 0x80, 0xff, 0xff, 0x01, 0xbd, 0x04, 0xbf, 0x03, 0x14, - 0x06, 0x77, 0x10, 0x06, 0x04, 0x90, 0x00, 0x8d, 0xff, 0xff, 0x01, 0xbd, - 0xfe, 0x0c, 0x03, 0x14, 0xff, 0xc4, 0x10, 0x07, 0x04, 0x90, 0x00, 0x00, - 0xf8, 0xda, 0x00, 0x00, 0x00, 0x01, 0x01, 0x5c, 0x04, 0xee, 0x03, 0x76, - 0x06, 0x34, 0x00, 0x06, 0x00, 0x00, 0x01, 0x03, 0x33, 0x17, 0x37, 0x33, - 0x03, 0x02, 0x1e, 0xc2, 0x8a, 0x82, 0x82, 0x8c, 0xc4, 0x04, 0xee, 0x01, - 0x46, 0xc3, 0xc3, 0xfe, 0xba, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0xfa, - 0x01, 0xc2, 0x02, 0xd6, 0x02, 0xbc, 0x00, 0x03, 0x00, 0x00, 0x01, 0x33, - 0x15, 0x23, 0x01, 0xfa, 0xdc, 0xdc, 0x02, 0xbc, 0xfa, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x96, 0x00, 0x00, 0x03, 0x3c, 0x05, 0x14, 0x00, 0x09, - 0x00, 0x00, 0x21, 0x23, 0x10, 0x27, 0x02, 0x03, 0x33, 0x12, 0x13, 0x16, - 0x03, 0x3c, 0xb4, 0x26, 0x31, 0x9b, 0xc4, 0x79, 0x49, 0x20, 0x01, 0xa9, - 0xdc, 0x01, 0x21, 0x01, 0x6e, 0xfe, 0xdd, 0xfe, 0x94, 0x9b, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x9a, 0x00, 0x00, 0x04, 0x38, 0x05, 0x14, 0x00, 0x18, - 0x00, 0x00, 0x01, 0x16, 0x17, 0x16, 0x11, 0x23, 0x10, 0x27, 0x02, 0x03, - 0x33, 0x16, 0x17, 0x16, 0x33, 0x16, 0x37, 0x36, 0x37, 0x33, 0x06, 0x07, - 0x02, 0x23, 0x22, 0x01, 0xed, 0x1c, 0x17, 0x20, 0xb4, 0x26, 0x31, 0x9b, - 0xc6, 0x43, 0x03, 0x52, 0xb4, 0x7a, 0x36, 0x20, 0x08, 0xb4, 0x08, 0x2a, - 0x62, 0xf4, 0x6f, 0x03, 0x61, 0x6a, 0x72, 0x9b, 0xfe, 0x16, 0x01, 0xa9, - 0xdc, 0x01, 0x21, 0x01, 0x6e, 0x9b, 0x05, 0x98, 0x02, 0x95, 0x55, 0x50, - 0x79, 0x6d, 0xfe, 0xfa, 0x00, 0x01, 0x00, 0x86, 0x00, 0x00, 0x04, 0x4c, - 0x05, 0x14, 0x00, 0x25, 0x00, 0x00, 0x01, 0x16, 0x17, 0x16, 0x11, 0x23, - 0x10, 0x27, 0x02, 0x03, 0x33, 0x16, 0x17, 0x16, 0x37, 0x36, 0x37, 0x36, - 0x35, 0x33, 0x14, 0x17, 0x16, 0x17, 0x16, 0x37, 0x36, 0x35, 0x33, 0x10, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x06, 0x07, 0x06, 0x01, 0xe4, 0x18, 0x10, - 0x20, 0xb4, 0x26, 0x31, 0x9b, 0xc4, 0x2f, 0x28, 0x13, 0x30, 0x48, 0x08, - 0x06, 0xb4, 0x0e, 0x15, 0x2f, 0x3c, 0x0e, 0x0e, 0xb4, 0x28, 0x46, 0x9c, - 0x84, 0x21, 0x33, 0x34, 0x2e, 0x03, 0x35, 0x57, 0x59, 0xbe, 0xfe, 0x39, - 0x01, 0xa9, 0xdc, 0x01, 0x21, 0x01, 0x6e, 0x72, 0x7c, 0x3e, 0x08, 0x0c, - 0x40, 0x32, 0xa6, 0xde, 0x19, 0x25, 0x02, 0x02, 0x2c, 0x2a, 0xca, 0xfe, - 0xcf, 0x3b, 0x6c, 0x3e, 0x33, 0x0c, 0x0a, 0x00, 0x00, 0x01, 0x00, 0xec, - 0xff, 0xec, 0x03, 0xe4, 0x05, 0x20, 0x00, 0x2a, 0x00, 0x00, 0x01, 0x15, - 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x15, 0x22, 0x07, 0x06, - 0x15, 0x14, 0x17, 0x16, 0x17, 0x32, 0x37, 0x36, 0x37, 0x15, 0x06, 0x07, - 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x26, 0x27, - 0x26, 0x27, 0x26, 0x37, 0x36, 0x03, 0x60, 0x79, 0x67, 0x88, 0x5c, 0x4e, - 0x4e, 0x59, 0x87, 0x70, 0x30, 0x3c, 0x4a, 0x62, 0x58, 0x7e, 0x56, 0x48, - 0x7c, 0x65, 0x65, 0x96, 0x70, 0x64, 0x6c, 0x40, 0x58, 0x48, 0x2c, 0x37, - 0x01, 0x01, 0xe1, 0x71, 0x05, 0x20, 0xa8, 0x11, 0x34, 0x43, 0x40, 0x23, - 0x39, 0x30, 0x04, 0xa4, 0x4c, 0x40, 0x72, 0x52, 0x3c, 0x4a, 0x01, 0x17, - 0x21, 0x2b, 0xc4, 0x25, 0x1c, 0x17, 0x7d, 0x70, 0xa5, 0x86, 0x80, 0x4c, - 0x18, 0x20, 0x30, 0x3a, 0x3f, 0x96, 0x80, 0x3f, 0x00, 0x02, 0x00, 0xca, - 0xff, 0xec, 0x04, 0x08, 0x05, 0x24, 0x00, 0x0d, 0x00, 0x1c, 0x00, 0x00, - 0x00, 0x22, 0x07, 0x06, 0x07, 0x06, 0x17, 0x16, 0x20, 0x37, 0x36, 0x27, - 0x26, 0x27, 0x03, 0x16, 0x13, 0x16, 0x15, 0x10, 0x07, 0x06, 0x20, 0x27, - 0x26, 0x11, 0x34, 0x37, 0x12, 0x02, 0xab, 0x85, 0x56, 0x4f, 0x03, 0x05, - 0x47, 0x29, 0x00, 0xff, 0x28, 0x48, 0x04, 0x04, 0x4e, 0x9a, 0xbf, 0x87, - 0x5a, 0x56, 0x68, 0xfe, 0x3d, 0x69, 0x54, 0x5a, 0x87, 0x04, 0x68, 0xd4, - 0xc0, 0xae, 0xc7, 0x73, 0x42, 0x42, 0x73, 0xc7, 0xae, 0xc0, 0x01, 0x90, - 0x01, 0xfe, 0xa1, 0xeb, 0xb3, 0xfe, 0xcb, 0x75, 0x90, 0x90, 0x75, 0x01, - 0x35, 0xb3, 0xeb, 0x01, 0x61, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x9a, - 0x00, 0x00, 0x04, 0x37, 0x05, 0x14, 0x00, 0x11, 0x00, 0x00, 0x01, 0x10, - 0x13, 0x12, 0x13, 0x23, 0x02, 0x03, 0x02, 0x27, 0x06, 0x23, 0x22, 0x27, - 0x35, 0x16, 0x33, 0x32, 0x03, 0x93, 0x25, 0x1d, 0x62, 0xc4, 0x55, 0x1f, - 0x1c, 0x02, 0x60, 0x8e, 0xb2, 0xa7, 0xb4, 0xa5, 0xd2, 0x05, 0x14, 0xfe, - 0xdc, 0xfe, 0x9f, 0xfe, 0xeb, 0xfe, 0x86, 0x01, 0x44, 0x01, 0x4b, 0x01, - 0x2a, 0x91, 0x1c, 0x32, 0xb4, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0x7e, - 0x00, 0x00, 0x04, 0x52, 0x05, 0x14, 0x00, 0x12, 0x00, 0x00, 0x21, 0x26, - 0x03, 0x02, 0x27, 0x33, 0x12, 0x13, 0x16, 0x17, 0x36, 0x37, 0x12, 0x13, - 0x33, 0x02, 0x03, 0x02, 0x07, 0x02, 0x0e, 0x10, 0x62, 0xa0, 0x7e, 0xc4, - 0x9a, 0x5a, 0x30, 0x02, 0x02, 0x30, 0x5a, 0x9a, 0xc4, 0xa4, 0x78, 0x56, - 0x1e, 0xf6, 0x01, 0x3a, 0x01, 0xfe, 0xe6, 0xfe, 0xca, 0xfe, 0xc5, 0xa8, - 0x0b, 0x0b, 0xa8, 0x01, 0x3b, 0x01, 0x36, 0xfe, 0xd3, 0xfe, 0x49, 0xfe, - 0xca, 0xfa, 0x00, 0x00, 0x00, 0x01, 0x00, 0x7e, 0x00, 0x00, 0x04, 0x52, - 0x05, 0x14, 0x00, 0x12, 0x00, 0x00, 0x01, 0x33, 0x16, 0x13, 0x12, 0x13, - 0x23, 0x02, 0x03, 0x26, 0x27, 0x06, 0x07, 0x02, 0x03, 0x23, 0x36, 0x13, - 0x12, 0x02, 0x0e, 0xb4, 0x1e, 0x56, 0x78, 0xa4, 0xc4, 0x9a, 0x5a, 0x30, - 0x02, 0x02, 0x30, 0x5a, 0x9a, 0xc4, 0x7e, 0xa0, 0x62, 0x05, 0x14, 0xfa, - 0xfe, 0xca, 0xfe, 0x49, 0xfe, 0xd3, 0x01, 0x36, 0x01, 0x3b, 0xa8, 0x0b, - 0x0b, 0xa8, 0xfe, 0xc5, 0xfe, 0xca, 0xe6, 0x01, 0xfe, 0x01, 0x3a, 0x00, - 0x00, 0x02, 0x00, 0xa2, 0x00, 0x00, 0x04, 0x30, 0x05, 0x1e, 0x00, 0x14, - 0x00, 0x23, 0x00, 0x00, 0x01, 0x26, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, - 0x37, 0x36, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x12, 0x13, 0x23, - 0x02, 0x03, 0x27, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x17, 0x16, - 0x17, 0x16, 0x17, 0x16, 0x02, 0xfc, 0xcd, 0x3d, 0xa5, 0x42, 0x67, 0x02, - 0x04, 0x63, 0x7e, 0x92, 0x9a, 0x5c, 0x80, 0x0e, 0x0a, 0x12, 0x24, 0x5b, - 0xc4, 0x5c, 0x24, 0x07, 0x0a, 0x22, 0x38, 0x6b, 0x4e, 0x3a, 0x3a, 0x02, - 0x01, 0x3b, 0x21, 0x4d, 0x4f, 0x02, 0x55, 0x03, 0x0f, 0x29, 0x41, 0x65, - 0x7b, 0x8e, 0x62, 0x7e, 0x01, 0x01, 0x54, 0x76, 0xa7, 0x87, 0x96, 0xfe, - 0xcd, 0xfe, 0xa4, 0x01, 0x9c, 0x01, 0x6e, 0x57, 0x6c, 0x3c, 0x61, 0x37, - 0x36, 0x47, 0x39, 0x36, 0x1f, 0x0d, 0x0e, 0x00, 0x00, 0x03, 0x00, 0xc8, - 0x00, 0x00, 0x04, 0x0a, 0x05, 0x14, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, - 0x00, 0x00, 0x25, 0x33, 0x15, 0x23, 0x01, 0x33, 0x15, 0x23, 0x25, 0x33, - 0x01, 0x23, 0x03, 0x46, 0xb4, 0xb4, 0xfd, 0x90, 0xb4, 0xb4, 0x02, 0x94, - 0xa0, 0xfd, 0x5e, 0xa0, 0xfa, 0xfa, 0x05, 0x14, 0xfa, 0xfa, 0xfa, 0xec, - 0x00, 0x01, 0x01, 0x36, 0xff, 0x1f, 0x03, 0x9b, 0x02, 0x8b, 0x00, 0x11, - 0x00, 0x00, 0x05, 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x33, - 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x01, 0x36, 0xa8, 0x71, - 0x6b, 0x2f, 0x19, 0x15, 0x96, 0x18, 0x4b, 0x4f, 0xa5, 0x6a, 0xbc, 0x46, - 0x05, 0x71, 0x6d, 0x8f, 0x50, 0x4f, 0x60, 0x60, 0x4e, 0x6f, 0xaa, 0xa0, - 0xa6, 0x71, 0x48, 0x06, 0x00, 0x01, 0x01, 0xd6, 0x03, 0xfe, 0x02, 0xfb, - 0x05, 0xd5, 0x00, 0x05, 0x00, 0x00, 0x01, 0x33, 0x15, 0x03, 0x23, 0x13, - 0x02, 0x28, 0xd3, 0xa4, 0x81, 0x52, 0x05, 0xd5, 0x98, 0xfe, 0xc1, 0x01, - 0x3f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x92, 0x00, 0xce, 0x04, 0x40, - 0x04, 0x4c, 0x00, 0x09, 0x00, 0x00, 0x13, 0x21, 0x1b, 0x01, 0x21, 0x05, - 0x13, 0x25, 0x05, 0x13, 0x92, 0x01, 0x67, 0x6f, 0x71, 0x01, 0x67, 0xfe, - 0xdd, 0x70, 0xfe, 0xdb, 0xfe, 0xdd, 0x6f, 0x02, 0xf7, 0x01, 0x55, 0xfe, - 0xab, 0xd4, 0xfe, 0xab, 0xd3, 0xd3, 0x01, 0x55, 0x00, 0x01, 0x01, 0xbd, - 0x05, 0x32, 0x03, 0x14, 0x06, 0xea, 0x00, 0x18, 0x00, 0x00, 0x01, 0x37, - 0x26, 0x27, 0x26, 0x37, 0x36, 0x37, 0x36, 0x17, 0x16, 0x17, 0x15, 0x26, - 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x37, 0x15, 0x05, 0x01, - 0xbd, 0x4e, 0x2c, 0x10, 0x11, 0x01, 0x02, 0x36, 0x38, 0x5e, 0x3d, 0x35, - 0x33, 0x3f, 0x42, 0x11, 0x1d, 0x5e, 0x21, 0x78, 0xfe, 0xa9, 0x05, 0x96, - 0x12, 0x14, 0x24, 0x25, 0x2d, 0x5f, 0x2c, 0x2e, 0x01, 0x01, 0x20, 0x64, - 0x21, 0x12, 0x20, 0x1a, 0x4d, 0x1b, 0x0a, 0x1d, 0x66, 0x4d, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x45, 0xff, 0xec, 0x04, 0xb0, 0x04, 0x99, 0x10, 0x27, - 0x04, 0x4e, 0x00, 0x2a, 0xfd, 0xa8, 0x10, 0x06, 0x0c, 0xe0, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x45, 0xff, 0xec, 0x04, 0xb0, 0x04, 0x1a, 0x10, 0x27, - 0x0c, 0xda, 0x02, 0x16, 0x03, 0x84, 0x10, 0x06, 0x0c, 0xe0, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x45, 0xfe, 0x0c, 0x04, 0xb0, 0x02, 0x1b, 0x10, 0x27, - 0x0c, 0xda, 0x02, 0x10, 0xff, 0x06, 0x10, 0x06, 0x0c, 0xe0, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x45, 0xfe, 0x0c, 0x04, 0xb0, 0x02, 0x1b, 0x10, 0x27, - 0x0c, 0xd9, 0x01, 0x9e, 0xff, 0x06, 0x10, 0x06, 0x0c, 0xe0, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x45, 0xff, 0xec, 0x04, 0xb0, 0x04, 0x1a, 0x10, 0x27, - 0x0c, 0xdb, 0x01, 0xa4, 0x03, 0x84, 0x10, 0x06, 0x0c, 0xe0, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x45, 0xfe, 0x0c, 0x04, 0xb0, 0x02, 0x1b, 0x10, 0x27, - 0x0c, 0xdb, 0x01, 0x9e, 0xff, 0x06, 0x10, 0x06, 0x0c, 0xe0, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x58, 0xfe, 0x0c, 0x04, 0xad, 0x03, 0x66, 0x10, 0x27, - 0x0c, 0xd2, 0x02, 0x2a, 0x00, 0x51, 0x10, 0x06, 0x04, 0x5d, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x58, 0xfe, 0x0c, 0x04, 0xad, 0x03, 0x66, 0x10, 0x27, - 0x0c, 0xda, 0x02, 0xcb, 0x00, 0xaf, 0x10, 0x06, 0x04, 0x5d, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x58, 0xfe, 0x0c, 0x04, 0xad, 0x03, 0x66, 0x10, 0x27, - 0x0c, 0xd9, 0x02, 0x6a, 0x00, 0x96, 0x10, 0x06, 0x04, 0x5d, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x58, 0xfe, 0x0c, 0x04, 0xad, 0x03, 0x66, 0x10, 0x27, - 0x0c, 0xdb, 0x02, 0x62, 0x00, 0xaf, 0x10, 0x06, 0x04, 0x5d, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xcc, 0xfe, 0x08, 0x04, 0xd0, 0x04, 0xa8, 0x10, 0x26, - 0x04, 0x61, 0x00, 0x00, 0x10, 0x07, 0x04, 0x4e, 0x01, 0x62, 0xfd, 0xb7, - 0xff, 0xff, 0xff, 0xcc, 0xfe, 0x08, 0x04, 0x65, 0x04, 0x71, 0x10, 0x27, - 0x0c, 0xd3, 0x02, 0xd5, 0x02, 0xe1, 0x10, 0x06, 0x04, 0x61, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xb6, 0xff, 0xa4, 0x04, 0x8c, 0x05, 0x99, 0x10, 0x27, - 0x0c, 0xd3, 0x02, 0x70, 0x04, 0x09, 0x10, 0x06, 0x0c, 0xe8, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x0a, 0xff, 0xa7, 0x05, 0x5d, 0x06, 0x14, 0x00, 0x2a, - 0x00, 0x00, 0x25, 0x32, 0x36, 0x37, 0x36, 0x35, 0x34, 0x2f, 0x01, 0x26, - 0x35, 0x34, 0x37, 0x36, 0x37, 0x01, 0x15, 0x01, 0x06, 0x15, 0x14, 0x1f, - 0x01, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x24, - 0x11, 0x34, 0x37, 0x33, 0x06, 0x15, 0x14, 0x17, 0x16, 0x02, 0x26, 0xa2, - 0xda, 0x36, 0x34, 0x5f, 0xb7, 0x3e, 0x12, 0x2e, 0x56, 0x02, 0x0f, 0xfe, - 0x68, 0x47, 0x20, 0x94, 0x8e, 0x68, 0x52, 0xa4, 0x63, 0xcf, 0x70, 0x6c, - 0xfe, 0xb6, 0x3f, 0xb8, 0x41, 0xcb, 0x4f, 0x58, 0x6a, 0x3c, 0x39, 0x55, - 0x39, 0x69, 0xca, 0x44, 0x47, 0x54, 0x1f, 0x4f, 0x41, 0x01, 0x8e, 0xd1, - 0xfe, 0xc2, 0x37, 0x2e, 0x3f, 0x23, 0xa2, 0x9b, 0x6f, 0x9d, 0x75, 0x5c, - 0x4e, 0x2f, 0x20, 0x62, 0x01, 0x0b, 0x8a, 0x5c, 0x5e, 0x88, 0x78, 0x48, - 0x1c, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0a, 0xff, 0xa7, 0x05, 0x61, - 0x07, 0x38, 0x10, 0x27, 0x0c, 0xdc, 0x02, 0xaa, 0x00, 0x00, 0x10, 0x06, - 0x04, 0x9e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xff, 0xbd, 0x04, 0x93, - 0x03, 0xe5, 0x00, 0x26, 0x00, 0x36, 0x00, 0x46, 0x00, 0x00, 0x28, 0x01, - 0x27, 0x26, 0x35, 0x34, 0x37, 0x33, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, - 0x32, 0x37, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x17, 0x26, 0x27, - 0x35, 0x16, 0x17, 0x04, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, - 0x27, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, - 0x06, 0x15, 0x14, 0x17, 0x16, 0x25, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, - 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x01, 0xdd, 0xfe, - 0xdc, 0x43, 0x76, 0x10, 0xb8, 0x0e, 0x1e, 0x2d, 0x28, 0x3b, 0x47, 0x2d, - 0x0f, 0x12, 0x2d, 0x30, 0x4d, 0x2c, 0x51, 0xdb, 0xdc, 0x01, 0x05, 0x3b, - 0x0e, 0x28, 0x4a, 0xaf, 0x83, 0x9a, 0x15, 0x24, 0x22, 0x27, 0x0f, 0x16, - 0x3a, 0x41, 0x17, 0x16, 0x07, 0x15, 0x01, 0x47, 0x06, 0x62, 0x0c, 0x11, - 0x34, 0x31, 0x7e, 0x10, 0x07, 0x21, 0x1d, 0x24, 0x40, 0x80, 0x4b, 0x35, - 0x3a, 0x2c, 0x2b, 0x0b, 0x10, 0x0b, 0x69, 0x45, 0x4e, 0x40, 0x54, 0x53, - 0x5a, 0x09, 0x27, 0x0e, 0xb9, 0x43, 0xb4, 0xd6, 0xd9, 0x34, 0x39, 0x67, - 0x3d, 0x71, 0x6c, 0xe4, 0x1b, 0x40, 0x48, 0x3d, 0x2e, 0x25, 0x34, 0x2d, - 0x2b, 0x23, 0x1e, 0x25, 0x76, 0xbc, 0x25, 0x27, 0x8a, 0x72, 0x0e, 0x13, - 0x2e, 0x43, 0x1e, 0x21, 0x3c, 0x4e, 0x45, 0x00, 0xff, 0xff, 0x00, 0x19, - 0xfe, 0xf3, 0x04, 0xd1, 0x03, 0x1c, 0x10, 0x06, 0x04, 0x74, 0x00, 0x00, - 0xff, 0xff, 0x01, 0xfa, 0x01, 0xc2, 0x02, 0xd6, 0x02, 0xbc, 0x10, 0x06, - 0x04, 0x82, 0x00, 0x00, 0xff, 0xff, 0x01, 0x96, 0x00, 0x00, 0x03, 0x3c, - 0x05, 0x14, 0x10, 0x06, 0x04, 0x83, 0x00, 0x00, 0xff, 0xff, 0x00, 0x9a, - 0x00, 0x00, 0x04, 0x38, 0x05, 0x14, 0x10, 0x06, 0x04, 0x84, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x86, 0x00, 0x00, 0x04, 0x4c, 0x05, 0x14, 0x10, 0x06, - 0x04, 0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0xaf, 0x00, 0x00, 0x04, 0x22, - 0x05, 0x25, 0x00, 0x27, 0x00, 0x00, 0x01, 0x26, 0x35, 0x34, 0x37, 0x36, - 0x33, 0x32, 0x17, 0x15, 0x26, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, - 0x16, 0x37, 0x36, 0x37, 0x15, 0x06, 0x23, 0x22, 0x27, 0x16, 0x17, 0x16, - 0x11, 0x23, 0x10, 0x27, 0x02, 0x03, 0x33, 0x16, 0x17, 0x16, 0x02, 0x25, - 0x04, 0x58, 0x5c, 0x6c, 0x54, 0x58, 0x5c, 0x44, 0x38, 0x1e, 0x1f, 0x19, - 0x2f, 0x30, 0x45, 0x8d, 0xc3, 0x3d, 0x8d, 0x92, 0x1b, 0x17, 0x20, 0xb4, - 0x25, 0x31, 0x9c, 0xc7, 0x42, 0x03, 0x1b, 0x04, 0x14, 0x0f, 0x13, 0x78, - 0x3a, 0x3d, 0x19, 0x9c, 0x24, 0x02, 0x01, 0x21, 0x22, 0x15, 0x34, 0x15, - 0x27, 0x02, 0x02, 0x11, 0xb4, 0x1a, 0x51, 0x6a, 0x72, 0x9b, 0xfe, 0x16, - 0x01, 0xa9, 0xdc, 0x01, 0x21, 0x01, 0x6e, 0x9b, 0x05, 0x38, 0x00, 0x00, - 0x00, 0x02, 0x00, 0xac, 0xff, 0xf5, 0x04, 0x24, 0x05, 0x24, 0x00, 0x13, - 0x00, 0x27, 0x00, 0x00, 0x01, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, - 0x27, 0x26, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, - 0x17, 0x06, 0x27, 0x26, 0x27, 0x26, 0x35, 0x10, 0x37, 0x12, 0x33, 0x32, - 0x13, 0x16, 0x13, 0x16, 0x07, 0x06, 0x07, 0x06, 0x02, 0xc2, 0x2d, 0x32, - 0x22, 0x12, 0x1b, 0x57, 0x5a, 0xae, 0x5b, 0x56, 0x1b, 0x0f, 0x25, 0x33, - 0x2c, 0x5a, 0x28, 0x91, 0xa0, 0x2e, 0x35, 0x5f, 0xb3, 0xaa, 0xa2, 0xbb, - 0x5e, 0x01, 0x01, 0x35, 0x33, 0x9c, 0x90, 0x01, 0x5a, 0xa1, 0x4a, 0x6b, - 0x56, 0xd7, 0xd8, 0xe0, 0xe0, 0xd5, 0xda, 0x3c, 0x85, 0x4a, 0xa1, 0xd0, - 0x97, 0x02, 0x02, 0x9c, 0xb5, 0x7c, 0x01, 0x26, 0xc4, 0x01, 0x76, 0xfe, - 0x8a, 0xbb, 0xfe, 0xd1, 0x8d, 0xa4, 0x9d, 0x01, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x08, 0x00, 0x00, 0x03, 0xc8, 0x05, 0x1f, 0x00, 0x20, - 0x00, 0x00, 0x21, 0x12, 0x37, 0x36, 0x37, 0x22, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x36, 0x37, 0x36, 0x17, 0x15, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, - 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x15, 0x06, 0x07, 0x06, 0x07, 0x01, - 0x08, 0x42, 0x6e, 0x44, 0x64, 0x4e, 0x2e, 0x86, 0x62, 0x70, 0x8c, 0x79, - 0x57, 0x56, 0x74, 0x3e, 0x30, 0x42, 0x37, 0x2c, 0x67, 0x8c, 0x60, 0xe1, - 0x6f, 0x86, 0x36, 0x00, 0xff, 0xb5, 0x6f, 0x55, 0x25, 0x6d, 0x97, 0xaf, - 0x60, 0x6d, 0x02, 0x02, 0x21, 0xb4, 0x33, 0x2f, 0x41, 0x62, 0x4d, 0x33, - 0x29, 0x29, 0xb4, 0x49, 0x98, 0xb7, 0xe1, 0x00, 0xff, 0xff, 0x00, 0x7e, - 0x00, 0x00, 0x04, 0x52, 0x05, 0x14, 0x10, 0x06, 0x04, 0x89, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x7e, 0x00, 0x00, 0x04, 0x52, 0x05, 0x14, 0x10, 0x06, - 0x04, 0x8a, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa2, 0x00, 0x00, 0x04, 0x30, - 0x05, 0x1e, 0x10, 0x06, 0x04, 0x8b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x3e, - 0xff, 0xeb, 0x04, 0x64, 0x04, 0x7b, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x2a, - 0x00, 0x3e, 0x40, 0x0d, 0x23, 0x06, 0x25, 0x0a, 0x02, 0x1b, 0x14, 0x0e, - 0x06, 0x16, 0x06, 0x10, 0x2b, 0x10, 0xdc, 0xec, 0xcc, 0xcc, 0xdc, 0x3c, - 0xcc, 0xcc, 0x2f, 0xec, 0x31, 0x00, 0x40, 0x07, 0x00, 0x16, 0x04, 0x12, - 0x99, 0x25, 0x2b, 0x10, 0x3c, 0xf4, 0xcc, 0xdc, 0xcc, 0x40, 0x09, 0x0c, - 0x19, 0x08, 0x28, 0x8c, 0x1d, 0x21, 0xbe, 0x2c, 0x10, 0xfc, 0x3c, 0xec, - 0xcc, 0xdc, 0xcc, 0x30, 0x25, 0x26, 0x15, 0x14, 0x37, 0x36, 0x27, 0x26, - 0x03, 0x26, 0x15, 0x14, 0x37, 0x36, 0x27, 0x26, 0x13, 0x14, 0x23, 0x22, - 0x35, 0x34, 0x37, 0x11, 0x06, 0x23, 0x22, 0x35, 0x34, 0x33, 0x32, 0x17, - 0x36, 0x33, 0x20, 0x19, 0x01, 0x23, 0x11, 0x34, 0x23, 0x22, 0x07, 0x01, - 0x14, 0x3f, 0x3f, 0x42, 0x01, 0x01, 0x4c, 0x3f, 0x3f, 0x42, 0x01, 0x01, - 0xa2, 0xc6, 0xe6, 0xf4, 0x15, 0x15, 0xca, 0xca, 0x91, 0x2c, 0x4c, 0xbd, - 0x01, 0x96, 0xb8, 0xe2, 0x89, 0x57, 0xf4, 0x02, 0x42, 0x41, 0x01, 0x01, - 0x3f, 0x3e, 0x03, 0x05, 0x02, 0x42, 0x41, 0x01, 0x01, 0x3f, 0x3e, 0xfc, - 0xc3, 0xcd, 0xc9, 0xca, 0x06, 0x01, 0x70, 0x08, 0xd0, 0xbf, 0x51, 0x51, - 0xfe, 0xbe, 0xfc, 0xc7, 0x03, 0x39, 0xaa, 0x8e, 0x00, 0x02, 0x00, 0x6c, - 0xff, 0xdd, 0x04, 0xae, 0x04, 0x8c, 0x00, 0x03, 0x00, 0x2c, 0x00, 0x00, - 0x00, 0x22, 0x14, 0x32, 0x07, 0x22, 0x35, 0x34, 0x37, 0x36, 0x37, 0x24, - 0x13, 0x16, 0x05, 0x07, 0x04, 0x17, 0x16, 0x33, 0x32, 0x36, 0x33, 0x32, - 0x17, 0x07, 0x26, 0x23, 0x22, 0x06, 0x23, 0x20, 0x27, 0x34, 0x25, 0x37, - 0x36, 0x35, 0x34, 0x05, 0x06, 0x07, 0x16, 0x17, 0x14, 0x01, 0x82, 0x80, - 0x80, 0x44, 0xd2, 0xbc, 0xbb, 0x97, 0x01, 0xe5, 0x01, 0x02, 0xfe, 0x98, - 0xb6, 0xfe, 0xe3, 0x03, 0x05, 0xe7, 0x4a, 0xd6, 0x50, 0x9e, 0x8a, 0x86, - 0x69, 0x3f, 0x33, 0xcc, 0x6b, 0xfe, 0x5d, 0x01, 0x01, 0xb4, 0xb2, 0xd6, - 0xfe, 0xc8, 0x4b, 0x4d, 0x3f, 0x01, 0x03, 0x6f, 0x80, 0x94, 0xe4, 0x89, - 0x61, 0x62, 0x01, 0x02, 0xfe, 0xa9, 0xed, 0x75, 0x3b, 0x5c, 0x53, 0x66, - 0x8e, 0xd5, 0x61, 0x91, 0x7f, 0xf9, 0xc6, 0x8e, 0x3a, 0x46, 0x82, 0xbd, - 0x03, 0x01, 0x37, 0x38, 0x55, 0xd8, 0x00, 0x00, 0x00, 0x03, 0x00, 0x79, - 0xff, 0xec, 0x04, 0x50, 0x04, 0x8c, 0x00, 0x07, 0x00, 0x11, 0x00, 0x38, - 0x00, 0x00, 0x01, 0x16, 0x33, 0x32, 0x37, 0x26, 0x27, 0x22, 0x13, 0x16, - 0x27, 0x26, 0x23, 0x22, 0x17, 0x14, 0x15, 0x16, 0x25, 0x34, 0x37, 0x26, - 0x37, 0x36, 0x24, 0x17, 0x04, 0x12, 0x19, 0x01, 0x23, 0x11, 0x10, 0x26, - 0x07, 0x0e, 0x01, 0x17, 0x36, 0x37, 0x20, 0x07, 0x14, 0x23, 0x22, 0x27, - 0x06, 0x17, 0x16, 0x17, 0x36, 0x33, 0x32, 0x15, 0x14, 0x07, 0x04, 0x01, - 0x59, 0x36, 0x05, 0x17, 0x30, 0x49, 0x01, 0x12, 0x7f, 0x36, 0x02, 0x03, - 0x31, 0x36, 0x02, 0x01, 0xfe, 0xae, 0x2a, 0x2c, 0x03, 0x06, 0x01, 0x0b, - 0xe5, 0x01, 0x21, 0xbf, 0xb8, 0x7f, 0xa9, 0xb1, 0x9b, 0x03, 0x2a, 0x3a, - 0x01, 0x05, 0x01, 0xfa, 0x39, 0x14, 0x1f, 0x03, 0x02, 0x14, 0x17, 0xab, - 0xcc, 0xcc, 0xfe, 0x75, 0x02, 0x60, 0x14, 0x12, 0x11, 0x01, 0xfe, 0x10, - 0x01, 0x30, 0x27, 0x22, 0x01, 0x03, 0x2f, 0xdc, 0x7f, 0x80, 0x36, 0x4f, - 0xd3, 0xd9, 0x01, 0x01, 0xfe, 0xe0, 0xfe, 0xd6, 0xfd, 0xbf, 0x02, 0x41, - 0x01, 0x01, 0xb7, 0x03, 0x03, 0xb8, 0x4b, 0x12, 0x01, 0xa5, 0xa5, 0x0b, - 0x25, 0x5b, 0x39, 0x2e, 0x8d, 0xc8, 0xb5, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0xf6, 0xfe, 0x18, 0x03, 0xdb, 0x04, 0x8c, 0x00, 0x19, - 0x00, 0x21, 0x00, 0x00, 0x13, 0x34, 0x36, 0x33, 0x20, 0x19, 0x01, 0x10, - 0x06, 0x23, 0x22, 0x26, 0x27, 0x37, 0x16, 0x33, 0x32, 0x35, 0x11, 0x10, - 0x23, 0x16, 0x15, 0x06, 0x27, 0x26, 0x13, 0x26, 0x17, 0x06, 0x37, 0x16, - 0x27, 0x36, 0xf7, 0xa2, 0xdd, 0x01, 0x65, 0x9b, 0xcc, 0xd6, 0x74, 0x0d, - 0xbd, 0x21, 0x79, 0xaf, 0x82, 0x02, 0x06, 0xd7, 0xd1, 0xd7, 0x43, 0x03, - 0x02, 0x42, 0x42, 0x02, 0x01, 0x03, 0xa6, 0x71, 0x75, 0xfd, 0xf4, 0xfd, - 0x8f, 0xfe, 0xf9, 0xf0, 0xd0, 0x8d, 0x0a, 0xd1, 0xf3, 0x02, 0xdf, 0x01, - 0x68, 0x15, 0x21, 0xcf, 0x01, 0x01, 0x01, 0x09, 0x01, 0x41, 0x43, 0x03, - 0x02, 0x42, 0x42, 0x00, 0x00, 0x02, 0x00, 0x7c, 0xff, 0xff, 0x04, 0x55, - 0x04, 0x9a, 0x00, 0x0b, 0x00, 0x29, 0x00, 0x00, 0x01, 0x22, 0x06, 0x15, - 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x03, 0x32, 0x17, 0x16, - 0x19, 0x01, 0x07, 0x13, 0x34, 0x27, 0x14, 0x27, 0x26, 0x35, 0x34, 0x33, - 0x32, 0x17, 0x10, 0x05, 0x06, 0x07, 0x06, 0x1d, 0x01, 0x23, 0x35, 0x34, - 0x37, 0x36, 0x02, 0x6e, 0x24, 0x1c, 0x20, 0x20, 0x25, 0x1b, 0x20, 0x2a, - 0xfa, 0x7c, 0x7b, 0xb8, 0x01, 0x65, 0xc8, 0xd9, 0xda, 0xf4, 0x36, 0xfe, - 0xc4, 0xcf, 0x4c, 0x11, 0xb8, 0x1e, 0x6a, 0x02, 0x60, 0x20, 0x20, 0x25, - 0x1b, 0x22, 0x1e, 0x25, 0x1b, 0x02, 0x3a, 0x79, 0x78, 0xfe, 0xd9, 0xfd, - 0x7e, 0x01, 0x01, 0x29, 0x8e, 0x52, 0xa6, 0x01, 0x02, 0xb7, 0xc0, 0x68, - 0x01, 0x95, 0x05, 0x04, 0x86, 0x1e, 0x86, 0x4b, 0x4b, 0xaa, 0x3e, 0xdc, - 0x00, 0x02, 0x00, 0x61, 0xfe, 0x19, 0x04, 0xc9, 0x04, 0x82, 0x00, 0x0b, - 0x00, 0x39, 0x00, 0x00, 0x01, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, - 0x36, 0x35, 0x34, 0x26, 0x03, 0x26, 0x35, 0x34, 0x35, 0x36, 0x37, 0x36, - 0x37, 0x24, 0x13, 0x16, 0x0d, 0x01, 0x06, 0x17, 0x16, 0x33, 0x32, 0x37, - 0x36, 0x33, 0x32, 0x15, 0x14, 0x13, 0x30, 0x07, 0x02, 0x11, 0x06, 0x21, - 0x20, 0x35, 0x34, 0x2d, 0x01, 0x36, 0x35, 0x34, 0x05, 0x06, 0x07, 0x16, - 0x17, 0x06, 0x01, 0x36, 0x24, 0x1c, 0x20, 0x20, 0x25, 0x1b, 0x20, 0x23, - 0xd2, 0x02, 0xe5, 0x76, 0xca, 0x01, 0xc9, 0x02, 0x01, 0xfe, 0x8a, 0xfe, - 0xfb, 0xa9, 0x05, 0x04, 0xc7, 0xb3, 0x5d, 0x23, 0x78, 0x97, 0x86, 0x90, - 0xb0, 0x2e, 0xfe, 0xa4, 0xfe, 0x7f, 0x01, 0x3e, 0x01, 0x01, 0xe5, 0xfe, - 0xe2, 0x72, 0x3e, 0x3e, 0x01, 0x24, 0x03, 0x6f, 0x20, 0x20, 0x25, 0x1b, - 0x22, 0x1e, 0x25, 0x1b, 0xfe, 0xec, 0x10, 0xd1, 0x02, 0x01, 0x85, 0x7d, - 0x40, 0x01, 0x02, 0xfe, 0xbc, 0xd6, 0x7e, 0x59, 0x39, 0x70, 0x65, 0xb7, - 0x44, 0xd8, 0xf3, 0xfe, 0xb5, 0x51, 0x01, 0x63, 0x01, 0x46, 0xd3, 0xf8, - 0xe2, 0x6c, 0x57, 0x4e, 0x6e, 0xa9, 0x03, 0x01, 0x2d, 0x37, 0x56, 0xbc, - 0x00, 0x02, 0x00, 0x73, 0xff, 0xef, 0x04, 0x5c, 0x04, 0x95, 0x00, 0x0b, - 0x00, 0x2c, 0x00, 0x00, 0x01, 0x32, 0x36, 0x35, 0x34, 0x26, 0x27, 0x26, - 0x06, 0x15, 0x14, 0x16, 0x03, 0x14, 0x21, 0x20, 0x19, 0x01, 0x33, 0x11, - 0x10, 0x25, 0x24, 0x11, 0x34, 0x35, 0x36, 0x37, 0x26, 0x37, 0x12, 0x05, - 0x16, 0x15, 0x14, 0x07, 0x06, 0x27, 0x16, 0x17, 0x16, 0x37, 0x15, 0x07, - 0x06, 0x01, 0xd7, 0x24, 0x1c, 0x21, 0x1f, 0x25, 0x1b, 0x20, 0x82, 0x01, - 0x2f, 0x01, 0x40, 0xb8, 0xfe, 0x08, 0xfe, 0x0f, 0x03, 0xa2, 0xa6, 0x01, - 0x01, 0x01, 0x6c, 0xb4, 0xc0, 0x7e, 0x2e, 0x02, 0x5a, 0x41, 0x90, 0x8d, - 0x93, 0x03, 0xa4, 0x20, 0x20, 0x24, 0x1b, 0x01, 0x01, 0x21, 0x20, 0x24, - 0x1c, 0xfd, 0x8c, 0xae, 0x01, 0xb8, 0x02, 0x3f, 0xfd, 0xc1, 0xfd, 0xb4, - 0x01, 0x01, 0x01, 0x3d, 0x02, 0x01, 0x91, 0x51, 0x6d, 0xea, 0x01, 0x2e, - 0x02, 0x01, 0xb0, 0xba, 0x02, 0x01, 0x75, 0xbd, 0x47, 0x34, 0x0c, 0xa1, - 0x17, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x7b, 0xff, 0xe3, 0x04, 0x56, - 0x04, 0x7b, 0x00, 0x07, 0x00, 0x1c, 0x00, 0x2c, 0x40, 0x09, 0x1b, 0x06, - 0x08, 0x06, 0x10, 0x02, 0x15, 0x06, 0x0e, 0x2f, 0xfc, 0xcc, 0xdc, 0xcc, - 0x2f, 0xec, 0x31, 0x00, 0x40, 0x0c, 0x0b, 0x8c, 0x18, 0xbe, 0x1d, 0x00, - 0x0e, 0x04, 0x12, 0x99, 0x1c, 0x1d, 0x10, 0x3c, 0xf4, 0xcc, 0xdc, 0xcc, - 0x10, 0xfc, 0xfc, 0x30, 0x25, 0x22, 0x15, 0x14, 0x33, 0x32, 0x35, 0x34, - 0x05, 0x11, 0x34, 0x05, 0x04, 0x15, 0x11, 0x24, 0x17, 0x16, 0x23, 0x22, - 0x35, 0x11, 0x34, 0x24, 0x37, 0x36, 0x04, 0x15, 0x11, 0x01, 0x66, 0x40, - 0x40, 0x40, 0x01, 0xf8, 0xfe, 0xca, 0xfe, 0xcb, 0x01, 0x18, 0x01, 0x01, - 0xe7, 0xeb, 0x01, 0x13, 0xda, 0xc5, 0x01, 0x29, 0xeb, 0x40, 0x40, 0x40, - 0x40, 0xeb, 0x03, 0x1f, 0xc9, 0x03, 0x03, 0xc3, 0xfe, 0x50, 0x1b, 0xdf, - 0xc8, 0xc8, 0x02, 0x8e, 0xc7, 0x79, 0x02, 0x02, 0x78, 0xcc, 0xfc, 0xc7, - 0x00, 0x02, 0x00, 0x95, 0xff, 0xe2, 0x04, 0x6f, 0x04, 0xa1, 0x00, 0x0b, - 0x00, 0x2a, 0x00, 0x00, 0x25, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, - 0x36, 0x35, 0x34, 0x26, 0x13, 0x22, 0x02, 0x23, 0x22, 0x07, 0x03, 0x20, - 0x15, 0x14, 0x23, 0x22, 0x35, 0x11, 0x10, 0x33, 0x32, 0x12, 0x33, 0x32, - 0x12, 0x37, 0x32, 0x19, 0x01, 0x23, 0x11, 0x34, 0x23, 0x22, 0x02, 0x01, - 0x80, 0x24, 0x1c, 0x20, 0x20, 0x25, 0x1b, 0x20, 0xe4, 0x7a, 0x77, 0x0f, - 0x36, 0x01, 0x01, 0x01, 0x19, 0xd5, 0xfb, 0xf2, 0x83, 0x5e, 0x22, 0x24, - 0x4a, 0x85, 0xf2, 0xb8, 0x37, 0x16, 0x66, 0xf1, 0x20, 0x20, 0x25, 0x1b, - 0x22, 0x1e, 0x25, 0x1b, 0x01, 0xfa, 0x01, 0x26, 0xe1, 0xfe, 0x50, 0xc4, - 0xda, 0xd2, 0x02, 0x96, 0x01, 0x57, 0xfe, 0xe0, 0x01, 0x1f, 0x01, 0xfe, - 0xa9, 0xfc, 0xb6, 0x03, 0x30, 0xdb, 0xfe, 0xe0, 0x00, 0x03, 0x00, 0x1a, - 0xfe, 0x14, 0x04, 0x3e, 0x04, 0x7b, 0x00, 0x03, 0x00, 0x07, 0x00, 0x23, - 0x00, 0x00, 0x24, 0x22, 0x14, 0x32, 0x00, 0x22, 0x14, 0x32, 0x13, 0x32, - 0x17, 0x16, 0x23, 0x22, 0x35, 0x11, 0x06, 0x23, 0x26, 0x35, 0x36, 0x37, - 0x36, 0x17, 0x36, 0x33, 0x20, 0x16, 0x15, 0x11, 0x23, 0x11, 0x34, 0x23, - 0x22, 0x07, 0x02, 0x26, 0x80, 0x80, 0xfe, 0xed, 0x80, 0x80, 0xa6, 0xf1, - 0x02, 0x02, 0xda, 0xd3, 0x21, 0x1f, 0xa7, 0x01, 0xb3, 0x91, 0x37, 0x79, - 0x8b, 0x01, 0x06, 0x9e, 0xb8, 0xf4, 0x7b, 0x5e, 0xdc, 0x80, 0x03, 0xa6, - 0x80, 0xfd, 0xdd, 0xb9, 0xc3, 0xe3, 0x02, 0x49, 0x07, 0x02, 0xbe, 0xb2, - 0x01, 0x01, 0x65, 0x64, 0xd5, 0x6d, 0xfa, 0xdb, 0x05, 0x25, 0xa3, 0x8b, - 0x00, 0x02, 0x00, 0x6a, 0xff, 0xe3, 0x04, 0x68, 0x04, 0x7b, 0x00, 0x07, - 0x00, 0x27, 0x00, 0x3e, 0x40, 0x07, 0x06, 0x0c, 0x02, 0x08, 0x24, 0x06, - 0x0f, 0x2f, 0xfc, 0x3c, 0xcc, 0xdc, 0xcc, 0x40, 0x07, 0x14, 0x06, 0x20, - 0x18, 0x06, 0x1a, 0x29, 0x10, 0xdc, 0xec, 0xdc, 0xec, 0x31, 0x00, 0x40, - 0x06, 0x11, 0x8c, 0x22, 0x99, 0x1a, 0x29, 0x10, 0x3c, 0xf4, 0xec, 0x40, - 0x09, 0x04, 0x26, 0x00, 0x1d, 0x8c, 0x16, 0x0a, 0xbe, 0x29, 0x10, 0xfc, - 0x3c, 0xec, 0xcc, 0xdc, 0xcc, 0x30, 0x01, 0x26, 0x17, 0x06, 0x37, 0x16, - 0x27, 0x36, 0x05, 0x34, 0x33, 0x32, 0x15, 0x14, 0x06, 0x15, 0x14, 0x33, - 0x32, 0x35, 0x11, 0x34, 0x17, 0x04, 0x15, 0x11, 0x23, 0x11, 0x34, 0x07, - 0x06, 0x15, 0x03, 0x02, 0x25, 0x24, 0x11, 0x10, 0x37, 0x22, 0x01, 0x36, - 0x43, 0x03, 0x02, 0x42, 0x43, 0x03, 0x02, 0xfe, 0xf4, 0xca, 0xd8, 0xfe, - 0xaa, 0xb2, 0xfc, 0x01, 0x00, 0xa4, 0x62, 0x52, 0x01, 0x01, 0xfe, 0xac, - 0xfe, 0xb0, 0xd8, 0xd6, 0x04, 0x12, 0x02, 0x42, 0x43, 0x03, 0x01, 0x41, - 0x43, 0x4b, 0xb1, 0xad, 0xca, 0xe0, 0xd4, 0xd8, 0xbc, 0x02, 0x4a, 0xfe, - 0x01, 0x01, 0xfb, 0xfc, 0x81, 0x03, 0x7f, 0x6a, 0x03, 0x03, 0x65, 0xfd, - 0xb7, 0xfe, 0xad, 0x01, 0x01, 0x01, 0x68, 0x01, 0x30, 0x9a, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x4b, 0xff, 0xe3, 0x04, 0x54, 0x04, 0x8c, 0x00, 0x05, - 0x00, 0x20, 0x00, 0x00, 0x00, 0x32, 0x34, 0x23, 0x22, 0x07, 0x03, 0x35, - 0x33, 0x32, 0x36, 0x35, 0x11, 0x24, 0x35, 0x34, 0x37, 0x36, 0x15, 0x11, - 0x16, 0x37, 0x36, 0x35, 0x11, 0x33, 0x11, 0x10, 0x21, 0x22, 0x27, 0x06, - 0x23, 0x01, 0x03, 0x80, 0x40, 0x3e, 0x02, 0xb8, 0x7a, 0x5d, 0x55, 0xfe, - 0xe8, 0xe2, 0xee, 0x5d, 0x78, 0x98, 0xb8, 0xfe, 0xb4, 0xae, 0x54, 0x72, - 0xd9, 0x03, 0x73, 0x80, 0x40, 0xfc, 0x30, 0x8f, 0x65, 0x9c, 0x01, 0x67, - 0x08, 0xcc, 0xdd, 0x01, 0x01, 0xdb, 0xfd, 0x75, 0xa9, 0x01, 0x01, 0xb1, - 0x03, 0x2f, 0xfc, 0xd1, 0xfe, 0xb2, 0x73, 0x73, 0x00, 0x02, 0x00, 0x7d, - 0xff, 0xef, 0x04, 0x54, 0x04, 0x7c, 0x00, 0x03, 0x00, 0x19, 0x00, 0x00, - 0x00, 0x22, 0x14, 0x32, 0x01, 0x34, 0x37, 0x26, 0x37, 0x36, 0x17, 0x16, - 0x07, 0x06, 0x00, 0x15, 0x16, 0x25, 0x20, 0x19, 0x01, 0x33, 0x11, 0x10, - 0x25, 0x24, 0x01, 0xa9, 0x80, 0x80, 0xfe, 0xd4, 0xb6, 0xb7, 0x01, 0x01, - 0xe5, 0xed, 0x01, 0x01, 0xfe, 0xec, 0x01, 0x01, 0x25, 0x01, 0x3c, 0xb8, - 0xfe, 0x0c, 0xfe, 0x1d, 0x03, 0xee, 0x80, 0xfd, 0xd2, 0xda, 0xc4, 0x26, - 0xb6, 0xc4, 0x02, 0x02, 0xbc, 0x97, 0xfe, 0xd1, 0xa8, 0xcc, 0x01, 0x01, - 0x27, 0x02, 0xb4, 0xfd, 0x4c, 0xfe, 0x42, 0x01, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x7d, 0xff, 0xef, 0x04, 0x54, 0x06, 0x14, 0x00, 0x03, - 0x00, 0x19, 0x00, 0x00, 0x00, 0x22, 0x14, 0x32, 0x01, 0x34, 0x37, 0x26, - 0x37, 0x36, 0x17, 0x16, 0x07, 0x06, 0x00, 0x15, 0x16, 0x21, 0x20, 0x19, - 0x01, 0x33, 0x11, 0x10, 0x25, 0x24, 0x01, 0xa9, 0x80, 0x80, 0xfe, 0xd4, - 0xb6, 0xb7, 0x01, 0x01, 0xe5, 0xed, 0x01, 0x01, 0xfe, 0xec, 0x01, 0x01, - 0x25, 0x01, 0x3c, 0xb8, 0xfe, 0x0c, 0xfe, 0x1d, 0x03, 0xee, 0x80, 0xfd, - 0xd2, 0xda, 0xc4, 0x26, 0xb6, 0xc4, 0x02, 0x02, 0xbc, 0x97, 0xfe, 0xd1, - 0xa8, 0xcb, 0x01, 0x27, 0x04, 0x68, 0xfb, 0x98, 0xfe, 0x42, 0x01, 0x01, - 0x00, 0x03, 0x00, 0x63, 0xff, 0xef, 0x04, 0xf5, 0x05, 0x1b, 0x00, 0x0b, - 0x00, 0x17, 0x00, 0x4a, 0x00, 0x00, 0x01, 0x22, 0x06, 0x15, 0x14, 0x16, - 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x05, 0x22, 0x06, 0x15, 0x14, 0x16, - 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x01, 0x2b, 0x01, 0x26, 0x27, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x35, 0x11, 0x34, 0x33, 0x32, 0x15, 0x06, 0x27, - 0x10, 0x15, 0x14, 0x33, 0x32, 0x35, 0x11, 0x33, 0x11, 0x14, 0x37, 0x36, - 0x35, 0x11, 0x26, 0x37, 0x34, 0x17, 0x16, 0x17, 0x36, 0x35, 0x26, 0x27, - 0x37, 0x16, 0x17, 0x16, 0x07, 0x13, 0x14, 0x07, 0x06, 0x03, 0x84, 0x24, - 0x1c, 0x20, 0x20, 0x25, 0x1b, 0x20, 0xfd, 0x92, 0x24, 0x1c, 0x20, 0x20, - 0x26, 0x1a, 0x20, 0x01, 0xe0, 0x02, 0x02, 0x63, 0x67, 0x65, 0x85, 0x7e, - 0x50, 0x4c, 0xd2, 0xd8, 0x01, 0xf1, 0x66, 0x8a, 0xb8, 0x72, 0x74, 0xf3, - 0x01, 0xd0, 0xb3, 0x1b, 0x1e, 0x01, 0x4a, 0x77, 0x54, 0x01, 0x03, 0x98, - 0x02, 0x5c, 0x55, 0x03, 0xfa, 0x20, 0x20, 0x26, 0x1a, 0x22, 0x1e, 0x24, - 0x1c, 0x01, 0x20, 0x20, 0x25, 0x1b, 0x22, 0x1e, 0x25, 0x1b, 0xfb, 0xf6, - 0x01, 0x49, 0x4a, 0x54, 0x4f, 0x9a, 0x02, 0x62, 0xdf, 0xc5, 0xc7, 0x17, - 0xfe, 0x6f, 0x3b, 0x84, 0x84, 0x01, 0x34, 0xfe, 0xcb, 0x8b, 0x05, 0x05, - 0x82, 0x01, 0xcc, 0x08, 0xa8, 0xd1, 0x01, 0x01, 0x98, 0x16, 0x50, 0x36, - 0x41, 0x5e, 0x67, 0x5b, 0xc3, 0x6f, 0xfe, 0x06, 0xa4, 0x50, 0x49, 0x00, - 0x00, 0x02, 0x00, 0x63, 0xff, 0xef, 0x04, 0x62, 0x06, 0x14, 0x00, 0x24, - 0x00, 0x30, 0x00, 0x00, 0x01, 0x14, 0x07, 0x06, 0x2b, 0x02, 0x26, 0x27, - 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x11, 0x34, 0x33, 0x32, 0x15, 0x06, - 0x27, 0x10, 0x15, 0x14, 0x33, 0x32, 0x35, 0x11, 0x33, 0x11, 0x14, 0x37, - 0x36, 0x35, 0x11, 0x33, 0x01, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, - 0x36, 0x35, 0x34, 0x26, 0x04, 0x62, 0x5c, 0x55, 0x7b, 0x02, 0x02, 0x63, - 0x67, 0x65, 0x85, 0x7e, 0x50, 0x4c, 0xd2, 0xd8, 0x01, 0xf1, 0x66, 0x8a, - 0xb8, 0x72, 0x74, 0xb8, 0xfc, 0xd4, 0x24, 0x1c, 0x20, 0x20, 0x26, 0x1a, - 0x20, 0x01, 0x2c, 0xa4, 0x50, 0x49, 0x01, 0x49, 0x4a, 0x54, 0x4f, 0x9a, - 0x02, 0x62, 0xdf, 0xc5, 0xc7, 0x17, 0xfe, 0x6f, 0x3b, 0x84, 0x84, 0x01, - 0x34, 0xfe, 0xcb, 0x8b, 0x05, 0x05, 0x82, 0x04, 0xe8, 0xfd, 0xe5, 0x20, - 0x20, 0x25, 0x1b, 0x22, 0x1e, 0x25, 0x1b, 0x00, 0x00, 0x02, 0x00, 0x65, - 0xff, 0xef, 0x04, 0x6c, 0x04, 0x7d, 0x00, 0x0b, 0x00, 0x2c, 0x00, 0x00, - 0x01, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, - 0x13, 0x32, 0x35, 0x11, 0x33, 0x11, 0x06, 0x37, 0x36, 0x35, 0x11, 0x33, - 0x11, 0x10, 0x25, 0x26, 0x27, 0x06, 0x23, 0x20, 0x11, 0x34, 0x37, 0x26, - 0x37, 0x36, 0x17, 0x16, 0x07, 0x06, 0x00, 0x17, 0x14, 0x01, 0x62, 0x24, - 0x1c, 0x20, 0x20, 0x24, 0x1c, 0x20, 0x30, 0x6e, 0xb8, 0x01, 0x75, 0x68, - 0xb8, 0xfe, 0xe0, 0x69, 0x67, 0x65, 0x8f, 0xfe, 0xde, 0x98, 0x8a, 0x02, - 0x02, 0xe4, 0xed, 0x01, 0x02, 0xfe, 0xd6, 0x02, 0x03, 0xd2, 0x20, 0x20, - 0x25, 0x1b, 0x22, 0x1e, 0x25, 0x1b, 0xfc, 0xb3, 0xa7, 0x01, 0x34, 0xfe, - 0xcb, 0xae, 0x05, 0x05, 0xa5, 0x03, 0x2f, 0xfc, 0xd1, 0xfe, 0xc0, 0x03, - 0x01, 0x49, 0x4a, 0x01, 0x3d, 0xf0, 0xa6, 0x25, 0x9e, 0xf9, 0x01, 0x01, - 0xdb, 0x8f, 0xfe, 0xaa, 0x90, 0xa7, 0x00, 0x00, 0x00, 0x02, 0x00, 0x65, - 0xff, 0xef, 0x04, 0x6c, 0x06, 0x14, 0x00, 0x0b, 0x00, 0x2c, 0x00, 0x00, - 0x01, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, - 0x13, 0x32, 0x35, 0x11, 0x33, 0x11, 0x06, 0x37, 0x36, 0x35, 0x11, 0x33, - 0x11, 0x10, 0x25, 0x26, 0x27, 0x06, 0x23, 0x20, 0x11, 0x34, 0x37, 0x26, - 0x37, 0x36, 0x17, 0x16, 0x07, 0x06, 0x00, 0x17, 0x14, 0x01, 0x62, 0x24, - 0x1c, 0x20, 0x20, 0x24, 0x1c, 0x20, 0x30, 0x6e, 0xb8, 0x01, 0x75, 0x68, - 0xb8, 0xfe, 0xe0, 0x69, 0x67, 0x65, 0x8f, 0xfe, 0xde, 0x98, 0x8a, 0x02, - 0x02, 0xe4, 0xed, 0x01, 0x02, 0xfe, 0xd6, 0x02, 0x03, 0xd2, 0x20, 0x20, - 0x25, 0x1b, 0x22, 0x1e, 0x25, 0x1b, 0xfc, 0xb3, 0xa7, 0x01, 0x34, 0xfe, - 0xcb, 0xaf, 0x06, 0x05, 0xa5, 0x04, 0xe8, 0xfb, 0x18, 0xfe, 0xc0, 0x03, - 0x01, 0x49, 0x4a, 0x01, 0x3d, 0xf0, 0xa6, 0x25, 0x9e, 0xf9, 0x01, 0x01, - 0xdb, 0x8f, 0xfe, 0xaa, 0x90, 0xa7, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, - 0xff, 0xe3, 0x04, 0x60, 0x04, 0x60, 0x00, 0x17, 0x00, 0x00, 0x01, 0x33, - 0x11, 0x10, 0x33, 0x32, 0x19, 0x01, 0x33, 0x11, 0x10, 0x21, 0x22, 0x27, - 0x06, 0x23, 0x22, 0x35, 0x34, 0x33, 0x32, 0x07, 0x32, 0x35, 0x01, 0x63, - 0xb8, 0xbd, 0xd0, 0xb8, 0xfe, 0x78, 0xf0, 0x29, 0x33, 0xb6, 0xc6, 0x9c, - 0x90, 0x02, 0x29, 0x04, 0x60, 0xfd, 0x2c, 0xfe, 0xed, 0x01, 0x13, 0x02, - 0xd4, 0xfc, 0xc5, 0xfe, 0xbe, 0x38, 0x38, 0x9c, 0x96, 0x7b, 0x8b, 0x00, - 0x00, 0x02, 0x00, 0x73, 0xff, 0xef, 0x04, 0x5c, 0x06, 0x14, 0x00, 0x0b, - 0x00, 0x2c, 0x00, 0x00, 0x01, 0x32, 0x36, 0x35, 0x34, 0x26, 0x27, 0x26, - 0x06, 0x15, 0x14, 0x16, 0x03, 0x14, 0x21, 0x20, 0x19, 0x01, 0x33, 0x11, - 0x10, 0x25, 0x24, 0x11, 0x34, 0x35, 0x36, 0x37, 0x26, 0x37, 0x12, 0x05, - 0x16, 0x15, 0x14, 0x07, 0x06, 0x27, 0x16, 0x17, 0x16, 0x37, 0x15, 0x07, - 0x06, 0x01, 0xd7, 0x24, 0x1c, 0x21, 0x1f, 0x25, 0x1b, 0x20, 0x82, 0x01, - 0x2f, 0x01, 0x40, 0xb8, 0xfe, 0x08, 0xfe, 0x0f, 0x03, 0xa2, 0xa6, 0x01, - 0x01, 0x01, 0x6c, 0xb4, 0xc0, 0x7e, 0x2e, 0x02, 0x5a, 0x41, 0x90, 0x8d, - 0x93, 0x03, 0xa4, 0x20, 0x20, 0x24, 0x1b, 0x01, 0x01, 0x21, 0x20, 0x24, - 0x1c, 0xfd, 0x8c, 0xae, 0x01, 0xb8, 0x03, 0xda, 0xfc, 0x26, 0xfd, 0xb4, - 0x01, 0x01, 0x01, 0x3d, 0x02, 0x01, 0x91, 0x51, 0x6d, 0xea, 0x01, 0x2e, - 0x02, 0x01, 0xb0, 0xba, 0x02, 0x01, 0x75, 0xbd, 0x47, 0x34, 0x0c, 0xa1, - 0x17, 0x18, 0x00, 0x00, 0x00, 0x02, 0x00, 0x64, 0xff, 0xef, 0x04, 0x6d, - 0x04, 0x8c, 0x00, 0x0b, 0x00, 0x2b, 0x00, 0x00, 0x01, 0x22, 0x06, 0x15, - 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x05, 0x26, 0x21, 0x20, - 0x13, 0x12, 0x21, 0x20, 0x17, 0x07, 0x26, 0x07, 0x04, 0x17, 0x16, 0x05, - 0x04, 0x03, 0x02, 0x25, 0x24, 0x26, 0x37, 0x36, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x16, 0x37, 0x36, 0x01, 0x3d, 0x24, 0x1c, 0x20, 0x20, 0x24, 0x1c, - 0x20, 0x02, 0x57, 0x01, 0xfe, 0xbd, 0xfd, 0xf3, 0x01, 0x01, 0x02, 0x15, - 0x01, 0x36, 0xb8, 0x74, 0xb1, 0xd3, 0xfe, 0xa9, 0x03, 0x05, 0x01, 0x6d, - 0x01, 0xe1, 0x03, 0x02, 0xfe, 0x32, 0xfe, 0xa7, 0xdf, 0x01, 0x01, 0xd2, - 0xe0, 0x16, 0x4a, 0x8e, 0xdb, 0x01, 0x58, 0x20, 0x20, 0x24, 0x1c, 0x20, - 0x20, 0x24, 0x1c, 0x10, 0xe8, 0x01, 0x38, 0x01, 0x24, 0xdc, 0x7b, 0xbc, - 0x01, 0x02, 0x8a, 0x9e, 0x01, 0x01, 0xfe, 0x90, 0xfe, 0x9a, 0x01, 0x01, - 0xb2, 0x7b, 0xcc, 0x01, 0x01, 0xd1, 0x4e, 0x14, 0x26, 0x01, 0x02, 0x00, - 0x00, 0x02, 0x00, 0x61, 0xff, 0xef, 0x04, 0x70, 0x04, 0x8c, 0x00, 0x0b, - 0x00, 0x2e, 0x00, 0x00, 0x25, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, - 0x36, 0x35, 0x34, 0x26, 0x01, 0x04, 0x19, 0x01, 0x14, 0x25, 0x26, 0x02, - 0x27, 0x26, 0x07, 0x16, 0x07, 0x06, 0x27, 0x26, 0x37, 0x12, 0x21, 0x32, - 0x12, 0x37, 0x36, 0x35, 0x11, 0x10, 0x21, 0x22, 0x07, 0x06, 0x07, 0x27, - 0x36, 0x37, 0x36, 0x01, 0x46, 0x25, 0x1b, 0x20, 0x20, 0x24, 0x1c, 0x20, - 0x01, 0x08, 0x02, 0x02, 0xfe, 0xf4, 0xe8, 0x57, 0x8b, 0x44, 0x0c, 0xe3, - 0x02, 0x02, 0xcf, 0xfa, 0x01, 0x01, 0x01, 0x4e, 0xe8, 0x62, 0x66, 0x50, - 0xfe, 0xc6, 0xe5, 0x27, 0x1a, 0x02, 0xb7, 0x06, 0x11, 0x47, 0xf8, 0x21, - 0x1f, 0x24, 0x1c, 0x20, 0x20, 0x24, 0x1b, 0x03, 0x95, 0x01, 0xfe, 0x89, - 0xfd, 0xd4, 0xfa, 0x01, 0x01, 0x01, 0xdd, 0x02, 0x01, 0x54, 0x01, 0xb7, - 0xd6, 0x01, 0x01, 0xeb, 0x01, 0x89, 0xfe, 0x1e, 0x02, 0x02, 0xae, 0x01, - 0xa8, 0x01, 0x18, 0x72, 0x4a, 0x63, 0x14, 0x6f, 0x3c, 0xf9, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x6f, 0xff, 0xe5, 0x04, 0x62, 0x04, 0x7b, 0x00, 0x05, - 0x00, 0x1f, 0x00, 0x00, 0x01, 0x22, 0x14, 0x33, 0x32, 0x36, 0x01, 0x12, - 0x21, 0x20, 0x19, 0x01, 0x10, 0x25, 0x26, 0x24, 0x27, 0x34, 0x17, 0x32, - 0x17, 0x16, 0x07, 0x16, 0x33, 0x20, 0x35, 0x11, 0x34, 0x21, 0x20, 0x07, - 0x01, 0x50, 0x40, 0x40, 0x3c, 0x08, 0xfe, 0xf4, 0x29, 0x01, 0xbd, 0x01, - 0xf4, 0xfe, 0x22, 0xf0, 0xfe, 0xdc, 0x01, 0xe5, 0xd9, 0x04, 0x01, 0x46, - 0x19, 0x7f, 0x01, 0x1e, 0xfe, 0xcc, 0xfe, 0xe9, 0x18, 0x01, 0x54, 0x80, - 0x80, 0x01, 0xce, 0x01, 0x59, 0xfe, 0xd7, 0xfd, 0xb8, 0xfe, 0xd9, 0x02, - 0x01, 0x9c, 0x8f, 0xd3, 0x01, 0xd7, 0x3d, 0x49, 0x08, 0xd8, 0x01, 0xc4, - 0xcc, 0xd5, 0x00, 0x00, 0x00, 0x03, 0x00, 0x62, 0xff, 0xef, 0x05, 0x22, - 0x05, 0x9c, 0x00, 0x0b, 0x00, 0x32, 0x00, 0x3a, 0x00, 0x00, 0x25, 0x22, - 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x25, 0x11, - 0x06, 0x21, 0x24, 0x37, 0x36, 0x21, 0x20, 0x17, 0x36, 0x27, 0x26, 0x27, - 0x37, 0x16, 0x17, 0x16, 0x07, 0x11, 0x14, 0x25, 0x26, 0x02, 0x27, 0x26, - 0x07, 0x16, 0x07, 0x06, 0x27, 0x26, 0x37, 0x12, 0x21, 0x32, 0x12, 0x37, - 0x36, 0x01, 0x20, 0x35, 0x34, 0x21, 0x20, 0x15, 0x14, 0x01, 0x48, 0x26, - 0x1a, 0x20, 0x20, 0x24, 0x1c, 0x20, 0x02, 0x4a, 0x46, 0xfe, 0xea, 0xfe, - 0x0a, 0x02, 0x02, 0x01, 0xf2, 0x01, 0x8e, 0x72, 0x1c, 0x02, 0x0b, 0x63, - 0x9e, 0x80, 0x02, 0x02, 0xb2, 0xfe, 0xf4, 0xe8, 0x58, 0x8a, 0x44, 0x0c, - 0xe2, 0x02, 0x02, 0xce, 0xfb, 0x01, 0x02, 0x01, 0x4e, 0xe8, 0x62, 0x66, - 0x50, 0xfe, 0xa4, 0x01, 0x74, 0xfe, 0x8c, 0xfe, 0xb6, 0xf8, 0x21, 0x1f, - 0x24, 0x1c, 0x20, 0x20, 0x24, 0x1b, 0x3d, 0x01, 0x99, 0x0e, 0x01, 0xfc, - 0xe9, 0x9a, 0x31, 0x12, 0x54, 0x84, 0x76, 0xae, 0xa0, 0x92, 0x97, 0xfd, - 0xc3, 0xfa, 0x01, 0x01, 0x01, 0xdd, 0x02, 0x01, 0x54, 0x01, 0xb7, 0xd6, - 0x01, 0x01, 0xeb, 0x01, 0x89, 0xfe, 0x1e, 0x02, 0x02, 0x02, 0xd1, 0x45, - 0x6d, 0x4d, 0x64, 0x00, 0x00, 0x03, 0x00, 0x14, 0xff, 0xe8, 0x04, 0xbd, - 0x04, 0x99, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x36, 0x00, 0x00, 0x00, 0x22, - 0x15, 0x06, 0x33, 0x32, 0x37, 0x24, 0x22, 0x15, 0x06, 0x33, 0x32, 0x37, - 0x03, 0x24, 0x11, 0x10, 0x37, 0x26, 0x37, 0x36, 0x17, 0x16, 0x07, 0x0e, - 0x01, 0x11, 0x14, 0x33, 0x36, 0x35, 0x11, 0x06, 0x2b, 0x01, 0x26, 0x37, - 0x36, 0x33, 0x32, 0x17, 0x36, 0x37, 0x36, 0x19, 0x01, 0x23, 0x11, 0x34, - 0x23, 0x22, 0x07, 0x13, 0x10, 0x01, 0x1a, 0x80, 0x01, 0x41, 0x3f, 0x01, - 0x01, 0x91, 0x80, 0x01, 0x41, 0x3f, 0x01, 0xee, 0xfe, 0x60, 0x82, 0x8c, - 0x01, 0x01, 0xc6, 0xbe, 0x01, 0x01, 0xba, 0xdf, 0xe1, 0x14, 0x1d, 0x02, - 0xb9, 0x01, 0x01, 0xa6, 0xa2, 0x35, 0x40, 0x56, 0xf7, 0xb8, 0x43, 0x3f, - 0x2f, 0x01, 0x04, 0x1a, 0x40, 0x40, 0x40, 0x4c, 0x40, 0x40, 0x40, 0xfc, - 0x02, 0x01, 0x01, 0x45, 0x01, 0x3e, 0xa9, 0x2f, 0x99, 0xb5, 0x01, 0x01, - 0xb2, 0x7d, 0xcc, 0xfe, 0x9f, 0xb6, 0x01, 0xb5, 0x02, 0x08, 0x09, 0x06, - 0xb7, 0xa9, 0x63, 0x62, 0x01, 0x04, 0xfe, 0xba, 0xfc, 0xa9, 0x03, 0x57, - 0x9d, 0x5a, 0xfd, 0x9a, 0xfe, 0xb3, 0x00, 0x00, 0x00, 0x03, 0x00, 0x77, - 0xff, 0xef, 0x04, 0x6a, 0x04, 0x8c, 0x00, 0x0b, 0x00, 0x25, 0x00, 0x2d, - 0x00, 0x00, 0x01, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, - 0x34, 0x26, 0x37, 0x24, 0x11, 0x10, 0x05, 0x04, 0x19, 0x01, 0x14, 0x25, - 0x26, 0x27, 0x26, 0x37, 0x36, 0x17, 0x16, 0x15, 0x14, 0x07, 0x16, 0x33, - 0x20, 0x35, 0x11, 0x06, 0x13, 0x34, 0x05, 0x04, 0x07, 0x06, 0x05, 0x04, - 0x01, 0x5c, 0x24, 0x1c, 0x20, 0x20, 0x25, 0x1b, 0x20, 0xf4, 0xfe, 0x07, - 0x01, 0xf9, 0x01, 0xfa, 0xfe, 0x0a, 0xca, 0xaa, 0x86, 0x01, 0x01, 0xdc, - 0xed, 0x3d, 0x41, 0x38, 0x01, 0x29, 0x53, 0x55, 0xfe, 0xc4, 0xfe, 0xc0, - 0x01, 0x01, 0x01, 0x42, 0x01, 0x3c, 0x01, 0x53, 0x20, 0x20, 0x25, 0x1b, - 0x22, 0x1e, 0x24, 0x1c, 0xd0, 0x01, 0x01, 0x33, 0x01, 0x36, 0x01, 0x01, - 0xfe, 0xd1, 0xfd, 0x8c, 0xfb, 0x02, 0x01, 0x48, 0x39, 0xaa, 0xd7, 0x01, - 0x01, 0xd8, 0x47, 0x29, 0x23, 0xaf, 0x01, 0x24, 0x36, 0x01, 0x37, 0x9c, - 0x01, 0x01, 0x9a, 0x9f, 0x01, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x55, - 0xff, 0xef, 0x04, 0xda, 0x04, 0xd8, 0x00, 0x0b, 0x00, 0x36, 0x00, 0x00, - 0x01, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, - 0x01, 0x24, 0x27, 0x26, 0x25, 0x24, 0x37, 0x36, 0x21, 0x32, 0x17, 0x16, - 0x33, 0x32, 0x13, 0x17, 0x02, 0x07, 0x06, 0x27, 0x26, 0x23, 0x22, 0x17, - 0x16, 0x05, 0x04, 0x03, 0x02, 0x25, 0x24, 0x27, 0x26, 0x37, 0x36, 0x17, - 0x16, 0x15, 0x14, 0x15, 0x06, 0x07, 0x16, 0x01, 0x32, 0x24, 0x1c, 0x20, - 0x20, 0x25, 0x1b, 0x20, 0x01, 0x00, 0x01, 0x54, 0x01, 0x01, 0xfe, 0xc0, - 0xfd, 0xfe, 0x03, 0x03, 0x01, 0x9e, 0x88, 0x5c, 0x6f, 0x45, 0x68, 0x40, - 0x94, 0x4d, 0xf3, 0x87, 0x71, 0x4b, 0x55, 0xd2, 0x05, 0x05, 0x01, 0x50, - 0x01, 0xe6, 0x01, 0x01, 0xfd, 0xf0, 0xfe, 0xec, 0x88, 0x6e, 0x01, 0x01, - 0xe0, 0xd7, 0x01, 0x5e, 0x99, 0x01, 0x8b, 0x20, 0x20, 0x25, 0x1b, 0x22, - 0x1e, 0x25, 0x1b, 0xfe, 0xf9, 0x02, 0xfe, 0xc3, 0x2b, 0x44, 0xe7, 0xfc, - 0x59, 0x6c, 0x01, 0x04, 0x30, 0xfe, 0x95, 0x01, 0x01, 0x79, 0x50, 0x5e, - 0x64, 0x36, 0x51, 0xfe, 0xc1, 0xfe, 0x71, 0x02, 0x01, 0x74, 0x5e, 0x7d, - 0xdf, 0x01, 0x01, 0xd6, 0x02, 0x01, 0x5d, 0x46, 0x1c, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x30, 0xff, 0x26, 0x04, 0xa9, 0x04, 0xa1, 0x00, 0x03, - 0x00, 0x24, 0x00, 0x00, 0x00, 0x22, 0x14, 0x32, 0x03, 0x27, 0x01, 0x00, - 0x27, 0x26, 0x0f, 0x01, 0x06, 0x27, 0x24, 0x03, 0x02, 0x21, 0x20, 0x07, - 0x06, 0x27, 0x26, 0x35, 0x22, 0x15, 0x14, 0x33, 0x32, 0x3f, 0x01, 0x36, - 0x17, 0x16, 0x15, 0x14, 0x01, 0x02, 0x2a, 0x80, 0x80, 0xca, 0x81, 0x02, - 0x2b, 0x01, 0x18, 0x3d, 0x19, 0x78, 0xa5, 0x82, 0xd7, 0xfe, 0xe2, 0x07, - 0x09, 0x01, 0x88, 0x01, 0x0f, 0x01, 0x01, 0xd3, 0xd4, 0x23, 0x65, 0x73, - 0x5a, 0x8c, 0xaf, 0x68, 0xe0, 0xfe, 0xe1, 0x04, 0x0d, 0x80, 0xfb, 0x99, - 0x86, 0x02, 0x4e, 0x01, 0x29, 0x3d, 0x19, 0x89, 0xbb, 0x93, 0x01, 0x01, - 0x01, 0x6d, 0x01, 0x90, 0xce, 0xd8, 0x03, 0x04, 0xcd, 0xcd, 0xc3, 0x64, - 0x9d, 0xc4, 0x02, 0x05, 0xbd, 0x9d, 0xfe, 0xcf, 0xff, 0xff, 0x00, 0x5b, - 0xff, 0xe5, 0x04, 0x64, 0x04, 0x80, 0x10, 0x27, 0x04, 0xc9, 0x04, 0xd1, - 0xfa, 0xc9, 0x10, 0x07, 0x04, 0xc9, 0x04, 0xd1, 0xfd, 0x75, 0x00, 0x00, - 0x00, 0x02, 0xfb, 0x8a, 0x05, 0x1c, 0xff, 0x93, 0x07, 0x0b, 0x00, 0x13, - 0x00, 0x1a, 0x00, 0x00, 0x03, 0x02, 0x21, 0x20, 0x26, 0x37, 0x36, 0x17, - 0x32, 0x07, 0x06, 0x07, 0x16, 0x33, 0x24, 0x35, 0x34, 0x27, 0x37, 0x16, - 0x04, 0x34, 0x07, 0x22, 0x15, 0x06, 0x17, 0x6d, 0x02, 0xfe, 0x05, 0xfe, - 0xb6, 0xc3, 0x01, 0x01, 0xe5, 0xf1, 0x03, 0x01, 0x23, 0x21, 0x41, 0x01, - 0x1c, 0x56, 0x8a, 0xa8, 0xfd, 0x1c, 0x42, 0x38, 0x01, 0x3f, 0x06, 0x1d, - 0xfe, 0xff, 0xa8, 0x6b, 0xd9, 0x01, 0xd8, 0x50, 0x24, 0x04, 0x01, 0x55, - 0x2e, 0x46, 0x8a, 0x8f, 0x8c, 0x7e, 0x01, 0x3e, 0x3d, 0x01, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x9d, 0x00, 0x00, 0x04, 0x21, 0x04, 0x7b, 0x00, 0x10, - 0x00, 0x16, 0x00, 0x00, 0x01, 0x20, 0x19, 0x01, 0x23, 0x11, 0x10, 0x23, - 0x22, 0x07, 0x32, 0x15, 0x14, 0x23, 0x22, 0x35, 0x10, 0x12, 0x14, 0x33, - 0x32, 0x34, 0x23, 0x02, 0x6a, 0x01, 0xb7, 0xb8, 0xff, 0xa4, 0x3d, 0xda, - 0xe5, 0xe1, 0xa6, 0x3b, 0x43, 0x3e, 0x04, 0x7b, 0xfe, 0x6a, 0xfd, 0x1b, - 0x02, 0xcb, 0x01, 0x19, 0x56, 0xc1, 0xc7, 0xc7, 0x01, 0xae, 0xfe, 0x89, - 0x6e, 0x6e, 0x00, 0x00, 0xff, 0xff, 0xfc, 0xc5, 0x00, 0x00, 0x04, 0x21, - 0x06, 0x72, 0x10, 0x26, 0x04, 0xca, 0x00, 0x00, 0x10, 0x07, 0x04, 0xd9, - 0xfb, 0x2f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x53, 0x04, 0xec, 0x04, 0x7e, - 0x07, 0x69, 0x00, 0x11, 0x00, 0x00, 0x01, 0x14, 0x21, 0x15, 0x20, 0x11, - 0x10, 0x21, 0x20, 0x11, 0x10, 0x21, 0x35, 0x20, 0x37, 0x34, 0x21, 0x20, - 0x01, 0x12, 0x01, 0x24, 0xfe, 0x1e, 0x02, 0x26, 0x02, 0x04, 0xfe, 0x3e, - 0x01, 0x02, 0x02, 0xfe, 0xba, 0xfe, 0x98, 0x06, 0x25, 0xbb, 0x7e, 0x01, - 0x3f, 0x01, 0x3e, 0xfe, 0xc2, 0xfe, 0xc1, 0x7e, 0xbb, 0xc5, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x53, 0x04, 0xe6, 0x05, 0x13, 0x07, 0x69, 0x00, 0x15, - 0x00, 0x00, 0x01, 0x14, 0x21, 0x15, 0x20, 0x11, 0x10, 0x21, 0x20, 0x11, - 0x14, 0x07, 0x33, 0x15, 0x21, 0x3d, 0x01, 0x20, 0x37, 0x34, 0x21, 0x20, - 0x01, 0x11, 0x01, 0x25, 0xfe, 0x1d, 0x02, 0x26, 0x02, 0x04, 0x3e, 0xd4, - 0xfd, 0xa9, 0x01, 0x01, 0x02, 0xfe, 0xba, 0xfe, 0x98, 0x06, 0x25, 0xbb, - 0x7e, 0x01, 0x3f, 0x01, 0x3e, 0xfe, 0xc2, 0x77, 0x4a, 0x84, 0x06, 0x7e, - 0xbb, 0xc5, 0x00, 0x00, 0x00, 0x02, 0x00, 0x53, 0x04, 0xec, 0x04, 0x7e, - 0x07, 0x69, 0x00, 0x11, 0x00, 0x15, 0x00, 0x00, 0x01, 0x14, 0x21, 0x15, - 0x20, 0x11, 0x10, 0x21, 0x20, 0x11, 0x10, 0x21, 0x35, 0x20, 0x37, 0x34, - 0x21, 0x20, 0x05, 0x15, 0x23, 0x35, 0x01, 0x12, 0x01, 0x24, 0xfe, 0x1e, - 0x02, 0x26, 0x02, 0x04, 0xfe, 0x3e, 0x01, 0x02, 0x02, 0xfe, 0xba, 0xfe, - 0x98, 0x01, 0xde, 0xee, 0x06, 0x25, 0xbb, 0x7e, 0x01, 0x3f, 0x01, 0x3e, - 0xfe, 0xc2, 0xfe, 0xc1, 0x7e, 0xbb, 0xc5, 0x4e, 0xdc, 0xdc, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x53, 0x04, 0xe6, 0x05, 0x13, 0x07, 0x69, 0x00, 0x15, - 0x00, 0x19, 0x00, 0x00, 0x01, 0x14, 0x21, 0x15, 0x20, 0x11, 0x10, 0x21, - 0x20, 0x11, 0x14, 0x07, 0x33, 0x15, 0x21, 0x3d, 0x01, 0x20, 0x37, 0x34, - 0x21, 0x20, 0x05, 0x15, 0x23, 0x35, 0x01, 0x11, 0x01, 0x25, 0xfe, 0x1d, - 0x02, 0x26, 0x02, 0x04, 0x3e, 0xd4, 0xfd, 0xa9, 0x01, 0x01, 0x02, 0xfe, - 0xba, 0xfe, 0x98, 0x01, 0xdd, 0xee, 0x06, 0x25, 0xbb, 0x7e, 0x01, 0x3f, - 0x01, 0x3e, 0xfe, 0xc2, 0x77, 0x4a, 0x84, 0x06, 0x7e, 0xbb, 0xc5, 0x54, - 0xdc, 0xdc, 0x00, 0x00, 0x00, 0x02, 0x01, 0xcf, 0xfd, 0x33, 0x03, 0x87, - 0xff, 0xb2, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x04, 0x22, 0x14, 0x33, - 0x36, 0x03, 0x36, 0x35, 0x34, 0x27, 0x06, 0x23, 0x22, 0x35, 0x34, 0x33, - 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x02, 0xbf, 0x82, 0x41, 0x41, 0x5c, - 0x90, 0x05, 0x28, 0x44, 0xb3, 0xaa, 0x65, 0x4e, 0x5b, 0xcc, 0xbc, 0x81, - 0x01, 0xfe, 0xcf, 0x6f, 0x5b, 0x11, 0x10, 0x24, 0x9e, 0xba, 0x4e, 0x5b, - 0x8b, 0x75, 0xd6, 0x00, 0x00, 0x02, 0x01, 0x78, 0xfd, 0x8e, 0x03, 0x99, - 0xff, 0xaf, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x04, 0x22, 0x14, 0x33, - 0x32, 0x35, 0x13, 0x22, 0x35, 0x34, 0x37, 0x26, 0x35, 0x34, 0x32, 0x15, - 0x14, 0x06, 0x15, 0x14, 0x33, 0x32, 0x35, 0x11, 0x33, 0x11, 0x14, 0x02, - 0x05, 0x2c, 0x17, 0x15, 0x72, 0xf3, 0x3e, 0x4a, 0xea, 0x6d, 0x82, 0x9e, - 0x84, 0xb2, 0x2c, 0x15, 0xfe, 0x57, 0x92, 0x73, 0x3e, 0x0a, 0x5b, 0x79, - 0x75, 0x3f, 0x7b, 0x45, 0x42, 0x58, 0x01, 0x46, 0xfe, 0xba, 0xc3, 0x00, - 0x00, 0x02, 0x00, 0x45, 0x05, 0x1c, 0x04, 0x8c, 0x07, 0x0b, 0x00, 0x14, - 0x00, 0x1b, 0x00, 0x00, 0x01, 0x16, 0x07, 0x27, 0x36, 0x35, 0x36, 0x25, - 0x22, 0x07, 0x16, 0x07, 0x06, 0x07, 0x06, 0x27, 0x26, 0x37, 0x36, 0x21, - 0x20, 0x00, 0x34, 0x07, 0x22, 0x17, 0x14, 0x33, 0x04, 0x8c, 0x01, 0xa8, - 0x8a, 0x56, 0x01, 0xfe, 0xa5, 0x41, 0x21, 0x2e, 0x0a, 0x15, 0xd9, 0xe5, - 0x01, 0x01, 0x7b, 0x78, 0x01, 0x1a, 0x02, 0x39, 0xfc, 0xe1, 0x3c, 0x3f, - 0x01, 0x38, 0x06, 0x0a, 0x5f, 0x8f, 0x8a, 0x46, 0x2e, 0x55, 0x01, 0x04, - 0x44, 0x57, 0xb0, 0x01, 0x01, 0xd9, 0x54, 0x5f, 0x60, 0xfe, 0xae, 0x7e, - 0x01, 0x3f, 0x3d, 0x00, 0x00, 0x02, 0xff, 0xf0, 0xfd, 0xc7, 0x04, 0xe1, - 0xff, 0xb1, 0x00, 0x07, 0x00, 0x1a, 0x00, 0x00, 0x13, 0x32, 0x35, 0x34, - 0x23, 0x22, 0x15, 0x14, 0x05, 0x22, 0x02, 0x23, 0x16, 0x15, 0x14, 0x23, - 0x22, 0x35, 0x10, 0x21, 0x32, 0x12, 0x33, 0x32, 0x37, 0x17, 0x06, 0xb0, - 0x30, 0x30, 0x2b, 0x02, 0xc9, 0xda, 0xac, 0xb8, 0x5c, 0xc4, 0xb8, 0x01, - 0x4c, 0xde, 0xde, 0x60, 0x5d, 0xa6, 0x86, 0xbf, 0xfe, 0x4e, 0x30, 0x2f, - 0x2e, 0x31, 0x69, 0x01, 0x33, 0x20, 0x72, 0xbf, 0xa7, 0x01, 0x43, 0xfe, - 0xd0, 0xc6, 0x72, 0xf0, 0x00, 0x01, 0x02, 0x0e, 0x04, 0xf1, 0x02, 0xc3, - 0x06, 0x56, 0x00, 0x03, 0x00, 0x00, 0x01, 0x33, 0x11, 0x23, 0x02, 0x0e, - 0xb4, 0xb4, 0x06, 0x56, 0xfe, 0x9b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x56, - 0x04, 0xe0, 0x04, 0x7b, 0x07, 0x20, 0x00, 0x07, 0x00, 0x1b, 0x00, 0x00, - 0x13, 0x16, 0x27, 0x36, 0x07, 0x22, 0x17, 0x06, 0x25, 0x14, 0x02, 0x29, - 0x01, 0x35, 0x36, 0x35, 0x06, 0x37, 0x34, 0x17, 0x16, 0x1d, 0x01, 0x14, - 0x07, 0x20, 0x36, 0x35, 0xf1, 0x2a, 0x01, 0x01, 0x2a, 0x2c, 0x02, 0x02, - 0x03, 0xb5, 0xd6, 0xfe, 0x84, 0xfe, 0x55, 0x90, 0xb7, 0x01, 0x9d, 0x91, - 0x47, 0x01, 0xb1, 0xf3, 0x06, 0x6d, 0x01, 0x2b, 0x2b, 0x02, 0x29, 0x2c, - 0x7d, 0xe5, 0xfe, 0xdd, 0x85, 0x2e, 0x70, 0x07, 0x9d, 0x88, 0x01, 0x01, - 0x83, 0xb7, 0x5c, 0x28, 0x8d, 0xfa, 0x00, 0x00, 0x00, 0x01, 0x00, 0x5f, - 0x04, 0xc8, 0x05, 0x50, 0x06, 0xf3, 0x00, 0x34, 0x00, 0x00, 0x01, 0x22, - 0x11, 0x10, 0x21, 0x32, 0x16, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x15, - 0x14, 0x07, 0x16, 0x37, 0x36, 0x37, 0x33, 0x06, 0x07, 0x06, 0x21, 0x23, - 0x35, 0x36, 0x35, 0x34, 0x23, 0x22, 0x07, 0x06, 0x27, 0x26, 0x27, 0x26, - 0x23, 0x22, 0x15, 0x14, 0x3b, 0x01, 0x26, 0x35, 0x34, 0x33, 0x16, 0x07, - 0x06, 0x07, 0x06, 0x01, 0x50, 0xf0, 0x01, 0x24, 0x32, 0x7e, 0x2a, 0x26, - 0x4a, 0x48, 0x48, 0xdc, 0x9e, 0x84, 0x42, 0x50, 0x04, 0x9a, 0x02, 0x68, - 0x28, 0xfe, 0xe2, 0xc4, 0xd0, 0x4c, 0x18, 0x42, 0x44, 0x5c, 0x6a, 0x24, - 0x3e, 0x18, 0x92, 0x66, 0x3e, 0x2e, 0x60, 0x68, 0x02, 0x02, 0x3e, 0x34, - 0x04, 0xc8, 0x01, 0x14, 0x01, 0x17, 0x82, 0x01, 0x01, 0x41, 0x3f, 0xd7, - 0x7e, 0x3d, 0x04, 0x0d, 0x10, 0x68, 0x82, 0x5c, 0x24, 0x85, 0x6b, 0x62, - 0x38, 0x3a, 0x3b, 0x01, 0x01, 0x2d, 0x46, 0x90, 0xa1, 0x02, 0x5f, 0x5a, - 0x01, 0x6b, 0x66, 0x32, 0x29, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x49, - 0x04, 0xe0, 0x03, 0x88, 0x07, 0x1e, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x35, - 0x33, 0x35, 0x33, 0x15, 0x33, 0x15, 0x23, 0x15, 0x23, 0x35, 0x01, 0x4a, - 0xd8, 0x8e, 0xd8, 0xd8, 0x8e, 0x05, 0xb8, 0x8e, 0xd8, 0xd8, 0x8e, 0xd8, - 0xd8, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf0, 0x05, 0x17, 0x04, 0xe1, - 0x07, 0x01, 0x10, 0x07, 0x04, 0xd3, 0x00, 0x00, 0x07, 0x50, 0x00, 0x00, - 0x00, 0x02, 0x01, 0x96, 0x04, 0xf6, 0x03, 0x3b, 0x06, 0x72, 0x00, 0x07, - 0x00, 0x0c, 0x00, 0x00, 0x01, 0x34, 0x33, 0x32, 0x15, 0x14, 0x23, 0x22, - 0x12, 0x14, 0x33, 0x32, 0x34, 0x01, 0x96, 0xd4, 0xd0, 0xd4, 0xd0, 0x84, - 0x4c, 0x54, 0x05, 0xbe, 0xb4, 0xb4, 0xc8, 0x01, 0x10, 0x90, 0x90, 0x00, - 0x00, 0x01, 0x00, 0xa0, 0x00, 0x00, 0x04, 0x33, 0x04, 0x7a, 0x00, 0x15, - 0x00, 0x00, 0x01, 0x02, 0x21, 0x20, 0x11, 0x34, 0x37, 0x33, 0x06, 0x15, - 0x10, 0x21, 0x20, 0x11, 0x34, 0x27, 0x24, 0x03, 0x33, 0x16, 0x17, 0x04, - 0x04, 0x33, 0x01, 0xfe, 0x31, 0xfe, 0x3d, 0x50, 0xbe, 0x55, 0x01, 0x0f, - 0x01, 0x11, 0xbd, 0xfe, 0xdc, 0x02, 0xb5, 0x01, 0x7e, 0x01, 0x69, 0x01, - 0xef, 0xfe, 0x11, 0x01, 0xc9, 0x69, 0x62, 0x63, 0x57, 0xfe, 0xb7, 0x01, - 0x4f, 0xd6, 0x4a, 0x66, 0x01, 0x14, 0xa1, 0x33, 0x82, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x9e, 0x00, 0x00, 0x04, 0x34, 0x06, 0x16, 0x00, 0x12, - 0x00, 0x1a, 0x00, 0x00, 0x01, 0x10, 0x21, 0x20, 0x03, 0x12, 0x25, 0x35, - 0x36, 0x27, 0x26, 0x35, 0x33, 0x14, 0x17, 0x16, 0x1d, 0x01, 0x04, 0x03, - 0x12, 0x21, 0x04, 0x11, 0x10, 0x21, 0x20, 0x04, 0x34, 0xfe, 0x3c, 0xfe, - 0x31, 0x03, 0x03, 0x01, 0x83, 0x01, 0xa3, 0x8d, 0xb5, 0x7e, 0xa1, 0x01, - 0x6b, 0xbc, 0x01, 0xfe, 0xef, 0xfe, 0xf1, 0x01, 0x16, 0x01, 0x09, 0x02, - 0x20, 0xfd, 0xe0, 0x02, 0x21, 0x01, 0xab, 0x54, 0x8a, 0x78, 0x1c, 0x1b, - 0xbd, 0x59, 0x1b, 0x39, 0xb9, 0x90, 0x76, 0xfe, 0x77, 0x01, 0x73, 0x03, - 0xfe, 0x95, 0xfe, 0x6b, 0x00, 0x02, 0x00, 0x6e, 0xfe, 0x57, 0x04, 0x61, - 0x04, 0x15, 0x00, 0x19, 0x00, 0x21, 0x00, 0x00, 0x25, 0x10, 0x21, 0x20, - 0x11, 0x12, 0x25, 0x36, 0x37, 0x34, 0x23, 0x22, 0x17, 0x14, 0x17, 0x07, - 0x26, 0x35, 0x10, 0x21, 0x20, 0x03, 0x14, 0x07, 0x15, 0x04, 0x03, 0x10, - 0x25, 0x20, 0x03, 0x10, 0x25, 0x04, 0x04, 0x61, 0xfe, 0x09, 0xfe, 0x04, - 0x01, 0x02, 0x1c, 0x6c, 0x02, 0xd5, 0xb7, 0x01, 0x0f, 0x89, 0x2e, 0x01, - 0x5f, 0x01, 0x8b, 0x01, 0x7a, 0x01, 0x2d, 0xb3, 0xfe, 0xbe, 0xfe, 0xb6, - 0x02, 0x01, 0x46, 0x01, 0x48, 0x2b, 0xfe, 0x2c, 0x01, 0xd4, 0x01, 0xcd, - 0x05, 0x53, 0xa9, 0x8e, 0x8b, 0x2e, 0x2b, 0x52, 0x4c, 0x6f, 0x01, 0x09, - 0xfe, 0xdb, 0xa4, 0x54, 0x14, 0x6e, 0xfe, 0xb5, 0x01, 0x42, 0x01, 0xfe, - 0xbd, 0xfe, 0xc0, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x37, - 0xfe, 0x57, 0x04, 0x9a, 0x04, 0x0b, 0x00, 0x21, 0x00, 0x2c, 0x00, 0x00, - 0x17, 0x36, 0x37, 0x35, 0x00, 0x11, 0x10, 0x05, 0x32, 0x17, 0x33, 0x36, - 0x33, 0x20, 0x11, 0x15, 0x10, 0x21, 0x20, 0x11, 0x35, 0x34, 0x2b, 0x01, - 0x22, 0x11, 0x15, 0x10, 0x00, 0x17, 0x07, 0x26, 0x24, 0x07, 0x01, 0x35, - 0x34, 0x2b, 0x01, 0x22, 0x1d, 0x01, 0x10, 0x33, 0x32, 0xdd, 0x28, 0x54, - 0xfe, 0xde, 0x01, 0x58, 0x5b, 0x50, 0x14, 0x3c, 0xaa, 0x01, 0x66, 0xfe, - 0xa6, 0xfe, 0xaa, 0x49, 0x2b, 0x81, 0x02, 0x79, 0x68, 0xca, 0x5a, 0xfe, - 0xcb, 0x74, 0x02, 0xd4, 0x95, 0x47, 0x77, 0xba, 0x99, 0xe1, 0x2c, 0x12, - 0x0b, 0x01, 0x16, 0x01, 0xc8, 0x01, 0xc6, 0x01, 0x62, 0x62, 0xfe, 0x2b, - 0x14, 0xfe, 0x06, 0x02, 0x0f, 0xea, 0x5d, 0xfe, 0xc4, 0x6d, 0xfe, 0x4c, - 0xfe, 0xff, 0xc8, 0x01, 0xa7, 0x0e, 0x56, 0x03, 0x03, 0xd4, 0xf1, 0xb6, - 0xf7, 0xfe, 0xe8, 0x00, 0x00, 0x01, 0x00, 0xa0, 0xfe, 0x57, 0x04, 0x33, - 0x04, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x05, 0x02, 0x21, 0x20, 0x11, 0x34, - 0x37, 0x33, 0x06, 0x15, 0x10, 0x21, 0x20, 0x35, 0x11, 0x10, 0x20, 0x15, - 0x14, 0x17, 0x07, 0x26, 0x35, 0x10, 0x05, 0x20, 0x13, 0x04, 0x33, 0x01, - 0xfe, 0x49, 0xfe, 0x25, 0x8d, 0xbc, 0x90, 0x01, 0x24, 0x01, 0x06, 0xfe, - 0x26, 0x3e, 0xb0, 0x38, 0x01, 0x96, 0x01, 0x9d, 0x01, 0x20, 0xfe, 0x77, - 0x01, 0x92, 0x8f, 0x6a, 0x73, 0x85, 0xfe, 0xfb, 0xf1, 0x02, 0xa4, 0x01, - 0x0d, 0xde, 0x6f, 0x65, 0x01, 0x4b, 0x85, 0x01, 0x72, 0x01, 0xfe, 0x64, - 0x00, 0x01, 0x00, 0x9e, 0xfe, 0x57, 0x04, 0x32, 0x04, 0x15, 0x00, 0x27, - 0x00, 0x00, 0x05, 0x10, 0x21, 0x20, 0x03, 0x36, 0x37, 0x33, 0x06, 0x15, - 0x10, 0x21, 0x20, 0x3d, 0x01, 0x34, 0x2b, 0x01, 0x35, 0x33, 0x16, 0x37, - 0x34, 0x23, 0x20, 0x07, 0x16, 0x17, 0x23, 0x26, 0x35, 0x10, 0x21, 0x20, - 0x11, 0x14, 0x07, 0x15, 0x16, 0x11, 0x04, 0x32, 0xfe, 0x34, 0xfe, 0x3a, - 0x02, 0x02, 0x69, 0xc0, 0x70, 0x01, 0x0d, 0x01, 0x14, 0xed, 0x49, 0x49, - 0xe2, 0x01, 0xe1, 0xfe, 0xfc, 0x01, 0x01, 0x2d, 0xa1, 0x3c, 0x01, 0xb1, - 0x01, 0x9e, 0xe5, 0xed, 0x2d, 0xfe, 0x84, 0x01, 0x98, 0x5d, 0x6d, 0x78, - 0x52, 0xfe, 0xf6, 0xdf, 0x62, 0xf3, 0x8c, 0x01, 0xf0, 0xf3, 0xca, 0x58, - 0x78, 0x52, 0x7e, 0x01, 0x58, 0xfe, 0x7b, 0xd1, 0x5c, 0x14, 0x2b, 0xfe, - 0xfe, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x9e, 0x00, 0x00, 0x04, 0x32, - 0x06, 0x14, 0x00, 0x11, 0x00, 0x18, 0x00, 0x20, 0x00, 0x00, 0x01, 0x02, - 0x21, 0x20, 0x11, 0x10, 0x37, 0x35, 0x26, 0x37, 0x02, 0x21, 0x20, 0x11, - 0x06, 0x07, 0x15, 0x04, 0x03, 0x10, 0x05, 0x04, 0x13, 0x02, 0x20, 0x03, - 0x34, 0x27, 0x22, 0x15, 0x06, 0x17, 0x36, 0x04, 0x32, 0x01, 0xfe, 0x35, - 0xfe, 0x38, 0xc8, 0xc8, 0x01, 0x01, 0x01, 0x54, 0x01, 0x57, 0x01, 0x5c, - 0x01, 0x46, 0xb9, 0xfe, 0xeb, 0xfe, 0xf5, 0x01, 0x01, 0x02, 0x20, 0xcd, - 0xbe, 0xa8, 0x01, 0xba, 0xaf, 0x01, 0xf8, 0xfe, 0x08, 0x01, 0xf9, 0x01, - 0x49, 0x4a, 0x14, 0x3a, 0xe9, 0x01, 0x51, 0xfe, 0xbd, 0x9b, 0x55, 0x14, - 0x2d, 0xfe, 0x5c, 0x01, 0x70, 0x02, 0x01, 0xfe, 0x90, 0xfe, 0x98, 0x04, - 0x21, 0xd4, 0x02, 0xd6, 0xda, 0x01, 0x01, 0x00, 0x00, 0x02, 0x00, 0x37, - 0x00, 0x00, 0x04, 0x9a, 0x04, 0x0b, 0x00, 0x1a, 0x00, 0x25, 0x00, 0x00, - 0x01, 0x15, 0x10, 0x07, 0x23, 0x36, 0x11, 0x35, 0x10, 0x2b, 0x01, 0x22, - 0x1d, 0x01, 0x10, 0x21, 0x20, 0x11, 0x35, 0x10, 0x21, 0x32, 0x17, 0x33, - 0x36, 0x33, 0x20, 0x01, 0x11, 0x36, 0x23, 0x07, 0x26, 0x11, 0x15, 0x10, - 0x33, 0x32, 0x04, 0x9a, 0xef, 0xa2, 0xd4, 0x84, 0x21, 0x53, 0xfe, 0xcb, - 0xfe, 0x87, 0x01, 0x7d, 0x92, 0x47, 0x0e, 0x4a, 0x74, 0x01, 0x41, 0xfd, - 0xaa, 0x02, 0x46, 0x57, 0xb4, 0xa5, 0xac, 0x02, 0x48, 0x43, 0xfe, 0xa2, - 0xa7, 0xae, 0x01, 0x42, 0x75, 0x01, 0x19, 0xb6, 0xdc, 0xfe, 0x14, 0x02, - 0x07, 0x1e, 0x01, 0xe6, 0x63, 0x63, 0xfd, 0x79, 0x01, 0x69, 0x91, 0x01, - 0x01, 0xfe, 0xef, 0xbd, 0xfe, 0xe1, 0x00, 0x00, 0x00, 0x01, 0x00, 0xa0, - 0x00, 0x00, 0x04, 0x32, 0x04, 0x15, 0x00, 0x11, 0x00, 0x00, 0x01, 0x10, - 0x07, 0x23, 0x12, 0x03, 0x10, 0x21, 0x20, 0x11, 0x10, 0x13, 0x23, 0x26, - 0x13, 0x02, 0x21, 0x20, 0x04, 0x32, 0xf0, 0x92, 0xc9, 0x01, 0xfe, 0xfc, - 0xfe, 0xe6, 0xc6, 0x94, 0xee, 0x02, 0x02, 0x01, 0xd2, 0x01, 0xc3, 0x02, - 0x23, 0xfe, 0xa5, 0xc8, 0x01, 0x04, 0x01, 0x1f, 0x01, 0x63, 0xfe, 0xa0, - 0xfe, 0xe6, 0xfe, 0xf4, 0xcf, 0x01, 0x5a, 0x01, 0xec, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x9e, 0xfe, 0x59, 0x04, 0x34, 0x04, 0x02, 0x00, 0x1f, - 0x00, 0x00, 0x05, 0x02, 0x21, 0x20, 0x11, 0x34, 0x37, 0x33, 0x06, 0x15, - 0x10, 0x21, 0x20, 0x3d, 0x01, 0x10, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x35, - 0x34, 0x21, 0x35, 0x20, 0x11, 0x16, 0x05, 0x15, 0x04, 0x13, 0x04, 0x34, - 0x01, 0xfe, 0x43, 0xfe, 0x28, 0x70, 0xad, 0x62, 0x01, 0x1d, 0x01, 0x02, - 0xee, 0x41, 0x41, 0xe4, 0xfe, 0x5a, 0x02, 0x5a, 0x01, 0xfe, 0xf5, 0x01, - 0x1a, 0x02, 0x1e, 0xfe, 0x77, 0x01, 0xa7, 0x8b, 0x66, 0x71, 0x80, 0xfe, - 0xe6, 0xfc, 0x32, 0x01, 0x10, 0x98, 0xc6, 0xe6, 0x9a, 0xfe, 0x80, 0xd0, - 0x31, 0x14, 0x31, 0xfe, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xa0, - 0xfe, 0x57, 0x04, 0x32, 0x04, 0x15, 0x00, 0x1b, 0x00, 0x00, 0x01, 0x20, - 0x11, 0x10, 0x00, 0x15, 0x23, 0x26, 0x24, 0x07, 0x27, 0x36, 0x3f, 0x01, - 0x02, 0x11, 0x10, 0x21, 0x20, 0x11, 0x14, 0x06, 0x17, 0x07, 0x26, 0x36, - 0x35, 0x10, 0x02, 0x6c, 0xfe, 0xed, 0x02, 0x5f, 0xbe, 0x24, 0xfe, 0xb3, - 0x5e, 0x4d, 0x3e, 0x70, 0x0d, 0xf9, 0x01, 0xcc, 0x01, 0xc6, 0x76, 0x14, - 0x9f, 0x14, 0x5c, 0x03, 0x88, 0xfe, 0xbd, 0xfe, 0x59, 0xfe, 0x31, 0x78, - 0xb0, 0x4f, 0x68, 0x5f, 0x5b, 0x0d, 0x0e, 0x01, 0x05, 0x01, 0x82, 0x01, - 0xcb, 0xfe, 0x29, 0x65, 0xb5, 0x9c, 0x01, 0x9d, 0xa8, 0x75, 0x01, 0x47, - 0x00, 0x02, 0x00, 0x9e, 0x00, 0x00, 0x04, 0x34, 0x06, 0x15, 0x00, 0x15, - 0x00, 0x1c, 0x00, 0x00, 0x01, 0x10, 0x21, 0x20, 0x11, 0x10, 0x21, 0x32, - 0x17, 0x33, 0x11, 0x34, 0x21, 0x06, 0x1d, 0x01, 0x23, 0x35, 0x10, 0x21, - 0x20, 0x11, 0x03, 0x10, 0x20, 0x11, 0x02, 0x21, 0x20, 0x04, 0x34, 0xfe, - 0x45, 0xfe, 0x25, 0x01, 0xcb, 0xc4, 0x44, 0x14, 0xfe, 0xe4, 0xe8, 0xbb, - 0x01, 0xa3, 0x01, 0xcb, 0xbc, 0xfd, 0xe2, 0x01, 0x01, 0x1e, 0x01, 0x01, - 0x01, 0xef, 0xfe, 0x11, 0x02, 0x0d, 0x02, 0x09, 0x7d, 0x01, 0x02, 0xed, - 0x01, 0x98, 0x3e, 0x3e, 0x01, 0x26, 0xfe, 0x86, 0xfd, 0x54, 0x01, 0x97, - 0xfe, 0x89, 0xfe, 0x82, 0x00, 0x02, 0x00, 0x9f, 0x00, 0x00, 0x04, 0x32, - 0x05, 0xfb, 0x00, 0x11, 0x00, 0x19, 0x00, 0x00, 0x01, 0x12, 0x21, 0x20, - 0x19, 0x01, 0x02, 0x29, 0x01, 0x15, 0x21, 0x22, 0x15, 0x11, 0x33, 0x36, - 0x33, 0x04, 0x03, 0x10, 0x21, 0x20, 0x11, 0x10, 0x25, 0x04, 0x04, 0x32, - 0x01, 0xfe, 0x32, 0xfe, 0x3a, 0x01, 0x01, 0x4d, 0x01, 0xce, 0xfe, 0x1e, - 0x8d, 0x23, 0x40, 0xb8, 0x01, 0xcd, 0xb9, 0xfe, 0xea, 0xfe, 0xef, 0x01, - 0x11, 0x01, 0x16, 0x02, 0x24, 0xfd, 0xdc, 0x01, 0xea, 0x02, 0xb6, 0x01, - 0x5b, 0x8f, 0xb0, 0xfe, 0xda, 0x80, 0x01, 0xfe, 0x0c, 0x01, 0x67, 0xfe, - 0x85, 0xfe, 0x84, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, - 0x00, 0x00, 0x04, 0x9a, 0x04, 0x0b, 0x00, 0x23, 0x00, 0x00, 0x01, 0x14, - 0x07, 0x23, 0x36, 0x35, 0x11, 0x34, 0x07, 0x23, 0x22, 0x15, 0x11, 0x23, - 0x11, 0x34, 0x2b, 0x01, 0x22, 0x15, 0x11, 0x06, 0x17, 0x23, 0x26, 0x3d, - 0x01, 0x10, 0x21, 0x32, 0x17, 0x33, 0x36, 0x33, 0x20, 0x11, 0x04, 0x9a, - 0xbc, 0xb3, 0xb3, 0x99, 0x4b, 0x40, 0xa0, 0x42, 0x4d, 0x94, 0x02, 0xcb, - 0xc2, 0xc7, 0x01, 0x7b, 0x68, 0x49, 0x11, 0x46, 0x60, 0x01, 0x80, 0x01, - 0xc6, 0xec, 0xda, 0xc0, 0xcf, 0x01, 0x19, 0xd7, 0x01, 0xcf, 0xfe, 0xeb, - 0x01, 0x15, 0xcf, 0xe4, 0xfe, 0xfc, 0xd6, 0xc0, 0xe1, 0xec, 0x66, 0x01, - 0xd8, 0x68, 0x68, 0xfe, 0x26, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xa0, - 0x00, 0x00, 0x04, 0x34, 0x06, 0x0f, 0x00, 0x21, 0x00, 0x00, 0x01, 0x10, - 0x21, 0x20, 0x13, 0x34, 0x37, 0x33, 0x06, 0x15, 0x10, 0x21, 0x20, 0x11, - 0x10, 0x21, 0x23, 0x35, 0x33, 0x32, 0x37, 0x34, 0x25, 0x24, 0x35, 0x33, - 0x14, 0x17, 0x04, 0x11, 0x14, 0x07, 0x15, 0x16, 0x04, 0x34, 0xfe, 0x44, - 0xfe, 0x27, 0x01, 0x65, 0xaf, 0x5b, 0x01, 0x1f, 0x01, 0x00, 0xfe, 0xec, - 0x3f, 0x52, 0xd7, 0x01, 0xfe, 0xe9, 0xfe, 0xdc, 0xac, 0xef, 0x01, 0x57, - 0xba, 0xe8, 0x01, 0xda, 0xfe, 0x26, 0x01, 0xb2, 0xb7, 0x5a, 0x7e, 0x93, - 0xfe, 0xdf, 0x01, 0x49, 0x01, 0x4a, 0x87, 0xc8, 0x95, 0x21, 0x36, 0xb0, - 0x47, 0x29, 0x29, 0xfe, 0xfb, 0xcb, 0x3d, 0x14, 0x69, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x9f, 0xfe, 0x59, 0x04, 0x33, 0x04, 0x32, 0x00, 0x17, - 0x00, 0x00, 0x05, 0x02, 0x21, 0x20, 0x03, 0x33, 0x06, 0x21, 0x20, 0x19, - 0x01, 0x05, 0x15, 0x16, 0x15, 0x10, 0x05, 0x35, 0x20, 0x27, 0x12, 0x25, - 0x35, 0x25, 0x04, 0x33, 0x01, 0xfe, 0x30, 0xfe, 0x3e, 0x01, 0xbb, 0x01, - 0x01, 0x04, 0x01, 0x27, 0xfe, 0x4d, 0xdd, 0xfd, 0xf1, 0x01, 0x68, 0x01, - 0x01, 0xfe, 0x98, 0x03, 0x94, 0x12, 0xfe, 0x6b, 0x01, 0x6f, 0xe3, 0x01, - 0x0b, 0x03, 0xa8, 0x34, 0x3c, 0x59, 0xee, 0xfe, 0xce, 0x01, 0xa7, 0x8c, - 0x01, 0x03, 0x4b, 0x82, 0x81, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x37, - 0x00, 0x00, 0x04, 0x9a, 0x06, 0x15, 0x00, 0x29, 0x00, 0x00, 0x01, 0x15, - 0x14, 0x07, 0x23, 0x36, 0x3d, 0x01, 0x10, 0x2b, 0x01, 0x22, 0x15, 0x11, - 0x23, 0x13, 0x36, 0x2b, 0x01, 0x22, 0x11, 0x15, 0x14, 0x17, 0x23, 0x26, - 0x11, 0x35, 0x34, 0x00, 0x25, 0x17, 0x04, 0x03, 0x33, 0x37, 0x32, 0x17, - 0x33, 0x36, 0x33, 0x20, 0x04, 0x9a, 0xd0, 0xc5, 0xd8, 0x84, 0x58, 0x41, - 0xa0, 0x01, 0x01, 0x4a, 0x7c, 0x67, 0xe6, 0xd2, 0xd2, 0x01, 0x5a, 0x01, - 0xa7, 0x19, 0xfe, 0x96, 0xda, 0x18, 0x56, 0xa5, 0x48, 0x0f, 0x49, 0xa0, - 0x01, 0x3a, 0x02, 0x54, 0x8e, 0xf4, 0xd2, 0xb8, 0xdb, 0xc1, 0x01, 0x2a, - 0xa7, 0xfe, 0xc3, 0x01, 0x3d, 0xa7, 0xfe, 0xdb, 0xa5, 0xfc, 0xb8, 0xd2, - 0x01, 0x18, 0x67, 0xfb, 0x02, 0x4e, 0x7b, 0x94, 0x52, 0xfe, 0x9f, 0x3d, - 0x62, 0x62, 0x00, 0x00, 0x00, 0x01, 0x00, 0x9f, 0x00, 0x00, 0x04, 0x33, - 0x05, 0xf1, 0x00, 0x15, 0x00, 0x00, 0x01, 0x10, 0x21, 0x20, 0x19, 0x01, - 0x33, 0x11, 0x10, 0x21, 0x20, 0x11, 0x34, 0x24, 0x35, 0x34, 0x37, 0x17, - 0x06, 0x15, 0x14, 0x04, 0x04, 0x33, 0xfe, 0x3d, 0xfe, 0x2f, 0xb6, 0x01, - 0x1b, 0x01, 0x09, 0xfe, 0xf1, 0xce, 0x57, 0x8e, 0x01, 0x32, 0x02, 0x03, - 0xfd, 0xfd, 0x02, 0x03, 0x03, 0xee, 0xfc, 0x12, 0xfe, 0x8e, 0x01, 0x72, - 0xaf, 0xa1, 0x67, 0x94, 0x7d, 0x7c, 0x38, 0x3b, 0x43, 0xbc, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x2d, 0xfe, 0x59, 0x04, 0xa4, 0x04, 0xea, 0x00, 0x0a, - 0x00, 0x15, 0x00, 0x00, 0x13, 0x10, 0x25, 0x03, 0x33, 0x03, 0x04, 0x11, - 0x02, 0x21, 0x20, 0x13, 0x10, 0x21, 0x20, 0x11, 0x10, 0x25, 0x13, 0x23, - 0x13, 0x04, 0x2d, 0x01, 0xfa, 0x0f, 0xa6, 0x0f, 0x01, 0xf5, 0x02, 0xfd, - 0xca, 0xfd, 0xc1, 0xbc, 0x01, 0x7f, 0x01, 0x86, 0xfe, 0xc1, 0x0f, 0xa5, - 0x0e, 0xfe, 0xc2, 0x01, 0x22, 0x02, 0x75, 0x52, 0x01, 0x01, 0xfe, 0xfb, - 0x4e, 0xfd, 0x85, 0xfd, 0x3d, 0x02, 0xc9, 0xfd, 0xc3, 0x02, 0x3d, 0x01, - 0xe7, 0x6f, 0xfd, 0xe5, 0x02, 0x1a, 0x6e, 0x00, 0x00, 0x01, 0x00, 0x37, - 0xfe, 0x59, 0x04, 0x4a, 0x04, 0x0c, 0x00, 0x29, 0x00, 0x00, 0x05, 0x02, - 0x21, 0x20, 0x11, 0x34, 0x37, 0x33, 0x06, 0x15, 0x10, 0x21, 0x20, 0x35, - 0x11, 0x34, 0x23, 0x06, 0x11, 0x07, 0x23, 0x27, 0x10, 0x27, 0x0e, 0x01, - 0x23, 0x22, 0x27, 0x37, 0x16, 0x33, 0x32, 0x36, 0x33, 0x32, 0x17, 0x33, - 0x36, 0x17, 0x24, 0x13, 0x04, 0x4a, 0x02, 0xfe, 0x4d, 0xfe, 0x1f, 0x91, - 0xb3, 0x8a, 0x01, 0x27, 0x01, 0x03, 0x82, 0x84, 0x0a, 0x85, 0x09, 0x6e, - 0x3e, 0x3e, 0x3e, 0x48, 0x53, 0x32, 0x3e, 0x2b, 0x33, 0x3c, 0x4c, 0x67, - 0x45, 0x14, 0x48, 0x89, 0x01, 0x2b, 0x01, 0x2b, 0xfe, 0x84, 0x01, 0xa4, - 0x9f, 0x5a, 0x7b, 0x7e, 0xfe, 0xe8, 0xf0, 0x02, 0xea, 0xbf, 0x01, 0xfe, - 0xf2, 0xc1, 0xc1, 0x01, 0x0e, 0x01, 0x01, 0x86, 0x5f, 0xb5, 0x62, 0x63, - 0xb8, 0xb8, 0x01, 0x01, 0xfe, 0xb3, 0x00, 0x00, 0x00, 0x02, 0x00, 0x37, - 0xfe, 0x57, 0x04, 0x9d, 0x04, 0x0b, 0x00, 0x2d, 0x00, 0x38, 0x00, 0x00, - 0x05, 0x10, 0x21, 0x23, 0x20, 0x11, 0x33, 0x14, 0x3b, 0x01, 0x20, 0x3d, - 0x01, 0x34, 0x27, 0x23, 0x35, 0x33, 0x36, 0x3d, 0x01, 0x34, 0x2b, 0x01, - 0x22, 0x1d, 0x01, 0x10, 0x21, 0x04, 0x11, 0x35, 0x10, 0x21, 0x32, 0x17, - 0x33, 0x36, 0x33, 0x20, 0x11, 0x14, 0x07, 0x15, 0x16, 0x15, 0x01, 0x34, - 0x2b, 0x01, 0x22, 0x11, 0x15, 0x10, 0x33, 0x32, 0x11, 0x04, 0x9d, 0xfe, - 0x34, 0x38, 0xfe, 0x52, 0xb7, 0xf9, 0x2f, 0x01, 0x16, 0x39, 0x50, 0x50, - 0x36, 0x64, 0x53, 0x3b, 0xfe, 0xbe, 0xfe, 0x8e, 0x01, 0x77, 0x8a, 0x43, - 0x11, 0x60, 0x8b, 0x01, 0x23, 0x9e, 0xa1, 0xfd, 0xa5, 0x5e, 0x4d, 0xa2, - 0xb0, 0x9d, 0x3d, 0xfe, 0x94, 0x01, 0x85, 0xf7, 0xde, 0x65, 0xa6, 0x02, - 0x97, 0x01, 0x94, 0xb6, 0xcc, 0x7b, 0xca, 0xfe, 0x20, 0x01, 0x01, 0x99, - 0x80, 0x01, 0x9a, 0x63, 0x63, 0xfe, 0x6d, 0xfb, 0x54, 0x14, 0x5b, 0x8e, - 0x02, 0xab, 0xa7, 0xfe, 0xfa, 0x78, 0xfe, 0xd7, 0x01, 0x05, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xa0, 0xfe, 0x57, 0x04, 0x31, 0x05, 0xf1, 0x00, 0x1e, - 0x00, 0x00, 0x25, 0x10, 0x21, 0x20, 0x11, 0x34, 0x37, 0x17, 0x06, 0x15, - 0x10, 0x21, 0x20, 0x03, 0x13, 0x10, 0x05, 0x26, 0x15, 0x14, 0x17, 0x23, - 0x26, 0x35, 0x10, 0x21, 0x16, 0x17, 0x33, 0x13, 0x33, 0x04, 0x31, 0xfe, - 0x54, 0xfe, 0x1b, 0x86, 0xb0, 0x7d, 0x01, 0x29, 0x01, 0x01, 0x01, 0x02, - 0xfe, 0xdf, 0xc5, 0x52, 0xb3, 0x46, 0x01, 0x71, 0x8e, 0x7c, 0x11, 0x01, - 0xad, 0x43, 0xfe, 0x14, 0x01, 0xa9, 0x84, 0x64, 0x01, 0x79, 0x71, 0xfe, - 0xe8, 0x01, 0x5e, 0x01, 0x28, 0x02, 0x1e, 0x03, 0x03, 0xa4, 0xb6, 0x59, - 0x6f, 0xa0, 0x01, 0x31, 0x01, 0xbd, 0x02, 0x99, 0x00, 0x01, 0x00, 0x37, - 0xfe, 0x56, 0x04, 0x9a, 0x04, 0x0c, 0x00, 0x2b, 0x00, 0x00, 0x17, 0x36, - 0x37, 0x35, 0x00, 0x11, 0x35, 0x10, 0x21, 0x16, 0x17, 0x33, 0x36, 0x37, - 0x04, 0x11, 0x15, 0x14, 0x0f, 0x01, 0x36, 0x3d, 0x01, 0x34, 0x2b, 0x01, - 0x22, 0x15, 0x11, 0x23, 0x11, 0x34, 0x2b, 0x01, 0x22, 0x11, 0x15, 0x10, - 0x00, 0x17, 0x27, 0x26, 0x24, 0x07, 0xed, 0x39, 0x41, 0xfe, 0xd0, 0x01, - 0x5f, 0x83, 0x4a, 0x10, 0x46, 0x95, 0x01, 0x4c, 0xa9, 0x8c, 0x78, 0x86, - 0x64, 0x3a, 0xa0, 0x41, 0x4c, 0x97, 0x02, 0x96, 0x45, 0xcb, 0x19, 0xfe, - 0xc4, 0x82, 0xc9, 0x53, 0x02, 0x16, 0x01, 0x05, 0x01, 0x27, 0x50, 0x01, - 0xee, 0x01, 0x67, 0x67, 0x01, 0x01, 0xfe, 0x3f, 0x46, 0xf4, 0xb1, 0x01, - 0xa7, 0xae, 0xdb, 0xf0, 0xaf, 0xfe, 0xcb, 0x01, 0x35, 0xaf, 0xfe, 0xfa, - 0x8a, 0xfe, 0x8d, 0xfe, 0xb3, 0xd8, 0x01, 0x8e, 0x70, 0x7a, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x9e, 0xfe, 0x59, 0x04, 0x32, 0x03, 0xf7, 0x00, 0x1a, - 0x00, 0x00, 0x05, 0x10, 0x21, 0x20, 0x11, 0x33, 0x10, 0x05, 0x24, 0x3d, - 0x01, 0x23, 0x06, 0x23, 0x20, 0x11, 0x10, 0x25, 0x33, 0x04, 0x15, 0x10, - 0x21, 0x20, 0x35, 0x11, 0x33, 0x04, 0x32, 0xfe, 0x46, 0xfe, 0x26, 0xbc, - 0x01, 0x1e, 0x01, 0x07, 0x14, 0x58, 0xaf, 0xfe, 0x3a, 0x01, 0x17, 0xd8, - 0xfe, 0xcc, 0x01, 0x0b, 0x01, 0x1b, 0xb3, 0x2f, 0xfe, 0x88, 0x01, 0x90, - 0xfe, 0xfc, 0x01, 0x01, 0xf0, 0xf4, 0x62, 0x01, 0xe5, 0x01, 0x04, 0xa7, - 0xce, 0xdd, 0xfe, 0xaf, 0xeb, 0x02, 0x09, 0x00, 0x00, 0x02, 0x00, 0x37, - 0x00, 0x00, 0x04, 0x34, 0x06, 0x14, 0x00, 0x1f, 0x00, 0x27, 0x00, 0x00, - 0x01, 0x10, 0x21, 0x20, 0x03, 0x10, 0x25, 0x16, 0x17, 0x33, 0x11, 0x34, - 0x23, 0x22, 0x1d, 0x01, 0x23, 0x35, 0x34, 0x23, 0x22, 0x15, 0x23, 0x10, - 0x33, 0x32, 0x17, 0x33, 0x36, 0x33, 0x20, 0x0b, 0x01, 0x02, 0x21, 0x20, - 0x13, 0x02, 0x21, 0x32, 0x04, 0x34, 0xfe, 0x59, 0xfe, 0x12, 0x01, 0x01, - 0xc6, 0xc1, 0x46, 0x14, 0x8e, 0x8d, 0x9d, 0xa0, 0x55, 0x9b, 0xdc, 0xba, - 0x3f, 0x14, 0x3a, 0xac, 0x01, 0x2e, 0x02, 0xb8, 0x01, 0xfe, 0xe9, 0xfe, - 0xf7, 0x01, 0x01, 0x01, 0x38, 0xe8, 0x01, 0xdd, 0xfe, 0x23, 0x02, 0x0d, - 0x02, 0x08, 0x01, 0x01, 0x81, 0x01, 0x21, 0xd5, 0xd2, 0x21, 0x23, 0xd0, - 0xe2, 0x01, 0x6c, 0xc1, 0xc1, 0xfe, 0xc0, 0xfd, 0x2f, 0x01, 0x85, 0xfe, - 0x85, 0xfe, 0x84, 0x00, 0x00, 0x02, 0x00, 0x9e, 0x00, 0x00, 0x04, 0x34, - 0x06, 0x14, 0x00, 0x13, 0x00, 0x1d, 0x00, 0x00, 0x01, 0x16, 0x13, 0x02, - 0x05, 0x23, 0x24, 0x13, 0x10, 0x25, 0x24, 0x19, 0x01, 0x23, 0x13, 0x10, - 0x21, 0x20, 0x13, 0x16, 0x27, 0x26, 0x23, 0x22, 0x15, 0x11, 0x33, 0x36, - 0x05, 0x36, 0x03, 0x4d, 0xe6, 0x01, 0x01, 0xfe, 0xe9, 0xb2, 0x01, 0x0e, - 0x01, 0xfe, 0xfa, 0xfe, 0xdd, 0xb2, 0x02, 0x01, 0x70, 0x01, 0x7f, 0x1e, - 0x01, 0xa4, 0x1e, 0xd9, 0xc3, 0x1e, 0x3f, 0x01, 0x25, 0x38, 0x03, 0xda, - 0x68, 0xfe, 0x92, 0xfe, 0xb8, 0xbc, 0xc7, 0x01, 0x41, 0x01, 0x6a, 0x01, - 0x13, 0xfe, 0xc5, 0xfd, 0xb5, 0x04, 0xbe, 0x01, 0x56, 0xfe, 0xc7, 0x60, - 0x4d, 0xbf, 0xd6, 0xfe, 0xe4, 0x80, 0x1e, 0x86, 0x00, 0x01, 0x00, 0x56, - 0xfe, 0x59, 0x04, 0x7a, 0x04, 0x25, 0x00, 0x23, 0x00, 0x00, 0x01, 0x14, - 0x07, 0x15, 0x16, 0x15, 0x02, 0x21, 0x20, 0x11, 0x35, 0x10, 0x13, 0x17, - 0x06, 0x03, 0x15, 0x12, 0x21, 0x20, 0x03, 0x36, 0x2b, 0x01, 0x35, 0x33, - 0x32, 0x27, 0x36, 0x27, 0x26, 0x27, 0x33, 0x14, 0x17, 0x16, 0x04, 0x5c, - 0xab, 0xc9, 0x02, 0xfd, 0xf7, 0xfd, 0xe7, 0xd1, 0x91, 0xa4, 0x01, 0x01, - 0x01, 0x5c, 0x01, 0x58, 0x01, 0x01, 0xb7, 0xb8, 0xb0, 0xa4, 0x01, 0x01, - 0xa1, 0x8f, 0x01, 0xb7, 0x82, 0xa7, 0x02, 0x85, 0x99, 0x58, 0x14, 0x7b, - 0xbf, 0xfe, 0x13, 0x02, 0xc3, 0x61, 0x01, 0x44, 0x01, 0x64, 0x4c, 0xfa, - 0xfe, 0xdb, 0x9e, 0xfd, 0xc9, 0x01, 0x82, 0xda, 0x88, 0xb8, 0x77, 0x2f, - 0x2e, 0xad, 0x7d, 0x2e, 0x38, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x9e, - 0x00, 0x00, 0x04, 0x33, 0x05, 0xf1, 0x00, 0x0b, 0x00, 0x13, 0x00, 0x00, - 0x01, 0x12, 0x21, 0x20, 0x11, 0x10, 0x21, 0x32, 0x17, 0x33, 0x11, 0x33, - 0x03, 0x10, 0x21, 0x20, 0x11, 0x10, 0x21, 0x20, 0x04, 0x33, 0x02, 0xfe, - 0x2f, 0xfe, 0x3a, 0x01, 0xc6, 0xd7, 0x32, 0x14, 0xb2, 0xba, 0xfe, 0xea, - 0xfe, 0xf6, 0x01, 0x09, 0x01, 0x17, 0x02, 0x05, 0xfd, 0xfb, 0x01, 0xfd, - 0x02, 0x19, 0x73, 0x02, 0x4e, 0xfc, 0x16, 0x01, 0x80, 0xfe, 0x76, 0xfe, - 0x94, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xa1, 0x00, 0x00, 0x04, 0x9c, - 0x06, 0x14, 0x00, 0x1f, 0x00, 0x27, 0x00, 0x00, 0x13, 0x02, 0x21, 0x32, - 0x17, 0x33, 0x36, 0x33, 0x32, 0x11, 0x23, 0x34, 0x23, 0x22, 0x1d, 0x01, - 0x23, 0x35, 0x34, 0x23, 0x22, 0x15, 0x11, 0x33, 0x36, 0x37, 0x20, 0x11, - 0x02, 0x05, 0x20, 0x11, 0x37, 0x12, 0x33, 0x24, 0x03, 0x12, 0x05, 0x20, - 0xa1, 0x02, 0x01, 0x30, 0xac, 0x3a, 0x14, 0x3f, 0xba, 0xda, 0x99, 0x55, - 0xa0, 0x9d, 0x8d, 0x8e, 0x14, 0x46, 0xc1, 0x01, 0xc1, 0x01, 0xfe, 0x2b, - 0xfe, 0x45, 0xba, 0x01, 0xfc, 0x01, 0x22, 0x01, 0x01, 0xfe, 0xf9, 0xfe, - 0xe9, 0x04, 0xd4, 0x01, 0x40, 0xc1, 0xc1, 0xfe, 0x94, 0xe2, 0xd0, 0x23, - 0x21, 0xd2, 0xd5, 0xfe, 0xdf, 0x81, 0x01, 0xfd, 0xee, 0xfd, 0xfd, 0x01, - 0x02, 0x0f, 0x26, 0xfe, 0x5c, 0x01, 0x01, 0x72, 0x01, 0x85, 0x01, 0x00, - 0x00, 0x02, 0x00, 0xa0, 0xfe, 0x59, 0x04, 0x34, 0x05, 0xf1, 0x00, 0x25, - 0x00, 0x2d, 0x00, 0x00, 0x05, 0x10, 0x21, 0x20, 0x13, 0x34, 0x37, 0x17, - 0x06, 0x15, 0x14, 0x05, 0x20, 0x03, 0x34, 0x27, 0x26, 0x27, 0x07, 0x20, - 0x11, 0x10, 0x21, 0x17, 0x11, 0x33, 0x11, 0x16, 0x17, 0x33, 0x15, 0x23, - 0x14, 0x0f, 0x01, 0x16, 0x17, 0x16, 0x01, 0x14, 0x33, 0x16, 0x27, 0x36, - 0x23, 0x26, 0x04, 0x34, 0xfe, 0x34, 0xfe, 0x36, 0x02, 0x51, 0x8f, 0x26, - 0x01, 0x0e, 0x01, 0x11, 0x01, 0xb0, 0x71, 0x03, 0x59, 0xfe, 0xcb, 0x01, - 0x41, 0x4d, 0x9d, 0x5e, 0x01, 0xb8, 0xbd, 0x52, 0x01, 0x01, 0xac, 0x8d, - 0xfd, 0x42, 0xa3, 0xab, 0x01, 0x01, 0xa2, 0xac, 0x14, 0xfe, 0x6d, 0x01, - 0x95, 0x69, 0x5e, 0x69, 0x24, 0x49, 0xfa, 0x01, 0x01, 0x08, 0xa0, 0x63, - 0x6f, 0x66, 0x13, 0x01, 0x48, 0x01, 0x4d, 0x09, 0x01, 0xb4, 0xfe, 0x01, - 0x3b, 0x69, 0xa2, 0x69, 0x37, 0x48, 0x41, 0x69, 0x61, 0x02, 0x42, 0xc9, - 0x03, 0xcc, 0xc1, 0x01, 0x00, 0x02, 0x00, 0x9f, 0x00, 0x00, 0x04, 0x34, - 0x05, 0xf1, 0x00, 0x0b, 0x00, 0x13, 0x00, 0x00, 0x01, 0x02, 0x21, 0x20, - 0x19, 0x01, 0x33, 0x11, 0x33, 0x36, 0x33, 0x04, 0x03, 0x10, 0x21, 0x20, - 0x11, 0x10, 0x21, 0x20, 0x04, 0x34, 0x01, 0xfe, 0x39, 0xfe, 0x33, 0xab, - 0x29, 0x4a, 0xaf, 0x01, 0xc8, 0xbb, 0xfe, 0xf2, 0xfe, 0xee, 0x01, 0x14, - 0x01, 0x0c, 0x02, 0x0d, 0xfd, 0xf3, 0x02, 0x0d, 0x03, 0xe4, 0xfd, 0xa1, - 0x84, 0x01, 0xfd, 0xf8, 0x01, 0x7b, 0xfe, 0x83, 0xfe, 0x86, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x9f, 0xfe, 0x59, 0x04, 0x34, 0x04, 0xd7, 0x00, 0x1f, - 0x00, 0x00, 0x25, 0x10, 0x21, 0x20, 0x11, 0x34, 0x37, 0x17, 0x06, 0x15, - 0x10, 0x05, 0x20, 0x11, 0x36, 0x27, 0x26, 0x27, 0x35, 0x25, 0x35, 0x05, - 0x35, 0x33, 0x11, 0x05, 0x15, 0x25, 0x15, 0x14, 0x17, 0x16, 0x04, 0x34, - 0xfe, 0x2e, 0xfe, 0x3d, 0x6b, 0x90, 0x40, 0x01, 0x08, 0x01, 0x16, 0x01, - 0xc2, 0xaa, 0x01, 0xfe, 0xb9, 0x01, 0x47, 0x92, 0x01, 0x50, 0xfe, 0xb0, - 0xd7, 0xbe, 0x29, 0xfe, 0x30, 0x01, 0xcf, 0x7d, 0x8c, 0x59, 0x69, 0x47, - 0xfe, 0xbe, 0x01, 0x01, 0x42, 0xad, 0x9d, 0xab, 0x87, 0xa0, 0x78, 0xb4, - 0x80, 0xe8, 0xfe, 0xf3, 0x7f, 0xb1, 0x86, 0x7d, 0x48, 0xba, 0xb7, 0x00, - 0x00, 0x01, 0x00, 0x9e, 0x00, 0x00, 0x04, 0x34, 0x06, 0x14, 0x00, 0x2b, - 0x00, 0x00, 0x01, 0x10, 0x21, 0x20, 0x11, 0x35, 0x33, 0x15, 0x02, 0x21, - 0x20, 0x27, 0x34, 0x27, 0x23, 0x35, 0x33, 0x32, 0x35, 0x36, 0x2b, 0x01, - 0x35, 0x33, 0x32, 0x37, 0x34, 0x25, 0x26, 0x35, 0x33, 0x14, 0x05, 0x16, - 0x15, 0x14, 0x07, 0x15, 0x16, 0x15, 0x14, 0x07, 0x15, 0x16, 0x04, 0x34, - 0xfe, 0x37, 0xfe, 0x33, 0xbc, 0x01, 0x01, 0x0c, 0x01, 0x15, 0x02, 0x6c, - 0xfb, 0xfb, 0x64, 0x01, 0x65, 0xfb, 0xf9, 0x5b, 0x01, 0xff, 0x00, 0xe9, - 0xa6, 0x01, 0x14, 0xe9, 0x90, 0x9a, 0x94, 0x9e, 0x01, 0x68, 0xfe, 0x98, - 0x01, 0xa0, 0x65, 0x65, 0xfe, 0xec, 0xd4, 0xae, 0x01, 0x96, 0x7a, 0x73, - 0x98, 0x84, 0x55, 0x20, 0x21, 0xd0, 0x78, 0x1a, 0x1a, 0xbe, 0x8c, 0x2f, - 0x14, 0x36, 0x89, 0x7e, 0x3a, 0x14, 0x5f, 0x00, 0x00, 0x01, 0x00, 0x76, - 0xfe, 0x59, 0x04, 0x33, 0x06, 0x14, 0x00, 0x3d, 0x00, 0x00, 0x05, 0x02, - 0x21, 0x20, 0x11, 0x10, 0x13, 0x36, 0x03, 0x33, 0x12, 0x03, 0x06, 0x03, - 0x12, 0x21, 0x32, 0x27, 0x34, 0x27, 0x23, 0x35, 0x33, 0x36, 0x35, 0x34, - 0x2b, 0x01, 0x35, 0x33, 0x32, 0x35, 0x34, 0x07, 0x23, 0x35, 0x33, 0x32, - 0x35, 0x26, 0x27, 0x26, 0x27, 0x33, 0x14, 0x17, 0x16, 0x17, 0x06, 0x07, - 0x15, 0x16, 0x17, 0x06, 0x07, 0x15, 0x16, 0x17, 0x06, 0x07, 0x15, 0x16, - 0x04, 0x33, 0x01, 0xfe, 0x54, 0xfd, 0xf0, 0x37, 0x36, 0x68, 0xb9, 0x54, - 0x25, 0x31, 0x01, 0x01, 0x01, 0x54, 0xfb, 0x02, 0x86, 0x88, 0x88, 0x86, - 0x84, 0x8a, 0x8a, 0x84, 0x86, 0x88, 0x88, 0x86, 0x01, 0xb9, 0x91, 0x01, - 0xa6, 0xbd, 0x9c, 0x01, 0x01, 0xb2, 0xb2, 0x01, 0x01, 0xb2, 0xb2, 0x01, - 0x02, 0xb1, 0xb2, 0x7c, 0xfe, 0xd5, 0x01, 0xd8, 0x01, 0x2b, 0x01, 0x0d, - 0xe3, 0x01, 0x3f, 0xfe, 0xf9, 0xfe, 0xe5, 0xe1, 0xfe, 0xa9, 0xfe, 0xb3, - 0xa0, 0xc6, 0x02, 0x8e, 0x01, 0x86, 0xa4, 0x8a, 0x9c, 0x84, 0x01, 0x91, - 0x8e, 0x52, 0x21, 0x22, 0xb2, 0x48, 0x36, 0x31, 0x98, 0xa5, 0x22, 0x14, - 0x28, 0x9f, 0xbb, 0x1e, 0x14, 0x26, 0xb7, 0x92, 0x30, 0x14, 0x3a, 0x00, - 0x00, 0x02, 0x00, 0xa0, 0xfe, 0xf3, 0x04, 0x34, 0x04, 0x16, 0x00, 0x11, - 0x00, 0x19, 0x00, 0x00, 0x17, 0x32, 0x37, 0x24, 0x11, 0x12, 0x25, 0x20, - 0x11, 0x10, 0x05, 0x16, 0x37, 0x15, 0x24, 0x27, 0x06, 0x07, 0x13, 0x10, - 0x05, 0x24, 0x03, 0x12, 0x21, 0x20, 0xc9, 0x95, 0x50, 0xfe, 0xf2, 0x03, - 0x01, 0xc5, 0x01, 0xcc, 0xfe, 0xe7, 0x5c, 0x8f, 0xfe, 0xf8, 0x96, 0xc1, - 0xde, 0x90, 0x01, 0x0f, 0x01, 0x12, 0x01, 0x01, 0xfe, 0xe9, 0xfe, 0xf6, - 0x3c, 0x59, 0xaa, 0x01, 0x40, 0x02, 0x0e, 0x01, 0xfd, 0xf1, 0xfe, 0xc0, - 0xaa, 0x5e, 0x05, 0xd1, 0x45, 0xc2, 0xc1, 0x46, 0x03, 0x14, 0xfe, 0xc4, - 0x55, 0x55, 0x01, 0x3c, 0x01, 0x7f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x9f, - 0xfe, 0x57, 0x04, 0x34, 0x04, 0x15, 0x00, 0x1d, 0x00, 0x00, 0x05, 0x02, - 0x05, 0x20, 0x11, 0x37, 0x17, 0x07, 0x12, 0x21, 0x20, 0x11, 0x35, 0x10, - 0x05, 0x23, 0x35, 0x33, 0x20, 0x13, 0x27, 0x05, 0x15, 0x23, 0x11, 0x25, - 0x10, 0x05, 0x04, 0x11, 0x04, 0x34, 0x01, 0xfe, 0x30, 0xfe, 0x3c, 0x1f, - 0xb4, 0x15, 0x01, 0x01, 0x0a, 0x01, 0x0e, 0xfe, 0xc2, 0x72, 0x72, 0x01, - 0x1e, 0x01, 0x02, 0xfe, 0x20, 0xad, 0x03, 0x6c, 0xfe, 0xec, 0x01, 0x14, - 0x14, 0xfe, 0x6d, 0x02, 0x01, 0x95, 0x6f, 0x14, 0x5b, 0xfe, 0xf9, 0x01, - 0x07, 0x20, 0x01, 0x2b, 0x01, 0xa0, 0x01, 0x65, 0x4a, 0x1e, 0xcc, 0x01, - 0x5d, 0x1d, 0xfe, 0x30, 0xb9, 0x71, 0xfe, 0xf1, 0x00, 0x01, 0x00, 0x9f, - 0xfe, 0x57, 0x04, 0x34, 0x06, 0x15, 0x00, 0x24, 0x00, 0x00, 0x05, 0x10, - 0x21, 0x20, 0x11, 0x33, 0x10, 0x21, 0x20, 0x11, 0x35, 0x34, 0x21, 0x23, - 0x35, 0x33, 0x24, 0x11, 0x06, 0x23, 0x04, 0x11, 0x10, 0x05, 0x15, 0x20, - 0x15, 0x14, 0x21, 0x32, 0x37, 0x11, 0x12, 0x05, 0x15, 0x04, 0x15, 0x04, - 0x34, 0xfe, 0x34, 0xfe, 0x37, 0xbe, 0x01, 0x0b, 0x01, 0x0d, 0xfe, 0xed, - 0x9c, 0x9c, 0x01, 0x14, 0x7d, 0x8f, 0xfe, 0x35, 0x01, 0xcb, 0xfe, 0xc8, - 0x01, 0x36, 0xee, 0xdd, 0x01, 0xfe, 0xcb, 0x01, 0x35, 0x14, 0xfe, 0x6b, - 0x01, 0x95, 0xfe, 0xf8, 0x01, 0x08, 0x37, 0xec, 0x9d, 0x0b, 0x01, 0x9e, - 0x25, 0x03, 0x01, 0x64, 0x01, 0x85, 0x01, 0x8e, 0xf6, 0xd2, 0xa8, 0xfe, - 0xf8, 0xfe, 0x75, 0x69, 0x14, 0x3e, 0xf6, 0x00, 0x00, 0x03, 0x00, 0x8b, - 0x00, 0x00, 0x04, 0x7c, 0x06, 0x15, 0x00, 0x17, 0x00, 0x1f, 0x00, 0x27, - 0x00, 0x00, 0x01, 0x15, 0x10, 0x21, 0x20, 0x11, 0x10, 0x25, 0x21, 0x35, - 0x21, 0x24, 0x11, 0x10, 0x21, 0x20, 0x11, 0x15, 0x33, 0x15, 0x23, 0x15, - 0x33, 0x15, 0x25, 0x21, 0x20, 0x15, 0x14, 0x21, 0x20, 0x35, 0x01, 0x14, - 0x29, 0x01, 0x35, 0x34, 0x21, 0x20, 0x04, 0x0a, 0xfe, 0x49, 0xfe, 0x38, - 0x01, 0xc4, 0x01, 0x11, 0xfe, 0xef, 0xfe, 0x3c, 0x01, 0xcc, 0x01, 0xb3, - 0x72, 0x72, 0x72, 0xfe, 0xe4, 0xfe, 0xef, 0xfe, 0xfa, 0x01, 0x0e, 0x01, - 0x09, 0xfd, 0xe9, 0x01, 0x06, 0x01, 0x11, 0xfe, 0xf7, 0xfe, 0xf2, 0x02, - 0x05, 0xb6, 0xfe, 0xb1, 0x01, 0x4f, 0x01, 0x66, 0x02, 0xa1, 0x01, 0x01, - 0x6b, 0x01, 0x51, 0xfe, 0xaf, 0xd8, 0x94, 0xa1, 0xb2, 0x1e, 0xce, 0xc9, - 0xd3, 0x03, 0x63, 0xd6, 0xd8, 0xc3, 0x00, 0x00, 0x00, 0x02, 0x00, 0x37, - 0xfe, 0x58, 0x04, 0x9a, 0x04, 0x16, 0x00, 0x21, 0x00, 0x2c, 0x00, 0x00, - 0x01, 0x10, 0x21, 0x22, 0x27, 0x23, 0x15, 0x02, 0x21, 0x35, 0x32, 0x27, - 0x11, 0x34, 0x23, 0x07, 0x26, 0x15, 0x11, 0x14, 0x33, 0x15, 0x24, 0x11, - 0x35, 0x10, 0x21, 0x32, 0x17, 0x33, 0x36, 0x33, 0x04, 0x11, 0x03, 0x11, - 0x34, 0x2b, 0x01, 0x22, 0x15, 0x11, 0x14, 0x33, 0x32, 0x04, 0x9a, 0xfe, - 0xcd, 0x7e, 0x1a, 0x0f, 0x0b, 0xfe, 0xb3, 0xb7, 0x09, 0x4d, 0x61, 0x73, - 0x80, 0xfe, 0xc2, 0x01, 0x31, 0xb7, 0x44, 0x10, 0x3e, 0xb6, 0x01, 0x33, - 0xbd, 0x88, 0x4c, 0x49, 0xa7, 0x76, 0x01, 0x96, 0xfe, 0x6a, 0x74, 0x98, - 0xfe, 0x7c, 0x8e, 0xe7, 0x03, 0x09, 0xb2, 0x01, 0x01, 0xbd, 0xfe, 0xc1, - 0xd9, 0x94, 0x03, 0x01, 0x78, 0xf0, 0x01, 0x8c, 0x91, 0x91, 0x01, 0xfe, - 0x75, 0xfe, 0xae, 0x01, 0xa1, 0xaf, 0xa7, 0xfe, 0x83, 0xd3, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x6b, 0xfe, 0x59, 0x04, 0x66, 0x04, 0x16, 0x00, 0x1f, - 0x00, 0x00, 0x21, 0x02, 0x21, 0x20, 0x03, 0x10, 0x25, 0x24, 0x35, 0x34, - 0x23, 0x22, 0x07, 0x17, 0x07, 0x27, 0x10, 0x21, 0x20, 0x11, 0x06, 0x05, - 0x04, 0x11, 0x02, 0x21, 0x20, 0x13, 0x34, 0x27, 0x37, 0x16, 0x04, 0x66, - 0x01, 0xfd, 0xf5, 0xfe, 0x12, 0x01, 0x01, 0x47, 0x01, 0x44, 0x98, 0xb5, - 0x01, 0x05, 0xa5, 0x0a, 0x01, 0x60, 0x01, 0x55, 0x01, 0xfe, 0xaf, 0xfe, - 0xc8, 0x01, 0x01, 0x36, 0x01, 0x49, 0x01, 0x40, 0x9a, 0x62, 0xfe, 0x59, - 0x01, 0xa7, 0x01, 0x73, 0x72, 0x67, 0x7f, 0xbc, 0x9f, 0x38, 0x15, 0x41, - 0x01, 0x3a, 0xfe, 0xa8, 0xd4, 0x83, 0x4d, 0xfe, 0xee, 0xfe, 0xdc, 0x01, - 0x29, 0x7b, 0x36, 0x5c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xa1, - 0xfe, 0x59, 0x04, 0x34, 0x04, 0x28, 0x00, 0x1b, 0x00, 0x00, 0x13, 0x33, - 0x11, 0x16, 0x21, 0x20, 0x11, 0x34, 0x25, 0x37, 0x04, 0x13, 0x10, 0x25, - 0x23, 0x22, 0x27, 0x23, 0x15, 0x02, 0x25, 0x20, 0x11, 0x33, 0x02, 0x21, - 0x20, 0x11, 0xa1, 0xad, 0x01, 0x01, 0x23, 0x01, 0x07, 0xfe, 0xf9, 0xab, - 0x01, 0x16, 0x01, 0xfe, 0x3e, 0x02, 0xb9, 0x55, 0x14, 0x02, 0x01, 0x26, - 0x01, 0x07, 0xbb, 0x01, 0xfe, 0x3b, 0xfe, 0x33, 0x03, 0xfe, 0xfd, 0xcc, - 0xbf, 0x01, 0x30, 0xfd, 0xb1, 0x3f, 0xe2, 0xfe, 0xf5, 0xfe, 0x37, 0x01, - 0x59, 0xe3, 0xfe, 0xfb, 0x01, 0x01, 0x04, 0xfe, 0x70, 0x01, 0x8c, 0x00, - 0x00, 0x02, 0x00, 0x6e, 0xfe, 0x57, 0x04, 0x63, 0x04, 0x24, 0x00, 0x16, - 0x00, 0x1e, 0x00, 0x00, 0x13, 0x02, 0x21, 0x04, 0x11, 0x10, 0x05, 0x04, - 0x15, 0x14, 0x17, 0x36, 0x3d, 0x01, 0x33, 0x15, 0x02, 0x21, 0x20, 0x11, - 0x34, 0x37, 0x24, 0x13, 0x16, 0x05, 0x24, 0x35, 0x10, 0x21, 0x20, 0x6e, - 0x01, 0x02, 0x00, 0x01, 0xf6, 0xfe, 0x96, 0xfe, 0xda, 0x9e, 0xc3, 0xb2, - 0x01, 0xfe, 0x8c, 0xfe, 0xaa, 0xef, 0xfe, 0x64, 0xbf, 0x01, 0x01, 0x3f, - 0x01, 0x3b, 0xfe, 0xc5, 0xfe, 0xc0, 0x02, 0x6b, 0x01, 0xb9, 0x01, 0xfe, - 0x48, 0xfe, 0xeb, 0xa9, 0x75, 0x9e, 0xb5, 0x01, 0x01, 0x8c, 0x4c, 0x4c, - 0xfe, 0xe6, 0x01, 0x38, 0xe7, 0x54, 0x57, 0x01, 0x4a, 0xff, 0x26, 0x29, - 0xfc, 0x01, 0x2a, 0x00, 0x00, 0x01, 0x00, 0xa0, 0xff, 0x79, 0x03, 0xa4, - 0x04, 0x16, 0x00, 0x1a, 0x00, 0x00, 0x05, 0x35, 0x34, 0x26, 0x23, 0x22, - 0x07, 0x27, 0x36, 0x37, 0x35, 0x26, 0x11, 0x10, 0x25, 0x04, 0x01, 0x27, - 0x00, 0x25, 0x20, 0x03, 0x1e, 0x01, 0x17, 0x16, 0x17, 0x02, 0xef, 0x74, - 0x5f, 0x82, 0x43, 0x82, 0x43, 0x74, 0xec, 0x01, 0xe4, 0x02, 0xa7, 0xfe, - 0x79, 0x91, 0x01, 0x11, 0xfe, 0x60, 0xfe, 0xdc, 0x01, 0x03, 0x5e, 0x71, - 0xb2, 0x7c, 0x87, 0x01, 0x05, 0x79, 0x74, 0x4a, 0x66, 0x18, 0x1e, 0xad, - 0x01, 0x49, 0x01, 0xb5, 0x01, 0x38, 0xfd, 0x05, 0x3d, 0x02, 0x5c, 0x0b, - 0xfe, 0xdb, 0xa3, 0xca, 0x62, 0x2a, 0x93, 0x00, 0x00, 0x03, 0x01, 0x23, - 0x00, 0x32, 0x03, 0xae, 0x03, 0xe3, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, - 0x00, 0x00, 0x01, 0x33, 0x15, 0x23, 0x05, 0x33, 0x15, 0x23, 0x05, 0x33, - 0x15, 0x23, 0x01, 0x23, 0xc0, 0xc0, 0x01, 0xd1, 0xba, 0xba, 0xfe, 0x2f, - 0xbd, 0xbd, 0x03, 0xe3, 0xb0, 0xbd, 0xae, 0xe8, 0xae, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x01, 0x95, 0x02, 0xf5, 0x03, 0x3b, 0x06, 0x14, 0x00, 0x0f, - 0x00, 0x17, 0x00, 0x00, 0x01, 0x32, 0x03, 0x10, 0x07, 0x22, 0x19, 0x01, - 0x34, 0x3b, 0x01, 0x15, 0x25, 0x22, 0x1d, 0x01, 0x17, 0x34, 0x23, 0x22, - 0x07, 0x14, 0x33, 0x32, 0x02, 0x6c, 0xd0, 0x01, 0xd5, 0xd1, 0xb9, 0xeb, - 0xfe, 0xfe, 0x46, 0xed, 0x7c, 0x70, 0x01, 0x75, 0x78, 0x05, 0x24, 0xfe, - 0xef, 0xfe, 0xe3, 0x01, 0x01, 0x1e, 0x01, 0x4c, 0xb5, 0x52, 0x02, 0x51, - 0x9e, 0xc2, 0xb4, 0xba, 0xc9, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x29, - 0xff, 0xe3, 0x04, 0xb0, 0x04, 0x7b, 0x00, 0x0a, 0x00, 0x12, 0x00, 0x42, - 0x00, 0x00, 0x01, 0x15, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, - 0x06, 0x01, 0x15, 0x14, 0x16, 0x32, 0x36, 0x3d, 0x01, 0x25, 0x21, 0x3e, - 0x01, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, - 0x32, 0x16, 0x17, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x2b, - 0x01, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x15, 0x0e, 0x01, 0x23, - 0x22, 0x26, 0x27, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x11, 0x02, 0xba, 0x31, - 0xa9, 0x78, 0x59, 0x53, 0x5c, 0x4a, 0xfe, 0x13, 0x4d, 0xae, 0x4c, 0xfe, - 0x15, 0x01, 0xeb, 0x01, 0x01, 0x65, 0x70, 0x4f, 0x81, 0x32, 0x37, 0x84, - 0x47, 0x6e, 0x95, 0x20, 0x27, 0x85, 0x61, 0x9c, 0xa3, 0xc8, 0xbf, 0x75, - 0x63, 0x5e, 0x38, 0x84, 0x3e, 0x4d, 0x84, 0x3c, 0x5b, 0x7c, 0x25, 0x21, - 0x84, 0x59, 0xae, 0x91, 0x02, 0xa4, 0x48, 0x5a, 0x71, 0x59, 0x61, 0x85, - 0xfe, 0x71, 0x34, 0x97, 0x85, 0x88, 0x9d, 0x2b, 0x8f, 0x0f, 0x23, 0x22, - 0xa1, 0x90, 0x33, 0x33, 0xac, 0x29, 0x2b, 0x52, 0x4e, 0x50, 0x50, 0xac, - 0xa4, 0xab, 0xb3, 0x58, 0x78, 0x80, 0x2b, 0x27, 0xa8, 0x23, 0x21, 0x3f, - 0x40, 0x3d, 0x42, 0xed, 0x01, 0x32, 0x00, 0x00, 0x00, 0x01, 0x00, 0xa9, - 0xff, 0xea, 0x04, 0x28, 0x04, 0x7b, 0x00, 0x30, 0x00, 0x00, 0x01, 0x16, - 0x17, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x35, 0x16, - 0x17, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x27, 0x26, 0x2b, 0x01, 0x35, - 0x33, 0x32, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, - 0x35, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x06, 0x03, - 0x10, 0x77, 0x41, 0x40, 0xf4, 0xd1, 0x51, 0x5b, 0x5c, 0x69, 0x68, 0x57, - 0x56, 0x4c, 0x8a, 0x94, 0x48, 0x48, 0x87, 0xa6, 0x9f, 0x96, 0xa8, 0x5a, - 0x5b, 0xad, 0x63, 0x5b, 0x5b, 0x4d, 0x61, 0x5a, 0x5b, 0x56, 0xfe, 0x8b, - 0x8a, 0x94, 0x02, 0x06, 0x19, 0x41, 0x40, 0x5e, 0x86, 0x9e, 0x0c, 0x0c, - 0x18, 0xa7, 0x1b, 0x0d, 0x0c, 0x56, 0x4a, 0x3d, 0x2b, 0x2c, 0x90, 0x6e, - 0x51, 0x62, 0x35, 0x34, 0x12, 0x11, 0x22, 0xad, 0x1c, 0x0e, 0x0e, 0x5b, - 0x5c, 0xa6, 0x6d, 0x94, 0x00, 0x02, 0x00, 0xb2, 0xfe, 0x50, 0x04, 0x44, - 0x04, 0x64, 0x00, 0x09, 0x00, 0x0d, 0x00, 0x00, 0x25, 0x21, 0x11, 0x21, - 0x35, 0x21, 0x15, 0x21, 0x11, 0x21, 0x01, 0x23, 0x35, 0x33, 0x03, 0xf6, - 0xfe, 0x29, 0xfe, 0x93, 0x03, 0x92, 0xfe, 0x93, 0x01, 0x1f, 0xfe, 0xe1, - 0xb8, 0xb8, 0x04, 0x03, 0xd1, 0x8f, 0x8f, 0xfc, 0xbe, 0xfd, 0xbd, 0xe9, - 0x00, 0x03, 0x00, 0x0e, 0xff, 0xe3, 0x04, 0xba, 0x04, 0x7b, 0x00, 0x0a, - 0x00, 0x15, 0x00, 0x36, 0x00, 0x00, 0x13, 0x14, 0x06, 0x15, 0x14, 0x16, - 0x33, 0x32, 0x36, 0x3d, 0x01, 0x01, 0x22, 0x06, 0x15, 0x10, 0x16, 0x33, - 0x32, 0x36, 0x10, 0x26, 0x01, 0x21, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, - 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x17, 0x3e, 0x01, 0x33, 0x32, - 0x12, 0x10, 0x02, 0x23, 0x22, 0x26, 0x27, 0x0e, 0x01, 0x23, 0x22, 0x26, - 0x11, 0xb1, 0x02, 0x50, 0x56, 0x57, 0x4d, 0x01, 0x5a, 0x66, 0x52, 0x50, - 0x68, 0x67, 0x50, 0x50, 0xfc, 0x54, 0x01, 0xeb, 0x63, 0x70, 0x50, 0x83, - 0x2f, 0x3b, 0x7d, 0x4a, 0x62, 0x93, 0x30, 0x34, 0x80, 0x54, 0xbd, 0xaa, - 0xaa, 0xbd, 0x59, 0x80, 0x2f, 0x25, 0x82, 0x57, 0xaf, 0x90, 0x01, 0xcd, - 0x0b, 0x26, 0x09, 0x91, 0x87, 0x89, 0x9e, 0x2b, 0x02, 0x16, 0xa8, 0xef, - 0xfe, 0xdd, 0xae, 0xa7, 0x02, 0x1a, 0xa7, 0xfe, 0x79, 0x54, 0xa3, 0x90, - 0x35, 0x33, 0xac, 0x2b, 0x29, 0x43, 0x42, 0x44, 0x41, 0xfe, 0xec, 0xfd, - 0x90, 0xfe, 0xec, 0x3e, 0x41, 0x3e, 0x41, 0xed, 0x01, 0x32, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x89, 0x02, 0x2f, 0x04, 0x48, 0x04, 0x7b, 0x00, 0x0c, - 0x00, 0x00, 0x13, 0x10, 0x12, 0x20, 0x12, 0x11, 0x23, 0x34, 0x26, 0x23, - 0x22, 0x06, 0x15, 0x89, 0xf6, 0x01, 0xd2, 0xf7, 0xc3, 0x90, 0x8d, 0x8c, - 0x90, 0x02, 0x2f, 0x01, 0x1e, 0x01, 0x2e, 0xfe, 0xd2, 0xfe, 0xe2, 0xd6, - 0xda, 0xda, 0xd6, 0x00, 0x00, 0x01, 0x00, 0x88, 0xff, 0xe3, 0x04, 0x47, - 0x02, 0x2f, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x10, 0x02, 0x20, 0x02, 0x11, - 0x33, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x04, 0x47, 0xf6, 0xfe, 0x2e, - 0xf7, 0xc3, 0x90, 0x8d, 0x8c, 0x90, 0x02, 0x2f, 0xfe, 0xe2, 0xfe, 0xd2, - 0x01, 0x2e, 0x01, 0x1e, 0xd6, 0xda, 0xda, 0xd6, 0x00, 0x01, 0x00, 0x2b, - 0x00, 0x02, 0x04, 0xa6, 0x03, 0x5b, 0x00, 0x13, 0x00, 0x00, 0x25, 0x21, - 0x35, 0x21, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x21, 0x35, 0x21, 0x15, - 0x23, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x02, 0xe1, 0xfd, 0x4a, 0x02, 0xb6, - 0x97, 0x8e, 0xb7, 0xab, 0xfd, 0x87, 0x04, 0x5e, 0xa8, 0x61, 0x64, 0xe1, - 0x02, 0xb8, 0x6c, 0x70, 0x82, 0x8a, 0xb8, 0xb8, 0x32, 0xa8, 0x72, 0xac, - 0xa8, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x3f, 0xff, 0xfe, 0x04, 0x92, - 0x03, 0x57, 0x00, 0x03, 0x00, 0x07, 0x00, 0x1b, 0x00, 0x00, 0x37, 0x35, - 0x33, 0x15, 0x03, 0x35, 0x33, 0x15, 0x01, 0x21, 0x35, 0x21, 0x32, 0x36, - 0x35, 0x34, 0x26, 0x23, 0x21, 0x35, 0x21, 0x15, 0x23, 0x1e, 0x01, 0x15, - 0x14, 0x06, 0x3f, 0x8e, 0x8e, 0x8e, 0x02, 0x88, 0xfe, 0x1a, 0x01, 0xe6, - 0x69, 0x64, 0x80, 0x78, 0xfe, 0x45, 0x03, 0x0f, 0x76, 0x44, 0x46, 0x9e, - 0x7a, 0xcc, 0xcc, 0x01, 0x88, 0xca, 0xca, 0xfd, 0xfc, 0xb8, 0x6c, 0x70, - 0x82, 0x8a, 0xb8, 0xb8, 0x32, 0xa8, 0x72, 0xac, 0xa8, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x2b, 0x00, 0x01, 0x04, 0xa6, 0x04, 0x03, 0x00, 0x22, - 0x00, 0x00, 0x01, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x29, 0x01, 0x35, 0x21, - 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x21, 0x35, 0x21, 0x32, 0x36, 0x35, - 0x34, 0x26, 0x23, 0x21, 0x35, 0x21, 0x15, 0x23, 0x1e, 0x01, 0x15, 0x14, - 0x06, 0x04, 0x19, 0x48, 0x45, 0xd1, 0xfe, 0xdf, 0xfd, 0x77, 0x02, 0x81, - 0xed, 0x73, 0x7b, 0xe5, 0xfd, 0x7f, 0x02, 0x81, 0xf0, 0x70, 0x7b, 0xe5, - 0xfd, 0x7f, 0x04, 0x60, 0x60, 0x3c, 0x3f, 0x46, 0x01, 0xcc, 0x22, 0x69, - 0x4a, 0x87, 0x6f, 0xa8, 0x35, 0x46, 0x50, 0x3b, 0xa8, 0x39, 0x4a, 0x49, - 0x39, 0xa7, 0xa7, 0x21, 0x63, 0x3f, 0x4c, 0x65, 0x00, 0x02, 0x00, 0xfc, - 0x02, 0x9c, 0x03, 0xd6, 0x05, 0xe0, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, - 0x01, 0x03, 0x21, 0x03, 0x33, 0x01, 0x23, 0x27, 0x21, 0x07, 0x23, 0x02, - 0x68, 0x86, 0x01, 0x0c, 0xd2, 0x9a, 0x01, 0x20, 0x84, 0x44, 0xfe, 0xb6, - 0x44, 0x84, 0x05, 0x7c, 0xfe, 0x55, 0x02, 0x0f, 0xfc, 0xbc, 0xda, 0xda, - 0x00, 0x02, 0x00, 0xf5, 0x02, 0x9c, 0x03, 0xdc, 0x05, 0xe0, 0x00, 0x0f, - 0x00, 0x13, 0x00, 0x00, 0x01, 0x15, 0x23, 0x15, 0x33, 0x15, 0x23, 0x11, - 0x33, 0x15, 0x21, 0x35, 0x23, 0x07, 0x23, 0x01, 0x17, 0x03, 0x33, 0x11, - 0x03, 0xd0, 0xd5, 0xc2, 0xc2, 0xe1, 0xfe, 0xaa, 0xdd, 0x40, 0x74, 0x01, - 0x02, 0x4c, 0x7f, 0xc2, 0x05, 0xe0, 0x5f, 0xf8, 0x5f, 0xfe, 0xd1, 0x5f, - 0xd6, 0xd6, 0x03, 0x44, 0x5f, 0xfe, 0x50, 0x01, 0xb0, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x01, 0x37, 0x02, 0x9c, 0x03, 0x9a, 0x05, 0xe0, 0x00, 0x08, - 0x00, 0x11, 0x00, 0x20, 0x00, 0x00, 0x01, 0x11, 0x33, 0x32, 0x36, 0x35, - 0x34, 0x26, 0x23, 0x03, 0x15, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, - 0x25, 0x21, 0x32, 0x16, 0x15, 0x14, 0x06, 0x07, 0x1e, 0x01, 0x15, 0x14, - 0x06, 0x23, 0x21, 0x01, 0xb6, 0x97, 0x6f, 0x5e, 0x63, 0x6a, 0x97, 0x95, - 0x5b, 0x53, 0x51, 0x5d, 0xfe, 0xec, 0x01, 0x16, 0x90, 0x9d, 0x53, 0x53, - 0x5d, 0x69, 0xa7, 0xa6, 0xfe, 0xea, 0x04, 0x2b, 0xfe, 0xce, 0x45, 0x4f, - 0x52, 0x4c, 0x01, 0x58, 0xfc, 0x3f, 0x46, 0x3f, 0x38, 0x5d, 0x6f, 0x65, - 0x4d, 0x58, 0x0c, 0x0c, 0x74, 0x59, 0x72, 0x74, 0x00, 0x02, 0x01, 0x37, - 0x02, 0x9c, 0x03, 0x9a, 0x05, 0xe0, 0x00, 0x08, 0x00, 0x11, 0x00, 0x00, - 0x01, 0x32, 0x36, 0x35, 0x34, 0x26, 0x2b, 0x01, 0x11, 0x13, 0x32, 0x16, - 0x15, 0x14, 0x06, 0x2b, 0x01, 0x11, 0x01, 0xf4, 0xa0, 0x80, 0x7f, 0xa1, - 0x3d, 0x3f, 0xd8, 0xcc, 0xcc, 0xd8, 0xbf, 0x02, 0xf9, 0x8d, 0xb7, 0xba, - 0x8c, 0xfd, 0x76, 0x02, 0xe7, 0xcc, 0xd7, 0xd6, 0xcb, 0x03, 0x44, 0x00, - 0x00, 0x01, 0x01, 0x4c, 0x02, 0x9c, 0x03, 0x86, 0x05, 0xe0, 0x00, 0x0b, - 0x00, 0x00, 0x01, 0x21, 0x15, 0x21, 0x15, 0x21, 0x15, 0x21, 0x11, 0x21, - 0x15, 0x21, 0x01, 0x4c, 0x02, 0x2e, 0xfe, 0x50, 0x01, 0x9c, 0xfe, 0x64, - 0x01, 0xbc, 0xfd, 0xc6, 0x05, 0xe0, 0x5f, 0xf8, 0x5f, 0xfe, 0xd1, 0x5f, - 0x00, 0x01, 0x01, 0x4c, 0x02, 0x9c, 0x03, 0x86, 0x05, 0xe0, 0x00, 0x0b, - 0x00, 0x00, 0x01, 0x11, 0x21, 0x35, 0x21, 0x11, 0x21, 0x35, 0x21, 0x35, - 0x21, 0x35, 0x03, 0x86, 0xfd, 0xc6, 0x01, 0xba, 0xfe, 0x64, 0x01, 0x9c, - 0xfe, 0x52, 0x05, 0xe0, 0xfc, 0xbc, 0x5f, 0x01, 0x2f, 0x5f, 0xf8, 0x5f, - 0x00, 0x01, 0x01, 0x2c, 0x02, 0x8c, 0x03, 0xa4, 0x05, 0xef, 0x00, 0x1c, - 0x00, 0x00, 0x01, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x10, 0x36, 0x33, 0x32, - 0x16, 0x17, 0x15, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, - 0x32, 0x36, 0x37, 0x35, 0x23, 0x35, 0x21, 0x03, 0xa4, 0x34, 0x7e, 0x4c, - 0xb2, 0xc8, 0xca, 0xb4, 0x3c, 0x6c, 0x32, 0x34, 0x6a, 0x3c, 0x7c, 0x7c, - 0x78, 0x7c, 0x2a, 0x40, 0x1a, 0x88, 0x01, 0x02, 0x02, 0xe1, 0x2a, 0x2b, - 0xe4, 0x01, 0x9a, 0xe5, 0x1d, 0x1f, 0x74, 0x2b, 0x29, 0xaa, 0xac, 0xae, - 0xa7, 0x11, 0x12, 0xe1, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x3a, - 0x02, 0x9c, 0x03, 0x96, 0x05, 0xe0, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x33, - 0x11, 0x21, 0x11, 0x33, 0x11, 0x23, 0x11, 0x21, 0x11, 0x23, 0x01, 0x3a, - 0x80, 0x01, 0x5e, 0x7e, 0x7e, 0xfe, 0xa2, 0x80, 0x05, 0xe0, 0xfe, 0xa9, - 0x01, 0x57, 0xfc, 0xbc, 0x01, 0x8e, 0xfe, 0x72, 0x00, 0x01, 0x01, 0x64, - 0x02, 0x9c, 0x03, 0x6e, 0x05, 0xe0, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x21, - 0x15, 0x23, 0x11, 0x33, 0x15, 0x21, 0x35, 0x33, 0x11, 0x23, 0x01, 0x64, - 0x02, 0x0a, 0xc6, 0xc6, 0xfd, 0xf6, 0xc4, 0xc4, 0x05, 0xe0, 0x5f, 0xfd, - 0x7a, 0x5f, 0x5f, 0x02, 0x86, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x5e, - 0x02, 0x8c, 0x03, 0x73, 0x05, 0xe0, 0x00, 0x11, 0x00, 0x00, 0x01, 0x35, - 0x1e, 0x01, 0x33, 0x32, 0x36, 0x35, 0x11, 0x23, 0x35, 0x21, 0x11, 0x14, - 0x06, 0x23, 0x22, 0x26, 0x01, 0x5e, 0x39, 0x7a, 0x42, 0x5a, 0x47, 0xf0, - 0x01, 0x6f, 0x85, 0x9b, 0x3d, 0x77, 0x02, 0xbe, 0x84, 0x2d, 0x2d, 0x53, - 0x72, 0x01, 0xd4, 0x5f, 0xfd, 0xcd, 0x9e, 0x83, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x12, 0x02, 0x9c, 0x03, 0xc0, 0x05, 0xe0, 0x00, 0x0b, - 0x00, 0x00, 0x01, 0x33, 0x11, 0x01, 0x33, 0x09, 0x01, 0x23, 0x01, 0x07, - 0x11, 0x23, 0x01, 0x12, 0x80, 0x01, 0x8e, 0x94, 0xfe, 0x92, 0x01, 0x7a, - 0x9a, 0xfe, 0xcc, 0x60, 0x80, 0x05, 0xe0, 0xfe, 0x8c, 0x01, 0x74, 0xfe, - 0xaa, 0xfe, 0x12, 0x01, 0xa3, 0x5c, 0xfe, 0xb9, 0x00, 0x01, 0x01, 0x45, - 0x02, 0x9c, 0x03, 0x8c, 0x05, 0xe0, 0x00, 0x05, 0x00, 0x00, 0x01, 0x33, - 0x11, 0x21, 0x15, 0x21, 0x01, 0x45, 0x80, 0x01, 0xc7, 0xfd, 0xb9, 0x05, - 0xe0, 0xfd, 0x1b, 0x5f, 0x00, 0x01, 0x01, 0x1b, 0x02, 0x9c, 0x03, 0xb6, - 0x05, 0xe0, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x33, 0x1b, 0x01, 0x33, 0x11, - 0x23, 0x11, 0x03, 0x23, 0x03, 0x11, 0x23, 0x01, 0x1b, 0xaa, 0xa3, 0xa4, - 0xaa, 0x75, 0xa8, 0x60, 0xa9, 0x75, 0x05, 0xe0, 0xfe, 0x56, 0x01, 0xaa, - 0xfc, 0xbc, 0x02, 0xe3, 0xfe, 0x47, 0x01, 0xb9, 0xfd, 0x1d, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x3c, 0x02, 0x9c, 0x03, 0x95, 0x05, 0xe0, 0x00, 0x09, - 0x00, 0x00, 0x01, 0x33, 0x01, 0x11, 0x33, 0x11, 0x23, 0x01, 0x11, 0x23, - 0x01, 0x3c, 0xa1, 0x01, 0x3d, 0x7b, 0xa1, 0xfe, 0xc2, 0x7a, 0x05, 0xe0, - 0xfd, 0x50, 0x02, 0xb0, 0xfc, 0xbc, 0x02, 0xb0, 0xfd, 0x50, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x3c, 0x02, 0x9c, 0x03, 0x95, 0x05, 0xe0, 0x00, 0x09, - 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x01, 0x23, 0x11, 0x33, 0x11, 0x01, - 0x03, 0x95, 0x7b, 0xfe, 0xc3, 0xa1, 0x7a, 0x01, 0x3e, 0x05, 0xe0, 0xfc, - 0xbc, 0x02, 0xb0, 0xfd, 0x50, 0x03, 0x44, 0xfd, 0x50, 0x02, 0xb0, 0x00, - 0x00, 0x02, 0x01, 0x2e, 0x02, 0x8c, 0x03, 0xa3, 0x05, 0xef, 0x00, 0x0a, - 0x00, 0x13, 0x00, 0x00, 0x00, 0x10, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, - 0x16, 0x33, 0x32, 0x13, 0x14, 0x06, 0x20, 0x26, 0x10, 0x36, 0x20, 0x16, - 0x03, 0x1e, 0x55, 0x61, 0x60, 0x55, 0x55, 0x60, 0x61, 0xda, 0x9c, 0xfe, - 0xc2, 0x9b, 0x9b, 0x01, 0x3e, 0x9c, 0x03, 0x85, 0x01, 0x70, 0x9e, 0x9e, - 0xb8, 0xb7, 0x9e, 0x01, 0x55, 0xda, 0xd7, 0xd6, 0x01, 0xb6, 0xd7, 0xd7, - 0x00, 0x02, 0x01, 0x3f, 0x02, 0x9c, 0x03, 0x92, 0x05, 0xe0, 0x00, 0x08, - 0x00, 0x12, 0x00, 0x00, 0x01, 0x11, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, - 0x23, 0x25, 0x21, 0x32, 0x16, 0x14, 0x06, 0x2b, 0x01, 0x11, 0x23, 0x01, - 0xbe, 0x94, 0x58, 0x63, 0x62, 0x59, 0xfe, 0xed, 0x01, 0x13, 0x9d, 0xa3, - 0xa2, 0x9e, 0x94, 0x7f, 0x05, 0x83, 0xfe, 0xc6, 0x53, 0x4a, 0x4b, 0x52, - 0x5d, 0x7f, 0xf6, 0x7f, 0xfe, 0xb0, 0x00, 0x00, 0x00, 0x02, 0x01, 0x11, - 0x02, 0x9c, 0x03, 0xc0, 0x05, 0xe0, 0x00, 0x13, 0x00, 0x1c, 0x00, 0x00, - 0x01, 0x1e, 0x01, 0x1f, 0x01, 0x23, 0x27, 0x2e, 0x01, 0x2b, 0x01, 0x11, - 0x23, 0x11, 0x21, 0x32, 0x16, 0x15, 0x14, 0x06, 0x01, 0x11, 0x33, 0x32, - 0x36, 0x35, 0x34, 0x26, 0x23, 0x02, 0x96, 0x31, 0x45, 0x34, 0x80, 0x89, - 0x70, 0x31, 0x4d, 0x3e, 0x7a, 0x80, 0x01, 0x06, 0x9b, 0xa5, 0x65, 0xfe, - 0x9f, 0x8b, 0x5c, 0x59, 0x5f, 0x5b, 0x04, 0x27, 0x0b, 0x3f, 0x5d, 0xe4, - 0xd3, 0x5a, 0x34, 0xfe, 0x9f, 0x03, 0x44, 0x7c, 0x76, 0x53, 0x68, 0x01, - 0x50, 0xfe, 0xd7, 0x49, 0x4b, 0x48, 0x4d, 0x00, 0x00, 0x01, 0x01, 0x02, - 0x02, 0x9c, 0x03, 0xcf, 0x05, 0xe0, 0x00, 0x07, 0x00, 0x00, 0x01, 0x21, - 0x15, 0x21, 0x11, 0x23, 0x11, 0x21, 0x01, 0x02, 0x02, 0xcd, 0xfe, 0xda, - 0x80, 0xfe, 0xd9, 0x05, 0xe0, 0x5f, 0xfd, 0x1b, 0x02, 0xe5, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x41, 0x02, 0x8c, 0x03, 0x90, 0x05, 0xe0, 0x00, 0x1d, - 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, 0x14, 0x16, 0x17, 0x1e, 0x01, 0x33, - 0x32, 0x36, 0x37, 0x3e, 0x01, 0x35, 0x11, 0x33, 0x11, 0x14, 0x06, 0x07, - 0x0e, 0x01, 0x23, 0x22, 0x26, 0x27, 0x2e, 0x01, 0x01, 0x41, 0x7f, 0x08, - 0x0a, 0x14, 0x4c, 0x36, 0x37, 0x4b, 0x15, 0x0a, 0x07, 0x80, 0x24, 0x2c, - 0x2a, 0x6b, 0x43, 0x42, 0x6b, 0x2a, 0x2c, 0x24, 0x03, 0xdd, 0x02, 0x03, - 0xfd, 0xc9, 0x3d, 0x34, 0x0e, 0x21, 0x21, 0x21, 0x21, 0x0e, 0x34, 0x3c, - 0x02, 0x38, 0xfd, 0xfd, 0x80, 0x6c, 0x24, 0x21, 0x20, 0x20, 0x21, 0x23, - 0x6e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xe4, 0x02, 0x9c, 0x03, 0xed, - 0x05, 0xe0, 0x00, 0x0c, 0x00, 0x00, 0x13, 0x33, 0x1b, 0x01, 0x33, 0x1b, - 0x01, 0x33, 0x03, 0x23, 0x0b, 0x01, 0x23, 0xe4, 0x7c, 0x5a, 0x6b, 0x85, - 0x6d, 0x5a, 0x7c, 0x8d, 0x78, 0x80, 0x7f, 0x79, 0x05, 0xe0, 0xfd, 0x59, - 0x01, 0xc1, 0xfe, 0x3e, 0x02, 0xa8, 0xfc, 0xbc, 0x01, 0xf1, 0xfe, 0x0f, - 0x00, 0x02, 0x01, 0x45, 0x02, 0x8c, 0x03, 0x8c, 0x05, 0x1e, 0x00, 0x0b, - 0x00, 0x29, 0x00, 0x00, 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, - 0x32, 0x36, 0x37, 0x35, 0x37, 0x11, 0x23, 0x35, 0x0e, 0x01, 0x23, 0x22, - 0x26, 0x35, 0x34, 0x36, 0x3b, 0x01, 0x35, 0x2e, 0x01, 0x23, 0x22, 0x06, - 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x17, 0x1e, 0x01, 0x02, 0xab, - 0x26, 0x66, 0x66, 0x4d, 0x44, 0x5f, 0x6e, 0x01, 0x74, 0x74, 0x26, 0x70, - 0x51, 0x6c, 0x80, 0x9e, 0x99, 0x9c, 0x01, 0x54, 0x5d, 0x3b, 0x79, 0x3a, - 0x41, 0x76, 0x37, 0x58, 0x7c, 0x26, 0x18, 0x14, 0x03, 0xd7, 0x3f, 0x3f, - 0x38, 0x3f, 0x76, 0x68, 0x17, 0x2b, 0xfe, 0x9a, 0x5d, 0x38, 0x35, 0x6c, - 0x5b, 0x68, 0x6d, 0x10, 0x4b, 0x44, 0x1e, 0x1d, 0x67, 0x15, 0x16, 0x2e, - 0x2e, 0x1c, 0x52, 0x00, 0x00, 0x02, 0x01, 0x45, 0x02, 0x8c, 0x03, 0x8c, - 0x05, 0x1e, 0x00, 0x0b, 0x00, 0x29, 0x00, 0x00, 0x01, 0x33, 0x32, 0x36, - 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x15, 0x07, 0x11, 0x33, 0x15, - 0x3e, 0x01, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x2b, 0x01, 0x15, 0x1e, - 0x01, 0x33, 0x32, 0x36, 0x37, 0x15, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x27, - 0x2e, 0x01, 0x02, 0x26, 0x26, 0x66, 0x66, 0x4d, 0x44, 0x5f, 0x6e, 0x01, - 0x74, 0x74, 0x26, 0x70, 0x51, 0x6c, 0x80, 0x9e, 0x99, 0x9c, 0x01, 0x54, - 0x5d, 0x3b, 0x79, 0x3a, 0x41, 0x76, 0x37, 0x58, 0x7c, 0x26, 0x18, 0x14, - 0x03, 0xd3, 0x3f, 0x3f, 0x38, 0x3f, 0x76, 0x68, 0x17, 0x2b, 0x01, 0x66, - 0x5d, 0x38, 0x35, 0x6c, 0x5a, 0x69, 0x6d, 0x10, 0x4b, 0x44, 0x1e, 0x1d, - 0x67, 0x15, 0x16, 0x2e, 0x2e, 0x1c, 0x52, 0x00, 0x00, 0x02, 0x01, 0x47, - 0x02, 0x8c, 0x03, 0x8a, 0x05, 0x1e, 0x00, 0x10, 0x00, 0x1a, 0x00, 0x00, - 0x01, 0x35, 0x33, 0x11, 0x23, 0x35, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x35, - 0x34, 0x36, 0x33, 0x32, 0x16, 0x04, 0x14, 0x16, 0x33, 0x32, 0x36, 0x34, - 0x26, 0x23, 0x22, 0x03, 0x16, 0x74, 0x74, 0x1d, 0x60, 0x3f, 0x80, 0x93, - 0x93, 0x80, 0x3f, 0x61, 0xfe, 0xc7, 0x56, 0x54, 0x53, 0x58, 0x58, 0x53, - 0x54, 0x04, 0xbf, 0x4e, 0xfd, 0x8f, 0x4f, 0x2f, 0x30, 0xb0, 0x9b, 0x99, - 0xae, 0x30, 0xa1, 0xf0, 0x7a, 0x7b, 0xee, 0x7b, 0x00, 0x03, 0x00, 0xfb, - 0x02, 0x8c, 0x03, 0xd6, 0x05, 0x1e, 0x00, 0x0a, 0x00, 0x12, 0x00, 0x42, - 0x00, 0x00, 0x01, 0x15, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, - 0x06, 0x05, 0x15, 0x14, 0x16, 0x32, 0x36, 0x3d, 0x01, 0x25, 0x21, 0x34, - 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, - 0x32, 0x16, 0x17, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x2b, - 0x01, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x15, 0x0e, 0x01, 0x23, - 0x22, 0x26, 0x27, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x35, 0x02, 0x99, 0x1f, - 0x6b, 0x4b, 0x38, 0x34, 0x3a, 0x2f, 0xfe, 0xca, 0x30, 0x6e, 0x30, 0xfe, - 0xca, 0x01, 0x36, 0x01, 0x40, 0x46, 0x32, 0x51, 0x20, 0x23, 0x53, 0x2d, - 0x45, 0x5e, 0x14, 0x19, 0x54, 0x3d, 0x62, 0x67, 0x7e, 0x79, 0x49, 0x3e, - 0x3b, 0x23, 0x54, 0x27, 0x31, 0x53, 0x26, 0x39, 0x4e, 0x18, 0x14, 0x54, - 0x38, 0x6d, 0x5c, 0x04, 0x17, 0x29, 0x33, 0x3f, 0x32, 0x36, 0x4a, 0xe0, - 0x1d, 0x55, 0x4a, 0x4c, 0x58, 0x18, 0x50, 0x09, 0x13, 0x13, 0x5a, 0x51, - 0x1c, 0x1d, 0x60, 0x17, 0x18, 0x2e, 0x2b, 0x2d, 0x2c, 0x60, 0x5c, 0x60, - 0x64, 0x31, 0x43, 0x48, 0x18, 0x16, 0x5e, 0x14, 0x12, 0x23, 0x24, 0x22, - 0x25, 0x84, 0xac, 0x00, 0x00, 0x02, 0x01, 0x47, 0x02, 0x8c, 0x03, 0x8a, - 0x06, 0x03, 0x00, 0x07, 0x00, 0x18, 0x00, 0x00, 0x00, 0x34, 0x26, 0x22, - 0x06, 0x14, 0x16, 0x32, 0x03, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x15, 0x14, - 0x06, 0x23, 0x22, 0x26, 0x27, 0x15, 0x23, 0x11, 0x33, 0x03, 0x10, 0x56, - 0xa8, 0x57, 0x57, 0xa8, 0xff, 0x1c, 0x61, 0x41, 0x7f, 0x92, 0x93, 0x80, - 0x3f, 0x60, 0x1d, 0x74, 0x74, 0x03, 0x5d, 0xf0, 0x7a, 0x7b, 0xee, 0x7b, - 0x01, 0xdc, 0x2e, 0x31, 0xae, 0x99, 0x9b, 0xb0, 0x30, 0x2f, 0x4f, 0x03, - 0x67, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x47, 0x02, 0x8c, 0x03, 0x8a, - 0x06, 0x03, 0x00, 0x10, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, - 0x23, 0x35, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, - 0x16, 0x04, 0x14, 0x16, 0x33, 0x32, 0x36, 0x34, 0x26, 0x23, 0x22, 0x03, - 0x16, 0x74, 0x74, 0x1d, 0x60, 0x3f, 0x80, 0x93, 0x93, 0x80, 0x3f, 0x61, - 0xfe, 0xc7, 0x56, 0x54, 0x53, 0x58, 0x58, 0x53, 0x54, 0x04, 0xbf, 0x01, - 0x44, 0xfc, 0x99, 0x4f, 0x2f, 0x30, 0xb0, 0x9b, 0x99, 0xae, 0x30, 0xa1, - 0xf0, 0x7a, 0x7b, 0xee, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x31, - 0x02, 0x8c, 0x03, 0xa0, 0x05, 0x1e, 0x00, 0x15, 0x00, 0x1c, 0x00, 0x00, - 0x01, 0x15, 0x21, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x15, 0x0e, - 0x01, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x07, 0x2e, - 0x01, 0x23, 0x22, 0x06, 0x07, 0x03, 0xa0, 0xfe, 0x0a, 0x78, 0x6e, 0x37, - 0x79, 0x45, 0x42, 0x7b, 0x39, 0xa5, 0xb9, 0xb5, 0x98, 0x86, 0x9c, 0x74, - 0x02, 0x5c, 0x55, 0x54, 0x6d, 0x0a, 0x03, 0xef, 0x32, 0x03, 0x67, 0x70, - 0x1f, 0x20, 0x66, 0x18, 0x18, 0xaf, 0x9a, 0x96, 0xb3, 0xa2, 0x6e, 0x5a, - 0x5f, 0x62, 0x57, 0x00, 0x00, 0x02, 0x01, 0x31, 0x02, 0x8c, 0x03, 0xa0, - 0x05, 0x1e, 0x00, 0x15, 0x00, 0x1c, 0x00, 0x00, 0x01, 0x35, 0x21, 0x35, - 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x16, - 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x37, 0x1e, 0x01, 0x33, 0x32, 0x36, - 0x37, 0x01, 0x31, 0x01, 0xf6, 0x78, 0x6e, 0x37, 0x79, 0x45, 0x42, 0x7b, - 0x39, 0xa5, 0xb9, 0xb5, 0x98, 0x86, 0x9c, 0x74, 0x02, 0x5c, 0x55, 0x54, - 0x6d, 0x0a, 0x03, 0xbb, 0x32, 0x03, 0x67, 0x70, 0x1f, 0x20, 0x66, 0x18, - 0x18, 0xaf, 0x9a, 0x96, 0xb3, 0xa2, 0x6e, 0x5a, 0x5f, 0x62, 0x57, 0x00, - 0x00, 0x01, 0x01, 0x4f, 0x02, 0x90, 0x03, 0x82, 0x05, 0x1e, 0x00, 0x28, - 0x00, 0x00, 0x01, 0x2e, 0x01, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x17, - 0x15, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x3b, 0x01, 0x15, - 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x15, 0x0e, - 0x01, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x01, 0xff, 0x4b, 0x51, 0x99, - 0x84, 0x33, 0x73, 0x43, 0x42, 0x6d, 0x30, 0x57, 0x5d, 0x5b, 0x55, 0x68, - 0x64, 0x5e, 0x6a, 0x72, 0x6d, 0x3e, 0x73, 0x30, 0x3d, 0x72, 0x36, 0xa0, - 0xae, 0x5d, 0x03, 0xf0, 0x0e, 0x48, 0x35, 0x4b, 0x58, 0x0d, 0x0e, 0x5d, - 0x0f, 0x0e, 0x30, 0x2a, 0x22, 0x30, 0x51, 0x3e, 0x2d, 0x37, 0x3b, 0x14, - 0x13, 0x61, 0x10, 0x0f, 0x66, 0x5d, 0x3d, 0x53, 0x00, 0x01, 0x01, 0x4f, - 0x02, 0x90, 0x03, 0x82, 0x05, 0x1e, 0x00, 0x28, 0x00, 0x00, 0x01, 0x1e, - 0x01, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x27, 0x35, 0x1e, 0x01, 0x33, - 0x32, 0x36, 0x35, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x36, 0x35, - 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x16, - 0x15, 0x14, 0x06, 0x02, 0xd2, 0x4b, 0x51, 0x99, 0x84, 0x33, 0x73, 0x43, - 0x42, 0x6d, 0x30, 0x57, 0x5d, 0x5b, 0x55, 0x68, 0x64, 0x5e, 0x6a, 0x72, - 0x6d, 0x3e, 0x73, 0x30, 0x3d, 0x72, 0x36, 0xa0, 0xae, 0x5d, 0x03, 0xbe, - 0x0e, 0x48, 0x35, 0x4b, 0x58, 0x0d, 0x0e, 0x5d, 0x0f, 0x0e, 0x30, 0x2a, - 0x22, 0x30, 0x51, 0x3e, 0x2d, 0x37, 0x3b, 0x14, 0x13, 0x61, 0x10, 0x0f, - 0x66, 0x5d, 0x3d, 0x53, 0x00, 0x02, 0x01, 0x47, 0x01, 0xa6, 0x03, 0x8a, - 0x05, 0x1e, 0x00, 0x09, 0x00, 0x27, 0x00, 0x00, 0x00, 0x34, 0x26, 0x23, - 0x22, 0x06, 0x14, 0x16, 0x33, 0x32, 0x17, 0x14, 0x06, 0x23, 0x22, 0x26, - 0x27, 0x35, 0x1e, 0x01, 0x33, 0x32, 0x36, 0x3d, 0x02, 0x0e, 0x01, 0x23, - 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x17, 0x35, 0x33, 0x03, - 0x16, 0x55, 0x51, 0x55, 0x5a, 0x5a, 0x56, 0x50, 0xc9, 0x96, 0x91, 0x30, - 0x69, 0x34, 0x3e, 0x64, 0x2b, 0x5d, 0x56, 0x1c, 0x5f, 0x45, 0x7c, 0x93, - 0x93, 0x7c, 0x44, 0x5e, 0x1e, 0x74, 0x03, 0x67, 0xe8, 0x78, 0x78, 0xe8, - 0x7a, 0x29, 0x8d, 0x91, 0x0f, 0x0f, 0x66, 0x19, 0x19, 0x5b, 0x62, 0x05, - 0x46, 0x35, 0x33, 0xaf, 0x94, 0x93, 0xb0, 0x30, 0x32, 0x51, 0x00, 0x00, - 0x00, 0x02, 0x01, 0x49, 0x01, 0xaa, 0x03, 0x88, 0x05, 0x11, 0x00, 0x09, - 0x00, 0x0d, 0x00, 0x00, 0x01, 0x21, 0x11, 0x23, 0x35, 0x21, 0x15, 0x23, - 0x11, 0x33, 0x03, 0x23, 0x35, 0x33, 0x03, 0x57, 0xfe, 0xd8, 0xe6, 0x02, - 0x3f, 0xe6, 0xb5, 0xb5, 0x73, 0x73, 0x02, 0x9e, 0x02, 0x23, 0x50, 0x50, - 0xfe, 0x2d, 0xfe, 0xbc, 0x83, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x38, - 0x02, 0x9c, 0x03, 0x99, 0x06, 0x03, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x33, - 0x11, 0x01, 0x33, 0x05, 0x01, 0x23, 0x01, 0x07, 0x15, 0x23, 0x01, 0x38, - 0x78, 0x01, 0x30, 0x8d, 0xfe, 0xea, 0x01, 0x42, 0x8e, 0xfe, 0xfb, 0x56, - 0x78, 0x06, 0x03, 0xfe, 0x08, 0x01, 0x04, 0xec, 0xfe, 0x79, 0x01, 0x44, - 0x49, 0xfb, 0x00, 0x00, 0x00, 0x01, 0x01, 0x25, 0x02, 0x9c, 0x03, 0xac, - 0x05, 0x1e, 0x00, 0x22, 0x00, 0x00, 0x01, 0x3e, 0x01, 0x33, 0x32, 0x16, - 0x15, 0x11, 0x23, 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, - 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, 0x15, - 0x3e, 0x01, 0x33, 0x32, 0x16, 0x02, 0x8b, 0x15, 0x42, 0x2f, 0x55, 0x46, - 0x6a, 0x22, 0x2c, 0x32, 0x25, 0x6a, 0x24, 0x2f, 0x2e, 0x23, 0x6a, 0x6a, - 0x14, 0x3f, 0x27, 0x30, 0x40, 0x04, 0xcf, 0x29, 0x26, 0x75, 0xa2, 0xfe, - 0x95, 0x01, 0x67, 0x85, 0x40, 0x45, 0x80, 0xfe, 0x99, 0x01, 0x67, 0x86, - 0x3f, 0x45, 0x80, 0xfe, 0x99, 0x02, 0x73, 0x36, 0x22, 0x23, 0x27, 0x00, - 0x00, 0x01, 0x01, 0x5b, 0x01, 0xad, 0x03, 0x76, 0x05, 0x1e, 0x00, 0x1f, - 0x00, 0x00, 0x01, 0x11, 0x14, 0x07, 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, - 0x37, 0x36, 0x35, 0x11, 0x34, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x11, - 0x23, 0x11, 0x33, 0x15, 0x36, 0x37, 0x36, 0x33, 0x32, 0x16, 0x03, 0x76, - 0x38, 0x39, 0x68, 0x81, 0x75, 0x39, 0x1c, 0x1c, 0x43, 0x47, 0x52, 0x2c, - 0x2b, 0x74, 0x74, 0x1f, 0x35, 0x34, 0x49, 0x6c, 0x6a, 0x04, 0x21, 0xfe, - 0x70, 0x6d, 0x3b, 0x3c, 0x58, 0x23, 0x22, 0x47, 0x01, 0x90, 0x54, 0x50, - 0x33, 0x34, 0x60, 0xfe, 0x9e, 0x02, 0x73, 0x5e, 0x36, 0x1c, 0x1b, 0x7e, - 0x00, 0x02, 0x01, 0x3a, 0x02, 0x8c, 0x03, 0x97, 0x05, 0x1e, 0x00, 0x0b, - 0x00, 0x16, 0x00, 0x00, 0x01, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, - 0x36, 0x35, 0x34, 0x2e, 0x01, 0x20, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, - 0x26, 0x35, 0x34, 0x02, 0x68, 0x58, 0x5b, 0x5b, 0x58, 0x59, 0x5b, 0x5b, - 0xec, 0x01, 0x26, 0x9c, 0x9b, 0x94, 0x93, 0x9b, 0x04, 0xc7, 0x7a, 0x78, - 0x77, 0x7b, 0x7b, 0x77, 0x78, 0x7a, 0x57, 0xa9, 0xa0, 0xa1, 0xa8, 0xa8, - 0xa1, 0xa0, 0x00, 0x00, 0x00, 0x01, 0x01, 0x58, 0x02, 0x8c, 0x03, 0x79, - 0x05, 0x1e, 0x00, 0x17, 0x00, 0x00, 0x01, 0x3e, 0x01, 0x33, 0x32, 0x16, - 0x10, 0x06, 0x23, 0x22, 0x26, 0x27, 0x35, 0x1e, 0x01, 0x33, 0x32, 0x36, - 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x01, 0x58, 0x2e, 0x63, 0x34, 0xa4, - 0xb8, 0xb8, 0xa4, 0x33, 0x61, 0x31, 0x2e, 0x5c, 0x3b, 0x6d, 0x75, 0x76, - 0x6c, 0x3d, 0x5f, 0x29, 0x04, 0xee, 0x18, 0x18, 0xae, 0xfe, 0xca, 0xae, - 0x17, 0x19, 0x6c, 0x24, 0x21, 0x7e, 0xe8, 0x7e, 0x21, 0x23, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x3a, 0x03, 0xd5, 0x03, 0x97, 0x05, 0x1e, 0x00, 0x0c, - 0x00, 0x00, 0x01, 0x34, 0x36, 0x20, 0x16, 0x15, 0x23, 0x34, 0x26, 0x23, - 0x22, 0x06, 0x15, 0x01, 0x3a, 0x9b, 0x01, 0x26, 0x9c, 0x7b, 0x5b, 0x59, - 0x58, 0x5b, 0x03, 0xd5, 0xa0, 0xa9, 0xa9, 0xa0, 0x78, 0x7a, 0x7a, 0x78, - 0x00, 0x01, 0x01, 0x3a, 0x02, 0x8c, 0x03, 0x97, 0x03, 0xd5, 0x00, 0x0c, - 0x00, 0x00, 0x01, 0x14, 0x06, 0x20, 0x26, 0x35, 0x33, 0x14, 0x16, 0x33, - 0x32, 0x36, 0x35, 0x03, 0x97, 0x9b, 0xfe, 0xda, 0x9c, 0x7b, 0x5b, 0x59, - 0x58, 0x5b, 0x03, 0xd5, 0xa0, 0xa9, 0xa9, 0xa0, 0x78, 0x7a, 0x7a, 0x78, - 0x00, 0x02, 0x01, 0x47, 0x01, 0xad, 0x03, 0x8a, 0x05, 0x1e, 0x00, 0x10, - 0x00, 0x18, 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x33, 0x15, 0x3e, 0x01, - 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x24, 0x34, 0x26, - 0x22, 0x06, 0x14, 0x16, 0x32, 0x01, 0xbc, 0x75, 0x75, 0x1d, 0x60, 0x3f, - 0x80, 0x92, 0x92, 0x80, 0x40, 0x60, 0x01, 0x38, 0x55, 0xa8, 0x57, 0x57, - 0xa8, 0x02, 0xeb, 0xfe, 0xc2, 0x03, 0x62, 0x50, 0x2f, 0x30, 0xb0, 0x9b, - 0x99, 0xae, 0x30, 0xa1, 0xf0, 0x7a, 0x7b, 0xee, 0x7b, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x4d, 0x02, 0x9c, 0x03, 0x84, 0x05, 0xc1, 0x00, 0x13, - 0x00, 0x00, 0x01, 0x15, 0x21, 0x15, 0x21, 0x11, 0x14, 0x16, 0x3b, 0x01, - 0x15, 0x23, 0x22, 0x26, 0x35, 0x11, 0x23, 0x35, 0x33, 0x35, 0x02, 0x7d, - 0x01, 0x07, 0xfe, 0xf9, 0x3b, 0x4a, 0x82, 0x8d, 0x83, 0x6b, 0xbc, 0xbc, - 0x05, 0xc1, 0xb2, 0x50, 0xfe, 0xac, 0x46, 0x37, 0x52, 0x5d, 0x72, 0x01, - 0x54, 0x50, 0xb2, 0x00, 0x00, 0x01, 0x01, 0x5b, 0x02, 0x8c, 0x03, 0x76, - 0x05, 0x0e, 0x00, 0x13, 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, 0x14, 0x16, - 0x33, 0x32, 0x36, 0x35, 0x11, 0x33, 0x11, 0x23, 0x35, 0x0e, 0x01, 0x23, - 0x22, 0x26, 0x01, 0x5b, 0x74, 0x43, 0x47, 0x52, 0x57, 0x74, 0x74, 0x1f, - 0x6b, 0x47, 0x6c, 0x6a, 0x03, 0x89, 0x01, 0x85, 0xfe, 0x7b, 0x54, 0x50, - 0x67, 0x60, 0x01, 0x62, 0xfd, 0x8e, 0x5e, 0x36, 0x38, 0x7e, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xff, 0x02, 0x9d, 0x03, 0xd2, 0x04, 0x7d, 0x00, 0x13, - 0x00, 0x00, 0x01, 0x21, 0x35, 0x21, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, - 0x21, 0x35, 0x21, 0x15, 0x23, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x02, 0xb4, - 0xfe, 0x4b, 0x01, 0xb5, 0x60, 0x59, 0x73, 0x6c, 0xfe, 0x71, 0x02, 0xc1, - 0x6a, 0x3d, 0x3f, 0x8e, 0x02, 0x9d, 0x67, 0x3c, 0x3f, 0x49, 0x4d, 0x68, - 0x68, 0x1b, 0x5f, 0x3f, 0x61, 0x5e, 0x00, 0x00, 0x00, 0x01, 0x01, 0x25, - 0x02, 0x9c, 0x03, 0xac, 0x05, 0x1e, 0x00, 0x22, 0x00, 0x00, 0x01, 0x0e, - 0x01, 0x23, 0x22, 0x26, 0x35, 0x11, 0x33, 0x11, 0x14, 0x16, 0x33, 0x32, - 0x36, 0x35, 0x11, 0x33, 0x11, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x11, - 0x33, 0x11, 0x23, 0x35, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x02, 0x46, 0x15, - 0x42, 0x2f, 0x55, 0x46, 0x6a, 0x22, 0x2c, 0x32, 0x25, 0x6a, 0x24, 0x2f, - 0x2e, 0x23, 0x6a, 0x6a, 0x14, 0x3f, 0x27, 0x30, 0x40, 0x02, 0xeb, 0x28, - 0x27, 0x75, 0xa2, 0x01, 0x6b, 0xfe, 0x99, 0x84, 0x41, 0x45, 0x80, 0x01, - 0x67, 0xfe, 0x99, 0x86, 0x3f, 0x45, 0x80, 0x01, 0x67, 0xfd, 0x8d, 0x36, - 0x22, 0x23, 0x27, 0x00, 0x00, 0x01, 0x01, 0x23, 0x02, 0x9c, 0x03, 0xae, - 0x05, 0x0f, 0x00, 0x06, 0x00, 0x00, 0x01, 0x33, 0x1b, 0x01, 0x33, 0x03, - 0x23, 0x01, 0x23, 0x78, 0xcd, 0xce, 0x78, 0xfb, 0x95, 0x05, 0x0f, 0xfd, - 0xf2, 0x02, 0x0e, 0xfd, 0x8d, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x48, - 0x00, 0x00, 0x03, 0x88, 0x03, 0x67, 0x12, 0x07, 0x07, 0x3f, 0x00, 0x00, - 0xfd, 0x64, 0x00, 0x00, 0xff, 0xff, 0x01, 0x99, 0x00, 0x00, 0x03, 0x38, - 0x02, 0x83, 0x12, 0x07, 0x02, 0x59, 0x00, 0x00, 0xfd, 0x64, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x5b, 0xff, 0xf0, 0x03, 0x76, 0x02, 0x72, 0x12, 0x07, - 0x05, 0x3a, 0x00, 0x00, 0xfd, 0x64, 0x00, 0x00, 0xff, 0xff, 0x01, 0x23, - 0x00, 0x00, 0x03, 0xae, 0x02, 0x73, 0x12, 0x07, 0x05, 0x3d, 0x00, 0x00, - 0xfd, 0x64, 0x00, 0x00, 0x00, 0x02, 0x00, 0x7b, 0xfe, 0x48, 0x04, 0x12, - 0x04, 0x7b, 0x00, 0x0a, 0x00, 0x28, 0x00, 0x00, 0x25, 0x14, 0x16, 0x33, - 0x32, 0x36, 0x10, 0x26, 0x23, 0x22, 0x06, 0x03, 0x34, 0x12, 0x33, 0x32, - 0x16, 0x17, 0x15, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x1d, 0x02, 0x3e, 0x01, - 0x33, 0x32, 0x12, 0x11, 0x10, 0x02, 0x23, 0x22, 0x26, 0x27, 0x15, 0x23, - 0x01, 0x33, 0x87, 0x81, 0x87, 0x8e, 0x8f, 0x88, 0x7f, 0x87, 0xb8, 0xee, - 0xe7, 0x4c, 0xa6, 0x53, 0x62, 0xa0, 0x43, 0x95, 0x88, 0x2c, 0x98, 0x6d, - 0xc4, 0xea, 0xea, 0xc4, 0x6c, 0x96, 0x2f, 0xb8, 0x8a, 0xcf, 0xd7, 0xd7, - 0x01, 0x9e, 0xd9, 0xda, 0x01, 0x23, 0xfc, 0x01, 0x04, 0x1c, 0x1b, 0xb6, - 0x2e, 0x2c, 0xa2, 0xb0, 0x08, 0x7d, 0x5e, 0x5c, 0xfe, 0xc6, 0xfe, 0xf9, - 0xfe, 0xf8, 0xfe, 0xc6, 0x56, 0x5a, 0x91, 0x00, 0xff, 0xff, 0x01, 0x3a, - 0x02, 0x9c, 0x03, 0x96, 0x05, 0xe0, 0x10, 0x06, 0x05, 0x17, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x9c, 0x00, 0x00, 0x04, 0x35, 0x04, 0x60, 0x00, 0x13, - 0x00, 0x00, 0x01, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x35, 0x21, 0x11, - 0x21, 0x35, 0x21, 0x11, 0x21, 0x35, 0x21, 0x15, 0x21, 0x11, 0x04, 0x35, - 0xfe, 0x8f, 0x01, 0x6e, 0xfc, 0x6e, 0x01, 0x6c, 0xfe, 0x90, 0x01, 0x70, - 0xfe, 0x94, 0x03, 0x92, 0xfe, 0x92, 0x02, 0x68, 0xa4, 0xfe, 0xcb, 0x8f, - 0x8f, 0x01, 0x35, 0xa4, 0x01, 0x69, 0x8f, 0x8f, 0xfe, 0x97, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xa0, 0xfe, 0x56, 0x04, 0x0a, 0x06, 0x1f, 0x00, 0x1b, - 0x00, 0x00, 0x01, 0x14, 0x16, 0x3b, 0x01, 0x1d, 0x02, 0x14, 0x07, 0x06, - 0x2b, 0x01, 0x35, 0x33, 0x32, 0x37, 0x36, 0x3d, 0x01, 0x23, 0x22, 0x26, - 0x35, 0x11, 0x21, 0x35, 0x21, 0x02, 0x7f, 0x5b, 0x59, 0xd7, 0x59, 0x5a, - 0xa5, 0xcd, 0xb9, 0x5a, 0x2d, 0x2c, 0x30, 0xa5, 0xb5, 0xfe, 0xd9, 0x01, - 0xdf, 0x01, 0x96, 0x7c, 0x7e, 0x1c, 0x80, 0x14, 0xc3, 0x69, 0x6a, 0x9c, - 0x3e, 0x3e, 0x7e, 0x14, 0xd4, 0xc2, 0x03, 0xf9, 0x90, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x01, 0x47, 0x02, 0x8c, 0x03, 0x8a, 0x05, 0x1e, 0x00, 0x10, - 0x00, 0x1a, 0x00, 0x00, 0x01, 0x15, 0x23, 0x11, 0x33, 0x15, 0x3e, 0x01, - 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x24, 0x34, 0x26, - 0x23, 0x22, 0x06, 0x14, 0x16, 0x33, 0x32, 0x01, 0xbb, 0x74, 0x74, 0x1d, - 0x60, 0x3f, 0x80, 0x93, 0x93, 0x80, 0x3f, 0x61, 0x01, 0x39, 0x56, 0x54, - 0x53, 0x58, 0x58, 0x53, 0x54, 0x02, 0xeb, 0x4e, 0x02, 0x71, 0x4f, 0x2f, - 0x30, 0xb0, 0x9b, 0x99, 0xae, 0x30, 0xa1, 0xf0, 0x7a, 0x7b, 0xee, 0x7b, - 0x00, 0x01, 0x01, 0x58, 0x02, 0x8c, 0x03, 0x79, 0x05, 0x1e, 0x00, 0x18, - 0x00, 0x00, 0x01, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x10, 0x36, 0x33, 0x32, - 0x16, 0x17, 0x15, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, - 0x32, 0x36, 0x37, 0x03, 0x79, 0x2e, 0x63, 0x34, 0xa4, 0xb8, 0xb8, 0xa4, - 0x33, 0x61, 0x31, 0x2e, 0x5c, 0x3b, 0x6d, 0x75, 0x76, 0x6c, 0x3d, 0x5f, - 0x29, 0x02, 0xbc, 0x18, 0x18, 0xae, 0x01, 0x36, 0xae, 0x17, 0x19, 0x6c, - 0x24, 0x21, 0x7d, 0x75, 0x74, 0x7e, 0x21, 0x23, 0x00, 0x02, 0x01, 0x51, - 0x02, 0x49, 0x03, 0x80, 0x05, 0x1c, 0x00, 0x07, 0x00, 0x2b, 0x00, 0x00, - 0x01, 0x16, 0x33, 0x32, 0x35, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x07, - 0x34, 0x37, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, - 0x16, 0x17, 0x15, 0x2e, 0x01, 0x23, 0x22, 0x07, 0x06, 0x14, 0x17, 0x16, - 0x17, 0x36, 0x33, 0x32, 0x17, 0x14, 0x23, 0x22, 0x02, 0x64, 0x26, 0x2f, - 0x5c, 0x01, 0x52, 0x40, 0x35, 0x03, 0x61, 0x08, 0x24, 0x1e, 0x5e, 0x60, - 0x5e, 0xa5, 0x36, 0x33, 0x33, 0x30, 0x32, 0x62, 0x33, 0x71, 0x3e, 0x3e, - 0x3e, 0x04, 0x04, 0x35, 0x7c, 0xbc, 0x01, 0xd2, 0x34, 0x02, 0xec, 0x0b, - 0x20, 0x2a, 0x9a, 0x20, 0x26, 0x02, 0x3a, 0x2f, 0x14, 0x1d, 0x5a, 0x96, - 0x99, 0x58, 0x58, 0x09, 0x0b, 0x13, 0x60, 0x18, 0x18, 0x40, 0x3f, 0xe6, - 0x40, 0x04, 0x03, 0x62, 0x8a, 0x6a, 0x00, 0x00, 0x00, 0x02, 0x01, 0x3a, - 0x02, 0x8c, 0x03, 0x97, 0x06, 0x03, 0x00, 0x1a, 0x00, 0x29, 0x00, 0x00, - 0x01, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, - 0x33, 0x32, 0x16, 0x17, 0x2e, 0x01, 0x27, 0x07, 0x27, 0x37, 0x27, 0x33, - 0x17, 0x37, 0x17, 0x03, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, - 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x02, 0xa8, 0x7c, 0x73, 0x9f, 0x90, - 0x8f, 0x9f, 0x9f, 0x8d, 0x15, 0x16, 0x0a, 0x15, 0x2e, 0x18, 0xaf, 0x13, - 0x95, 0x73, 0x8a, 0x50, 0xb7, 0x14, 0x6d, 0x16, 0x34, 0x1c, 0x5c, 0x61, - 0x5e, 0x55, 0x56, 0x5e, 0x25, 0x05, 0x83, 0x77, 0xd4, 0x70, 0x96, 0xa6, - 0xa6, 0x96, 0x94, 0xa6, 0x01, 0x01, 0x19, 0x32, 0x18, 0x33, 0x37, 0x2c, - 0x70, 0x51, 0x35, 0x37, 0xfe, 0xee, 0x07, 0x08, 0x76, 0x6f, 0x6e, 0x77, - 0x77, 0x6e, 0x3d, 0x72, 0x00, 0x01, 0x01, 0x4f, 0x02, 0x90, 0x03, 0x82, - 0x05, 0x1e, 0x00, 0x28, 0x00, 0x00, 0x01, 0x1e, 0x01, 0x15, 0x14, 0x06, - 0x23, 0x22, 0x26, 0x27, 0x35, 0x1e, 0x01, 0x33, 0x32, 0x36, 0x35, 0x34, - 0x26, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, - 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x02, - 0xd1, 0x54, 0x5d, 0xae, 0xa1, 0x35, 0x73, 0x3c, 0x2f, 0x73, 0x3f, 0x6d, - 0x72, 0x6a, 0x5f, 0x63, 0x68, 0x55, 0x5b, 0x5e, 0x57, 0x2f, 0x6d, 0x42, - 0x43, 0x73, 0x32, 0x85, 0x99, 0x52, 0x03, 0xf0, 0x0d, 0x53, 0x3d, 0x5d, - 0x66, 0x0f, 0x10, 0x61, 0x13, 0x14, 0x3b, 0x37, 0x2d, 0x3e, 0x51, 0x30, - 0x22, 0x2a, 0x30, 0x0e, 0x0f, 0x5d, 0x0e, 0x0d, 0x58, 0x4b, 0x35, 0x48, - 0x00, 0x01, 0x01, 0x57, 0x02, 0x9c, 0x03, 0x7a, 0x06, 0x03, 0x00, 0x13, - 0x00, 0x00, 0x01, 0x15, 0x23, 0x22, 0x06, 0x1d, 0x01, 0x33, 0x15, 0x23, - 0x11, 0x23, 0x11, 0x23, 0x35, 0x33, 0x35, 0x34, 0x36, 0x33, 0x03, 0x7a, - 0x84, 0x3e, 0x31, 0xf3, 0xf3, 0x74, 0xbc, 0xbc, 0x6b, 0x71, 0x06, 0x03, - 0x55, 0x2e, 0x39, 0x38, 0x50, 0xfd, 0xdd, 0x02, 0x23, 0x50, 0x2c, 0x67, - 0x61, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x62, 0x01, 0xad, 0x03, 0x6f, - 0x05, 0x0f, 0x00, 0x17, 0x00, 0x00, 0x01, 0x35, 0x33, 0x11, 0x23, 0x35, - 0x21, 0x11, 0x33, 0x15, 0x23, 0x15, 0x14, 0x07, 0x06, 0x2b, 0x01, 0x35, - 0x33, 0x32, 0x37, 0x36, 0x3d, 0x01, 0x01, 0xce, 0x99, 0xc8, 0x01, 0x3c, - 0x94, 0x94, 0x39, 0x38, 0x68, 0xa0, 0x93, 0x39, 0x1c, 0x1d, 0x02, 0x9c, - 0x5c, 0x01, 0xc7, 0x50, 0xfd, 0xe9, 0x5c, 0x0b, 0x6d, 0x3b, 0x3c, 0x58, - 0x23, 0x23, 0x46, 0x0b, 0x00, 0x02, 0x01, 0x47, 0x01, 0xa6, 0x03, 0x8a, - 0x05, 0x0d, 0x00, 0x0a, 0x00, 0x24, 0x00, 0x00, 0x01, 0x30, 0x35, 0x27, - 0x22, 0x06, 0x14, 0x16, 0x33, 0x32, 0x36, 0x17, 0x14, 0x06, 0x23, 0x22, - 0x26, 0x27, 0x35, 0x1e, 0x01, 0x33, 0x32, 0x36, 0x3d, 0x02, 0x0e, 0x01, - 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x21, 0x03, 0x16, 0xa6, 0x55, - 0x5a, 0x5a, 0x56, 0x50, 0x55, 0x74, 0x96, 0x91, 0x30, 0x69, 0x34, 0x3e, - 0x64, 0x2b, 0x5d, 0x56, 0x1c, 0x5f, 0x45, 0x7c, 0x93, 0x91, 0x7e, 0x01, - 0x34, 0x03, 0xdb, 0x77, 0x75, 0x78, 0xe8, 0x7a, 0x7a, 0xa3, 0x8d, 0x91, - 0x0f, 0x0f, 0x66, 0x19, 0x19, 0x5b, 0x62, 0x05, 0x46, 0x35, 0x33, 0xaf, - 0x94, 0x7f, 0xb3, 0x00, 0x00, 0x01, 0x01, 0x5b, 0x01, 0xab, 0x03, 0x76, - 0x05, 0x0e, 0x00, 0x13, 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, 0x14, 0x16, - 0x33, 0x32, 0x36, 0x35, 0x11, 0x33, 0x11, 0x23, 0x11, 0x0e, 0x01, 0x23, - 0x22, 0x26, 0x01, 0x5b, 0x74, 0x43, 0x47, 0x52, 0x57, 0x74, 0x74, 0x1f, - 0x6b, 0x47, 0x6c, 0x6a, 0x03, 0x89, 0x01, 0x85, 0xfe, 0x7b, 0x54, 0x50, - 0x67, 0x60, 0x01, 0x62, 0xfc, 0x9d, 0x01, 0x4f, 0x36, 0x38, 0x7e, 0x00, - 0x00, 0x02, 0x01, 0x43, 0x02, 0x9c, 0x03, 0x8e, 0x06, 0x03, 0x00, 0x03, - 0x00, 0x15, 0x00, 0x00, 0x01, 0x33, 0x15, 0x23, 0x07, 0x21, 0x11, 0x33, - 0x15, 0x23, 0x15, 0x33, 0x15, 0x21, 0x35, 0x33, 0x35, 0x23, 0x35, 0x33, - 0x35, 0x23, 0x02, 0x34, 0x74, 0x74, 0xb5, 0x01, 0x29, 0xdf, 0xdf, 0xe6, - 0xfd, 0xc0, 0xe6, 0xf1, 0xf1, 0xb5, 0x06, 0x03, 0x82, 0x72, 0xfe, 0xe6, - 0x5c, 0xad, 0x50, 0x50, 0xad, 0x5c, 0xca, 0x00, 0x00, 0x01, 0x01, 0x61, - 0x02, 0x9c, 0x03, 0x70, 0x05, 0x0f, 0x00, 0x0d, 0x00, 0x00, 0x01, 0x23, - 0x22, 0x26, 0x35, 0x11, 0x23, 0x35, 0x21, 0x11, 0x06, 0x16, 0x3b, 0x01, - 0x03, 0x70, 0x81, 0x68, 0x71, 0xb5, 0x01, 0x29, 0x01, 0x39, 0x39, 0x75, - 0x02, 0x9c, 0x75, 0x6e, 0x01, 0x40, 0x50, 0xfe, 0x70, 0x46, 0x46, 0x00, - 0x00, 0x01, 0x01, 0x49, 0x02, 0x9c, 0x03, 0x88, 0x05, 0x0f, 0x00, 0x0b, - 0x00, 0x00, 0x01, 0x21, 0x15, 0x23, 0x11, 0x33, 0x15, 0x21, 0x35, 0x33, - 0x11, 0x23, 0x01, 0x49, 0x02, 0x3f, 0xe6, 0xe6, 0xfd, 0xc1, 0xe6, 0xe6, - 0x05, 0x0f, 0x50, 0xfe, 0x2d, 0x50, 0x50, 0x01, 0xd3, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x47, 0x02, 0x9c, 0x03, 0x8a, 0x05, 0x0f, 0x00, 0x13, - 0x00, 0x00, 0x01, 0x15, 0x23, 0x15, 0x33, 0x15, 0x21, 0x35, 0x33, 0x35, - 0x23, 0x35, 0x33, 0x35, 0x23, 0x35, 0x21, 0x15, 0x23, 0x15, 0x03, 0x8a, - 0xe8, 0xe6, 0xfd, 0xc1, 0xe6, 0xe8, 0xe8, 0xe6, 0x02, 0x3f, 0xe6, 0x03, - 0xf5, 0x5c, 0xad, 0x50, 0x50, 0xad, 0x5c, 0xca, 0x50, 0x50, 0xca, 0x00, - 0x00, 0x03, 0x01, 0x64, 0x01, 0xad, 0x03, 0x6d, 0x06, 0x03, 0x00, 0x03, - 0x00, 0x12, 0x00, 0x1c, 0x00, 0x00, 0x01, 0x33, 0x15, 0x23, 0x03, 0x22, - 0x35, 0x34, 0x3b, 0x01, 0x11, 0x33, 0x11, 0x33, 0x15, 0x23, 0x06, 0x07, - 0x06, 0x27, 0x30, 0x23, 0x22, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x02, - 0x87, 0x74, 0x74, 0x64, 0xbf, 0xaa, 0x79, 0x74, 0x72, 0x78, 0x0c, 0x21, - 0x33, 0x15, 0x72, 0x4a, 0x01, 0x03, 0x4d, 0x42, 0x18, 0x0b, 0x06, 0x03, - 0x82, 0xfc, 0x2c, 0x7c, 0x73, 0x02, 0x73, 0xfd, 0x8d, 0x57, 0x3f, 0x23, - 0x35, 0x98, 0x1d, 0x24, 0x1b, 0x0d, 0x00, 0x00, 0x00, 0x01, 0x01, 0x55, - 0x01, 0xad, 0x03, 0x7c, 0x06, 0x0a, 0x00, 0x0d, 0x00, 0x00, 0x01, 0x14, - 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x26, 0x35, 0x11, 0x23, 0x35, 0x21, - 0x02, 0x83, 0x39, 0x38, 0x88, 0x93, 0x64, 0x76, 0xba, 0x01, 0x2e, 0x02, - 0x91, 0x46, 0x46, 0x58, 0x74, 0x70, 0x03, 0x28, 0x51, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x55, 0x01, 0xad, 0x03, 0x7c, 0x06, 0x0a, 0x00, 0x19, - 0x00, 0x00, 0x01, 0x14, 0x16, 0x3b, 0x01, 0x15, 0x14, 0x07, 0x06, 0x2b, - 0x01, 0x35, 0x33, 0x32, 0x37, 0x36, 0x3d, 0x01, 0x23, 0x22, 0x26, 0x35, - 0x11, 0x23, 0x35, 0x21, 0x02, 0x83, 0x39, 0x38, 0x88, 0x38, 0x39, 0x68, - 0x81, 0x74, 0x39, 0x1d, 0x1b, 0x1e, 0x68, 0x72, 0xba, 0x01, 0x2e, 0x03, - 0x7f, 0x45, 0x47, 0x62, 0x6d, 0x3b, 0x3c, 0x58, 0x23, 0x22, 0x47, 0x0b, - 0x77, 0x6c, 0x02, 0x3a, 0x51, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x7e, - 0x02, 0x9c, 0x03, 0x53, 0x05, 0x1e, 0x00, 0x05, 0x00, 0x00, 0x01, 0x33, - 0x11, 0x21, 0x15, 0x21, 0x01, 0x7e, 0x80, 0x01, 0x55, 0xfe, 0x2b, 0x05, - 0x1e, 0xfd, 0xdd, 0x5f, 0x00, 0x01, 0x01, 0x25, 0x01, 0xad, 0x03, 0xab, - 0x05, 0x1e, 0x00, 0x30, 0x00, 0x00, 0x01, 0x3e, 0x01, 0x33, 0x32, 0x17, - 0x16, 0x15, 0x11, 0x15, 0x14, 0x07, 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, - 0x37, 0x36, 0x3d, 0x01, 0x31, 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, - 0x11, 0x23, 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, 0x11, - 0x33, 0x15, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x02, 0x8a, 0x16, 0x42, 0x2e, - 0x56, 0x22, 0x23, 0x32, 0x33, 0x5f, 0x75, 0x6a, 0x33, 0x1a, 0x19, 0x22, - 0x2c, 0x32, 0x25, 0x6a, 0x24, 0x2f, 0x2e, 0x24, 0x69, 0x69, 0x15, 0x3e, - 0x28, 0x30, 0x40, 0x04, 0xcf, 0x29, 0x26, 0x3a, 0x3b, 0xa2, 0xfe, 0xdd, - 0x53, 0x6d, 0x3b, 0x3c, 0x58, 0x23, 0x22, 0x47, 0x0b, 0x01, 0x67, 0x85, - 0x40, 0x45, 0x80, 0xfe, 0x99, 0x01, 0x67, 0x86, 0x3f, 0x45, 0x80, 0xfe, - 0x99, 0x02, 0x73, 0x36, 0x22, 0x23, 0x27, 0x00, 0x00, 0x01, 0x01, 0x25, - 0x01, 0xab, 0x03, 0xac, 0x05, 0x1e, 0x00, 0x22, 0x00, 0x00, 0x01, 0x0e, - 0x01, 0x23, 0x22, 0x26, 0x35, 0x11, 0x33, 0x11, 0x14, 0x16, 0x33, 0x32, - 0x36, 0x35, 0x11, 0x33, 0x11, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x11, - 0x33, 0x11, 0x23, 0x11, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x02, 0x46, 0x15, - 0x42, 0x2f, 0x55, 0x46, 0x6a, 0x22, 0x2c, 0x32, 0x25, 0x6a, 0x24, 0x2f, - 0x2e, 0x23, 0x6a, 0x6a, 0x14, 0x3f, 0x27, 0x30, 0x40, 0x02, 0xeb, 0x28, - 0x27, 0x75, 0xa2, 0x01, 0x6b, 0xfe, 0x99, 0x84, 0x41, 0x45, 0x80, 0x01, - 0x67, 0xfe, 0x99, 0x86, 0x3f, 0x45, 0x80, 0x01, 0x67, 0xfc, 0x8d, 0x01, - 0x36, 0x22, 0x23, 0x27, 0x00, 0x01, 0x01, 0x55, 0x01, 0xad, 0x03, 0x7c, - 0x05, 0x1e, 0x00, 0x1b, 0x00, 0x00, 0x01, 0x14, 0x06, 0x2b, 0x01, 0x35, - 0x33, 0x32, 0x36, 0x35, 0x11, 0x33, 0x15, 0x3e, 0x01, 0x33, 0x32, 0x16, - 0x15, 0x11, 0x23, 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x02, 0x18, - 0x4d, 0x55, 0x21, 0x17, 0x31, 0x24, 0x58, 0x1f, 0x54, 0x38, 0x5b, 0x5d, - 0x56, 0x3b, 0x3b, 0x46, 0x51, 0x02, 0x91, 0x78, 0x6c, 0x58, 0x36, 0x56, - 0x02, 0x7e, 0x61, 0x38, 0x38, 0x86, 0x81, 0xfe, 0x85, 0x01, 0x77, 0x59, - 0x59, 0x6b, 0x5c, 0x00, 0x00, 0x01, 0x01, 0x55, 0x01, 0xad, 0x03, 0x7c, - 0x05, 0x1e, 0x00, 0x24, 0x00, 0x00, 0x01, 0x35, 0x11, 0x34, 0x27, 0x26, - 0x23, 0x22, 0x07, 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, 0x15, 0x36, 0x37, - 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x11, 0x1d, 0x01, 0x14, 0x16, 0x3b, - 0x01, 0x15, 0x23, 0x22, 0x27, 0x26, 0x35, 0x02, 0xb9, 0x1d, 0x1e, 0x3a, - 0x47, 0x28, 0x29, 0x57, 0x57, 0x1f, 0x2a, 0x2b, 0x37, 0x5b, 0x2f, 0x2f, - 0x24, 0x31, 0x17, 0x21, 0x55, 0x26, 0x27, 0x02, 0x9c, 0x48, 0x01, 0x2f, - 0x59, 0x2c, 0x2d, 0x35, 0x36, 0x5c, 0xfe, 0x9e, 0x02, 0x73, 0x61, 0x38, - 0x1c, 0x1c, 0x42, 0x44, 0x81, 0xfe, 0xcd, 0x48, 0x0b, 0x56, 0x36, 0x58, - 0x36, 0x36, 0x78, 0x00, 0x00, 0x01, 0x01, 0x3f, 0x02, 0x9c, 0x03, 0x92, - 0x05, 0x1e, 0x00, 0x09, 0x00, 0x00, 0x01, 0x33, 0x01, 0x11, 0x33, 0x11, - 0x23, 0x01, 0x11, 0x23, 0x01, 0x3f, 0xab, 0x01, 0x2d, 0x7b, 0xab, 0xfe, - 0xd3, 0x7b, 0x05, 0x1e, 0xfe, 0x07, 0x01, 0xf9, 0xfd, 0x7e, 0x01, 0xfa, - 0xfe, 0x06, 0x00, 0x00, 0x00, 0x03, 0x01, 0x3a, 0x02, 0x8c, 0x03, 0x97, - 0x05, 0x1e, 0x00, 0x0e, 0x00, 0x17, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x17, 0x22, 0x07, 0x06, 0x07, 0x21, 0x26, 0x27, 0x26, 0x13, 0x21, - 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x01, 0xd5, 0x01, 0x26, 0x4e, - 0x4e, 0x4e, 0x4d, 0x94, 0x93, 0x4d, 0x4e, 0x4e, 0xe0, 0x58, 0x2d, 0x28, - 0x05, 0x01, 0x65, 0x05, 0x28, 0x2d, 0x57, 0xfe, 0xa1, 0x09, 0x21, 0x2d, - 0x58, 0x59, 0x2d, 0x21, 0x05, 0x1e, 0x54, 0x55, 0xa0, 0xa1, 0x54, 0x54, - 0x54, 0x54, 0xa1, 0xa0, 0x55, 0x03, 0x3d, 0x35, 0x63, 0x63, 0x35, 0x3d, - 0xfe, 0xcf, 0x4a, 0x2c, 0x3d, 0x3d, 0x2c, 0x00, 0x00, 0x03, 0x01, 0x3a, - 0x01, 0xae, 0x03, 0x97, 0x06, 0x03, 0x00, 0x1d, 0x00, 0x26, 0x00, 0x2f, - 0x00, 0x00, 0x01, 0x23, 0x35, 0x21, 0x15, 0x23, 0x15, 0x16, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x06, 0x07, 0x15, 0x33, 0x15, 0x21, 0x35, 0x33, 0x35, - 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x17, 0x11, 0x36, 0x37, - 0x36, 0x35, 0x34, 0x27, 0x26, 0x03, 0x11, 0x06, 0x07, 0x06, 0x15, 0x14, - 0x17, 0x16, 0x02, 0x33, 0x97, 0x01, 0xa2, 0x97, 0x66, 0x3c, 0x4e, 0x4e, - 0x3c, 0x66, 0x97, 0xfe, 0x5e, 0x97, 0x6c, 0x3f, 0x4e, 0x4e, 0x3f, 0x6c, - 0x74, 0x2c, 0x1b, 0x2e, 0x2e, 0x1b, 0xa0, 0x32, 0x1e, 0x2e, 0x2e, 0x1e, - 0x05, 0xa7, 0x5c, 0x5c, 0x8d, 0x0f, 0x41, 0x55, 0xa0, 0xa1, 0x54, 0x41, - 0x0f, 0x86, 0x5c, 0x5c, 0x85, 0x0d, 0x44, 0x54, 0xa1, 0xa0, 0x55, 0x44, - 0x0d, 0x5d, 0xfe, 0x2f, 0x0e, 0x25, 0x3e, 0x77, 0x78, 0x3d, 0x25, 0xfe, - 0x3b, 0x01, 0xd6, 0x0d, 0x29, 0x3d, 0x78, 0x77, 0x3e, 0x29, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x5b, 0x01, 0xad, 0x03, 0x76, 0x05, 0x1e, 0x00, 0x3c, - 0x00, 0x00, 0x01, 0x15, 0x2e, 0x01, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, - 0x17, 0x16, 0x1f, 0x01, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, - 0x22, 0x2f, 0x01, 0x15, 0x14, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, - 0x26, 0x3d, 0x03, 0x16, 0x17, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x27, - 0x26, 0x2f, 0x01, 0x2e, 0x01, 0x35, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, - 0x16, 0x03, 0x50, 0x31, 0x6a, 0x38, 0x57, 0x2a, 0x2c, 0x1f, 0x1f, 0x5d, - 0x28, 0x7b, 0x34, 0x34, 0x4d, 0x4e, 0x89, 0x38, 0x3e, 0x0d, 0x30, 0x42, - 0x93, 0xa0, 0x72, 0x33, 0x34, 0x40, 0x3e, 0x3f, 0x3d, 0x52, 0x58, 0x1f, - 0x21, 0x6b, 0x29, 0x6b, 0x60, 0x46, 0x47, 0x82, 0x40, 0x39, 0x38, 0x04, - 0xfd, 0x62, 0x17, 0x16, 0x17, 0x18, 0x2f, 0x24, 0x15, 0x14, 0x12, 0x08, - 0x18, 0x2b, 0x2a, 0x4d, 0x57, 0x33, 0x33, 0x09, 0x03, 0x07, 0x56, 0x36, - 0x58, 0x36, 0x36, 0x78, 0x22, 0x31, 0x39, 0x1d, 0x0f, 0x0f, 0x32, 0x2d, - 0x2a, 0x17, 0x16, 0x15, 0x08, 0x14, 0x54, 0x49, 0x58, 0x30, 0x30, 0x08, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x78, 0x01, 0xad, 0x03, 0x59, - 0x06, 0x03, 0x00, 0x14, 0x00, 0x00, 0x01, 0x02, 0x03, 0x34, 0x36, 0x3b, - 0x01, 0x15, 0x23, 0x22, 0x06, 0x15, 0x13, 0x14, 0x06, 0x2b, 0x01, 0x35, - 0x33, 0x32, 0x36, 0x02, 0x09, 0x01, 0x01, 0x6a, 0x7b, 0x6d, 0x6f, 0x3e, - 0x31, 0x02, 0x67, 0x72, 0x2c, 0x1f, 0x42, 0x30, 0x02, 0x91, 0x01, 0x5d, - 0x01, 0x4d, 0x65, 0x63, 0x55, 0x2d, 0x3a, 0xfd, 0x4a, 0x78, 0x6c, 0x58, - 0x36, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x4d, 0x01, 0xad, 0x03, 0x84, - 0x05, 0xc1, 0x00, 0x21, 0x00, 0x00, 0x01, 0x15, 0x21, 0x15, 0x21, 0x11, - 0x14, 0x17, 0x16, 0x3b, 0x01, 0x15, 0x14, 0x07, 0x06, 0x2b, 0x01, 0x35, - 0x33, 0x32, 0x37, 0x36, 0x3d, 0x01, 0x23, 0x22, 0x27, 0x26, 0x35, 0x11, - 0x23, 0x35, 0x33, 0x35, 0x02, 0x7d, 0x01, 0x07, 0xfe, 0xf9, 0x1e, 0x1d, - 0x4a, 0x82, 0x38, 0x38, 0x68, 0x82, 0x75, 0x39, 0x1c, 0x1c, 0x19, 0x83, - 0x35, 0x36, 0xbc, 0xbc, 0x05, 0xc1, 0xb2, 0x50, 0xfe, 0xac, 0x46, 0x1b, - 0x1c, 0x5d, 0x6d, 0x3b, 0x3c, 0x58, 0x23, 0x22, 0x47, 0x0b, 0x2e, 0x2f, - 0x72, 0x01, 0x54, 0x50, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xd0, - 0x02, 0x8c, 0x04, 0x01, 0x05, 0x0f, 0x00, 0x17, 0x00, 0x21, 0x00, 0x00, - 0x13, 0x35, 0x33, 0x11, 0x33, 0x11, 0x21, 0x11, 0x33, 0x11, 0x33, 0x15, - 0x23, 0x15, 0x23, 0x35, 0x06, 0x07, 0x06, 0x23, 0x22, 0x26, 0x3d, 0x01, - 0x29, 0x01, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0xd0, 0x6d, - 0x74, 0x01, 0x67, 0x74, 0x75, 0x75, 0x74, 0x2a, 0x38, 0x37, 0x4a, 0x7a, - 0x7e, 0x01, 0xdb, 0xfe, 0x99, 0x27, 0x27, 0x4e, 0x5e, 0x37, 0x31, 0x03, - 0x99, 0x5c, 0x01, 0x1a, 0xfe, 0xe6, 0x01, 0x1a, 0xfe, 0xe6, 0x5c, 0xfd, - 0x60, 0x39, 0x1c, 0x1b, 0x86, 0x82, 0x05, 0x02, 0x59, 0x2c, 0x2d, 0x36, - 0x2f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x20, 0x02, 0x8b, 0x03, 0xb1, - 0x05, 0x0f, 0x00, 0x1d, 0x00, 0x00, 0x01, 0x35, 0x21, 0x15, 0x0e, 0x01, - 0x15, 0x14, 0x16, 0x32, 0x36, 0x35, 0x34, 0x26, 0x27, 0x35, 0x21, 0x15, - 0x23, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x20, 0x26, 0x35, 0x34, 0x36, 0x37, - 0x01, 0x20, 0x01, 0x16, 0x44, 0x52, 0x6f, 0xb6, 0x6f, 0x57, 0x3f, 0x01, - 0x13, 0x95, 0x48, 0x45, 0xb2, 0xfe, 0xe4, 0xb3, 0x42, 0x4b, 0x04, 0xb3, - 0x5c, 0x7b, 0x27, 0x79, 0x4b, 0x59, 0x6d, 0x6d, 0x59, 0x52, 0x76, 0x23, - 0x7b, 0x5c, 0x38, 0x7d, 0x4c, 0x83, 0xa4, 0xa3, 0x80, 0x52, 0x79, 0x3a, - 0x00, 0x01, 0x01, 0x46, 0x02, 0x9c, 0x03, 0x8b, 0x05, 0x0f, 0x00, 0x1a, - 0x00, 0x00, 0x01, 0x33, 0x31, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x2b, 0x01, - 0x22, 0x26, 0x35, 0x11, 0x33, 0x11, 0x14, 0x16, 0x3f, 0x01, 0x32, 0x36, - 0x35, 0x34, 0x26, 0x27, 0x26, 0x02, 0x33, 0xcb, 0x48, 0x45, 0xb3, 0x8d, - 0x2d, 0x72, 0x66, 0x74, 0x31, 0x41, 0x20, 0x5b, 0x6e, 0x5b, 0x3a, 0x30, - 0x04, 0xc4, 0x38, 0x7d, 0x4c, 0x83, 0xa4, 0x6c, 0x77, 0x01, 0x90, 0xfe, - 0x70, 0x55, 0x38, 0x01, 0x01, 0x6d, 0x59, 0x51, 0x7b, 0x1f, 0x18, 0x00, - 0x00, 0x01, 0x01, 0x11, 0x02, 0x9c, 0x03, 0xc0, 0x05, 0x0f, 0x00, 0x06, - 0x00, 0x00, 0x01, 0x23, 0x0b, 0x01, 0x23, 0x01, 0x33, 0x03, 0xc0, 0x7b, - 0xdd, 0xdc, 0x7b, 0x01, 0x09, 0x9d, 0x02, 0x9c, 0x02, 0x0e, 0xfd, 0xf2, - 0x02, 0x73, 0x00, 0x00, 0x00, 0x01, 0x01, 0x61, 0x02, 0x9c, 0x03, 0x70, - 0x05, 0x10, 0x00, 0x09, 0x00, 0x00, 0x01, 0x21, 0x15, 0x01, 0x21, 0x15, - 0x21, 0x35, 0x01, 0x21, 0x01, 0x70, 0x02, 0x00, 0xfe, 0x6b, 0x01, 0x95, - 0xfd, 0xf1, 0x01, 0x95, 0xfe, 0x7a, 0x05, 0x10, 0x5e, 0xfe, 0x3e, 0x54, - 0x5f, 0x01, 0xc3, 0x00, 0x00, 0x01, 0x01, 0x5e, 0x01, 0xad, 0x03, 0x73, - 0x05, 0x0f, 0x00, 0x16, 0x00, 0x00, 0x01, 0x21, 0x15, 0x01, 0x21, 0x15, - 0x23, 0x15, 0x14, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, 0x26, 0x3d, - 0x01, 0x21, 0x35, 0x01, 0x21, 0x01, 0x6a, 0x01, 0x9d, 0xfe, 0xb9, 0x01, - 0x47, 0x01, 0x24, 0x32, 0x17, 0x21, 0x56, 0x26, 0x27, 0xfe, 0xaf, 0x01, - 0x47, 0xfe, 0xc5, 0x05, 0x0f, 0x5e, 0xfe, 0x3d, 0x52, 0x0b, 0x56, 0x36, - 0x58, 0x36, 0x36, 0x78, 0x0b, 0x5e, 0x01, 0xc3, 0x00, 0x02, 0x01, 0x4d, - 0x02, 0x5e, 0x03, 0x84, 0x05, 0x0f, 0x00, 0x14, 0x00, 0x1c, 0x00, 0x00, - 0x01, 0x06, 0x15, 0x23, 0x34, 0x37, 0x23, 0x35, 0x01, 0x21, 0x35, 0x21, - 0x15, 0x01, 0x33, 0x36, 0x33, 0x32, 0x15, 0x16, 0x23, 0x27, 0x30, 0x33, - 0x32, 0x35, 0x34, 0x23, 0x06, 0x02, 0x92, 0x02, 0x61, 0x03, 0xe5, 0x01, - 0xb4, 0xfe, 0x5c, 0x02, 0x27, 0xfe, 0x4c, 0x6e, 0x26, 0x8a, 0x8f, 0x01, - 0xd2, 0x0d, 0x0d, 0x6d, 0x2c, 0x38, 0x02, 0x9c, 0x1d, 0x21, 0x21, 0x1d, - 0x5e, 0x01, 0xc3, 0x52, 0x5e, 0xfe, 0x3d, 0xa2, 0x8a, 0x6a, 0x52, 0x1f, - 0x33, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x33, 0x01, 0xa8, 0x03, 0x9e, - 0x05, 0x0f, 0x00, 0x1c, 0x00, 0x00, 0x01, 0x32, 0x17, 0x1e, 0x01, 0x15, - 0x14, 0x06, 0x23, 0x22, 0x26, 0x27, 0x35, 0x1e, 0x01, 0x33, 0x32, 0x36, - 0x35, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x01, 0x21, 0x35, 0x21, 0x15, 0x02, - 0x64, 0x43, 0x50, 0x3e, 0x69, 0xbf, 0xb1, 0x3b, 0x7d, 0x43, 0x35, 0x7e, - 0x44, 0x78, 0x7e, 0x75, 0x68, 0x6e, 0x01, 0x0f, 0xfe, 0x5c, 0x02, 0x27, - 0x03, 0xa7, 0x20, 0x17, 0x78, 0x4d, 0x7c, 0x87, 0x15, 0x14, 0x6d, 0x1b, - 0x1c, 0x54, 0x50, 0x4a, 0x53, 0x5d, 0x01, 0x18, 0x52, 0x5e, 0x00, 0x00, - 0x00, 0x03, 0x01, 0x3a, 0x02, 0x8c, 0x03, 0x97, 0x05, 0xe4, 0x00, 0x06, - 0x00, 0x0d, 0x00, 0x18, 0x00, 0x00, 0x01, 0x2e, 0x01, 0x23, 0x22, 0x06, - 0x07, 0x05, 0x21, 0x1e, 0x01, 0x33, 0x32, 0x36, 0x00, 0x20, 0x16, 0x15, - 0x14, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x03, 0x1a, 0x04, 0x55, 0x59, - 0x58, 0x55, 0x04, 0x01, 0x63, 0xfe, 0x9d, 0x03, 0x56, 0x58, 0x59, 0x56, - 0xfe, 0xbe, 0x01, 0x26, 0x9c, 0x9b, 0x94, 0x93, 0x9b, 0x04, 0x6c, 0x7e, - 0xa2, 0xa2, 0x7e, 0x67, 0x7e, 0xa3, 0xa3, 0x02, 0x5d, 0xdc, 0xd0, 0xd1, - 0xdb, 0xdb, 0xd1, 0xd0, 0xff, 0xff, 0x00, 0x25, 0xfe, 0x0a, 0x04, 0xac, - 0x05, 0xd5, 0x10, 0x26, 0x02, 0xad, 0x00, 0x00, 0x10, 0x06, 0x00, 0x24, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x85, 0xfe, 0x0a, 0x04, 0x23, - 0x04, 0x7b, 0x10, 0x26, 0x02, 0xad, 0x00, 0x00, 0x10, 0x06, 0x00, 0x44, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa6, 0x00, 0x00, 0x04, 0x71, - 0x07, 0x50, 0x10, 0x26, 0x0c, 0xc7, 0x00, 0x00, 0x10, 0x06, 0x00, 0x25, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc1, 0xff, 0xe3, 0x04, 0x58, - 0x06, 0x14, 0x10, 0x26, 0x02, 0x8f, 0x32, 0x00, 0x10, 0x06, 0x00, 0x45, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa6, 0xfe, 0x63, 0x04, 0x71, - 0x05, 0xd5, 0x10, 0x26, 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x25, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc1, 0xfe, 0x63, 0x04, 0x58, - 0x06, 0x14, 0x10, 0x26, 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x45, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa6, 0xfe, 0x9b, 0x04, 0x71, - 0x05, 0xd5, 0x10, 0x26, 0x02, 0xb9, 0x00, 0x00, 0x10, 0x06, 0x00, 0x25, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc1, 0xfe, 0x9b, 0x04, 0x58, - 0x06, 0x14, 0x10, 0x26, 0x02, 0xb9, 0x00, 0x00, 0x10, 0x06, 0x00, 0x45, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8b, 0xfe, 0x75, 0x04, 0x31, - 0x07, 0x6b, 0x10, 0x27, 0x0c, 0xbf, 0x00, 0x5a, 0x01, 0x75, 0x10, 0x26, - 0x02, 0xaf, 0x64, 0x00, 0x10, 0x06, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x75, 0x04, 0x25, 0x06, 0x66, 0x10, 0x26, - 0x00, 0x76, 0x5a, 0x00, 0x10, 0x26, 0x02, 0xaf, 0x68, 0x00, 0x10, 0x06, - 0x00, 0x46, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0x00, 0x00, 0x04, 0x52, - 0x07, 0x50, 0x10, 0x26, 0x0c, 0xc7, 0xce, 0x00, 0x10, 0x06, 0x00, 0x27, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, 0xff, 0xe3, 0x04, 0x12, - 0x06, 0x14, 0x10, 0x26, 0x02, 0x8f, 0xce, 0x00, 0x10, 0x06, 0x00, 0x47, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0xfe, 0x63, 0x04, 0x52, - 0x05, 0xd5, 0x10, 0x26, 0x02, 0xab, 0xce, 0x00, 0x10, 0x06, 0x00, 0x27, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, 0xfe, 0x63, 0x04, 0x12, - 0x06, 0x14, 0x10, 0x26, 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x47, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0xfe, 0x9b, 0x04, 0x52, - 0x05, 0xd5, 0x10, 0x26, 0x02, 0xb9, 0xce, 0x00, 0x10, 0x06, 0x00, 0x27, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, 0xfe, 0x9b, 0x04, 0x12, - 0x06, 0x14, 0x10, 0x26, 0x02, 0xb9, 0x00, 0x00, 0x10, 0x06, 0x00, 0x47, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7d, 0xfe, 0x75, 0x04, 0x52, - 0x05, 0xd5, 0x10, 0x27, 0x02, 0xaf, 0xfe, 0xf2, 0x00, 0x00, 0x12, 0x06, - 0x00, 0x27, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, 0xfe, 0x75, 0x04, 0x12, - 0x06, 0x14, 0x10, 0x26, 0x02, 0xaf, 0xec, 0x00, 0x12, 0x06, 0x00, 0x47, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0xfe, 0x1b, 0x04, 0x52, - 0x05, 0xd5, 0x10, 0x26, 0x02, 0xb5, 0xce, 0x00, 0x10, 0x06, 0x00, 0x27, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, 0xfe, 0x1b, 0x04, 0x12, - 0x06, 0x14, 0x10, 0x26, 0x02, 0xb5, 0x00, 0x00, 0x10, 0x06, 0x00, 0x47, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc5, 0xfe, 0x1b, 0x04, 0x4e, - 0x05, 0xd5, 0x10, 0x26, 0x02, 0xb5, 0x12, 0x00, 0x10, 0x06, 0x00, 0x28, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, 0xfe, 0x1b, 0x04, 0x58, - 0x04, 0x7b, 0x10, 0x26, 0x02, 0xb5, 0x0e, 0x00, 0x10, 0x06, 0x00, 0x48, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc5, 0xfe, 0x1b, 0x04, 0x4e, - 0x05, 0xd5, 0x10, 0x26, 0x02, 0xb8, 0x12, 0x00, 0x10, 0x06, 0x00, 0x28, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, 0xfe, 0x1b, 0x04, 0x58, - 0x04, 0x7b, 0x10, 0x26, 0x02, 0xb8, 0x0e, 0x00, 0x10, 0x06, 0x00, 0x48, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc5, 0xfe, 0x75, 0x04, 0x4e, - 0x07, 0x6d, 0x10, 0x26, 0x0c, 0xc6, 0x12, 0x00, 0x10, 0x26, 0x00, 0x28, - 0x00, 0x00, 0x10, 0x06, 0x02, 0xaf, 0x32, 0x00, 0xff, 0xff, 0x00, 0x7b, - 0xfe, 0x75, 0x04, 0x58, 0x06, 0x48, 0x10, 0x26, 0x02, 0x8e, 0x0e, 0x00, - 0x10, 0x26, 0x00, 0x48, 0x00, 0x00, 0x10, 0x06, 0x02, 0xaf, 0x32, 0x00, - 0xff, 0xff, 0x00, 0xe9, 0x00, 0x00, 0x04, 0x58, 0x07, 0x50, 0x10, 0x26, - 0x0c, 0xc7, 0x36, 0x00, 0x10, 0x06, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0x00, 0x00, 0x04, 0x27, 0x07, 0x50, 0x10, 0x26, - 0x0c, 0xc7, 0x00, 0x00, 0x10, 0x06, 0x00, 0x49, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x66, 0xff, 0xe3, 0x04, 0x50, 0x07, 0x30, 0x10, 0x26, - 0x0c, 0xcb, 0x32, 0x00, 0x10, 0x06, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x7b, 0xfe, 0x48, 0x04, 0x12, 0x05, 0xf6, 0x10, 0x26, - 0x02, 0x8c, 0x00, 0x00, 0x10, 0x06, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x89, 0x00, 0x00, 0x04, 0x48, 0x07, 0x50, 0x10, 0x26, - 0x0c, 0xc7, 0x00, 0x00, 0x10, 0x06, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0x00, 0x00, 0x04, 0x1b, 0x07, 0x50, 0x10, 0x26, - 0x0c, 0xc7, 0x00, 0x00, 0x10, 0x06, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x89, 0xfe, 0x63, 0x04, 0x48, 0x05, 0xd5, 0x10, 0x26, - 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x63, 0x04, 0x1b, 0x06, 0x14, 0x10, 0x26, - 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x89, 0x00, 0x00, 0x04, 0x48, 0x07, 0x35, 0x10, 0x27, - 0x0c, 0xbe, 0x00, 0x00, 0x01, 0x5c, 0x12, 0x06, 0x00, 0x2b, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0x00, 0x00, 0x04, 0x1b, 0x07, 0x58, 0x10, 0x27, - 0x00, 0x6a, 0x00, 0x07, 0x01, 0x48, 0x12, 0x06, 0x00, 0x4b, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x14, 0xfe, 0x75, 0x04, 0x48, 0x05, 0xd5, 0x10, 0x27, - 0x02, 0xaf, 0xfe, 0x89, 0x00, 0x00, 0x10, 0x06, 0x00, 0x2b, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x37, 0xfe, 0x75, 0x04, 0x1b, 0x06, 0x14, 0x10, 0x27, - 0x02, 0xaf, 0xfe, 0xac, 0x00, 0x00, 0x10, 0x06, 0x00, 0x4b, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x89, 0xfe, 0x19, 0x04, 0x48, 0x05, 0xd5, 0x10, 0x26, - 0x02, 0xb6, 0x00, 0x00, 0x10, 0x06, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x19, 0x04, 0x1b, 0x06, 0x14, 0x10, 0x26, - 0x02, 0xb6, 0x00, 0x00, 0x10, 0x06, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc9, 0xfe, 0x1b, 0x04, 0x06, 0x05, 0xd5, 0x10, 0x26, - 0x02, 0xb8, 0x00, 0x00, 0x10, 0x06, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xb2, 0xfe, 0x1b, 0x04, 0x44, 0x06, 0x14, 0x10, 0x26, - 0x02, 0xb8, 0x00, 0x00, 0x10, 0x06, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x89, 0x00, 0x00, 0x04, 0xc9, 0x07, 0x6b, 0x10, 0x27, - 0x0c, 0xbf, 0x00, 0x00, 0x01, 0x75, 0x10, 0x06, 0x00, 0x2e, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xec, 0x00, 0x00, 0x04, 0xb2, 0x07, 0x6b, 0x10, 0x27, - 0x0c, 0xbf, 0xff, 0x25, 0x01, 0x75, 0x10, 0x06, 0x00, 0x4e, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x89, 0xfe, 0x63, 0x04, 0xc9, 0x05, 0xd5, 0x10, 0x26, - 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xec, 0xfe, 0x63, 0x04, 0xb2, 0x06, 0x14, 0x10, 0x26, - 0x02, 0xab, 0x32, 0x00, 0x10, 0x06, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x89, 0xfe, 0x9b, 0x04, 0xc9, 0x05, 0xd5, 0x10, 0x26, - 0x02, 0xb9, 0x00, 0x00, 0x10, 0x06, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xec, 0xfe, 0x9b, 0x04, 0xb2, 0x06, 0x14, 0x10, 0x26, - 0x02, 0xb9, 0x32, 0x00, 0x10, 0x06, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xd7, 0xfe, 0x63, 0x04, 0x73, 0x05, 0xd5, 0x10, 0x26, - 0x02, 0xab, 0x32, 0x00, 0x10, 0x06, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xa0, 0xfe, 0x63, 0x04, 0x0a, 0x06, 0x1f, 0x10, 0x26, - 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xd7, 0xfe, 0x63, 0x04, 0x73, 0x07, 0x30, 0x10, 0x26, - 0x0c, 0xcb, 0x00, 0x00, 0x10, 0x06, 0x05, 0x9a, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xa0, 0xfe, 0x63, 0x04, 0x0a, 0x07, 0x30, 0x10, 0x26, - 0x0c, 0xcb, 0x00, 0x00, 0x10, 0x06, 0x05, 0x9b, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xd7, 0xfe, 0x9b, 0x04, 0x73, 0x05, 0xd5, 0x10, 0x26, - 0x02, 0xb9, 0x32, 0x00, 0x10, 0x06, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xa0, 0xfe, 0x9b, 0x04, 0x0a, 0x06, 0x1f, 0x10, 0x26, - 0x02, 0xb9, 0x00, 0x00, 0x10, 0x06, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xd7, 0xfe, 0x1b, 0x04, 0x73, 0x05, 0xd5, 0x10, 0x26, - 0x02, 0xb5, 0x32, 0x00, 0x10, 0x06, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xa0, 0xfe, 0x1b, 0x04, 0x0a, 0x06, 0x1f, 0x10, 0x26, - 0x02, 0xb5, 0x00, 0x00, 0x10, 0x06, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x56, 0x00, 0x00, 0x04, 0x79, 0x07, 0x6b, 0x10, 0x27, - 0x0c, 0xbf, 0x00, 0x00, 0x01, 0x75, 0x10, 0x06, 0x00, 0x30, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x6d, 0x00, 0x00, 0x04, 0x6f, 0x06, 0x66, 0x10, 0x26, - 0x00, 0x76, 0x00, 0x00, 0x10, 0x06, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x56, 0x00, 0x00, 0x04, 0x79, 0x07, 0x50, 0x10, 0x26, - 0x0c, 0xc7, 0x00, 0x00, 0x10, 0x06, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x6d, 0x00, 0x00, 0x04, 0x6f, 0x06, 0x10, 0x10, 0x26, - 0x02, 0x8f, 0x00, 0x00, 0x12, 0x06, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x56, 0xfe, 0x63, 0x04, 0x79, 0x05, 0xd5, 0x10, 0x26, - 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x6d, 0xfe, 0x63, 0x04, 0x6f, 0x04, 0x7b, 0x10, 0x26, - 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x8b, 0x00, 0x00, 0x04, 0x46, 0x07, 0x50, 0x10, 0x26, - 0x0c, 0xc7, 0x00, 0x00, 0x10, 0x06, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0x00, 0x00, 0x04, 0x1b, 0x06, 0x10, 0x10, 0x26, - 0x02, 0x8f, 0x00, 0x00, 0x10, 0x06, 0x00, 0x51, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x8b, 0xfe, 0x63, 0x04, 0x46, 0x05, 0xd5, 0x10, 0x26, - 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x63, 0x04, 0x1b, 0x04, 0x7b, 0x10, 0x26, - 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x51, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x8b, 0xfe, 0x9b, 0x04, 0x46, 0x05, 0xd5, 0x10, 0x26, - 0x02, 0xb9, 0x00, 0x00, 0x10, 0x06, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x9b, 0x04, 0x1b, 0x04, 0x7b, 0x10, 0x26, - 0x02, 0xb9, 0x00, 0x00, 0x10, 0x06, 0x00, 0x51, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x8b, 0xfe, 0x1b, 0x04, 0x46, 0x05, 0xd5, 0x10, 0x26, - 0x02, 0xb5, 0x00, 0x00, 0x10, 0x06, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x1b, 0x04, 0x1b, 0x04, 0x7b, 0x10, 0x26, - 0x02, 0xb5, 0x00, 0x00, 0x10, 0x06, 0x00, 0x51, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x75, 0xff, 0xe3, 0x04, 0x5c, 0x07, 0xf9, 0x10, 0x26, - 0x00, 0x32, 0x00, 0x00, 0x10, 0x27, 0x0c, 0xc0, 0x00, 0x00, 0x01, 0x06, - 0x10, 0x07, 0x0c, 0xbf, 0x00, 0x32, 0x02, 0x03, 0xff, 0xff, 0x00, 0x89, - 0xff, 0xe3, 0x04, 0x48, 0x07, 0xfa, 0x10, 0x27, 0x02, 0x89, 0x00, 0x00, - 0x01, 0x94, 0x10, 0x26, 0x00, 0x52, 0x00, 0x00, 0x10, 0x06, 0x02, 0x79, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc5, 0x00, 0x00, 0x04, 0x75, - 0x07, 0x72, 0x10, 0x27, 0x0c, 0xbf, 0xff, 0x77, 0x01, 0x7c, 0x12, 0x06, - 0x00, 0x33, 0x00, 0x00, 0xff, 0xff, 0x00, 0xbe, 0xfe, 0x56, 0x04, 0x54, - 0x06, 0x66, 0x10, 0x26, 0x02, 0x89, 0x00, 0x00, 0x12, 0x06, 0x00, 0x53, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc5, 0x00, 0x00, 0x04, 0x75, - 0x07, 0x50, 0x10, 0x26, 0x0c, 0xc7, 0x00, 0x00, 0x10, 0x06, 0x00, 0x33, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xbe, 0xfe, 0x56, 0x04, 0x54, - 0x06, 0x10, 0x10, 0x26, 0x02, 0x8f, 0x00, 0x00, 0x12, 0x06, 0x00, 0x53, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8f, 0x00, 0x00, 0x04, 0xd1, - 0x07, 0x50, 0x10, 0x26, 0x0c, 0xc7, 0xce, 0x00, 0x10, 0x06, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x6a, 0x00, 0x00, 0x04, 0x83, - 0x06, 0x10, 0x10, 0x26, 0x02, 0x8f, 0x00, 0x00, 0x10, 0x06, 0x00, 0x55, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8f, 0xfe, 0x63, 0x04, 0xd1, - 0x05, 0xd5, 0x10, 0x26, 0x02, 0xab, 0xce, 0x00, 0x10, 0x06, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x6a, 0xfe, 0x63, 0x04, 0x83, - 0x04, 0x7b, 0x10, 0x26, 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x55, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8f, 0xfe, 0x63, 0x04, 0xd1, - 0x07, 0x30, 0x10, 0x26, 0x0c, 0xcb, 0xce, 0x00, 0x10, 0x06, 0x05, 0xb8, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x3d, 0xfe, 0x63, 0x04, 0x83, - 0x05, 0xf6, 0x10, 0x26, 0x02, 0x8c, 0x00, 0x00, 0x10, 0x06, 0x05, 0xb9, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8f, 0xfe, 0x9b, 0x04, 0xd1, - 0x05, 0xd5, 0x10, 0x26, 0x02, 0xb9, 0x00, 0x00, 0x10, 0x06, 0x00, 0x35, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x3d, 0xfe, 0x9b, 0x04, 0x83, - 0x04, 0x7b, 0x10, 0x26, 0x02, 0xb9, 0x00, 0x00, 0x10, 0x06, 0x00, 0x55, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8b, 0xff, 0xe3, 0x04, 0x4a, - 0x07, 0x50, 0x10, 0x26, 0x0c, 0xc7, 0x00, 0x00, 0x10, 0x06, 0x00, 0x36, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xd5, 0xff, 0xe3, 0x04, 0x06, - 0x06, 0x10, 0x10, 0x26, 0x02, 0x8f, 0x00, 0x00, 0x12, 0x06, 0x00, 0x56, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8b, 0xfe, 0x63, 0x04, 0x4a, - 0x05, 0xf0, 0x10, 0x26, 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x36, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xd5, 0xfe, 0x63, 0x04, 0x06, - 0x04, 0x7b, 0x10, 0x26, 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x56, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8b, 0xfe, 0x63, 0x04, 0x4a, - 0x07, 0x50, 0x10, 0x26, 0x0c, 0xc7, 0x00, 0x00, 0x10, 0x26, 0x00, 0x36, - 0x00, 0x00, 0x10, 0x06, 0x02, 0xab, 0x00, 0x00, 0xff, 0xff, 0x00, 0xd5, - 0xfe, 0x63, 0x04, 0x06, 0x06, 0x10, 0x10, 0x26, 0x02, 0x8f, 0x00, 0x00, - 0x10, 0x26, 0x00, 0x56, 0x00, 0x00, 0x10, 0x06, 0x02, 0xab, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x2f, 0x00, 0x00, 0x04, 0xa2, 0x07, 0x50, 0x10, 0x26, - 0x0c, 0xc7, 0x00, 0x00, 0x10, 0x06, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x83, 0x00, 0x00, 0x04, 0x08, 0x07, 0x50, 0x10, 0x26, - 0x0c, 0xc7, 0x00, 0x00, 0x10, 0x06, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x2f, 0xfe, 0x63, 0x04, 0xa2, 0x05, 0xd5, 0x10, 0x26, - 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x83, 0xfe, 0x63, 0x04, 0x08, 0x05, 0x9e, 0x10, 0x26, - 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x2f, 0xfe, 0x9b, 0x04, 0xa2, 0x05, 0xd5, 0x10, 0x26, - 0x02, 0xb9, 0x00, 0x00, 0x10, 0x06, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x83, 0xfe, 0x9b, 0x04, 0x08, 0x05, 0x9e, 0x10, 0x26, - 0x02, 0xb9, 0x00, 0x00, 0x10, 0x06, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x2f, 0xfe, 0x1b, 0x04, 0xa2, 0x05, 0xd5, 0x10, 0x26, - 0x02, 0xb5, 0x00, 0x00, 0x10, 0x06, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x83, 0xfe, 0x1b, 0x04, 0x08, 0x05, 0x9e, 0x10, 0x26, - 0x02, 0xb5, 0x00, 0x00, 0x10, 0x06, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x93, 0xfe, 0x64, 0x04, 0x3d, 0x05, 0xd5, 0x10, 0x26, - 0x02, 0xac, 0x00, 0x00, 0x10, 0x06, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x64, 0x04, 0x1b, 0x04, 0x5e, 0x10, 0x26, - 0x02, 0xac, 0x00, 0x00, 0x10, 0x06, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x93, 0xfe, 0x1b, 0x04, 0x3d, 0x05, 0xd5, 0x10, 0x26, - 0x02, 0xb8, 0x00, 0x00, 0x10, 0x06, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x1b, 0x04, 0x1b, 0x04, 0x5e, 0x10, 0x26, - 0x02, 0xb8, 0x00, 0x00, 0x10, 0x06, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x93, 0xfe, 0x1b, 0x04, 0x3d, 0x05, 0xd5, 0x10, 0x26, - 0x02, 0xb5, 0x00, 0x00, 0x10, 0x06, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x1b, 0x04, 0x1b, 0x04, 0x5e, 0x10, 0x26, - 0x02, 0xb5, 0x00, 0x00, 0x10, 0x06, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x93, 0xff, 0xe3, 0x04, 0x3d, 0x07, 0xf9, 0x10, 0x27, - 0x0c, 0xc0, 0x00, 0x00, 0x01, 0x06, 0x10, 0x27, 0x0c, 0xbf, 0x00, 0x32, - 0x02, 0x03, 0x10, 0x06, 0x00, 0x38, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, - 0xff, 0xe3, 0x04, 0x1b, 0x07, 0xfa, 0x10, 0x27, 0x02, 0x89, 0x00, 0x00, - 0x01, 0x94, 0x10, 0x26, 0x02, 0x79, 0x00, 0x00, 0x10, 0x06, 0x00, 0x58, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x39, 0x00, 0x00, 0x04, 0x98, - 0x07, 0x45, 0x10, 0x27, 0x0c, 0xc0, 0x00, 0x00, 0x01, 0x5c, 0x12, 0x06, - 0x00, 0x39, 0x00, 0x00, 0xff, 0xff, 0x00, 0x64, 0x00, 0x00, 0x04, 0x6d, - 0x06, 0x0f, 0x10, 0x26, 0x02, 0x79, 0x00, 0xd8, 0x12, 0x06, 0x00, 0x59, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x39, 0xfe, 0x63, 0x04, 0x98, - 0x05, 0xd5, 0x10, 0x26, 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x39, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x64, 0xfe, 0x63, 0x04, 0x6d, - 0x04, 0x60, 0x10, 0x26, 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x59, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd1, - 0x07, 0x72, 0x10, 0x27, 0x0c, 0xc1, 0x00, 0x00, 0x01, 0x7c, 0x10, 0x06, - 0x00, 0x3a, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd1, - 0x06, 0x6d, 0x10, 0x26, 0x00, 0x43, 0xc0, 0x07, 0x10, 0x06, 0x00, 0x5a, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd1, - 0x07, 0x72, 0x10, 0x27, 0x0c, 0xbf, 0x00, 0x00, 0x01, 0x7c, 0x10, 0x06, - 0x00, 0x3a, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd1, - 0x06, 0x6d, 0x10, 0x26, 0x00, 0x76, 0x40, 0x07, 0x10, 0x06, 0x00, 0x5a, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd1, - 0x07, 0x34, 0x10, 0x27, 0x00, 0x6a, 0x00, 0x00, 0x01, 0x24, 0x10, 0x06, - 0x00, 0x3a, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd1, - 0x05, 0xbf, 0x10, 0x26, 0x00, 0x6a, 0x00, 0xaf, 0x10, 0x06, 0x00, 0x5a, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd1, - 0x07, 0x50, 0x10, 0x26, 0x0c, 0xc7, 0x00, 0x00, 0x10, 0x06, 0x00, 0x3a, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd1, - 0x06, 0x10, 0x10, 0x26, 0x02, 0x8f, 0x00, 0x00, 0x10, 0x06, 0x00, 0x5a, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0x63, 0x04, 0xd1, - 0x05, 0xd5, 0x10, 0x26, 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x3a, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0x63, 0x04, 0xd1, - 0x04, 0x60, 0x10, 0x26, 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x5a, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x12, 0x00, 0x00, 0x04, 0xbe, - 0x07, 0x50, 0x10, 0x26, 0x0c, 0xc7, 0x00, 0x00, 0x10, 0x06, 0x00, 0x3b, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4c, 0x00, 0x00, 0x04, 0x85, - 0x06, 0x10, 0x10, 0x26, 0x02, 0x8f, 0x00, 0x00, 0x10, 0x06, 0x00, 0x5b, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x12, 0x00, 0x00, 0x04, 0xbe, - 0x07, 0x35, 0x10, 0x27, 0x0c, 0xbe, 0x00, 0x12, 0x01, 0x5c, 0x12, 0x06, - 0x00, 0x3b, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4c, 0x00, 0x00, 0x04, 0x85, - 0x05, 0xbf, 0x10, 0x26, 0x00, 0x6a, 0x00, 0xaf, 0x12, 0x06, 0x00, 0x5b, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, - 0x07, 0x50, 0x10, 0x26, 0x0c, 0xc7, 0x00, 0x00, 0x10, 0x06, 0x00, 0x3c, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x68, 0xfe, 0x56, 0x04, 0x81, - 0x06, 0x10, 0x10, 0x26, 0x02, 0x8f, 0x00, 0x00, 0x10, 0x06, 0x00, 0x5c, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x9c, 0x00, 0x00, 0x04, 0x91, - 0x07, 0x74, 0x10, 0x27, 0x0c, 0xc2, 0x00, 0x2e, 0x01, 0x7c, 0x12, 0x06, - 0x00, 0x3d, 0x00, 0x00, 0xff, 0xff, 0x00, 0xcb, 0x00, 0x00, 0x04, 0x10, - 0x06, 0x6d, 0x10, 0x26, 0x02, 0x67, 0x11, 0x07, 0x12, 0x06, 0x00, 0x5d, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x9c, 0xfe, 0x63, 0x04, 0x91, - 0x05, 0xd5, 0x10, 0x26, 0x02, 0xab, 0x32, 0x00, 0x12, 0x06, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xcb, 0xfe, 0x63, 0x04, 0x10, - 0x04, 0x62, 0x10, 0x26, 0x02, 0xab, 0x00, 0x00, 0x12, 0x06, 0x00, 0x5d, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x9c, 0xfe, 0x9b, 0x04, 0x91, - 0x05, 0xd5, 0x10, 0x26, 0x02, 0xb9, 0x32, 0x00, 0x10, 0x06, 0x00, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xcb, 0xfe, 0x9b, 0x04, 0x10, - 0x04, 0x62, 0x10, 0x26, 0x02, 0xb9, 0x00, 0x00, 0x10, 0x06, 0x00, 0x5d, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x9b, 0x04, 0x1b, - 0x06, 0x14, 0x10, 0x26, 0x02, 0xb9, 0x00, 0x00, 0x10, 0x06, 0x00, 0x4b, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x83, 0x00, 0x00, 0x04, 0x08, - 0x06, 0xe2, 0x10, 0x27, 0x00, 0x6a, 0xff, 0xa2, 0x00, 0xd2, 0x12, 0x06, - 0x00, 0x57, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd1, - 0x07, 0x1a, 0x10, 0x26, 0x02, 0x77, 0x00, 0x14, 0x12, 0x06, 0x00, 0x5a, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x68, 0xfe, 0x56, 0x04, 0x81, - 0x07, 0x1a, 0x10, 0x26, 0x02, 0x77, 0x0c, 0x14, 0x12, 0x06, 0x00, 0x5c, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, 0x00, 0x00, 0x04, 0x27, - 0x07, 0x50, 0x10, 0x26, 0x0c, 0xc7, 0x00, 0x00, 0x10, 0x06, 0x01, 0x41, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, - 0x06, 0x22, 0x10, 0x06, 0x02, 0xfc, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, - 0xfe, 0x63, 0x04, 0xac, 0x05, 0xd5, 0x10, 0x26, 0x02, 0xab, 0x00, 0x00, - 0x10, 0x06, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x85, - 0xfe, 0x63, 0x04, 0x23, 0x04, 0x7b, 0x10, 0x26, 0x02, 0xab, 0x00, 0x00, - 0x10, 0x06, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, - 0xfe, 0x63, 0x04, 0xac, 0x07, 0x74, 0x10, 0x27, 0x0c, 0xc2, 0x00, 0x00, - 0x01, 0x7c, 0x12, 0x06, 0x05, 0xf4, 0x00, 0x00, 0xff, 0xff, 0x00, 0x85, - 0xfe, 0x63, 0x04, 0x23, 0x06, 0x6d, 0x10, 0x26, 0x02, 0x67, 0xe8, 0x07, - 0x12, 0x06, 0x05, 0xf5, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, - 0x00, 0x00, 0x04, 0xac, 0x07, 0xf9, 0x10, 0x26, 0x0c, 0xc6, 0x00, 0x80, - 0x10, 0x26, 0x00, 0x24, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xc1, 0x00, 0x00, - 0x02, 0x03, 0x00, 0x00, 0xff, 0xff, 0x00, 0x85, 0xff, 0xe3, 0x04, 0x23, - 0x07, 0xa2, 0x10, 0x27, 0x02, 0x88, 0x00, 0x00, 0x01, 0x3c, 0x12, 0x06, - 0x00, 0xc5, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, 0xfe, 0x63, 0x04, 0xac, - 0x07, 0x6d, 0x10, 0x26, 0x0c, 0xc6, 0x00, 0x00, 0x12, 0x06, 0x05, 0xf4, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x85, 0xfe, 0x63, 0x04, 0x23, - 0x06, 0x14, 0x10, 0x26, 0x02, 0x75, 0xe8, 0xcc, 0x12, 0x06, 0x05, 0xf5, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc5, 0xfe, 0x63, 0x04, 0x4e, - 0x05, 0xd5, 0x10, 0x26, 0x02, 0xab, 0x12, 0x00, 0x10, 0x06, 0x00, 0x28, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, 0xfe, 0x63, 0x04, 0x58, - 0x04, 0x7b, 0x10, 0x26, 0x02, 0xab, 0x0e, 0x00, 0x10, 0x06, 0x00, 0x48, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc5, 0x00, 0x00, 0x04, 0x4e, - 0x07, 0x5e, 0x10, 0x27, 0x0c, 0xc0, 0x00, 0x2a, 0x01, 0x75, 0x10, 0x06, - 0x00, 0x28, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, 0xff, 0xe3, 0x04, 0x58, - 0x06, 0x37, 0x10, 0x26, 0x02, 0x79, 0x00, 0x00, 0x10, 0x06, 0x00, 0x48, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc5, 0xfe, 0x63, 0x04, 0x4e, - 0x07, 0x74, 0x10, 0x27, 0x0c, 0xc2, 0x00, 0x18, 0x01, 0x7c, 0x12, 0x06, - 0x05, 0xfc, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, 0xfe, 0x63, 0x04, 0x58, - 0x06, 0x6d, 0x10, 0x26, 0x02, 0x67, 0x22, 0x07, 0x12, 0x06, 0x05, 0xfd, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc9, 0xfe, 0x63, 0x04, 0x06, - 0x05, 0xd5, 0x10, 0x26, 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x2c, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xb2, 0xfe, 0x63, 0x04, 0x44, - 0x06, 0x14, 0x10, 0x26, 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x4c, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x75, 0xfe, 0x63, 0x04, 0x5c, - 0x05, 0xf0, 0x10, 0x26, 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x32, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0xfe, 0x63, 0x04, 0x48, - 0x04, 0x7b, 0x10, 0x26, 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x52, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x75, 0xfe, 0x63, 0x04, 0x5c, - 0x07, 0x74, 0x10, 0x27, 0x0c, 0xc2, 0x00, 0x00, 0x01, 0x7c, 0x12, 0x06, - 0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0xfe, 0x63, 0x04, 0x48, - 0x06, 0x6d, 0x10, 0x26, 0x02, 0x67, 0x00, 0x07, 0x12, 0x06, 0x06, 0x05, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x06, 0xff, 0xe3, 0x04, 0xa7, - 0x07, 0x6b, 0x10, 0x27, 0x0c, 0xbf, 0xff, 0x91, 0x01, 0x75, 0x12, 0x06, - 0x01, 0x62, 0x00, 0x00, 0xff, 0xff, 0x00, 0x20, 0xff, 0xe3, 0x04, 0xb2, - 0x06, 0x66, 0x10, 0x26, 0x00, 0x76, 0x97, 0x00, 0x12, 0x06, 0x01, 0x63, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x06, 0xff, 0xe3, 0x04, 0xa7, - 0x07, 0x6b, 0x10, 0x27, 0x0c, 0xc1, 0xff, 0x91, 0x01, 0x75, 0x12, 0x06, - 0x01, 0x62, 0x00, 0x00, 0xff, 0xff, 0x00, 0x20, 0xff, 0xe3, 0x04, 0xb2, - 0x06, 0x66, 0x10, 0x26, 0x00, 0x43, 0x97, 0x00, 0x12, 0x06, 0x01, 0x63, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x06, 0xff, 0xe3, 0x04, 0xa7, - 0x07, 0x5e, 0x10, 0x27, 0x0c, 0xc0, 0xff, 0x91, 0x01, 0x75, 0x12, 0x06, - 0x01, 0x62, 0x00, 0x00, 0xff, 0xff, 0x00, 0x20, 0xff, 0xe3, 0x04, 0xb2, - 0x06, 0x37, 0x10, 0x26, 0x02, 0x79, 0x97, 0x00, 0x12, 0x06, 0x01, 0x63, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x06, 0xfe, 0x63, 0x04, 0xa7, - 0x06, 0x15, 0x10, 0x26, 0x02, 0xab, 0x91, 0x00, 0x12, 0x06, 0x01, 0x62, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x20, 0xfe, 0x63, 0x04, 0xb2, - 0x04, 0x7b, 0x10, 0x26, 0x02, 0xab, 0x97, 0x00, 0x12, 0x06, 0x01, 0x63, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x93, 0xfe, 0x63, 0x04, 0x3d, - 0x05, 0xd5, 0x10, 0x26, 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x38, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x63, 0x04, 0x1b, - 0x04, 0x5e, 0x10, 0x26, 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x58, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x09, 0xff, 0xe3, 0x04, 0xc8, - 0x07, 0x6b, 0x10, 0x27, 0x0c, 0xbf, 0xff, 0x76, 0x01, 0x75, 0x12, 0x06, - 0x01, 0x71, 0x00, 0x00, 0xff, 0xff, 0x00, 0x27, 0xff, 0xe3, 0x04, 0xaa, - 0x06, 0x66, 0x10, 0x27, 0x00, 0x76, 0xff, 0x64, 0x00, 0x00, 0x12, 0x06, - 0x01, 0x72, 0x00, 0x00, 0xff, 0xff, 0x00, 0x09, 0xff, 0xe3, 0x04, 0xc8, - 0x07, 0x6b, 0x10, 0x27, 0x0c, 0xc1, 0xff, 0x76, 0x01, 0x75, 0x12, 0x06, - 0x01, 0x71, 0x00, 0x00, 0xff, 0xff, 0x00, 0x27, 0xff, 0xe3, 0x04, 0xaa, - 0x06, 0x66, 0x10, 0x27, 0x00, 0x43, 0xff, 0x64, 0x00, 0x00, 0x12, 0x06, - 0x01, 0x72, 0x00, 0x00, 0xff, 0xff, 0x00, 0x09, 0xff, 0xe3, 0x04, 0xc8, - 0x07, 0x5e, 0x10, 0x27, 0x0c, 0xc0, 0xff, 0x76, 0x01, 0x75, 0x12, 0x06, - 0x01, 0x71, 0x00, 0x00, 0xff, 0xff, 0x00, 0x27, 0xff, 0xe3, 0x04, 0xaa, - 0x06, 0x37, 0x10, 0x27, 0x02, 0x79, 0xff, 0x64, 0x00, 0x00, 0x12, 0x06, - 0x01, 0x72, 0x00, 0x00, 0xff, 0xff, 0x00, 0x09, 0xfe, 0x63, 0x04, 0xc8, - 0x06, 0x19, 0x10, 0x27, 0x02, 0xab, 0xff, 0x76, 0x00, 0x00, 0x12, 0x06, - 0x01, 0x71, 0x00, 0x00, 0xff, 0xff, 0x00, 0x27, 0xfe, 0x63, 0x04, 0xaa, - 0x04, 0x71, 0x10, 0x27, 0x02, 0xab, 0xff, 0x64, 0x00, 0x00, 0x12, 0x06, - 0x01, 0x72, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, - 0x07, 0x72, 0x10, 0x27, 0x0c, 0xc1, 0x00, 0x00, 0x01, 0x7c, 0x10, 0x06, - 0x00, 0x3c, 0x00, 0x00, 0xff, 0xff, 0x00, 0x68, 0xfe, 0x56, 0x04, 0x81, - 0x06, 0x6d, 0x10, 0x26, 0x00, 0x43, 0xcc, 0x07, 0x10, 0x06, 0x00, 0x5c, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, 0xfe, 0x63, 0x04, 0xac, - 0x05, 0xd5, 0x10, 0x26, 0x02, 0xab, 0x00, 0x00, 0x10, 0x06, 0x00, 0x3c, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x68, 0xfe, 0x56, 0x04, 0x81, - 0x04, 0x60, 0x10, 0x27, 0x02, 0xab, 0x00, 0xfa, 0x00, 0x00, 0x10, 0x06, - 0x00, 0x5c, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, - 0x07, 0x5e, 0x10, 0x27, 0x0c, 0xc0, 0x00, 0x00, 0x01, 0x75, 0x10, 0x06, - 0x00, 0x3c, 0x00, 0x00, 0xff, 0xff, 0x00, 0x68, 0xfe, 0x56, 0x04, 0x81, - 0x06, 0x37, 0x10, 0x26, 0x02, 0x79, 0x00, 0x00, 0x10, 0x06, 0x00, 0x5c, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xff, 0xe7, 0x04, 0x95, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xf9, 0x00, 0x00, 0x10, 0x06, 0x06, 0xd0, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xff, 0xe7, 0x04, 0x95, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xf9, 0x00, 0x00, 0x10, 0x06, 0x07, 0x08, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xff, 0xe7, 0x04, 0x95, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xf9, 0x00, 0x00, 0x10, 0x06, 0x06, 0xdd, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xff, 0xe7, 0x04, 0x95, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xf9, 0x00, 0x00, 0x10, 0x06, 0x06, 0xea, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xff, 0xe7, 0x04, 0x95, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xf9, 0x00, 0x00, 0x10, 0x06, 0x06, 0xde, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xff, 0xe7, 0x04, 0x95, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xf9, 0x00, 0x00, 0x10, 0x06, 0x06, 0xeb, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xff, 0xe7, 0x04, 0x95, - 0x07, 0xd1, 0x10, 0x26, 0x02, 0xf9, 0x00, 0x00, 0x10, 0x06, 0x06, 0xdf, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xff, 0xe7, 0x04, 0x95, - 0x07, 0xd1, 0x10, 0x26, 0x02, 0xf9, 0x00, 0x00, 0x10, 0x06, 0x06, 0xec, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xda, 0x00, 0x00, 0x10, 0x07, 0x06, 0xd0, - 0xfe, 0xa2, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xda, 0x00, 0x00, 0x10, 0x07, 0x07, 0x08, - 0xfe, 0x70, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x6b, 0x00, 0x00, 0x04, 0xac, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xda, 0x00, 0x00, 0x10, 0x07, 0x06, 0xdd, - 0xfd, 0x76, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x6b, 0x00, 0x00, 0x04, 0xac, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xda, 0x00, 0x00, 0x10, 0x07, 0x06, 0xea, - 0xfd, 0x76, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1a, 0x00, 0x00, 0x04, 0xac, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xda, 0x00, 0x00, 0x10, 0x07, 0x06, 0xde, - 0xfd, 0xf3, 0x00, 0x00, 0xff, 0xff, 0xff, 0x06, 0x00, 0x00, 0x04, 0xac, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xda, 0x00, 0x00, 0x10, 0x07, 0x06, 0xeb, - 0xfd, 0xf3, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc1, 0x00, 0x00, 0x04, 0xac, - 0x07, 0xd1, 0x10, 0x26, 0x02, 0xda, 0x00, 0x00, 0x10, 0x07, 0x06, 0xdf, - 0xfe, 0xa2, 0x00, 0x00, 0xff, 0xff, 0xff, 0x8f, 0x00, 0x00, 0x04, 0xac, - 0x07, 0xd1, 0x10, 0x26, 0x02, 0xda, 0x00, 0x00, 0x10, 0x07, 0x06, 0xec, - 0xfe, 0x70, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa9, 0xff, 0xea, 0x04, 0x28, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xfd, 0x00, 0x00, 0x10, 0x06, 0x06, 0xd0, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa9, 0xff, 0xea, 0x04, 0x28, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xfd, 0x00, 0x00, 0x10, 0x06, 0x07, 0x08, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa9, 0xff, 0xea, 0x04, 0x28, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xfd, 0x00, 0x00, 0x10, 0x06, 0x06, 0xdd, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa9, 0xff, 0xea, 0x04, 0x28, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xfd, 0x00, 0x00, 0x10, 0x06, 0x06, 0xea, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa9, 0xff, 0xea, 0x04, 0x28, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xfd, 0x00, 0x00, 0x10, 0x06, 0x06, 0xde, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa9, 0xff, 0xea, 0x04, 0x28, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xfd, 0x00, 0x00, 0x10, 0x06, 0x06, 0xeb, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x04, 0x4e, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xde, 0x00, 0x00, 0x10, 0x07, 0x06, 0xd0, - 0xfd, 0x8f, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x04, 0x4e, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xde, 0x00, 0x00, 0x10, 0x07, 0x07, 0x08, - 0xfd, 0x8f, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x8a, 0x00, 0x00, 0x04, 0x4e, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xde, 0x00, 0x00, 0x10, 0x07, 0x06, 0xdd, - 0xfc, 0x95, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x8a, 0x00, 0x00, 0x04, 0x4e, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xde, 0x00, 0x00, 0x10, 0x07, 0x06, 0xea, - 0xfc, 0x95, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x07, 0x00, 0x00, 0x04, 0x4e, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xde, 0x00, 0x00, 0x10, 0x07, 0x06, 0xde, - 0xfc, 0xe0, 0x00, 0x00, 0xff, 0xff, 0xfd, 0xf3, 0x00, 0x00, 0x04, 0x4e, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xde, 0x00, 0x00, 0x10, 0x07, 0x06, 0xeb, - 0xfc, 0xe0, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x56, 0x04, 0x1b, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xff, 0x00, 0x00, 0x10, 0x06, 0x06, 0xd0, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x56, 0x04, 0x1b, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xff, 0x00, 0x00, 0x10, 0x06, 0x07, 0x08, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x56, 0x04, 0x1b, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xff, 0x00, 0x00, 0x10, 0x06, 0x06, 0xdd, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x56, 0x04, 0x1b, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xff, 0x00, 0x00, 0x10, 0x06, 0x06, 0xea, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x56, 0x04, 0x1e, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xff, 0x00, 0x00, 0x10, 0x06, 0x06, 0xde, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x56, 0x04, 0x1e, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xff, 0x00, 0x00, 0x10, 0x06, 0x06, 0xeb, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x56, 0x04, 0x1b, - 0x07, 0xd1, 0x10, 0x26, 0x02, 0xff, 0x00, 0x00, 0x10, 0x06, 0x06, 0xdf, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x56, 0x04, 0x1b, - 0x07, 0xd1, 0x10, 0x26, 0x02, 0xff, 0x00, 0x00, 0x10, 0x06, 0x06, 0xec, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x4c, 0x00, 0x00, 0x04, 0x48, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xe0, 0x00, 0x00, 0x10, 0x07, 0x06, 0xd0, - 0xfd, 0x5d, 0x00, 0x00, 0xff, 0xff, 0xff, 0x4c, 0x00, 0x00, 0x04, 0x48, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xe0, 0x00, 0x00, 0x10, 0x07, 0x07, 0x08, - 0xfd, 0x5d, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x3f, 0x00, 0x00, 0x04, 0x48, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xe0, 0x00, 0x00, 0x10, 0x07, 0x06, 0xdd, - 0xfc, 0x4a, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x3f, 0x00, 0x00, 0x04, 0x48, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xe0, 0x00, 0x00, 0x10, 0x07, 0x06, 0xea, - 0xfc, 0x4a, 0x00, 0x00, 0xff, 0xff, 0xfd, 0xa3, 0x00, 0x00, 0x04, 0x48, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xe0, 0x00, 0x00, 0x10, 0x07, 0x06, 0xde, - 0xfc, 0x7c, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x8f, 0x00, 0x00, 0x04, 0x48, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xe0, 0x00, 0x00, 0x10, 0x07, 0x06, 0xeb, - 0xfc, 0x7c, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x63, 0x00, 0x00, 0x04, 0x48, - 0x07, 0xd1, 0x10, 0x26, 0x02, 0xe0, 0x00, 0x00, 0x10, 0x07, 0x06, 0xdf, - 0xfd, 0x44, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x63, 0x00, 0x00, 0x04, 0x48, - 0x07, 0xd1, 0x10, 0x26, 0x02, 0xe0, 0x00, 0x00, 0x10, 0x07, 0x06, 0xec, - 0xfd, 0x44, 0x00, 0x00, 0xff, 0xff, 0x01, 0x36, 0x00, 0x00, 0x03, 0xcf, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x01, 0x00, 0x00, 0x10, 0x06, 0x06, 0xd0, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x36, 0x00, 0x00, 0x03, 0xcf, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x01, 0x00, 0x00, 0x10, 0x06, 0x07, 0x08, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xf5, 0x00, 0x00, 0x03, 0xf0, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x01, 0x00, 0x00, 0x10, 0x06, 0x06, 0xdd, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xf5, 0x00, 0x00, 0x03, 0xf0, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x01, 0x00, 0x00, 0x10, 0x06, 0x06, 0xea, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x27, 0x00, 0x00, 0x04, 0x1e, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x01, 0x00, 0x00, 0x10, 0x06, 0x06, 0xde, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x13, 0x00, 0x00, 0x04, 0x1e, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x01, 0x00, 0x00, 0x10, 0x06, 0x06, 0xeb, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x1f, 0x00, 0x00, 0x03, 0xcf, - 0x07, 0xd1, 0x10, 0x26, 0x03, 0x01, 0x00, 0x00, 0x10, 0x06, 0x06, 0xdf, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x1f, 0x00, 0x00, 0x03, 0xcf, - 0x07, 0xd1, 0x10, 0x26, 0x03, 0x01, 0x00, 0x00, 0x10, 0x06, 0x06, 0xec, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x04, 0x06, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xe2, 0x00, 0x00, 0x10, 0x07, 0x06, 0xd0, - 0xfd, 0x8f, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x04, 0x06, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xe2, 0x00, 0x00, 0x10, 0x07, 0x07, 0x08, - 0xfd, 0x8f, 0x00, 0x00, 0xff, 0xff, 0xfd, 0xa3, 0x00, 0x00, 0x04, 0x06, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xe2, 0x00, 0x00, 0x10, 0x07, 0x06, 0xdd, - 0xfc, 0xae, 0x00, 0x00, 0xff, 0xff, 0xfd, 0xa3, 0x00, 0x00, 0x04, 0x06, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xe2, 0x00, 0x00, 0x10, 0x07, 0x06, 0xea, - 0xfc, 0xae, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x07, 0x00, 0x00, 0x04, 0x06, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xe2, 0x00, 0x00, 0x10, 0x07, 0x06, 0xde, - 0xfc, 0xe0, 0x00, 0x00, 0xff, 0xff, 0xfd, 0xf3, 0x00, 0x00, 0x04, 0x06, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xe2, 0x00, 0x00, 0x10, 0x07, 0x06, 0xeb, - 0xfc, 0xe0, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xae, 0x00, 0x00, 0x04, 0x06, - 0x07, 0xd1, 0x10, 0x26, 0x02, 0xe2, 0x00, 0x00, 0x10, 0x07, 0x06, 0xdf, - 0xfd, 0x8f, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xae, 0x00, 0x00, 0x04, 0x06, - 0x07, 0xd1, 0x10, 0x26, 0x02, 0xe2, 0x00, 0x00, 0x10, 0x07, 0x06, 0xec, - 0xfd, 0x8f, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x07, 0x00, 0x00, 0x10, 0x06, 0x06, 0xd0, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x07, 0x00, 0x00, 0x10, 0x06, 0x07, 0x08, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x07, 0x00, 0x00, 0x10, 0x06, 0x06, 0xdd, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x07, 0x00, 0x00, 0x10, 0x06, 0x06, 0xea, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x07, 0x00, 0x00, 0x10, 0x06, 0x06, 0xde, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x07, 0x00, 0x00, 0x10, 0x06, 0x06, 0xeb, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc9, 0xff, 0xe3, 0x04, 0x5c, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xe8, 0x00, 0x00, 0x10, 0x07, 0x06, 0xd0, - 0xfd, 0xda, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7e, 0xff, 0xe3, 0x04, 0x5c, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xe8, 0x00, 0x00, 0x10, 0x07, 0x07, 0x08, - 0xfd, 0x8f, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x8a, 0xff, 0xe3, 0x04, 0x5c, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xe8, 0x00, 0x00, 0x10, 0x07, 0x06, 0xdd, - 0xfc, 0x95, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x8a, 0xff, 0xe3, 0x04, 0x5c, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xe8, 0x00, 0x00, 0x10, 0x07, 0x06, 0xea, - 0xfc, 0x95, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x9d, 0xff, 0xe3, 0x04, 0x5c, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xe8, 0x00, 0x00, 0x10, 0x07, 0x06, 0xde, - 0xfd, 0x76, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x89, 0xff, 0xe3, 0x04, 0x5c, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xe8, 0x00, 0x00, 0x10, 0x07, 0x06, 0xeb, - 0xfd, 0x76, 0x00, 0x00, 0xff, 0xff, 0x00, 0x33, 0x00, 0x00, 0x04, 0x69, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x0d, 0x00, 0x00, 0x10, 0x06, 0x06, 0xd0, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x33, 0x00, 0x00, 0x04, 0x69, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x0d, 0x00, 0x00, 0x10, 0x06, 0x07, 0x08, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x33, 0x00, 0x00, 0x04, 0x69, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x0d, 0x00, 0x00, 0x10, 0x06, 0x06, 0xdd, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x33, 0x00, 0x00, 0x04, 0x69, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x0d, 0x00, 0x00, 0x10, 0x06, 0x06, 0xea, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x33, 0x00, 0x00, 0x04, 0x69, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x0d, 0x00, 0x00, 0x10, 0x06, 0x06, 0xde, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x33, 0x00, 0x00, 0x04, 0x69, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x0d, 0x00, 0x00, 0x10, 0x06, 0x06, 0xeb, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x33, 0x00, 0x00, 0x04, 0x69, - 0x07, 0xd1, 0x10, 0x26, 0x03, 0x0d, 0x00, 0x00, 0x10, 0x06, 0x06, 0xdf, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x33, 0x00, 0x00, 0x04, 0x69, - 0x07, 0xd1, 0x10, 0x26, 0x03, 0x0d, 0x00, 0x00, 0x10, 0x06, 0x06, 0xec, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xe8, 0x00, 0x00, 0x04, 0xac, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xed, 0x00, 0x00, 0x10, 0x07, 0x07, 0x08, - 0xfc, 0xf9, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x3f, 0x00, 0x00, 0x04, 0xac, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xed, 0x00, 0x00, 0x10, 0x07, 0x06, 0xea, - 0xfc, 0x4a, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x44, 0x00, 0x00, 0x04, 0xac, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xed, 0x00, 0x00, 0x10, 0x07, 0x06, 0xeb, - 0xfc, 0x31, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x18, 0x00, 0x00, 0x04, 0xac, - 0x07, 0xd1, 0x10, 0x26, 0x02, 0xed, 0x00, 0x00, 0x10, 0x07, 0x06, 0xec, - 0xfc, 0xf9, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xff, 0xe3, 0x04, 0x8c, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x11, 0x00, 0x00, 0x10, 0x06, 0x06, 0xd0, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xff, 0xe3, 0x04, 0x8c, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x11, 0x00, 0x00, 0x10, 0x06, 0x07, 0x08, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xff, 0xe3, 0x04, 0x8c, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x11, 0x00, 0x00, 0x10, 0x06, 0x06, 0xdd, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xff, 0xe3, 0x04, 0x8c, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x11, 0x00, 0x00, 0x10, 0x06, 0x06, 0xea, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xff, 0xe3, 0x04, 0x8c, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x11, 0x00, 0x00, 0x10, 0x06, 0x06, 0xde, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xff, 0xe3, 0x04, 0x8c, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x11, 0x00, 0x00, 0x10, 0x06, 0x06, 0xeb, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xff, 0xe3, 0x04, 0x8c, - 0x07, 0xd1, 0x10, 0x26, 0x03, 0x11, 0x00, 0x00, 0x10, 0x06, 0x06, 0xdf, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xff, 0xe3, 0x04, 0x8c, - 0x07, 0xd1, 0x10, 0x26, 0x03, 0x11, 0x00, 0x00, 0x10, 0x06, 0x06, 0xec, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc9, 0x00, 0x00, 0x04, 0x87, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xf1, 0x00, 0x00, 0x10, 0x07, 0x06, 0xd0, - 0xfd, 0xda, 0x00, 0x00, 0xff, 0xff, 0xff, 0x65, 0x00, 0x00, 0x04, 0x87, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xf1, 0x00, 0x00, 0x10, 0x07, 0x07, 0x08, - 0xfd, 0x76, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x8a, 0x00, 0x00, 0x04, 0x87, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xf1, 0x00, 0x00, 0x10, 0x07, 0x06, 0xdd, - 0xfc, 0x95, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x8a, 0x00, 0x00, 0x04, 0x87, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xf1, 0x00, 0x00, 0x10, 0x07, 0x06, 0xea, - 0xfc, 0x95, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xb6, 0x00, 0x00, 0x04, 0x87, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xf1, 0x00, 0x00, 0x10, 0x07, 0x06, 0xde, - 0xfd, 0x8f, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xa2, 0x00, 0x00, 0x04, 0x87, - 0x06, 0x72, 0x10, 0x26, 0x02, 0xf1, 0x00, 0x00, 0x10, 0x07, 0x06, 0xeb, - 0xfd, 0x8f, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xf9, 0x00, 0x00, 0x04, 0x87, - 0x07, 0xd1, 0x10, 0x26, 0x02, 0xf1, 0x00, 0x00, 0x10, 0x07, 0x06, 0xdf, - 0xfd, 0xda, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xae, 0x00, 0x00, 0x04, 0x87, - 0x07, 0xd1, 0x10, 0x26, 0x02, 0xf1, 0x00, 0x00, 0x10, 0x07, 0x06, 0xec, - 0xfd, 0x8f, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xff, 0xe7, 0x04, 0x95, - 0x06, 0x66, 0x10, 0x26, 0x02, 0xf9, 0x00, 0x00, 0x10, 0x06, 0x00, 0x43, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xff, 0xe7, 0x04, 0x95, - 0x06, 0x66, 0x10, 0x06, 0x02, 0xf4, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa9, - 0xff, 0xea, 0x04, 0x28, 0x06, 0x66, 0x10, 0x26, 0x02, 0xfd, 0x00, 0x00, - 0x10, 0x06, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa9, - 0xff, 0xea, 0x04, 0x28, 0x06, 0x66, 0x10, 0x06, 0x02, 0xf5, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x56, 0x04, 0x1b, 0x06, 0x66, 0x10, 0x26, - 0x02, 0xff, 0x00, 0x00, 0x10, 0x06, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x56, 0x04, 0x1b, 0x06, 0x66, 0x10, 0x06, - 0x02, 0xf6, 0x00, 0x00, 0xff, 0xff, 0x01, 0x17, 0x00, 0x00, 0x03, 0xcf, - 0x06, 0x66, 0x10, 0x26, 0x03, 0x01, 0x00, 0x00, 0x10, 0x06, 0x00, 0x43, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x36, 0x00, 0x00, 0x03, 0xcf, - 0x06, 0x66, 0x10, 0x06, 0x02, 0xf7, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, - 0xff, 0xe3, 0x04, 0x48, 0x06, 0x66, 0x10, 0x26, 0x03, 0x07, 0x00, 0x00, - 0x10, 0x06, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, - 0xff, 0xe3, 0x04, 0x48, 0x06, 0x66, 0x10, 0x06, 0x03, 0x14, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x33, 0x00, 0x00, 0x04, 0x69, 0x06, 0x66, 0x10, 0x26, - 0x03, 0x0d, 0x00, 0x00, 0x10, 0x06, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x33, 0x00, 0x00, 0x04, 0x69, 0x06, 0x66, 0x10, 0x06, - 0x03, 0x15, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xff, 0xe3, 0x04, 0x8c, - 0x06, 0x66, 0x10, 0x26, 0x03, 0x11, 0x00, 0x00, 0x10, 0x06, 0x00, 0x43, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xff, 0xe3, 0x04, 0x8c, - 0x06, 0x66, 0x10, 0x06, 0x03, 0x16, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xfe, 0x56, 0x04, 0x95, 0x06, 0x72, 0x10, 0x26, 0x06, 0x20, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xcd, 0x9c, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xfe, 0x56, 0x04, 0x95, 0x06, 0x72, 0x10, 0x26, 0x06, 0x21, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xcd, 0x9c, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xfe, 0x56, 0x04, 0x95, 0x06, 0x72, 0x10, 0x26, 0x06, 0x22, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xcd, 0x9c, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xfe, 0x56, 0x04, 0x95, 0x06, 0x72, 0x10, 0x26, 0x06, 0x23, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xcd, 0x9c, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xfe, 0x56, 0x04, 0x95, 0x06, 0x72, 0x10, 0x26, 0x02, 0xcd, 0x9c, 0x00, - 0x10, 0x06, 0x06, 0x24, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xfe, 0x56, 0x04, 0x95, 0x06, 0x72, 0x10, 0x26, 0x02, 0xcd, 0x9c, 0x00, - 0x10, 0x06, 0x06, 0x25, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xfe, 0x56, 0x04, 0x95, 0x07, 0xd1, 0x10, 0x26, 0x06, 0x26, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xcd, 0x9c, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xfe, 0x56, 0x04, 0x95, 0x07, 0xd1, 0x10, 0x26, 0x06, 0x27, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xcd, 0x9c, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, - 0xfe, 0x56, 0x04, 0xac, 0x06, 0x72, 0x10, 0x26, 0x06, 0x28, 0x00, 0x00, - 0x10, 0x06, 0x06, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, - 0xfe, 0x56, 0x04, 0xac, 0x06, 0x72, 0x10, 0x26, 0x06, 0x29, 0x00, 0x00, - 0x10, 0x06, 0x06, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x6b, - 0xfe, 0x56, 0x04, 0xac, 0x06, 0x72, 0x10, 0x26, 0x06, 0x2a, 0x00, 0x00, - 0x10, 0x06, 0x06, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x6b, - 0xfe, 0x56, 0x04, 0xac, 0x06, 0x72, 0x10, 0x26, 0x06, 0x2b, 0x00, 0x00, - 0x10, 0x06, 0x06, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1a, - 0xfe, 0x56, 0x04, 0xac, 0x06, 0x72, 0x10, 0x26, 0x06, 0xcf, 0x00, 0x00, - 0x10, 0x06, 0x06, 0x2c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x06, - 0xfe, 0x56, 0x04, 0xac, 0x06, 0x72, 0x10, 0x26, 0x06, 0xcf, 0x00, 0x00, - 0x10, 0x06, 0x06, 0x2d, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc1, - 0xfe, 0x56, 0x04, 0xac, 0x07, 0xd1, 0x10, 0x26, 0x06, 0x2e, 0x00, 0x00, - 0x10, 0x06, 0x06, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x8f, - 0xfe, 0x56, 0x04, 0xac, 0x07, 0xd1, 0x10, 0x26, 0x06, 0x2f, 0x00, 0x00, - 0x10, 0x06, 0x06, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, - 0xfe, 0x56, 0x04, 0x1b, 0x06, 0x72, 0x10, 0x26, 0x06, 0x3c, 0x00, 0x00, - 0x10, 0x07, 0x02, 0xcd, 0xfe, 0xc8, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, - 0xfe, 0x56, 0x04, 0x1b, 0x06, 0x72, 0x10, 0x26, 0x06, 0x3d, 0x00, 0x00, - 0x10, 0x07, 0x02, 0xcd, 0xfe, 0xc8, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, - 0xfe, 0x56, 0x04, 0x1b, 0x06, 0x72, 0x10, 0x26, 0x06, 0x3e, 0x00, 0x00, - 0x10, 0x07, 0x02, 0xcd, 0xfe, 0xc8, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, - 0xfe, 0x56, 0x04, 0x1b, 0x06, 0x72, 0x10, 0x26, 0x06, 0x3f, 0x00, 0x00, - 0x10, 0x07, 0x02, 0xcd, 0xfe, 0xc8, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, - 0xfe, 0x56, 0x04, 0x1e, 0x06, 0x72, 0x10, 0x27, 0x02, 0xcd, 0xfe, 0xc8, - 0x00, 0x00, 0x10, 0x06, 0x06, 0x40, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, - 0xfe, 0x56, 0x04, 0x1e, 0x06, 0x72, 0x10, 0x27, 0x02, 0xcd, 0xfe, 0xc8, - 0x00, 0x00, 0x10, 0x06, 0x06, 0x41, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, - 0xfe, 0x56, 0x04, 0x1b, 0x07, 0xd1, 0x10, 0x26, 0x06, 0x42, 0x00, 0x00, - 0x10, 0x07, 0x02, 0xcd, 0xfe, 0xc8, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, - 0xfe, 0x56, 0x04, 0x1b, 0x07, 0xd1, 0x10, 0x26, 0x06, 0x43, 0x00, 0x00, - 0x10, 0x07, 0x02, 0xcd, 0xfe, 0xc8, 0x00, 0x00, 0xff, 0xff, 0xff, 0x4c, - 0xfe, 0x56, 0x04, 0x48, 0x06, 0x72, 0x10, 0x26, 0x06, 0x44, 0x00, 0x00, - 0x10, 0x06, 0x06, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x4c, - 0xfe, 0x56, 0x04, 0x48, 0x06, 0x72, 0x10, 0x26, 0x06, 0x45, 0x00, 0x00, - 0x10, 0x06, 0x06, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x3f, - 0xfe, 0x56, 0x04, 0x48, 0x06, 0x72, 0x10, 0x26, 0x06, 0x46, 0x00, 0x00, - 0x10, 0x06, 0x06, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x3f, - 0xfe, 0x56, 0x04, 0x48, 0x06, 0x72, 0x10, 0x26, 0x06, 0x47, 0x00, 0x00, - 0x10, 0x06, 0x06, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfd, 0xa3, - 0xfe, 0x56, 0x04, 0x48, 0x06, 0x72, 0x10, 0x26, 0x06, 0xcf, 0x00, 0x00, - 0x10, 0x06, 0x06, 0x48, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x8f, - 0xfe, 0x56, 0x04, 0x48, 0x06, 0x72, 0x10, 0x26, 0x06, 0xcf, 0x00, 0x00, - 0x10, 0x06, 0x06, 0x49, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x63, - 0xfe, 0x56, 0x04, 0x48, 0x07, 0xd1, 0x10, 0x26, 0x06, 0x4a, 0x00, 0x00, - 0x10, 0x06, 0x06, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x63, - 0xfe, 0x56, 0x04, 0x48, 0x07, 0xd1, 0x10, 0x26, 0x06, 0x4b, 0x00, 0x00, - 0x10, 0x06, 0x06, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xfe, 0x56, 0x04, 0x8c, 0x06, 0x72, 0x10, 0x26, 0x06, 0x74, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xcd, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xfe, 0x56, 0x04, 0x8c, 0x06, 0x72, 0x10, 0x26, 0x06, 0x75, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xcd, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xfe, 0x56, 0x04, 0x8c, 0x06, 0x72, 0x10, 0x26, 0x06, 0x76, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xcd, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xfe, 0x56, 0x04, 0x8c, 0x06, 0x72, 0x10, 0x26, 0x06, 0x77, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xcd, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xfe, 0x56, 0x04, 0x8c, 0x06, 0x72, 0x10, 0x26, 0x02, 0xcd, 0x00, 0x00, - 0x10, 0x06, 0x06, 0x78, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xfe, 0x56, 0x04, 0x8c, 0x06, 0x72, 0x10, 0x26, 0x02, 0xcd, 0x00, 0x00, - 0x10, 0x06, 0x06, 0x79, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xfe, 0x56, 0x04, 0x8c, 0x07, 0xd1, 0x10, 0x26, 0x06, 0x7a, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xcd, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xfe, 0x56, 0x04, 0x8c, 0x07, 0xd1, 0x10, 0x26, 0x06, 0x7b, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xcd, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xc9, - 0xfe, 0x56, 0x04, 0x87, 0x06, 0x72, 0x10, 0x26, 0x06, 0x7c, 0x00, 0x00, - 0x10, 0x06, 0x06, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x65, - 0xfe, 0x56, 0x04, 0x87, 0x06, 0x72, 0x10, 0x26, 0x06, 0x7d, 0x00, 0x00, - 0x10, 0x06, 0x06, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x8a, - 0xfe, 0x56, 0x04, 0x87, 0x06, 0x72, 0x10, 0x26, 0x06, 0x7e, 0x00, 0x00, - 0x10, 0x06, 0x06, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfd, 0x8a, - 0xfe, 0x56, 0x04, 0x87, 0x06, 0x72, 0x10, 0x26, 0x06, 0x7f, 0x00, 0x00, - 0x10, 0x06, 0x06, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xb6, - 0xfe, 0x56, 0x04, 0x87, 0x06, 0x72, 0x10, 0x26, 0x06, 0xcf, 0x00, 0x00, - 0x10, 0x06, 0x06, 0x80, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xa2, - 0xfe, 0x56, 0x04, 0x87, 0x06, 0x72, 0x10, 0x26, 0x06, 0xcf, 0x00, 0x00, - 0x10, 0x06, 0x06, 0x81, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xf9, - 0xfe, 0x56, 0x04, 0x87, 0x07, 0xd1, 0x10, 0x26, 0x06, 0x82, 0x00, 0x00, - 0x10, 0x06, 0x06, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xae, - 0xfe, 0x56, 0x04, 0x87, 0x07, 0xd1, 0x10, 0x26, 0x06, 0x83, 0x00, 0x00, - 0x10, 0x06, 0x06, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xff, 0xe7, 0x04, 0x95, 0x06, 0x48, 0x10, 0x26, 0x02, 0x8e, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xf9, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xff, 0xe7, 0x04, 0x95, 0x05, 0xf6, 0x10, 0x26, 0x02, 0x8c, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xf9, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xfe, 0x56, 0x04, 0x95, 0x06, 0x66, 0x10, 0x26, 0x06, 0x84, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xcd, 0x9c, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xfe, 0x56, 0x04, 0x95, 0x04, 0x79, 0x10, 0x26, 0x02, 0xf9, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xcd, 0x9c, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xfe, 0x56, 0x04, 0x95, 0x06, 0x66, 0x10, 0x26, 0x02, 0xf4, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xcd, 0x9c, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xff, 0xe7, 0x04, 0x95, 0x06, 0x37, 0x10, 0x26, 0x02, 0xf9, 0x00, 0x00, - 0x10, 0x06, 0x06, 0xd1, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xfe, 0x56, 0x04, 0x95, 0x06, 0x37, 0x10, 0x26, 0x06, 0xc7, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xcd, 0x9c, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, - 0x00, 0x00, 0x04, 0xac, 0x07, 0x6d, 0x10, 0x26, 0x0c, 0xc6, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xda, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, - 0x00, 0x00, 0x04, 0xac, 0x07, 0x30, 0x10, 0x26, 0x0c, 0xcb, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xda, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x87, - 0x00, 0x00, 0x04, 0xac, 0x06, 0x66, 0x10, 0x26, 0x02, 0xda, 0x00, 0x00, - 0x10, 0x07, 0x06, 0xfc, 0xfe, 0x70, 0x00, 0x00, 0xff, 0xff, 0x00, 0x19, - 0x00, 0x00, 0x04, 0xac, 0x06, 0x66, 0x10, 0x06, 0x02, 0xd1, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x25, 0xfe, 0x56, 0x04, 0xac, 0x05, 0xd5, 0x10, 0x26, - 0x02, 0xda, 0x00, 0x00, 0x10, 0x06, 0x06, 0xcf, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x01, 0xef, 0x04, 0xc2, 0x02, 0xe1, 0x06, 0x72, 0x10, 0x06, - 0x06, 0xd0, 0x00, 0x00, 0xff, 0xff, 0x02, 0x1e, 0xfe, 0x56, 0x02, 0xfa, - 0xff, 0xa4, 0x10, 0x06, 0x02, 0xcd, 0x00, 0x00, 0x00, 0x01, 0x01, 0xef, - 0x04, 0xc2, 0x02, 0xe1, 0x06, 0x72, 0x00, 0x08, 0x00, 0x00, 0x01, 0x10, - 0x23, 0x35, 0x32, 0x35, 0x23, 0x35, 0x33, 0x02, 0xe1, 0xf1, 0x8e, 0x8e, - 0xf1, 0x05, 0xc3, 0xfe, 0xff, 0x64, 0x9d, 0xaf, 0xff, 0xff, 0x01, 0x1f, - 0x05, 0x1d, 0x03, 0xb2, 0x06, 0x37, 0x10, 0x06, 0x02, 0x79, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x1f, 0x05, 0x46, 0x03, 0xb2, 0x07, 0x8b, 0x10, 0x26, - 0x00, 0x6a, 0x00, 0x00, 0x10, 0x07, 0x06, 0xd1, 0x00, 0x00, 0x01, 0x54, - 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x56, 0x04, 0x1b, 0x06, 0x66, 0x10, 0x26, - 0x06, 0x88, 0x00, 0x00, 0x10, 0x07, 0x02, 0xcd, 0xfe, 0xc8, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x56, 0x04, 0x1b, 0x04, 0x7b, 0x10, 0x26, - 0x02, 0xff, 0x00, 0x00, 0x10, 0x07, 0x02, 0xcd, 0xfe, 0xc8, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x56, 0x04, 0x1b, 0x06, 0x66, 0x10, 0x26, - 0x02, 0xf6, 0x00, 0x00, 0x10, 0x07, 0x02, 0xcd, 0xfe, 0xc8, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x56, 0x04, 0x1b, 0x06, 0x37, 0x10, 0x26, - 0x02, 0xff, 0x00, 0x00, 0x10, 0x06, 0x06, 0xd1, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0xfe, 0x56, 0x04, 0x1b, 0x06, 0x37, 0x10, 0x26, - 0x06, 0xd6, 0x00, 0x00, 0x10, 0x07, 0x02, 0xcd, 0xfe, 0xc8, 0x00, 0x00, - 0xff, 0xff, 0xfe, 0x8d, 0x00, 0x00, 0x04, 0x4e, 0x06, 0x66, 0x10, 0x26, - 0x02, 0xde, 0x00, 0x00, 0x10, 0x07, 0x06, 0xfc, 0xfd, 0x76, 0x00, 0x00, - 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x04, 0x4e, 0x06, 0x66, 0x10, 0x06, - 0x02, 0xd3, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x5b, 0x00, 0x00, 0x04, 0x48, - 0x06, 0x66, 0x10, 0x26, 0x02, 0xe0, 0x00, 0x00, 0x10, 0x07, 0x06, 0xfc, - 0xfd, 0x44, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xed, 0x00, 0x00, 0x04, 0x48, - 0x06, 0x66, 0x10, 0x06, 0x02, 0xd4, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, - 0xfe, 0x56, 0x04, 0x48, 0x05, 0xd5, 0x10, 0x26, 0x02, 0xe0, 0x00, 0x00, - 0x10, 0x06, 0x06, 0xcf, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xf5, - 0x04, 0xc2, 0x03, 0xf0, 0x06, 0x72, 0x10, 0x27, 0x06, 0xd0, 0xff, 0x06, - 0x00, 0x00, 0x10, 0x07, 0x06, 0xfc, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x27, 0x04, 0xc2, 0x04, 0x1e, 0x06, 0x72, 0x10, 0x27, - 0x06, 0xd0, 0xff, 0x38, 0x00, 0x00, 0x10, 0x06, 0x07, 0x07, 0x64, 0x00, - 0xff, 0xff, 0x01, 0x1f, 0x04, 0xc2, 0x03, 0xb2, 0x07, 0xd1, 0x10, 0x26, - 0x06, 0xd0, 0x00, 0x00, 0x10, 0x07, 0x06, 0xd1, 0x00, 0x00, 0x01, 0x9a, - 0xff, 0xff, 0x01, 0x2f, 0x00, 0x00, 0x03, 0xcf, 0x06, 0x48, 0x10, 0x26, - 0x02, 0x8e, 0x00, 0x00, 0x10, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x36, 0x00, 0x00, 0x03, 0xcf, 0x05, 0xf6, 0x10, 0x26, - 0x02, 0x8c, 0x00, 0x00, 0x10, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x17, 0x00, 0x00, 0x03, 0xcf, 0x07, 0xd8, 0x10, 0x26, - 0x03, 0x01, 0x00, 0x00, 0x10, 0x06, 0x06, 0xfa, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x36, 0x00, 0x00, 0x03, 0xcf, 0x07, 0xd8, 0x10, 0x06, - 0x02, 0xd9, 0x00, 0x00, 0xff, 0xff, 0x01, 0x1f, 0x00, 0x00, 0x03, 0xcf, - 0x06, 0x37, 0x10, 0x26, 0x03, 0x01, 0x00, 0x00, 0x10, 0x06, 0x06, 0xd1, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x1f, 0x00, 0x00, 0x03, 0xcf, - 0x07, 0x8b, 0x10, 0x26, 0x03, 0x01, 0x00, 0x00, 0x10, 0x06, 0x06, 0xd2, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc9, 0x00, 0x00, 0x04, 0x06, - 0x07, 0x6d, 0x10, 0x26, 0x0c, 0xc6, 0x00, 0x00, 0x10, 0x06, 0x02, 0xe2, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc9, 0x00, 0x00, 0x04, 0x06, - 0x07, 0x30, 0x10, 0x26, 0x0c, 0xcb, 0x00, 0x00, 0x10, 0x06, 0x02, 0xe2, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xbf, 0x00, 0x00, 0x04, 0x06, - 0x06, 0x66, 0x10, 0x26, 0x02, 0xe2, 0x00, 0x00, 0x10, 0x07, 0x06, 0xfc, - 0xfd, 0xa8, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x04, 0x06, - 0x06, 0x66, 0x10, 0x06, 0x02, 0xd5, 0x00, 0x00, 0xff, 0xff, 0x00, 0xf5, - 0x04, 0xc2, 0x03, 0xf0, 0x06, 0x72, 0x10, 0x27, 0x07, 0x08, 0xff, 0x06, - 0x00, 0x00, 0x10, 0x07, 0x06, 0xfc, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x13, 0x04, 0xc2, 0x04, 0x1e, 0x06, 0x72, 0x10, 0x27, - 0x07, 0x08, 0xff, 0x24, 0x00, 0x00, 0x10, 0x06, 0x07, 0x07, 0x64, 0x00, - 0xff, 0xff, 0x01, 0x1f, 0x04, 0xc2, 0x03, 0xb2, 0x07, 0xd1, 0x10, 0x26, - 0x07, 0x08, 0x00, 0x00, 0x10, 0x07, 0x06, 0xd1, 0x00, 0x00, 0x01, 0x9a, - 0xff, 0xff, 0x00, 0x33, 0x00, 0x00, 0x04, 0x69, 0x06, 0x48, 0x10, 0x26, - 0x02, 0x8e, 0x00, 0x00, 0x10, 0x06, 0x03, 0x0d, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x33, 0x00, 0x00, 0x04, 0x69, 0x05, 0xf6, 0x10, 0x26, - 0x02, 0x8c, 0x00, 0x00, 0x10, 0x06, 0x03, 0x0d, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x33, 0x00, 0x00, 0x04, 0x69, 0x07, 0xd8, 0x10, 0x26, - 0x03, 0x0d, 0x00, 0x00, 0x10, 0x06, 0x06, 0xfa, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x33, 0x00, 0x00, 0x04, 0x69, 0x07, 0xd8, 0x10, 0x06, - 0x02, 0xf8, 0x00, 0x00, 0xff, 0xff, 0x00, 0xbe, 0xfe, 0x56, 0x04, 0x54, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x09, 0x00, 0x00, 0x10, 0x06, 0x06, 0xd0, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xbe, 0xfe, 0x56, 0x04, 0x54, - 0x06, 0x72, 0x10, 0x26, 0x03, 0x09, 0x00, 0x00, 0x10, 0x06, 0x07, 0x08, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x33, 0x00, 0x00, 0x04, 0x69, - 0x06, 0x37, 0x10, 0x26, 0x03, 0x0d, 0x00, 0x00, 0x10, 0x06, 0x06, 0xd1, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x33, 0x00, 0x00, 0x04, 0x69, - 0x07, 0x8b, 0x10, 0x26, 0x03, 0x0d, 0x00, 0x00, 0x10, 0x06, 0x06, 0xd2, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, - 0x07, 0x6d, 0x10, 0x26, 0x0c, 0xc6, 0x00, 0x00, 0x10, 0x06, 0x02, 0xed, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, - 0x07, 0x30, 0x10, 0x26, 0x0c, 0xcb, 0x00, 0x00, 0x10, 0x06, 0x02, 0xed, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x5b, 0x00, 0x00, 0x04, 0xac, - 0x06, 0x66, 0x10, 0x26, 0x02, 0xed, 0x00, 0x00, 0x10, 0x07, 0x06, 0xfc, - 0xfd, 0x44, 0x00, 0x00, 0xff, 0xff, 0xfe, 0x70, 0x00, 0x00, 0x04, 0xac, - 0x06, 0x66, 0x10, 0x06, 0x02, 0xd7, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7e, - 0x00, 0x00, 0x04, 0x75, 0x06, 0x72, 0x10, 0x26, 0x02, 0xea, 0x00, 0x00, - 0x10, 0x07, 0x07, 0x08, 0xfd, 0x8f, 0x00, 0x00, 0xff, 0xff, 0x01, 0x17, - 0x05, 0x46, 0x03, 0x91, 0x07, 0xd8, 0x10, 0x26, 0x00, 0x6a, 0x00, 0x00, - 0x10, 0x07, 0x06, 0xfc, 0x00, 0x00, 0x01, 0x72, 0xff, 0xff, 0x01, 0x3f, - 0x05, 0x46, 0x03, 0xba, 0x07, 0xd8, 0x10, 0x06, 0x02, 0xd0, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x17, 0x04, 0xee, 0x02, 0xf6, 0x06, 0x66, 0x10, 0x06, - 0x00, 0x43, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xfe, 0x56, 0x04, 0x8c, - 0x06, 0x66, 0x10, 0x26, 0x06, 0x90, 0x00, 0x00, 0x10, 0x06, 0x02, 0xcd, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xfe, 0x56, 0x04, 0x8c, - 0x04, 0x60, 0x10, 0x26, 0x03, 0x11, 0x00, 0x00, 0x10, 0x06, 0x02, 0xcd, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xfe, 0x56, 0x04, 0x8c, - 0x06, 0x66, 0x10, 0x26, 0x03, 0x16, 0x00, 0x00, 0x10, 0x06, 0x02, 0xcd, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xff, 0xe3, 0x04, 0x8c, - 0x06, 0x37, 0x10, 0x26, 0x03, 0x11, 0x00, 0x00, 0x10, 0x06, 0x06, 0xd1, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xfe, 0x56, 0x04, 0x8c, - 0x06, 0x37, 0x10, 0x26, 0x07, 0x00, 0x00, 0x00, 0x10, 0x06, 0x02, 0xcd, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xa6, 0xff, 0xe3, 0x04, 0x5c, - 0x06, 0x66, 0x10, 0x26, 0x02, 0xe8, 0x00, 0x00, 0x10, 0x07, 0x06, 0xfc, - 0xfd, 0x8f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xb5, 0xff, 0xe3, 0x04, 0x5c, - 0x06, 0x66, 0x10, 0x06, 0x02, 0xd6, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xa6, - 0x00, 0x00, 0x04, 0x87, 0x06, 0x66, 0x10, 0x26, 0x02, 0xf1, 0x00, 0x00, - 0x10, 0x07, 0x06, 0xfc, 0xfd, 0x8f, 0x00, 0x00, 0xff, 0xff, 0xff, 0xce, - 0x00, 0x00, 0x04, 0x87, 0x06, 0x66, 0x10, 0x06, 0x02, 0xd8, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x4a, 0xfe, 0x56, 0x04, 0x87, 0x05, 0xb4, 0x10, 0x26, - 0x02, 0xf1, 0x00, 0x00, 0x10, 0x06, 0x06, 0xcf, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x01, 0xdb, 0x04, 0xee, 0x03, 0xba, 0x06, 0x66, 0x10, 0x06, - 0x00, 0x76, 0x00, 0x00, 0x00, 0x01, 0x01, 0xef, 0x04, 0xc2, 0x02, 0xe1, - 0x06, 0x72, 0x00, 0x08, 0x00, 0x00, 0x01, 0x35, 0x33, 0x15, 0x23, 0x06, - 0x33, 0x15, 0x22, 0x01, 0xf0, 0xf0, 0x8d, 0x01, 0x8f, 0xf1, 0x05, 0xc3, - 0xaf, 0xaf, 0x9d, 0x64, 0x00, 0x01, 0x01, 0x64, 0x01, 0xdf, 0x03, 0x6d, - 0x02, 0x83, 0x00, 0x03, 0x00, 0x11, 0xb6, 0x00, 0xa0, 0x02, 0x04, 0x01, - 0x00, 0x04, 0x10, 0xd4, 0xc4, 0x31, 0x00, 0x10, 0xd4, 0xec, 0x30, 0x01, - 0x21, 0x15, 0x21, 0x01, 0x64, 0x02, 0x09, 0xfd, 0xf7, 0x02, 0x83, 0xa4, - 0xff, 0xff, 0x01, 0x64, 0x01, 0xdf, 0x03, 0x6d, 0x02, 0x83, 0x10, 0x06, - 0x07, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0xec, 0x04, 0xd1, - 0x02, 0x79, 0x00, 0x03, 0x00, 0x10, 0xb6, 0x02, 0xb6, 0x00, 0xfd, 0x04, - 0x01, 0x00, 0x2f, 0xc6, 0x31, 0x00, 0x10, 0xfc, 0xec, 0x30, 0x11, 0x21, - 0x15, 0x21, 0x04, 0xd1, 0xfb, 0x2f, 0x02, 0x79, 0x8d, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x01, 0xec, 0x04, 0xd1, 0x02, 0x79, 0x00, 0x03, - 0x00, 0x10, 0xb6, 0x02, 0xb6, 0x00, 0xfd, 0x04, 0x01, 0x00, 0x2f, 0xc6, - 0x31, 0x00, 0x10, 0xfc, 0xec, 0x30, 0x11, 0x21, 0x15, 0x21, 0x04, 0xd1, - 0xfb, 0x2f, 0x02, 0x79, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x01, 0xec, 0x04, 0xd1, 0x02, 0x79, 0x00, 0x03, 0x00, 0x0f, 0xb5, 0x02, - 0xb6, 0x00, 0x04, 0x01, 0x00, 0x2f, 0xc4, 0x31, 0x00, 0x10, 0xd4, 0xec, - 0x30, 0x11, 0x21, 0x15, 0x21, 0x04, 0xd1, 0xfb, 0x2f, 0x02, 0x79, 0x8d, - 0x00, 0x01, 0x00, 0x00, 0x01, 0xec, 0x04, 0xd1, 0x02, 0x79, 0x00, 0x03, - 0x00, 0x0f, 0xb5, 0x02, 0xb6, 0x00, 0x04, 0x01, 0x00, 0x2f, 0xc4, 0x31, - 0x00, 0x10, 0xd4, 0xec, 0x30, 0x11, 0x21, 0x15, 0x21, 0x04, 0xd1, 0xfb, - 0x2f, 0x02, 0x79, 0x8d, 0xff, 0xff, 0x01, 0x1d, 0xfe, 0x1d, 0x03, 0xb3, - 0x06, 0x1d, 0x10, 0x27, 0x00, 0x5f, 0x00, 0xf5, 0x00, 0x00, 0x10, 0x07, - 0x00, 0x5f, 0xff, 0x0b, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0xfe, 0x1d, 0x04, 0xd1, 0xff, 0x5d, 0x10, 0x26, 0x00, 0x42, 0x00, 0x00, - 0x10, 0x07, 0x00, 0x42, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x01, 0x01, 0xcf, - 0x03, 0xc7, 0x03, 0x2d, 0x06, 0x14, 0x00, 0x05, 0x00, 0x18, 0x40, 0x0b, - 0x00, 0xa3, 0x03, 0xb5, 0x06, 0x03, 0x04, 0x00, 0x1d, 0x01, 0x06, 0x10, - 0xd4, 0xfc, 0xd4, 0xcc, 0x31, 0x00, 0x10, 0xfc, 0xec, 0x30, 0x01, 0x23, - 0x35, 0x13, 0x33, 0x03, 0x02, 0xcb, 0xfc, 0xc4, 0x9a, 0x62, 0x03, 0xc7, - 0xcf, 0x01, 0x7e, 0xfe, 0x82, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0xcf, - 0x03, 0xc7, 0x03, 0x2d, 0x06, 0x14, 0x00, 0x05, 0x00, 0x18, 0x40, 0x0b, - 0x03, 0xa3, 0x00, 0xb5, 0x06, 0x03, 0x04, 0x01, 0x1d, 0x00, 0x06, 0x10, - 0xd4, 0xec, 0xd4, 0xcc, 0x31, 0x00, 0x10, 0xfc, 0xec, 0x30, 0x01, 0x33, - 0x15, 0x03, 0x23, 0x13, 0x02, 0x31, 0xfc, 0xc5, 0x99, 0x62, 0x06, 0x14, - 0xce, 0xfe, 0x81, 0x01, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x93, - 0xfe, 0xe1, 0x02, 0xf2, 0x01, 0x2f, 0x00, 0x05, 0x00, 0x1a, 0xb2, 0x03, - 0xa3, 0x00, 0xb8, 0x01, 0x01, 0xb6, 0x06, 0x03, 0x04, 0x01, 0x1d, 0x00, - 0x06, 0x10, 0xd4, 0xec, 0xd4, 0xcc, 0x31, 0x00, 0x10, 0xfc, 0xec, 0x30, - 0x01, 0x33, 0x15, 0x03, 0x23, 0x13, 0x01, 0xf6, 0xfc, 0xc5, 0x9a, 0x63, - 0x01, 0x2f, 0xcf, 0xfe, 0x81, 0x01, 0x7f, 0x00, 0x00, 0x01, 0x01, 0xcf, - 0x03, 0xc7, 0x03, 0x2d, 0x06, 0x14, 0x00, 0x05, 0x00, 0x00, 0x01, 0x15, - 0x13, 0x23, 0x03, 0x35, 0x02, 0xcb, 0x62, 0x99, 0xc5, 0x06, 0x14, 0xce, - 0xfe, 0x81, 0x01, 0x7f, 0xce, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xd3, - 0x03, 0xc7, 0x03, 0xfe, 0x06, 0x14, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x25, - 0x40, 0x12, 0x06, 0x00, 0xa3, 0x09, 0x03, 0xb5, 0x0c, 0x03, 0x04, 0x00, - 0x1d, 0x01, 0x07, 0x1d, 0x06, 0x09, 0x0a, 0x0c, 0x10, 0xd4, 0xcc, 0xd4, - 0xec, 0xd4, 0xfc, 0xd4, 0xcc, 0x31, 0x00, 0x10, 0xfc, 0x3c, 0xec, 0x32, - 0x30, 0x01, 0x23, 0x35, 0x13, 0x33, 0x03, 0x05, 0x23, 0x35, 0x13, 0x33, - 0x03, 0x03, 0x9c, 0xfc, 0xc4, 0x9a, 0x62, 0xfe, 0x35, 0xfe, 0xc7, 0x99, - 0x62, 0x03, 0xc7, 0xcf, 0x01, 0x7e, 0xfe, 0x82, 0xcf, 0xcf, 0x01, 0x7e, - 0xfe, 0x82, 0x00, 0x00, 0x00, 0x02, 0x00, 0xd3, 0x03, 0xc7, 0x03, 0xfc, - 0x06, 0x14, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x27, 0x40, 0x13, 0x09, 0x03, - 0xa3, 0x06, 0x00, 0xb5, 0x0c, 0x09, 0x0a, 0x06, 0x03, 0x04, 0x01, 0x1d, - 0x00, 0x06, 0x1d, 0x07, 0x0c, 0x10, 0xd4, 0xec, 0xd4, 0xec, 0xd4, 0xcc, - 0x10, 0xd4, 0xce, 0x31, 0x00, 0x10, 0xfc, 0x3c, 0xec, 0x32, 0x30, 0x01, - 0x33, 0x15, 0x03, 0x23, 0x13, 0x25, 0x33, 0x15, 0x03, 0x23, 0x13, 0x03, - 0x00, 0xfc, 0xc5, 0x99, 0x62, 0xfe, 0x35, 0xfc, 0xc4, 0x9a, 0x62, 0x06, - 0x14, 0xce, 0xfe, 0x81, 0x01, 0x7f, 0xce, 0xce, 0xfe, 0x81, 0x01, 0x7f, - 0x00, 0x02, 0x00, 0xd3, 0xfe, 0xe1, 0x03, 0xfc, 0x01, 0x2f, 0x00, 0x05, - 0x00, 0x0b, 0x00, 0x2a, 0xb4, 0x09, 0x03, 0xa3, 0x06, 0x00, 0xb8, 0x01, - 0x01, 0x40, 0x0d, 0x0c, 0x09, 0x0a, 0x06, 0x03, 0x04, 0x01, 0x1d, 0x00, - 0x06, 0x1d, 0x07, 0x0c, 0x10, 0xd4, 0xec, 0xd4, 0xec, 0xd4, 0xcc, 0x10, - 0xd4, 0xce, 0x31, 0x00, 0x10, 0xfc, 0x3c, 0xec, 0x32, 0x30, 0x01, 0x33, - 0x15, 0x03, 0x23, 0x13, 0x25, 0x33, 0x15, 0x03, 0x23, 0x13, 0x03, 0x00, - 0xfc, 0xc5, 0x99, 0x62, 0xfe, 0x35, 0xfc, 0xc4, 0x9a, 0x62, 0x01, 0x2f, - 0xcf, 0xfe, 0x81, 0x01, 0x7f, 0xcf, 0xcf, 0xfe, 0x81, 0x01, 0x7f, 0x00, - 0x00, 0x02, 0x00, 0xd3, 0x03, 0xc7, 0x03, 0xfc, 0x06, 0x14, 0x00, 0x05, - 0x00, 0x0b, 0x00, 0x00, 0x01, 0x15, 0x13, 0x23, 0x03, 0x35, 0x21, 0x15, - 0x13, 0x23, 0x03, 0x35, 0x01, 0xcf, 0x62, 0x99, 0xc5, 0x02, 0xc7, 0x62, - 0x9a, 0xc4, 0x06, 0x14, 0xce, 0xfe, 0x81, 0x01, 0x7f, 0xce, 0xce, 0xfe, - 0x81, 0x01, 0x7f, 0xce, 0x00, 0x01, 0x00, 0xa2, 0xff, 0x3b, 0x04, 0x2f, - 0x05, 0xd5, 0x00, 0x0b, 0x00, 0x27, 0x40, 0x14, 0x08, 0x04, 0xcb, 0x0a, - 0x02, 0x00, 0x88, 0x06, 0xca, 0x0c, 0x03, 0x52, 0x05, 0x01, 0x51, 0x09, - 0x52, 0x07, 0x00, 0x0c, 0x10, 0xd4, 0x3c, 0xec, 0xfc, 0x3c, 0xec, 0x31, - 0x00, 0x10, 0xe4, 0xf4, 0xd4, 0x3c, 0xec, 0x32, 0x30, 0x01, 0x33, 0x11, - 0x21, 0x15, 0x21, 0x11, 0x23, 0x11, 0x21, 0x35, 0x21, 0x02, 0x10, 0xb1, - 0x01, 0x6e, 0xfe, 0x92, 0xb1, 0xfe, 0x92, 0x01, 0x6e, 0x05, 0xd5, 0xfe, - 0x5c, 0x99, 0xfb, 0xa3, 0x04, 0x5d, 0x99, 0x00, 0x00, 0x01, 0x00, 0xa2, - 0xff, 0x3b, 0x04, 0x2f, 0x05, 0xd5, 0x00, 0x13, 0x00, 0x3c, 0x40, 0x1f, - 0x12, 0x06, 0xcb, 0x00, 0x10, 0x08, 0xcb, 0x0e, 0x0a, 0x0c, 0x04, 0x00, - 0x02, 0xca, 0x0c, 0x88, 0x14, 0x0f, 0x00, 0x52, 0x11, 0x0d, 0x01, 0x51, - 0x09, 0x05, 0x52, 0x0b, 0x07, 0x03, 0x14, 0x10, 0xd4, 0x3c, 0x3c, 0xec, - 0x32, 0xfc, 0x3c, 0x3c, 0xec, 0x32, 0x31, 0x00, 0x10, 0xe4, 0xf4, 0xc4, - 0x32, 0x10, 0xd4, 0x3c, 0xee, 0x32, 0x10, 0xee, 0x32, 0x30, 0x25, 0x21, - 0x11, 0x23, 0x11, 0x21, 0x35, 0x21, 0x11, 0x21, 0x35, 0x21, 0x11, 0x33, - 0x11, 0x21, 0x15, 0x21, 0x11, 0x21, 0x04, 0x2f, 0xfe, 0x92, 0xb1, 0xfe, - 0x92, 0x01, 0x6e, 0xfe, 0x92, 0x01, 0x6e, 0xb1, 0x01, 0x6e, 0xfe, 0x92, - 0x01, 0x6e, 0xdf, 0xfe, 0x5c, 0x01, 0xa4, 0x9a, 0x02, 0x1f, 0x99, 0x01, - 0xa4, 0xfe, 0x5c, 0x99, 0xfd, 0xe1, 0x00, 0x00, 0x00, 0x01, 0x01, 0x3f, - 0x01, 0xd1, 0x03, 0x91, 0x04, 0x21, 0x00, 0x0b, 0x00, 0x12, 0xb7, 0x09, - 0xd0, 0x03, 0x0c, 0x06, 0x56, 0x00, 0x0c, 0x10, 0xd4, 0xec, 0x31, 0x00, - 0x10, 0xd4, 0xe4, 0x30, 0x01, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, - 0x06, 0x23, 0x22, 0x26, 0x01, 0x3f, 0xac, 0x7d, 0x7c, 0xad, 0xae, 0x7d, - 0x7c, 0xab, 0x02, 0xfa, 0x7c, 0xab, 0xac, 0x7b, 0x7c, 0xad, 0xab, 0x00, - 0x00, 0x01, 0x01, 0x3f, 0x01, 0x81, 0x03, 0xe1, 0x04, 0x71, 0x00, 0x02, - 0x00, 0x00, 0x01, 0x11, 0x01, 0x01, 0x3f, 0x02, 0xa2, 0x01, 0x81, 0x02, - 0xf0, 0xfe, 0x88, 0x00, 0x00, 0x03, 0x00, 0x50, 0x00, 0x00, 0x04, 0x7f, - 0x01, 0x31, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x23, 0x40, 0x11, - 0x08, 0x04, 0x00, 0xa2, 0x0a, 0x06, 0x02, 0x04, 0x1d, 0x05, 0x08, 0x1d, - 0x09, 0x01, 0x1d, 0x00, 0x0c, 0x10, 0xd4, 0xfc, 0xd4, 0xec, 0xd4, 0xec, - 0x31, 0x00, 0x2f, 0x3c, 0x3c, 0xec, 0x32, 0x32, 0x30, 0x13, 0x33, 0x11, - 0x23, 0x01, 0x33, 0x11, 0x23, 0x01, 0x33, 0x11, 0x23, 0x50, 0xfc, 0xfc, - 0x03, 0x33, 0xfc, 0xfc, 0xfe, 0x66, 0xfc, 0xfc, 0x01, 0x31, 0xfe, 0xcf, - 0x01, 0x31, 0xfe, 0xcf, 0x01, 0x31, 0xfe, 0xcf, 0x00, 0x07, 0x00, 0x00, - 0x00, 0x00, 0x04, 0xd1, 0x05, 0x98, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x1b, - 0x00, 0x27, 0x00, 0x33, 0x00, 0x3f, 0x00, 0x4b, 0x00, 0x74, 0x40, 0x0e, - 0x03, 0x02, 0x25, 0x1f, 0x01, 0x31, 0x00, 0x3d, 0x0d, 0xc8, 0x13, 0x1f, - 0xc8, 0x31, 0xb8, 0x01, 0x02, 0xb5, 0x25, 0xc8, 0x2b, 0x91, 0x43, 0x13, - 0xb8, 0x01, 0x02, 0x40, 0x26, 0x37, 0x07, 0xc8, 0x49, 0x19, 0x03, 0x46, - 0x02, 0x3a, 0x34, 0x01, 0x28, 0x00, 0x1c, 0x10, 0x3a, 0x50, 0x46, 0x7a, - 0x34, 0x50, 0x40, 0x0a, 0x50, 0x16, 0x7a, 0x04, 0x50, 0x10, 0x22, 0x50, - 0x2e, 0x7a, 0x10, 0x1c, 0x50, 0x40, 0x28, 0x2f, 0xc4, 0xec, 0xc4, 0xf4, - 0xec, 0x10, 0xee, 0xf6, 0xee, 0x10, 0xee, 0xf6, 0xee, 0x11, 0x12, 0x39, - 0x12, 0x39, 0x11, 0x12, 0x39, 0x11, 0x39, 0x31, 0x00, 0x2f, 0x3c, 0xee, - 0x32, 0xee, 0x32, 0xf6, 0xee, 0xfe, 0xee, 0x10, 0xee, 0x32, 0x39, 0x12, - 0x39, 0x11, 0x12, 0x39, 0x39, 0x30, 0x13, 0x27, 0x01, 0x17, 0x01, 0x14, - 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x34, - 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x13, 0x14, - 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x34, - 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x01, 0x14, - 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x34, - 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x48, 0x25, - 0x04, 0x14, 0x27, 0xfc, 0x48, 0x5f, 0x45, 0x44, 0x62, 0x63, 0x43, 0x45, - 0x5f, 0x79, 0xa5, 0x78, 0x78, 0xa6, 0xa7, 0x77, 0x79, 0xa4, 0x4c, 0x61, - 0x45, 0x45, 0x61, 0x63, 0x43, 0x45, 0x61, 0x79, 0xa6, 0x79, 0x78, 0xa6, - 0xa6, 0x78, 0x79, 0xa6, 0x03, 0x0c, 0x61, 0x45, 0x46, 0x60, 0x62, 0x44, - 0x45, 0x61, 0x79, 0xa6, 0x79, 0x78, 0xa7, 0xa7, 0x78, 0x79, 0xa6, 0x02, - 0x37, 0x61, 0x01, 0x9f, 0x60, 0xfd, 0x4a, 0x47, 0x61, 0x63, 0x45, 0x43, - 0x63, 0x61, 0x45, 0x79, 0xa5, 0xa6, 0x78, 0x79, 0xa8, 0xa6, 0x03, 0xd3, - 0x45, 0x61, 0x61, 0x45, 0x43, 0x63, 0x61, 0x45, 0x78, 0xa7, 0xa7, 0x78, - 0x79, 0xa8, 0xa7, 0xfd, 0x22, 0x47, 0x61, 0x61, 0x47, 0x43, 0x63, 0x61, - 0x45, 0x78, 0xa6, 0xa6, 0x78, 0x79, 0xa8, 0xa7, 0x00, 0x07, 0x00, 0x00, - 0x00, 0x00, 0x04, 0xd1, 0x05, 0x98, 0x00, 0x0b, 0x00, 0x15, 0x00, 0x19, - 0x00, 0x44, 0x00, 0x50, 0x00, 0x5c, 0x00, 0x68, 0x00, 0x00, 0x11, 0x34, - 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x36, 0x14, - 0x16, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x03, 0x27, 0x01, 0x17, - 0x01, 0x34, 0x36, 0x32, 0x17, 0x16, 0x17, 0x36, 0x37, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x17, 0x36, 0x37, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x27, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, - 0x27, 0x06, 0x07, 0x06, 0x23, 0x22, 0x26, 0x37, 0x14, 0x16, 0x33, 0x32, - 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x05, 0x14, 0x16, 0x33, 0x32, - 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x05, 0x14, 0x16, 0x33, 0x32, - 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0xa6, 0x79, 0x78, 0xa6, 0xa6, - 0x78, 0x79, 0xa6, 0x79, 0x61, 0x8a, 0x61, 0x63, 0x43, 0x45, 0x92, 0x25, - 0x04, 0x14, 0x27, 0xfb, 0xa2, 0x8a, 0xc8, 0x45, 0x0a, 0x09, 0x09, 0x0a, - 0x46, 0x65, 0x64, 0x45, 0x0b, 0x08, 0x09, 0x0a, 0x46, 0x65, 0x64, 0x8b, - 0x8b, 0x64, 0x65, 0x46, 0x0a, 0x09, 0x08, 0x0b, 0x45, 0x64, 0x65, 0x46, - 0x0a, 0x09, 0x09, 0x0a, 0x46, 0x63, 0x65, 0x89, 0x65, 0x4f, 0x3a, 0x38, - 0x52, 0x52, 0x38, 0x3a, 0x4f, 0x01, 0x78, 0x51, 0x3a, 0x3a, 0x50, 0x52, - 0x38, 0x3a, 0x51, 0x01, 0x7a, 0x51, 0x3a, 0x3a, 0x50, 0x52, 0x38, 0x3a, - 0x51, 0x04, 0x79, 0x78, 0xa7, 0xa7, 0x78, 0x79, 0xa8, 0xa7, 0xbf, 0x8a, - 0x61, 0x61, 0x45, 0x43, 0x63, 0xfd, 0x18, 0x61, 0x01, 0x9f, 0x60, 0xfd, - 0x4a, 0x79, 0xa5, 0x53, 0x0c, 0x0e, 0x0e, 0x0c, 0x53, 0x53, 0x0c, 0x0d, - 0x0d, 0x0c, 0x53, 0xa6, 0x78, 0x79, 0xa8, 0x54, 0x0c, 0x0d, 0x0d, 0x0c, - 0x54, 0x54, 0x0c, 0x0e, 0x0d, 0x0d, 0x54, 0xa6, 0x7b, 0x47, 0x61, 0x63, - 0x45, 0x43, 0x63, 0x61, 0x45, 0x47, 0x61, 0x61, 0x47, 0x43, 0x63, 0x61, - 0x45, 0x47, 0x61, 0x61, 0x47, 0x43, 0x63, 0x61, 0x00, 0x01, 0x01, 0xac, - 0x04, 0x60, 0x03, 0x24, 0x05, 0xd5, 0x00, 0x03, 0x00, 0x00, 0x01, 0x13, - 0x33, 0x01, 0x01, 0xac, 0xae, 0xca, 0xfe, 0xe0, 0x04, 0x60, 0x01, 0x75, - 0xfe, 0x8b, 0x00, 0x00, 0xff, 0xff, 0x01, 0x16, 0x04, 0x60, 0x03, 0xba, - 0x05, 0xd5, 0x10, 0x27, 0x07, 0x2c, 0x00, 0x96, 0x00, 0x00, 0x10, 0x07, - 0x07, 0x2c, 0xff, 0x6a, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x80, - 0x04, 0x60, 0x04, 0x50, 0x05, 0xd5, 0x10, 0x27, 0x07, 0x2c, 0x01, 0x2c, - 0x00, 0x00, 0x10, 0x27, 0x07, 0x2c, 0xfe, 0xd4, 0x00, 0x00, 0x10, 0x06, - 0x07, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x01, 0xac, 0x04, 0x60, 0x03, 0x24, - 0x05, 0xd5, 0x00, 0x03, 0x00, 0x00, 0x01, 0x23, 0x01, 0x33, 0x03, 0x24, - 0x56, 0xfe, 0xde, 0xcc, 0x04, 0x60, 0x01, 0x75, 0xff, 0xff, 0x01, 0x16, - 0x04, 0x60, 0x03, 0xba, 0x05, 0xd5, 0x10, 0x27, 0x07, 0x2f, 0x00, 0x96, - 0x00, 0x00, 0x10, 0x07, 0x07, 0x2f, 0xff, 0x6a, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x80, 0x04, 0x60, 0x04, 0x50, 0x05, 0xd5, 0x10, 0x26, - 0x07, 0x2f, 0x00, 0x00, 0x10, 0x27, 0x07, 0x2f, 0x01, 0x2c, 0x00, 0x00, - 0x10, 0x07, 0x07, 0x2f, 0xfe, 0xd4, 0x00, 0x00, 0x00, 0x01, 0x01, 0x5a, - 0x00, 0x8d, 0x03, 0x2f, 0x04, 0x23, 0x00, 0x06, 0x00, 0x1a, 0x40, 0x0c, - 0x02, 0x04, 0xfc, 0x00, 0xac, 0x07, 0x02, 0x03, 0x00, 0x76, 0x05, 0x07, - 0x10, 0xd4, 0xec, 0x32, 0x39, 0x31, 0x00, 0x10, 0xf4, 0xec, 0x39, 0x30, - 0x01, 0x15, 0x09, 0x01, 0x15, 0x01, 0x35, 0x03, 0x2f, 0xfe, 0xd3, 0x01, - 0x2d, 0xfe, 0x2b, 0x04, 0x23, 0xbf, 0xfe, 0xf4, 0xfe, 0xf4, 0xbf, 0x01, - 0xa2, 0x52, 0x00, 0x00, 0x00, 0x01, 0x01, 0xa4, 0x00, 0x8d, 0x03, 0x79, - 0x04, 0x23, 0x00, 0x06, 0x00, 0x1a, 0x40, 0x0c, 0x05, 0x03, 0xfc, 0x00, - 0xac, 0x07, 0x05, 0x01, 0x76, 0x03, 0x00, 0x07, 0x10, 0xd4, 0x3c, 0xec, - 0x39, 0x31, 0x00, 0x10, 0xf4, 0xec, 0x39, 0x30, 0x09, 0x01, 0x15, 0x01, - 0x35, 0x09, 0x01, 0x01, 0xa4, 0x01, 0xd5, 0xfe, 0x2b, 0x01, 0x2d, 0xfe, - 0xd3, 0x04, 0x23, 0xfe, 0x5e, 0x52, 0xfe, 0x5e, 0xbf, 0x01, 0x0c, 0x01, - 0x0c, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xd0, 0x00, 0x00, 0x04, 0x03, - 0x05, 0xd5, 0x10, 0x27, 0x00, 0x04, 0xfe, 0xcc, 0x00, 0x00, 0x10, 0x07, - 0x00, 0x04, 0x01, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xf4, - 0x00, 0x00, 0x04, 0x10, 0x05, 0xf0, 0x00, 0x17, 0x00, 0x1b, 0x00, 0x25, - 0x00, 0x00, 0x01, 0x23, 0x11, 0x06, 0x07, 0x06, 0x07, 0x35, 0x36, 0x37, - 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x0f, 0x01, 0x0e, - 0x01, 0x15, 0x03, 0x35, 0x33, 0x15, 0x03, 0x11, 0x37, 0x36, 0x37, 0x36, - 0x35, 0x34, 0x27, 0x26, 0x02, 0xac, 0xbe, 0x1f, 0x20, 0x59, 0x62, 0x5e, - 0x60, 0x5f, 0x68, 0xba, 0x6f, 0x6e, 0x22, 0x21, 0x5e, 0x58, 0x45, 0x26, - 0xc5, 0xcb, 0x06, 0x2d, 0x3e, 0x17, 0x18, 0x42, 0x25, 0x01, 0x91, 0x03, - 0xad, 0x08, 0x0c, 0x23, 0x44, 0xbc, 0x39, 0x1c, 0x1c, 0x60, 0x60, 0xa1, - 0x4c, 0x41, 0x42, 0x5c, 0x56, 0x42, 0x54, 0x3d, 0xfd, 0xc5, 0xfe, 0xfe, - 0x05, 0x42, 0xfe, 0x52, 0x2d, 0x3b, 0x2c, 0x2c, 0x31, 0x59, 0x37, 0x1f, - 0xff, 0xff, 0x00, 0x00, 0x05, 0xbb, 0x04, 0xd1, 0x06, 0x0b, 0x10, 0x07, - 0x00, 0x42, 0x00, 0x00, 0x07, 0x9e, 0x00, 0x00, 0x00, 0x01, 0x01, 0xcf, - 0xfe, 0xf2, 0x03, 0x77, 0x06, 0x14, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x21, - 0x15, 0x23, 0x11, 0x33, 0x15, 0x23, 0x11, 0x33, 0x15, 0x21, 0x01, 0xcf, - 0x01, 0xa8, 0xf0, 0xf0, 0xf0, 0xf0, 0xfe, 0x58, 0x06, 0x14, 0x8f, 0xfd, - 0x45, 0x8f, 0xfd, 0x46, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x5a, - 0xfe, 0xf2, 0x03, 0x02, 0x06, 0x14, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x35, 0x33, 0x11, 0x23, 0x35, 0x33, 0x11, 0x23, 0x35, 0x03, 0x02, - 0xfe, 0x58, 0xf0, 0xf0, 0xf0, 0xf0, 0x06, 0x14, 0xf8, 0xde, 0x8f, 0x02, - 0xba, 0x8f, 0x02, 0xbb, 0x8f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x21, - 0x00, 0x00, 0x04, 0xb1, 0x05, 0xf0, 0x10, 0x27, 0x0c, 0xca, 0xfe, 0xbc, - 0x00, 0x00, 0x10, 0x07, 0x0c, 0xca, 0x01, 0x1c, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x21, 0x00, 0x00, 0x04, 0x03, 0x05, 0xf0, 0x10, 0x27, - 0x0c, 0xca, 0xfe, 0xbc, 0x00, 0x00, 0x10, 0x07, 0x00, 0x04, 0x01, 0x34, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xd0, 0x00, 0x00, 0x04, 0xb1, - 0x05, 0xf0, 0x10, 0x27, 0x00, 0x04, 0xfe, 0xcc, 0x00, 0x00, 0x10, 0x07, - 0x0c, 0xca, 0x01, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xcb, - 0xff, 0x3b, 0x04, 0x67, 0x05, 0xd5, 0x00, 0x0d, 0x00, 0x00, 0x01, 0x32, - 0x04, 0x15, 0x14, 0x06, 0x07, 0x11, 0x23, 0x11, 0x23, 0x11, 0x23, 0x11, - 0x02, 0x8b, 0xd7, 0x01, 0x05, 0xec, 0xd7, 0x8d, 0xbf, 0x8d, 0x05, 0xd5, - 0xe8, 0xbe, 0xb8, 0xdd, 0x11, 0xfc, 0xb2, 0x06, 0x1f, 0xf9, 0xe1, 0x06, - 0x9a, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x3d, 0x02, 0x8d, 0x03, 0x95, - 0x05, 0xf0, 0x00, 0x0c, 0x00, 0x1c, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x34, - 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x22, 0x13, - 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, - 0x34, 0x27, 0x26, 0x27, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, - 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x02, 0x16, 0x18, 0x17, 0x22, - 0x25, 0x17, 0x18, 0x18, 0x19, 0x46, 0x24, 0x57, 0x2b, 0x2c, 0x2c, 0x2b, - 0x57, 0x58, 0x2b, 0x2c, 0x2c, 0x2b, 0x58, 0x95, 0x4c, 0x4c, 0x4c, 0x4c, - 0x95, 0x96, 0x4a, 0x4b, 0x4b, 0x4c, 0x04, 0x20, 0x40, 0x17, 0x16, 0x16, - 0x17, 0x20, 0x21, 0x14, 0x15, 0x01, 0xa1, 0x55, 0x55, 0xaf, 0xae, 0x55, - 0x55, 0x55, 0x55, 0xae, 0xaf, 0x55, 0x55, 0x59, 0x6e, 0x6d, 0xd7, 0xd6, - 0x6e, 0x6d, 0x6d, 0x6e, 0xd6, 0xd7, 0x6d, 0x6e, 0x00, 0x02, 0x01, 0x48, - 0x02, 0x9c, 0x03, 0x88, 0x06, 0x03, 0x00, 0x09, 0x00, 0x0d, 0x00, 0x00, - 0x01, 0x21, 0x11, 0x33, 0x15, 0x21, 0x35, 0x33, 0x11, 0x23, 0x13, 0x33, - 0x15, 0x23, 0x01, 0x7a, 0x01, 0x28, 0xe6, 0xfd, 0xc0, 0xe6, 0xb4, 0xb4, - 0x74, 0x74, 0x05, 0x0f, 0xfd, 0xdd, 0x50, 0x50, 0x01, 0xd3, 0x01, 0x44, - 0x82, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x0c, 0x02, 0x9c, 0x03, 0x8d, - 0x05, 0xdf, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x35, 0xb3, 0x0b, 0x00, 0x0c, - 0x02, 0xb8, 0x01, 0x09, 0xb2, 0x08, 0x04, 0x06, 0xba, 0x01, 0x0a, 0x00, - 0x00, 0x01, 0x15, 0x40, 0x0b, 0x0e, 0x0c, 0x09, 0x0b, 0x07, 0x57, 0x03, - 0x05, 0x01, 0x09, 0x0e, 0x10, 0xd4, 0xd4, 0x3c, 0xc4, 0xec, 0x32, 0x11, - 0x39, 0x31, 0x00, 0x10, 0xf4, 0xf4, 0xd4, 0x3c, 0xec, 0x32, 0x11, 0x39, - 0x30, 0x01, 0x33, 0x11, 0x33, 0x15, 0x23, 0x15, 0x23, 0x35, 0x21, 0x35, - 0x09, 0x01, 0x21, 0x02, 0x77, 0xa2, 0x74, 0x74, 0x8a, 0xfe, 0x7d, 0x01, - 0x83, 0xfe, 0xee, 0x01, 0x12, 0x05, 0xdf, 0xfd, 0xe6, 0x6f, 0xba, 0xba, - 0x79, 0x01, 0x93, 0xfe, 0x63, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x3f, - 0x02, 0x8d, 0x03, 0x7d, 0x05, 0xdf, 0x00, 0x21, 0x00, 0x00, 0x01, 0x21, - 0x15, 0x21, 0x15, 0x3e, 0x01, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, - 0x06, 0x23, 0x22, 0x26, 0x27, 0x35, 0x16, 0x17, 0x16, 0x33, 0x32, 0x36, - 0x35, 0x34, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x01, 0x66, 0x01, 0xd6, - 0xfe, 0x9d, 0x1a, 0x36, 0x1c, 0x90, 0x54, 0x54, 0x58, 0x59, 0x99, 0x4a, - 0x7a, 0x30, 0x34, 0x3f, 0x39, 0x3c, 0x68, 0x70, 0x74, 0x67, 0x33, 0x2f, - 0x30, 0x2c, 0x05, 0xdf, 0x5f, 0xcc, 0x09, 0x08, 0x4d, 0x4c, 0x83, 0x84, - 0x4c, 0x4c, 0x12, 0x12, 0x72, 0x1a, 0x0f, 0x0e, 0x62, 0x5b, 0x59, 0x64, - 0x0a, 0x0b, 0x14, 0x00, 0x00, 0x02, 0x01, 0x49, 0x02, 0x8d, 0x03, 0xa1, - 0x05, 0xf0, 0x00, 0x1d, 0x00, 0x29, 0x00, 0x00, 0x01, 0x15, 0x2e, 0x01, - 0x23, 0x22, 0x07, 0x06, 0x15, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x03, 0x22, 0x06, 0x14, 0x16, 0x33, 0x32, 0x37, 0x36, 0x34, - 0x27, 0x26, 0x03, 0x5d, 0x27, 0x58, 0x30, 0x77, 0x3e, 0x3d, 0x20, 0x32, - 0x35, 0x44, 0x87, 0x49, 0x4a, 0x4c, 0x4c, 0x89, 0xa1, 0x96, 0xb4, 0xab, - 0x2e, 0x2e, 0x2e, 0xb4, 0x50, 0x5c, 0x5c, 0x50, 0x53, 0x2a, 0x2a, 0x2a, - 0x2a, 0x05, 0xcf, 0x68, 0x14, 0x16, 0x51, 0x51, 0x9e, 0x3b, 0x1c, 0x1e, - 0x4a, 0x4a, 0x89, 0x87, 0x4b, 0x4a, 0xd0, 0xe1, 0xd4, 0xde, 0x09, 0x08, - 0xfe, 0x8e, 0x68, 0xb8, 0x68, 0x32, 0x31, 0xc2, 0x31, 0x32, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x3d, 0x02, 0x9c, 0x03, 0x85, 0x05, 0xdf, 0x00, 0x06, - 0x00, 0x00, 0x01, 0x21, 0x15, 0x01, 0x23, 0x01, 0x21, 0x01, 0x3d, 0x02, - 0x48, 0xfe, 0xb4, 0x83, 0x01, 0x43, 0xfe, 0x44, 0x05, 0xdf, 0x30, 0xfc, - 0xed, 0x02, 0xe4, 0x00, 0x00, 0x03, 0x01, 0x3b, 0x02, 0x8c, 0x03, 0x96, - 0x05, 0xee, 0x00, 0x0e, 0x00, 0x2e, 0x00, 0x3d, 0x00, 0x00, 0x01, 0x22, - 0x07, 0x06, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, - 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, - 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, - 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x14, 0x17, - 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x07, 0x06, - 0x02, 0x68, 0x54, 0x2d, 0x2e, 0x2e, 0x2f, 0x52, 0x55, 0x2d, 0x2e, 0x2e, - 0x2f, 0xc0, 0x50, 0x2d, 0x2d, 0x4b, 0x4b, 0x81, 0x82, 0x4b, 0x4b, 0x2d, - 0x2d, 0x50, 0x5d, 0x31, 0x32, 0x50, 0x50, 0x8e, 0x8d, 0x50, 0x50, 0x32, - 0x31, 0x30, 0x27, 0x28, 0x4b, 0x4c, 0x28, 0x27, 0x4e, 0x4d, 0x4b, 0x28, - 0x27, 0x04, 0x29, 0x2b, 0x2a, 0x9a, 0x2b, 0x2b, 0x2a, 0x2b, 0x4e, 0x4d, - 0x2a, 0x2b, 0x2f, 0x12, 0x32, 0x33, 0x47, 0x63, 0x3b, 0x3a, 0x3a, 0x3b, - 0x63, 0x47, 0x33, 0x32, 0x12, 0x13, 0x38, 0x38, 0x59, 0x71, 0x3f, 0x40, - 0x3f, 0x40, 0x70, 0x5a, 0x38, 0x38, 0xc6, 0x43, 0x23, 0x24, 0x24, 0x23, - 0x43, 0x44, 0x48, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x30, - 0x02, 0x8d, 0x03, 0x88, 0x05, 0xf0, 0x00, 0x0f, 0x00, 0x2e, 0x00, 0x00, - 0x01, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, - 0x15, 0x14, 0x17, 0x16, 0x03, 0x35, 0x1e, 0x01, 0x33, 0x32, 0x37, 0x36, - 0x35, 0x0e, 0x01, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x33, - 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x02, - 0x53, 0x50, 0x2d, 0x2e, 0x2e, 0x2d, 0x50, 0x53, 0x2b, 0x2a, 0x2a, 0x2a, - 0x8c, 0x28, 0x58, 0x2f, 0x78, 0x3d, 0x3d, 0x1d, 0x6a, 0x44, 0x88, 0x48, - 0x49, 0x4b, 0x4c, 0x89, 0xa2, 0x4b, 0x4b, 0x5a, 0x5b, 0xac, 0x2d, 0x2e, - 0x2e, 0x04, 0x0f, 0x34, 0x34, 0x5d, 0x5c, 0x34, 0x34, 0x32, 0x31, 0x61, - 0x62, 0x32, 0x31, 0xfe, 0x9f, 0x68, 0x14, 0x16, 0x51, 0x50, 0x9e, 0x38, - 0x3c, 0x4a, 0x4b, 0x89, 0x87, 0x4a, 0x4a, 0x68, 0x69, 0xe1, 0xd3, 0x6f, - 0x6f, 0x08, 0x09, 0x00, 0x00, 0x01, 0x01, 0x1c, 0x02, 0xdb, 0x03, 0xb6, - 0x05, 0x2c, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x15, 0x21, 0x15, 0x21, 0x15, - 0x23, 0x35, 0x21, 0x35, 0x21, 0x35, 0x02, 0x9e, 0x01, 0x18, 0xfe, 0xe8, - 0x6a, 0xfe, 0xe8, 0x01, 0x18, 0x05, 0x2c, 0xf9, 0x5f, 0xf9, 0xf9, 0x5f, - 0xf9, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x1c, 0x03, 0xd4, 0x03, 0xb6, - 0x04, 0x33, 0x00, 0x03, 0x00, 0x00, 0x01, 0x21, 0x15, 0x21, 0x01, 0x1c, - 0x02, 0x9a, 0xfd, 0x66, 0x04, 0x33, 0x5f, 0x00, 0x00, 0x02, 0x01, 0x1c, - 0x03, 0x61, 0x03, 0xb6, 0x04, 0xa5, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, - 0x01, 0x21, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x01, 0x1c, 0x02, 0x9a, - 0xfd, 0x66, 0x02, 0x9a, 0xfd, 0x66, 0x03, 0xc1, 0x60, 0x01, 0x44, 0x5f, - 0x00, 0x01, 0x01, 0xd8, 0x02, 0x05, 0x02, 0xfa, 0x06, 0x02, 0x00, 0x0c, - 0x00, 0x00, 0x01, 0x0e, 0x01, 0x15, 0x14, 0x16, 0x17, 0x23, 0x2e, 0x01, - 0x34, 0x36, 0x37, 0x02, 0xfa, 0x54, 0x54, 0x54, 0x54, 0x66, 0x5e, 0x5e, - 0x5e, 0x5e, 0x06, 0x02, 0x7f, 0xfe, 0x81, 0x80, 0xfe, 0x81, 0x85, 0xfd, - 0xfa, 0xfd, 0x84, 0x00, 0x00, 0x01, 0x01, 0xd8, 0x02, 0x05, 0x02, 0xf9, - 0x06, 0x02, 0x00, 0x0d, 0x00, 0x00, 0x01, 0x33, 0x1e, 0x01, 0x15, 0x14, - 0x06, 0x07, 0x23, 0x3e, 0x01, 0x35, 0x34, 0x26, 0x01, 0xd8, 0x65, 0x5f, - 0x5d, 0x5d, 0x5f, 0x65, 0x54, 0x53, 0x53, 0x06, 0x02, 0x84, 0xfd, 0x7d, - 0x7e, 0xfd, 0x84, 0x82, 0xfe, 0x7f, 0x80, 0xfe, 0x00, 0x01, 0x01, 0x41, - 0x02, 0x9c, 0x03, 0x90, 0x05, 0x1f, 0x00, 0x13, 0x00, 0x20, 0x40, 0x06, - 0x00, 0x03, 0x0e, 0x0a, 0x0b, 0x14, 0x10, 0xd4, 0xdc, 0x3c, 0x2f, 0xcc, - 0x4b, 0x31, 0x00, 0x40, 0x06, 0x06, 0x11, 0x0c, 0x02, 0x0b, 0x14, 0x10, - 0xd4, 0x3c, 0xc4, 0xd4, 0xcc, 0x30, 0x01, 0x11, 0x23, 0x11, 0x34, 0x26, - 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, 0x15, 0x3e, 0x01, 0x33, - 0x32, 0x16, 0x03, 0x90, 0x74, 0x4e, 0x4e, 0x5e, 0x6c, 0x75, 0x75, 0x29, - 0x71, 0x4a, 0x79, 0x7d, 0x04, 0x17, 0xfe, 0x85, 0x01, 0x77, 0x59, 0x59, - 0x6b, 0x5c, 0xfe, 0x9e, 0x02, 0x73, 0x61, 0x38, 0x38, 0x86, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x3d, 0xff, 0xf1, 0x03, 0x95, 0x03, 0x54, 0x12, 0x07, - 0x07, 0x3e, 0x00, 0x00, 0xfd, 0x64, 0x00, 0x00, 0xff, 0xff, 0x01, 0x58, - 0x00, 0x00, 0x03, 0x93, 0x03, 0x43, 0x12, 0x07, 0x00, 0x7b, 0x00, 0x00, - 0xfd, 0x64, 0x00, 0x00, 0xff, 0xff, 0x01, 0x42, 0x00, 0x00, 0x03, 0x7d, - 0x03, 0x54, 0x12, 0x07, 0x00, 0x74, 0x00, 0x00, 0xfd, 0x64, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x46, 0xff, 0xf1, 0x03, 0x9c, 0x03, 0x54, 0x12, 0x07, - 0x00, 0x75, 0x00, 0x00, 0xfd, 0x64, 0x00, 0x00, 0xff, 0xff, 0x01, 0x0c, - 0x00, 0x00, 0x03, 0x8d, 0x03, 0x43, 0x12, 0x07, 0x07, 0x40, 0x00, 0x00, - 0xfd, 0x64, 0x00, 0x00, 0xff, 0xff, 0x01, 0x3f, 0xff, 0xf1, 0x03, 0x7d, - 0x03, 0x43, 0x12, 0x07, 0x07, 0x41, 0x00, 0x00, 0xfd, 0x64, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x49, 0xff, 0xf1, 0x03, 0xa1, 0x03, 0x54, 0x12, 0x07, - 0x07, 0x42, 0x00, 0x00, 0xfd, 0x64, 0x00, 0x00, 0xff, 0xff, 0x01, 0x3d, - 0x00, 0x00, 0x03, 0x85, 0x03, 0x43, 0x12, 0x07, 0x07, 0x43, 0x00, 0x00, - 0xfd, 0x64, 0x00, 0x00, 0xff, 0xff, 0x01, 0x3b, 0xff, 0xf0, 0x03, 0x96, - 0x03, 0x52, 0x12, 0x07, 0x07, 0x44, 0x00, 0x00, 0xfd, 0x64, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x30, 0xff, 0xf1, 0x03, 0x88, 0x03, 0x54, 0x12, 0x07, - 0x07, 0x45, 0x00, 0x00, 0xfd, 0x64, 0x00, 0x00, 0xff, 0xff, 0x01, 0x1c, - 0x00, 0x3f, 0x03, 0xb6, 0x02, 0x90, 0x12, 0x07, 0x07, 0x46, 0x00, 0x00, - 0xfd, 0x64, 0x00, 0x00, 0xff, 0xff, 0x01, 0x1c, 0x01, 0x38, 0x03, 0xb6, - 0x01, 0x97, 0x12, 0x07, 0x07, 0x47, 0x00, 0x00, 0xfd, 0x64, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x1c, 0x00, 0xc5, 0x03, 0xb6, 0x02, 0x09, 0x12, 0x07, - 0x07, 0x48, 0x00, 0x00, 0xfd, 0x64, 0x00, 0x00, 0xff, 0xff, 0x01, 0xd8, - 0xff, 0x69, 0x02, 0xfa, 0x03, 0x66, 0x12, 0x07, 0x07, 0x49, 0x00, 0x00, - 0xfd, 0x64, 0x00, 0x00, 0xff, 0xff, 0x01, 0xd8, 0xff, 0x69, 0x02, 0xf9, - 0x03, 0x66, 0x12, 0x07, 0x07, 0x4a, 0x00, 0x00, 0xfd, 0x64, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x45, 0xff, 0xf0, 0x03, 0x8c, 0x02, 0x82, 0x12, 0x07, - 0x05, 0x25, 0x00, 0x00, 0xfd, 0x64, 0x00, 0x00, 0xff, 0xff, 0x01, 0x31, - 0xff, 0xf0, 0x03, 0xa0, 0x02, 0x82, 0x12, 0x07, 0x05, 0x2b, 0x00, 0x00, - 0xfd, 0x64, 0x00, 0x00, 0xff, 0xff, 0x01, 0x3a, 0xff, 0xf0, 0x03, 0x97, - 0x02, 0x82, 0x12, 0x07, 0x05, 0x34, 0x00, 0x00, 0xfd, 0x64, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x12, 0x00, 0x00, 0x03, 0xbf, 0x02, 0x73, 0x12, 0x07, - 0x02, 0x7f, 0x00, 0x00, 0xfd, 0x64, 0x00, 0x00, 0xff, 0xff, 0x01, 0x31, - 0xff, 0xf0, 0x03, 0xa0, 0x02, 0x82, 0x12, 0x07, 0x05, 0x2c, 0x00, 0x00, - 0xfd, 0x64, 0x00, 0x00, 0xff, 0xff, 0x01, 0x41, 0x00, 0x00, 0x03, 0x90, - 0x03, 0x68, 0x12, 0x07, 0x02, 0x56, 0x00, 0x00, 0xfd, 0x64, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x38, 0x00, 0x00, 0x03, 0x99, 0x03, 0x67, 0x12, 0x07, - 0x05, 0x31, 0x00, 0x00, 0xfd, 0x64, 0x00, 0x00, 0xff, 0xff, 0x01, 0x56, - 0x00, 0x00, 0x03, 0x7c, 0x03, 0x6e, 0x12, 0x07, 0x02, 0x7d, 0x00, 0x00, - 0xfd, 0x64, 0x00, 0x00, 0xff, 0xff, 0x01, 0x25, 0x00, 0x00, 0x03, 0xac, - 0x02, 0x82, 0x12, 0x07, 0x05, 0x32, 0x00, 0x00, 0xfd, 0x64, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x41, 0x00, 0x00, 0x03, 0x90, 0x02, 0x83, 0x12, 0x07, - 0x07, 0x4b, 0x00, 0x00, 0xfd, 0x64, 0x00, 0x00, 0xff, 0xff, 0x01, 0x47, - 0xff, 0x11, 0x03, 0x8a, 0x02, 0x82, 0x12, 0x07, 0x05, 0x38, 0x00, 0x00, - 0xfd, 0x64, 0x00, 0x00, 0xff, 0xff, 0x01, 0x5b, 0x00, 0x00, 0x03, 0x76, - 0x02, 0x93, 0x12, 0x07, 0x02, 0x7e, 0x00, 0x00, 0xfd, 0x64, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x4d, 0x00, 0x00, 0x03, 0x84, 0x03, 0x25, 0x12, 0x07, - 0x05, 0x39, 0x00, 0x00, 0xfd, 0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0a, - 0xff, 0xe9, 0x04, 0xcc, 0x05, 0xe5, 0x00, 0x23, 0x00, 0x00, 0x01, 0x0e, - 0x01, 0x23, 0x22, 0x02, 0x10, 0x12, 0x33, 0x32, 0x16, 0x17, 0x15, 0x2e, - 0x01, 0x23, 0x22, 0x06, 0x10, 0x16, 0x33, 0x32, 0x36, 0x37, 0x11, 0x21, - 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x02, 0xaf, - 0x3b, 0x86, 0x4a, 0xbe, 0xdc, 0xdc, 0xbe, 0x4c, 0x85, 0x3a, 0x39, 0x82, - 0x49, 0x90, 0x99, 0x99, 0x90, 0x49, 0x82, 0x39, 0x02, 0x13, 0xfe, 0x5e, - 0x01, 0x91, 0xfe, 0x6f, 0x01, 0xac, 0xfd, 0xe3, 0x01, 0xac, 0x37, 0x38, - 0x01, 0x3f, 0x02, 0x2a, 0x01, 0x3f, 0x37, 0x37, 0xa3, 0x49, 0x47, 0xef, - 0xfe, 0x38, 0xef, 0x47, 0x49, 0x02, 0x17, 0x83, 0xfe, 0xad, 0x83, 0xfe, - 0x60, 0x83, 0x00, 0x00, 0x00, 0x03, 0x00, 0x7b, 0xff, 0xa6, 0x04, 0x63, - 0x06, 0x39, 0x00, 0x27, 0x00, 0x2e, 0x00, 0x34, 0x00, 0x00, 0x01, 0x16, - 0x17, 0x37, 0x33, 0x07, 0x16, 0x17, 0x15, 0x26, 0x27, 0x01, 0x33, 0x32, - 0x36, 0x37, 0x15, 0x0e, 0x01, 0x23, 0x22, 0x27, 0x07, 0x23, 0x37, 0x26, - 0x27, 0x07, 0x23, 0x37, 0x26, 0x27, 0x26, 0x11, 0x10, 0x37, 0x36, 0x3f, - 0x01, 0x33, 0x07, 0x06, 0x07, 0x06, 0x11, 0x14, 0x17, 0x01, 0x26, 0x27, - 0x01, 0x16, 0x17, 0x03, 0x2c, 0x3b, 0x38, 0x1c, 0x8d, 0x2b, 0x24, 0x22, - 0x35, 0x3a, 0xfe, 0xde, 0x10, 0x6c, 0xc0, 0x55, 0x58, 0xc5, 0x6e, 0x18, - 0x18, 0x10, 0x8d, 0x16, 0x3b, 0x34, 0x22, 0x8d, 0x3b, 0x12, 0x0f, 0xa2, - 0xa2, 0x92, 0xf0, 0x13, 0x8e, 0xcf, 0x84, 0x50, 0x71, 0x4a, 0x02, 0x01, - 0x38, 0x3d, 0xfe, 0xde, 0x30, 0x3b, 0x05, 0xeb, 0x08, 0x13, 0x69, 0xa5, - 0x16, 0x1c, 0xd5, 0x3c, 0x29, 0xfb, 0x97, 0x5e, 0x5f, 0xd3, 0x48, 0x48, - 0x02, 0x3f, 0x57, 0x12, 0x1e, 0x87, 0xe6, 0x12, 0x15, 0xcf, 0x01, 0x67, - 0x01, 0x6a, 0xce, 0xb9, 0x14, 0x4b, 0xfc, 0x1f, 0x70, 0x9d, 0xfe, 0xd8, - 0xee, 0x94, 0x03, 0xcb, 0x13, 0x04, 0xfb, 0x95, 0x28, 0x15, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x5f, 0xff, 0xe4, 0x04, 0x59, 0x05, 0xf0, 0x00, 0x2c, - 0x00, 0x00, 0x25, 0x36, 0x37, 0x36, 0x37, 0x15, 0x0e, 0x01, 0x23, 0x20, - 0x00, 0x11, 0x10, 0x00, 0x21, 0x32, 0x16, 0x17, 0x15, 0x2e, 0x01, 0x23, - 0x22, 0x02, 0x11, 0x10, 0x17, 0x16, 0x17, 0x11, 0x33, 0x15, 0x3e, 0x01, - 0x33, 0x32, 0x16, 0x1f, 0x01, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x15, 0x02, - 0xf3, 0x59, 0x51, 0x62, 0x55, 0x59, 0xc8, 0x6f, 0xfe, 0xe3, 0xfe, 0xb8, - 0x01, 0x48, 0x01, 0x1d, 0x71, 0xc8, 0x57, 0x55, 0xc3, 0x6e, 0xd7, 0xe5, - 0x72, 0x56, 0x8d, 0x8c, 0x2c, 0x8e, 0x65, 0x0e, 0x23, 0x15, 0x01, 0x18, - 0x37, 0x21, 0x76, 0x80, 0x8a, 0x07, 0x27, 0x2f, 0x5f, 0xd3, 0x48, 0x47, - 0x01, 0x9e, 0x01, 0x67, 0x01, 0x68, 0x01, 0x9f, 0x47, 0x47, 0xd5, 0x5f, - 0x5e, 0xfe, 0xc7, 0xfe, 0xd8, 0xfe, 0xd9, 0x9c, 0x75, 0x1e, 0x03, 0x5d, - 0x9d, 0x5c, 0x59, 0x04, 0x05, 0xaa, 0x10, 0x0f, 0xb6, 0xab, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x43, 0x05, 0xd5, 0x00, 0x11, - 0x00, 0x00, 0x13, 0x11, 0x21, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x11, - 0x33, 0x15, 0x23, 0x11, 0x23, 0x11, 0x23, 0x35, 0xe9, 0x03, 0x5a, 0xfd, - 0x70, 0x02, 0x50, 0xfd, 0xb0, 0xf7, 0xf7, 0xca, 0xe9, 0x01, 0x7e, 0x04, - 0x57, 0xaa, 0xfe, 0x48, 0xaa, 0xfe, 0xb5, 0x45, 0xfe, 0xc7, 0x01, 0x39, - 0x45, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x8b, 0x00, 0x00, 0x04, 0x6c, - 0x05, 0xf0, 0x00, 0x23, 0x00, 0x00, 0x01, 0x11, 0x21, 0x15, 0x21, 0x35, - 0x33, 0x11, 0x23, 0x35, 0x33, 0x35, 0x23, 0x35, 0x33, 0x35, 0x10, 0x36, - 0x33, 0x32, 0x16, 0x17, 0x15, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x1d, 0x01, - 0x21, 0x15, 0x21, 0x15, 0x21, 0x15, 0x02, 0x3f, 0x02, 0x2d, 0xfc, 0x1f, - 0xec, 0xbf, 0xbf, 0xc7, 0xc7, 0xd6, 0xe8, 0x3d, 0x97, 0x4f, 0x4c, 0x88, - 0x3d, 0x94, 0x74, 0x01, 0x87, 0xfe, 0x79, 0x01, 0x8f, 0x01, 0xec, 0xfe, - 0xbe, 0xaa, 0xaa, 0x01, 0x42, 0x8f, 0x8f, 0x8f, 0x5f, 0x01, 0x05, 0xf3, - 0x1f, 0x1d, 0xb6, 0x29, 0x29, 0x9b, 0xd4, 0x48, 0x8f, 0x8f, 0x8f, 0x00, - 0x00, 0x01, 0x00, 0x6d, 0xff, 0x42, 0x04, 0x6f, 0x05, 0x1e, 0x00, 0x29, - 0x00, 0x00, 0x01, 0x36, 0x33, 0x32, 0x16, 0x19, 0x01, 0x23, 0x11, 0x34, - 0x26, 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, 0x35, 0x03, 0x23, 0x13, 0x26, - 0x27, 0x26, 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, 0x15, 0x3e, - 0x01, 0x33, 0x32, 0x17, 0x16, 0x17, 0x13, 0x33, 0x03, 0x0a, 0x30, 0x3f, - 0x87, 0x6f, 0xa8, 0x35, 0x46, 0x50, 0x3b, 0xa8, 0x5d, 0x69, 0xc6, 0x01, - 0x1c, 0x1c, 0x4a, 0x49, 0x39, 0xa7, 0xa7, 0x21, 0x63, 0x3f, 0x4c, 0x33, - 0x21, 0x17, 0x42, 0x6a, 0x04, 0x62, 0x19, 0xd1, 0xfe, 0xdf, 0xfd, 0x77, - 0x02, 0x81, 0xed, 0x73, 0x7b, 0xe5, 0xfd, 0x7f, 0xb0, 0xfe, 0x92, 0x03, - 0x45, 0xeb, 0x37, 0x38, 0x7b, 0xe5, 0xfd, 0x7f, 0x04, 0x60, 0x60, 0x3c, - 0x3f, 0x23, 0x17, 0x27, 0x01, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x04, 0xd1, 0x05, 0xd5, 0x00, 0x02, 0x00, 0x06, 0x00, 0x22, - 0x00, 0x26, 0x00, 0x29, 0x00, 0x00, 0x01, 0x27, 0x15, 0x13, 0x27, 0x23, - 0x15, 0x03, 0x21, 0x13, 0x33, 0x11, 0x33, 0x11, 0x33, 0x15, 0x23, 0x15, - 0x33, 0x15, 0x23, 0x11, 0x21, 0x03, 0x23, 0x11, 0x23, 0x11, 0x23, 0x35, - 0x33, 0x35, 0x23, 0x35, 0x33, 0x05, 0x17, 0x33, 0x35, 0x03, 0x17, 0x35, - 0x01, 0xb5, 0x4f, 0xb7, 0x39, 0x7e, 0xc4, 0x01, 0x10, 0xd3, 0xe6, 0xc4, - 0xa2, 0xa2, 0xa2, 0xa2, 0xfe, 0xf0, 0xd3, 0xe6, 0xc4, 0xa2, 0xa2, 0xa2, - 0xa2, 0x02, 0x12, 0x39, 0x7e, 0x4f, 0x4f, 0x03, 0xaf, 0xce, 0xce, 0xfe, - 0xf2, 0x93, 0x93, 0x03, 0x34, 0xfd, 0xda, 0x02, 0x26, 0xfd, 0xda, 0x7b, - 0x93, 0x7b, 0xfd, 0xda, 0x02, 0x26, 0xfd, 0xda, 0x02, 0x26, 0x7b, 0x93, - 0x7b, 0x7b, 0x93, 0x93, 0xfe, 0xf2, 0xce, 0xce, 0x00, 0x02, 0x00, 0x0a, - 0xff, 0xe3, 0x04, 0xcc, 0x05, 0xd5, 0x00, 0x08, 0x00, 0x50, 0x00, 0x00, - 0x13, 0x11, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x13, 0x06, 0x07, - 0x06, 0x2b, 0x01, 0x11, 0x23, 0x11, 0x33, 0x32, 0x17, 0x16, 0x17, 0x33, - 0x11, 0x33, 0x11, 0x33, 0x15, 0x23, 0x11, 0x14, 0x16, 0x3b, 0x01, 0x35, - 0x1e, 0x01, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x2f, 0x01, 0x2e, 0x01, - 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x17, 0x15, 0x2e, 0x01, 0x23, 0x22, - 0x06, 0x15, 0x14, 0x16, 0x1f, 0x01, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x23, - 0x22, 0x26, 0x27, 0x35, 0x23, 0x22, 0x26, 0x35, 0x11, 0x6e, 0x7e, 0x46, - 0x4d, 0x4d, 0x46, 0xfc, 0x03, 0x3c, 0x40, 0x7d, 0x7e, 0x64, 0xe2, 0x7d, - 0x40, 0x2e, 0x0d, 0x2a, 0x5c, 0xbd, 0xbd, 0x26, 0x39, 0x5a, 0x32, 0x63, - 0x30, 0x40, 0x46, 0x32, 0x55, 0x20, 0x55, 0x4b, 0x6f, 0x67, 0x32, 0x59, - 0x26, 0x27, 0x53, 0x2d, 0x44, 0x44, 0x31, 0x4a, 0x1f, 0x61, 0x52, 0x7b, - 0x6b, 0x2d, 0x60, 0x36, 0x5a, 0x6a, 0x51, 0x05, 0x2f, 0xfd, 0xcf, 0x92, - 0x87, 0x86, 0x92, 0xfe, 0xcc, 0xc8, 0x6a, 0x71, 0xfd, 0xa8, 0x05, 0xd5, - 0x71, 0x52, 0x88, 0x01, 0x3e, 0xfe, 0xc2, 0x8f, 0xfd, 0xa0, 0x89, 0x4e, - 0x23, 0x35, 0x35, 0x59, 0x51, 0x4b, 0x50, 0x25, 0x0f, 0x24, 0x95, 0x82, - 0x9e, 0xac, 0x1e, 0x1e, 0xae, 0x28, 0x28, 0x54, 0x54, 0x40, 0x49, 0x21, - 0x0e, 0x2a, 0x99, 0x89, 0x9c, 0xb6, 0x23, 0x23, 0x01, 0x9f, 0xd2, 0x02, - 0x60, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0a, 0xff, 0xe3, 0x04, 0xc9, - 0x05, 0xd5, 0x00, 0x07, 0x00, 0x45, 0x00, 0x00, 0x13, 0x11, 0x33, 0x32, - 0x36, 0x10, 0x26, 0x23, 0x01, 0x17, 0x23, 0x03, 0x2e, 0x01, 0x2b, 0x01, - 0x11, 0x23, 0x11, 0x21, 0x32, 0x16, 0x15, 0x14, 0x06, 0x07, 0x1e, 0x01, - 0x1f, 0x01, 0x16, 0x17, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x2f, - 0x01, 0x2e, 0x01, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x17, 0x15, 0x2e, - 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x1f, 0x01, 0x1e, 0x01, 0x15, - 0x14, 0x06, 0x23, 0x22, 0x27, 0x26, 0x8b, 0xa3, 0x5d, 0x60, 0x60, 0x5d, - 0x01, 0xc2, 0x02, 0x8b, 0x7a, 0x2f, 0x59, 0x4d, 0x8d, 0x81, 0x01, 0x24, - 0xa4, 0xa1, 0x54, 0x50, 0x2a, 0x4e, 0x28, 0x3a, 0x3f, 0x3e, 0x3f, 0x3e, - 0x53, 0x5a, 0x41, 0x6d, 0x29, 0x6e, 0x61, 0x8f, 0x84, 0x41, 0x74, 0x30, - 0x32, 0x6b, 0x3a, 0x57, 0x58, 0x3f, 0x5e, 0x29, 0x7d, 0x6a, 0x9e, 0x8b, - 0x39, 0x3e, 0x1c, 0x05, 0x2f, 0xfd, 0xee, 0x87, 0x01, 0x06, 0x85, 0xfa, - 0xd8, 0x07, 0x01, 0x7f, 0x96, 0x62, 0xfd, 0x89, 0x05, 0xd5, 0xd6, 0xd8, - 0x8d, 0xba, 0x24, 0x16, 0x90, 0x7e, 0xb4, 0x33, 0x19, 0x1b, 0x59, 0x51, - 0x4b, 0x50, 0x25, 0x0f, 0x24, 0x95, 0x82, 0x9e, 0xac, 0x1e, 0x1e, 0xae, - 0x28, 0x28, 0x54, 0x54, 0x40, 0x49, 0x21, 0x0e, 0x2a, 0x99, 0x89, 0x9c, - 0xb6, 0x12, 0x08, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd1, - 0x05, 0xd5, 0x00, 0x03, 0x00, 0x06, 0x00, 0x0a, 0x00, 0x2a, 0x00, 0x2d, - 0x00, 0x30, 0x00, 0x00, 0x13, 0x17, 0x33, 0x37, 0x01, 0x23, 0x1b, 0x01, - 0x21, 0x17, 0x33, 0x01, 0x21, 0x37, 0x33, 0x17, 0x21, 0x37, 0x33, 0x07, - 0x33, 0x15, 0x23, 0x07, 0x33, 0x15, 0x23, 0x03, 0x23, 0x03, 0x23, 0x03, - 0x23, 0x03, 0x23, 0x35, 0x33, 0x27, 0x23, 0x35, 0x33, 0x27, 0x33, 0x1b, - 0x03, 0x07, 0x33, 0xec, 0x0e, 0xe1, 0x12, 0x01, 0xd9, 0xb9, 0x70, 0x67, - 0xfe, 0xfd, 0x12, 0xe4, 0xfd, 0x05, 0x01, 0x31, 0x1e, 0x8c, 0x1e, 0x01, - 0x20, 0x17, 0xc5, 0x1d, 0x1d, 0x32, 0x11, 0x43, 0x59, 0x86, 0xbf, 0xbf, - 0x0e, 0xc8, 0xbf, 0x86, 0x59, 0x44, 0x12, 0x32, 0x1d, 0x1d, 0xc5, 0x46, - 0x49, 0x6e, 0xa6, 0x13, 0x24, 0x04, 0x84, 0x75, 0x75, 0xfe, 0xfc, 0xfd, - 0x97, 0x03, 0x6d, 0x75, 0x01, 0x04, 0xc2, 0xc2, 0xc2, 0xc2, 0x8f, 0x75, - 0x8f, 0xfc, 0x80, 0x03, 0x77, 0xfc, 0x89, 0x03, 0x80, 0x8f, 0x75, 0x8f, - 0xc2, 0xfd, 0xab, 0xfd, 0x99, 0x02, 0x67, 0x01, 0x04, 0x75, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x2a, 0xff, 0xe3, 0x04, 0xa7, 0x05, 0xd5, 0x00, 0x0d, - 0x00, 0x1b, 0x00, 0x00, 0x13, 0x25, 0x32, 0x12, 0x19, 0x01, 0x23, 0x11, - 0x34, 0x26, 0x23, 0x21, 0x11, 0x23, 0x29, 0x01, 0x22, 0x02, 0x19, 0x01, - 0x33, 0x11, 0x14, 0x16, 0x33, 0x21, 0x11, 0x33, 0x2a, 0x01, 0xa3, 0xce, - 0xd4, 0x95, 0x7f, 0x8e, 0xfe, 0xf2, 0x95, 0x04, 0x7c, 0xfe, 0x61, 0xce, - 0xd4, 0x95, 0x7e, 0x8f, 0x01, 0x11, 0x8f, 0x05, 0xd2, 0x03, 0xfe, 0xd6, - 0xfe, 0xdc, 0xfe, 0x91, 0x01, 0x56, 0xf0, 0xd3, 0xfa, 0xb2, 0x01, 0x2a, - 0x01, 0x24, 0x01, 0x6f, 0xfe, 0xaa, 0xf0, 0xd3, 0x05, 0x4e, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x7b, 0xfe, 0x9b, 0x04, 0xd1, 0x06, 0x14, 0x12, 0x26, - 0x00, 0xd3, 0x00, 0x00, 0x10, 0x06, 0x02, 0x6c, 0x7a, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x25, 0xff, 0xe3, 0x04, 0x25, 0x05, 0xf0, 0x00, 0x33, - 0x00, 0x70, 0x40, 0x3c, 0x0d, 0x00, 0xe7, 0x31, 0x0f, 0x26, 0x18, 0xe7, - 0x16, 0x1f, 0xb3, 0x20, 0xb2, 0x1c, 0x97, 0x28, 0x16, 0x23, 0x07, 0xb3, - 0x06, 0xb2, 0x0a, 0x97, 0x03, 0x96, 0x23, 0x99, 0x34, 0x33, 0x28, 0x27, - 0x31, 0x29, 0x2d, 0x18, 0x16, 0x10, 0x03, 0x13, 0x0f, 0x17, 0x0e, 0x26, - 0x00, 0x2d, 0x19, 0x0d, 0x17, 0x13, 0x0e, 0x32, 0x27, 0x13, 0x1e, 0x1f, - 0x06, 0x17, 0x2d, 0x34, 0x10, 0xd4, 0xc4, 0xc4, 0x32, 0xec, 0xc4, 0x32, - 0xc4, 0x11, 0x12, 0x39, 0x39, 0x12, 0x39, 0x39, 0x11, 0x12, 0x39, 0x11, - 0x17, 0x39, 0x12, 0x39, 0x39, 0x11, 0x39, 0x39, 0x31, 0x00, 0x10, 0xe4, - 0xf4, 0xec, 0xf4, 0xec, 0x10, 0xc6, 0x32, 0xee, 0xf6, 0xee, 0x10, 0xee, - 0x32, 0xd5, 0x3c, 0xee, 0x32, 0x30, 0x13, 0x12, 0x00, 0x33, 0x32, 0x16, - 0x17, 0x15, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x21, 0x07, 0x21, 0x0e, - 0x01, 0x15, 0x14, 0x16, 0x17, 0x21, 0x07, 0x21, 0x1e, 0x01, 0x33, 0x32, - 0x36, 0x37, 0x15, 0x0e, 0x01, 0x23, 0x22, 0x00, 0x03, 0x23, 0x37, 0x33, - 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x23, 0x37, 0xd3, 0x30, - 0x01, 0x12, 0xdf, 0x54, 0x93, 0x4a, 0x42, 0x9f, 0x4e, 0x92, 0xae, 0x18, - 0x01, 0xe1, 0x31, 0xfe, 0x46, 0x02, 0x01, 0x01, 0x01, 0x01, 0x69, 0x31, - 0xfe, 0xd3, 0x17, 0xae, 0x93, 0x4f, 0x9d, 0x43, 0x48, 0x94, 0x55, 0xe2, - 0xfe, 0xed, 0x2c, 0xae, 0x31, 0x75, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, - 0xa6, 0x31, 0x03, 0xb4, 0x01, 0x1b, 0x01, 0x21, 0x28, 0x2a, 0xcf, 0x3d, - 0x44, 0xd0, 0xcc, 0x6c, 0x14, 0x2d, 0x2e, 0x0f, 0x26, 0x17, 0x6e, 0xcb, - 0xd1, 0x43, 0x3e, 0xcf, 0x2a, 0x28, 0x01, 0x20, 0x01, 0x1c, 0x6e, 0x0c, - 0x14, 0x2d, 0x0f, 0x12, 0x2f, 0x13, 0x0b, 0x6c, 0x00, 0x01, 0x00, 0x2a, - 0x00, 0x00, 0x04, 0xa7, 0x05, 0xd5, 0x00, 0x11, 0x00, 0x00, 0x13, 0x11, - 0x33, 0x11, 0x01, 0x33, 0x01, 0x21, 0x15, 0x21, 0x01, 0x23, 0x01, 0x11, - 0x23, 0x11, 0x23, 0x35, 0xb4, 0xac, 0x02, 0x3c, 0xdd, 0xfd, 0xba, 0x01, - 0x84, 0xfe, 0x7e, 0x02, 0x72, 0xe3, 0xfd, 0x9c, 0xac, 0x8a, 0x03, 0x54, - 0x02, 0x81, 0xfd, 0x89, 0x02, 0x77, 0xfd, 0x7f, 0x73, 0xfd, 0x1f, 0x02, - 0xcf, 0xfd, 0x31, 0x02, 0xe1, 0x73, 0x00, 0x00, 0x00, 0x01, 0x00, 0x2f, - 0x00, 0x00, 0x04, 0xa2, 0x05, 0xd5, 0x00, 0x17, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x35, 0x21, 0x15, 0x21, 0x11, 0x37, 0x17, 0x05, 0x15, 0x37, 0x17, - 0x05, 0x11, 0x23, 0x11, 0x07, 0x27, 0x25, 0x35, 0x07, 0x27, 0x02, 0x04, - 0xfe, 0x2b, 0x04, 0x73, 0xfe, 0x2d, 0xe5, 0x50, 0xfe, 0xcb, 0xe6, 0x50, - 0xfe, 0xca, 0xcb, 0xd0, 0x4d, 0x01, 0x1d, 0xd1, 0x4d, 0x03, 0x8d, 0x01, - 0x9e, 0xaa, 0xaa, 0xfe, 0xf1, 0xa1, 0x6f, 0xd8, 0x88, 0xa2, 0x6f, 0xd9, - 0xfd, 0xb8, 0x01, 0xba, 0xa1, 0x6e, 0xd9, 0x88, 0xa2, 0x6e, 0x00, 0x00, - 0x00, 0x05, 0x00, 0x1e, 0xfe, 0x39, 0x04, 0xc6, 0x05, 0xf0, 0x00, 0x16, - 0x00, 0x2d, 0x00, 0x62, 0x00, 0x77, 0x00, 0x83, 0x00, 0x00, 0x01, 0x27, - 0x13, 0x36, 0x37, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x13, 0x22, 0x07, - 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x36, 0x37, 0x36, - 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x05, 0x36, 0x37, 0x13, - 0x06, 0x07, 0x06, 0x07, 0x06, 0x07, 0x27, 0x3e, 0x01, 0x37, 0x36, 0x33, - 0x32, 0x16, 0x17, 0x1e, 0x01, 0x15, 0x14, 0x07, 0x06, 0x07, 0x0e, 0x01, - 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x2e, 0x01, 0x27, 0x26, 0x2f, - 0x01, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x36, 0x33, - 0x32, 0x01, 0x03, 0x06, 0x07, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x36, - 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x01, 0x26, - 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x03, 0x66, - 0x62, 0x55, 0x12, 0x21, 0x1a, 0x4f, 0x33, 0x27, 0x41, 0x14, 0x22, 0x19, - 0x1a, 0x2b, 0x30, 0x2e, 0x1d, 0x21, 0x18, 0x10, 0x82, 0x2e, 0x1a, 0x06, - 0x08, 0x06, 0x0c, 0x11, 0x21, 0x13, 0x20, 0x0c, 0x0b, 0x0a, 0x09, 0x0f, - 0x07, 0x0c, 0x0b, 0xfc, 0xb0, 0x07, 0x05, 0x5f, 0x18, 0x11, 0x12, 0x0d, - 0x0b, 0x09, 0x5c, 0x0e, 0x35, 0x23, 0x3f, 0x5c, 0x6b, 0x9f, 0x32, 0x2c, - 0x2c, 0x0f, 0x0e, 0x23, 0x13, 0x32, 0x21, 0x24, 0x28, 0x32, 0x28, 0x20, - 0x19, 0x1a, 0x34, 0x11, 0x22, 0x08, 0x08, 0x09, 0x0b, 0x29, 0x31, 0x3e, - 0x28, 0x28, 0x45, 0x38, 0x26, 0x01, 0x00, 0x5e, 0x0d, 0x0b, 0x15, 0x2c, - 0x1b, 0x1e, 0x1c, 0x39, 0x51, 0x1e, 0x17, 0x0f, 0x0d, 0x10, 0x11, 0x1d, - 0x46, 0xfe, 0x91, 0x15, 0x19, 0x14, 0x08, 0x07, 0x0d, 0x0c, 0x11, 0x17, - 0xfe, 0x39, 0x29, 0x02, 0xd0, 0x97, 0x69, 0x52, 0x6d, 0x3a, 0x33, 0x58, - 0x92, 0x77, 0x64, 0x67, 0x37, 0x3f, 0x20, 0x17, 0x32, 0x01, 0xf8, 0x6a, - 0x1a, 0x37, 0x23, 0x3d, 0x35, 0x28, 0x36, 0x24, 0x20, 0x1b, 0x36, 0x32, - 0x39, 0x54, 0x2f, 0x14, 0x0c, 0x0b, 0xb7, 0x28, 0x32, 0x03, 0x4d, 0x0a, - 0x14, 0x16, 0x21, 0x1d, 0x3a, 0x35, 0x53, 0x7d, 0x24, 0x40, 0x7b, 0x6d, - 0x62, 0xf5, 0x81, 0x71, 0x8c, 0x82, 0x7e, 0x45, 0x73, 0x2f, 0x34, 0x18, - 0x1d, 0x09, 0x0a, 0x2d, 0x13, 0x26, 0x0a, 0x0a, 0x22, 0x17, 0x54, 0x41, - 0x42, 0x60, 0x5d, 0x85, 0x03, 0x92, 0xfc, 0x9b, 0x7c, 0x40, 0x1b, 0x38, - 0x16, 0x19, 0x86, 0x6e, 0x52, 0x80, 0x6b, 0x63, 0x64, 0x5d, 0x61, 0x43, - 0x9c, 0xfb, 0xa0, 0x22, 0x0e, 0x0e, 0x0f, 0x18, 0x0f, 0x0e, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x2e, 0xff, 0xe3, 0x04, 0x8e, 0x05, 0xf0, 0x00, 0x29, - 0x00, 0x35, 0x00, 0x00, 0x13, 0x27, 0x36, 0x33, 0x32, 0x17, 0x16, 0x33, - 0x32, 0x37, 0x26, 0x35, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, - 0x14, 0x07, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x35, 0x32, 0x37, 0x36, - 0x35, 0x34, 0x27, 0x06, 0x23, 0x22, 0x27, 0x26, 0x23, 0x22, 0x25, 0x36, - 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, 0xb9, 0x8b, - 0x93, 0x6f, 0x7c, 0x40, 0x58, 0x22, 0x30, 0x37, 0xe3, 0x50, 0x59, 0x88, - 0x74, 0x61, 0x54, 0x6b, 0xb5, 0x7e, 0x6a, 0xfc, 0x86, 0x5b, 0x49, 0x77, - 0x89, 0x6d, 0x71, 0x4a, 0x32, 0x35, 0x33, 0x02, 0x30, 0x44, 0x1b, 0x23, - 0x32, 0x34, 0x21, 0x19, 0x02, 0x04, 0x60, 0xf0, 0x4e, 0x6b, 0x42, 0xb1, - 0xfe, 0xac, 0x58, 0x60, 0x60, 0x53, 0xb1, 0xe3, 0xab, 0xa3, 0xbf, 0xc2, - 0x86, 0x71, 0xa2, 0x4a, 0x3c, 0x93, 0x58, 0x72, 0x7e, 0x68, 0x46, 0xd9, - 0x6c, 0xaf, 0x56, 0x31, 0x3f, 0x3f, 0x30, 0x57, 0xa6, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x6a, 0x00, 0x00, 0x04, 0xd1, 0x05, 0xd5, 0x00, 0x1a, - 0x00, 0x1f, 0x00, 0x24, 0x00, 0x29, 0x00, 0x00, 0x13, 0x21, 0x20, 0x13, - 0x33, 0x15, 0x23, 0x16, 0x07, 0x33, 0x15, 0x23, 0x06, 0x07, 0x06, 0x2b, - 0x01, 0x11, 0x23, 0x11, 0x23, 0x35, 0x33, 0x35, 0x23, 0x35, 0x33, 0x37, - 0x15, 0x21, 0x26, 0x23, 0x13, 0x21, 0x15, 0x33, 0x32, 0x37, 0x36, 0x27, - 0x21, 0x15, 0xc5, 0x01, 0xb4, 0x01, 0x82, 0x5e, 0x78, 0x5f, 0x09, 0x08, - 0x5e, 0x72, 0x26, 0x61, 0x7e, 0xe1, 0xea, 0xca, 0x5b, 0x5b, 0x5b, 0x5b, - 0xca, 0x01, 0xdc, 0x4d, 0xa5, 0xfd, 0xfe, 0x19, 0xea, 0xb1, 0x75, 0x07, - 0x09, 0xfd, 0xf2, 0x05, 0xd5, 0xfe, 0xf7, 0x74, 0x3a, 0x39, 0x73, 0x7b, - 0x46, 0x59, 0xfd, 0xa8, 0x03, 0x72, 0x73, 0x73, 0x74, 0x63, 0x63, 0x63, - 0xfe, 0x43, 0x74, 0xe7, 0x3b, 0x38, 0x73, 0x00, 0x00, 0x02, 0x00, 0x35, - 0xff, 0x5b, 0x04, 0x89, 0x06, 0x78, 0x00, 0x24, 0x00, 0x2d, 0x00, 0x00, - 0x05, 0x23, 0x35, 0x26, 0x27, 0x26, 0x11, 0x10, 0x37, 0x36, 0x37, 0x35, - 0x33, 0x15, 0x16, 0x17, 0x16, 0x17, 0x15, 0x26, 0x27, 0x26, 0x27, 0x11, - 0x36, 0x37, 0x36, 0x37, 0x11, 0x23, 0x35, 0x21, 0x11, 0x06, 0x07, 0x06, - 0x07, 0x27, 0x11, 0x06, 0x07, 0x06, 0x11, 0x10, 0x17, 0x16, 0x02, 0xd1, - 0x8c, 0xdf, 0x89, 0xa8, 0xa8, 0x89, 0xdf, 0x8c, 0x69, 0x60, 0x70, 0x5e, - 0x5f, 0x6b, 0x62, 0x6b, 0x4e, 0x3f, 0x48, 0x39, 0x78, 0x01, 0x22, 0x63, - 0x78, 0x68, 0x75, 0x8c, 0x85, 0x4f, 0x6f, 0x6f, 0x4f, 0xa5, 0x8f, 0x1f, - 0xa7, 0xcc, 0x01, 0x6d, 0x01, 0x6e, 0xcd, 0xa6, 0x1f, 0x8f, 0x89, 0x04, - 0x1f, 0x24, 0x46, 0xd7, 0x5f, 0x30, 0x2c, 0x04, 0xfb, 0x3f, 0x02, 0x11, - 0x12, 0x27, 0x01, 0x91, 0xa6, 0xfd, 0x7f, 0x53, 0x2a, 0x25, 0x05, 0xb2, - 0x04, 0xa7, 0x20, 0x6c, 0x99, 0xfe, 0xd1, 0xfe, 0xd2, 0x99, 0x6c, 0x00, - 0x00, 0x03, 0x00, 0x27, 0x00, 0x00, 0x04, 0xa9, 0x05, 0xd5, 0x00, 0x17, - 0x00, 0x1b, 0x00, 0x1e, 0x00, 0x00, 0x13, 0x35, 0x21, 0x13, 0x33, 0x13, - 0x21, 0x15, 0x23, 0x17, 0x33, 0x15, 0x23, 0x13, 0x23, 0x03, 0x21, 0x03, - 0x23, 0x13, 0x23, 0x35, 0x33, 0x37, 0x33, 0x07, 0x21, 0x2f, 0x01, 0x33, - 0x03, 0x46, 0x01, 0x16, 0xa5, 0xd0, 0xa5, 0x01, 0x14, 0xed, 0x41, 0xac, - 0x85, 0xa4, 0xbf, 0x9a, 0xfe, 0x33, 0x9b, 0xc1, 0xa4, 0x85, 0xac, 0x43, - 0xaf, 0x3d, 0x01, 0x83, 0x3e, 0xe3, 0xbf, 0x60, 0x03, 0x52, 0x7b, 0x02, - 0x08, 0xfd, 0xf8, 0x7b, 0xcf, 0x7b, 0xfd, 0xf8, 0x02, 0x08, 0xfd, 0xf8, - 0x02, 0x08, 0x7b, 0xcf, 0xcf, 0xcf, 0x7b, 0x01, 0x41, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0xff, 0xe3, 0x04, 0xd1, 0x05, 0xf0, 0x00, 0x36, - 0x00, 0x00, 0x01, 0x36, 0x37, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, - 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x04, 0x15, 0x14, 0x07, 0x33, 0x15, - 0x23, 0x06, 0x0f, 0x01, 0x21, 0x15, 0x21, 0x06, 0x15, 0x14, 0x16, 0x33, - 0x32, 0x36, 0x37, 0x15, 0x0e, 0x01, 0x23, 0x22, 0x24, 0x35, 0x34, 0x37, - 0x23, 0x35, 0x33, 0x36, 0x37, 0x36, 0x37, 0x21, 0x35, 0x03, 0x3f, 0x0a, - 0x09, 0x37, 0xa6, 0x8f, 0x5e, 0xb9, 0x5c, 0x69, 0xbe, 0x56, 0xdf, 0x01, - 0x0d, 0x15, 0x9c, 0xe9, 0x5e, 0xcc, 0x27, 0x02, 0x3a, 0xfc, 0xa7, 0x2c, - 0xaa, 0x99, 0x68, 0xcd, 0x73, 0x6b, 0xd4, 0x69, 0xfc, 0xfe, 0xf8, 0x12, - 0x9d, 0xd9, 0x09, 0x09, 0x48, 0x88, 0xfe, 0x45, 0x03, 0xaf, 0x07, 0x09, - 0x34, 0x63, 0x71, 0x85, 0x3c, 0x3b, 0xcd, 0x27, 0x27, 0xf1, 0xc8, 0x4b, - 0x3d, 0x7b, 0x5b, 0x2f, 0x09, 0x7b, 0x39, 0x62, 0x7b, 0x89, 0x44, 0x49, - 0xd7, 0x2d, 0x2d, 0xe0, 0xd5, 0x4e, 0x40, 0x7b, 0x0b, 0x0a, 0x4f, 0x2f, - 0x7b, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x82, 0xfe, 0xd3, 0x04, 0x4f, - 0x06, 0x14, 0x00, 0x21, 0x00, 0x2c, 0x00, 0x00, 0x01, 0x15, 0x26, 0x27, - 0x26, 0x23, 0x11, 0x32, 0x37, 0x36, 0x37, 0x15, 0x06, 0x07, 0x06, 0x07, - 0x11, 0x23, 0x11, 0x26, 0x27, 0x26, 0x11, 0x35, 0x10, 0x37, 0x36, 0x37, - 0x35, 0x37, 0x15, 0x16, 0x17, 0x16, 0x01, 0x03, 0x06, 0x07, 0x06, 0x07, - 0x06, 0x17, 0x16, 0x17, 0x16, 0x04, 0x4f, 0x5b, 0x54, 0x55, 0x65, 0x65, - 0x55, 0x54, 0x5b, 0x59, 0x5c, 0x59, 0x5b, 0x64, 0xb9, 0x73, 0xd4, 0xd4, - 0x79, 0xb2, 0x65, 0x5d, 0x59, 0x5c, 0xfe, 0x8a, 0x01, 0x5b, 0x43, 0x76, - 0x0f, 0x0e, 0x0e, 0x19, 0x6c, 0x43, 0x04, 0xa4, 0xd5, 0x69, 0x2d, 0x2d, - 0xfb, 0xf1, 0x2d, 0x2d, 0x69, 0xd3, 0x48, 0x24, 0x22, 0x02, 0xfe, 0xf0, - 0x01, 0x15, 0x17, 0x75, 0xd6, 0x01, 0x39, 0x11, 0x01, 0x42, 0xcb, 0x74, - 0x17, 0xe6, 0x02, 0xe2, 0x02, 0x22, 0x23, 0xfb, 0xa3, 0x03, 0xf9, 0x17, - 0x42, 0x75, 0xaa, 0xa1, 0x66, 0xb4, 0x6c, 0x43, 0x00, 0x02, 0x00, 0x2f, - 0x00, 0x00, 0x04, 0xa2, 0x05, 0xd5, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x00, - 0x13, 0x21, 0x15, 0x21, 0x15, 0x21, 0x15, 0x21, 0x11, 0x23, 0x11, 0x21, - 0x2f, 0x04, 0x73, 0xfb, 0x8d, 0x04, 0x73, 0xfe, 0x2d, 0xcb, 0xfe, 0x2b, - 0x05, 0xd5, 0xaa, 0x78, 0xaa, 0xfb, 0xf7, 0x04, 0x09, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x68, 0x00, 0x00, 0x04, 0x71, 0x05, 0xd5, 0x00, 0x25, - 0x00, 0x00, 0x01, 0x07, 0x21, 0x16, 0x17, 0x21, 0x07, 0x23, 0x06, 0x07, - 0x06, 0x07, 0x16, 0x17, 0x16, 0x17, 0x13, 0x23, 0x03, 0x2e, 0x01, 0x2b, - 0x01, 0x35, 0x33, 0x32, 0x37, 0x36, 0x37, 0x21, 0x37, 0x21, 0x26, 0x27, - 0x26, 0x2b, 0x01, 0x37, 0x04, 0x71, 0x37, 0xfe, 0xa7, 0x56, 0x17, 0x01, - 0x23, 0x37, 0xe3, 0x06, 0x4b, 0x50, 0x92, 0x4e, 0x37, 0x36, 0x53, 0xcb, - 0xd9, 0xb2, 0x4d, 0x7b, 0x63, 0xc1, 0xdd, 0x91, 0x47, 0x3b, 0x0a, 0xfd, - 0xe8, 0x37, 0x01, 0xdb, 0x10, 0x34, 0x4b, 0x90, 0xf3, 0x37, 0x05, 0xd5, - 0x7b, 0x50, 0x7f, 0x7b, 0x86, 0x56, 0x5e, 0x15, 0x14, 0x37, 0x37, 0xa7, - 0xfe, 0x68, 0x01, 0x79, 0xa1, 0x5d, 0xa6, 0x4d, 0x40, 0x66, 0x7b, 0x4c, - 0x35, 0x4e, 0x7b, 0x00, 0x00, 0x02, 0x00, 0x8c, 0xff, 0xe4, 0x04, 0x31, - 0x05, 0xf0, 0x00, 0x17, 0x00, 0x20, 0x00, 0x00, 0x25, 0x16, 0x33, 0x32, - 0x36, 0x37, 0x15, 0x0e, 0x01, 0x23, 0x20, 0x00, 0x11, 0x10, 0x00, 0x21, - 0x32, 0x16, 0x17, 0x15, 0x2e, 0x01, 0x22, 0x0f, 0x01, 0x06, 0x07, 0x06, - 0x11, 0x10, 0x17, 0x16, 0x17, 0x02, 0x01, 0x5f, 0x7c, 0x64, 0x9d, 0x54, - 0x09, 0xc8, 0x84, 0xfe, 0xf8, 0xfe, 0xb8, 0x01, 0x45, 0x01, 0x16, 0x7d, - 0x90, 0x3d, 0x5b, 0x7e, 0xe8, 0x6f, 0x69, 0x08, 0x0b, 0x89, 0x86, 0x0c, - 0x0a, 0x83, 0x37, 0x40, 0x2c, 0x83, 0x05, 0x4c, 0x01, 0xa8, 0x01, 0x5d, - 0x01, 0x72, 0x01, 0x95, 0x34, 0x1e, 0x82, 0x2a, 0x3a, 0x30, 0x4e, 0x08, - 0x0e, 0xb2, 0xfe, 0xaf, 0xfe, 0xcc, 0xbe, 0x11, 0x0b, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x06, 0xff, 0xcf, 0x04, 0xd0, 0x06, 0x04, 0x00, 0x19, - 0x00, 0x1d, 0x00, 0x28, 0x00, 0x32, 0x00, 0x00, 0x01, 0x15, 0x2e, 0x01, - 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x15, 0x0e, - 0x01, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x25, 0x33, - 0x01, 0x23, 0x01, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x10, - 0x2e, 0x01, 0x32, 0x16, 0x15, 0x14, 0x06, 0x22, 0x26, 0x35, 0x34, 0x01, - 0xc4, 0x3a, 0x46, 0x23, 0x4b, 0x56, 0x56, 0x4b, 0x23, 0x46, 0x3a, 0x2d, - 0x51, 0x2e, 0x7e, 0x94, 0x95, 0x83, 0x2a, 0x50, 0x01, 0xca, 0x87, 0xfd, - 0xaa, 0x87, 0x02, 0xc3, 0x3d, 0x49, 0x49, 0x3d, 0x3c, 0x4a, 0x4a, 0xb5, - 0xf2, 0x88, 0x88, 0xf2, 0x87, 0x05, 0x97, 0xb2, 0x34, 0x1e, 0x9c, 0x94, - 0x93, 0x9d, 0x1f, 0x34, 0xb1, 0x22, 0x1d, 0xfc, 0xd1, 0xd4, 0xf9, 0x1b, - 0x4b, 0xf9, 0xcb, 0x03, 0x04, 0x9e, 0x92, 0x91, 0x9f, 0xa0, 0x01, 0x20, - 0xa0, 0x9d, 0xf8, 0xd5, 0xd4, 0xf8, 0xf8, 0xd4, 0xd5, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x3a, 0x00, 0x00, 0x04, 0x9e, 0x05, 0xd5, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x13, 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, 0x21, 0x11, - 0x33, 0x11, 0x25, 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, - 0x11, 0x21, 0x03, 0x8d, 0xbd, 0xfc, 0x44, 0xbe, 0xfe, 0xee, 0x01, 0x66, - 0x01, 0x99, 0x01, 0x65, 0xfe, 0x9b, 0xfe, 0x67, 0xfe, 0x9a, 0x05, 0x71, - 0xfa, 0xf3, 0x05, 0x0d, 0xfa, 0xf3, 0x05, 0x0d, 0x64, 0xfd, 0x88, 0x02, - 0x78, 0xfa, 0x2b, 0x02, 0xdb, 0xfd, 0x25, 0x00, 0x00, 0x01, 0x00, 0x54, - 0x00, 0x00, 0x04, 0x48, 0x06, 0x14, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x03, - 0x23, 0x13, 0x36, 0x37, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, - 0x03, 0x23, 0x01, 0x33, 0x03, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x15, 0x14, - 0x06, 0x04, 0x33, 0x87, 0xb8, 0x87, 0x01, 0x02, 0x0f, 0x5d, 0x57, 0x7f, - 0xb2, 0x21, 0x7b, 0xb8, 0x01, 0x2f, 0xb8, 0x74, 0x4b, 0xaf, 0x62, 0x8b, - 0x9a, 0x0b, 0x02, 0xb6, 0xfd, 0x4a, 0x02, 0xb7, 0x04, 0x0a, 0x47, 0x27, - 0x51, 0x57, 0xba, 0xa8, 0xfd, 0x87, 0x06, 0x14, 0xfd, 0xa4, 0x61, 0x62, - 0x91, 0x82, 0x20, 0x5e, 0x00, 0x01, 0x00, 0x54, 0x00, 0x00, 0x04, 0x48, - 0x06, 0x14, 0x00, 0x1d, 0x00, 0x00, 0x01, 0x36, 0x33, 0x32, 0x16, 0x15, - 0x14, 0x07, 0x03, 0x23, 0x13, 0x36, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, - 0x03, 0x23, 0x13, 0x07, 0x27, 0x3f, 0x01, 0x33, 0x07, 0x25, 0x17, 0x05, - 0x01, 0xc7, 0x97, 0xc5, 0x8b, 0x9a, 0x15, 0x87, 0xb8, 0x87, 0x12, 0x5d, - 0x57, 0x7f, 0xb2, 0x21, 0x7b, 0xb8, 0xe9, 0xde, 0x0b, 0xfe, 0x31, 0xb8, - 0x24, 0x01, 0x1c, 0x0e, 0xfe, 0xc1, 0x03, 0xb8, 0xc3, 0x91, 0x82, 0x45, - 0x6d, 0xfd, 0x4a, 0x02, 0xb7, 0x48, 0x85, 0x57, 0xba, 0xa8, 0xfd, 0x87, - 0x04, 0xad, 0x45, 0x62, 0x4f, 0xfb, 0xbe, 0x59, 0x62, 0x63, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x4a, 0x00, 0x00, 0x04, 0x85, 0x05, 0xd5, 0x00, 0x03, - 0x00, 0x0d, 0x00, 0x00, 0x25, 0x01, 0x23, 0x09, 0x01, 0x21, 0x01, 0x11, - 0x33, 0x11, 0x21, 0x01, 0x11, 0x23, 0x04, 0x20, 0xfd, 0x47, 0xb8, 0x02, - 0xb9, 0xfc, 0xe2, 0x01, 0x48, 0x02, 0xa6, 0x4d, 0xfe, 0xb8, 0xfd, 0x5a, - 0x4d, 0x64, 0x05, 0x0d, 0xfa, 0xf3, 0x05, 0x71, 0xfb, 0x1f, 0x04, 0xe1, - 0xfa, 0x2b, 0x04, 0xe1, 0xfb, 0x1f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0a, - 0x00, 0x00, 0x04, 0xc7, 0x05, 0xd5, 0x00, 0x03, 0x00, 0x09, 0x00, 0x0d, - 0x00, 0x23, 0x00, 0x00, 0x00, 0x20, 0x10, 0x20, 0x13, 0x22, 0x10, 0x33, - 0x32, 0x10, 0x03, 0x21, 0x15, 0x21, 0x01, 0x11, 0x33, 0x13, 0x11, 0x34, - 0x36, 0x33, 0x15, 0x22, 0x06, 0x15, 0x11, 0x23, 0x03, 0x11, 0x14, 0x06, - 0x23, 0x35, 0x32, 0x36, 0x03, 0x65, 0x01, 0x62, 0xfe, 0x9e, 0xb1, 0x32, - 0x32, 0x33, 0xe4, 0x01, 0x62, 0xfe, 0x9e, 0xfd, 0x20, 0xf5, 0xcc, 0x57, - 0xdc, 0x55, 0x26, 0xf5, 0xcc, 0x57, 0xdc, 0x55, 0x26, 0x03, 0x0c, 0xfd, - 0xea, 0x01, 0x95, 0xfe, 0xec, 0x01, 0x14, 0xfe, 0x09, 0x94, 0x01, 0x31, - 0x04, 0xa4, 0xfb, 0x51, 0x03, 0x7e, 0x83, 0xae, 0xb8, 0x3e, 0x3b, 0xfb, - 0x5c, 0x04, 0xaf, 0xfc, 0x82, 0x83, 0xae, 0xb8, 0x3e, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x7d, 0x04, 0xd1, 0x05, 0x4e, 0x00, 0x14, - 0x00, 0x2a, 0x00, 0x33, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x22, 0x0e, 0x02, - 0x15, 0x14, 0x16, 0x17, 0x1e, 0x01, 0x33, 0x32, 0x3e, 0x02, 0x35, 0x34, - 0x2e, 0x02, 0x27, 0x32, 0x16, 0x17, 0x1e, 0x01, 0x15, 0x14, 0x0e, 0x02, - 0x23, 0x22, 0x2e, 0x02, 0x35, 0x34, 0x36, 0x37, 0x3e, 0x01, 0x13, 0x11, - 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x25, 0x21, 0x32, 0x16, 0x15, - 0x14, 0x06, 0x2b, 0x01, 0x11, 0x23, 0x02, 0x68, 0x6a, 0xb5, 0x96, 0x4d, - 0x4d, 0x4b, 0x4c, 0xb5, 0x69, 0x6a, 0xb5, 0x98, 0x4b, 0x4c, 0x96, 0xb5, - 0x6b, 0x7f, 0xda, 0x5a, 0x5a, 0x5c, 0x5b, 0xb6, 0xda, 0x7e, 0x7d, 0xda, - 0xb6, 0x5b, 0x5c, 0x5a, 0x5a, 0xda, 0x26, 0x93, 0x52, 0x58, 0x58, 0x52, - 0xfe, 0xf8, 0x01, 0x08, 0x92, 0x95, 0x95, 0x92, 0x93, 0x75, 0x04, 0xe7, - 0x4a, 0x96, 0xb8, 0x6a, 0x68, 0xb7, 0x4b, 0x4c, 0x4c, 0x4c, 0x98, 0xb5, - 0x69, 0x6a, 0xb8, 0x96, 0x4a, 0x67, 0x5a, 0x5a, 0x5b, 0xdc, 0x7e, 0x7d, - 0xda, 0xb6, 0x5b, 0x5b, 0xb6, 0xda, 0x7d, 0x7e, 0xdc, 0x5b, 0x5a, 0x5a, - 0xfe, 0xb8, 0xfe, 0xe9, 0x49, 0x43, 0x42, 0x49, 0x53, 0x71, 0x6d, 0x6f, - 0x70, 0xfe, 0xd6, 0x00, 0x00, 0x04, 0x00, 0x42, 0x00, 0x00, 0x04, 0x9a, - 0x05, 0xd5, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x16, 0x00, 0x1f, 0x00, 0x00, - 0x13, 0x11, 0x33, 0x11, 0x33, 0x11, 0x21, 0x32, 0x37, 0x11, 0x26, 0x23, - 0x25, 0x21, 0x32, 0x16, 0x15, 0x14, 0x06, 0x2b, 0x01, 0x11, 0x21, 0x01, - 0x11, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0xa2, 0xc0, 0x60, 0x01, - 0x20, 0x17, 0x16, 0x16, 0x17, 0xfd, 0x60, 0x02, 0x73, 0xef, 0xf6, 0xf6, - 0xf0, 0xf2, 0xfe, 0x80, 0x03, 0x31, 0x3a, 0x2b, 0x59, 0x58, 0x2a, 0x05, - 0x71, 0xfa, 0xf3, 0x05, 0x0d, 0xfd, 0x6a, 0x02, 0x02, 0x92, 0x02, 0x64, - 0xdb, 0xd3, 0xd5, 0xda, 0xfd, 0x88, 0x05, 0x5a, 0xfd, 0x99, 0x16, 0x29, - 0x56, 0x9f, 0x9e, 0x56, 0x29, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x11, - 0xfe, 0xf8, 0x04, 0xbc, 0x05, 0xf0, 0x00, 0x10, 0x00, 0x18, 0x00, 0x20, - 0x00, 0x28, 0x00, 0x00, 0x25, 0x13, 0x23, 0x27, 0x07, 0x06, 0x23, 0x20, - 0x00, 0x11, 0x10, 0x00, 0x20, 0x00, 0x11, 0x10, 0x02, 0x25, 0x16, 0x32, - 0x37, 0x11, 0x26, 0x22, 0x07, 0x03, 0x11, 0x06, 0x07, 0x06, 0x10, 0x17, - 0x16, 0x01, 0x11, 0x36, 0x37, 0x36, 0x10, 0x27, 0x26, 0x03, 0x5c, 0xe6, - 0xd3, 0xbf, 0x2c, 0x0f, 0x0e, 0xfe, 0xf0, 0xfe, 0xba, 0x01, 0x46, 0x02, - 0x20, 0x01, 0x45, 0xb5, 0xfd, 0x8d, 0x5d, 0xec, 0x5d, 0x5d, 0xec, 0x5d, - 0x5b, 0x1f, 0x1c, 0x86, 0x86, 0x1c, 0x02, 0x7b, 0x1e, 0x1b, 0x86, 0x86, - 0x1b, 0x1b, 0xfe, 0xdd, 0xef, 0x03, 0x01, 0x01, 0xa5, 0x01, 0x61, 0x01, - 0x62, 0x01, 0xa5, 0xfe, 0x5b, 0xfe, 0x9e, 0xfe, 0xfc, 0xfe, 0x8e, 0x0b, - 0x32, 0x32, 0x04, 0xd7, 0x32, 0x32, 0xfb, 0x6a, 0x04, 0x54, 0x1d, 0x25, - 0xb6, 0xfd, 0x9c, 0xb5, 0x25, 0x04, 0x35, 0xfb, 0xaf, 0x1d, 0x24, 0xb6, - 0x02, 0x63, 0xb6, 0x24, 0x00, 0x05, 0x00, 0x25, 0x00, 0x00, 0x04, 0xbd, - 0x05, 0xd5, 0x00, 0x09, 0x00, 0x1e, 0x00, 0x26, 0x00, 0x2e, 0x00, 0x32, - 0x00, 0x00, 0x01, 0x26, 0x27, 0x26, 0x2b, 0x01, 0x16, 0x17, 0x13, 0x33, - 0x03, 0x1e, 0x01, 0x17, 0x13, 0x21, 0x03, 0x2e, 0x01, 0x2b, 0x01, 0x11, - 0x21, 0x11, 0x21, 0x32, 0x16, 0x15, 0x14, 0x07, 0x06, 0x01, 0x11, 0x21, - 0x32, 0x37, 0x11, 0x26, 0x23, 0x17, 0x11, 0x36, 0x37, 0x36, 0x10, 0x27, - 0x26, 0x25, 0x11, 0x33, 0x11, 0x03, 0xb6, 0x41, 0x3a, 0x3a, 0x66, 0x26, - 0x41, 0x56, 0x79, 0xa9, 0xe0, 0x2d, 0x60, 0x35, 0xad, 0xfe, 0x8b, 0xa2, - 0x3f, 0x76, 0x66, 0x11, 0xfe, 0xab, 0x02, 0x41, 0xd9, 0xd6, 0x64, 0x29, - 0xfd, 0xf2, 0x01, 0x14, 0x15, 0x13, 0x13, 0x15, 0x81, 0x37, 0x25, 0x4c, - 0x4b, 0x24, 0xfd, 0x32, 0xac, 0x01, 0x7f, 0x97, 0x30, 0x31, 0x2f, 0xc9, - 0xfe, 0xe5, 0x02, 0x4f, 0x19, 0x84, 0x7e, 0xfe, 0x68, 0x01, 0x7f, 0x96, - 0x62, 0xfd, 0x89, 0x05, 0xd5, 0xd6, 0xd8, 0xd0, 0x62, 0x29, 0x02, 0xa5, - 0xfd, 0x6a, 0x02, 0x02, 0x92, 0x02, 0x17, 0xfd, 0x99, 0x16, 0x29, 0x56, - 0x01, 0x3e, 0x55, 0x29, 0x2d, 0xfa, 0xf3, 0x05, 0x0d, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x03, 0x93, 0x04, 0x66, 0x05, 0xd5, 0x00, 0x07, - 0x00, 0x14, 0x00, 0x68, 0x40, 0x36, 0x0f, 0x09, 0x0a, 0x09, 0x0e, 0x0a, - 0x0a, 0x09, 0x11, 0x08, 0x09, 0x08, 0x10, 0x09, 0x09, 0x08, 0x42, 0x11, - 0x0e, 0x09, 0x03, 0x01, 0x0f, 0x12, 0x0c, 0x03, 0x05, 0x01, 0xd7, 0x0a, - 0x08, 0x00, 0x88, 0x15, 0x10, 0x0f, 0x0a, 0x09, 0x08, 0x05, 0x11, 0x0d, - 0x60, 0x0b, 0x11, 0x60, 0x13, 0x00, 0x5f, 0x02, 0x60, 0x04, 0x5f, 0x06, - 0x2f, 0xfc, 0xfe, 0xec, 0xd5, 0xee, 0xd6, 0xee, 0x11, 0x17, 0x39, 0x31, - 0x00, 0x10, 0xf4, 0x3c, 0x3c, 0xec, 0x32, 0xd4, 0x3c, 0x3c, 0xc4, 0x11, - 0x17, 0x39, 0x30, 0x4b, 0x53, 0x58, 0x07, 0x10, 0x05, 0xc9, 0x07, 0x10, - 0x04, 0xc9, 0x07, 0x10, 0x04, 0xc9, 0x07, 0x10, 0x05, 0xc9, 0x59, 0x22, - 0x01, 0x15, 0x23, 0x11, 0x23, 0x11, 0x23, 0x35, 0x21, 0x1b, 0x01, 0x33, - 0x11, 0x23, 0x11, 0x03, 0x23, 0x03, 0x11, 0x23, 0x11, 0x01, 0xb6, 0xa2, - 0x72, 0xa2, 0x02, 0xb4, 0x89, 0x7d, 0xac, 0x72, 0x9c, 0x37, 0xa6, 0x71, - 0x05, 0xd5, 0x5e, 0xfe, 0x1c, 0x01, 0xe4, 0x5e, 0xff, 0x00, 0x01, 0x00, - 0xfd, 0xbe, 0x01, 0xe2, 0xfe, 0xd3, 0x01, 0x2d, 0xfe, 0x1e, 0x02, 0x42, - 0x00, 0x02, 0x00, 0x30, 0x00, 0x00, 0x04, 0x99, 0x05, 0xd5, 0x00, 0x03, - 0x00, 0x0d, 0x00, 0x00, 0x25, 0x01, 0x23, 0x01, 0x03, 0x21, 0x15, 0x01, - 0x21, 0x15, 0x21, 0x35, 0x01, 0x21, 0x01, 0x62, 0x02, 0xb6, 0xc5, 0xfd, - 0x4a, 0x5a, 0x04, 0x43, 0xfd, 0x4a, 0x02, 0xc9, 0xfb, 0x97, 0x02, 0xb6, - 0xfd, 0x5d, 0x64, 0x05, 0x0d, 0xfa, 0xf3, 0x05, 0x71, 0x64, 0xfa, 0xf3, - 0x64, 0x64, 0x05, 0x0d, 0xff, 0xff, 0x00, 0x4a, 0x00, 0x00, 0x04, 0x87, - 0x05, 0xb4, 0x10, 0x06, 0x02, 0xf1, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, - 0x00, 0x00, 0x04, 0xc9, 0x05, 0xd5, 0x10, 0x06, 0x00, 0x2e, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, 0x07, 0x6d, 0x10, 0x06, - 0x00, 0x87, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0b, 0xff, 0xe7, 0x04, 0xc6, - 0x05, 0x2d, 0x00, 0x1a, 0x00, 0x29, 0x00, 0x00, 0x37, 0x16, 0x17, 0x16, - 0x20, 0x37, 0x36, 0x37, 0x33, 0x06, 0x07, 0x06, 0x20, 0x24, 0x02, 0x35, - 0x34, 0x12, 0x24, 0x33, 0x32, 0x04, 0x12, 0x15, 0x21, 0x22, 0x15, 0x35, - 0x14, 0x33, 0x21, 0x32, 0x35, 0x11, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, - 0x06, 0x07, 0xe9, 0x36, 0x4b, 0x79, 0x01, 0x0b, 0x7b, 0x55, 0x3e, 0x5a, - 0x4c, 0x74, 0x90, 0xfe, 0xc5, 0xfe, 0xe0, 0xa0, 0xa2, 0x01, 0x22, 0x9a, - 0x98, 0x01, 0x22, 0xa3, 0xfc, 0x33, 0x10, 0x10, 0x02, 0xe0, 0x10, 0x38, - 0x4d, 0x7b, 0x80, 0x81, 0x7b, 0x4d, 0x37, 0xe4, 0x4d, 0x33, 0x54, 0x54, - 0x3c, 0x60, 0x78, 0x47, 0x5a, 0xb3, 0x01, 0x41, 0xaf, 0xb0, 0x01, 0x45, - 0xae, 0xae, 0xfe, 0xbb, 0xb0, 0x13, 0x49, 0x13, 0x13, 0x01, 0x70, 0x50, - 0x33, 0x52, 0x51, 0x34, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x1b, - 0x00, 0x00, 0x03, 0xc0, 0x06, 0x14, 0x00, 0x09, 0x00, 0x0d, 0x00, 0x11, - 0x00, 0x00, 0x01, 0x21, 0x03, 0x21, 0x07, 0x21, 0x37, 0x21, 0x13, 0x23, - 0x13, 0x33, 0x13, 0x23, 0x13, 0x33, 0x07, 0x23, 0x01, 0x42, 0x02, 0x21, - 0xc6, 0x01, 0x23, 0x13, 0xfc, 0x6e, 0x13, 0x01, 0x21, 0xb3, 0xd3, 0x84, - 0x86, 0xb3, 0x86, 0x4f, 0xb8, 0x2d, 0xb8, 0x04, 0x60, 0xfc, 0x04, 0x64, - 0x64, 0x03, 0x98, 0xfc, 0x68, 0x03, 0x98, 0x02, 0x18, 0xe9, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x1b, 0xfe, 0xe3, 0x04, 0x65, 0x06, 0x7b, 0x10, 0x27, - 0x00, 0x75, 0x00, 0xc9, 0xfc, 0x56, 0x10, 0x26, 0x0c, 0xc4, 0x00, 0x00, - 0x10, 0x07, 0x00, 0x7b, 0xfe, 0xfe, 0x00, 0x9c, 0xff, 0xff, 0x00, 0x1b, - 0xfe, 0xe3, 0x04, 0x65, 0x06, 0x8c, 0x10, 0x27, 0x00, 0x75, 0x00, 0xc9, - 0xfc, 0x56, 0x10, 0x26, 0x0c, 0xc4, 0x00, 0x00, 0x10, 0x07, 0x00, 0x74, - 0xfe, 0xfe, 0x00, 0x9c, 0xff, 0xff, 0x00, 0x1b, 0xfe, 0xe3, 0x04, 0x5a, - 0x06, 0x7b, 0x10, 0x27, 0x07, 0x41, 0x00, 0xc9, 0xfc, 0x56, 0x10, 0x26, - 0x0c, 0xc4, 0x00, 0x00, 0x10, 0x07, 0x00, 0x7b, 0xfe, 0xfe, 0x00, 0x9c, - 0xff, 0xff, 0x00, 0x1b, 0xfe, 0xe3, 0x04, 0x5a, 0x06, 0x8c, 0x10, 0x27, - 0x07, 0x41, 0x00, 0xc9, 0xfc, 0x56, 0x10, 0x26, 0x0c, 0xc4, 0x00, 0x00, - 0x10, 0x07, 0x00, 0x74, 0xfe, 0xfe, 0x00, 0x9c, 0xff, 0xff, 0x00, 0x1b, - 0xfe, 0xe3, 0x04, 0x5a, 0x06, 0x8c, 0x10, 0x27, 0x07, 0x41, 0x00, 0xc9, - 0xfc, 0x56, 0x10, 0x26, 0x0c, 0xc4, 0x00, 0x00, 0x10, 0x07, 0x00, 0x75, - 0xfe, 0xfe, 0x00, 0x9c, 0xff, 0xff, 0x00, 0x0a, 0xfe, 0xe3, 0x04, 0x5a, - 0x06, 0x7b, 0x10, 0x27, 0x07, 0x41, 0x00, 0xc9, 0xfc, 0x56, 0x10, 0x26, - 0x0c, 0xc4, 0x00, 0x00, 0x10, 0x07, 0x07, 0x40, 0xfe, 0xfe, 0x00, 0x9c, - 0xff, 0xff, 0x00, 0x1b, 0xfe, 0xe3, 0x04, 0x6a, 0x06, 0x7b, 0x10, 0x27, - 0x07, 0x42, 0x00, 0xc9, 0xfc, 0x56, 0x10, 0x26, 0x0c, 0xc4, 0x00, 0x00, - 0x10, 0x07, 0x00, 0x7b, 0xfe, 0xfe, 0x00, 0x9c, 0xff, 0xff, 0x00, 0x1b, - 0xfe, 0xe3, 0x04, 0x6a, 0x06, 0x7b, 0x10, 0x27, 0x07, 0x42, 0x00, 0xc9, - 0xfc, 0x56, 0x10, 0x26, 0x0c, 0xc4, 0x00, 0x00, 0x10, 0x07, 0x07, 0x41, - 0xfe, 0xfe, 0x00, 0x9c, 0xff, 0xff, 0x00, 0x1b, 0xfe, 0xe2, 0x04, 0x5f, - 0x06, 0x7b, 0x10, 0x27, 0x07, 0x44, 0x00, 0xc9, 0xfc, 0x56, 0x10, 0x26, - 0x0c, 0xc4, 0x00, 0x00, 0x10, 0x07, 0x00, 0x7b, 0xfe, 0xfe, 0x00, 0x9c, - 0xff, 0xff, 0x00, 0x1b, 0xfe, 0xe2, 0x04, 0x5f, 0x06, 0x8c, 0x10, 0x27, - 0x07, 0x44, 0x00, 0xc9, 0xfc, 0x56, 0x10, 0x26, 0x0c, 0xc4, 0x00, 0x00, - 0x10, 0x07, 0x00, 0x75, 0xfe, 0xfe, 0x00, 0x9c, 0xff, 0xff, 0x00, 0x1b, - 0xfe, 0xe2, 0x04, 0x5f, 0x06, 0x7b, 0x10, 0x27, 0x07, 0x44, 0x00, 0xc9, - 0xfc, 0x56, 0x10, 0x26, 0x0c, 0xc4, 0x00, 0x00, 0x10, 0x07, 0x07, 0x41, - 0xfe, 0xfe, 0x00, 0x9c, 0xff, 0xff, 0x00, 0x1b, 0xfe, 0xe2, 0x04, 0x5f, - 0x06, 0x7b, 0x10, 0x27, 0x07, 0x44, 0x00, 0xc9, 0xfc, 0x56, 0x10, 0x26, - 0x0c, 0xc4, 0x00, 0x00, 0x10, 0x07, 0x07, 0x43, 0xfe, 0xfe, 0x00, 0x9c, - 0xff, 0xff, 0x00, 0x1b, 0x01, 0xf8, 0x04, 0x5a, 0x06, 0x7b, 0x10, 0x26, - 0x0c, 0xc4, 0x00, 0x00, 0x10, 0x07, 0x00, 0x7b, 0xfe, 0xfe, 0x00, 0x9c, - 0x00, 0x01, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, 0x03, 0x7d, 0x00, 0x09, - 0x00, 0x00, 0x13, 0x35, 0x01, 0x17, 0x07, 0x21, 0x15, 0x21, 0x17, 0x07, - 0x42, 0x01, 0x23, 0x5a, 0xa0, 0x03, 0x70, 0xfc, 0x90, 0xa0, 0x5a, 0x02, - 0x08, 0x52, 0x01, 0x23, 0x5a, 0xa0, 0xa4, 0xa0, 0x5a, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x1c, 0x00, 0x00, 0x03, 0xb5, 0x04, 0x4d, 0x00, 0x09, - 0x00, 0x00, 0x09, 0x01, 0x07, 0x27, 0x11, 0x23, 0x11, 0x07, 0x27, 0x01, - 0x02, 0x92, 0x01, 0x22, 0x5a, 0xa0, 0xa4, 0xa0, 0x5a, 0x01, 0x24, 0x04, - 0x4d, 0xfe, 0xdd, 0x5a, 0xa0, 0xfc, 0x90, 0x03, 0x70, 0xa0, 0x5a, 0x01, - 0x23, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, - 0x03, 0x7d, 0x00, 0x09, 0x00, 0x00, 0x09, 0x01, 0x27, 0x37, 0x21, 0x35, - 0x21, 0x27, 0x37, 0x01, 0x04, 0x8f, 0xfe, 0xdd, 0x5a, 0xa0, 0xfc, 0x90, - 0x03, 0x70, 0xa0, 0x5a, 0x01, 0x23, 0x02, 0x08, 0xfe, 0xdd, 0x5a, 0xa0, - 0xa4, 0xa0, 0x5a, 0xfe, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x1c, - 0x00, 0x00, 0x03, 0xb5, 0x04, 0x4d, 0x00, 0x09, 0x00, 0x00, 0x21, 0x01, - 0x37, 0x17, 0x11, 0x33, 0x11, 0x37, 0x17, 0x01, 0x02, 0x40, 0xfe, 0xdc, - 0x5a, 0xa0, 0xa4, 0xa0, 0x5a, 0xfe, 0xde, 0x01, 0x23, 0x5a, 0xa0, 0x03, - 0x70, 0xfc, 0x90, 0xa0, 0x5a, 0xfe, 0xdd, 0x00, 0x00, 0x01, 0x00, 0x42, - 0x00, 0xe5, 0x04, 0x8f, 0x03, 0x7d, 0x00, 0x0f, 0x00, 0x00, 0x01, 0x21, - 0x17, 0x07, 0x01, 0x35, 0x01, 0x17, 0x07, 0x21, 0x27, 0x37, 0x01, 0x15, - 0x01, 0x27, 0x03, 0xb2, 0xfd, 0x6d, 0xa0, 0x5a, 0xfe, 0xdd, 0x01, 0x23, - 0x5a, 0xa0, 0x02, 0x93, 0xa0, 0x5a, 0x01, 0x23, 0xfe, 0xdd, 0x5a, 0x01, - 0xdf, 0xa0, 0x5a, 0x01, 0x23, 0x52, 0x01, 0x23, 0x5a, 0xa0, 0xa0, 0x5a, - 0xfe, 0xdd, 0x52, 0xfe, 0xdd, 0x5a, 0x00, 0x00, 0x00, 0x01, 0x01, 0x1c, - 0x00, 0x00, 0x03, 0xb5, 0x04, 0x4d, 0x00, 0x0f, 0x00, 0x00, 0x25, 0x37, - 0x17, 0x01, 0x23, 0x01, 0x37, 0x17, 0x11, 0x07, 0x27, 0x01, 0x33, 0x01, - 0x07, 0x27, 0x02, 0xba, 0xa0, 0x5a, 0xfe, 0xde, 0x52, 0xfe, 0xdc, 0x5a, - 0xa0, 0xa0, 0x5a, 0x01, 0x24, 0x52, 0x01, 0x22, 0x5a, 0xa0, 0xdd, 0xa0, - 0x5a, 0xfe, 0xdd, 0x01, 0x23, 0x5a, 0xa0, 0x02, 0x93, 0xa0, 0x5a, 0x01, - 0x23, 0xfe, 0xdd, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb8, - 0x00, 0x00, 0x04, 0x19, 0x03, 0x61, 0x00, 0x09, 0x00, 0x00, 0x13, 0x37, - 0x21, 0x15, 0x23, 0x01, 0x07, 0x01, 0x15, 0x23, 0xb8, 0x3a, 0x01, 0x9c, - 0xe3, 0x02, 0x6e, 0x74, 0xfd, 0x92, 0x7f, 0x03, 0x27, 0x3a, 0x7f, 0xfd, - 0x92, 0x74, 0x02, 0x6e, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb8, - 0x00, 0x00, 0x04, 0x19, 0x03, 0x61, 0x00, 0x09, 0x00, 0x00, 0x01, 0x11, - 0x23, 0x35, 0x01, 0x27, 0x01, 0x23, 0x35, 0x21, 0x04, 0x19, 0x7f, 0xfd, - 0x92, 0x74, 0x02, 0x6e, 0xe3, 0x01, 0x9c, 0x03, 0x27, 0xfe, 0x64, 0xe3, - 0xfd, 0x92, 0x74, 0x02, 0x6e, 0x7f, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb8, - 0x00, 0x00, 0x04, 0x19, 0x03, 0x61, 0x00, 0x09, 0x00, 0x00, 0x29, 0x01, - 0x35, 0x33, 0x01, 0x37, 0x01, 0x35, 0x33, 0x11, 0x03, 0xdf, 0xfe, 0x64, - 0xe3, 0xfd, 0x92, 0x74, 0x02, 0x6e, 0x7f, 0x7f, 0x02, 0x6e, 0x74, 0xfd, - 0x92, 0xe3, 0xfe, 0x64, 0x00, 0x01, 0x00, 0xb8, 0x00, 0x00, 0x04, 0x19, - 0x03, 0x61, 0x00, 0x09, 0x00, 0x00, 0x37, 0x11, 0x33, 0x15, 0x01, 0x17, - 0x01, 0x33, 0x15, 0x21, 0xb8, 0x7f, 0x02, 0x6e, 0x74, 0xfd, 0x92, 0xe3, - 0xfe, 0x64, 0x3a, 0x01, 0x9c, 0xe3, 0x02, 0x6e, 0x74, 0xfd, 0x92, 0x7f, - 0x00, 0x01, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, 0x03, 0x7d, 0x00, 0x11, - 0x00, 0x00, 0x01, 0x33, 0x15, 0x21, 0x07, 0x27, 0x37, 0x21, 0x17, 0x07, - 0x01, 0x35, 0x01, 0x17, 0x07, 0x21, 0x37, 0x17, 0x03, 0xc1, 0xce, 0xfe, - 0xd1, 0x93, 0x8e, 0x63, 0xfe, 0x7d, 0xa0, 0x5a, 0xfe, 0xdd, 0x01, 0x23, - 0x5a, 0xa0, 0x01, 0xe3, 0x94, 0x8e, 0x02, 0x83, 0xa4, 0xfa, 0x52, 0xa8, - 0xa0, 0x5a, 0x01, 0x23, 0x52, 0x01, 0x23, 0x5a, 0xa0, 0xfa, 0x52, 0x00, - 0x00, 0x01, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, 0x03, 0x7d, 0x00, 0x11, - 0x00, 0x00, 0x01, 0x23, 0x35, 0x21, 0x37, 0x17, 0x07, 0x21, 0x27, 0x37, - 0x01, 0x15, 0x01, 0x27, 0x37, 0x21, 0x07, 0x27, 0x01, 0x10, 0xce, 0x01, - 0x2f, 0x93, 0x8e, 0x63, 0x01, 0x83, 0xa0, 0x5a, 0x01, 0x23, 0xfe, 0xdd, - 0x5a, 0xa0, 0xfe, 0x1d, 0x94, 0x8e, 0x01, 0xdf, 0xa4, 0xfa, 0x52, 0xa8, - 0xa0, 0x5a, 0xfe, 0xdd, 0x52, 0xfe, 0xdd, 0x5a, 0xa0, 0xfa, 0x52, 0x00, - 0x00, 0x01, 0x00, 0x59, 0x01, 0x8b, 0x04, 0x78, 0x03, 0x61, 0x00, 0x35, - 0x00, 0x00, 0x01, 0x16, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, - 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x17, 0x16, 0x17, 0x07, 0x26, 0x27, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, - 0x0e, 0x01, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, - 0x2f, 0x01, 0x15, 0x23, 0x11, 0x37, 0x21, 0x15, 0x01, 0x24, 0x07, 0x66, - 0x12, 0x20, 0x19, 0x21, 0x1f, 0x1a, 0x18, 0x1a, 0x15, 0x0d, 0x11, 0x2b, - 0x21, 0x33, 0x2d, 0x36, 0x38, 0x2b, 0x32, 0x22, 0x2c, 0x18, 0x6a, 0x05, - 0x21, 0x11, 0x21, 0x18, 0x21, 0x1c, 0x1c, 0x19, 0x33, 0x0a, 0x0e, 0x2e, - 0x1e, 0x36, 0x2b, 0x38, 0x35, 0x2e, 0x30, 0x24, 0x6d, 0x7f, 0x3a, 0x01, - 0x9c, 0x02, 0xe2, 0x0c, 0x77, 0x15, 0x12, 0x0f, 0x0f, 0x0c, 0x1d, 0x16, - 0x27, 0x30, 0x37, 0x29, 0x1b, 0x17, 0x17, 0x1c, 0x28, 0x36, 0x3b, 0x43, - 0x12, 0x2b, 0x16, 0x13, 0x0e, 0x0e, 0x0c, 0x3a, 0x20, 0x2c, 0x3a, 0x27, - 0x1d, 0x18, 0x18, 0x19, 0x2b, 0x80, 0xe0, 0x01, 0x9c, 0x3a, 0x7f, 0x00, - 0x00, 0x01, 0x00, 0x59, 0x01, 0x8b, 0x04, 0x78, 0x03, 0x61, 0x00, 0x35, - 0x00, 0x00, 0x01, 0x21, 0x35, 0x21, 0x17, 0x11, 0x23, 0x35, 0x07, 0x06, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x2e, 0x01, 0x27, - 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x06, 0x07, 0x27, 0x36, 0x37, 0x36, - 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, - 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x36, 0x03, 0xad, 0xfe, 0xf5, - 0x01, 0x9c, 0x3a, 0x7f, 0x6d, 0x24, 0x30, 0x2e, 0x35, 0x38, 0x2b, 0x36, - 0x1e, 0x2e, 0x0e, 0x0a, 0x33, 0x19, 0x1c, 0x1c, 0x21, 0x18, 0x21, 0x11, - 0x21, 0x05, 0x6a, 0x18, 0x2c, 0x22, 0x32, 0x2b, 0x38, 0x36, 0x2d, 0x33, - 0x21, 0x2b, 0x11, 0x0d, 0x15, 0x1a, 0x18, 0x1a, 0x1f, 0x21, 0x19, 0x20, - 0x12, 0x66, 0x02, 0xe2, 0x7f, 0x3a, 0xfe, 0x64, 0xe0, 0x80, 0x2b, 0x19, - 0x18, 0x18, 0x1d, 0x27, 0x3a, 0x2c, 0x20, 0x3a, 0x0c, 0x0e, 0x0e, 0x13, - 0x16, 0x2b, 0x12, 0x43, 0x3b, 0x36, 0x28, 0x1c, 0x17, 0x17, 0x1b, 0x29, - 0x37, 0x30, 0x27, 0x16, 0x1d, 0x0c, 0x0f, 0x0f, 0x12, 0x15, 0x77, 0x00, - 0x00, 0x01, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, 0x03, 0x7d, 0x00, 0x11, - 0x00, 0x00, 0x01, 0x21, 0x15, 0x21, 0x17, 0x07, 0x27, 0x23, 0x17, 0x07, - 0x01, 0x35, 0x01, 0x17, 0x07, 0x33, 0x37, 0x17, 0x02, 0x69, 0x02, 0x26, - 0xfd, 0xda, 0xa0, 0x5a, 0xfa, 0x96, 0xa0, 0x5a, 0xfe, 0xdd, 0x01, 0x23, - 0x5a, 0xa0, 0x96, 0xfa, 0x5a, 0x02, 0x83, 0xa4, 0xa0, 0x5a, 0xfa, 0xa0, - 0x5a, 0x01, 0x23, 0x52, 0x01, 0x23, 0x5a, 0xa0, 0xfa, 0x5a, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x1c, 0x00, 0x00, 0x03, 0xb5, 0x04, 0x4d, 0x00, 0x11, - 0x00, 0x00, 0x01, 0x07, 0x27, 0x37, 0x35, 0x07, 0x27, 0x01, 0x33, 0x01, - 0x07, 0x27, 0x15, 0x17, 0x07, 0x27, 0x11, 0x23, 0x02, 0x16, 0xa0, 0x5a, - 0xfa, 0xa0, 0x5a, 0x01, 0x24, 0x52, 0x01, 0x22, 0x5a, 0xa0, 0xfa, 0x5a, - 0xa0, 0xa4, 0x02, 0x26, 0xa0, 0x5a, 0xfa, 0x96, 0xa0, 0x5a, 0x01, 0x23, - 0xfe, 0xdd, 0x5a, 0xa0, 0x96, 0xfa, 0x5a, 0xa0, 0xfd, 0xda, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, 0x03, 0x7d, 0x00, 0x11, - 0x00, 0x00, 0x01, 0x27, 0x37, 0x17, 0x33, 0x27, 0x37, 0x01, 0x15, 0x01, - 0x27, 0x37, 0x23, 0x07, 0x27, 0x37, 0x21, 0x35, 0x02, 0x68, 0xa0, 0x5a, - 0xfa, 0x96, 0xa0, 0x5a, 0x01, 0x23, 0xfe, 0xdd, 0x5a, 0xa0, 0x96, 0xfa, - 0x5a, 0xa0, 0xfd, 0xda, 0x02, 0x83, 0xa0, 0x5a, 0xfa, 0xa0, 0x5a, 0xfe, - 0xdd, 0x52, 0xfe, 0xdd, 0x5a, 0xa0, 0xfa, 0x5a, 0xa0, 0xa4, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x1c, 0x00, 0x00, 0x03, 0xb5, 0x04, 0x4d, 0x00, 0x11, - 0x00, 0x00, 0x01, 0x37, 0x17, 0x07, 0x15, 0x37, 0x17, 0x01, 0x23, 0x01, - 0x37, 0x17, 0x35, 0x27, 0x37, 0x17, 0x11, 0x33, 0x02, 0xba, 0xa0, 0x5a, - 0xfa, 0xa0, 0x5a, 0xfe, 0xde, 0x52, 0xfe, 0xdc, 0x5a, 0xa0, 0xfa, 0x5a, - 0xa0, 0xa4, 0x02, 0x27, 0xa0, 0x5a, 0xfa, 0x96, 0xa0, 0x5a, 0xfe, 0xdd, - 0x01, 0x23, 0x5a, 0xa0, 0x96, 0xfa, 0x5a, 0xa0, 0x02, 0x26, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, 0x03, 0x7d, 0x00, 0x0e, - 0x00, 0x00, 0x01, 0x17, 0x07, 0x27, 0x21, 0x17, 0x07, 0x01, 0x35, 0x01, - 0x17, 0x07, 0x21, 0x37, 0x17, 0x03, 0x9d, 0xf2, 0x5a, 0xfa, 0xfd, 0xe4, - 0xa0, 0x5a, 0xfe, 0xdd, 0x01, 0x23, 0x5a, 0xa0, 0x02, 0x1c, 0xfa, 0x5a, - 0x02, 0x31, 0xf2, 0x5a, 0xfa, 0xa0, 0x5a, 0x01, 0x23, 0x52, 0x01, 0x23, - 0x5a, 0xa0, 0xfa, 0x5a, 0x00, 0x01, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, - 0x03, 0x7d, 0x00, 0x0e, 0x00, 0x00, 0x01, 0x27, 0x37, 0x17, 0x21, 0x27, - 0x37, 0x01, 0x15, 0x01, 0x27, 0x37, 0x21, 0x07, 0x27, 0x01, 0x34, 0xf2, - 0x5a, 0xfa, 0x02, 0x1c, 0xa0, 0x5a, 0x01, 0x23, 0xfe, 0xdd, 0x5a, 0xa0, - 0xfd, 0xe4, 0xfa, 0x5a, 0x02, 0x31, 0xf2, 0x5a, 0xfa, 0xa0, 0x5a, 0xfe, - 0xdd, 0x52, 0xfe, 0xdd, 0x5a, 0xa0, 0xfa, 0x5a, 0x00, 0x01, 0x00, 0x42, - 0x00, 0xe5, 0x04, 0x8f, 0x03, 0x7d, 0x00, 0x0d, 0x00, 0x00, 0x01, 0x35, - 0x33, 0x11, 0x23, 0x35, 0x21, 0x17, 0x07, 0x01, 0x35, 0x01, 0x17, 0x07, - 0x03, 0xeb, 0xa4, 0xa4, 0xfd, 0x34, 0xa0, 0x5a, 0xfe, 0xdd, 0x01, 0x23, - 0x5a, 0xa0, 0x02, 0x83, 0xfa, 0xfd, 0x68, 0xfa, 0xa0, 0x5a, 0x01, 0x23, - 0x52, 0x01, 0x23, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x1c, - 0x00, 0x00, 0x03, 0xb5, 0x04, 0x4d, 0x00, 0x0d, 0x00, 0x00, 0x25, 0x11, - 0x07, 0x27, 0x01, 0x33, 0x01, 0x07, 0x27, 0x11, 0x33, 0x15, 0x21, 0x35, - 0x02, 0x16, 0xa0, 0x5a, 0x01, 0x24, 0x52, 0x01, 0x22, 0x5a, 0xa0, 0xfa, - 0xfd, 0x68, 0xa4, 0x02, 0xcc, 0xa0, 0x5a, 0x01, 0x23, 0xfe, 0xdd, 0x5a, - 0xa0, 0xfd, 0x34, 0xa4, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, - 0x00, 0xe5, 0x04, 0x8f, 0x03, 0x7d, 0x00, 0x0d, 0x00, 0x00, 0x13, 0x21, - 0x27, 0x37, 0x01, 0x15, 0x01, 0x27, 0x37, 0x21, 0x15, 0x23, 0x11, 0x33, - 0xe6, 0x02, 0xcc, 0xa0, 0x5a, 0x01, 0x23, 0xfe, 0xdd, 0x5a, 0xa0, 0xfd, - 0x34, 0xa4, 0xa4, 0x02, 0x83, 0xa0, 0x5a, 0xfe, 0xdd, 0x52, 0xfe, 0xdd, - 0x5a, 0xa0, 0xfa, 0x02, 0x98, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x1c, - 0x00, 0x00, 0x03, 0xb5, 0x04, 0x4d, 0x00, 0x0d, 0x00, 0x00, 0x01, 0x11, - 0x37, 0x17, 0x01, 0x23, 0x01, 0x37, 0x17, 0x11, 0x23, 0x35, 0x21, 0x15, - 0x02, 0xba, 0xa0, 0x5a, 0xfe, 0xde, 0x52, 0xfe, 0xdc, 0x5a, 0xa0, 0xfa, - 0x02, 0x98, 0x03, 0xa9, 0xfd, 0x34, 0xa0, 0x5a, 0xfe, 0xdd, 0x01, 0x23, - 0x5a, 0xa0, 0x02, 0xcc, 0xa4, 0xa4, 0x00, 0x00, 0x00, 0x01, 0x01, 0x1c, - 0x00, 0x00, 0x03, 0xb5, 0x04, 0x4d, 0x00, 0x13, 0x00, 0x00, 0x25, 0x27, - 0x37, 0x17, 0x11, 0x07, 0x27, 0x01, 0x33, 0x01, 0x07, 0x27, 0x11, 0x37, - 0x17, 0x07, 0x33, 0x15, 0x21, 0x35, 0x02, 0x16, 0xfa, 0x5a, 0xa0, 0xa0, - 0x5a, 0x01, 0x24, 0x52, 0x01, 0x22, 0x5a, 0xa0, 0xa0, 0x5a, 0xfa, 0xfa, - 0xfd, 0x68, 0xa4, 0xfa, 0x5a, 0xa0, 0x02, 0x18, 0xa0, 0x5a, 0x01, 0x23, - 0xfe, 0xdd, 0x5a, 0xa0, 0xfd, 0xe8, 0xa0, 0x5a, 0xfa, 0xa4, 0xa4, 0x00, - 0x00, 0x01, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, 0x04, 0x23, 0x00, 0x28, - 0x00, 0x00, 0x01, 0x32, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, - 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x23, 0x35, 0x32, 0x16, 0x17, 0x16, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x21, - 0x17, 0x07, 0x01, 0x35, 0x01, 0x17, 0x07, 0x03, 0x64, 0x1e, 0x1a, 0x17, - 0x13, 0x11, 0x0a, 0x0a, 0x09, 0x0a, 0x12, 0x10, 0x1a, 0x17, 0x19, 0x3e, - 0x62, 0x2d, 0x2a, 0x16, 0x16, 0x15, 0x14, 0x2c, 0x25, 0x3a, 0x30, 0x1f, - 0xfd, 0x93, 0xa0, 0x5a, 0xfe, 0xdd, 0x01, 0x23, 0x5a, 0xa0, 0x02, 0x83, - 0x0a, 0x09, 0x12, 0x11, 0x17, 0x18, 0x19, 0x1b, 0x15, 0x17, 0x12, 0x10, - 0x0b, 0x0a, 0xa4, 0x2a, 0x2b, 0x28, 0x35, 0x34, 0x3c, 0x38, 0x35, 0x32, - 0x2e, 0x26, 0x1a, 0x15, 0xa0, 0x5a, 0x01, 0x23, 0x52, 0x01, 0x23, 0x5a, - 0xa0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, - 0x04, 0x23, 0x00, 0x29, 0x00, 0x00, 0x01, 0x21, 0x27, 0x37, 0x01, 0x15, - 0x01, 0x27, 0x37, 0x21, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, - 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x15, 0x22, 0x07, 0x06, - 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, - 0x01, 0x6d, 0x02, 0x45, 0xa0, 0x5a, 0x01, 0x23, 0xfe, 0xdd, 0x5a, 0xa0, - 0xfd, 0x93, 0x1f, 0x30, 0x3a, 0x25, 0x2c, 0x14, 0x15, 0x16, 0x16, 0x2a, - 0x2d, 0x31, 0x31, 0x3e, 0x19, 0x17, 0x1a, 0x10, 0x12, 0x0a, 0x09, 0x0a, - 0x0a, 0x11, 0x13, 0x17, 0x1a, 0x02, 0x83, 0xa0, 0x5a, 0xfe, 0xdd, 0x52, - 0xfe, 0xdd, 0x5a, 0xa0, 0x15, 0x1a, 0x26, 0x2e, 0x32, 0x35, 0x38, 0x3c, - 0x34, 0x35, 0x28, 0x2b, 0x15, 0x15, 0xa4, 0x0a, 0x0b, 0x10, 0x12, 0x17, - 0x15, 0x1b, 0x19, 0x18, 0x17, 0x11, 0x12, 0x09, 0x0a, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, 0x04, 0x23, 0x00, 0x24, - 0x00, 0x3e, 0x00, 0x00, 0x01, 0x32, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, - 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x2b, 0x01, 0x15, 0x23, 0x35, - 0x21, 0x17, 0x07, 0x01, 0x35, 0x01, 0x17, 0x07, 0x21, 0x35, 0x34, 0x37, - 0x36, 0x37, 0x36, 0x37, 0x36, 0x17, 0x22, 0x07, 0x06, 0x07, 0x06, 0x07, - 0x06, 0x1d, 0x01, 0x33, 0x32, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, - 0x34, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x03, 0x6c, 0x3e, 0x62, 0x2d, - 0x2a, 0x16, 0x16, 0x15, 0x14, 0x2c, 0x25, 0x3a, 0x30, 0x1f, 0x97, 0xa4, - 0xfe, 0xce, 0xa0, 0x5a, 0xfe, 0xdd, 0x01, 0x23, 0x5a, 0xa0, 0x01, 0x32, - 0x15, 0x16, 0x29, 0x2d, 0x30, 0x31, 0x39, 0x11, 0x1a, 0x16, 0x12, 0x0f, - 0x0c, 0x09, 0x6f, 0x1e, 0x1a, 0x17, 0x13, 0x11, 0x0a, 0x0a, 0x09, 0x0a, - 0x12, 0x10, 0x1a, 0x17, 0x04, 0x23, 0x2a, 0x2b, 0x28, 0x35, 0x34, 0x3c, - 0x38, 0x35, 0x32, 0x2e, 0x26, 0x1a, 0x15, 0xd5, 0xd5, 0xa0, 0x5a, 0x01, - 0x23, 0x52, 0x01, 0x23, 0x5a, 0xa0, 0x7d, 0x3b, 0x34, 0x37, 0x28, 0x2b, - 0x15, 0x14, 0xa3, 0x0a, 0x0a, 0x11, 0x0f, 0x1b, 0x16, 0x1a, 0x7d, 0x0a, - 0x09, 0x12, 0x11, 0x17, 0x18, 0x19, 0x1b, 0x15, 0x17, 0x12, 0x10, 0x0b, - 0x0a, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, - 0x04, 0x23, 0x00, 0x25, 0x00, 0x3f, 0x00, 0x00, 0x01, 0x16, 0x17, 0x16, - 0x17, 0x16, 0x17, 0x16, 0x1d, 0x01, 0x21, 0x27, 0x37, 0x01, 0x15, 0x01, - 0x27, 0x37, 0x21, 0x15, 0x23, 0x35, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, - 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x17, 0x22, - 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, - 0x17, 0x16, 0x3b, 0x01, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, - 0x01, 0x65, 0x39, 0x31, 0x30, 0x2d, 0x29, 0x16, 0x15, 0x01, 0x32, 0xa0, - 0x5a, 0x01, 0x23, 0xfe, 0xdd, 0x5a, 0xa0, 0xfe, 0xce, 0xa4, 0x97, 0x1f, - 0x30, 0x3a, 0x25, 0x2c, 0x14, 0x15, 0x16, 0x16, 0x2a, 0x2d, 0x31, 0x31, - 0x3e, 0x19, 0x17, 0x1a, 0x10, 0x12, 0x0a, 0x09, 0x0a, 0x0a, 0x11, 0x13, - 0x17, 0x1a, 0x1e, 0x6f, 0x09, 0x0c, 0x0f, 0x12, 0x16, 0x1a, 0x04, 0x23, - 0x01, 0x14, 0x15, 0x2b, 0x28, 0x37, 0x34, 0x3b, 0x7d, 0xa0, 0x5a, 0xfe, - 0xdd, 0x52, 0xfe, 0xdd, 0x5a, 0xa0, 0xd5, 0xd5, 0x15, 0x1a, 0x26, 0x2e, - 0x32, 0x35, 0x38, 0x3c, 0x34, 0x35, 0x28, 0x2b, 0x15, 0x15, 0xa4, 0x0a, - 0x0b, 0x10, 0x12, 0x17, 0x15, 0x1b, 0x19, 0x18, 0x17, 0x11, 0x12, 0x09, - 0x0a, 0x7d, 0x1a, 0x16, 0x1b, 0x0f, 0x11, 0x0a, 0x0a, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, 0x03, 0x7d, 0x00, 0x58, - 0x00, 0x00, 0x01, 0x33, 0x16, 0x17, 0x16, 0x17, 0x1e, 0x01, 0x32, 0x36, - 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x17, 0x16, 0x17, 0x16, 0x17, 0x1e, 0x01, 0x32, 0x36, 0x37, 0x36, 0x37, - 0x36, 0x3f, 0x01, 0x27, 0x37, 0x01, 0x15, 0x01, 0x27, 0x37, 0x23, 0x26, - 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, - 0x26, 0x27, 0x26, 0x27, 0x26, 0x22, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, - 0x07, 0x06, 0x07, 0x06, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x07, - 0x23, 0x17, 0x07, 0x01, 0x35, 0x01, 0x17, 0x01, 0x1f, 0x08, 0x21, 0x18, - 0x18, 0x19, 0x07, 0x10, 0x13, 0x10, 0x07, 0x07, 0x04, 0x0b, 0x16, 0x17, - 0x1a, 0x1b, 0x1f, 0x21, 0x19, 0x1e, 0x13, 0x16, 0x0b, 0x03, 0x07, 0x07, - 0x11, 0x12, 0x11, 0x07, 0x1e, 0x13, 0x17, 0x1a, 0x0f, 0xa0, 0x5a, 0x01, - 0x23, 0xfe, 0xdd, 0x5a, 0xa0, 0x06, 0x0c, 0x06, 0x09, 0x07, 0x1b, 0x15, - 0x1b, 0x3e, 0x1b, 0x1b, 0x16, 0x19, 0x08, 0x03, 0x07, 0x07, 0x09, 0x08, - 0x13, 0x08, 0x08, 0x07, 0x07, 0x03, 0x08, 0x1a, 0x15, 0x1c, 0x1a, 0x3e, - 0x1b, 0x18, 0x19, 0x07, 0x09, 0x06, 0x0b, 0x07, 0xa0, 0x5a, 0xfe, 0xdd, - 0x01, 0x23, 0x5a, 0x02, 0x83, 0x03, 0x10, 0x11, 0x22, 0x09, 0x0b, 0x0b, - 0x09, 0x0c, 0x0c, 0x2a, 0x21, 0x23, 0x10, 0x11, 0x11, 0x15, 0x1e, 0x24, - 0x27, 0x0c, 0x0c, 0x09, 0x0b, 0x0b, 0x09, 0x2a, 0x09, 0x0c, 0x04, 0x03, - 0xa0, 0x5a, 0xfe, 0xdd, 0x52, 0xfe, 0xdd, 0x5a, 0xa0, 0x01, 0x05, 0x05, - 0x0a, 0x25, 0x0d, 0x11, 0x11, 0x12, 0x20, 0x27, 0x25, 0x0c, 0x0b, 0x0a, - 0x05, 0x06, 0x06, 0x05, 0x0a, 0x08, 0x0f, 0x25, 0x27, 0x20, 0x12, 0x11, - 0x11, 0x10, 0x22, 0x0a, 0x05, 0x05, 0x01, 0xa0, 0x5a, 0x01, 0x23, 0x52, - 0x01, 0x23, 0x5a, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0xd1, 0x04, 0x8f, - 0x03, 0x91, 0x00, 0x17, 0x00, 0x00, 0x01, 0x21, 0x03, 0x27, 0x37, 0x23, - 0x17, 0x07, 0x01, 0x35, 0x01, 0x17, 0x07, 0x21, 0x13, 0x17, 0x07, 0x33, - 0x27, 0x37, 0x01, 0x15, 0x01, 0x27, 0x03, 0xb2, 0xfe, 0xe8, 0x3c, 0x8c, - 0x32, 0xe5, 0xa0, 0x5a, 0xfe, 0xdd, 0x01, 0x23, 0x5a, 0xa0, 0x01, 0x06, - 0x3c, 0x8c, 0x32, 0xf7, 0xa0, 0x5a, 0x01, 0x23, 0xfe, 0xdd, 0x5a, 0x01, - 0xdf, 0xfe, 0xf2, 0x20, 0xee, 0xa0, 0x5a, 0x01, 0x23, 0x52, 0x01, 0x23, - 0x5a, 0xa0, 0x01, 0x0e, 0x20, 0xee, 0xa0, 0x5a, 0xfe, 0xdd, 0x52, 0xfe, - 0xdd, 0x5a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x71, 0x00, 0x00, 0x04, 0x60, - 0x05, 0x95, 0x00, 0x0d, 0x00, 0x00, 0x25, 0x37, 0x17, 0x05, 0x27, 0x03, - 0x37, 0x17, 0x13, 0x01, 0x13, 0x17, 0x03, 0x01, 0x03, 0x5d, 0xb8, 0x4a, - 0xfe, 0xb1, 0x51, 0xef, 0x67, 0x84, 0x7a, 0xfd, 0x3d, 0x97, 0xa0, 0x5a, - 0x02, 0xc3, 0xd3, 0x84, 0x68, 0xef, 0x0d, 0x01, 0x50, 0x4a, 0xb9, 0x02, - 0xd4, 0xfe, 0x56, 0x03, 0x7d, 0x1e, 0xfd, 0xec, 0x01, 0xaa, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xb7, 0x00, 0x00, 0x04, 0x1a, 0x05, 0x65, 0x00, 0x0b, - 0x00, 0x00, 0x01, 0x17, 0x07, 0x01, 0x35, 0x01, 0x17, 0x07, 0x21, 0x11, - 0x23, 0x11, 0x01, 0x94, 0xa0, 0x5a, 0xfe, 0xde, 0x01, 0x22, 0x5a, 0xa0, - 0x02, 0x86, 0xa4, 0x03, 0xc7, 0xa0, 0x5a, 0x01, 0x23, 0x52, 0x01, 0x23, - 0x5a, 0xa0, 0xfb, 0x95, 0x03, 0xc7, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb7, - 0x00, 0x00, 0x04, 0x1a, 0x05, 0x65, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x21, - 0x11, 0x23, 0x11, 0x21, 0x27, 0x37, 0x01, 0x15, 0x01, 0x27, 0x03, 0x3c, - 0xfe, 0x20, 0xa4, 0x02, 0x84, 0xa0, 0x5a, 0x01, 0x24, 0xfe, 0xdc, 0x5a, - 0x03, 0xc7, 0xfc, 0x39, 0x04, 0x6b, 0xa0, 0x5a, 0xfe, 0xdd, 0x52, 0xfe, - 0xdd, 0x5a, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb7, 0x00, 0x00, 0x04, 0x1a, - 0x05, 0x65, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x21, 0x11, 0x33, 0x11, 0x21, - 0x17, 0x07, 0x01, 0x35, 0x01, 0x17, 0x01, 0x94, 0x01, 0xe2, 0xa4, 0xfd, - 0x7a, 0xa0, 0x5a, 0xfe, 0xde, 0x01, 0x22, 0x5a, 0x01, 0x9e, 0x03, 0xc7, - 0xfb, 0x95, 0xa0, 0x5a, 0x01, 0x23, 0x52, 0x01, 0x23, 0x5a, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xb7, 0x00, 0x00, 0x04, 0x1a, 0x05, 0x65, 0x00, 0x0b, - 0x00, 0x00, 0x01, 0x27, 0x37, 0x01, 0x15, 0x01, 0x27, 0x37, 0x21, 0x11, - 0x33, 0x11, 0x03, 0x3c, 0xa0, 0x5a, 0x01, 0x24, 0xfe, 0xdc, 0x5a, 0xa0, - 0xfd, 0x7c, 0xa4, 0x01, 0x9e, 0xa0, 0x5a, 0xfe, 0xdd, 0x52, 0xfe, 0xdd, - 0x5a, 0xa0, 0x04, 0x6b, 0xfc, 0x39, 0x00, 0x00, 0x00, 0x01, 0x00, 0xba, - 0x00, 0x00, 0x04, 0x17, 0x04, 0x52, 0x00, 0x0b, 0x00, 0x00, 0x25, 0x11, - 0x21, 0x35, 0x21, 0x11, 0x37, 0x17, 0x01, 0x23, 0x01, 0x37, 0x02, 0x79, - 0xfe, 0x41, 0x02, 0x63, 0xa0, 0x5a, 0xfe, 0xdd, 0x52, 0xfe, 0xdd, 0x5a, - 0xdd, 0x02, 0xd1, 0xa4, 0xfc, 0x8b, 0xa0, 0x5a, 0xfe, 0xdd, 0x01, 0x23, - 0x5a, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x3f, 0x00, 0x00, 0x04, 0x92, - 0x03, 0x5d, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x21, 0x11, 0x33, 0x11, 0x21, - 0x17, 0x07, 0x01, 0x35, 0x01, 0x17, 0x01, 0x1c, 0x02, 0xd2, 0xa4, 0xfc, - 0x8a, 0xa0, 0x5a, 0xfe, 0xde, 0x01, 0x22, 0x5a, 0x01, 0x9e, 0x01, 0xbf, - 0xfd, 0x9d, 0xa0, 0x5a, 0x01, 0x23, 0x52, 0x01, 0x23, 0x5a, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x51, 0x01, 0x58, 0x04, 0x80, 0x03, 0xe5, 0x00, 0x29, - 0x00, 0x00, 0x01, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, - 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x23, 0x34, 0x27, 0x26, - 0x27, 0x26, 0x27, 0x26, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, - 0x17, 0x15, 0x37, 0x17, 0x01, 0x23, 0x01, 0x37, 0x01, 0x4b, 0x01, 0x01, - 0x24, 0x1e, 0x3c, 0x39, 0x4a, 0x47, 0x54, 0x57, 0x44, 0x4c, 0x37, 0x3a, - 0x20, 0x1e, 0x01, 0x98, 0x13, 0x13, 0x25, 0x23, 0x30, 0x28, 0x37, 0x39, - 0x29, 0x2e, 0x25, 0x24, 0x14, 0x11, 0x02, 0xa0, 0x5a, 0xfe, 0xdd, 0x52, - 0xfe, 0xdd, 0x5a, 0x02, 0x35, 0x18, 0x4e, 0x53, 0x48, 0x3b, 0x39, 0x1e, - 0x1d, 0x1d, 0x21, 0x36, 0x3a, 0x49, 0x46, 0x54, 0x37, 0x2f, 0x30, 0x27, - 0x24, 0x17, 0x13, 0x01, 0x01, 0x12, 0x14, 0x26, 0x24, 0x32, 0x28, 0x47, - 0x17, 0xa0, 0x5a, 0xfe, 0xdd, 0x01, 0x23, 0x5a, 0x00, 0x01, 0x00, 0x51, - 0x01, 0x58, 0x04, 0x80, 0x03, 0xe5, 0x00, 0x2a, 0x00, 0x00, 0x01, 0x37, - 0x17, 0x01, 0x23, 0x01, 0x37, 0x17, 0x35, 0x36, 0x27, 0x26, 0x27, 0x26, - 0x27, 0x26, 0x27, 0x26, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x30, - 0x23, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x17, 0x16, 0x17, 0x16, 0x17, 0x03, 0x86, 0xa0, 0x5a, 0xfe, 0xdd, 0x52, - 0xfe, 0xdd, 0x5a, 0xa0, 0x02, 0x11, 0x14, 0x24, 0x25, 0x2e, 0x29, 0x39, - 0x37, 0x28, 0x30, 0x23, 0x25, 0x13, 0x13, 0x98, 0x01, 0x1e, 0x20, 0x3a, - 0x37, 0x4c, 0x44, 0x57, 0x54, 0x47, 0x4a, 0x39, 0x3c, 0x1e, 0x24, 0x01, - 0x02, 0x35, 0xa0, 0x5a, 0xfe, 0xdd, 0x01, 0x23, 0x5a, 0xa0, 0x17, 0x47, - 0x28, 0x32, 0x24, 0x26, 0x14, 0x12, 0x01, 0x01, 0x13, 0x17, 0x24, 0x27, - 0x30, 0x2f, 0x37, 0x54, 0x46, 0x49, 0x3a, 0x36, 0x21, 0x1d, 0x1d, 0x1e, - 0x39, 0x3b, 0x48, 0x53, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x32, - 0x00, 0x00, 0x04, 0x9f, 0x04, 0x1a, 0x00, 0x09, 0x00, 0x0d, 0x00, 0x00, - 0x13, 0x37, 0x21, 0x15, 0x23, 0x01, 0x07, 0x01, 0x15, 0x23, 0x03, 0x35, - 0x21, 0x15, 0xb8, 0x3a, 0x01, 0x9c, 0xe3, 0x02, 0x6e, 0x74, 0xfd, 0x92, - 0x7f, 0x86, 0x04, 0x6c, 0x03, 0x27, 0x3a, 0x7f, 0xfd, 0x92, 0x74, 0x02, - 0x6e, 0xe3, 0x02, 0x3f, 0x50, 0x50, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, - 0x00, 0x00, 0x04, 0x8f, 0x04, 0xd6, 0x00, 0x0d, 0x00, 0x1b, 0x00, 0x00, - 0x13, 0x01, 0x17, 0x07, 0x21, 0x15, 0x21, 0x17, 0x07, 0x01, 0x11, 0x23, - 0x11, 0x33, 0x01, 0x11, 0x33, 0x11, 0x23, 0x11, 0x01, 0x27, 0x37, 0x21, - 0x35, 0x21, 0x27, 0x37, 0xe6, 0x01, 0x23, 0x5a, 0xa0, 0x02, 0xcc, 0xfd, - 0x34, 0xa0, 0x5a, 0xfe, 0xdd, 0xa4, 0xa4, 0x03, 0x05, 0xa4, 0xa4, 0xfe, - 0xdd, 0x5a, 0xa0, 0xfd, 0x34, 0x02, 0xcc, 0xa0, 0x5a, 0x03, 0xb3, 0x01, - 0x23, 0x5a, 0xa0, 0xa4, 0xa0, 0x5a, 0x01, 0x23, 0xfe, 0xdd, 0x02, 0x98, - 0xfc, 0x9f, 0x01, 0x23, 0xfd, 0x68, 0x01, 0x23, 0xfe, 0xdd, 0x5a, 0xa0, - 0xa4, 0xa0, 0x5a, 0x00, 0x00, 0x01, 0x00, 0x58, 0x00, 0x00, 0x04, 0x79, - 0x03, 0xf9, 0x00, 0x36, 0x00, 0x00, 0x01, 0x17, 0x16, 0x17, 0x16, 0x15, - 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, - 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x17, 0x06, 0x07, 0x06, - 0x15, 0x14, 0x16, 0x17, 0x16, 0x17, 0x16, 0x32, 0x37, 0x36, 0x37, 0x3e, - 0x01, 0x35, 0x34, 0x27, 0x26, 0x2f, 0x01, 0x15, 0x23, 0x11, 0x37, 0x21, - 0x15, 0x03, 0x95, 0x1d, 0x4a, 0x25, 0x25, 0x25, 0x27, 0x48, 0x44, 0x5f, - 0x53, 0x6c, 0x68, 0x58, 0x5b, 0x48, 0x4a, 0x25, 0x25, 0x25, 0x25, 0x4a, - 0x77, 0x34, 0x18, 0x19, 0x32, 0x32, 0x2d, 0x41, 0x38, 0x90, 0x3b, 0x3e, - 0x31, 0x31, 0x32, 0x19, 0x1e, 0x2d, 0x21, 0x7f, 0x3a, 0x01, 0x9c, 0x03, - 0x7a, 0x1d, 0x4a, 0x5a, 0x5b, 0x67, 0x68, 0x58, 0x5c, 0x48, 0x43, 0x2b, - 0x25, 0x25, 0x27, 0x47, 0x4b, 0x59, 0x5b, 0x65, 0x67, 0x5b, 0x57, 0x4d, - 0x73, 0x32, 0x3d, 0x3e, 0x46, 0x44, 0x7b, 0x32, 0x2c, 0x1e, 0x19, 0x19, - 0x1b, 0x2f, 0x32, 0x7b, 0x44, 0x46, 0x3e, 0x48, 0x27, 0x1c, 0xe3, 0x01, - 0x9c, 0x3a, 0x7f, 0x00, 0x00, 0x01, 0x00, 0x58, 0x00, 0x00, 0x04, 0x79, - 0x03, 0xf9, 0x00, 0x36, 0x00, 0x00, 0x01, 0x23, 0x35, 0x21, 0x17, 0x11, - 0x23, 0x35, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x16, 0x17, 0x16, 0x17, - 0x16, 0x32, 0x37, 0x36, 0x37, 0x3e, 0x01, 0x35, 0x34, 0x27, 0x26, 0x27, - 0x37, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, - 0x37, 0x01, 0x3c, 0xe3, 0x01, 0x9c, 0x3a, 0x7f, 0x21, 0x2d, 0x1e, 0x19, - 0x32, 0x31, 0x31, 0x3e, 0x3b, 0x90, 0x38, 0x41, 0x2d, 0x32, 0x32, 0x19, - 0x18, 0x34, 0x77, 0x4a, 0x25, 0x25, 0x25, 0x25, 0x4a, 0x48, 0x5b, 0x58, - 0x68, 0x6c, 0x53, 0x5f, 0x44, 0x48, 0x27, 0x26, 0x26, 0x26, 0x49, 0x03, - 0x7a, 0x7f, 0x3a, 0xfe, 0x64, 0xe3, 0x1c, 0x27, 0x48, 0x3e, 0x46, 0x44, - 0x7b, 0x32, 0x2f, 0x1b, 0x19, 0x19, 0x1e, 0x2c, 0x32, 0x7b, 0x44, 0x46, - 0x3e, 0x3d, 0x32, 0x73, 0x4d, 0x57, 0x5b, 0x67, 0x65, 0x5b, 0x59, 0x4b, - 0x47, 0x27, 0x25, 0x25, 0x2b, 0x43, 0x48, 0x5c, 0x58, 0x68, 0x67, 0x5b, - 0x5b, 0x49, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x01, 0xdf, 0x04, 0x8f, - 0x03, 0x7d, 0x00, 0x06, 0x00, 0x00, 0x13, 0x35, 0x01, 0x17, 0x07, 0x21, - 0x15, 0x42, 0x01, 0x23, 0x5a, 0xa0, 0x03, 0x70, 0x01, 0xdf, 0x7b, 0x01, - 0x23, 0x5a, 0xa0, 0xa4, 0x00, 0x01, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, - 0x02, 0x83, 0x00, 0x06, 0x00, 0x00, 0x13, 0x21, 0x15, 0x21, 0x17, 0x07, - 0x01, 0x42, 0x04, 0x4d, 0xfc, 0x90, 0xa0, 0x5a, 0xfe, 0xdd, 0x02, 0x83, - 0xa4, 0xa0, 0x5a, 0x01, 0x23, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x16, - 0x00, 0x00, 0x03, 0xb5, 0x04, 0x4d, 0x00, 0x06, 0x00, 0x00, 0x01, 0x33, - 0x01, 0x07, 0x27, 0x11, 0x23, 0x02, 0x16, 0x7c, 0x01, 0x22, 0x5a, 0xa0, - 0xa4, 0x04, 0x4d, 0xfe, 0xdd, 0x5a, 0xa0, 0xfc, 0x90, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x1c, 0x00, 0x00, 0x02, 0xbb, 0x04, 0x4d, 0x00, 0x06, - 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x07, 0x27, 0x01, 0x02, 0xba, 0xa4, - 0xa0, 0x5a, 0x01, 0x24, 0x04, 0x4d, 0xfb, 0xb3, 0x03, 0x70, 0xa0, 0x5a, - 0x01, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x01, 0xdf, 0x04, 0x8f, - 0x03, 0x7d, 0x00, 0x06, 0x00, 0x00, 0x01, 0x21, 0x35, 0x21, 0x27, 0x37, - 0x01, 0x04, 0x8f, 0xfb, 0xb3, 0x03, 0x70, 0xa0, 0x5a, 0x01, 0x23, 0x01, - 0xdf, 0xa4, 0xa0, 0x5a, 0xfe, 0xdd, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, - 0x00, 0xe5, 0x04, 0x8f, 0x02, 0x83, 0x00, 0x06, 0x00, 0x00, 0x01, 0x15, - 0x01, 0x27, 0x37, 0x21, 0x35, 0x04, 0x8f, 0xfe, 0xdd, 0x5a, 0xa0, 0xfc, - 0x90, 0x02, 0x83, 0x7b, 0xfe, 0xdd, 0x5a, 0xa0, 0xa4, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x02, 0x16, 0x00, 0x00, 0x03, 0xb5, 0x04, 0x4d, 0x00, 0x06, - 0x00, 0x00, 0x21, 0x11, 0x33, 0x11, 0x37, 0x17, 0x01, 0x02, 0x16, 0xa4, - 0xa0, 0x5a, 0xfe, 0xde, 0x04, 0x4d, 0xfc, 0x90, 0xa0, 0x5a, 0xfe, 0xdd, - 0x00, 0x01, 0x01, 0x47, 0x00, 0x00, 0x02, 0xe5, 0x04, 0x4d, 0x00, 0x06, - 0x00, 0x00, 0x21, 0x23, 0x01, 0x37, 0x17, 0x11, 0x33, 0x02, 0xe5, 0x7b, - 0xfe, 0xdd, 0x5a, 0xa0, 0xa4, 0x01, 0x23, 0x5a, 0xa0, 0x03, 0x70, 0x00, - 0x00, 0x02, 0x00, 0x42, 0x00, 0x00, 0x04, 0x8f, 0x04, 0x7c, 0x00, 0x09, - 0x00, 0x13, 0x00, 0x00, 0x09, 0x01, 0x27, 0x37, 0x21, 0x35, 0x21, 0x27, - 0x37, 0x09, 0x01, 0x35, 0x01, 0x17, 0x07, 0x21, 0x15, 0x21, 0x17, 0x07, - 0x04, 0x8f, 0xfe, 0xdd, 0x5a, 0xa0, 0xfc, 0x90, 0x03, 0x70, 0xa0, 0x5a, - 0x01, 0x23, 0xfb, 0xb3, 0x01, 0x23, 0x5a, 0xa0, 0x03, 0x70, 0xfc, 0x90, - 0xa0, 0x5a, 0x03, 0x07, 0xfe, 0xdd, 0x5a, 0xa0, 0xa4, 0xa0, 0x5a, 0xfe, - 0xdd, 0xfd, 0xca, 0x52, 0x01, 0x23, 0x5a, 0xa0, 0xa4, 0xa0, 0x5a, 0x00, - 0x00, 0x02, 0x00, 0x2a, 0x00, 0x00, 0x04, 0xa7, 0x04, 0x4d, 0x00, 0x09, - 0x00, 0x13, 0x00, 0x00, 0x21, 0x01, 0x37, 0x17, 0x11, 0x33, 0x11, 0x37, - 0x17, 0x09, 0x01, 0x33, 0x01, 0x07, 0x27, 0x11, 0x23, 0x11, 0x07, 0x27, - 0x03, 0x32, 0xfe, 0xdc, 0x5a, 0xa0, 0xa4, 0xa0, 0x5a, 0xfe, 0xde, 0xfd, - 0xca, 0x52, 0x01, 0x22, 0x5a, 0xa0, 0xa4, 0xa0, 0x5a, 0x01, 0x23, 0x5a, - 0xa0, 0x03, 0x70, 0xfc, 0x90, 0xa0, 0x5a, 0xfe, 0xdd, 0x04, 0x4d, 0xfe, - 0xdd, 0x5a, 0xa0, 0xfc, 0x90, 0x03, 0x70, 0xa0, 0x5a, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x42, 0x00, 0x00, 0x04, 0x8f, 0x04, 0x7c, 0x00, 0x09, - 0x00, 0x13, 0x00, 0x00, 0x01, 0x15, 0x01, 0x27, 0x37, 0x21, 0x35, 0x21, - 0x27, 0x37, 0x25, 0x01, 0x17, 0x07, 0x21, 0x15, 0x21, 0x17, 0x07, 0x01, - 0x04, 0x8f, 0xfe, 0xdd, 0x5a, 0xa0, 0xfc, 0x90, 0x03, 0x70, 0xa0, 0x5a, - 0xfc, 0xd6, 0x01, 0x23, 0x5a, 0xa0, 0x03, 0x70, 0xfc, 0x90, 0xa0, 0x5a, - 0xfe, 0xdd, 0x01, 0x75, 0x52, 0xfe, 0xdd, 0x5a, 0xa0, 0xa4, 0xa0, 0x5a, - 0xc1, 0x01, 0x23, 0x5a, 0xa0, 0xa4, 0xa0, 0x5a, 0x01, 0x23, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x42, 0x00, 0x00, 0x04, 0x8f, 0x04, 0x7c, 0x00, 0x11, - 0x00, 0x00, 0x01, 0x27, 0x35, 0x01, 0x17, 0x07, 0x21, 0x15, 0x21, 0x17, - 0x07, 0x21, 0x15, 0x21, 0x17, 0x07, 0x01, 0x35, 0x01, 0x0b, 0xc9, 0x01, - 0x23, 0x5a, 0xa0, 0x03, 0x70, 0xfc, 0x90, 0xa0, 0xa0, 0x03, 0x70, 0xfc, - 0x90, 0xa0, 0x5a, 0xfe, 0xdd, 0x02, 0x3e, 0xc9, 0x52, 0x01, 0x23, 0x5a, - 0xa0, 0xa4, 0xa0, 0xa0, 0xa4, 0xa0, 0x5a, 0x01, 0x23, 0x52, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x2a, 0x00, 0x00, 0x04, 0xa7, 0x04, 0x4d, 0x00, 0x11, - 0x00, 0x00, 0x01, 0x37, 0x33, 0x01, 0x07, 0x27, 0x11, 0x23, 0x11, 0x07, - 0x27, 0x11, 0x23, 0x11, 0x07, 0x27, 0x01, 0x33, 0x02, 0x68, 0xca, 0x52, - 0x01, 0x22, 0x5a, 0xa0, 0xa4, 0xa0, 0xa0, 0xa4, 0xa0, 0x5a, 0x01, 0x24, - 0x52, 0x03, 0x84, 0xc9, 0xfe, 0xdd, 0x5a, 0xa0, 0xfc, 0x90, 0x03, 0x70, - 0xa0, 0xa0, 0xfc, 0x90, 0x03, 0x70, 0xa0, 0x5a, 0x01, 0x23, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x42, 0x00, 0x00, 0x04, 0x8f, 0x04, 0x7c, 0x00, 0x11, - 0x00, 0x00, 0x01, 0x17, 0x15, 0x01, 0x27, 0x37, 0x21, 0x35, 0x21, 0x27, - 0x37, 0x21, 0x35, 0x21, 0x27, 0x37, 0x01, 0x15, 0x03, 0xc6, 0xc9, 0xfe, - 0xdd, 0x5a, 0xa0, 0xfc, 0x90, 0x03, 0x70, 0xa0, 0xa0, 0xfc, 0x90, 0x03, - 0x70, 0xa0, 0x5a, 0x01, 0x23, 0x02, 0x3e, 0xc9, 0x52, 0xfe, 0xdd, 0x5a, - 0xa0, 0xa4, 0xa0, 0xa0, 0xa4, 0xa0, 0x5a, 0xfe, 0xdd, 0x52, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x2a, 0x00, 0x00, 0x04, 0xa7, 0x04, 0x4d, 0x00, 0x11, - 0x00, 0x00, 0x25, 0x07, 0x23, 0x01, 0x37, 0x17, 0x11, 0x33, 0x11, 0x37, - 0x17, 0x11, 0x33, 0x11, 0x37, 0x17, 0x01, 0x23, 0x02, 0x68, 0xc8, 0x52, - 0xfe, 0xdc, 0x5a, 0xa0, 0xa4, 0xa0, 0xa0, 0xa4, 0xa0, 0x5a, 0xfe, 0xde, - 0x52, 0xc9, 0xc9, 0x01, 0x23, 0x5a, 0xa0, 0x03, 0x70, 0xfc, 0x90, 0xa0, - 0xa0, 0x03, 0x70, 0xfc, 0x90, 0xa0, 0x5a, 0xfe, 0xdd, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x42, 0x00, 0x41, 0x04, 0x8f, 0x04, 0x21, 0x00, 0x06, - 0x00, 0x0d, 0x00, 0x00, 0x01, 0x15, 0x01, 0x27, 0x37, 0x21, 0x3d, 0x02, - 0x01, 0x17, 0x07, 0x21, 0x15, 0x04, 0x8f, 0xfe, 0xdd, 0x5a, 0xa0, 0xfc, - 0x90, 0x01, 0x23, 0x5a, 0xa0, 0x03, 0x70, 0x01, 0xdf, 0x7b, 0xfe, 0xdd, - 0x5a, 0xa0, 0xa4, 0xa4, 0x7b, 0x01, 0x23, 0x5a, 0xa0, 0xa4, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x42, 0x00, 0x41, 0x04, 0x8f, 0x04, 0x21, 0x00, 0x06, - 0x00, 0x0d, 0x00, 0x00, 0x13, 0x21, 0x15, 0x21, 0x17, 0x07, 0x09, 0x01, - 0x21, 0x35, 0x21, 0x27, 0x37, 0x01, 0x42, 0x04, 0x4d, 0xfc, 0x90, 0xa0, - 0x5a, 0xfe, 0xdd, 0x04, 0x4d, 0xfb, 0xb3, 0x03, 0x70, 0xa0, 0x5a, 0x01, - 0x23, 0x01, 0xdf, 0xa4, 0xa0, 0x5a, 0x01, 0x23, 0x01, 0x1f, 0xa4, 0xa0, - 0x5a, 0xfe, 0xdd, 0x00, 0x00, 0x02, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, - 0x03, 0x7d, 0x00, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x21, 0x37, 0x17, - 0x07, 0x33, 0x15, 0x21, 0x07, 0x21, 0x15, 0x21, 0x07, 0x27, 0x37, 0x23, - 0x17, 0x07, 0x01, 0x35, 0x01, 0x17, 0x05, 0x21, 0x07, 0x17, 0x21, 0x01, - 0x71, 0x01, 0xa3, 0x56, 0x61, 0x36, 0xfa, 0xfe, 0xd2, 0x5a, 0x01, 0x88, - 0xfe, 0x45, 0x56, 0x60, 0x36, 0xe3, 0x4e, 0x5a, 0xfe, 0xdd, 0x01, 0x23, - 0x5a, 0x01, 0x22, 0xfe, 0x3e, 0x52, 0x52, 0x01, 0x6a, 0x02, 0xd5, 0xa8, - 0x3b, 0x6d, 0x52, 0xa4, 0x52, 0xa6, 0x3a, 0x6c, 0x4e, 0x5a, 0x01, 0x23, - 0x52, 0x01, 0x23, 0x5a, 0xa0, 0x52, 0x52, 0x00, 0x00, 0x03, 0x00, 0x42, - 0x00, 0xe5, 0x04, 0x8f, 0x03, 0xaf, 0x00, 0x04, 0x00, 0x1c, 0x00, 0x21, - 0x00, 0x00, 0x01, 0x21, 0x07, 0x17, 0x33, 0x37, 0x33, 0x27, 0x37, 0x01, - 0x15, 0x01, 0x27, 0x37, 0x23, 0x07, 0x27, 0x37, 0x23, 0x17, 0x07, 0x01, - 0x35, 0x01, 0x17, 0x07, 0x33, 0x37, 0x17, 0x03, 0x07, 0x21, 0x37, 0x27, - 0x02, 0x21, 0xfe, 0xfe, 0x52, 0x52, 0xdf, 0xc8, 0x9a, 0x4e, 0x5a, 0x01, - 0x23, 0xfe, 0xdd, 0x5a, 0x4e, 0xe3, 0x1f, 0x8c, 0x1b, 0x7c, 0x4e, 0x5a, - 0xfe, 0xdd, 0x01, 0x23, 0x5a, 0x4e, 0xc2, 0x2e, 0x8c, 0x39, 0x23, 0x01, - 0x21, 0x52, 0x52, 0x02, 0x83, 0x52, 0x52, 0xf6, 0x4e, 0x5a, 0xfe, 0xdd, - 0x52, 0xfe, 0xdd, 0x5a, 0x4e, 0x9e, 0x20, 0x7e, 0x4e, 0x5a, 0x01, 0x23, - 0x52, 0x01, 0x23, 0x5a, 0x4e, 0xda, 0x20, 0xfe, 0xf4, 0xa4, 0x52, 0x52, - 0x00, 0x02, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, 0x03, 0x7d, 0x00, 0x15, - 0x00, 0x1a, 0x00, 0x00, 0x01, 0x21, 0x07, 0x27, 0x37, 0x23, 0x35, 0x21, - 0x37, 0x21, 0x35, 0x21, 0x37, 0x17, 0x07, 0x33, 0x27, 0x37, 0x01, 0x15, - 0x01, 0x27, 0x25, 0x21, 0x37, 0x27, 0x21, 0x03, 0x60, 0xfe, 0x5d, 0x56, - 0x61, 0x36, 0xfa, 0x01, 0x2e, 0x5a, 0xfe, 0x78, 0x01, 0xbb, 0x56, 0x60, - 0x36, 0xe3, 0x4e, 0x5a, 0x01, 0x23, 0xfe, 0xdd, 0x5a, 0xfe, 0xde, 0x01, - 0xc2, 0x52, 0x52, 0xfe, 0x96, 0x01, 0x8d, 0xa8, 0x3b, 0x6d, 0x52, 0xa4, - 0x52, 0xa6, 0x3a, 0x6c, 0x4e, 0x5a, 0xfe, 0xdd, 0x52, 0xfe, 0xdd, 0x5a, - 0xa0, 0x52, 0x52, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, - 0x03, 0x7d, 0x00, 0x0e, 0x00, 0x00, 0x01, 0x07, 0x17, 0x21, 0x15, 0x21, - 0x17, 0x07, 0x01, 0x35, 0x01, 0x17, 0x07, 0x21, 0x15, 0x01, 0x1f, 0x52, - 0x52, 0x03, 0x70, 0xfc, 0xe2, 0x4e, 0x5a, 0xfe, 0xdd, 0x01, 0x23, 0x5a, - 0x4e, 0x03, 0x1e, 0x02, 0x83, 0x52, 0x52, 0x52, 0x4e, 0x5a, 0x01, 0x23, - 0x52, 0x01, 0x23, 0x5a, 0x4e, 0x52, 0x00, 0x00, 0x00, 0x01, 0x01, 0x1c, - 0x00, 0x00, 0x03, 0xb5, 0x04, 0x4d, 0x00, 0x0e, 0x00, 0x00, 0x01, 0x11, - 0x23, 0x11, 0x07, 0x27, 0x01, 0x33, 0x01, 0x07, 0x27, 0x11, 0x23, 0x13, - 0x27, 0x02, 0x16, 0x52, 0x4e, 0x5a, 0x01, 0x24, 0x52, 0x01, 0x22, 0x5a, - 0x4e, 0x52, 0x01, 0x53, 0x03, 0x70, 0xfc, 0x90, 0x03, 0x1e, 0x4e, 0x5a, - 0x01, 0x23, 0xfe, 0xdd, 0x5a, 0x4e, 0xfc, 0xe2, 0x03, 0x70, 0x52, 0x00, - 0x00, 0x01, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, 0x03, 0x7d, 0x00, 0x0e, - 0x00, 0x00, 0x01, 0x21, 0x35, 0x21, 0x27, 0x37, 0x01, 0x15, 0x01, 0x27, - 0x37, 0x21, 0x35, 0x21, 0x37, 0x03, 0xb2, 0xfc, 0x90, 0x03, 0x1e, 0x4e, - 0x5a, 0x01, 0x23, 0xfe, 0xdd, 0x5a, 0x4e, 0xfc, 0xe2, 0x03, 0x70, 0x52, - 0x02, 0x83, 0x52, 0x4e, 0x5a, 0xfe, 0xdd, 0x52, 0xfe, 0xdd, 0x5a, 0x4e, - 0x52, 0x52, 0x00, 0x00, 0x00, 0x01, 0x01, 0x1c, 0x00, 0x00, 0x03, 0xb5, - 0x04, 0x4d, 0x00, 0x0e, 0x00, 0x00, 0x25, 0x03, 0x33, 0x11, 0x37, 0x17, - 0x01, 0x23, 0x01, 0x37, 0x17, 0x11, 0x33, 0x11, 0x17, 0x02, 0xbb, 0x01, - 0x52, 0x4e, 0x5a, 0xfe, 0xde, 0x52, 0xfe, 0xdc, 0x5a, 0x4e, 0x52, 0x52, - 0xdd, 0x03, 0x70, 0xfc, 0xe2, 0x4e, 0x5a, 0xfe, 0xdd, 0x01, 0x23, 0x5a, - 0x4e, 0x03, 0x1e, 0xfc, 0x90, 0x52, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, - 0x00, 0xe5, 0x04, 0x8f, 0x03, 0x7d, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, - 0x01, 0x21, 0x07, 0x17, 0x21, 0x37, 0x2f, 0x01, 0x37, 0x01, 0x15, 0x01, - 0x27, 0x37, 0x21, 0x17, 0x07, 0x01, 0x35, 0x01, 0x17, 0x07, 0x03, 0xb2, - 0xfd, 0x6d, 0x52, 0x52, 0x02, 0x93, 0x52, 0xa4, 0x4e, 0x5a, 0x01, 0x23, - 0xfe, 0xdd, 0x5a, 0x4e, 0xfe, 0x11, 0x4e, 0x5a, 0xfe, 0xdd, 0x01, 0x23, - 0x5a, 0x4e, 0x02, 0x83, 0x52, 0x52, 0x52, 0xa4, 0x4e, 0x5a, 0xfe, 0xdd, - 0x52, 0xfe, 0xdd, 0x5a, 0x4e, 0x4e, 0x5a, 0x01, 0x23, 0x52, 0x01, 0x23, - 0x5a, 0x4e, 0x00, 0x00, 0x00, 0x02, 0x01, 0x1c, 0x00, 0x00, 0x03, 0xb5, - 0x04, 0x4d, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x01, 0x27, 0x07, 0x11, - 0x17, 0x37, 0x13, 0x11, 0x37, 0x17, 0x01, 0x23, 0x01, 0x37, 0x17, 0x11, - 0x07, 0x27, 0x01, 0x33, 0x01, 0x07, 0x02, 0xbb, 0x53, 0x52, 0x52, 0x53, - 0x51, 0x4e, 0x5a, 0xfe, 0xde, 0x52, 0xfe, 0xdc, 0x5a, 0x4e, 0x4e, 0x5a, - 0x01, 0x24, 0x52, 0x01, 0x22, 0x5a, 0x03, 0x70, 0x52, 0x52, 0xfd, 0x6d, - 0x52, 0x52, 0x02, 0x41, 0xfe, 0x11, 0x4e, 0x5a, 0xfe, 0xdd, 0x01, 0x23, - 0x5a, 0x4e, 0x01, 0xef, 0x4e, 0x5a, 0x01, 0x23, 0xfe, 0xdd, 0x5a, 0x00, - 0x00, 0x01, 0x00, 0x9b, 0xff, 0xc6, 0x04, 0x36, 0x03, 0x61, 0x00, 0x0e, - 0x00, 0x00, 0x01, 0x23, 0x15, 0x01, 0x07, 0x01, 0x15, 0x23, 0x11, 0x37, - 0x21, 0x15, 0x23, 0x01, 0x07, 0x01, 0x8e, 0x74, 0x02, 0x6e, 0x3a, 0xfd, - 0xcc, 0x7f, 0x3a, 0x01, 0x9c, 0x6e, 0x02, 0x33, 0x3a, 0x02, 0xe2, 0x74, - 0xfd, 0x92, 0x3a, 0x02, 0x35, 0x70, 0x01, 0x9c, 0x3a, 0x7f, 0xfd, 0xcc, - 0x3a, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x9b, 0xff, 0xc6, 0x04, 0x36, - 0x03, 0x61, 0x00, 0x0e, 0x00, 0x00, 0x09, 0x01, 0x27, 0x01, 0x23, 0x35, - 0x21, 0x17, 0x11, 0x23, 0x35, 0x01, 0x27, 0x01, 0x35, 0x03, 0x43, 0xfd, - 0x92, 0x3a, 0x02, 0x33, 0x6e, 0x01, 0x9c, 0x3a, 0x7f, 0xfd, 0xcc, 0x3a, - 0x02, 0x6e, 0x02, 0xe2, 0xfd, 0x92, 0x3a, 0x02, 0x34, 0x7f, 0x3a, 0xfe, - 0x64, 0x70, 0xfd, 0xcb, 0x3a, 0x02, 0x6e, 0x74, 0x00, 0x01, 0x00, 0x9b, - 0x00, 0x00, 0x04, 0x36, 0x03, 0x9b, 0x00, 0x0e, 0x00, 0x00, 0x25, 0x01, - 0x37, 0x01, 0x35, 0x33, 0x11, 0x07, 0x21, 0x35, 0x33, 0x01, 0x37, 0x01, - 0x33, 0x03, 0xb7, 0xfd, 0x92, 0x3a, 0x02, 0x34, 0x7f, 0x3a, 0xfe, 0x64, - 0x70, 0xfd, 0xcb, 0x3a, 0x02, 0x6e, 0x74, 0xf3, 0x02, 0x6e, 0x3a, 0xfd, - 0xcd, 0x6e, 0xfe, 0x64, 0x3a, 0x7f, 0x02, 0x34, 0x3a, 0xfd, 0x92, 0x00, - 0x00, 0x01, 0x00, 0x9b, 0x00, 0x00, 0x04, 0x36, 0x03, 0x9b, 0x00, 0x0e, - 0x00, 0x00, 0x25, 0x01, 0x17, 0x01, 0x33, 0x15, 0x21, 0x27, 0x11, 0x33, - 0x15, 0x01, 0x17, 0x01, 0x15, 0x01, 0x8e, 0x02, 0x6e, 0x3a, 0xfd, 0xcd, - 0x6e, 0xfe, 0x64, 0x3a, 0x7f, 0x02, 0x34, 0x3a, 0xfd, 0x92, 0x7f, 0x02, - 0x6e, 0x3a, 0xfd, 0xcc, 0x7f, 0x3a, 0x01, 0x9c, 0x70, 0x02, 0x35, 0x3a, - 0xfd, 0x92, 0x74, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, - 0x03, 0x7d, 0x00, 0x0f, 0x00, 0x00, 0x01, 0x07, 0x01, 0x35, 0x01, 0x17, - 0x21, 0x15, 0x21, 0x07, 0x21, 0x15, 0x21, 0x17, 0x21, 0x15, 0x01, 0xbf, - 0x5a, 0xfe, 0xdd, 0x01, 0x23, 0x5a, 0x02, 0xd0, 0xfc, 0xde, 0x77, 0x03, - 0x99, 0xfc, 0x67, 0x77, 0x03, 0x22, 0x01, 0x3f, 0x5a, 0x01, 0x23, 0x52, - 0x01, 0x23, 0x5a, 0x52, 0x77, 0x52, 0x77, 0x52, 0x00, 0x01, 0x00, 0x42, - 0x00, 0xe5, 0x04, 0x8f, 0x03, 0x7d, 0x00, 0x0f, 0x00, 0x00, 0x01, 0x21, - 0x35, 0x21, 0x37, 0x21, 0x35, 0x21, 0x27, 0x21, 0x35, 0x21, 0x37, 0x01, - 0x15, 0x01, 0x03, 0x12, 0xfd, 0x30, 0x03, 0x22, 0x77, 0xfc, 0x67, 0x03, - 0x99, 0x77, 0xfc, 0xde, 0x02, 0xd0, 0x5a, 0x01, 0x23, 0xfe, 0xdd, 0x01, - 0x3f, 0x52, 0x77, 0x52, 0x77, 0x52, 0x5a, 0xfe, 0xdd, 0x52, 0xfe, 0xdd, - 0x00, 0x01, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, 0x03, 0x7d, 0x00, 0x16, - 0x00, 0x00, 0x01, 0x33, 0x17, 0x37, 0x17, 0x37, 0x17, 0x37, 0x33, 0x15, - 0x07, 0x27, 0x07, 0x27, 0x07, 0x27, 0x23, 0x17, 0x07, 0x01, 0x35, 0x01, - 0x17, 0x01, 0x1f, 0x81, 0x3a, 0x97, 0x96, 0x96, 0x96, 0x3b, 0x21, 0x5c, - 0x96, 0x96, 0x96, 0x97, 0x5b, 0x60, 0xa0, 0x5a, 0xfe, 0xdd, 0x01, 0x23, - 0x5a, 0x02, 0x83, 0x43, 0xad, 0xad, 0xad, 0xad, 0x43, 0xa4, 0x6a, 0xad, - 0xad, 0xad, 0xad, 0x6a, 0xa0, 0x5a, 0x01, 0x23, 0x52, 0x01, 0x23, 0x5a, - 0x00, 0x01, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, 0x03, 0x7d, 0x00, 0x16, - 0x00, 0x00, 0x01, 0x27, 0x37, 0x01, 0x15, 0x01, 0x27, 0x37, 0x23, 0x07, - 0x27, 0x07, 0x27, 0x07, 0x27, 0x35, 0x33, 0x17, 0x37, 0x17, 0x37, 0x17, - 0x37, 0x03, 0xb2, 0xa0, 0x5a, 0x01, 0x23, 0xfe, 0xdd, 0x5a, 0xa0, 0x60, - 0x5b, 0x97, 0x96, 0x96, 0x96, 0x5c, 0x21, 0x3b, 0x96, 0x96, 0x96, 0x97, - 0x3a, 0x02, 0x83, 0xa0, 0x5a, 0xfe, 0xdd, 0x52, 0xfe, 0xdd, 0x5a, 0xa0, - 0x6a, 0xad, 0xad, 0xad, 0xad, 0x6a, 0xa4, 0x43, 0xad, 0xad, 0xad, 0xad, - 0x43, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x1c, 0x00, 0x00, 0x03, 0xb5, - 0x04, 0x4d, 0x00, 0x19, 0x00, 0x00, 0x25, 0x15, 0x23, 0x35, 0x23, 0x35, - 0x33, 0x35, 0x23, 0x35, 0x33, 0x35, 0x07, 0x27, 0x01, 0x33, 0x01, 0x07, - 0x27, 0x15, 0x33, 0x15, 0x23, 0x15, 0x33, 0x15, 0x02, 0xba, 0xa4, 0xfa, - 0xfa, 0xfa, 0xfa, 0xa0, 0x5a, 0x01, 0x24, 0x52, 0x01, 0x22, 0x5a, 0xa0, - 0xfa, 0xfa, 0xfa, 0xbc, 0xbc, 0xbc, 0xa4, 0x74, 0xa4, 0xf8, 0xa0, 0x5a, - 0x01, 0x23, 0xfe, 0xdd, 0x5a, 0xa0, 0xf8, 0xa4, 0x74, 0xa4, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x1c, 0x00, 0x00, 0x03, 0xb5, 0x04, 0x4d, 0x00, 0x19, - 0x00, 0x00, 0x01, 0x35, 0x33, 0x15, 0x33, 0x15, 0x23, 0x15, 0x33, 0x15, - 0x23, 0x15, 0x37, 0x17, 0x01, 0x23, 0x01, 0x37, 0x17, 0x35, 0x23, 0x35, - 0x33, 0x35, 0x23, 0x35, 0x02, 0x16, 0xa4, 0xfa, 0xfa, 0xfa, 0xfa, 0xa0, - 0x5a, 0xfe, 0xde, 0x52, 0xfe, 0xdc, 0x5a, 0xa0, 0xfa, 0xfa, 0xfa, 0x03, - 0x90, 0xbd, 0xbd, 0xa4, 0x74, 0xa4, 0xf7, 0xa0, 0x5a, 0xfe, 0xdd, 0x01, - 0x23, 0x5a, 0xa0, 0xf7, 0xa4, 0x74, 0xa4, 0x00, 0x00, 0x03, 0x00, 0x42, - 0x00, 0xe5, 0x04, 0x8f, 0x03, 0x7d, 0x00, 0x09, 0x00, 0x0d, 0x00, 0x11, - 0x00, 0x00, 0x01, 0x15, 0x21, 0x17, 0x07, 0x01, 0x35, 0x01, 0x17, 0x07, - 0x05, 0x35, 0x33, 0x15, 0x33, 0x35, 0x33, 0x15, 0x02, 0x21, 0xfe, 0xfe, - 0xa0, 0x5a, 0xfe, 0xdd, 0x01, 0x23, 0x5a, 0xa0, 0x01, 0x7f, 0xbb, 0x7b, - 0xbb, 0x02, 0x83, 0xa4, 0xa0, 0x5a, 0x01, 0x23, 0x52, 0x01, 0x23, 0x5a, - 0xa0, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0x00, 0x00, 0x00, 0x03, 0x01, 0x1c, - 0x00, 0x00, 0x03, 0xb5, 0x04, 0x4d, 0x00, 0x09, 0x00, 0x0d, 0x00, 0x11, - 0x00, 0x00, 0x01, 0x11, 0x07, 0x27, 0x01, 0x33, 0x01, 0x07, 0x27, 0x13, - 0x07, 0x17, 0x23, 0x37, 0x13, 0x15, 0x23, 0x37, 0x02, 0x16, 0xa0, 0x5a, - 0x01, 0x24, 0x52, 0x01, 0x22, 0x5a, 0xa0, 0x01, 0x01, 0x01, 0xa5, 0x01, - 0xa3, 0xa4, 0x01, 0x02, 0x6e, 0x01, 0x02, 0xa0, 0x5a, 0x01, 0x23, 0xfe, - 0xdd, 0x5a, 0xa0, 0xfe, 0xfe, 0x7d, 0xbb, 0xbb, 0xfe, 0xca, 0xbb, 0xbb, - 0x00, 0x03, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, 0x03, 0x7d, 0x00, 0x09, - 0x00, 0x0d, 0x00, 0x11, 0x00, 0x00, 0x01, 0x21, 0x27, 0x37, 0x01, 0x15, - 0x01, 0x27, 0x37, 0x21, 0x2b, 0x01, 0x35, 0x33, 0x05, 0x23, 0x35, 0x33, - 0x02, 0xb0, 0x01, 0x02, 0xa0, 0x5a, 0x01, 0x23, 0xfe, 0xdd, 0x5a, 0xa0, - 0xfe, 0xfe, 0x7d, 0xbb, 0xbb, 0xfe, 0xca, 0xbb, 0xbb, 0x02, 0x83, 0xa0, - 0x5a, 0xfe, 0xdd, 0x52, 0xfe, 0xdd, 0x5a, 0xa0, 0xa4, 0xa4, 0xa4, 0x00, - 0x00, 0x03, 0x01, 0x1c, 0x00, 0x00, 0x03, 0xb5, 0x04, 0x4d, 0x00, 0x09, - 0x00, 0x0d, 0x00, 0x11, 0x00, 0x00, 0x01, 0x11, 0x37, 0x17, 0x01, 0x23, - 0x01, 0x37, 0x17, 0x11, 0x37, 0x27, 0x33, 0x15, 0x03, 0x27, 0x33, 0x15, - 0x02, 0xba, 0xa0, 0x5a, 0xfe, 0xde, 0x52, 0xfe, 0xdc, 0x5a, 0xa0, 0x01, - 0x01, 0xa4, 0xa3, 0x01, 0xa4, 0x01, 0xdf, 0xfe, 0xfe, 0xa0, 0x5a, 0xfe, - 0xdd, 0x01, 0x23, 0x5a, 0xa0, 0x01, 0x02, 0x7d, 0xbb, 0xbb, 0x01, 0x36, - 0xbb, 0xbb, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, - 0x03, 0x7d, 0x00, 0x0d, 0x00, 0x00, 0x13, 0x01, 0x17, 0x07, 0x21, 0x15, - 0x21, 0x17, 0x07, 0x01, 0x11, 0x23, 0x11, 0x33, 0xe6, 0x01, 0x23, 0x5a, - 0xa0, 0x02, 0xcc, 0xfd, 0x34, 0xa0, 0x5a, 0xfe, 0xdd, 0xa4, 0xa4, 0x02, - 0x5a, 0x01, 0x23, 0x5a, 0xa0, 0xa4, 0xa0, 0x5a, 0x01, 0x23, 0xfe, 0xdd, - 0x02, 0x98, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, - 0x03, 0x7d, 0x00, 0x0d, 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, 0x23, 0x11, - 0x01, 0x27, 0x37, 0x21, 0x35, 0x21, 0x27, 0x37, 0x03, 0xeb, 0xa4, 0xa4, - 0xfe, 0xdd, 0x5a, 0xa0, 0xfd, 0x34, 0x02, 0xcc, 0xa0, 0x5a, 0x02, 0x5a, - 0x01, 0x23, 0xfd, 0x68, 0x01, 0x23, 0xfe, 0xdd, 0x5a, 0xa0, 0xa4, 0xa0, - 0x5a, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x19, 0x00, 0xbc, 0x04, 0x8f, - 0x03, 0xa6, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x00, 0x01, 0x07, 0x17, 0x35, - 0x21, 0x35, 0x21, 0x13, 0x09, 0x01, 0x15, 0x21, 0x11, 0x21, 0x01, 0x3f, - 0xc2, 0xc2, 0x03, 0x0a, 0xfc, 0xf6, 0x4f, 0xfe, 0x8b, 0x01, 0x75, 0x03, - 0x01, 0xfc, 0xff, 0x02, 0xf4, 0xc3, 0xc3, 0x5d, 0xcc, 0xfe, 0x25, 0x01, - 0x75, 0x01, 0x75, 0xc9, 0xfe, 0xa8, 0x00, 0x00, 0x00, 0x02, 0x00, 0xf3, - 0x00, 0x00, 0x03, 0xde, 0x04, 0x76, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x00, - 0x01, 0x33, 0x11, 0x33, 0x11, 0x33, 0x27, 0x01, 0x23, 0x11, 0x21, 0x11, - 0x23, 0x01, 0x01, 0xa6, 0x5c, 0xcc, 0x5e, 0xc4, 0x01, 0x76, 0xca, 0xfe, - 0xa8, 0xc8, 0x01, 0x74, 0x03, 0x50, 0xfc, 0xf6, 0x03, 0x0a, 0xc2, 0xfe, - 0xef, 0xfc, 0xff, 0x03, 0x01, 0x01, 0x75, 0x00, 0x00, 0x02, 0x00, 0x42, - 0x00, 0xbc, 0x04, 0xb9, 0x03, 0xa6, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x00, - 0x01, 0x15, 0x21, 0x15, 0x21, 0x15, 0x37, 0x01, 0x35, 0x21, 0x11, 0x21, - 0x35, 0x01, 0x03, 0x92, 0xfc, 0xf6, 0x03, 0x0a, 0xc2, 0xfe, 0xf0, 0xfc, - 0xfe, 0x03, 0x02, 0x01, 0x74, 0x02, 0xf4, 0x5d, 0xcc, 0x5d, 0xc3, 0xfe, - 0x8b, 0xc9, 0x01, 0x58, 0xc9, 0xfe, 0x8b, 0x00, 0x00, 0x02, 0x00, 0xf3, - 0x00, 0x00, 0x03, 0xde, 0x04, 0x76, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x00, - 0x01, 0x23, 0x11, 0x23, 0x11, 0x23, 0x17, 0x01, 0x33, 0x11, 0x21, 0x11, - 0x33, 0x01, 0x03, 0x2c, 0x5e, 0xcc, 0x5c, 0xc2, 0xfe, 0x8c, 0xc8, 0x01, - 0x58, 0xca, 0xfe, 0x8a, 0x01, 0x26, 0x03, 0x0a, 0xfc, 0xf6, 0xc2, 0x01, - 0x11, 0x03, 0x01, 0xfc, 0xff, 0xfe, 0x8b, 0x00, 0x00, 0x04, 0x00, 0xf3, - 0x00, 0x00, 0x03, 0xde, 0x04, 0x76, 0x00, 0x06, 0x00, 0x0a, 0x00, 0x0e, - 0x00, 0x15, 0x00, 0x00, 0x01, 0x11, 0x33, 0x27, 0x07, 0x33, 0x19, 0x01, - 0x15, 0x33, 0x35, 0x25, 0x21, 0x11, 0x21, 0x19, 0x01, 0x23, 0x09, 0x01, - 0x23, 0x11, 0x02, 0xce, 0x5e, 0xc4, 0xc2, 0x5c, 0xcc, 0xfe, 0xee, 0x01, - 0x58, 0xfe, 0xa8, 0xc8, 0x01, 0x74, 0x01, 0x76, 0xca, 0x01, 0xe0, 0x01, - 0x70, 0xc2, 0xc2, 0xfe, 0x90, 0xfe, 0xf2, 0x8c, 0x8c, 0x46, 0xfe, 0xe8, - 0x01, 0x9a, 0x01, 0x67, 0x01, 0x75, 0xfe, 0x8b, 0xfe, 0x99, 0x00, 0x00, - 0x00, 0x02, 0x00, 0xf3, 0x00, 0x00, 0x03, 0xde, 0x04, 0x76, 0x00, 0x0a, - 0x00, 0x15, 0x00, 0x00, 0x25, 0x11, 0x33, 0x27, 0x07, 0x33, 0x11, 0x23, - 0x15, 0x21, 0x35, 0x25, 0x11, 0x23, 0x09, 0x01, 0x23, 0x11, 0x33, 0x11, - 0x21, 0x11, 0x02, 0xce, 0x5e, 0xc4, 0xc2, 0x5c, 0xc8, 0x02, 0x5e, 0xfe, - 0x24, 0xc8, 0x01, 0x74, 0x01, 0x76, 0xca, 0xca, 0xfd, 0x16, 0xd2, 0x02, - 0x7e, 0xc2, 0xc2, 0xfd, 0x82, 0x8c, 0x8c, 0x46, 0x01, 0xe9, 0x01, 0x75, - 0xfe, 0x8b, 0xfe, 0x17, 0xfe, 0xe8, 0x01, 0x18, 0x00, 0x03, 0x00, 0xf3, - 0x00, 0x00, 0x03, 0xde, 0x04, 0x76, 0x00, 0x0b, 0x00, 0x0e, 0x00, 0x19, - 0x00, 0x00, 0x01, 0x23, 0x07, 0x33, 0x11, 0x23, 0x15, 0x21, 0x35, 0x23, - 0x11, 0x33, 0x2f, 0x01, 0x07, 0x03, 0x11, 0x23, 0x09, 0x01, 0x23, 0x11, - 0x33, 0x11, 0x21, 0x11, 0x02, 0xe0, 0xf0, 0x4a, 0x5c, 0xc8, 0x02, 0x5e, - 0xca, 0x5e, 0x7c, 0x48, 0x47, 0x65, 0xc8, 0x01, 0x74, 0x01, 0x76, 0xca, - 0xca, 0xfd, 0x16, 0x03, 0x9a, 0x4a, 0xfd, 0x82, 0x8c, 0x8c, 0x02, 0x7e, - 0x7b, 0x47, 0x47, 0xfd, 0x4d, 0x01, 0xe9, 0x01, 0x75, 0xfe, 0x8b, 0xfe, - 0x17, 0xfe, 0xe8, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xf3, - 0x00, 0x00, 0x03, 0xde, 0x04, 0x76, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x18, - 0x00, 0x00, 0x01, 0x07, 0x33, 0x11, 0x23, 0x15, 0x21, 0x13, 0x11, 0x21, - 0x35, 0x23, 0x11, 0x33, 0x01, 0x11, 0x23, 0x09, 0x01, 0x23, 0x11, 0x33, - 0x11, 0x21, 0x11, 0x02, 0x46, 0xa0, 0x5c, 0xc8, 0x01, 0x0c, 0x46, 0x01, - 0x0c, 0xca, 0x5e, 0xfe, 0x90, 0xc8, 0x01, 0x74, 0x01, 0x76, 0xca, 0xca, - 0xfd, 0x16, 0x03, 0xef, 0x9f, 0xfd, 0x82, 0x8c, 0x03, 0xa9, 0xfc, 0x57, - 0x8c, 0x02, 0x7e, 0xfd, 0xc8, 0x01, 0xe9, 0x01, 0x75, 0xfe, 0x8b, 0xfe, - 0x17, 0xfe, 0xe8, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xf3, - 0x00, 0x00, 0x03, 0xde, 0x04, 0x76, 0x00, 0x06, 0x00, 0x0c, 0x00, 0x17, - 0x00, 0x00, 0x01, 0x33, 0x27, 0x07, 0x33, 0x11, 0x33, 0x03, 0x33, 0x27, - 0x07, 0x33, 0x37, 0x07, 0x23, 0x09, 0x01, 0x23, 0x17, 0x23, 0x11, 0x21, - 0x11, 0x23, 0x02, 0xce, 0x5e, 0xc4, 0xc2, 0x5c, 0xcc, 0x08, 0x66, 0xc4, - 0xc2, 0x64, 0x5e, 0xac, 0xc8, 0x01, 0x74, 0x01, 0x76, 0xca, 0xca, 0xca, - 0xfe, 0xa8, 0xc8, 0x02, 0x88, 0xc2, 0xc2, 0xfd, 0xbe, 0x03, 0x0a, 0xc2, - 0xc2, 0x5e, 0xad, 0x01, 0x75, 0xfe, 0x8b, 0xc8, 0xfd, 0xc7, 0x02, 0x39, - 0x00, 0x03, 0x00, 0xf3, 0x00, 0x00, 0x03, 0xde, 0x04, 0x76, 0x00, 0x0a, - 0x00, 0x10, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x11, 0x23, 0x15, 0x21, 0x35, - 0x23, 0x11, 0x33, 0x27, 0x07, 0x25, 0x33, 0x27, 0x07, 0x33, 0x37, 0x03, - 0x23, 0x37, 0x23, 0x09, 0x01, 0x23, 0x17, 0x23, 0x11, 0x33, 0x11, 0x21, - 0x11, 0x33, 0x02, 0x02, 0xc8, 0x02, 0x5e, 0xca, 0x5e, 0xc4, 0xc2, 0x01, - 0x20, 0x66, 0xc4, 0xc2, 0x64, 0x5e, 0xac, 0xc8, 0xc8, 0xc8, 0x01, 0x74, - 0x01, 0x76, 0xca, 0xca, 0xca, 0xca, 0xfd, 0x16, 0xc8, 0x02, 0x88, 0xfe, - 0x4a, 0x8c, 0x8c, 0x01, 0xb6, 0xc2, 0xc2, 0xc8, 0xc2, 0xc2, 0x5e, 0xfe, - 0x8b, 0xc8, 0x01, 0x75, 0xfe, 0x8b, 0xc8, 0xfe, 0xdf, 0xfe, 0xe8, 0x01, - 0x18, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x42, 0x00, 0xbc, 0x04, 0xb9, - 0x03, 0xa6, 0x00, 0x0a, 0x00, 0x15, 0x00, 0x00, 0x01, 0x27, 0x23, 0x11, - 0x33, 0x35, 0x21, 0x15, 0x37, 0x27, 0x15, 0x01, 0x15, 0x21, 0x11, 0x21, - 0x15, 0x21, 0x35, 0x09, 0x01, 0x35, 0x01, 0x15, 0x01, 0x8c, 0x8c, 0x02, - 0x7e, 0xc2, 0xc2, 0xfd, 0xc8, 0xfe, 0xe8, 0x01, 0x18, 0x01, 0xea, 0x01, - 0x74, 0xfe, 0x8c, 0x02, 0x97, 0xc9, 0xfd, 0xa2, 0xc9, 0x5d, 0xc3, 0xc3, - 0x5d, 0xfe, 0xee, 0xc9, 0x02, 0xea, 0xc9, 0xc9, 0xfe, 0x8b, 0xfe, 0x8b, - 0xc9, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x45, 0x00, 0x00, 0x04, 0x8c, - 0x04, 0x46, 0x00, 0x09, 0x00, 0x0f, 0x00, 0x00, 0x01, 0x37, 0x21, 0x15, - 0x23, 0x01, 0x07, 0x01, 0x15, 0x23, 0x01, 0x15, 0x21, 0x11, 0x23, 0x11, - 0x01, 0x2a, 0x3a, 0x01, 0x9c, 0xe3, 0x02, 0x6e, 0x74, 0xfd, 0x92, 0x7f, - 0x03, 0x61, 0xfc, 0x04, 0x49, 0x03, 0x27, 0x3a, 0x7f, 0xfd, 0x92, 0x74, - 0x02, 0x6e, 0xe3, 0x02, 0xbb, 0x49, 0xfc, 0x03, 0x04, 0x46, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x45, 0x00, 0x00, 0x04, 0x8c, 0x04, 0x46, 0x00, 0x09, - 0x00, 0x0f, 0x00, 0x00, 0x25, 0x21, 0x35, 0x33, 0x01, 0x37, 0x01, 0x35, - 0x33, 0x11, 0x13, 0x11, 0x21, 0x35, 0x21, 0x11, 0x03, 0x6c, 0xfe, 0x64, - 0xe4, 0xfd, 0x92, 0x74, 0x02, 0x6e, 0x7e, 0xe6, 0xfb, 0xba, 0x03, 0xfc, - 0xe5, 0x7f, 0x02, 0x6e, 0x74, 0xfd, 0x92, 0xe3, 0xfe, 0x64, 0x03, 0x26, - 0xfb, 0xbb, 0x49, 0x03, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xf3, - 0x00, 0x00, 0x03, 0xde, 0x04, 0x76, 0x00, 0x09, 0x00, 0x13, 0x00, 0x00, - 0x01, 0x11, 0x23, 0x17, 0x37, 0x23, 0x11, 0x33, 0x27, 0x07, 0x17, 0x23, - 0x09, 0x01, 0x23, 0x11, 0x33, 0x09, 0x01, 0x33, 0x02, 0x02, 0x5c, 0xc2, - 0xc4, 0x5e, 0x5e, 0xc4, 0xc2, 0x16, 0xc8, 0x01, 0x74, 0x01, 0x76, 0xca, - 0xca, 0xfe, 0x8a, 0xfe, 0x8c, 0xc8, 0x03, 0x50, 0xfd, 0xd6, 0xc2, 0xc2, - 0x02, 0x2a, 0xc2, 0xc2, 0x4f, 0x01, 0x75, 0xfe, 0x8b, 0xfe, 0x74, 0xfe, - 0x8b, 0x01, 0x75, 0x00, 0x00, 0x03, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, - 0x03, 0x7d, 0x00, 0x1e, 0x00, 0x27, 0x00, 0x30, 0x00, 0x00, 0x01, 0x06, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x23, 0x35, 0x33, 0x36, 0x37, - 0x36, 0x33, 0x32, 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x33, 0x27, 0x37, - 0x01, 0x15, 0x01, 0x27, 0x37, 0x25, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, - 0x06, 0x07, 0x05, 0x21, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x02, - 0xc5, 0x13, 0x34, 0x52, 0x76, 0x78, 0x4e, 0x31, 0x12, 0x6b, 0x6b, 0x13, - 0x32, 0x4f, 0x77, 0x39, 0x67, 0x27, 0x20, 0x1c, 0x06, 0x04, 0xed, 0xa0, - 0x5a, 0x01, 0x23, 0xfe, 0xdd, 0x5a, 0xa0, 0xfe, 0x99, 0x0b, 0x11, 0x30, - 0x47, 0x44, 0x32, 0x12, 0x0b, 0x01, 0x26, 0xfe, 0xdb, 0x0c, 0x0f, 0x2b, - 0x4a, 0x44, 0x35, 0x11, 0x01, 0xdf, 0x40, 0x33, 0x50, 0x4f, 0x32, 0x42, - 0xa4, 0x42, 0x34, 0x52, 0x2c, 0x28, 0x20, 0x3a, 0x0c, 0x0e, 0xa0, 0x5a, - 0xfe, 0xdd, 0x52, 0xfe, 0xdd, 0x5a, 0xa0, 0xa4, 0x14, 0x11, 0x31, 0x31, - 0x11, 0x14, 0xa4, 0x13, 0x11, 0x2f, 0x30, 0x10, 0x00, 0x02, 0x00, 0x2a, - 0x00, 0x00, 0x04, 0xa7, 0x04, 0x4d, 0x00, 0x09, 0x00, 0x13, 0x00, 0x00, - 0x21, 0x23, 0x01, 0x37, 0x17, 0x11, 0x33, 0x11, 0x37, 0x17, 0x13, 0x01, - 0x07, 0x27, 0x11, 0x23, 0x11, 0x07, 0x27, 0x01, 0x01, 0xa0, 0x52, 0xfe, - 0xdc, 0x5a, 0xa0, 0xa4, 0xa0, 0x5a, 0xc2, 0x01, 0x22, 0x5a, 0xa0, 0xa4, - 0xa0, 0x5a, 0x01, 0x24, 0x01, 0x23, 0x5a, 0xa0, 0x03, 0x70, 0xfc, 0x90, - 0xa0, 0x5a, 0x03, 0x2a, 0xfe, 0xdd, 0x5a, 0xa0, 0xfc, 0x90, 0x03, 0x70, - 0xa0, 0x5a, 0x01, 0x23, 0x00, 0x01, 0x00, 0x42, 0xff, 0x01, 0x04, 0x8f, - 0x05, 0x61, 0x00, 0x19, 0x00, 0x00, 0x01, 0x37, 0x21, 0x35, 0x21, 0x27, - 0x37, 0x21, 0x35, 0x21, 0x27, 0x37, 0x01, 0x15, 0x07, 0x17, 0x15, 0x07, - 0x17, 0x15, 0x01, 0x27, 0x37, 0x21, 0x35, 0x21, 0x03, 0x12, 0xa0, 0xfc, - 0x90, 0x03, 0x70, 0xa0, 0xa0, 0xfc, 0x90, 0x03, 0x70, 0xa0, 0x5a, 0x01, - 0x23, 0xc9, 0xc9, 0xc9, 0xc9, 0xfe, 0xdd, 0x5a, 0xa0, 0xfc, 0x90, 0x03, - 0x70, 0x01, 0x3f, 0xa0, 0xa4, 0xa0, 0xa0, 0xa4, 0xa0, 0x5a, 0xfe, 0xdd, - 0x52, 0xc9, 0xc9, 0x52, 0xc9, 0xc9, 0x52, 0xfe, 0xdd, 0x5a, 0xa0, 0xa4, - 0x00, 0x01, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, 0x03, 0x7d, 0x00, 0x11, - 0x00, 0x00, 0x01, 0x15, 0x23, 0x35, 0x21, 0x17, 0x07, 0x01, 0x35, 0x01, - 0x17, 0x07, 0x21, 0x35, 0x33, 0x15, 0x21, 0x15, 0x03, 0x1e, 0xa4, 0xfe, - 0xa5, 0xa0, 0x5a, 0xfe, 0xdd, 0x01, 0x23, 0x5a, 0xa0, 0x01, 0x5b, 0xa4, - 0x01, 0x71, 0x01, 0xdf, 0xfa, 0xfa, 0xa0, 0x5a, 0x01, 0x23, 0x52, 0x01, - 0x23, 0x5a, 0xa0, 0xfa, 0xfa, 0xa4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, - 0x00, 0xe5, 0x04, 0x8f, 0x03, 0x7d, 0x00, 0x11, 0x00, 0x00, 0x01, 0x21, - 0x35, 0x21, 0x35, 0x33, 0x15, 0x21, 0x27, 0x37, 0x01, 0x15, 0x01, 0x27, - 0x37, 0x21, 0x15, 0x23, 0x01, 0xb2, 0xfe, 0x90, 0x01, 0x70, 0xa4, 0x01, - 0x5c, 0xa0, 0x5a, 0x01, 0x23, 0xfe, 0xdd, 0x5a, 0xa0, 0xfe, 0xa4, 0xa4, - 0x01, 0xdf, 0xa4, 0xfa, 0xfa, 0xa0, 0x5a, 0xfe, 0xdd, 0x52, 0xfe, 0xdd, - 0x5a, 0xa0, 0xfa, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, - 0x03, 0x7d, 0x00, 0x17, 0x00, 0x00, 0x01, 0x23, 0x17, 0x07, 0x01, 0x35, - 0x01, 0x17, 0x07, 0x33, 0x35, 0x33, 0x15, 0x33, 0x27, 0x37, 0x01, 0x15, - 0x01, 0x27, 0x37, 0x23, 0x15, 0x23, 0x02, 0x16, 0xf7, 0xa0, 0x5a, 0xfe, - 0xdd, 0x01, 0x23, 0x5a, 0xa0, 0xf7, 0xa4, 0xf8, 0xa0, 0x5a, 0x01, 0x23, - 0xfe, 0xdd, 0x5a, 0xa0, 0xf8, 0xa4, 0x01, 0xdf, 0xa0, 0x5a, 0x01, 0x23, - 0x52, 0x01, 0x23, 0x5a, 0xa0, 0xfa, 0xfa, 0xa0, 0x5a, 0xfe, 0xdd, 0x52, - 0xfe, 0xdd, 0x5a, 0xa0, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x42, - 0x00, 0xe5, 0x04, 0x8f, 0x03, 0x7d, 0x00, 0x19, 0x00, 0x00, 0x01, 0x15, - 0x23, 0x35, 0x23, 0x15, 0x23, 0x35, 0x23, 0x17, 0x07, 0x01, 0x35, 0x01, - 0x17, 0x07, 0x33, 0x35, 0x33, 0x15, 0x33, 0x35, 0x33, 0x15, 0x33, 0x15, - 0x03, 0xd2, 0xa4, 0x74, 0xa4, 0xf7, 0xa0, 0x5a, 0xfe, 0xdd, 0x01, 0x23, - 0x5a, 0xa0, 0xf7, 0xa4, 0x74, 0xa4, 0xbd, 0x01, 0xdf, 0xfa, 0xfa, 0xfa, - 0xfa, 0xa0, 0x5a, 0x01, 0x23, 0x52, 0x01, 0x23, 0x5a, 0xa0, 0xfa, 0xfa, - 0xfa, 0xfa, 0xa4, 0x00, 0x00, 0x01, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, - 0x03, 0x7d, 0x00, 0x19, 0x00, 0x00, 0x13, 0x23, 0x35, 0x33, 0x35, 0x33, - 0x15, 0x33, 0x35, 0x33, 0x15, 0x33, 0x27, 0x37, 0x01, 0x15, 0x01, 0x27, - 0x37, 0x23, 0x15, 0x23, 0x35, 0x23, 0x15, 0x23, 0xfe, 0xbc, 0xbc, 0xa4, - 0x74, 0xa4, 0xf8, 0xa0, 0x5a, 0x01, 0x23, 0xfe, 0xdd, 0x5a, 0xa0, 0xf8, - 0xa4, 0x74, 0xa4, 0x01, 0xdf, 0xa4, 0xfa, 0xfa, 0xfa, 0xfa, 0xa0, 0x5a, - 0xfe, 0xdd, 0x52, 0xfe, 0xdd, 0x5a, 0xa0, 0xfa, 0xfa, 0xfa, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x42, 0x00, 0xe5, 0x04, 0x8f, 0x03, 0x7d, 0x00, 0x1f, - 0x00, 0x00, 0x01, 0x17, 0x07, 0x01, 0x35, 0x01, 0x17, 0x07, 0x33, 0x35, - 0x33, 0x15, 0x33, 0x35, 0x33, 0x15, 0x33, 0x27, 0x37, 0x01, 0x15, 0x01, - 0x27, 0x37, 0x23, 0x15, 0x23, 0x35, 0x23, 0x15, 0x23, 0x35, 0x01, 0x1f, - 0xa0, 0x5a, 0xfe, 0xdd, 0x01, 0x23, 0x5a, 0xa0, 0xa7, 0x86, 0x38, 0x86, - 0xa8, 0xa0, 0x5a, 0x01, 0x23, 0xfe, 0xdd, 0x5a, 0xa0, 0xa8, 0x86, 0x38, - 0x86, 0x01, 0xdf, 0xa0, 0x5a, 0x01, 0x23, 0x52, 0x01, 0x23, 0x5a, 0xa0, - 0xfa, 0xfa, 0xfa, 0xfa, 0xa0, 0x5a, 0xfe, 0xdd, 0x52, 0xfe, 0xdd, 0x5a, - 0xa0, 0xfa, 0xfa, 0xfa, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x19, - 0x00, 0xbc, 0x04, 0x8f, 0x03, 0xa6, 0x00, 0x02, 0x00, 0x09, 0x00, 0x00, - 0x01, 0x07, 0x17, 0x13, 0x21, 0x15, 0x21, 0x11, 0x09, 0x01, 0x01, 0x3f, - 0xc2, 0xc2, 0x4f, 0x03, 0x01, 0xfc, 0xff, 0xfe, 0x8b, 0x01, 0x75, 0x02, - 0xf4, 0xc3, 0xc3, 0x01, 0x15, 0xa4, 0xfe, 0xdd, 0x01, 0x75, 0x01, 0x75, - 0x00, 0x02, 0x00, 0x42, 0x00, 0xbc, 0x04, 0xb8, 0x03, 0xa6, 0x00, 0x02, - 0x00, 0x09, 0x00, 0x00, 0x01, 0x11, 0x37, 0x25, 0x11, 0x09, 0x01, 0x11, - 0x21, 0x35, 0x03, 0x92, 0xc2, 0xfe, 0xef, 0x01, 0x75, 0xfe, 0x8b, 0xfc, - 0xff, 0x02, 0xf4, 0xfe, 0x7a, 0xc3, 0x52, 0x01, 0x23, 0xfe, 0x8b, 0xfe, - 0x8b, 0x01, 0x23, 0xa4, 0x00, 0x03, 0x00, 0x19, 0x00, 0xbc, 0x04, 0xb8, - 0x03, 0xa6, 0x00, 0x02, 0x00, 0x05, 0x00, 0x0f, 0x00, 0x00, 0x01, 0x07, - 0x17, 0x01, 0x11, 0x37, 0x05, 0x11, 0x09, 0x01, 0x11, 0x21, 0x11, 0x09, - 0x01, 0x11, 0x01, 0x3f, 0xc2, 0xc2, 0x02, 0x53, 0xc2, 0xfd, 0x3a, 0xfe, - 0x8b, 0x01, 0x75, 0x01, 0xb5, 0x01, 0x75, 0xfe, 0x8b, 0x02, 0xf4, 0xc3, - 0xc3, 0x01, 0x86, 0xfe, 0x7a, 0xc3, 0x52, 0xfe, 0xdd, 0x01, 0x75, 0x01, - 0x75, 0xfe, 0xdd, 0x01, 0x23, 0xfe, 0x8b, 0xfe, 0x8b, 0x01, 0x23, 0x00, - 0x00, 0x02, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, 0x05, 0xd5, 0x00, 0x02, - 0x00, 0x0a, 0x00, 0x00, 0x25, 0x13, 0x21, 0x13, 0x01, 0x33, 0x13, 0x21, - 0x13, 0x33, 0x01, 0x02, 0x68, 0xd5, 0xfe, 0x56, 0x5b, 0xfe, 0x37, 0xd1, - 0x6c, 0x02, 0x0b, 0x6e, 0xd1, 0xfe, 0x37, 0xb2, 0x02, 0xfc, 0xfc, 0x52, - 0x05, 0xd5, 0xfe, 0x7b, 0x01, 0x85, 0xfa, 0x2b, 0x00, 0x01, 0x00, 0x75, - 0xff, 0xe3, 0x04, 0x5c, 0x05, 0xf0, 0x00, 0x19, 0x00, 0x00, 0x12, 0x10, - 0x00, 0x20, 0x17, 0x16, 0x17, 0x23, 0x26, 0x27, 0x26, 0x23, 0x22, 0x02, - 0x10, 0x12, 0x33, 0x32, 0x37, 0x36, 0x37, 0x33, 0x06, 0x07, 0x06, 0x20, - 0x75, 0x01, 0x09, 0x01, 0xf6, 0x85, 0x42, 0x21, 0xca, 0x12, 0x1b, 0x4f, - 0x9d, 0x9c, 0x9d, 0x9d, 0x9c, 0x9d, 0x4f, 0x1b, 0x12, 0xca, 0x21, 0x42, - 0x85, 0xfe, 0x0a, 0x01, 0x6f, 0x02, 0xf4, 0x01, 0x8d, 0xc6, 0x63, 0x90, - 0x49, 0x37, 0x99, 0xfe, 0xcd, 0xfd, 0x98, 0xfe, 0xcd, 0x99, 0x37, 0x49, - 0x90, 0x63, 0xc5, 0x00, 0x00, 0x02, 0x00, 0xb6, 0xff, 0xe3, 0x04, 0x1b, - 0x05, 0x4c, 0x00, 0x20, 0x00, 0x30, 0x00, 0x00, 0x05, 0x22, 0x27, 0x26, - 0x35, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x36, 0x35, 0x34, - 0x27, 0x26, 0x23, 0x22, 0x07, 0x35, 0x36, 0x33, 0x20, 0x17, 0x16, 0x15, - 0x14, 0x07, 0x02, 0x07, 0x06, 0x01, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, - 0x36, 0x37, 0x36, 0x37, 0x26, 0x23, 0x22, 0x07, 0x06, 0x02, 0x0c, 0x8d, - 0x5c, 0x6d, 0x60, 0x63, 0xb2, 0x75, 0x5c, 0x36, 0x25, 0x0d, 0x20, 0x47, - 0xbc, 0x47, 0x6e, 0x74, 0x68, 0x01, 0x0c, 0x72, 0x35, 0x19, 0x3f, 0xa3, - 0x80, 0xfe, 0xc1, 0x2c, 0x2f, 0x48, 0x40, 0x33, 0x48, 0x35, 0x2c, 0x16, - 0x59, 0x9a, 0x84, 0x3a, 0x24, 0x1d, 0x55, 0x65, 0xb7, 0xbe, 0x94, 0x98, - 0x49, 0x2b, 0x48, 0x51, 0x5c, 0x87, 0x4e, 0xad, 0x2c, 0xa8, 0x1f, 0xf6, - 0x74, 0xad, 0x71, 0x83, 0xfe, 0xb8, 0x9c, 0x7a, 0x01, 0x53, 0x64, 0x36, - 0x39, 0x2d, 0x3e, 0x65, 0x53, 0x59, 0xd7, 0xae, 0x6c, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xb2, 0x00, 0x00, 0x04, 0x1d, 0x05, 0xd5, 0x00, 0x0b, - 0x00, 0x00, 0x37, 0x21, 0x11, 0x21, 0x35, 0x21, 0x11, 0x21, 0x35, 0x21, - 0x11, 0x21, 0xb2, 0x02, 0xb4, 0xfd, 0x4c, 0x02, 0xb4, 0xfd, 0x4c, 0x03, - 0x6b, 0xfc, 0x95, 0xaa, 0x01, 0xec, 0xaa, 0x01, 0xeb, 0xaa, 0xfa, 0x2b, - 0x00, 0x03, 0x00, 0xb2, 0xff, 0xa2, 0x04, 0x1d, 0x06, 0x35, 0x00, 0x13, - 0x00, 0x17, 0x00, 0x1b, 0x00, 0x00, 0x01, 0x11, 0x21, 0x07, 0x23, 0x37, - 0x23, 0x35, 0x33, 0x13, 0x21, 0x35, 0x21, 0x13, 0x21, 0x35, 0x21, 0x37, - 0x33, 0x0f, 0x01, 0x03, 0x33, 0x11, 0x01, 0x03, 0x21, 0x11, 0x04, 0x1d, - 0xfd, 0x8a, 0x1b, 0x9a, 0x1a, 0x5a, 0x8a, 0x8b, 0xfe, 0xeb, 0x01, 0x44, - 0x8a, 0xfe, 0x32, 0x01, 0xfe, 0x1b, 0x9b, 0x1c, 0x2f, 0x8a, 0xd5, 0xfe, - 0xfb, 0x8a, 0x01, 0x8f, 0x05, 0xd5, 0xfa, 0x2b, 0x5e, 0x5e, 0xaa, 0x01, - 0xec, 0xaa, 0x01, 0xeb, 0xaa, 0x60, 0x60, 0xaa, 0xfe, 0x15, 0x01, 0xeb, - 0xfd, 0x6b, 0xfe, 0x14, 0x01, 0xec, 0x00, 0x00, 0x00, 0x03, 0x00, 0x49, - 0x00, 0x62, 0x04, 0x8a, 0x04, 0xa3, 0x00, 0x21, 0x00, 0x30, 0x00, 0x3f, - 0x00, 0x00, 0x01, 0x17, 0x07, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, - 0x07, 0x0e, 0x01, 0x22, 0x27, 0x26, 0x27, 0x07, 0x27, 0x37, 0x26, 0x27, - 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x3e, 0x01, 0x32, 0x17, 0x16, 0x17, - 0x06, 0x22, 0x07, 0x06, 0x07, 0x0e, 0x01, 0x15, 0x14, 0x17, 0x16, 0x17, - 0x01, 0x26, 0x27, 0x17, 0x01, 0x16, 0x17, 0x16, 0x32, 0x37, 0x36, 0x37, - 0x3e, 0x01, 0x35, 0x34, 0x27, 0x26, 0x04, 0x26, 0x63, 0x76, 0x2d, 0x1a, - 0x27, 0x27, 0x27, 0x4f, 0x4f, 0xbe, 0xdd, 0x5f, 0x40, 0x38, 0x76, 0x63, - 0x75, 0x2d, 0x1b, 0x27, 0x27, 0x27, 0x4f, 0x4f, 0xbe, 0xdd, 0x5f, 0x41, - 0x3a, 0xf7, 0xa3, 0x47, 0x45, 0x3a, 0x3b, 0x39, 0x1c, 0x11, 0x1a, 0x02, - 0x28, 0x24, 0x28, 0xaf, 0xfd, 0xd8, 0x23, 0x26, 0x47, 0xa3, 0x46, 0x46, - 0x3a, 0x3b, 0x39, 0x1c, 0x10, 0x04, 0xa2, 0x63, 0x76, 0x38, 0x40, 0x5f, - 0x70, 0x6d, 0x5f, 0x5f, 0x4f, 0x4e, 0x50, 0x28, 0x1a, 0x2d, 0x76, 0x63, - 0x75, 0x3a, 0x41, 0x5f, 0x6d, 0x70, 0x5f, 0x5f, 0x4f, 0x4f, 0x50, 0x28, - 0x1c, 0x2d, 0x1c, 0x1e, 0x1e, 0x39, 0x3b, 0x8c, 0x53, 0x50, 0x46, 0x28, - 0x24, 0x02, 0x28, 0x1a, 0x11, 0x8e, 0xfd, 0xd8, 0x19, 0x10, 0x1e, 0x1e, - 0x1e, 0x39, 0x3b, 0x8c, 0x50, 0x53, 0x46, 0x27, 0x00, 0x02, 0xff, 0xfa, - 0x00, 0x00, 0x04, 0xd9, 0x05, 0x8f, 0x00, 0x03, 0x00, 0x06, 0x00, 0x4f, - 0x40, 0x2a, 0x04, 0x69, 0x05, 0x04, 0x02, 0x03, 0x02, 0x06, 0x69, 0x03, - 0x03, 0x02, 0x05, 0x69, 0x00, 0x01, 0x00, 0x04, 0x69, 0x06, 0x04, 0x01, - 0x01, 0x00, 0x42, 0x04, 0x01, 0x05, 0xf9, 0x01, 0xfb, 0x00, 0x06, 0x05, - 0x04, 0x02, 0x01, 0x05, 0x07, 0x03, 0x00, 0x07, 0x10, 0xd4, 0xcc, 0x11, - 0x17, 0x39, 0x31, 0x00, 0x2f, 0xe4, 0xec, 0x11, 0x39, 0x30, 0x4b, 0x53, - 0x58, 0x07, 0x10, 0x08, 0xed, 0x07, 0x10, 0x05, 0xed, 0x07, 0x10, 0x05, - 0xed, 0x07, 0x10, 0x08, 0xed, 0x59, 0x22, 0x23, 0x01, 0x33, 0x09, 0x02, - 0x21, 0x06, 0x02, 0x06, 0xd1, 0x02, 0x08, 0xfd, 0x8f, 0xfe, 0x90, 0x02, - 0xe1, 0x05, 0x8f, 0xfa, 0x71, 0x04, 0xc3, 0xfb, 0xe9, 0x00, 0x00, 0x00, - 0x00, 0x02, 0xff, 0xfa, 0x00, 0x00, 0x04, 0xd9, 0x05, 0x8f, 0x00, 0x03, - 0x00, 0x06, 0x00, 0x00, 0x03, 0x21, 0x01, 0x23, 0x37, 0x01, 0x21, 0x06, - 0x04, 0xdf, 0xfd, 0xf8, 0xd1, 0x68, 0x01, 0x71, 0xfd, 0x1f, 0x05, 0x8f, - 0xfa, 0x71, 0xcc, 0x04, 0x17, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x81, - 0x00, 0x00, 0x04, 0x50, 0x05, 0xb8, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x16, - 0x17, 0x1e, 0x01, 0x33, 0x21, 0x15, 0x21, 0x22, 0x26, 0x02, 0x10, 0x12, - 0x36, 0x33, 0x21, 0x15, 0x21, 0x22, 0x07, 0x06, 0x07, 0x06, 0x07, 0x21, - 0x15, 0x01, 0x30, 0x08, 0x22, 0x2c, 0x98, 0x5a, 0x01, 0xd8, 0xfe, 0x28, - 0x88, 0xe8, 0x86, 0x86, 0xe8, 0x88, 0x01, 0xd8, 0xfe, 0x28, 0x5c, 0x4a, - 0x4e, 0x2a, 0x22, 0x08, 0x03, 0x1e, 0x02, 0x87, 0x66, 0x5f, 0x82, 0x96, - 0xaa, 0xc4, 0x01, 0x51, 0x01, 0x8e, 0x01, 0x51, 0xc4, 0xaa, 0x4b, 0x4d, - 0x80, 0x5f, 0x66, 0xaa, 0x00, 0x03, 0x00, 0x81, 0xff, 0x4f, 0x04, 0x50, - 0x06, 0x69, 0x00, 0x1c, 0x00, 0x25, 0x00, 0x2b, 0x00, 0x00, 0x25, 0x16, - 0x33, 0x21, 0x15, 0x21, 0x22, 0x27, 0x07, 0x27, 0x37, 0x26, 0x27, 0x26, - 0x10, 0x12, 0x36, 0x3b, 0x01, 0x37, 0x17, 0x07, 0x33, 0x15, 0x23, 0x03, - 0x21, 0x15, 0x21, 0x13, 0x23, 0x22, 0x07, 0x06, 0x07, 0x06, 0x07, 0x21, - 0x07, 0x23, 0x16, 0x17, 0x16, 0x17, 0x02, 0x4c, 0x15, 0x17, 0x01, 0xd8, - 0xfe, 0x28, 0x30, 0x2c, 0x3a, 0xa3, 0x43, 0x79, 0x45, 0x42, 0x86, 0xe8, - 0x88, 0xaa, 0x36, 0xa3, 0x27, 0x7c, 0xb0, 0x90, 0x01, 0x3e, 0xfe, 0x8e, - 0x12, 0x76, 0x5c, 0x4a, 0x4b, 0x2d, 0x22, 0x08, 0x01, 0x2e, 0x34, 0xfa, - 0x08, 0x22, 0x24, 0x3a, 0xae, 0x04, 0xaa, 0x0c, 0xbd, 0x31, 0xdd, 0x63, - 0xac, 0xa9, 0x01, 0x8e, 0x01, 0x51, 0xc4, 0xb1, 0x32, 0x7f, 0xaa, 0xfe, - 0x23, 0xaa, 0x02, 0x87, 0x4b, 0x4b, 0x82, 0x5f, 0x66, 0xaa, 0x66, 0x5f, - 0x6c, 0x46, 0x00, 0x00, 0x00, 0x01, 0x00, 0x82, 0x00, 0xa5, 0x04, 0x4f, - 0x04, 0x5d, 0x00, 0x17, 0x00, 0x42, 0x00, 0xb0, 0x08, 0x2f, 0xb0, 0x09, - 0x33, 0xb0, 0x0a, 0x33, 0xb1, 0x05, 0x04, 0xed, 0xb1, 0x06, 0x04, 0xed, - 0xb1, 0x07, 0x04, 0xed, 0xb0, 0x01, 0xb0, 0x05, 0x10, 0xde, 0xb0, 0x02, - 0x32, 0xb1, 0x00, 0x04, 0xed, 0xb1, 0x17, 0x04, 0xed, 0xb0, 0x12, 0xb0, - 0x00, 0x10, 0xde, 0xb0, 0x13, 0x32, 0xb0, 0x14, 0x32, 0xb1, 0x0f, 0x04, - 0xed, 0xb1, 0x10, 0x04, 0xed, 0xb1, 0x11, 0x04, 0xed, 0x01, 0x30, 0x31, - 0x01, 0x15, 0x21, 0x16, 0x17, 0x16, 0x33, 0x21, 0x15, 0x21, 0x22, 0x2e, - 0x01, 0x10, 0x3e, 0x01, 0x33, 0x21, 0x15, 0x21, 0x22, 0x07, 0x06, 0x07, - 0x04, 0x4e, 0xfc, 0xed, 0x16, 0x3d, 0x63, 0x85, 0x01, 0xd8, 0xfe, 0x28, - 0x88, 0xe6, 0x86, 0x86, 0xe6, 0x88, 0x01, 0xd8, 0xfe, 0x28, 0x85, 0x63, - 0x3d, 0x16, 0x02, 0xd6, 0xaa, 0x49, 0x39, 0x5b, 0xaa, 0x7f, 0xdc, 0x01, - 0x02, 0xdc, 0x7f, 0xaa, 0x5b, 0x39, 0x49, 0x00, 0x00, 0x01, 0x00, 0x81, - 0x00, 0x00, 0x04, 0x50, 0x05, 0xb8, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x26, - 0x27, 0x2e, 0x01, 0x23, 0x21, 0x35, 0x21, 0x32, 0x16, 0x12, 0x10, 0x02, - 0x06, 0x23, 0x21, 0x35, 0x21, 0x32, 0x37, 0x36, 0x37, 0x36, 0x37, 0x21, - 0x35, 0x03, 0xa0, 0x08, 0x20, 0x2c, 0x98, 0x5a, 0xfe, 0x28, 0x01, 0xd8, - 0x88, 0xe8, 0x86, 0x86, 0xe8, 0x88, 0xfe, 0x28, 0x01, 0xd8, 0x5c, 0x4a, - 0x4c, 0x2c, 0x20, 0x08, 0xfc, 0xe2, 0x03, 0x31, 0x66, 0x5f, 0x82, 0x96, - 0xaa, 0xc4, 0xfe, 0xaf, 0xfe, 0x72, 0xfe, 0xaf, 0xc4, 0xaa, 0x4b, 0x4d, - 0x80, 0x5f, 0x66, 0xaa, 0x00, 0x03, 0x00, 0x81, 0xff, 0x4f, 0x04, 0x50, - 0x06, 0x69, 0x00, 0x1c, 0x00, 0x25, 0x00, 0x2b, 0x00, 0x00, 0x01, 0x26, - 0x23, 0x21, 0x35, 0x21, 0x32, 0x17, 0x37, 0x17, 0x07, 0x16, 0x17, 0x16, - 0x10, 0x02, 0x06, 0x2b, 0x01, 0x07, 0x27, 0x37, 0x23, 0x35, 0x33, 0x13, - 0x21, 0x35, 0x21, 0x03, 0x33, 0x32, 0x37, 0x36, 0x37, 0x36, 0x37, 0x21, - 0x37, 0x33, 0x26, 0x27, 0x26, 0x27, 0x02, 0x85, 0x15, 0x16, 0xfe, 0x28, - 0x01, 0xd8, 0x2f, 0x2d, 0x39, 0xa3, 0x43, 0x79, 0x44, 0x44, 0x86, 0xe8, - 0x88, 0xab, 0x36, 0xa3, 0x27, 0x7b, 0xae, 0x92, 0xfe, 0xc0, 0x01, 0x72, - 0x12, 0x78, 0x5c, 0x4a, 0x4a, 0x2e, 0x20, 0x08, 0xfe, 0xd3, 0x34, 0xf9, - 0x08, 0x20, 0x25, 0x3a, 0x05, 0x0a, 0x04, 0xaa, 0x0c, 0xbd, 0x31, 0xdd, - 0x63, 0xac, 0xa9, 0xfe, 0x72, 0xfe, 0xaf, 0xc4, 0xb1, 0x32, 0x7f, 0xaa, - 0x01, 0xdd, 0xaa, 0xfd, 0x79, 0x4b, 0x4b, 0x82, 0x5f, 0x66, 0xaa, 0x66, - 0x5f, 0x6c, 0x46, 0x00, 0x00, 0x01, 0x00, 0x82, 0x00, 0xa5, 0x04, 0x4f, - 0x04, 0x5d, 0x00, 0x17, 0x00, 0x00, 0x13, 0x35, 0x21, 0x26, 0x27, 0x26, - 0x23, 0x21, 0x35, 0x21, 0x32, 0x1e, 0x01, 0x10, 0x0e, 0x01, 0x23, 0x21, - 0x35, 0x21, 0x32, 0x37, 0x36, 0x37, 0x83, 0x03, 0x13, 0x16, 0x3e, 0x62, - 0x86, 0xfe, 0x28, 0x01, 0xd8, 0x88, 0xe6, 0x86, 0x86, 0xe6, 0x88, 0xfe, - 0x28, 0x01, 0xd8, 0x86, 0x62, 0x3e, 0x16, 0x02, 0x2c, 0xaa, 0x49, 0x39, - 0x5b, 0xaa, 0x7f, 0xdc, 0xfe, 0xfe, 0xdc, 0x7f, 0xaa, 0x5b, 0x39, 0x49, - 0x00, 0x01, 0x00, 0x98, 0xfe, 0x4c, 0x04, 0x39, 0x05, 0xee, 0x00, 0x07, - 0x00, 0x1f, 0xb9, 0x00, 0x05, 0x01, 0x0f, 0x40, 0x0b, 0x01, 0x03, 0x00, - 0x08, 0x04, 0x80, 0x02, 0x06, 0x80, 0x00, 0x08, 0x10, 0xd4, 0xec, 0xd4, - 0xec, 0x31, 0x00, 0x10, 0xc4, 0x32, 0xd4, 0xec, 0x30, 0x13, 0x11, 0x21, - 0x11, 0x23, 0x11, 0x21, 0x11, 0x98, 0x03, 0xa1, 0x9b, 0xfd, 0x95, 0xfe, - 0x4c, 0x07, 0xa2, 0xf8, 0x5e, 0x07, 0x1e, 0xf8, 0xe2, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x8f, 0xfe, 0x4c, 0x04, 0x3d, 0x05, 0xee, 0x00, 0x0b, - 0x00, 0x37, 0xb4, 0x0b, 0x05, 0x0c, 0x09, 0x00, 0xbf, 0x01, 0x0f, 0x00, - 0x02, 0x00, 0x09, 0x01, 0x0f, 0x00, 0x07, 0x01, 0x0e, 0x00, 0x02, 0x01, - 0x10, 0x40, 0x0b, 0x0c, 0x0b, 0x0a, 0x08, 0x05, 0x00, 0x05, 0x01, 0x06, - 0x03, 0x0c, 0x10, 0xd4, 0x3c, 0xc4, 0x17, 0x39, 0x31, 0x00, 0x10, 0xe4, - 0xf4, 0xec, 0x10, 0xee, 0x11, 0x12, 0x39, 0x39, 0x30, 0x01, 0x21, 0x15, - 0x21, 0x35, 0x09, 0x01, 0x35, 0x21, 0x15, 0x21, 0x01, 0x01, 0x4c, 0x02, - 0xf1, 0xfc, 0x52, 0x02, 0x25, 0xfd, 0xdb, 0x03, 0x9a, 0xfd, 0x23, 0x02, - 0x0a, 0xfe, 0xd5, 0x89, 0x5c, 0x03, 0x97, 0x03, 0x50, 0x5f, 0x8c, 0xfc, - 0xdd, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x58, 0x02, 0x2d, 0x04, 0x79, - 0x02, 0xd7, 0x00, 0x03, 0x00, 0x11, 0xb6, 0x00, 0xa0, 0x02, 0x04, 0x01, - 0x00, 0x04, 0x10, 0xd4, 0xc4, 0x31, 0x00, 0x10, 0xd4, 0xec, 0x30, 0x13, - 0x21, 0x15, 0x21, 0x58, 0x04, 0x21, 0xfb, 0xdf, 0x02, 0xd7, 0xaa, 0x00, - 0x00, 0x02, 0x00, 0x58, 0x00, 0x00, 0x04, 0x79, 0x04, 0x93, 0x00, 0x03, - 0x00, 0x0f, 0x00, 0x00, 0x01, 0x21, 0x35, 0x21, 0x01, 0x11, 0x21, 0x35, - 0x21, 0x11, 0x33, 0x11, 0x21, 0x15, 0x21, 0x11, 0x04, 0x79, 0xfb, 0xdf, - 0x04, 0x21, 0xfd, 0x9b, 0xfe, 0x44, 0x01, 0xbc, 0xa8, 0x01, 0xbd, 0xfe, - 0x43, 0x03, 0xe9, 0xaa, 0xfb, 0x6d, 0x01, 0x49, 0xaa, 0x01, 0x4c, 0xfe, - 0xb4, 0xaa, 0xfe, 0xb7, 0xff, 0xff, 0x00, 0x66, 0xff, 0x42, 0x04, 0x37, - 0x05, 0xd5, 0x10, 0x06, 0x00, 0x12, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa6, - 0x00, 0xaf, 0x04, 0x2b, 0x04, 0x55, 0x10, 0x07, 0x00, 0x0d, 0x00, 0x00, - 0xfe, 0x65, 0x00, 0x00, 0xff, 0xff, 0x01, 0x2b, 0x01, 0x47, 0x03, 0xa6, - 0x03, 0xc2, 0x10, 0x07, 0x00, 0x72, 0x00, 0x00, 0xfd, 0xd2, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x3f, 0x01, 0x9a, 0x03, 0x91, 0x03, 0xea, 0x10, 0x06, - 0x07, 0x26, 0x00, 0xc9, 0x00, 0x01, 0x00, 0x3b, 0xff, 0xd9, 0x04, 0xa0, - 0x06, 0xa0, 0x00, 0x0a, 0x00, 0x2f, 0x40, 0x1a, 0x0a, 0x03, 0x02, 0x01, - 0x00, 0x05, 0x0b, 0x05, 0x04, 0x08, 0x06, 0x0b, 0x0a, 0x09, 0x08, 0x07, - 0x04, 0x03, 0x02, 0x07, 0x05, 0x00, 0x0b, 0x05, 0x01, 0x0b, 0x10, 0xd4, - 0xc4, 0x12, 0x39, 0x11, 0x17, 0x39, 0x31, 0x00, 0x10, 0xd4, 0xc4, 0xc0, - 0xc0, 0x12, 0x17, 0x39, 0x30, 0x13, 0x27, 0x25, 0x13, 0x01, 0x33, 0x15, - 0x23, 0x01, 0x23, 0x03, 0x64, 0x29, 0x01, 0x23, 0xdb, 0x01, 0xd3, 0x94, - 0x2f, 0xfe, 0x06, 0x7f, 0xf6, 0x02, 0xdd, 0x7d, 0x62, 0xfd, 0x25, 0x05, - 0xbf, 0x83, 0xf9, 0xbc, 0x03, 0x39, 0x00, 0x00, 0xff, 0xff, 0x00, 0x3b, - 0xff, 0xd9, 0x04, 0xa0, 0x07, 0x76, 0x10, 0x27, 0x00, 0x75, 0xff, 0x65, - 0x01, 0x86, 0x12, 0x06, 0x08, 0x25, 0x00, 0x00, 0xff, 0xff, 0x00, 0x3b, - 0xff, 0xd9, 0x04, 0xa0, 0x07, 0x65, 0x10, 0x27, 0x07, 0x40, 0xff, 0x65, - 0x01, 0x86, 0x12, 0x06, 0x08, 0x25, 0x00, 0x00, 0x00, 0x02, 0x00, 0xba, - 0x00, 0xfa, 0x04, 0x17, 0x03, 0xf0, 0x00, 0x0b, 0x00, 0x25, 0x00, 0x00, - 0x01, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, - 0x01, 0x22, 0x26, 0x27, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, - 0x33, 0x32, 0x16, 0x17, 0x3e, 0x01, 0x33, 0x15, 0x22, 0x06, 0x07, 0x1e, - 0x01, 0x33, 0x02, 0xaa, 0x38, 0x5c, 0x3c, 0x48, 0x5a, 0x52, 0x44, 0x44, - 0x6a, 0x01, 0x9a, 0x50, 0x80, 0x4e, 0x42, 0x84, 0x54, 0x7e, 0xa6, 0x9e, - 0x84, 0x5e, 0x88, 0x38, 0x2e, 0x94, 0x5a, 0x38, 0x68, 0x2e, 0x38, 0x5c, - 0x3a, 0x02, 0x7b, 0x86, 0x63, 0x85, 0x6a, 0x6d, 0x81, 0x76, 0xfe, 0xfd, - 0x64, 0x83, 0x7c, 0x6b, 0xd6, 0xa5, 0xad, 0xce, 0x73, 0x81, 0x75, 0x7f, - 0x8c, 0x75, 0x7c, 0x88, 0x64, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x29, - 0x00, 0xfa, 0x04, 0xa8, 0x03, 0xf0, 0x00, 0x0b, 0x00, 0x17, 0x00, 0x2f, - 0x00, 0x37, 0x40, 0x1c, 0x24, 0x18, 0x09, 0x15, 0x03, 0xe1, 0x27, 0x21, - 0xe2, 0x0f, 0x09, 0xe1, 0x2d, 0x1b, 0xdf, 0x30, 0x0c, 0x00, 0x24, 0x18, - 0x12, 0x06, 0x64, 0x1e, 0x12, 0x64, 0x2a, 0x30, 0x10, 0xd4, 0xec, 0xd4, - 0xec, 0x11, 0x39, 0x39, 0x39, 0x39, 0x31, 0x00, 0x10, 0xfc, 0x3c, 0xec, - 0x32, 0xfc, 0x3c, 0xec, 0x32, 0x11, 0x39, 0x39, 0x30, 0x01, 0x1e, 0x01, - 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x2e, 0x01, - 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x13, 0x3e, 0x01, - 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x27, 0x0e, 0x01, - 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x02, 0xb6, 0x39, - 0x5b, 0x3d, 0x47, 0x5b, 0x54, 0x46, 0x42, 0x69, 0xcb, 0x38, 0x5c, 0x3d, - 0x47, 0x5b, 0x53, 0x44, 0x43, 0x6a, 0x7e, 0x2f, 0x93, 0x5b, 0x77, 0xac, - 0xa3, 0x7e, 0x53, 0x80, 0x4e, 0x41, 0x84, 0x55, 0x7d, 0xa6, 0x9d, 0x84, - 0x5e, 0x88, 0x02, 0x73, 0x88, 0x64, 0x86, 0x6c, 0x6b, 0x80, 0x75, 0x74, - 0x86, 0x63, 0x85, 0x6a, 0x6d, 0x81, 0x76, 0x00, 0xff, 0x75, 0x7f, 0xdb, - 0xa0, 0xa7, 0xd4, 0x64, 0x83, 0x7c, 0x6b, 0xd6, 0xa5, 0xad, 0xce, 0x73, - 0x00, 0x01, 0x00, 0x7d, 0x01, 0x1f, 0x04, 0x54, 0x04, 0xf5, 0x00, 0x05, - 0x00, 0x00, 0x01, 0x21, 0x11, 0x33, 0x11, 0x21, 0x04, 0x54, 0xfc, 0x2a, - 0xaa, 0x03, 0x2c, 0x01, 0x1f, 0x03, 0xd6, 0xfc, 0xd4, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x7d, 0x01, 0x1f, 0x04, 0x54, 0x04, 0xf5, 0x00, 0x05, - 0x00, 0x00, 0x01, 0x21, 0x01, 0x33, 0x01, 0x21, 0x04, 0x54, 0xfc, 0x2a, - 0x03, 0x18, 0xaa, 0xfd, 0x70, 0x02, 0xa4, 0x01, 0x1f, 0x03, 0xd6, 0xfc, - 0xd4, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xa4, 0x00, 0x00, 0x04, 0x2c, - 0x04, 0xa2, 0x00, 0x06, 0x00, 0x00, 0x33, 0x01, 0x33, 0x01, 0x23, 0x09, - 0x01, 0xa4, 0x01, 0x4e, 0xed, 0x01, 0x4d, 0xbf, 0xfe, 0xfb, 0xfe, 0xfb, - 0x04, 0xa2, 0xfb, 0x5e, 0x03, 0xac, 0xfc, 0x54, 0x00, 0x01, 0x00, 0xa4, - 0x00, 0x00, 0x04, 0x2c, 0x04, 0xa2, 0x00, 0x06, 0x00, 0x00, 0x13, 0x33, - 0x09, 0x01, 0x33, 0x01, 0x23, 0xa4, 0xbf, 0x01, 0x05, 0x01, 0x05, 0xbf, - 0xfe, 0xb3, 0xed, 0x04, 0xa2, 0xfc, 0x54, 0x03, 0xac, 0xfb, 0x5e, 0x00, - 0x00, 0x01, 0x00, 0xa4, 0x00, 0x00, 0x04, 0x2c, 0x04, 0xa2, 0x00, 0x24, - 0x00, 0x00, 0x13, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, - 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x11, 0x23, 0x11, 0x34, 0x27, 0x26, - 0x27, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, - 0x15, 0x11, 0x23, 0xa4, 0x19, 0x1a, 0x3b, 0x39, 0x5f, 0x55, 0x69, 0x6a, - 0xaa, 0x42, 0x39, 0x1d, 0x18, 0xac, 0x0c, 0x0a, 0x07, 0x1d, 0x4b, 0x47, - 0x4c, 0x56, 0x3c, 0x53, 0x15, 0x0d, 0x04, 0x0c, 0xad, 0x02, 0x44, 0xe6, - 0x62, 0x67, 0x3a, 0x38, 0x20, 0x1d, 0x3a, 0x3b, 0x33, 0x6c, 0x5c, 0xee, - 0xfd, 0xbc, 0x02, 0xa2, 0x5d, 0x41, 0x39, 0x0e, 0x39, 0x20, 0x1e, 0x1e, - 0x29, 0x30, 0x21, 0x26, 0x70, 0x30, 0xfd, 0x60, 0x00, 0x01, 0x00, 0xa4, - 0x00, 0x00, 0x04, 0x2c, 0x04, 0xa2, 0x00, 0x24, 0x00, 0x00, 0x13, 0x11, - 0x33, 0x11, 0x14, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, - 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, 0x11, 0x33, 0x11, 0x14, 0x07, 0x06, - 0x07, 0x0e, 0x01, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0xa4, - 0xad, 0x0c, 0x04, 0x0d, 0x15, 0x53, 0x3c, 0x56, 0x4c, 0x47, 0x4b, 0x1d, - 0x07, 0x0a, 0x0c, 0xac, 0x18, 0x1d, 0x39, 0x42, 0xaa, 0x6a, 0x69, 0x55, - 0x5f, 0x39, 0x3b, 0x1a, 0x19, 0x02, 0x5e, 0x02, 0x44, 0xfd, 0x60, 0x30, - 0x70, 0x26, 0x21, 0x30, 0x29, 0x1e, 0x1e, 0x20, 0x39, 0x0e, 0x39, 0x41, - 0x5d, 0x02, 0xa2, 0xfd, 0xbc, 0xee, 0x5c, 0x6c, 0x33, 0x3b, 0x3a, 0x1d, - 0x20, 0x38, 0x3a, 0x67, 0x62, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x81, - 0xfe, 0x89, 0x04, 0x50, 0x06, 0xf8, 0x00, 0x17, 0x00, 0x1a, 0x40, 0x05, - 0x0c, 0x0d, 0x06, 0x01, 0x00, 0x2f, 0x3c, 0xfc, 0x3c, 0x31, 0x00, 0x40, - 0x06, 0x05, 0x8c, 0x0a, 0x16, 0x8c, 0x11, 0x2f, 0xec, 0x2f, 0xec, 0x30, - 0x05, 0x11, 0x34, 0x37, 0x36, 0x37, 0x36, 0x17, 0x07, 0x26, 0x07, 0x06, - 0x15, 0x11, 0x14, 0x07, 0x06, 0x07, 0x06, 0x27, 0x37, 0x16, 0x37, 0x36, - 0x02, 0x0c, 0x5e, 0x41, 0x91, 0x86, 0x8e, 0x6a, 0x5c, 0x4e, 0x78, 0x5d, - 0x41, 0x91, 0x86, 0x8e, 0x6a, 0x5c, 0x4e, 0x77, 0x44, 0x06, 0x22, 0x6a, - 0x64, 0x45, 0x07, 0x06, 0x71, 0x71, 0x43, 0x03, 0x05, 0x92, 0xf9, 0xde, - 0x6a, 0x64, 0x45, 0x07, 0x06, 0x71, 0x71, 0x43, 0x03, 0x05, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x3f, 0xfe, 0x7c, 0x04, 0x91, 0x07, 0x05, 0x00, 0x17, - 0x00, 0x2f, 0x00, 0x00, 0x05, 0x11, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, - 0x07, 0x26, 0x07, 0x06, 0x15, 0x03, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, - 0x37, 0x16, 0x37, 0x36, 0x25, 0x13, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, - 0x07, 0x26, 0x07, 0x06, 0x15, 0x11, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, - 0x37, 0x16, 0x37, 0x36, 0x02, 0xe4, 0x39, 0x43, 0x6d, 0x6a, 0x5a, 0x43, - 0x43, 0x3a, 0x35, 0x01, 0x39, 0x43, 0x6d, 0x6a, 0x5a, 0x43, 0x4d, 0x30, - 0x36, 0xfe, 0x50, 0x01, 0x39, 0x43, 0x6d, 0x6a, 0x5a, 0x43, 0x43, 0x3a, - 0x36, 0x39, 0x43, 0x6d, 0x6a, 0x5a, 0x43, 0x4d, 0x30, 0x35, 0x44, 0x06, - 0x22, 0x62, 0x5c, 0x69, 0x39, 0x7f, 0x26, 0x0a, 0x09, 0x9b, 0xf9, 0xde, - 0x62, 0x5c, 0x69, 0x39, 0x7f, 0x2b, 0x0f, 0x11, 0x93, 0x06, 0x22, 0x62, - 0x5c, 0x69, 0x39, 0x7f, 0x26, 0x0a, 0x09, 0x9b, 0xf9, 0xde, 0x62, 0x5c, - 0x69, 0x39, 0x7f, 0x2b, 0x0f, 0x11, 0x00, 0x00, 0x00, 0x03, 0x00, 0x35, - 0xfe, 0x97, 0x04, 0x9d, 0x06, 0xea, 0x00, 0x17, 0x00, 0x2f, 0x00, 0x47, - 0x00, 0x00, 0x05, 0x11, 0x34, 0x37, 0x36, 0x37, 0x36, 0x17, 0x07, 0x26, - 0x23, 0x22, 0x15, 0x11, 0x14, 0x07, 0x06, 0x07, 0x06, 0x27, 0x37, 0x16, - 0x33, 0x32, 0x25, 0x11, 0x34, 0x37, 0x36, 0x37, 0x36, 0x17, 0x07, 0x26, - 0x23, 0x22, 0x15, 0x11, 0x14, 0x07, 0x06, 0x07, 0x06, 0x27, 0x37, 0x16, - 0x33, 0x32, 0x25, 0x11, 0x34, 0x37, 0x36, 0x37, 0x36, 0x17, 0x07, 0x26, - 0x23, 0x22, 0x15, 0x11, 0x14, 0x07, 0x06, 0x07, 0x06, 0x27, 0x37, 0x16, - 0x33, 0x32, 0x03, 0x52, 0x31, 0x2d, 0x71, 0x32, 0x4a, 0x24, 0x22, 0x32, - 0x1b, 0x32, 0x2d, 0x71, 0x32, 0x4a, 0x24, 0x22, 0x32, 0x1c, 0xfe, 0xbc, - 0x31, 0x2d, 0x71, 0x32, 0x4a, 0x24, 0x22, 0x32, 0x1b, 0x32, 0x2d, 0x71, - 0x32, 0x4a, 0x24, 0x22, 0x32, 0x1c, 0xfe, 0xba, 0x32, 0x2d, 0x71, 0x32, - 0x4a, 0x24, 0x22, 0x32, 0x1c, 0x31, 0x2d, 0x71, 0x32, 0x4a, 0x24, 0x22, - 0x32, 0x1b, 0x7f, 0x06, 0x5d, 0x6d, 0x53, 0x4a, 0x02, 0x01, 0x1d, 0x8e, - 0x0e, 0x4e, 0xf9, 0xa3, 0x6f, 0x51, 0x4a, 0x02, 0x01, 0x1d, 0x8e, 0x0e, - 0x4e, 0x06, 0x5d, 0x6d, 0x53, 0x4a, 0x02, 0x01, 0x1d, 0x8e, 0x0e, 0x4e, - 0xf9, 0xa3, 0x6f, 0x51, 0x4a, 0x02, 0x01, 0x1d, 0x8e, 0x0e, 0x4e, 0x06, - 0x5d, 0x6d, 0x53, 0x4a, 0x02, 0x01, 0x1d, 0x8e, 0x0e, 0x4e, 0xf9, 0xa3, - 0x6f, 0x51, 0x4a, 0x02, 0x01, 0x1d, 0x8e, 0x0e, 0xff, 0xff, 0x00, 0xbb, - 0x00, 0x86, 0x04, 0x19, 0x04, 0x84, 0x10, 0x27, 0x08, 0x9a, 0xff, 0xff, - 0x01, 0x24, 0x10, 0x27, 0x08, 0x9a, 0xfe, 0xd2, 0xfe, 0x57, 0x10, 0x07, - 0x08, 0x9a, 0x01, 0x34, 0xfe, 0x57, 0x00, 0x00, 0xff, 0xff, 0x00, 0xbc, - 0x00, 0x86, 0x04, 0x15, 0x04, 0x84, 0x10, 0x27, 0x08, 0x9a, 0x00, 0x03, - 0xfe, 0x57, 0x10, 0x27, 0x08, 0x9a, 0xfe, 0xd3, 0x01, 0x24, 0x10, 0x07, - 0x08, 0x9a, 0x01, 0x30, 0x01, 0x24, 0x00, 0x00, 0xff, 0xff, 0x01, 0xe8, - 0x00, 0x86, 0x02, 0xe8, 0x04, 0x84, 0x10, 0x27, 0x08, 0x9a, 0x00, 0x03, - 0xfe, 0x57, 0x10, 0x07, 0x08, 0x9a, 0xff, 0xff, 0x01, 0x24, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xbb, 0x00, 0x86, 0x04, 0x19, 0x04, 0x84, 0x10, 0x27, - 0x08, 0x9a, 0xfe, 0xd2, 0xfe, 0x57, 0x10, 0x27, 0x08, 0x9a, 0xfe, 0xd3, - 0x01, 0x24, 0x10, 0x27, 0x08, 0x9a, 0x01, 0x34, 0xfe, 0x57, 0x10, 0x07, - 0x08, 0x9a, 0x01, 0x30, 0x01, 0x24, 0x00, 0x00, 0xff, 0xff, 0x00, 0x58, - 0x02, 0x2d, 0x04, 0x79, 0x04, 0x84, 0x10, 0x26, 0x08, 0x1f, 0x00, 0x00, - 0x10, 0x07, 0x08, 0x9a, 0x00, 0x02, 0x01, 0x24, 0x00, 0x03, 0x00, 0x4a, - 0x00, 0x86, 0x04, 0x87, 0x04, 0x84, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, - 0x00, 0x00, 0x01, 0x33, 0x11, 0x23, 0x03, 0x33, 0x11, 0x23, 0x01, 0x21, - 0x15, 0x21, 0x03, 0x8b, 0xfc, 0xfc, 0x02, 0xfc, 0xfc, 0xfc, 0xc1, 0x02, - 0xea, 0xfd, 0x16, 0x04, 0x84, 0xfe, 0xcf, 0xfe, 0x64, 0xfe, 0xcf, 0x02, - 0x51, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x00, 0x57, 0x00, 0x86, 0x04, 0x7d, - 0x04, 0x84, 0x10, 0x26, 0x08, 0x1f, 0x00, 0x00, 0x10, 0x27, 0x08, 0x9a, - 0x01, 0x94, 0x01, 0x24, 0x10, 0x27, 0x08, 0x9a, 0x01, 0x98, 0xfe, 0x57, - 0x10, 0x27, 0x08, 0x9a, 0xfe, 0x6f, 0x01, 0x24, 0x10, 0x07, 0x08, 0x9a, - 0xfe, 0x6e, 0xfe, 0x57, 0xff, 0xff, 0x00, 0x58, 0x00, 0x86, 0x04, 0x79, - 0x04, 0x84, 0x10, 0x26, 0x08, 0x3b, 0x00, 0x00, 0x10, 0x27, 0x08, 0x9a, - 0x00, 0x02, 0x01, 0x24, 0x10, 0x07, 0x08, 0x9a, 0x00, 0x01, 0xfe, 0x57, - 0x00, 0x01, 0x00, 0x58, 0x01, 0xf1, 0x04, 0x79, 0x03, 0x12, 0x00, 0x1b, - 0x00, 0x00, 0x01, 0x15, 0x0e, 0x01, 0x23, 0x22, 0x27, 0x26, 0x27, 0x2e, - 0x01, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x17, - 0x16, 0x17, 0x16, 0x33, 0x32, 0x36, 0x04, 0x79, 0x4b, 0x8f, 0x4f, 0x5a, - 0x71, 0x16, 0x0b, 0x4d, 0x67, 0x33, 0x4f, 0x8d, 0x49, 0x4e, 0x92, 0x53, - 0x35, 0x64, 0x4b, 0x0a, 0x16, 0x74, 0x5d, 0x46, 0x89, 0x03, 0x12, 0xaf, - 0x3b, 0x37, 0x33, 0x0a, 0x04, 0x22, 0x18, 0x3b, 0x40, 0xae, 0x3c, 0x37, - 0x16, 0x20, 0x04, 0x0b, 0x36, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x58, - 0x01, 0xf1, 0x04, 0x79, 0x03, 0x12, 0x00, 0x1b, 0x00, 0x00, 0x13, 0x1e, - 0x01, 0x33, 0x32, 0x37, 0x36, 0x37, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x17, - 0x15, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, - 0x26, 0x27, 0x58, 0x4a, 0x89, 0x46, 0x5d, 0x74, 0x16, 0x0a, 0x4b, 0x64, - 0x35, 0x53, 0x92, 0x4e, 0x49, 0x8d, 0x4f, 0x33, 0x67, 0x4d, 0x0b, 0x16, - 0x71, 0x5a, 0x4f, 0x8f, 0x4b, 0x03, 0x12, 0x3f, 0x3c, 0x36, 0x0b, 0x04, - 0x20, 0x16, 0x37, 0x3c, 0xae, 0x40, 0x3b, 0x18, 0x22, 0x04, 0x0a, 0x33, - 0x37, 0x3b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x58, 0x00, 0xae, 0x04, 0x79, - 0x04, 0x47, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x26, 0x27, 0x26, 0x23, 0x22, - 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x17, 0x16, 0x17, 0x13, 0x17, - 0x03, 0x16, 0x33, 0x32, 0x36, 0x37, 0x15, 0x0e, 0x01, 0x23, 0x22, 0x27, - 0x03, 0x27, 0x02, 0x18, 0x1d, 0x17, 0x34, 0x33, 0x4f, 0x8d, 0x49, 0x4e, - 0x92, 0x53, 0x36, 0x31, 0x2d, 0x1d, 0x4e, 0x88, 0x53, 0x58, 0x49, 0x46, - 0x89, 0x4a, 0x4b, 0x8f, 0x4f, 0x51, 0x64, 0x53, 0x88, 0x02, 0x50, 0x0b, - 0x05, 0x0c, 0x3b, 0x40, 0xae, 0x3c, 0x37, 0x0b, 0x0b, 0x0c, 0x01, 0x57, - 0x1f, 0xfe, 0x91, 0x22, 0x3c, 0x3f, 0xaf, 0x3b, 0x37, 0x29, 0xfe, 0x94, - 0x1f, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x58, 0x01, 0x31, 0x04, 0x79, - 0x03, 0xa2, 0x00, 0x03, 0x00, 0x1d, 0x00, 0x00, 0x13, 0x21, 0x15, 0x21, - 0x05, 0x15, 0x0e, 0x01, 0x23, 0x22, 0x2f, 0x01, 0x2e, 0x01, 0x23, 0x22, - 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x17, 0x33, 0x17, 0x16, 0x33, - 0x32, 0x36, 0x58, 0x04, 0x21, 0xfb, 0xdf, 0x04, 0x21, 0x4b, 0x8f, 0x4f, - 0x5a, 0x71, 0x21, 0x53, 0x63, 0x31, 0x4e, 0x8d, 0x4a, 0x4f, 0x92, 0x52, - 0x60, 0x82, 0x01, 0x21, 0x74, 0x5d, 0x44, 0x8a, 0x03, 0xa2, 0xaa, 0xa4, - 0xb0, 0x3b, 0x38, 0x33, 0x0f, 0x24, 0x17, 0x3c, 0x41, 0xae, 0x3e, 0x37, - 0x37, 0x0f, 0x37, 0x3d, 0x00, 0x02, 0x00, 0x58, 0x01, 0x60, 0x04, 0x79, - 0x03, 0xc3, 0x00, 0x03, 0x00, 0x1f, 0x00, 0x00, 0x13, 0x21, 0x15, 0x21, - 0x01, 0x15, 0x0e, 0x01, 0x23, 0x22, 0x27, 0x26, 0x27, 0x2e, 0x01, 0x23, - 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x17, 0x16, 0x17, - 0x16, 0x33, 0x32, 0x36, 0x58, 0x04, 0x21, 0xfb, 0xdf, 0x04, 0x21, 0x4b, - 0x8f, 0x4f, 0x5a, 0x71, 0x16, 0x0b, 0x4d, 0x67, 0x33, 0x4f, 0x8d, 0x49, - 0x4e, 0x92, 0x53, 0x35, 0x64, 0x4b, 0x0a, 0x16, 0x74, 0x5d, 0x46, 0x89, - 0x02, 0x0c, 0xac, 0x02, 0x63, 0xaf, 0x3b, 0x37, 0x33, 0x0a, 0x04, 0x22, - 0x18, 0x3b, 0x40, 0xae, 0x3c, 0x37, 0x16, 0x20, 0x04, 0x0b, 0x36, 0x3c, - 0x00, 0x01, 0x00, 0x58, 0x00, 0x62, 0x04, 0x7a, 0x04, 0xd5, 0x00, 0x27, - 0x00, 0x00, 0x01, 0x03, 0x16, 0x37, 0x36, 0x37, 0x15, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x07, 0x21, 0x15, 0x21, 0x07, 0x27, 0x37, 0x23, 0x35, - 0x21, 0x37, 0x26, 0x27, 0x26, 0x07, 0x06, 0x07, 0x35, 0x36, 0x37, 0x36, - 0x37, 0x36, 0x1f, 0x02, 0x13, 0x03, 0xc7, 0xa7, 0x66, 0x59, 0x55, 0x45, - 0x35, 0x6b, 0x49, 0x51, 0x25, 0x5c, 0x6e, 0x02, 0x2a, 0xfd, 0x78, 0x98, - 0x72, 0x59, 0xe9, 0x01, 0x51, 0x92, 0x4d, 0x6f, 0x49, 0x46, 0x5c, 0x3c, - 0x5b, 0x45, 0x54, 0x46, 0x52, 0x82, 0x0d, 0x1d, 0xc6, 0x04, 0x71, 0xfe, - 0xe0, 0x13, 0x24, 0x22, 0x42, 0xb2, 0x32, 0x28, 0x1a, 0x1e, 0xb2, 0xab, - 0xfe, 0x64, 0x9a, 0xab, 0xe7, 0x25, 0x05, 0x04, 0x1f, 0x28, 0x39, 0xac, - 0x4c, 0x13, 0x16, 0x02, 0x03, 0x35, 0x05, 0x10, 0x01, 0x58, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x58, 0x00, 0xc0, 0x04, 0x79, 0x04, 0x8f, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x24, 0x00, 0x00, 0x13, 0x21, 0x15, 0x21, 0x15, 0x21, - 0x15, 0x21, 0x01, 0x15, 0x0e, 0x01, 0x23, 0x22, 0x27, 0x26, 0x27, 0x2e, - 0x01, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x17, 0x16, - 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x36, 0x58, 0x04, 0x21, 0xfb, 0xdf, - 0x04, 0x21, 0xfb, 0xdf, 0x04, 0x21, 0x4b, 0x8f, 0x4f, 0x5a, 0x71, 0x16, - 0x0b, 0x4d, 0x67, 0x33, 0x4f, 0x8d, 0x49, 0x4e, 0x92, 0x53, 0x35, 0x32, - 0x27, 0x56, 0x0a, 0x16, 0x74, 0x5d, 0x46, 0x89, 0x02, 0xd8, 0xac, 0xc0, - 0xac, 0x03, 0xcf, 0xaf, 0x3b, 0x37, 0x33, 0x0a, 0x04, 0x22, 0x18, 0x3b, - 0x40, 0xae, 0x3c, 0x37, 0x0b, 0x09, 0x22, 0x04, 0x0b, 0x36, 0x3c, 0x00, - 0x00, 0x02, 0x00, 0x58, 0x00, 0x31, 0x04, 0x79, 0x04, 0x8f, 0x00, 0x13, - 0x00, 0x30, 0x00, 0x00, 0x25, 0x23, 0x35, 0x21, 0x37, 0x21, 0x35, 0x21, - 0x37, 0x17, 0x07, 0x33, 0x15, 0x21, 0x07, 0x21, 0x15, 0x21, 0x07, 0x27, - 0x01, 0x15, 0x0e, 0x01, 0x23, 0x22, 0x27, 0x26, 0x27, 0x2e, 0x01, 0x23, - 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, - 0x17, 0x16, 0x33, 0x32, 0x36, 0x01, 0x51, 0xf9, 0x01, 0x75, 0x8b, 0xfe, - 0x00, 0x02, 0x7b, 0x68, 0x71, 0x2c, 0xf9, 0xfe, 0x8b, 0x8b, 0x02, 0x00, - 0xfd, 0x84, 0x67, 0x71, 0x03, 0x54, 0x4b, 0x8f, 0x4f, 0x5a, 0x71, 0x16, - 0x0b, 0x4d, 0x67, 0x33, 0x4f, 0x8d, 0x49, 0x4e, 0x92, 0x53, 0x35, 0x32, - 0x27, 0x56, 0x0a, 0x16, 0x74, 0x5d, 0x46, 0x89, 0xc0, 0xac, 0xc0, 0xac, - 0x8f, 0x52, 0x3d, 0xac, 0xc0, 0xac, 0x8f, 0x52, 0x04, 0x0c, 0xaf, 0x3b, - 0x37, 0x33, 0x0a, 0x04, 0x22, 0x18, 0x3b, 0x40, 0xae, 0x3c, 0x37, 0x0b, - 0x09, 0x22, 0x04, 0x0b, 0x36, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x58, - 0x00, 0x00, 0x04, 0x79, 0x05, 0x2e, 0x00, 0x31, 0x00, 0x00, 0x25, 0x21, - 0x35, 0x21, 0x37, 0x21, 0x35, 0x21, 0x37, 0x26, 0x27, 0x2e, 0x01, 0x23, - 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x17, 0x16, 0x1f, 0x01, - 0x37, 0x17, 0x07, 0x16, 0x33, 0x32, 0x36, 0x37, 0x15, 0x0e, 0x01, 0x23, - 0x22, 0x27, 0x07, 0x21, 0x15, 0x21, 0x07, 0x21, 0x15, 0x21, 0x07, 0x27, - 0x01, 0x68, 0xfe, 0xf0, 0x01, 0x4d, 0x45, 0xfe, 0x6e, 0x01, 0xd0, 0x4b, - 0x09, 0x06, 0x4d, 0x67, 0x33, 0x4f, 0x8d, 0x49, 0x4e, 0x92, 0x53, 0x35, - 0x32, 0x33, 0x4a, 0x3a, 0x56, 0x9b, 0x51, 0x0b, 0x0c, 0x46, 0x89, 0x4a, - 0x4b, 0x8f, 0x4f, 0x1f, 0x21, 0x38, 0x01, 0xa1, 0xfe, 0x21, 0x45, 0x02, - 0x24, 0xfd, 0x9f, 0x46, 0x9c, 0xc0, 0xac, 0xc0, 0xac, 0xd1, 0x04, 0x02, - 0x22, 0x18, 0x3b, 0x40, 0xae, 0x3c, 0x37, 0x0b, 0x0b, 0x20, 0x19, 0xee, - 0x38, 0xe1, 0x01, 0x3c, 0x3f, 0xaf, 0x3b, 0x37, 0x06, 0x9c, 0xac, 0xc0, - 0xac, 0xc0, 0x37, 0x00, 0x00, 0x02, 0x00, 0x58, 0x01, 0x31, 0x04, 0x79, - 0x03, 0xc3, 0x00, 0x1b, 0x00, 0x37, 0x00, 0x4b, 0x40, 0x26, 0x1d, 0x27, - 0x20, 0x31, 0x30, 0x2b, 0x03, 0x35, 0x1c, 0x01, 0x0b, 0x04, 0x0f, 0x19, - 0x0b, 0xa0, 0x12, 0x00, 0x19, 0xa0, 0x0e, 0x04, 0x2a, 0x20, 0xa0, 0x35, - 0x27, 0xa0, 0x2e, 0x1c, 0x38, 0x31, 0x30, 0x1c, 0x00, 0x2a, 0x0e, 0x38, - 0x10, 0xd4, 0x3c, 0xc4, 0x32, 0x39, 0x39, 0x31, 0x00, 0x10, 0xd4, 0x3c, - 0xec, 0xd4, 0xec, 0x32, 0xdc, 0x3c, 0xfc, 0xd4, 0x3c, 0xec, 0x12, 0x39, - 0x11, 0x12, 0x39, 0x11, 0x12, 0x17, 0x39, 0x11, 0x12, 0x39, 0x30, 0x01, - 0x15, 0x0e, 0x01, 0x23, 0x22, 0x27, 0x26, 0x27, 0x2e, 0x01, 0x23, 0x22, - 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x17, 0x16, 0x17, 0x16, - 0x33, 0x32, 0x36, 0x13, 0x15, 0x0e, 0x01, 0x23, 0x22, 0x27, 0x26, 0x27, - 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x17, - 0x33, 0x16, 0x17, 0x16, 0x33, 0x32, 0x36, 0x04, 0x79, 0x4b, 0x8f, 0x4f, - 0x5a, 0x71, 0x16, 0x0b, 0x4d, 0x67, 0x33, 0x4f, 0x8d, 0x49, 0x4e, 0x92, - 0x53, 0x35, 0x64, 0x4b, 0x0a, 0x16, 0x74, 0x5d, 0x46, 0x89, 0x4a, 0x4b, - 0x8f, 0x4f, 0x5a, 0x71, 0x16, 0x0b, 0x53, 0x63, 0x31, 0x4e, 0x8d, 0x4a, - 0x4f, 0x92, 0x52, 0x60, 0x82, 0x01, 0x0b, 0x16, 0x74, 0x5d, 0x44, 0x8a, - 0x03, 0xc3, 0xaf, 0x3b, 0x37, 0x33, 0x0a, 0x04, 0x22, 0x18, 0x3b, 0x40, - 0xae, 0x3c, 0x37, 0x16, 0x20, 0x04, 0x0b, 0x36, 0x3c, 0xfe, 0xd0, 0xb0, - 0x3b, 0x38, 0x33, 0x0a, 0x05, 0x24, 0x17, 0x3c, 0x41, 0xae, 0x3e, 0x37, - 0x37, 0x05, 0x0a, 0x37, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x58, - 0x00, 0x30, 0x04, 0x79, 0x04, 0xc3, 0x00, 0x38, 0x00, 0x00, 0x01, 0x26, - 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x17, 0x37, 0x26, - 0x27, 0x26, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x17, - 0x16, 0x17, 0x13, 0x17, 0x03, 0x16, 0x33, 0x32, 0x36, 0x37, 0x15, 0x0e, - 0x01, 0x23, 0x22, 0x27, 0x07, 0x16, 0x33, 0x32, 0x36, 0x37, 0x15, 0x0e, - 0x01, 0x23, 0x22, 0x2f, 0x01, 0x03, 0x27, 0x01, 0xdd, 0x30, 0x30, 0x4e, - 0x8d, 0x4a, 0x4f, 0x92, 0x52, 0x3a, 0x47, 0x36, 0x37, 0x27, 0x34, 0x33, - 0x4f, 0x8d, 0x49, 0x4e, 0x92, 0x53, 0x35, 0x32, 0x30, 0x4e, 0x5d, 0x8a, - 0x61, 0x39, 0x31, 0x46, 0x89, 0x4a, 0x4b, 0x8f, 0x4f, 0x3f, 0x4a, 0x34, - 0x72, 0x5b, 0x44, 0x8a, 0x4b, 0x4b, 0x8f, 0x4f, 0x64, 0x67, 0x1f, 0x62, - 0x8a, 0x01, 0xa3, 0x0b, 0x3c, 0x41, 0xae, 0x3e, 0x37, 0x14, 0xb2, 0x16, - 0x09, 0x0c, 0x3b, 0x40, 0xae, 0x3c, 0x37, 0x0b, 0x0b, 0x21, 0x01, 0x37, - 0x29, 0xfe, 0xbd, 0x0f, 0x3c, 0x3f, 0xaf, 0x3b, 0x37, 0x19, 0xaf, 0x35, - 0x3d, 0x40, 0xb0, 0x3b, 0x38, 0x33, 0x10, 0xfe, 0xbc, 0x29, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x58, 0x00, 0xc0, 0x04, 0x79, 0x04, 0x93, 0x00, 0x1b, - 0x00, 0x37, 0x00, 0x3b, 0x00, 0x00, 0x01, 0x15, 0x0e, 0x01, 0x23, 0x22, - 0x27, 0x26, 0x27, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, - 0x33, 0x32, 0x16, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x36, 0x13, 0x15, - 0x0e, 0x01, 0x23, 0x22, 0x27, 0x26, 0x27, 0x2e, 0x01, 0x23, 0x22, 0x06, - 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x17, 0x33, 0x16, 0x17, 0x16, 0x33, - 0x32, 0x36, 0x01, 0x21, 0x15, 0x21, 0x04, 0x79, 0x4b, 0x8f, 0x4f, 0x5a, - 0x71, 0x16, 0x0b, 0x4d, 0x67, 0x33, 0x4f, 0x8d, 0x49, 0x4e, 0x92, 0x53, - 0x35, 0x64, 0x4b, 0x0a, 0x16, 0x74, 0x5d, 0x46, 0x89, 0x4a, 0x4b, 0x8f, - 0x4f, 0x5a, 0x71, 0x16, 0x0b, 0x53, 0x63, 0x31, 0x4e, 0x8d, 0x4a, 0x4f, - 0x92, 0x52, 0x60, 0x82, 0x01, 0x0b, 0x16, 0x74, 0x5d, 0x44, 0x8a, 0xfc, - 0x2a, 0x04, 0x21, 0xfb, 0xdf, 0x04, 0x93, 0xaf, 0x3b, 0x37, 0x33, 0x0a, - 0x04, 0x22, 0x18, 0x3b, 0x40, 0xae, 0x3c, 0x37, 0x16, 0x20, 0x04, 0x0b, - 0x36, 0x3c, 0xfe, 0xd0, 0xb0, 0x3b, 0x38, 0x33, 0x0a, 0x05, 0x24, 0x17, - 0x3c, 0x41, 0xae, 0x3e, 0x37, 0x37, 0x05, 0x0a, 0x37, 0x3d, 0xfe, 0x88, - 0xac, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x58, 0x00, 0x95, 0x04, 0x79, - 0x04, 0x93, 0x00, 0x1b, 0x00, 0x37, 0x00, 0x53, 0x00, 0x00, 0x01, 0x15, - 0x0e, 0x01, 0x23, 0x22, 0x27, 0x26, 0x27, 0x2e, 0x01, 0x23, 0x22, 0x06, - 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x17, 0x33, 0x16, 0x17, 0x16, 0x33, - 0x32, 0x36, 0x13, 0x15, 0x0e, 0x01, 0x23, 0x22, 0x27, 0x26, 0x27, 0x2e, - 0x01, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x17, - 0x16, 0x17, 0x16, 0x33, 0x32, 0x36, 0x13, 0x15, 0x0e, 0x01, 0x23, 0x22, - 0x27, 0x26, 0x27, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, - 0x33, 0x32, 0x17, 0x33, 0x16, 0x17, 0x16, 0x33, 0x32, 0x36, 0x04, 0x79, - 0x4b, 0x8f, 0x4f, 0x5a, 0x71, 0x16, 0x0b, 0x53, 0x63, 0x31, 0x4e, 0x8d, - 0x4a, 0x4f, 0x92, 0x52, 0x60, 0x82, 0x01, 0x0b, 0x16, 0x74, 0x5d, 0x44, - 0x8a, 0x4b, 0x4b, 0x8f, 0x4f, 0x5a, 0x71, 0x16, 0x0b, 0x4d, 0x67, 0x33, - 0x4f, 0x8d, 0x49, 0x4e, 0x92, 0x53, 0x35, 0x64, 0x4b, 0x0a, 0x16, 0x74, - 0x5d, 0x46, 0x89, 0x4a, 0x4b, 0x8f, 0x4f, 0x5a, 0x71, 0x16, 0x0b, 0x53, - 0x63, 0x31, 0x4e, 0x8d, 0x4a, 0x4f, 0x92, 0x52, 0x60, 0x82, 0x01, 0x0b, - 0x16, 0x74, 0x5d, 0x44, 0x8a, 0x01, 0xb8, 0xb0, 0x3b, 0x38, 0x33, 0x0a, - 0x05, 0x24, 0x17, 0x3c, 0x41, 0xae, 0x3e, 0x37, 0x37, 0x05, 0x0a, 0x37, - 0x3d, 0x03, 0x1b, 0xaf, 0x3b, 0x37, 0x33, 0x0a, 0x04, 0x22, 0x18, 0x3b, - 0x40, 0xae, 0x3c, 0x37, 0x16, 0x20, 0x04, 0x0b, 0x36, 0x3c, 0xfe, 0xd0, - 0xb0, 0x3b, 0x38, 0x33, 0x0a, 0x05, 0x24, 0x17, 0x3c, 0x41, 0xae, 0x3e, - 0x37, 0x37, 0x05, 0x0a, 0x37, 0x3d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x58, - 0x00, 0xc0, 0x04, 0x79, 0x04, 0x8f, 0x00, 0x03, 0x00, 0x07, 0x00, 0x24, - 0x00, 0x00, 0x01, 0x15, 0x21, 0x35, 0x01, 0x15, 0x21, 0x35, 0x11, 0x1e, - 0x01, 0x33, 0x32, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x16, - 0x17, 0x15, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, - 0x22, 0x26, 0x27, 0x04, 0x79, 0xfb, 0xdf, 0x04, 0x21, 0xfb, 0xdf, 0x4a, - 0x89, 0x46, 0x5d, 0x74, 0x16, 0x0a, 0x56, 0x27, 0x32, 0x35, 0x53, 0x92, - 0x4e, 0x49, 0x8d, 0x4f, 0x33, 0x67, 0x4d, 0x0b, 0x16, 0x71, 0x5a, 0x4f, - 0x8f, 0x4b, 0x02, 0xd8, 0xac, 0xac, 0xfe, 0x94, 0xac, 0xac, 0x03, 0x23, - 0x3f, 0x3c, 0x36, 0x0b, 0x04, 0x22, 0x09, 0x0b, 0x37, 0x3c, 0xae, 0x40, - 0x3b, 0x18, 0x22, 0x04, 0x0a, 0x33, 0x37, 0x3b, 0x00, 0x02, 0x00, 0x57, - 0x00, 0xdd, 0x04, 0x79, 0x04, 0x27, 0x00, 0x08, 0x00, 0x11, 0x00, 0x00, - 0x00, 0x20, 0x25, 0x35, 0x04, 0x17, 0x32, 0x25, 0x15, 0x00, 0x20, 0x05, - 0x15, 0x24, 0x27, 0x22, 0x05, 0x35, 0x03, 0x31, 0xfe, 0x70, 0xfe, 0xb6, - 0x01, 0x5a, 0xb8, 0xb9, 0x01, 0x56, 0xfd, 0x28, 0x01, 0x90, 0x01, 0x49, - 0xfe, 0xa7, 0xb8, 0xb9, 0xfe, 0xa9, 0x02, 0xd9, 0x9c, 0xb2, 0x9c, 0x07, - 0xa3, 0xb2, 0xfe, 0xb6, 0x9c, 0xb2, 0x9c, 0x07, 0xa3, 0xb2, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x58, 0x00, 0x44, 0x04, 0x7a, 0x04, 0xbe, 0x00, 0x1d, - 0x00, 0x3b, 0x00, 0x00, 0x25, 0x16, 0x37, 0x36, 0x37, 0x36, 0x37, 0x21, - 0x15, 0x23, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, - 0x26, 0x27, 0x23, 0x35, 0x21, 0x16, 0x17, 0x16, 0x17, 0x16, 0x13, 0x06, - 0x07, 0x06, 0x07, 0x06, 0x07, 0x21, 0x35, 0x33, 0x36, 0x37, 0x36, 0x37, - 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x33, 0x15, 0x21, 0x26, - 0x27, 0x26, 0x27, 0x26, 0x02, 0x69, 0x31, 0x2a, 0x2b, 0x1b, 0x15, 0x04, - 0x01, 0x56, 0xe1, 0x09, 0x19, 0x1b, 0x57, 0x4a, 0x52, 0x4e, 0x4d, 0x52, - 0x20, 0x19, 0x09, 0xe1, 0x01, 0x57, 0x04, 0x15, 0x1a, 0x2c, 0x21, 0x3a, - 0x3a, 0x21, 0x2c, 0x1a, 0x15, 0x04, 0xfe, 0xa9, 0xe1, 0x06, 0x1c, 0x16, - 0x5c, 0x48, 0x53, 0x4c, 0x50, 0x4d, 0x25, 0x17, 0x0b, 0xe1, 0xfe, 0xaa, - 0x03, 0x16, 0x1b, 0x2b, 0x2a, 0xdf, 0x03, 0x25, 0x27, 0x48, 0x3a, 0x5e, - 0xa8, 0x32, 0x3a, 0x41, 0x3c, 0x33, 0x33, 0x36, 0x47, 0x38, 0x34, 0xa8, - 0x5e, 0x3a, 0x48, 0x27, 0x1e, 0x03, 0x40, 0x04, 0x1e, 0x27, 0x48, 0x3f, - 0x59, 0xa8, 0x20, 0x4c, 0x3d, 0x40, 0x33, 0x33, 0x2f, 0x4e, 0x30, 0x3c, - 0xa8, 0x5e, 0x3a, 0x48, 0x27, 0x25, 0x00, 0x00, 0x00, 0x02, 0x00, 0x58, - 0x01, 0x60, 0x04, 0x7a, 0x04, 0xbe, 0x00, 0x1d, 0x00, 0x21, 0x00, 0x00, - 0x01, 0x06, 0x07, 0x06, 0x07, 0x06, 0x07, 0x21, 0x35, 0x33, 0x36, 0x37, - 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x33, 0x15, - 0x21, 0x26, 0x27, 0x26, 0x27, 0x26, 0x01, 0x21, 0x15, 0x21, 0x02, 0x69, - 0x3a, 0x21, 0x2c, 0x1a, 0x15, 0x04, 0xfe, 0xa9, 0xe1, 0x06, 0x1c, 0x16, - 0x5c, 0x48, 0x53, 0x4c, 0x50, 0x4d, 0x25, 0x17, 0x0b, 0xe1, 0xfe, 0xaa, - 0x03, 0x16, 0x1b, 0x2b, 0x2a, 0xfd, 0xbe, 0x04, 0x21, 0xfb, 0xdf, 0x04, - 0x23, 0x04, 0x1e, 0x27, 0x48, 0x3f, 0x59, 0xa8, 0x20, 0x4c, 0x3d, 0x40, - 0x33, 0x33, 0x2f, 0x4e, 0x30, 0x3c, 0xa8, 0x5e, 0x3a, 0x48, 0x27, 0x25, - 0xfd, 0xe4, 0xaa, 0x00, 0xff, 0xff, 0x00, 0x58, 0x01, 0x60, 0x04, 0x79, - 0x05, 0x19, 0x10, 0x26, 0x00, 0x20, 0x00, 0x00, 0x10, 0x07, 0x08, 0x9a, - 0x00, 0x02, 0x01, 0xb9, 0xff, 0xff, 0x00, 0x58, 0xff, 0xe9, 0x04, 0x79, - 0x05, 0x19, 0x10, 0x26, 0x00, 0x20, 0x00, 0x00, 0x10, 0x27, 0x08, 0x9a, - 0x00, 0x02, 0x01, 0xb9, 0x10, 0x27, 0x08, 0x9a, 0x00, 0x02, 0x01, 0xb9, - 0x10, 0x07, 0x08, 0x9a, 0x00, 0x01, 0xfd, 0xba, 0xff, 0xff, 0x00, 0x58, - 0xff, 0xec, 0x04, 0x79, 0x05, 0x19, 0x10, 0x27, 0x08, 0x9a, 0x01, 0x94, - 0xfd, 0xbd, 0x10, 0x26, 0x00, 0x20, 0x00, 0x00, 0x10, 0x07, 0x08, 0x9a, - 0xfe, 0x6f, 0x01, 0xb9, 0xff, 0xff, 0x00, 0x57, 0xff, 0xec, 0x04, 0x7a, - 0x05, 0x19, 0x10, 0x27, 0x08, 0x9a, 0x01, 0x94, 0x01, 0xb9, 0x10, 0x26, - 0x00, 0x20, 0x00, 0x00, 0x10, 0x07, 0x08, 0x9a, 0xfe, 0x6e, 0xfd, 0xbd, - 0x00, 0x04, 0x00, 0x4a, 0x01, 0x2e, 0x04, 0x87, 0x03, 0xd5, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x00, 0x13, 0x33, 0x11, 0x23, - 0x11, 0x33, 0x11, 0x23, 0x05, 0x15, 0x21, 0x35, 0x01, 0x15, 0x21, 0x35, - 0x4a, 0xec, 0xec, 0xec, 0xec, 0x04, 0x3d, 0xfc, 0xfb, 0x03, 0x05, 0xfc, - 0xfb, 0x02, 0x3e, 0xfe, 0xf0, 0x02, 0xa7, 0xfe, 0xf0, 0xb9, 0xac, 0xac, - 0x01, 0x96, 0xaa, 0xaa, 0x00, 0x04, 0x00, 0x4a, 0x01, 0x2e, 0x04, 0x87, - 0x03, 0xd5, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x00, - 0x01, 0x11, 0x23, 0x11, 0x13, 0x11, 0x23, 0x11, 0x01, 0x21, 0x15, 0x21, - 0x11, 0x21, 0x15, 0x21, 0x04, 0x87, 0xec, 0xec, 0xec, 0xfc, 0xaf, 0x03, - 0x05, 0xfc, 0xfb, 0x03, 0x05, 0xfc, 0xfb, 0x02, 0x3e, 0xfe, 0xf0, 0x01, - 0x10, 0x01, 0x97, 0xfe, 0xf0, 0x01, 0x10, 0xfe, 0x37, 0xac, 0x02, 0x42, - 0xaa, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x58, 0x01, 0x60, 0x04, 0x79, - 0x03, 0xa2, 0x00, 0x09, 0x00, 0x1b, 0x00, 0x00, 0x01, 0x06, 0x15, 0x14, - 0x17, 0x33, 0x36, 0x35, 0x26, 0x27, 0x17, 0x21, 0x15, 0x21, 0x35, 0x21, - 0x26, 0x35, 0x34, 0x37, 0x21, 0x35, 0x21, 0x15, 0x21, 0x16, 0x15, 0x14, - 0x02, 0x25, 0x34, 0x33, 0x91, 0x34, 0x01, 0x34, 0x8d, 0x01, 0x38, 0xfb, - 0xdf, 0x01, 0x3e, 0x19, 0x1b, 0xfe, 0xc0, 0x04, 0x21, 0xfe, 0xc9, 0x1a, - 0x02, 0xfa, 0x30, 0x49, 0x47, 0x30, 0x30, 0x47, 0x47, 0x32, 0xf0, 0xaa, - 0xaa, 0x3f, 0x38, 0x3e, 0x3b, 0xa8, 0xa8, 0x1a, 0x5f, 0x38, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x58, 0x01, 0x60, 0x04, 0x79, 0x06, 0x15, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x11, 0x00, 0x20, 0x00, 0x00, 0x13, 0x21, 0x15, 0x21, - 0x11, 0x21, 0x15, 0x21, 0x01, 0x22, 0x06, 0x15, 0x14, 0x16, 0x32, 0x36, - 0x34, 0x26, 0x27, 0x32, 0x16, 0x17, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x23, - 0x22, 0x26, 0x35, 0x34, 0x36, 0x58, 0x04, 0x21, 0xfb, 0xdf, 0x04, 0x21, - 0xfb, 0xdf, 0x02, 0x11, 0x49, 0x64, 0x64, 0x92, 0x64, 0x65, 0x48, 0x3a, - 0x6c, 0x27, 0x2a, 0x2a, 0xa9, 0x7a, 0x7b, 0xa4, 0xa8, 0x02, 0x0c, 0xac, - 0x02, 0x42, 0xaa, 0x02, 0xac, 0x62, 0x46, 0x45, 0x60, 0x60, 0x8b, 0x62, - 0x71, 0x2b, 0x28, 0x28, 0x64, 0x3a, 0x73, 0xa1, 0x9e, 0x76, 0x76, 0xa3, - 0x00, 0x03, 0x00, 0x58, 0x01, 0x60, 0x04, 0x79, 0x05, 0x4b, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x11, 0x00, 0x00, 0x13, 0x21, 0x15, 0x21, 0x11, 0x21, - 0x15, 0x21, 0x01, 0x32, 0x17, 0x15, 0x26, 0x27, 0x06, 0x07, 0x35, 0x36, - 0x58, 0x04, 0x21, 0xfb, 0xdf, 0x04, 0x21, 0xfb, 0xdf, 0x02, 0x12, 0xe6, - 0xcb, 0xd7, 0xda, 0xd8, 0xdc, 0xd2, 0x02, 0x0c, 0xac, 0x02, 0x42, 0xaa, - 0x02, 0x53, 0x97, 0xb2, 0x97, 0x09, 0x02, 0x9e, 0xb2, 0x97, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x58, 0x01, 0x60, 0x04, 0x79, 0x06, 0x44, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x0e, 0x00, 0x00, 0x13, 0x21, 0x15, 0x21, 0x11, 0x21, - 0x15, 0x21, 0x37, 0x13, 0x33, 0x13, 0x23, 0x0b, 0x01, 0x58, 0x04, 0x21, - 0xfb, 0xdf, 0x04, 0x21, 0xfb, 0xdf, 0xd6, 0xea, 0xa2, 0xe9, 0x8f, 0xab, - 0xa6, 0x02, 0x0c, 0xac, 0x02, 0x42, 0xaa, 0xf2, 0x02, 0x5a, 0xfd, 0xa6, - 0x01, 0xaa, 0xfe, 0x56, 0x00, 0x03, 0x00, 0x58, 0x01, 0x60, 0x04, 0x79, - 0x06, 0x44, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x00, 0x13, 0x21, - 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x13, 0x33, 0x1b, 0x01, 0x33, 0x03, - 0x23, 0x58, 0x04, 0x21, 0xfb, 0xdf, 0x04, 0x21, 0xfb, 0xdf, 0xd6, 0x95, - 0xa6, 0xab, 0x8f, 0xe9, 0xa2, 0x02, 0x0c, 0xac, 0x02, 0x42, 0xaa, 0x03, - 0x4c, 0xfe, 0x56, 0x01, 0xaa, 0xfd, 0xa6, 0x00, 0x00, 0x03, 0x00, 0x58, - 0x01, 0x60, 0x04, 0x79, 0x06, 0xa5, 0x00, 0x03, 0x00, 0x07, 0x00, 0x11, - 0x00, 0x00, 0x13, 0x21, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x13, 0x21, - 0x1b, 0x01, 0x21, 0x07, 0x13, 0x27, 0x07, 0x13, 0x58, 0x04, 0x21, 0xfb, - 0xdf, 0x04, 0x21, 0xfb, 0xdf, 0xb0, 0x01, 0x0d, 0x54, 0x55, 0x01, 0x0c, - 0xda, 0x55, 0xdc, 0xdb, 0x54, 0x02, 0x0c, 0xac, 0x02, 0x42, 0xaa, 0x02, - 0xad, 0x01, 0x00, 0xff, 0x00, 0x9e, 0xff, 0x00, 0x9f, 0x9f, 0x01, 0x00, - 0x00, 0x04, 0x00, 0x58, 0x01, 0x60, 0x04, 0x79, 0x06, 0xb0, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x00, 0x13, 0x21, 0x15, 0x21, - 0x11, 0x21, 0x15, 0x21, 0x01, 0x03, 0x21, 0x03, 0x33, 0x01, 0x21, 0x58, - 0x04, 0x21, 0xfb, 0xdf, 0x04, 0x21, 0xfb, 0xdf, 0x02, 0x10, 0x96, 0x01, - 0x2d, 0xc9, 0x65, 0x01, 0x04, 0xfd, 0x93, 0x02, 0x0c, 0xac, 0x02, 0x42, - 0xaa, 0x03, 0x15, 0xfe, 0x7a, 0x02, 0x28, 0xfd, 0x69, 0x00, 0x00, 0x00, - 0x00, 0x07, 0x00, 0x45, 0x01, 0x60, 0x04, 0x8c, 0x06, 0x1d, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x1b, 0x00, 0x30, 0x00, 0x37, 0x00, 0x47, 0x00, 0x4f, - 0x00, 0x00, 0x13, 0x21, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x01, 0x15, - 0x23, 0x22, 0x06, 0x1d, 0x01, 0x33, 0x15, 0x23, 0x11, 0x23, 0x11, 0x23, - 0x35, 0x33, 0x35, 0x34, 0x36, 0x33, 0x03, 0x15, 0x21, 0x1e, 0x01, 0x33, - 0x32, 0x36, 0x37, 0x15, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, - 0x33, 0x32, 0x16, 0x07, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x27, 0x35, - 0x33, 0x11, 0x23, 0x35, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x34, 0x36, 0x33, - 0x32, 0x16, 0x06, 0x14, 0x16, 0x32, 0x36, 0x34, 0x26, 0x22, 0x58, 0x04, - 0x21, 0xfb, 0xdf, 0x04, 0x21, 0xfb, 0xdf, 0x04, 0x34, 0x40, 0x23, 0x1c, - 0x6d, 0x6d, 0x43, 0x3f, 0x3f, 0x3f, 0x44, 0xed, 0xfe, 0xd0, 0x04, 0x4a, - 0x42, 0x26, 0x47, 0x24, 0x24, 0x4b, 0x26, 0x61, 0x71, 0x6b, 0x5b, 0x51, - 0x5f, 0x42, 0x01, 0x3b, 0x31, 0x38, 0x42, 0x05, 0xc7, 0x43, 0x43, 0x15, - 0x3f, 0x2d, 0x49, 0x5c, 0x5c, 0x49, 0x2d, 0x3f, 0xcc, 0x3c, 0x69, 0x3c, - 0x3c, 0x69, 0x02, 0x0c, 0xac, 0x02, 0x42, 0xaa, 0x03, 0x24, 0x37, 0x1d, - 0x25, 0x24, 0x33, 0xfe, 0xa0, 0x01, 0x60, 0x33, 0x1c, 0x44, 0x3d, 0xfe, - 0xaa, 0x20, 0x44, 0x48, 0x13, 0x12, 0x3e, 0x0f, 0x10, 0x70, 0x60, 0x63, - 0x74, 0x69, 0x46, 0x36, 0x41, 0x3f, 0x39, 0x69, 0xda, 0xfd, 0xd0, 0x3d, - 0x24, 0x23, 0x74, 0xbe, 0x75, 0x23, 0x67, 0x93, 0x53, 0x53, 0x93, 0x53, - 0x00, 0x03, 0x00, 0x58, 0x01, 0x60, 0x04, 0x79, 0x06, 0x14, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x2a, 0x00, 0x00, 0x13, 0x21, 0x15, 0x21, 0x11, 0x21, - 0x15, 0x21, 0x01, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x15, 0x11, 0x23, 0x11, - 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, 0x11, 0x34, 0x26, 0x23, - 0x22, 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, 0x15, 0x3e, 0x01, 0x33, 0x32, - 0x16, 0x58, 0x04, 0x21, 0xfb, 0xdf, 0x04, 0x21, 0xfb, 0xdf, 0x02, 0x2e, - 0x22, 0x5d, 0x3f, 0x54, 0x5c, 0x59, 0x38, 0x38, 0x45, 0x51, 0x59, 0x37, - 0x3a, 0x44, 0x51, 0x59, 0x59, 0x1f, 0x55, 0x3b, 0x3b, 0x52, 0x02, 0x0c, - 0xac, 0x02, 0x42, 0xaa, 0x02, 0xa5, 0x3d, 0x3a, 0x78, 0x6f, 0xfe, 0xb5, - 0x01, 0x48, 0x4f, 0x4d, 0x5d, 0x51, 0xfe, 0xca, 0x01, 0x48, 0x50, 0x4c, - 0x5e, 0x50, 0xfe, 0xca, 0x02, 0x25, 0x55, 0x32, 0x30, 0x3d, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x58, 0x01, 0x60, 0x04, 0x79, 0x06, 0xda, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x0b, 0x00, 0x2c, 0x00, 0x00, 0x13, 0x21, 0x15, 0x21, - 0x11, 0x21, 0x15, 0x21, 0x01, 0x33, 0x15, 0x23, 0x37, 0x23, 0x35, 0x34, - 0x36, 0x3f, 0x01, 0x3e, 0x01, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, - 0x35, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x0f, 0x01, 0x0e, - 0x01, 0x07, 0x0e, 0x01, 0x15, 0x58, 0x04, 0x21, 0xfb, 0xdf, 0x04, 0x21, - 0xfb, 0xdf, 0x01, 0xc3, 0x66, 0x66, 0x63, 0x60, 0x1c, 0x2d, 0x2d, 0x1d, - 0x19, 0x41, 0x36, 0x28, 0x59, 0x31, 0x2f, 0x61, 0x33, 0x5c, 0x70, 0x24, - 0x2d, 0x2c, 0x18, 0x13, 0x04, 0x03, 0x03, 0x02, 0x0c, 0xac, 0x02, 0x42, - 0xaa, 0x01, 0x69, 0x7f, 0xc8, 0x4e, 0x32, 0x41, 0x2b, 0x2c, 0x1b, 0x2f, - 0x18, 0x2d, 0x37, 0x23, 0x21, 0x5e, 0x1c, 0x1c, 0x61, 0x4f, 0x26, 0x45, - 0x2b, 0x2b, 0x17, 0x1b, 0x0d, 0x0a, 0x1e, 0x1a, 0x00, 0x01, 0x00, 0x58, - 0x00, 0x25, 0x04, 0x79, 0x04, 0xdd, 0x00, 0x13, 0x00, 0x3c, 0x40, 0x20, - 0x0d, 0x0c, 0x0a, 0x03, 0x02, 0x04, 0x00, 0xa0, 0x06, 0x0c, 0x0e, 0x0a, - 0xa0, 0x12, 0x06, 0x10, 0x08, 0x14, 0x12, 0x0e, 0x0d, 0x0c, 0x08, 0x04, - 0x03, 0x02, 0x08, 0x09, 0x05, 0x0f, 0x00, 0x14, 0x10, 0xd4, 0x3c, 0xc4, - 0x32, 0x17, 0x39, 0x31, 0x00, 0x10, 0xd4, 0x3c, 0xc4, 0x32, 0xfc, 0x3c, - 0xc4, 0x10, 0xfe, 0x3c, 0xc4, 0x39, 0x11, 0x12, 0x39, 0x30, 0x13, 0x21, - 0x13, 0x17, 0x07, 0x33, 0x15, 0x21, 0x07, 0x21, 0x15, 0x21, 0x03, 0x27, - 0x37, 0x23, 0x35, 0x21, 0x37, 0x21, 0x58, 0x02, 0x87, 0xf6, 0x7d, 0xa4, - 0xcb, 0xfe, 0xb2, 0xb8, 0x02, 0x06, 0xfd, 0x79, 0xf8, 0x7d, 0xa4, 0xc9, - 0x01, 0x4a, 0xb8, 0xfd, 0xfe, 0x03, 0xa2, 0x01, 0x3b, 0x66, 0xd5, 0xaa, - 0xec, 0xac, 0xfe, 0xc5, 0x68, 0xd3, 0xac, 0xec, 0x00, 0x03, 0x00, 0x58, - 0x00, 0xc0, 0x04, 0x79, 0x04, 0x42, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, - 0x00, 0x00, 0x13, 0x21, 0x15, 0x21, 0x15, 0x21, 0x15, 0x21, 0x11, 0x21, - 0x15, 0x21, 0x58, 0x04, 0x21, 0xfb, 0xdf, 0x04, 0x21, 0xfb, 0xdf, 0x04, - 0x21, 0xfb, 0xdf, 0x02, 0xd8, 0xac, 0xc0, 0xac, 0x03, 0x82, 0xaa, 0x00, - 0x00, 0x01, 0x00, 0x58, 0x00, 0x0a, 0x04, 0x79, 0x04, 0xfa, 0x00, 0x1b, - 0x00, 0x00, 0x25, 0x23, 0x35, 0x21, 0x37, 0x21, 0x35, 0x21, 0x37, 0x21, - 0x35, 0x21, 0x37, 0x17, 0x07, 0x33, 0x15, 0x21, 0x07, 0x21, 0x15, 0x21, - 0x07, 0x21, 0x15, 0x21, 0x07, 0x27, 0x01, 0x47, 0xef, 0x01, 0x3d, 0x58, - 0xfe, 0x6b, 0x01, 0xe5, 0x58, 0xfd, 0xc3, 0x02, 0x8b, 0x55, 0x8d, 0x37, - 0xeb, 0xfe, 0xc8, 0x59, 0x01, 0x91, 0xfe, 0x20, 0x5a, 0x02, 0x3a, 0xfd, - 0x77, 0x53, 0x8d, 0xc0, 0xac, 0xc0, 0xac, 0xc0, 0xaa, 0xb8, 0x41, 0x77, - 0xaa, 0xc0, 0xac, 0xc0, 0xac, 0xb6, 0x40, 0x00, 0x00, 0x04, 0x00, 0x58, - 0x00, 0x00, 0x04, 0x79, 0x04, 0xee, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, - 0x00, 0x0f, 0x00, 0x00, 0x37, 0x21, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, - 0x15, 0x21, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x58, 0x04, 0x21, 0xfb, - 0xdf, 0x04, 0x21, 0xfb, 0xdf, 0x04, 0x21, 0xfb, 0xdf, 0x04, 0x21, 0xfb, - 0xdf, 0xac, 0xac, 0x03, 0x84, 0xac, 0xc0, 0xac, 0x03, 0x82, 0xaa, 0x00, - 0x00, 0x02, 0x00, 0x58, 0x00, 0x00, 0x04, 0x79, 0x04, 0x3f, 0x00, 0x06, - 0x00, 0x0a, 0x00, 0x28, 0x40, 0x16, 0x06, 0x05, 0x03, 0x02, 0x00, 0x05, - 0x01, 0xe5, 0x04, 0xe4, 0x07, 0xa0, 0x08, 0x06, 0x07, 0x04, 0x00, 0x28, - 0x09, 0x02, 0x27, 0x0b, 0x10, 0xfc, 0x3c, 0xec, 0x32, 0x32, 0x39, 0x31, - 0x00, 0x2f, 0xec, 0xf4, 0xec, 0x17, 0x39, 0x30, 0x01, 0x15, 0x01, 0x35, - 0x01, 0x15, 0x05, 0x01, 0x15, 0x21, 0x35, 0x04, 0x79, 0xfb, 0xdf, 0x04, - 0x21, 0xfc, 0xdf, 0x03, 0x21, 0xfb, 0xdf, 0x01, 0xb6, 0xb6, 0x01, 0x4c, - 0xa8, 0x01, 0x4b, 0xb8, 0xe7, 0xfe, 0x0a, 0xaa, 0xaa, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x58, 0x00, 0x00, 0x04, 0x79, 0x04, 0x3f, 0x00, 0x06, - 0x00, 0x0a, 0x00, 0x28, 0x40, 0x16, 0x05, 0x04, 0x02, 0x01, 0x00, 0x05, - 0x06, 0xe5, 0x03, 0xe4, 0x07, 0xa0, 0x09, 0x01, 0x08, 0x04, 0x28, 0x07, - 0x02, 0x00, 0x27, 0x0b, 0x10, 0xfc, 0x3c, 0x3c, 0xec, 0x32, 0x39, 0x31, - 0x00, 0x2f, 0xec, 0xf4, 0xec, 0x17, 0x39, 0x30, 0x13, 0x2d, 0x01, 0x35, - 0x01, 0x15, 0x01, 0x15, 0x21, 0x15, 0x21, 0x58, 0x03, 0x23, 0xfc, 0xdd, - 0x04, 0x21, 0xfb, 0xdf, 0x04, 0x21, 0xfb, 0xdf, 0x01, 0xb6, 0xea, 0xe7, - 0xb8, 0xfe, 0xb5, 0xa8, 0xfe, 0xb4, 0x56, 0xaa, 0x00, 0x03, 0x00, 0x56, - 0xff, 0x54, 0x04, 0x77, 0x04, 0x9f, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x0e, - 0x00, 0x00, 0x33, 0x21, 0x15, 0x21, 0x01, 0x15, 0x01, 0x35, 0x01, 0x15, - 0x05, 0x01, 0x15, 0x21, 0x35, 0x56, 0x04, 0x21, 0xfb, 0xdf, 0x04, 0x21, - 0xfb, 0xdf, 0x04, 0x21, 0xfc, 0xdf, 0x03, 0x21, 0xfb, 0xdf, 0xac, 0x02, - 0xc2, 0xb6, 0x01, 0x4c, 0xa8, 0x01, 0x4b, 0xb8, 0xe7, 0xfe, 0x0a, 0xaa, - 0xaa, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x56, 0xff, 0x54, 0x04, 0x77, - 0x04, 0x9f, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x0e, 0x00, 0x00, 0x33, 0x21, - 0x15, 0x21, 0x11, 0x2d, 0x01, 0x35, 0x01, 0x15, 0x01, 0x05, 0x15, 0x21, - 0x35, 0x56, 0x04, 0x21, 0xfb, 0xdf, 0x03, 0x21, 0xfc, 0xdf, 0x04, 0x21, - 0xfb, 0xdf, 0x04, 0x21, 0xfb, 0xdf, 0xac, 0x02, 0xc2, 0xea, 0xe7, 0xb8, - 0xfe, 0xb5, 0xa8, 0xfe, 0xb4, 0x56, 0xaa, 0xaa, 0x00, 0x02, 0x00, 0x56, - 0xfe, 0xb5, 0x04, 0x77, 0x04, 0x9f, 0x00, 0x13, 0x00, 0x1a, 0x00, 0x00, - 0x05, 0x23, 0x35, 0x21, 0x37, 0x21, 0x35, 0x21, 0x37, 0x17, 0x07, 0x33, - 0x15, 0x21, 0x07, 0x21, 0x15, 0x21, 0x07, 0x27, 0x01, 0x15, 0x01, 0x35, - 0x01, 0x15, 0x05, 0x01, 0x20, 0xca, 0x01, 0x70, 0x5b, 0xfe, 0x35, 0x02, - 0x6d, 0x9a, 0x7b, 0x2a, 0xc9, 0xfe, 0x95, 0x5b, 0x01, 0xc6, 0xfd, 0x94, - 0x99, 0x79, 0x03, 0x7e, 0xfb, 0xdf, 0x04, 0x21, 0xfc, 0xdf, 0xac, 0xac, - 0x60, 0xaa, 0xa1, 0x75, 0x2c, 0xaa, 0x60, 0xac, 0x9f, 0x76, 0x02, 0xeb, - 0xb6, 0x01, 0x4c, 0xa8, 0x01, 0x4b, 0xb8, 0xe7, 0x00, 0x02, 0x00, 0x56, - 0xfe, 0xb5, 0x04, 0x77, 0x04, 0x9f, 0x00, 0x13, 0x00, 0x1a, 0x00, 0x00, - 0x05, 0x23, 0x35, 0x21, 0x37, 0x21, 0x35, 0x21, 0x37, 0x17, 0x07, 0x33, - 0x15, 0x21, 0x07, 0x21, 0x15, 0x21, 0x07, 0x27, 0x03, 0x2d, 0x01, 0x35, - 0x01, 0x15, 0x01, 0x01, 0x20, 0xca, 0x01, 0x70, 0x5b, 0xfe, 0x35, 0x02, - 0x6d, 0x9a, 0x7b, 0x2a, 0xc9, 0xfe, 0x95, 0x5b, 0x01, 0xc6, 0xfd, 0x94, - 0x99, 0x79, 0xa3, 0x03, 0x21, 0xfc, 0xdf, 0x04, 0x21, 0xfb, 0xdf, 0xac, - 0xac, 0x60, 0xaa, 0xa1, 0x75, 0x2c, 0xaa, 0x60, 0xac, 0x9f, 0x76, 0x02, - 0xeb, 0xea, 0xe7, 0xb8, 0xfe, 0xb5, 0xa8, 0xfe, 0xb4, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x57, 0x00, 0x00, 0x04, 0x79, 0x05, 0x04, 0x00, 0x1b, - 0x00, 0x00, 0x01, 0x26, 0x25, 0x35, 0x04, 0x37, 0x13, 0x17, 0x03, 0x36, - 0x37, 0x15, 0x06, 0x0f, 0x01, 0x16, 0x05, 0x15, 0x24, 0x07, 0x03, 0x27, - 0x13, 0x06, 0x07, 0x35, 0x36, 0x37, 0x02, 0x34, 0xbd, 0xfe, 0xe0, 0x01, - 0x5b, 0xd8, 0xc2, 0x9a, 0x82, 0x7a, 0x9a, 0xd8, 0xa2, 0x62, 0xbe, 0x01, - 0x1f, 0xfe, 0xa5, 0xd8, 0xc1, 0x9a, 0x81, 0x7c, 0x98, 0xdb, 0xa0, 0x02, - 0xdb, 0x12, 0x88, 0xb2, 0xaa, 0x08, 0x01, 0x7f, 0x4d, 0xfe, 0xfe, 0x29, - 0x49, 0xb2, 0x67, 0x23, 0xc2, 0x12, 0x88, 0xb2, 0xaa, 0x08, 0xfe, 0x81, - 0x4d, 0x01, 0x02, 0x28, 0x4a, 0xb2, 0x68, 0x23, 0x00, 0x02, 0x00, 0x58, - 0xff, 0xe3, 0x04, 0x79, 0x05, 0x20, 0x00, 0x0f, 0x00, 0x12, 0x00, 0x00, - 0x01, 0x25, 0x35, 0x25, 0x13, 0x17, 0x07, 0x25, 0x15, 0x05, 0x03, 0x05, - 0x15, 0x25, 0x03, 0x27, 0x13, 0x05, 0x17, 0x01, 0xe1, 0xfe, 0x77, 0x02, - 0x32, 0x72, 0x99, 0x4b, 0x01, 0x2f, 0xfe, 0x92, 0x64, 0x01, 0xd2, 0xfd, - 0xfe, 0x74, 0x99, 0xe4, 0xfe, 0xd9, 0xe9, 0x01, 0x94, 0x9b, 0xa6, 0xde, - 0x01, 0x6d, 0x30, 0xf1, 0x78, 0xb6, 0x8a, 0xfe, 0xbb, 0xae, 0xb7, 0xcb, - 0xfe, 0x8b, 0x30, 0x02, 0xdd, 0x6f, 0x56, 0x00, 0x00, 0x02, 0x00, 0x58, - 0xff, 0xe3, 0x04, 0x79, 0x05, 0x20, 0x00, 0x0f, 0x00, 0x12, 0x00, 0x00, - 0x01, 0x05, 0x15, 0x05, 0x03, 0x27, 0x37, 0x05, 0x35, 0x25, 0x13, 0x25, - 0x35, 0x05, 0x13, 0x17, 0x03, 0x25, 0x27, 0x02, 0xf0, 0x01, 0x89, 0xfd, - 0xce, 0x72, 0x99, 0x4b, 0xfe, 0xd1, 0x01, 0x6e, 0x64, 0xfe, 0x2e, 0x02, - 0x02, 0x74, 0x99, 0xe4, 0x01, 0x27, 0xe9, 0x03, 0x6f, 0x9b, 0xa6, 0xde, - 0xfe, 0x93, 0x30, 0xf1, 0x78, 0xb6, 0x8a, 0x01, 0x45, 0xae, 0xb7, 0xcb, - 0x01, 0x75, 0x30, 0xfd, 0x23, 0x6f, 0x56, 0x00, 0x00, 0x02, 0x00, 0x58, - 0xff, 0x0d, 0x04, 0x79, 0x05, 0x08, 0x00, 0x02, 0x00, 0x1a, 0x00, 0x00, - 0x01, 0x05, 0x17, 0x03, 0x21, 0x35, 0x21, 0x13, 0x25, 0x35, 0x25, 0x13, - 0x17, 0x07, 0x25, 0x15, 0x05, 0x07, 0x05, 0x15, 0x25, 0x07, 0x21, 0x15, - 0x21, 0x07, 0x27, 0x02, 0x58, 0xff, 0x00, 0xd3, 0xc7, 0xfe, 0xf4, 0x01, - 0x43, 0x5f, 0xfe, 0x5e, 0x02, 0x3f, 0x73, 0xa1, 0x4d, 0x01, 0x1b, 0xfe, - 0xa4, 0x4e, 0x01, 0xaa, 0xfe, 0x23, 0x4e, 0x02, 0x2b, 0xfd, 0x9e, 0x50, - 0xa2, 0x02, 0xea, 0x4a, 0x3e, 0xfd, 0x9e, 0xaa, 0x01, 0x1f, 0x83, 0xa8, - 0xb4, 0x01, 0x60, 0x35, 0xed, 0x59, 0xb8, 0x64, 0xf1, 0x7c, 0xb6, 0x96, - 0xec, 0xaa, 0xf3, 0x35, 0x00, 0x02, 0x00, 0x58, 0xff, 0x0d, 0x04, 0x79, - 0x05, 0x08, 0x00, 0x17, 0x00, 0x1a, 0x00, 0x00, 0x01, 0x05, 0x15, 0x05, - 0x07, 0x21, 0x15, 0x21, 0x07, 0x27, 0x37, 0x23, 0x35, 0x33, 0x37, 0x05, - 0x35, 0x25, 0x37, 0x25, 0x35, 0x05, 0x13, 0x17, 0x03, 0x37, 0x27, 0x02, - 0xe0, 0x01, 0x99, 0xfd, 0xcb, 0x4e, 0x02, 0x83, 0xfd, 0x45, 0x4f, 0xa2, - 0x3e, 0xb3, 0xeb, 0x3a, 0xfe, 0xdb, 0x01, 0x66, 0x4c, 0xfe, 0x4e, 0x01, - 0xe6, 0x74, 0xa1, 0xd0, 0xf8, 0xce, 0x03, 0x74, 0x80, 0xa8, 0xb1, 0xf1, - 0xaa, 0xf3, 0x35, 0xbe, 0xaa, 0xb2, 0x5c, 0xb6, 0x68, 0xec, 0x7d, 0xb8, - 0x98, 0x01, 0x61, 0x35, 0xfd, 0x85, 0x48, 0x3c, 0x00, 0x02, 0x00, 0x56, - 0xff, 0xd4, 0x04, 0x77, 0x04, 0x3f, 0x00, 0x1c, 0x00, 0x23, 0x00, 0x00, - 0x25, 0x15, 0x0e, 0x01, 0x23, 0x22, 0x27, 0x26, 0x27, 0x2e, 0x01, 0x23, - 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, - 0x17, 0x16, 0x33, 0x32, 0x36, 0x13, 0x15, 0x01, 0x35, 0x01, 0x15, 0x05, - 0x04, 0x77, 0x4b, 0x8f, 0x4f, 0x5a, 0x71, 0x16, 0x0b, 0x4d, 0x67, 0x33, - 0x4f, 0x8d, 0x49, 0x4e, 0x92, 0x53, 0x35, 0x32, 0x27, 0x56, 0x0a, 0x16, - 0x74, 0x5d, 0x46, 0x89, 0x4a, 0xfb, 0xdf, 0x04, 0x21, 0xfc, 0xdf, 0xf5, - 0xaf, 0x3b, 0x37, 0x33, 0x0a, 0x04, 0x22, 0x18, 0x3b, 0x40, 0xae, 0x3c, - 0x37, 0x0b, 0x09, 0x22, 0x04, 0x0b, 0x36, 0x3c, 0x01, 0x00, 0xb6, 0x01, - 0x4c, 0xa8, 0x01, 0x4b, 0xb8, 0xe7, 0x00, 0x00, 0x00, 0x02, 0x00, 0x56, - 0xff, 0xd4, 0x04, 0x77, 0x04, 0x3f, 0x00, 0x21, 0x00, 0x28, 0x00, 0x00, - 0x25, 0x15, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, - 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x35, 0x36, 0x37, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x01, 0x2d, - 0x01, 0x35, 0x01, 0x15, 0x01, 0x04, 0x77, 0x4b, 0x48, 0x47, 0x4f, 0x5a, - 0x71, 0x16, 0x0b, 0x4d, 0x33, 0x34, 0x33, 0x4f, 0x46, 0x47, 0x49, 0x4e, - 0x49, 0x49, 0x53, 0x35, 0x32, 0x27, 0x56, 0x0a, 0x16, 0x74, 0x5d, 0x46, - 0x44, 0x45, 0xfc, 0x29, 0x03, 0x21, 0xfc, 0xdf, 0x04, 0x21, 0xfb, 0xdf, - 0xf5, 0xaf, 0x3b, 0x1b, 0x1c, 0x33, 0x0a, 0x04, 0x22, 0x0c, 0x0c, 0x1d, - 0x1e, 0x40, 0xae, 0x3c, 0x1c, 0x1b, 0x0b, 0x09, 0x22, 0x04, 0x0b, 0x36, - 0x1e, 0x1e, 0x01, 0x00, 0xea, 0xe7, 0xb8, 0xfe, 0xb5, 0xa8, 0xfe, 0xb4, - 0x00, 0x02, 0x00, 0x56, 0xff, 0x0d, 0x04, 0x77, 0x05, 0x08, 0x00, 0x2b, - 0x00, 0x2e, 0x00, 0x00, 0x25, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, - 0x32, 0x17, 0x37, 0x25, 0x35, 0x25, 0x13, 0x17, 0x07, 0x25, 0x15, 0x05, - 0x07, 0x05, 0x15, 0x25, 0x07, 0x16, 0x17, 0x16, 0x33, 0x32, 0x36, 0x37, - 0x15, 0x0e, 0x01, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x03, 0x27, - 0x01, 0x05, 0x17, 0x01, 0x7d, 0x51, 0x8d, 0x49, 0x4e, 0x92, 0x53, 0x15, - 0x15, 0x45, 0xfe, 0x5e, 0x02, 0x41, 0x73, 0xa1, 0x4d, 0x01, 0x19, 0xfe, - 0xa7, 0x50, 0x01, 0xa9, 0xfe, 0x23, 0x42, 0x18, 0x1d, 0x74, 0x5d, 0x46, - 0x89, 0x4a, 0x4b, 0x8f, 0x4f, 0x5a, 0x71, 0x16, 0x0b, 0x20, 0x1c, 0x5f, - 0xa2, 0x01, 0x34, 0xfe, 0xfd, 0xd5, 0x4f, 0x3b, 0x40, 0xae, 0x3c, 0x37, - 0x02, 0xd6, 0x83, 0xa8, 0xb5, 0x01, 0x5f, 0x35, 0xec, 0x58, 0xb8, 0x63, - 0xf2, 0x7c, 0xb6, 0x96, 0xcf, 0x08, 0x0f, 0x36, 0x3c, 0x3f, 0xaf, 0x3b, - 0x37, 0x33, 0x0a, 0x04, 0x0e, 0x0b, 0xfe, 0xdf, 0x35, 0x03, 0xa9, 0x4b, - 0x3e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x56, 0xff, 0x0d, 0x04, 0x77, - 0x05, 0x08, 0x00, 0x02, 0x00, 0x32, 0x00, 0x00, 0x01, 0x37, 0x27, 0x37, - 0x05, 0x15, 0x05, 0x07, 0x16, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, - 0x36, 0x37, 0x15, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, - 0x27, 0x03, 0x27, 0x13, 0x06, 0x07, 0x06, 0x07, 0x35, 0x36, 0x37, 0x36, - 0x3f, 0x01, 0x05, 0x35, 0x25, 0x37, 0x25, 0x35, 0x05, 0x13, 0x17, 0x02, - 0x83, 0xf4, 0xca, 0x33, 0x01, 0x97, 0xfd, 0xcd, 0x3b, 0x18, 0x4c, 0x0a, - 0x16, 0x74, 0x5d, 0x46, 0x44, 0x45, 0x4a, 0x47, 0x4c, 0x47, 0x4f, 0x5a, - 0x71, 0x16, 0x0b, 0x50, 0x3c, 0x67, 0xa2, 0x55, 0x1f, 0x1d, 0x47, 0x49, - 0x4e, 0x49, 0x35, 0x3a, 0x22, 0xfe, 0xd8, 0x01, 0x67, 0x4e, 0xfe, 0x4b, - 0x01, 0xe8, 0x74, 0xa1, 0x02, 0x59, 0x47, 0x3b, 0x98, 0x7f, 0xa8, 0xb1, - 0xb8, 0x05, 0x1f, 0x04, 0x0b, 0x36, 0x1e, 0x1e, 0x3f, 0xaf, 0x38, 0x1e, - 0x1c, 0x33, 0x0a, 0x04, 0x24, 0x0d, 0xfe, 0xc7, 0x35, 0x01, 0x03, 0x07, - 0x0c, 0x1e, 0x40, 0xae, 0x3c, 0x1c, 0x14, 0x05, 0x6a, 0x5d, 0xb6, 0x69, - 0xea, 0x7e, 0xb8, 0x99, 0x01, 0x62, 0x35, 0x00, 0x00, 0x02, 0x00, 0x56, - 0xff, 0x4a, 0x04, 0x77, 0x04, 0xd3, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x00, - 0x33, 0x2d, 0x01, 0x35, 0x01, 0x15, 0x09, 0x01, 0x15, 0x01, 0x35, 0x01, - 0x15, 0x05, 0x56, 0x03, 0x21, 0xfc, 0xdf, 0x04, 0x21, 0xfb, 0xdf, 0x04, - 0x21, 0xfb, 0xdf, 0x04, 0x21, 0xfc, 0xdf, 0xea, 0xe7, 0xb8, 0xfe, 0xb5, - 0xa8, 0xfe, 0xb4, 0x03, 0x00, 0xb6, 0x01, 0x4c, 0xa8, 0x01, 0x4b, 0xb8, - 0xe7, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x56, 0xff, 0x4a, 0x04, 0x77, - 0x04, 0xd3, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x00, 0x21, 0x15, 0x01, 0x35, - 0x01, 0x15, 0x05, 0x01, 0x2d, 0x01, 0x35, 0x01, 0x15, 0x01, 0x04, 0x77, - 0xfb, 0xdf, 0x04, 0x21, 0xfc, 0xdf, 0xff, 0x00, 0x03, 0x21, 0xfc, 0xdf, - 0x04, 0x21, 0xfb, 0xdf, 0xb6, 0x01, 0x4c, 0xa8, 0x01, 0x4b, 0xb8, 0xe7, - 0x01, 0x60, 0xea, 0xe7, 0xb8, 0xfe, 0xb5, 0xa8, 0xfe, 0xb4, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x56, 0xfe, 0x70, 0x04, 0x77, 0x05, 0xb1, 0x00, 0x02, - 0x00, 0x1e, 0x00, 0x21, 0x00, 0x00, 0x01, 0x05, 0x1f, 0x01, 0x05, 0x15, - 0x25, 0x07, 0x05, 0x15, 0x05, 0x03, 0x27, 0x37, 0x07, 0x35, 0x25, 0x13, - 0x25, 0x35, 0x05, 0x37, 0x25, 0x35, 0x25, 0x13, 0x17, 0x07, 0x37, 0x15, - 0x05, 0x03, 0x25, 0x27, 0x02, 0x84, 0xfe, 0xd2, 0xfc, 0xa3, 0x01, 0x82, - 0xfe, 0x4e, 0x19, 0x01, 0xcb, 0xfd, 0x9b, 0x6d, 0xa2, 0x4c, 0xf9, 0x01, - 0x34, 0x50, 0xfe, 0x7c, 0x01, 0xb5, 0x18, 0xfe, 0x33, 0x02, 0x68, 0x6e, - 0xa2, 0x4c, 0xf5, 0xfe, 0xce, 0xfa, 0x01, 0x2c, 0xfa, 0x03, 0x8b, 0x57, - 0x4a, 0x2f, 0x71, 0xb6, 0x88, 0x4e, 0x90, 0xa8, 0xc1, 0xfe, 0x9b, 0x30, - 0xf8, 0x4e, 0xb6, 0x5a, 0x01, 0x07, 0x70, 0xb8, 0x89, 0x4f, 0x91, 0xa8, - 0xc1, 0x01, 0x68, 0x32, 0xf9, 0x4d, 0xb8, 0x58, 0xfc, 0xcf, 0x58, 0x48, - 0x00, 0x03, 0x00, 0x56, 0xfe, 0x70, 0x04, 0x77, 0x05, 0xb1, 0x00, 0x1b, - 0x00, 0x1e, 0x00, 0x21, 0x00, 0x00, 0x01, 0x17, 0x03, 0x05, 0x15, 0x05, - 0x07, 0x25, 0x15, 0x05, 0x07, 0x05, 0x15, 0x25, 0x03, 0x27, 0x13, 0x25, - 0x35, 0x25, 0x37, 0x05, 0x35, 0x25, 0x37, 0x25, 0x35, 0x05, 0x01, 0x37, - 0x07, 0x01, 0x07, 0x37, 0x03, 0x2c, 0xa2, 0x7e, 0x01, 0x27, 0xfe, 0x62, - 0x1d, 0x01, 0xbb, 0xfe, 0x0a, 0x30, 0x02, 0x26, 0xfd, 0xaa, 0x7c, 0xa2, - 0x7d, 0xfe, 0xd6, 0x01, 0xa2, 0x1d, 0xfe, 0x41, 0x01, 0xf9, 0x30, 0xfd, - 0xd7, 0x02, 0x59, 0xfe, 0xff, 0x11, 0x69, 0x01, 0xcc, 0x11, 0x66, 0x05, - 0xb1, 0x32, 0xfe, 0x65, 0x5c, 0xa8, 0x82, 0x60, 0x8b, 0xb8, 0x91, 0x9f, - 0xa1, 0xb6, 0xbc, 0xfe, 0x6a, 0x30, 0x01, 0x98, 0x5e, 0xa8, 0x83, 0x5f, - 0x8c, 0xb6, 0x93, 0x9e, 0xa0, 0xb8, 0xbc, 0xfc, 0xb9, 0x38, 0x1e, 0x02, - 0x63, 0x37, 0x1e, 0x00, 0x00, 0x01, 0x00, 0x56, 0xff, 0xd3, 0x04, 0x77, - 0x05, 0x2f, 0x00, 0x0a, 0x00, 0x00, 0x01, 0x00, 0x05, 0x04, 0x01, 0x15, - 0x00, 0x25, 0x35, 0x24, 0x01, 0x04, 0x77, 0xfe, 0xb9, 0xfe, 0x5c, 0x01, - 0xac, 0x01, 0x3f, 0xfe, 0xb9, 0xfd, 0x26, 0x02, 0xde, 0x01, 0x43, 0x04, - 0x40, 0xfe, 0x98, 0x57, 0x61, 0xfe, 0xa2, 0xef, 0x01, 0xc5, 0x96, 0xa6, - 0x94, 0x01, 0xc7, 0x00, 0x00, 0x01, 0x00, 0x58, 0xff, 0xd3, 0x04, 0x79, - 0x05, 0x2f, 0x00, 0x0a, 0x00, 0x00, 0x13, 0x35, 0x00, 0x05, 0x15, 0x04, - 0x01, 0x35, 0x00, 0x25, 0x24, 0x58, 0x01, 0x43, 0x02, 0xde, 0xfd, 0x26, - 0xfe, 0xb9, 0x01, 0x3f, 0x01, 0xac, 0xfe, 0x5c, 0x04, 0x40, 0xef, 0xfe, - 0x39, 0x94, 0xa6, 0x96, 0xfe, 0x3b, 0xef, 0x01, 0x5e, 0x61, 0x57, 0x00, - 0x00, 0x02, 0x00, 0x56, 0xff, 0x04, 0x04, 0x77, 0x05, 0xb1, 0x00, 0x09, - 0x00, 0x18, 0x00, 0x00, 0x25, 0x26, 0x25, 0x35, 0x04, 0x17, 0x04, 0x17, - 0x15, 0x26, 0x13, 0x00, 0x05, 0x04, 0x01, 0x15, 0x26, 0x25, 0x26, 0x25, - 0x35, 0x24, 0x37, 0x24, 0x37, 0x02, 0xa4, 0xe0, 0xfe, 0x92, 0x01, 0x70, - 0xde, 0x01, 0x08, 0xcb, 0xb1, 0xb1, 0xfe, 0xdd, 0xfe, 0x6c, 0x01, 0x94, - 0x01, 0x23, 0xb7, 0xfe, 0xe4, 0xf7, 0xfe, 0xa9, 0x01, 0x61, 0xed, 0x01, - 0x1c, 0xb7, 0x9b, 0x9a, 0x36, 0xc8, 0x38, 0x83, 0x9c, 0xdc, 0xfc, 0xcf, - 0x04, 0xef, 0xfe, 0xd0, 0x4f, 0x5d, 0xfe, 0xde, 0xef, 0xc9, 0x97, 0x82, - 0x39, 0xa6, 0x3d, 0x7d, 0x96, 0xcb, 0x00, 0x00, 0x00, 0x02, 0x00, 0x56, - 0xff, 0x04, 0x04, 0x77, 0x05, 0xb1, 0x00, 0x09, 0x00, 0x18, 0x00, 0x00, - 0x25, 0x04, 0x07, 0x35, 0x36, 0x25, 0x36, 0x25, 0x15, 0x04, 0x01, 0x35, - 0x16, 0x05, 0x16, 0x05, 0x15, 0x04, 0x07, 0x04, 0x07, 0x35, 0x00, 0x25, - 0x24, 0x02, 0x29, 0xfe, 0xde, 0xb1, 0xcb, 0x01, 0x08, 0xde, 0x01, 0x70, - 0xfe, 0x92, 0xfd, 0x4d, 0xb7, 0x01, 0x1c, 0xed, 0x01, 0x61, 0xfe, 0xa9, - 0xf7, 0xfe, 0xe4, 0xb7, 0x01, 0x23, 0x01, 0x94, 0xfe, 0x6c, 0x9b, 0xc8, - 0xcf, 0xfc, 0xdc, 0x9c, 0x83, 0x38, 0xc8, 0x36, 0x03, 0x8d, 0xef, 0xcb, - 0x96, 0x7d, 0x3d, 0xa6, 0x39, 0x82, 0x97, 0xc9, 0xef, 0x01, 0x22, 0x5d, - 0x4f, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x56, 0xff, 0x8e, 0x04, 0x77, - 0x05, 0xb1, 0x00, 0x1b, 0x00, 0x2a, 0x00, 0x00, 0x25, 0x15, 0x0e, 0x01, - 0x23, 0x22, 0x27, 0x26, 0x27, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x35, - 0x3e, 0x01, 0x33, 0x32, 0x16, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x36, - 0x13, 0x00, 0x05, 0x04, 0x01, 0x15, 0x26, 0x25, 0x26, 0x25, 0x35, 0x24, - 0x37, 0x24, 0x37, 0x04, 0x77, 0x4b, 0x8f, 0x4f, 0x5a, 0x71, 0x16, 0x0b, - 0x4d, 0x67, 0x33, 0x4f, 0x8d, 0x49, 0x4e, 0x92, 0x53, 0x35, 0x64, 0x4b, - 0x0a, 0x16, 0x74, 0x5d, 0x46, 0x89, 0x4a, 0xfe, 0xdd, 0xfe, 0x6c, 0x01, - 0x94, 0x01, 0x23, 0xb7, 0xfe, 0xe4, 0xf7, 0xfe, 0xa9, 0x01, 0x61, 0xed, - 0x01, 0x1c, 0xb7, 0xaf, 0xaf, 0x3b, 0x37, 0x33, 0x0a, 0x04, 0x22, 0x18, - 0x3b, 0x40, 0xae, 0x3c, 0x37, 0x16, 0x20, 0x04, 0x0b, 0x36, 0x3c, 0x04, - 0x52, 0xfe, 0xd0, 0x4f, 0x5d, 0xfe, 0xde, 0xef, 0xc9, 0x97, 0x82, 0x39, - 0xa6, 0x3d, 0x7d, 0x96, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x56, - 0xff, 0x8e, 0x04, 0x77, 0x05, 0xb1, 0x00, 0x1b, 0x00, 0x2a, 0x00, 0x00, - 0x25, 0x15, 0x0e, 0x01, 0x23, 0x22, 0x27, 0x26, 0x27, 0x2e, 0x01, 0x23, - 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x17, 0x16, 0x17, - 0x16, 0x33, 0x32, 0x36, 0x01, 0x35, 0x16, 0x05, 0x16, 0x05, 0x15, 0x04, - 0x07, 0x04, 0x07, 0x35, 0x00, 0x25, 0x24, 0x04, 0x77, 0x4b, 0x8f, 0x4f, - 0x5a, 0x71, 0x16, 0x0b, 0x4d, 0x67, 0x33, 0x4f, 0x8d, 0x49, 0x4e, 0x92, - 0x53, 0x35, 0x64, 0x4b, 0x0a, 0x16, 0x74, 0x5d, 0x46, 0x89, 0xfc, 0x29, - 0xb7, 0x01, 0x1c, 0xed, 0x01, 0x61, 0xfe, 0xa9, 0xf7, 0xfe, 0xe7, 0xba, - 0x01, 0x23, 0x01, 0x94, 0xfe, 0x6c, 0xaf, 0xaf, 0x3b, 0x37, 0x33, 0x0a, - 0x04, 0x22, 0x18, 0x3b, 0x40, 0xae, 0x3c, 0x37, 0x16, 0x20, 0x04, 0x0b, - 0x36, 0x3c, 0x04, 0x52, 0xef, 0xcb, 0x96, 0x7d, 0x3d, 0xa6, 0x39, 0x82, - 0x94, 0xcc, 0xef, 0x01, 0x22, 0x5d, 0x4f, 0x00, 0x00, 0x02, 0x00, 0x56, - 0xff, 0x5b, 0x04, 0x77, 0x05, 0xa7, 0x00, 0x15, 0x00, 0x1a, 0x00, 0x00, - 0x01, 0x17, 0x03, 0x36, 0x37, 0x15, 0x06, 0x07, 0x03, 0x16, 0x17, 0x15, - 0x26, 0x25, 0x03, 0x27, 0x13, 0x26, 0x27, 0x35, 0x24, 0x37, 0x03, 0x37, - 0x06, 0x07, 0x16, 0x03, 0x34, 0xa3, 0x68, 0x9b, 0x6d, 0xa0, 0xb5, 0x55, - 0xe9, 0xc1, 0xb2, 0xfe, 0xd6, 0xa0, 0xa2, 0xa6, 0xc0, 0xe9, 0x01, 0x47, - 0xf6, 0x63, 0x20, 0x5f, 0x65, 0x54, 0x05, 0xa7, 0x32, 0xfe, 0xaa, 0x77, - 0x99, 0xef, 0xb0, 0x6e, 0xfe, 0xeb, 0x77, 0xd4, 0xef, 0xf7, 0x9d, 0xfd, - 0xf4, 0x32, 0x02, 0x22, 0x4f, 0x30, 0xa6, 0x42, 0x7f, 0xfe, 0xbc, 0x6a, - 0x25, 0x15, 0x13, 0x00, 0x00, 0x02, 0x00, 0x56, 0xff, 0x5b, 0x04, 0x77, - 0x05, 0xa7, 0x00, 0x15, 0x00, 0x1a, 0x00, 0x00, 0x05, 0x27, 0x13, 0x06, - 0x07, 0x35, 0x36, 0x37, 0x13, 0x26, 0x27, 0x35, 0x16, 0x05, 0x13, 0x17, - 0x03, 0x16, 0x17, 0x15, 0x04, 0x07, 0x13, 0x07, 0x36, 0x37, 0x26, 0x01, - 0x99, 0xa3, 0x68, 0x9b, 0x6d, 0xa0, 0xb5, 0x55, 0xe9, 0xc1, 0xb2, 0x01, - 0x2a, 0xa0, 0xa2, 0xa6, 0xc0, 0xe9, 0xfe, 0xb9, 0xf6, 0x63, 0x20, 0x5f, - 0x65, 0x54, 0xa5, 0x32, 0x01, 0x56, 0x77, 0x99, 0xef, 0xb0, 0x6e, 0x01, - 0x15, 0x77, 0xd4, 0xef, 0xf7, 0x9d, 0x02, 0x0c, 0x32, 0xfd, 0xde, 0x4f, - 0x30, 0xa6, 0x42, 0x7f, 0x01, 0x44, 0x6a, 0x25, 0x15, 0x13, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x58, 0x00, 0xa3, 0x04, 0x79, 0x04, 0x5f, 0x00, 0x14, - 0x00, 0x00, 0x25, 0x21, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x33, - 0x21, 0x15, 0x21, 0x22, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x21, 0x04, - 0x79, 0xfd, 0xbd, 0xc9, 0x8a, 0x8b, 0x8b, 0x8a, 0xc8, 0x02, 0x44, 0xfd, - 0xbc, 0x89, 0xbe, 0x5f, 0x60, 0x88, 0x02, 0x44, 0xa3, 0x8b, 0x8b, 0xc8, - 0xc6, 0x8d, 0x8b, 0x96, 0xc0, 0x88, 0x8a, 0x5e, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x58, 0x00, 0xa3, 0x04, 0x79, 0x04, 0x5f, 0x00, 0x14, - 0x00, 0x00, 0x37, 0x35, 0x21, 0x32, 0x37, 0x36, 0x35, 0x34, 0x26, 0x23, - 0x21, 0x35, 0x21, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x58, - 0x02, 0x44, 0x88, 0x60, 0x5f, 0xbe, 0x89, 0xfd, 0xbc, 0x02, 0x44, 0xc8, - 0x8a, 0x8b, 0x8b, 0x8a, 0xc9, 0xa3, 0x96, 0x60, 0x5e, 0x8a, 0x88, 0xc0, - 0x96, 0x8b, 0x8d, 0xc6, 0xc8, 0x8b, 0x8b, 0x00, 0x00, 0x02, 0x00, 0x58, - 0xff, 0xc4, 0x04, 0x79, 0x05, 0x3e, 0x00, 0x08, 0x00, 0x20, 0x00, 0x00, - 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x07, 0x26, 0x27, - 0x26, 0x35, 0x34, 0x37, 0x36, 0x3b, 0x01, 0x37, 0x17, 0x07, 0x21, 0x15, - 0x21, 0x03, 0x21, 0x15, 0x21, 0x22, 0x23, 0x07, 0x27, 0x02, 0x7f, 0x4a, - 0x89, 0xbe, 0x5f, 0x2b, 0x33, 0x30, 0x54, 0x44, 0x8b, 0x8b, 0x8a, 0xc8, - 0x7e, 0x4b, 0xa1, 0x39, 0x01, 0x13, 0xfe, 0xba, 0xdd, 0x02, 0x23, 0xfd, - 0xbd, 0x0a, 0x0a, 0x4b, 0xa2, 0x03, 0xc9, 0xc0, 0x88, 0x8a, 0x5e, 0x2b, - 0x18, 0x90, 0x23, 0x45, 0x8b, 0xc8, 0xc6, 0x8d, 0x8b, 0xdf, 0x35, 0xaa, - 0x96, 0xfd, 0x70, 0x96, 0xdf, 0x35, 0x00, 0x00, 0x00, 0x02, 0x00, 0x58, - 0xff, 0xc4, 0x04, 0x79, 0x05, 0x3e, 0x00, 0x08, 0x00, 0x20, 0x00, 0x00, - 0x01, 0x33, 0x32, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x37, 0x16, 0x17, - 0x16, 0x15, 0x14, 0x07, 0x06, 0x2b, 0x01, 0x07, 0x27, 0x37, 0x21, 0x35, - 0x21, 0x13, 0x21, 0x35, 0x21, 0x32, 0x33, 0x37, 0x17, 0x02, 0x52, 0x4a, - 0x89, 0xbe, 0x5f, 0x2b, 0x33, 0x30, 0x54, 0x44, 0x8b, 0x8b, 0x8a, 0xc8, - 0x7e, 0x4b, 0xa1, 0x39, 0xfe, 0xed, 0x01, 0x46, 0xdd, 0xfd, 0xdd, 0x02, - 0x43, 0x0a, 0x0a, 0x4b, 0xa2, 0x01, 0x39, 0xc0, 0x88, 0x8a, 0x5e, 0x2b, - 0x18, 0x90, 0x23, 0x45, 0x8b, 0xc8, 0xc6, 0x8d, 0x8b, 0xdf, 0x35, 0xaa, - 0x96, 0x02, 0x90, 0x96, 0xdf, 0x35, 0x00, 0x00, 0x00, 0x02, 0x00, 0x58, - 0x00, 0x00, 0x04, 0x79, 0x05, 0x00, 0x00, 0x03, 0x00, 0x18, 0x00, 0x00, - 0x25, 0x15, 0x21, 0x35, 0x25, 0x21, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, - 0x36, 0x33, 0x21, 0x15, 0x21, 0x22, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, - 0x21, 0x04, 0x79, 0xfb, 0xdf, 0x04, 0x21, 0xfd, 0xbd, 0xc9, 0x8a, 0x8b, - 0x8b, 0x8a, 0xc8, 0x02, 0x44, 0xfd, 0xbc, 0x89, 0xbe, 0x5f, 0x60, 0x88, - 0x02, 0x44, 0xaa, 0xaa, 0xaa, 0x9a, 0x8b, 0x8b, 0xc8, 0xc6, 0x8d, 0x8b, - 0x96, 0xc0, 0x88, 0x8a, 0x5e, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x58, - 0x00, 0x00, 0x04, 0x79, 0x05, 0x00, 0x00, 0x03, 0x00, 0x18, 0x00, 0x00, - 0x25, 0x15, 0x21, 0x3d, 0x02, 0x21, 0x32, 0x37, 0x36, 0x35, 0x34, 0x26, - 0x23, 0x21, 0x35, 0x21, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, - 0x04, 0x79, 0xfb, 0xdf, 0x02, 0x44, 0x88, 0x60, 0x5f, 0xbe, 0x89, 0xfd, - 0xbc, 0x02, 0x44, 0xc8, 0x8a, 0x8b, 0x8b, 0x8a, 0xc9, 0xaa, 0xaa, 0xaa, - 0x9a, 0x96, 0x60, 0x5e, 0x8a, 0x88, 0xc0, 0x96, 0x8b, 0x8d, 0xc6, 0xc8, - 0x8b, 0x8b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x58, 0xff, 0x2c, 0x04, 0x79, - 0x05, 0xd6, 0x00, 0x1d, 0x00, 0x26, 0x00, 0x00, 0x25, 0x21, 0x15, 0x21, - 0x07, 0x27, 0x37, 0x23, 0x35, 0x21, 0x37, 0x26, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x36, 0x3b, 0x01, 0x37, 0x17, 0x07, 0x33, 0x15, 0x21, 0x03, 0x21, - 0x15, 0x21, 0x13, 0x23, 0x22, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x02, - 0x24, 0x02, 0x55, 0xfd, 0x72, 0x47, 0x9f, 0x36, 0xe3, 0x01, 0x1b, 0x3a, - 0x71, 0x59, 0x8b, 0x8b, 0x8a, 0xc8, 0xb2, 0x47, 0x9e, 0x35, 0xe2, 0xfe, - 0xec, 0xdc, 0x01, 0xf0, 0xfd, 0xdd, 0x5e, 0x7f, 0x89, 0xbe, 0x5f, 0x3d, - 0x52, 0xaa, 0xaa, 0xd4, 0x35, 0x9f, 0xaa, 0xac, 0x20, 0x59, 0x8b, 0xc8, - 0xc6, 0x8d, 0x8b, 0xd6, 0x35, 0xa1, 0x96, 0xfd, 0x70, 0x96, 0x03, 0x26, - 0xc0, 0x88, 0x88, 0x60, 0x3d, 0x17, 0x00, 0x00, 0x00, 0x02, 0x00, 0x58, - 0xff, 0x2c, 0x04, 0x79, 0x05, 0xd6, 0x00, 0x21, 0x00, 0x2b, 0x00, 0x00, - 0x01, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x2b, 0x01, 0x07, 0x21, - 0x15, 0x21, 0x07, 0x27, 0x37, 0x23, 0x35, 0x21, 0x37, 0x21, 0x35, 0x21, - 0x13, 0x26, 0x23, 0x21, 0x35, 0x21, 0x32, 0x17, 0x37, 0x17, 0x01, 0x33, - 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x03, 0x83, 0x39, 0x32, - 0x8b, 0x8b, 0x8a, 0xc9, 0x44, 0x34, 0x02, 0x56, 0xfd, 0x71, 0x46, 0x9f, - 0x35, 0xe2, 0x01, 0x1b, 0x33, 0xfe, 0xb2, 0x01, 0x81, 0xdb, 0x0c, 0x0c, - 0xfd, 0xbc, 0x02, 0x44, 0x26, 0x23, 0x49, 0x9e, 0xfe, 0xbc, 0x14, 0x88, - 0x60, 0x5f, 0x5f, 0x18, 0x1a, 0x04, 0xc7, 0x20, 0x32, 0x8d, 0xc6, 0xc8, - 0x8b, 0x8b, 0x9a, 0xaa, 0xd4, 0x35, 0x9f, 0xaa, 0x9a, 0x96, 0x02, 0x8f, - 0x01, 0x96, 0x05, 0xdb, 0x35, 0xfc, 0x39, 0x60, 0x5e, 0x8a, 0x88, 0x60, - 0x18, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x58, 0xff, 0x30, 0x04, 0x79, - 0x05, 0x00, 0x00, 0x21, 0x00, 0x00, 0x25, 0x15, 0x21, 0x07, 0x27, 0x37, - 0x21, 0x35, 0x21, 0x37, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, - 0x33, 0x21, 0x15, 0x21, 0x22, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x21, - 0x15, 0x21, 0x17, 0x07, 0x04, 0x79, 0xfe, 0x18, 0xa7, 0x84, 0x52, 0xfe, - 0xa0, 0x01, 0xe8, 0x7c, 0x86, 0xc9, 0x8a, 0x8b, 0x8b, 0x8a, 0xc8, 0x02, - 0x44, 0xfd, 0xbc, 0x89, 0xbe, 0x5f, 0x61, 0x87, 0x02, 0x44, 0xfe, 0xb1, - 0x41, 0x51, 0xaa, 0xaa, 0xd0, 0x6a, 0x66, 0xaa, 0x9a, 0x8b, 0x8c, 0xc7, - 0xc6, 0x8d, 0x8b, 0x96, 0xc0, 0x88, 0x8a, 0x5e, 0x60, 0x96, 0x35, 0x65, - 0x00, 0x01, 0x00, 0x58, 0xff, 0x30, 0x04, 0x79, 0x05, 0x00, 0x00, 0x22, - 0x00, 0x00, 0x25, 0x15, 0x21, 0x07, 0x27, 0x37, 0x21, 0x35, 0x21, 0x37, - 0x06, 0x23, 0x21, 0x35, 0x21, 0x32, 0x37, 0x36, 0x35, 0x34, 0x26, 0x23, - 0x21, 0x35, 0x21, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x17, - 0x07, 0x04, 0x79, 0xfe, 0x18, 0xa7, 0x84, 0x52, 0xfe, 0xa0, 0x01, 0xe8, - 0x7c, 0x10, 0x11, 0xfd, 0xbd, 0x02, 0x44, 0x87, 0x61, 0x5f, 0xbe, 0x89, - 0xfd, 0xbc, 0x02, 0x44, 0xc8, 0x8a, 0x8b, 0x8b, 0x5d, 0x7a, 0x54, 0x51, - 0xaa, 0xaa, 0xd0, 0x6a, 0x66, 0xaa, 0x9b, 0x01, 0x96, 0x60, 0x5e, 0x8a, - 0x88, 0xc0, 0x96, 0x8b, 0x8d, 0xc6, 0xc7, 0x8c, 0x5e, 0x1e, 0x44, 0x65, - 0x00, 0x01, 0x00, 0x58, 0x00, 0x77, 0x04, 0x79, 0x04, 0x8b, 0x00, 0x07, - 0x00, 0x31, 0x00, 0xb0, 0x06, 0x2f, 0xb0, 0x07, 0x33, 0xb1, 0x04, 0x04, - 0xed, 0xb1, 0x05, 0x04, 0xed, 0xb0, 0x02, 0xb0, 0x04, 0x10, 0xde, 0xb0, - 0x03, 0x32, 0xb1, 0x00, 0x04, 0xed, 0xb1, 0x01, 0x04, 0xed, 0x01, 0xb0, - 0x00, 0x2f, 0xb0, 0x07, 0x33, 0xb1, 0x03, 0x04, 0xed, 0xb1, 0x04, 0x04, - 0xed, 0x30, 0x31, 0x13, 0x21, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x58, - 0x04, 0x21, 0xfc, 0x89, 0x03, 0x77, 0xfb, 0xdf, 0x04, 0x8b, 0xaa, 0xfd, - 0x40, 0xaa, 0x00, 0x00, 0x00, 0x01, 0x00, 0x58, 0x00, 0x77, 0x04, 0x79, - 0x04, 0x8b, 0x00, 0x07, 0x00, 0x31, 0x00, 0xb0, 0x01, 0x2f, 0xb0, 0x02, - 0x33, 0xb1, 0x03, 0x04, 0xed, 0xb1, 0x04, 0x04, 0xed, 0xb0, 0x05, 0xb0, - 0x03, 0x10, 0xde, 0xb0, 0x06, 0x32, 0xb1, 0x00, 0x04, 0xed, 0xb1, 0x07, - 0x04, 0xed, 0x01, 0xb0, 0x04, 0x2f, 0xb0, 0x05, 0x33, 0xb1, 0x00, 0x04, - 0xed, 0xb1, 0x01, 0x04, 0xed, 0x30, 0x31, 0x01, 0x11, 0x21, 0x35, 0x21, - 0x11, 0x21, 0x35, 0x04, 0x79, 0xfb, 0xdf, 0x03, 0x77, 0xfc, 0x89, 0x04, - 0x8b, 0xfb, 0xec, 0xaa, 0x02, 0xc0, 0xaa, 0x00, 0x00, 0x02, 0x00, 0x58, - 0x00, 0x0e, 0x04, 0x79, 0x04, 0xf4, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x48, - 0x00, 0xb0, 0x02, 0x2f, 0xb0, 0x03, 0x33, 0xb1, 0x00, 0x04, 0xed, 0xb1, - 0x01, 0x04, 0xed, 0xb0, 0x0a, 0xb0, 0x00, 0x10, 0xde, 0xb0, 0x0b, 0x32, - 0xb1, 0x08, 0x04, 0xed, 0xb1, 0x09, 0x04, 0xed, 0xb0, 0x06, 0xb0, 0x08, - 0x10, 0xde, 0xb0, 0x07, 0x32, 0xb1, 0x04, 0x04, 0xed, 0xb1, 0x05, 0x04, - 0xed, 0x01, 0xb0, 0x00, 0x2f, 0xb0, 0x03, 0x33, 0xb0, 0x04, 0x33, 0xb0, - 0x0b, 0x33, 0xb1, 0x07, 0x04, 0xed, 0xb1, 0x08, 0x04, 0xed, 0x30, 0x31, - 0x37, 0x21, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, - 0x58, 0x04, 0x21, 0xfb, 0xdf, 0x04, 0x21, 0xfc, 0x89, 0x03, 0x77, 0xfb, - 0xdf, 0xb8, 0xaa, 0x04, 0xe6, 0xaa, 0xfd, 0x98, 0xaa, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x58, 0x00, 0x0e, 0x04, 0x79, 0x04, 0xf4, 0x00, 0x03, - 0x00, 0x0b, 0x00, 0x4a, 0x00, 0xb0, 0x01, 0x2f, 0xb0, 0x02, 0x33, 0xb1, - 0x00, 0x04, 0xed, 0xb1, 0x03, 0x04, 0xed, 0xb0, 0x05, 0xb0, 0x00, 0x10, - 0xde, 0xb0, 0x06, 0x32, 0xb1, 0x07, 0x04, 0xed, 0xb1, 0x08, 0x04, 0xed, - 0xb0, 0x09, 0xb0, 0x07, 0x10, 0xde, 0xb0, 0x0a, 0x32, 0xb1, 0x04, 0x04, - 0xed, 0xb1, 0x0b, 0x04, 0xed, 0x01, 0xb0, 0x08, 0x2f, 0xb0, 0x09, 0x33, - 0xb1, 0x00, 0x04, 0xed, 0xb1, 0x01, 0x04, 0xed, 0xb1, 0x04, 0x04, 0xed, - 0xb1, 0x05, 0x04, 0xed, 0x30, 0x31, 0x25, 0x15, 0x21, 0x35, 0x01, 0x11, - 0x21, 0x35, 0x21, 0x11, 0x21, 0x35, 0x04, 0x79, 0xfb, 0xdf, 0x04, 0x21, - 0xfb, 0xdf, 0x03, 0x77, 0xfc, 0x89, 0xb8, 0xaa, 0xaa, 0x04, 0x3c, 0xfc, - 0x44, 0xaa, 0x02, 0x68, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x4f, - 0x00, 0x69, 0x04, 0x82, 0x04, 0x9e, 0x00, 0x19, 0x00, 0x33, 0x00, 0x3f, - 0x00, 0x00, 0x00, 0x32, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, - 0x06, 0x07, 0x0e, 0x01, 0x22, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x36, 0x37, 0x36, 0x04, 0x22, 0x07, 0x06, 0x07, 0x0e, 0x01, 0x15, - 0x14, 0x16, 0x17, 0x16, 0x17, 0x16, 0x32, 0x37, 0x36, 0x37, 0x3e, 0x01, - 0x35, 0x34, 0x26, 0x27, 0x26, 0x27, 0x07, 0x33, 0x11, 0x21, 0x15, 0x21, - 0x11, 0x23, 0x11, 0x21, 0x35, 0x21, 0x01, 0xfa, 0xdd, 0xbe, 0x4f, 0x4f, - 0x27, 0x27, 0x27, 0x27, 0x4f, 0x4f, 0xbe, 0xdd, 0xbe, 0x4f, 0x4f, 0x27, - 0x27, 0x27, 0x27, 0x4f, 0x4f, 0x01, 0x7e, 0xa3, 0x47, 0x45, 0x3a, 0x3b, - 0x39, 0x39, 0x3b, 0x3a, 0x45, 0x47, 0xa3, 0x46, 0x46, 0x3a, 0x3b, 0x39, - 0x39, 0x3b, 0x3a, 0x46, 0xde, 0x8c, 0x01, 0x14, 0xfe, 0xec, 0x8c, 0xfe, - 0xed, 0x01, 0x13, 0x04, 0x9e, 0x50, 0x4f, 0x4f, 0x5f, 0x5f, 0x70, 0x6d, - 0x5f, 0x5f, 0x4f, 0x4e, 0x50, 0x50, 0x4e, 0x4f, 0x5f, 0x5f, 0x6d, 0x70, - 0x5f, 0x5f, 0x4f, 0x4f, 0x3d, 0x1e, 0x1e, 0x39, 0x3b, 0x8c, 0x53, 0x50, - 0x8c, 0x3b, 0x39, 0x1e, 0x1e, 0x1e, 0x1e, 0x39, 0x3b, 0x8c, 0x50, 0x53, - 0x8c, 0x3b, 0x39, 0x1e, 0x16, 0xfe, 0xeb, 0x8c, 0xfe, 0xee, 0x01, 0x12, - 0x8c, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x4f, 0x00, 0x69, 0x04, 0x82, - 0x04, 0x9e, 0x00, 0x19, 0x00, 0x33, 0x00, 0x37, 0x00, 0x00, 0x00, 0x32, - 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x0e, 0x01, - 0x22, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, - 0x04, 0x22, 0x07, 0x06, 0x07, 0x0e, 0x01, 0x15, 0x14, 0x16, 0x17, 0x16, - 0x17, 0x16, 0x32, 0x37, 0x36, 0x37, 0x3e, 0x01, 0x35, 0x34, 0x26, 0x27, - 0x26, 0x27, 0x13, 0x15, 0x21, 0x35, 0x01, 0xfa, 0xdd, 0xbe, 0x4f, 0x4f, - 0x27, 0x27, 0x27, 0x27, 0x4f, 0x4f, 0xbe, 0xdd, 0xbe, 0x4f, 0x4f, 0x27, - 0x27, 0x27, 0x27, 0x4f, 0x4f, 0x01, 0x7e, 0xa3, 0x47, 0x45, 0x3a, 0x3b, - 0x39, 0x39, 0x3b, 0x3a, 0x45, 0x47, 0xa3, 0x46, 0x46, 0x3a, 0x3b, 0x39, - 0x39, 0x3b, 0x3a, 0x46, 0xc2, 0xfd, 0x4d, 0x04, 0x9e, 0x50, 0x4f, 0x4f, - 0x5f, 0x5f, 0x70, 0x6d, 0x5f, 0x5f, 0x4f, 0x4e, 0x50, 0x50, 0x4e, 0x4f, - 0x5f, 0x5f, 0x6d, 0x70, 0x5f, 0x5f, 0x4f, 0x4f, 0x3d, 0x1e, 0x1e, 0x39, - 0x3b, 0x8c, 0x53, 0x50, 0x8c, 0x3b, 0x39, 0x1e, 0x1e, 0x1e, 0x1e, 0x39, - 0x3b, 0x8c, 0x50, 0x53, 0x8c, 0x3b, 0x39, 0x1e, 0xfe, 0xd5, 0x8c, 0x8c, - 0x00, 0x03, 0x00, 0x4f, 0x00, 0x69, 0x04, 0x82, 0x04, 0x9e, 0x00, 0x19, - 0x00, 0x33, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x32, 0x16, 0x17, 0x16, 0x17, - 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x0e, 0x01, 0x22, 0x26, 0x27, 0x26, - 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x04, 0x22, 0x07, 0x06, - 0x07, 0x0e, 0x01, 0x15, 0x14, 0x16, 0x17, 0x16, 0x17, 0x16, 0x32, 0x37, - 0x36, 0x37, 0x3e, 0x01, 0x35, 0x34, 0x26, 0x27, 0x26, 0x27, 0x05, 0x37, - 0x17, 0x37, 0x17, 0x07, 0x17, 0x07, 0x27, 0x07, 0x27, 0x37, 0x01, 0xfa, - 0xdd, 0xbe, 0x4f, 0x4f, 0x27, 0x27, 0x27, 0x27, 0x4f, 0x4f, 0xbe, 0xdd, - 0xbe, 0x4f, 0x4f, 0x27, 0x27, 0x27, 0x27, 0x4f, 0x4f, 0x01, 0x7e, 0xa3, - 0x47, 0x45, 0x3a, 0x3b, 0x39, 0x39, 0x3b, 0x3a, 0x45, 0x47, 0xa3, 0x46, - 0x46, 0x3a, 0x3b, 0x39, 0x39, 0x3b, 0x3a, 0x46, 0xfe, 0x42, 0x63, 0xc4, - 0xc3, 0x63, 0xc3, 0xc2, 0x63, 0xc2, 0xc2, 0x63, 0xc2, 0x04, 0x9e, 0x50, - 0x4f, 0x4f, 0x5f, 0x5f, 0x70, 0x6d, 0x5f, 0x5f, 0x4f, 0x4e, 0x50, 0x50, - 0x4e, 0x4f, 0x5f, 0x5f, 0x6d, 0x70, 0x5f, 0x5f, 0x4f, 0x4f, 0x3d, 0x1e, - 0x1e, 0x39, 0x3b, 0x8c, 0x53, 0x50, 0x8c, 0x3b, 0x39, 0x1e, 0x1e, 0x1e, - 0x1e, 0x39, 0x3b, 0x8c, 0x50, 0x53, 0x8c, 0x3b, 0x39, 0x1e, 0xad, 0x63, - 0xc4, 0xc3, 0x63, 0xc3, 0xc2, 0x63, 0xc2, 0xc2, 0x63, 0xc2, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x4f, 0x00, 0x69, 0x04, 0x82, 0x04, 0x9e, 0x00, 0x19, - 0x00, 0x33, 0x00, 0x37, 0x00, 0x00, 0x00, 0x32, 0x16, 0x17, 0x16, 0x17, - 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x0e, 0x01, 0x22, 0x26, 0x27, 0x26, - 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x04, 0x22, 0x07, 0x06, - 0x07, 0x0e, 0x01, 0x15, 0x14, 0x16, 0x17, 0x16, 0x17, 0x16, 0x32, 0x37, - 0x36, 0x37, 0x3e, 0x01, 0x35, 0x34, 0x26, 0x27, 0x26, 0x27, 0x1f, 0x01, - 0x01, 0x27, 0x01, 0xfa, 0xdd, 0xbe, 0x4f, 0x4f, 0x27, 0x27, 0x27, 0x27, - 0x4f, 0x4f, 0xbe, 0xdd, 0xbe, 0x4f, 0x4f, 0x27, 0x27, 0x27, 0x27, 0x4f, - 0x4f, 0x01, 0x7e, 0xa3, 0x47, 0x45, 0x3a, 0x3b, 0x39, 0x39, 0x3b, 0x3a, - 0x45, 0x47, 0xa3, 0x46, 0x46, 0x3a, 0x3b, 0x39, 0x39, 0x3b, 0x3a, 0x46, - 0x2c, 0x63, 0xfe, 0x18, 0x63, 0x04, 0x9e, 0x50, 0x4f, 0x4f, 0x5f, 0x5f, - 0x70, 0x6d, 0x5f, 0x5f, 0x4f, 0x4e, 0x50, 0x50, 0x4e, 0x4f, 0x5f, 0x5f, - 0x6d, 0x70, 0x5f, 0x5f, 0x4f, 0x4f, 0x3d, 0x1e, 0x1e, 0x39, 0x3b, 0x8c, - 0x53, 0x50, 0x8c, 0x3b, 0x39, 0x1e, 0x1e, 0x1e, 0x1e, 0x39, 0x3b, 0x8c, - 0x50, 0x53, 0x8c, 0x3b, 0x39, 0x1e, 0x4b, 0x63, 0xfe, 0x18, 0x63, 0x00, - 0x00, 0x03, 0x00, 0x4f, 0x00, 0x69, 0x04, 0x82, 0x04, 0x9e, 0x00, 0x03, - 0x00, 0x1d, 0x00, 0x37, 0x00, 0x00, 0x01, 0x33, 0x11, 0x23, 0x12, 0x32, - 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x0e, 0x01, - 0x22, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, - 0x04, 0x22, 0x07, 0x06, 0x07, 0x0e, 0x01, 0x15, 0x14, 0x16, 0x17, 0x16, - 0x17, 0x16, 0x32, 0x37, 0x36, 0x37, 0x3e, 0x01, 0x35, 0x34, 0x26, 0x27, - 0x26, 0x27, 0x01, 0xe9, 0xfc, 0xfc, 0x11, 0xdd, 0xbe, 0x4f, 0x4f, 0x27, - 0x27, 0x27, 0x27, 0x4f, 0x4f, 0xbe, 0xdd, 0xbe, 0x4f, 0x4f, 0x27, 0x27, - 0x27, 0x27, 0x4f, 0x4f, 0x01, 0x7e, 0xa3, 0x47, 0x45, 0x3a, 0x3b, 0x39, - 0x39, 0x3b, 0x3a, 0x45, 0x47, 0xa3, 0x46, 0x46, 0x3a, 0x3b, 0x39, 0x39, - 0x3b, 0x3a, 0x46, 0x03, 0x10, 0xfe, 0xcf, 0x02, 0xbf, 0x50, 0x4f, 0x4f, - 0x5f, 0x5f, 0x70, 0x6d, 0x5f, 0x5f, 0x4f, 0x4e, 0x50, 0x50, 0x4e, 0x4f, - 0x5f, 0x5f, 0x6d, 0x70, 0x5f, 0x5f, 0x4f, 0x4f, 0x3d, 0x1e, 0x1e, 0x39, - 0x3b, 0x8c, 0x53, 0x50, 0x8c, 0x3b, 0x39, 0x1e, 0x1e, 0x1e, 0x1e, 0x39, - 0x3b, 0x8c, 0x50, 0x53, 0x8c, 0x3b, 0x39, 0x1e, 0x00, 0x04, 0x00, 0x4f, - 0x00, 0x69, 0x04, 0x82, 0x04, 0x9e, 0x00, 0x0e, 0x00, 0x18, 0x00, 0x32, - 0x00, 0x4c, 0x00, 0x00, 0x01, 0x32, 0x16, 0x17, 0x1e, 0x01, 0x15, 0x14, - 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x16, 0x22, 0x06, 0x14, 0x16, - 0x33, 0x32, 0x36, 0x35, 0x34, 0x02, 0x32, 0x16, 0x17, 0x16, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x06, 0x07, 0x0e, 0x01, 0x22, 0x26, 0x27, 0x26, 0x27, - 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x04, 0x22, 0x07, 0x06, 0x07, - 0x0e, 0x01, 0x15, 0x14, 0x16, 0x17, 0x16, 0x17, 0x16, 0x32, 0x37, 0x36, - 0x37, 0x3e, 0x01, 0x35, 0x34, 0x26, 0x27, 0x26, 0x27, 0x02, 0x68, 0x37, - 0x62, 0x25, 0x26, 0x27, 0x9c, 0x71, 0x71, 0x97, 0x9a, 0xa7, 0x6e, 0x4e, - 0x4c, 0x38, 0x38, 0x4f, 0xf4, 0xdd, 0xbe, 0x4f, 0x4f, 0x27, 0x27, 0x27, - 0x27, 0x4f, 0x4f, 0xbe, 0xdd, 0xbe, 0x4f, 0x4f, 0x27, 0x27, 0x27, 0x27, - 0x4f, 0x4f, 0x01, 0x7e, 0xa3, 0x47, 0x45, 0x3a, 0x3b, 0x39, 0x39, 0x3b, - 0x3a, 0x45, 0x47, 0xa3, 0x46, 0x46, 0x3a, 0x3b, 0x39, 0x39, 0x3b, 0x3a, - 0x46, 0x03, 0x8f, 0x29, 0x27, 0x25, 0x60, 0x38, 0x6e, 0x9a, 0x97, 0x71, - 0x71, 0x9c, 0x87, 0x4d, 0x70, 0x4c, 0x4d, 0x37, 0x37, 0x01, 0xe4, 0x50, - 0x4f, 0x4f, 0x5f, 0x5f, 0x70, 0x6d, 0x5f, 0x5f, 0x4f, 0x4e, 0x50, 0x50, - 0x4e, 0x4f, 0x5f, 0x5f, 0x6d, 0x70, 0x5f, 0x5f, 0x4f, 0x4f, 0x3d, 0x1e, - 0x1e, 0x39, 0x3b, 0x8c, 0x53, 0x50, 0x8c, 0x3b, 0x39, 0x1e, 0x1e, 0x1e, - 0x1e, 0x39, 0x3b, 0x8c, 0x50, 0x53, 0x8c, 0x3b, 0x39, 0x1e, 0x00, 0x00, - 0x00, 0x07, 0x00, 0x4f, 0x00, 0x69, 0x04, 0x82, 0x04, 0x9e, 0x00, 0x19, - 0x00, 0x21, 0x00, 0x27, 0x00, 0x2f, 0x00, 0x37, 0x00, 0x3d, 0x00, 0x45, - 0x00, 0x00, 0x00, 0x32, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, - 0x06, 0x07, 0x0e, 0x01, 0x22, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x36, 0x37, 0x36, 0x05, 0x11, 0x25, 0x26, 0x27, 0x26, 0x27, 0x26, - 0x0d, 0x02, 0x36, 0x35, 0x34, 0x03, 0x27, 0x11, 0x36, 0x37, 0x36, 0x37, - 0x36, 0x05, 0x11, 0x07, 0x16, 0x17, 0x16, 0x17, 0x16, 0x2d, 0x02, 0x06, - 0x15, 0x14, 0x13, 0x05, 0x11, 0x06, 0x07, 0x06, 0x07, 0x06, 0x01, 0xfa, - 0xdd, 0xbe, 0x4f, 0x4f, 0x27, 0x27, 0x27, 0x27, 0x4f, 0x4f, 0xbe, 0xdd, - 0xbe, 0x4f, 0x4f, 0x27, 0x27, 0x27, 0x27, 0x4f, 0x4f, 0x01, 0x66, 0x00, - 0xff, 0x0f, 0x12, 0x3a, 0x46, 0x2d, 0x01, 0x06, 0xfe, 0xec, 0x01, 0x13, - 0x1c, 0x54, 0xfe, 0x31, 0x2d, 0x46, 0x3a, 0x11, 0xfe, 0x9e, 0xfe, 0x0f, - 0x11, 0x3a, 0x45, 0x2e, 0xfe, 0xfb, 0x01, 0x13, 0xfe, 0xec, 0x1b, 0x53, - 0x00, 0xff, 0x31, 0x2e, 0x45, 0x3a, 0x12, 0x04, 0x9e, 0x50, 0x4f, 0x4f, - 0x5f, 0x5f, 0x70, 0x6d, 0x5f, 0x5f, 0x4f, 0x4e, 0x50, 0x50, 0x4e, 0x4f, - 0x5f, 0x5f, 0x6d, 0x70, 0x5f, 0x5f, 0x4f, 0x4f, 0x41, 0xfe, 0xcf, 0x9a, - 0x13, 0x13, 0x39, 0x1e, 0x13, 0xee, 0x96, 0x96, 0x46, 0x50, 0x51, 0xfe, - 0xbc, 0x99, 0xfe, 0xd2, 0x07, 0x13, 0x1e, 0x39, 0x12, 0x83, 0x01, 0x2e, - 0x99, 0x12, 0x12, 0x39, 0x1e, 0x13, 0xeb, 0x96, 0x96, 0x45, 0x51, 0x50, - 0x01, 0x44, 0x9a, 0x01, 0x31, 0x07, 0x13, 0x1e, 0x39, 0x13, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x4f, 0x00, 0x69, 0x04, 0x82, 0x04, 0x9e, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x21, 0x00, 0x3b, 0x00, 0x00, 0x01, 0x21, 0x15, 0x21, - 0x11, 0x21, 0x15, 0x21, 0x12, 0x32, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, - 0x14, 0x07, 0x06, 0x07, 0x0e, 0x01, 0x22, 0x26, 0x27, 0x26, 0x27, 0x26, - 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x04, 0x22, 0x07, 0x06, 0x07, 0x0e, - 0x01, 0x15, 0x14, 0x16, 0x17, 0x16, 0x17, 0x16, 0x32, 0x37, 0x36, 0x37, - 0x3e, 0x01, 0x35, 0x34, 0x26, 0x27, 0x26, 0x27, 0x01, 0x2b, 0x02, 0x7b, - 0xfd, 0x85, 0x02, 0x7b, 0xfd, 0x85, 0xcf, 0xdd, 0xbe, 0x4f, 0x4f, 0x27, - 0x27, 0x27, 0x27, 0x4f, 0x4f, 0xbe, 0xdd, 0xbe, 0x4f, 0x4f, 0x27, 0x27, - 0x27, 0x27, 0x4f, 0x4f, 0x01, 0x7e, 0xa3, 0x47, 0x45, 0x3a, 0x3b, 0x39, - 0x39, 0x3b, 0x3a, 0x45, 0x47, 0xa3, 0x46, 0x46, 0x3a, 0x3b, 0x39, 0x39, - 0x3b, 0x3a, 0x46, 0x02, 0x3b, 0x67, 0x01, 0x5a, 0x66, 0x01, 0xd6, 0x50, - 0x4f, 0x4f, 0x5f, 0x5f, 0x70, 0x6d, 0x5f, 0x5f, 0x4f, 0x4e, 0x50, 0x50, - 0x4e, 0x4f, 0x5f, 0x5f, 0x6d, 0x70, 0x5f, 0x5f, 0x4f, 0x4f, 0x3d, 0x1e, - 0x1e, 0x39, 0x3b, 0x8c, 0x53, 0x50, 0x8c, 0x3b, 0x39, 0x1e, 0x1e, 0x1e, - 0x1e, 0x39, 0x3b, 0x8c, 0x50, 0x53, 0x8c, 0x3b, 0x39, 0x1e, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x4f, 0x00, 0x69, 0x04, 0x82, 0x04, 0x9e, 0x00, 0x19, - 0x00, 0x33, 0x00, 0x37, 0x00, 0x00, 0x00, 0x32, 0x16, 0x17, 0x16, 0x17, - 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x0e, 0x01, 0x22, 0x26, 0x27, 0x26, - 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x04, 0x22, 0x07, 0x06, - 0x07, 0x0e, 0x01, 0x15, 0x14, 0x16, 0x17, 0x16, 0x17, 0x16, 0x32, 0x37, - 0x36, 0x37, 0x3e, 0x01, 0x35, 0x34, 0x26, 0x27, 0x26, 0x27, 0x13, 0x21, - 0x35, 0x21, 0x01, 0xfa, 0xdd, 0xbe, 0x4f, 0x4f, 0x27, 0x27, 0x27, 0x27, - 0x4f, 0x4f, 0xbe, 0xdd, 0xbe, 0x4f, 0x4f, 0x27, 0x27, 0x27, 0x27, 0x4f, - 0x4f, 0x01, 0x7e, 0xa3, 0x47, 0x45, 0x3a, 0x3b, 0x39, 0x39, 0x3b, 0x3a, - 0x45, 0x47, 0xa3, 0x46, 0x46, 0x3a, 0x3b, 0x39, 0x39, 0x3b, 0x3a, 0x46, - 0x32, 0xfe, 0x6d, 0x01, 0x93, 0x04, 0x9e, 0x50, 0x4f, 0x4f, 0x5f, 0x5f, - 0x70, 0x6d, 0x5f, 0x5f, 0x4f, 0x4e, 0x50, 0x50, 0x4e, 0x4f, 0x5f, 0x5f, - 0x6d, 0x70, 0x5f, 0x5f, 0x4f, 0x4f, 0x3d, 0x1e, 0x1e, 0x39, 0x3b, 0x8c, - 0x53, 0x50, 0x8c, 0x3b, 0x39, 0x1e, 0x1e, 0x1e, 0x1e, 0x39, 0x3b, 0x8c, - 0x50, 0x53, 0x8c, 0x3b, 0x39, 0x1e, 0xfe, 0x49, 0x8c, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x50, 0x00, 0x69, 0x04, 0x83, 0x04, 0x9c, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x13, 0x00, 0x00, 0x25, 0x11, 0x21, 0x11, 0x03, 0x21, - 0x11, 0x21, 0x01, 0x33, 0x11, 0x21, 0x15, 0x21, 0x11, 0x23, 0x11, 0x21, - 0x35, 0x21, 0x03, 0xf4, 0xfc, 0xe8, 0x8c, 0x04, 0x33, 0xfb, 0xcd, 0x01, - 0xd2, 0x8c, 0x01, 0x38, 0xfe, 0xc8, 0x8c, 0xfe, 0xc9, 0x01, 0x37, 0xf5, - 0x03, 0x1b, 0xfc, 0xe5, 0x03, 0xa7, 0xfb, 0xcd, 0x03, 0x98, 0xfe, 0xc7, - 0x8c, 0xfe, 0xca, 0x01, 0x36, 0x8c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x50, - 0x00, 0x69, 0x04, 0x83, 0x04, 0x9c, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, - 0x00, 0x00, 0x25, 0x11, 0x21, 0x11, 0x03, 0x21, 0x11, 0x21, 0x01, 0x15, - 0x21, 0x35, 0x03, 0xf4, 0xfc, 0xe8, 0x8c, 0x04, 0x33, 0xfb, 0xcd, 0x03, - 0x72, 0xfd, 0x4d, 0xf5, 0x03, 0x1b, 0xfc, 0xe5, 0x03, 0xa7, 0xfb, 0xcd, - 0x02, 0x5f, 0x8c, 0x8c, 0x00, 0x03, 0x00, 0x50, 0x00, 0x69, 0x04, 0x83, - 0x04, 0x9c, 0x00, 0x03, 0x00, 0x07, 0x00, 0x13, 0x00, 0x00, 0x25, 0x11, - 0x21, 0x11, 0x03, 0x21, 0x11, 0x21, 0x13, 0x37, 0x09, 0x01, 0x17, 0x09, - 0x01, 0x07, 0x09, 0x01, 0x27, 0x01, 0x03, 0xf4, 0xfc, 0xe8, 0x8c, 0x04, - 0x33, 0xfb, 0xcd, 0xac, 0x63, 0x01, 0x0b, 0x01, 0x0c, 0x63, 0xfe, 0xf4, - 0x01, 0x08, 0x63, 0xfe, 0xf8, 0xfe, 0xf6, 0x63, 0x01, 0x0a, 0xf5, 0x03, - 0x1b, 0xfc, 0xe5, 0x03, 0xa7, 0xfb, 0xcd, 0x03, 0x23, 0x63, 0xfe, 0xf5, - 0x01, 0x0c, 0x63, 0xfe, 0xf4, 0xfe, 0xf8, 0x63, 0x01, 0x08, 0xfe, 0xf7, - 0x63, 0x01, 0x09, 0x00, 0x00, 0x03, 0x00, 0x50, 0x00, 0x69, 0x04, 0x83, - 0x04, 0x9c, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x33, - 0x11, 0x23, 0x05, 0x11, 0x21, 0x11, 0x03, 0x21, 0x11, 0x21, 0x01, 0xe9, - 0xfc, 0xfc, 0x02, 0x0b, 0xfc, 0xe8, 0x8c, 0x04, 0x33, 0xfb, 0xcd, 0x03, - 0x10, 0xfe, 0xcf, 0xea, 0x03, 0x1b, 0xfc, 0xe5, 0x03, 0xa7, 0xfb, 0xcd, - 0x00, 0x01, 0x00, 0x58, 0x00, 0x00, 0x04, 0x79, 0x05, 0x04, 0x00, 0x07, - 0x00, 0x00, 0x01, 0x11, 0x21, 0x15, 0x21, 0x11, 0x23, 0x11, 0x01, 0x00, - 0x03, 0x79, 0xfc, 0x87, 0xa8, 0x05, 0x04, 0xfd, 0xd3, 0xaa, 0xfd, 0xd3, - 0x05, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x58, 0x00, 0x00, 0x04, 0x79, - 0x05, 0x04, 0x00, 0x07, 0x00, 0x00, 0x21, 0x11, 0x21, 0x35, 0x21, 0x11, - 0x33, 0x11, 0x03, 0xd1, 0xfc, 0x87, 0x03, 0x79, 0xa8, 0x02, 0x2d, 0xaa, - 0x02, 0x2d, 0xfa, 0xfc, 0x00, 0x01, 0x00, 0x58, 0x00, 0x00, 0x04, 0x79, - 0x05, 0x04, 0x00, 0x07, 0x00, 0x00, 0x21, 0x11, 0x21, 0x35, 0x21, 0x15, - 0x21, 0x11, 0x02, 0x15, 0xfe, 0x43, 0x04, 0x21, 0xfe, 0x44, 0x04, 0x5a, - 0xaa, 0xaa, 0xfb, 0xa6, 0x00, 0x01, 0x00, 0x58, 0x00, 0x00, 0x04, 0x79, - 0x05, 0x04, 0x00, 0x07, 0x00, 0x00, 0x01, 0x03, 0x21, 0x15, 0x21, 0x35, - 0x21, 0x13, 0x02, 0xbd, 0x01, 0x01, 0xbd, 0xfb, 0xdf, 0x01, 0xbc, 0x01, - 0x05, 0x04, 0xfb, 0xa6, 0xaa, 0xaa, 0x04, 0x5a, 0x00, 0x01, 0x01, 0xe9, - 0x02, 0x2f, 0x02, 0xe5, 0x03, 0x60, 0x00, 0x03, 0x00, 0x15, 0xb9, 0x00, - 0x02, 0x01, 0x01, 0xb5, 0x00, 0x04, 0x01, 0x1d, 0x00, 0x04, 0x10, 0xd4, - 0xec, 0x31, 0x00, 0x10, 0xd4, 0xec, 0x30, 0x01, 0x33, 0x11, 0x23, 0x01, - 0xe9, 0xfc, 0xfc, 0x03, 0x60, 0xfe, 0xcf, 0x00, 0x00, 0x01, 0x01, 0x08, - 0x01, 0x9b, 0x03, 0xc9, 0x04, 0x37, 0x00, 0x09, 0x00, 0x00, 0x01, 0x21, - 0x13, 0x17, 0x21, 0x07, 0x17, 0x27, 0x07, 0x13, 0x01, 0x09, 0x01, 0x0c, - 0x54, 0x53, 0x01, 0x0c, 0xd9, 0x54, 0xda, 0xda, 0x53, 0x03, 0x38, 0x00, - 0xff, 0xff, 0x9e, 0xff, 0x9e, 0x9e, 0x00, 0xff, 0x00, 0x02, 0x00, 0x58, - 0x01, 0x60, 0x04, 0x79, 0x03, 0xc3, 0x00, 0x03, 0x00, 0x1f, 0x00, 0x00, - 0x01, 0x15, 0x21, 0x35, 0x11, 0x1e, 0x01, 0x33, 0x32, 0x37, 0x36, 0x37, - 0x3e, 0x01, 0x33, 0x32, 0x16, 0x17, 0x15, 0x2e, 0x01, 0x23, 0x22, 0x06, - 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x26, 0x27, 0x04, 0x79, 0xfb, 0xdf, - 0x4a, 0x89, 0x46, 0x5d, 0x74, 0x16, 0x0a, 0x4b, 0x64, 0x35, 0x53, 0x92, - 0x4e, 0x49, 0x8d, 0x4f, 0x33, 0x67, 0x4d, 0x0b, 0x16, 0x71, 0x5a, 0x4f, - 0x8f, 0x4b, 0x02, 0x0c, 0xac, 0xac, 0x01, 0xb7, 0x3f, 0x3c, 0x36, 0x0b, - 0x04, 0x20, 0x16, 0x37, 0x3c, 0xae, 0x40, 0x3b, 0x18, 0x22, 0x04, 0x0a, - 0x33, 0x37, 0x3b, 0x00, 0x00, 0x03, 0x00, 0x58, 0xfe, 0x41, 0x04, 0x79, - 0x06, 0x15, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x11, 0x00, 0x00, 0x37, 0x35, - 0x01, 0x15, 0x01, 0x35, 0x25, 0x13, 0x15, 0x01, 0x35, 0x01, 0x15, 0x05, - 0x01, 0x15, 0x21, 0x35, 0x58, 0x04, 0x21, 0xfb, 0xdf, 0x03, 0x23, 0xfe, - 0xfb, 0xdf, 0x04, 0x21, 0xfc, 0xdf, 0x03, 0x21, 0xfb, 0xdf, 0xca, 0xb6, - 0xfe, 0xb4, 0xa8, 0xfe, 0xb5, 0xb8, 0xe7, 0x03, 0xac, 0xb6, 0x01, 0x4c, - 0xa8, 0x01, 0x4b, 0xb8, 0xe7, 0xfe, 0x0a, 0xaa, 0xaa, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x58, 0xfe, 0x41, 0x04, 0x79, 0x06, 0x15, 0x00, 0x06, - 0x00, 0x0d, 0x00, 0x11, 0x00, 0x00, 0x25, 0x0d, 0x01, 0x15, 0x01, 0x35, - 0x09, 0x01, 0x2d, 0x01, 0x35, 0x01, 0x15, 0x01, 0x15, 0x21, 0x15, 0x21, - 0x04, 0x79, 0xfc, 0xdd, 0x03, 0x23, 0xfb, 0xdf, 0x04, 0x21, 0xfb, 0xdf, - 0x03, 0x21, 0xfc, 0xdf, 0x04, 0x21, 0xfb, 0xdf, 0x04, 0x21, 0xfb, 0xdf, - 0xca, 0xea, 0xe7, 0xb8, 0x01, 0x4b, 0xa8, 0x01, 0x4c, 0x02, 0x0c, 0xea, - 0xe7, 0xb8, 0xfe, 0xb5, 0xa8, 0xfe, 0xb4, 0x56, 0xaa, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x56, 0x00, 0x00, 0x04, 0x77, 0x04, 0x3f, 0x00, 0x06, - 0x00, 0x0a, 0x00, 0x00, 0x01, 0x0d, 0x01, 0x15, 0x01, 0x35, 0x01, 0x35, - 0x21, 0x35, 0x21, 0x04, 0x77, 0xfc, 0xdf, 0x03, 0x21, 0xfb, 0xdf, 0x04, - 0x21, 0xfb, 0xdf, 0x04, 0x21, 0x02, 0x89, 0xea, 0xe7, 0xb8, 0x01, 0x4b, - 0xa8, 0x01, 0x4c, 0x56, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x58, - 0x00, 0x00, 0x04, 0x79, 0x04, 0x3f, 0x00, 0x06, 0x00, 0x0a, 0x00, 0x00, - 0x13, 0x35, 0x01, 0x15, 0x01, 0x35, 0x25, 0x01, 0x35, 0x21, 0x15, 0x58, - 0x04, 0x21, 0xfb, 0xdf, 0x03, 0x23, 0xfc, 0xdd, 0x04, 0x21, 0x02, 0x89, - 0xb6, 0xfe, 0xb4, 0xa8, 0xfe, 0xb5, 0xb8, 0xe7, 0x01, 0xf6, 0xaa, 0xaa, - 0x00, 0x02, 0x00, 0x56, 0xff, 0x04, 0x04, 0x77, 0x05, 0xb1, 0x00, 0x09, - 0x00, 0x18, 0x00, 0x00, 0x01, 0x24, 0x37, 0x15, 0x06, 0x05, 0x06, 0x05, - 0x35, 0x24, 0x01, 0x15, 0x26, 0x25, 0x26, 0x25, 0x35, 0x24, 0x37, 0x24, - 0x37, 0x15, 0x00, 0x05, 0x04, 0x02, 0xa4, 0x01, 0x22, 0xb1, 0xcb, 0xfe, - 0xf8, 0xde, 0xfe, 0x90, 0x01, 0x6e, 0x02, 0xb3, 0xb7, 0xfe, 0xe4, 0xed, - 0xfe, 0x9f, 0x01, 0x57, 0xf7, 0x01, 0x1c, 0xb7, 0xfe, 0xdd, 0xfe, 0x6c, - 0x01, 0x94, 0x04, 0x1a, 0xc8, 0xcf, 0xfc, 0xdc, 0x9c, 0x83, 0x38, 0xc8, - 0x36, 0xfc, 0x73, 0xef, 0xcb, 0x96, 0x7d, 0x3d, 0xa6, 0x39, 0x82, 0x97, - 0xc9, 0xef, 0xfe, 0xde, 0x5d, 0x4f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x56, - 0xff, 0x04, 0x04, 0x77, 0x05, 0xb1, 0x00, 0x09, 0x00, 0x18, 0x00, 0x00, - 0x01, 0x16, 0x05, 0x15, 0x24, 0x27, 0x24, 0x27, 0x35, 0x16, 0x03, 0x00, - 0x25, 0x24, 0x01, 0x35, 0x16, 0x05, 0x16, 0x05, 0x15, 0x04, 0x07, 0x04, - 0x07, 0x02, 0x29, 0xe0, 0x01, 0x6e, 0xfe, 0x90, 0xde, 0xfe, 0xf8, 0xcb, - 0xb1, 0xb1, 0x01, 0x23, 0x01, 0x94, 0xfe, 0x6c, 0xfe, 0xdd, 0xb7, 0x01, - 0x1c, 0xf7, 0x01, 0x57, 0xfe, 0x9f, 0xed, 0xfe, 0xe4, 0xb7, 0x04, 0x1a, - 0x9a, 0x36, 0xc8, 0x38, 0x83, 0x9c, 0xdc, 0xfc, 0xcf, 0xfb, 0x11, 0x01, - 0x30, 0x4f, 0x5d, 0x01, 0x22, 0xef, 0xc9, 0x97, 0x82, 0x39, 0xa6, 0x3d, - 0x7d, 0x96, 0xcb, 0x00, 0x00, 0x02, 0x00, 0x56, 0xfe, 0x8c, 0x04, 0x77, - 0x06, 0x29, 0x00, 0x25, 0x00, 0x2a, 0x00, 0x00, 0x01, 0x17, 0x07, 0x36, - 0x37, 0x15, 0x06, 0x07, 0x03, 0x16, 0x17, 0x15, 0x26, 0x27, 0x07, 0x17, - 0x04, 0x17, 0x15, 0x26, 0x25, 0x26, 0x27, 0x03, 0x27, 0x13, 0x26, 0x27, - 0x35, 0x16, 0x17, 0x37, 0x26, 0x25, 0x35, 0x24, 0x3f, 0x01, 0x03, 0x37, - 0x06, 0x07, 0x16, 0x03, 0x64, 0xa2, 0x4d, 0x6a, 0x54, 0x81, 0x98, 0x56, - 0xca, 0xa5, 0xa9, 0xfe, 0x33, 0x07, 0x01, 0x08, 0xcb, 0xb1, 0xfe, 0xde, - 0x1f, 0x21, 0xb3, 0xa2, 0xba, 0xa3, 0xd0, 0xf7, 0xb6, 0x33, 0xd2, 0xfe, - 0xf2, 0x01, 0x61, 0xed, 0x34, 0x6d, 0x22, 0x63, 0x6a, 0x58, 0x06, 0x29, - 0x33, 0xf5, 0x53, 0x5d, 0xef, 0x87, 0x5b, 0xfe, 0xee, 0x65, 0xa5, 0xef, - 0xb9, 0x8f, 0xa1, 0x04, 0x9c, 0xdc, 0xfc, 0xcf, 0xc8, 0x15, 0x14, 0xfd, - 0xc8, 0x33, 0x02, 0x4e, 0x40, 0x1e, 0xc8, 0x25, 0x48, 0xa3, 0x5a, 0x2d, - 0xa6, 0x3d, 0x7d, 0x1d, 0xfe, 0xa4, 0x6b, 0x24, 0x15, 0x14, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x56, 0xfe, 0x8c, 0x04, 0x77, 0x06, 0x29, 0x00, 0x24, - 0x00, 0x28, 0x00, 0x00, 0x01, 0x17, 0x03, 0x16, 0x17, 0x15, 0x04, 0x0f, - 0x01, 0x36, 0x25, 0x15, 0x04, 0x0f, 0x01, 0x03, 0x27, 0x13, 0x06, 0x07, - 0x35, 0x36, 0x3f, 0x01, 0x06, 0x07, 0x35, 0x36, 0x25, 0x37, 0x24, 0x27, - 0x35, 0x16, 0x05, 0x16, 0x1f, 0x01, 0x07, 0x37, 0x26, 0x03, 0x25, 0xa2, - 0xa5, 0x9a, 0xbb, 0xff, 0x00, 0xcb, 0x44, 0xd1, 0x01, 0x3e, 0xfe, 0x92, - 0xe0, 0x16, 0xa1, 0xa2, 0x57, 0x77, 0x5a, 0x8c, 0xa9, 0x4e, 0xe7, 0x9c, - 0xcc, 0x01, 0x02, 0x28, 0xfe, 0xe5, 0xdb, 0xb7, 0x01, 0x1c, 0x2b, 0x2f, - 0x6d, 0x05, 0x22, 0x0f, 0x06, 0x29, 0x33, 0xfd, 0xf3, 0x33, 0x20, 0xa6, - 0x2b, 0x53, 0xd8, 0x69, 0x30, 0xc8, 0x36, 0x9a, 0x0f, 0xfe, 0x00, 0x33, - 0x01, 0x16, 0x68, 0x69, 0xfc, 0x98, 0x79, 0xf7, 0x87, 0xac, 0xef, 0xcb, - 0x6a, 0x7f, 0x65, 0xe5, 0xef, 0xcb, 0x96, 0x17, 0x14, 0xdc, 0x0e, 0x08, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x58, 0xff, 0x5b, 0x04, 0x79, - 0x05, 0xa7, 0x00, 0x0f, 0x00, 0x13, 0x00, 0x00, 0x01, 0x17, 0x07, 0x33, - 0x15, 0x21, 0x01, 0x21, 0x15, 0x21, 0x03, 0x27, 0x37, 0x23, 0x11, 0x21, - 0x09, 0x01, 0x21, 0x11, 0x03, 0x50, 0x9e, 0x59, 0xe4, 0xfe, 0xd8, 0xfe, - 0xe6, 0x02, 0x42, 0xfd, 0x7a, 0x72, 0x9e, 0x59, 0xe4, 0x02, 0x86, 0xfe, - 0xa2, 0x01, 0x1a, 0xfe, 0x68, 0x05, 0xa7, 0x3f, 0xdd, 0xaa, 0xfd, 0x40, - 0xaa, 0xfe, 0xe4, 0x3f, 0xdd, 0x04, 0x14, 0xfc, 0x96, 0x02, 0xc0, 0xfd, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x58, 0xff, 0x5b, 0x04, 0x79, - 0x05, 0xa7, 0x00, 0x0f, 0x00, 0x13, 0x00, 0x00, 0x01, 0x17, 0x07, 0x33, - 0x11, 0x21, 0x03, 0x27, 0x37, 0x23, 0x35, 0x21, 0x01, 0x21, 0x35, 0x21, - 0x17, 0x01, 0x21, 0x11, 0x03, 0x50, 0x9e, 0x59, 0xe4, 0xfd, 0x7a, 0x72, - 0x9e, 0x59, 0xe4, 0x01, 0x28, 0x01, 0x1a, 0xfd, 0xbe, 0x02, 0x86, 0x73, - 0xfe, 0xe6, 0x01, 0x98, 0x05, 0xa7, 0x3f, 0xdd, 0xfb, 0xec, 0xfe, 0xe4, - 0x3f, 0xdd, 0xaa, 0x02, 0xc0, 0xaa, 0xaa, 0xfd, 0x40, 0x02, 0xc0, 0x00, - 0x00, 0x01, 0x00, 0x58, 0xff, 0x3e, 0x04, 0x79, 0x04, 0xf4, 0x00, 0x14, - 0x00, 0x00, 0x13, 0x21, 0x15, 0x21, 0x11, 0x21, 0x15, 0x21, 0x17, 0x07, - 0x21, 0x15, 0x21, 0x07, 0x27, 0x37, 0x21, 0x35, 0x21, 0x37, 0x21, 0x58, - 0x04, 0x21, 0xfc, 0x89, 0x03, 0x77, 0xfe, 0xd2, 0x20, 0x52, 0x01, 0x60, - 0xfe, 0x18, 0xa7, 0x84, 0x52, 0xfe, 0xa0, 0x01, 0xe8, 0x67, 0xfd, 0xb1, - 0x04, 0xf4, 0xaa, 0xfd, 0x98, 0xaa, 0x1a, 0x66, 0xaa, 0xd0, 0x6a, 0x66, - 0xaa, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x58, 0xff, 0x3e, 0x04, 0x79, - 0x04, 0xf4, 0x00, 0x14, 0x00, 0x00, 0x25, 0x15, 0x21, 0x07, 0x27, 0x37, - 0x21, 0x35, 0x21, 0x37, 0x21, 0x35, 0x21, 0x11, 0x21, 0x35, 0x21, 0x11, - 0x21, 0x17, 0x07, 0x04, 0x79, 0xfe, 0x18, 0xa7, 0x84, 0x52, 0xfe, 0xa0, - 0x01, 0xe8, 0x67, 0xfd, 0xb1, 0x03, 0x77, 0xfc, 0x89, 0x04, 0x21, 0xfe, - 0xd2, 0x20, 0x52, 0xb8, 0xaa, 0xd0, 0x6a, 0x66, 0xaa, 0x80, 0xaa, 0x02, - 0x68, 0xaa, 0xfc, 0x44, 0x1a, 0x66, 0x00, 0x00, 0x00, 0x01, 0x00, 0x56, - 0xfe, 0xed, 0x04, 0x77, 0x04, 0x3f, 0x00, 0x25, 0x00, 0x00, 0x25, 0x26, - 0x27, 0x26, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x16, - 0x17, 0x37, 0x25, 0x35, 0x01, 0x15, 0x0d, 0x01, 0x15, 0x25, 0x07, 0x16, - 0x33, 0x32, 0x36, 0x37, 0x15, 0x0e, 0x01, 0x23, 0x22, 0x27, 0x03, 0x27, - 0x02, 0x16, 0x1d, 0x17, 0x34, 0x33, 0x4f, 0x8d, 0x49, 0x4e, 0x92, 0x53, - 0x3a, 0x5a, 0x1d, 0x30, 0xfd, 0xec, 0x04, 0x21, 0xfc, 0xdf, 0x03, 0x21, - 0xfe, 0x78, 0x32, 0x58, 0x49, 0x46, 0x89, 0x4a, 0x4b, 0x8f, 0x4f, 0x51, - 0x64, 0x3e, 0x88, 0x33, 0x0b, 0x05, 0x0c, 0x3b, 0x40, 0xae, 0x3c, 0x37, - 0x16, 0x0c, 0xd2, 0xa7, 0xa8, 0x01, 0x4b, 0xb8, 0xe7, 0xea, 0xb6, 0x7b, - 0xdf, 0x22, 0x3c, 0x3f, 0xaf, 0x3b, 0x37, 0x29, 0xfe, 0xf0, 0x1f, 0x00, - 0x00, 0x01, 0x00, 0x56, 0xfe, 0xed, 0x04, 0x77, 0x04, 0x3f, 0x00, 0x26, - 0x00, 0x00, 0x13, 0x2d, 0x01, 0x35, 0x01, 0x15, 0x05, 0x17, 0x03, 0x16, - 0x33, 0x32, 0x36, 0x37, 0x15, 0x0e, 0x01, 0x23, 0x22, 0x27, 0x03, 0x27, - 0x13, 0x26, 0x27, 0x26, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, - 0x32, 0x16, 0x17, 0x37, 0x05, 0x56, 0x03, 0x21, 0xfc, 0xdf, 0x04, 0x21, - 0xfe, 0x3f, 0x45, 0x3e, 0x58, 0x49, 0x46, 0x89, 0x4a, 0x4b, 0x8f, 0x4f, - 0x51, 0x64, 0x3e, 0x88, 0x43, 0x1d, 0x17, 0x34, 0x33, 0x4f, 0x8d, 0x49, - 0x4e, 0x92, 0x53, 0x3a, 0x5a, 0x1d, 0x30, 0xfd, 0xec, 0x01, 0xb6, 0xea, - 0xe7, 0xb8, 0xfe, 0xb5, 0xa8, 0x8d, 0x10, 0xfe, 0xed, 0x22, 0x3c, 0x3f, - 0xaf, 0x3b, 0x37, 0x29, 0xfe, 0xf0, 0x1f, 0x01, 0x27, 0x0b, 0x05, 0x0c, - 0x3b, 0x40, 0xae, 0x3c, 0x37, 0x16, 0x0c, 0xd4, 0xa7, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x56, 0xfe, 0x4b, 0x04, 0x77, 0x05, 0xb1, 0x00, 0x1f, - 0x00, 0x2e, 0x00, 0x00, 0x05, 0x26, 0x27, 0x26, 0x23, 0x22, 0x06, 0x07, - 0x35, 0x3e, 0x01, 0x33, 0x32, 0x17, 0x16, 0x17, 0x13, 0x17, 0x03, 0x16, - 0x33, 0x32, 0x36, 0x37, 0x15, 0x0e, 0x01, 0x23, 0x22, 0x27, 0x03, 0x27, - 0x01, 0x00, 0x05, 0x04, 0x01, 0x15, 0x26, 0x25, 0x26, 0x25, 0x35, 0x24, - 0x37, 0x24, 0x37, 0x02, 0x16, 0x1d, 0x17, 0x34, 0x33, 0x4f, 0x8d, 0x49, - 0x4e, 0x92, 0x53, 0x36, 0x31, 0x2d, 0x1d, 0x4e, 0x88, 0x53, 0x58, 0x49, - 0x46, 0x89, 0x4a, 0x4b, 0x8f, 0x4f, 0x51, 0x64, 0x53, 0x88, 0x02, 0xb9, - 0xfe, 0xdd, 0xfe, 0x6c, 0x01, 0x94, 0x01, 0x23, 0xb7, 0xfe, 0xe4, 0xf7, - 0xfe, 0xa9, 0x01, 0x61, 0xed, 0x01, 0x1c, 0xb7, 0x13, 0x0b, 0x05, 0x0c, - 0x3b, 0x40, 0xae, 0x3c, 0x37, 0x0b, 0x0b, 0x0c, 0x01, 0x57, 0x1f, 0xfe, - 0x91, 0x22, 0x3c, 0x3f, 0xaf, 0x3b, 0x37, 0x29, 0xfe, 0x94, 0x1f, 0x06, - 0x58, 0xfe, 0xd0, 0x4f, 0x5d, 0xfe, 0xde, 0xef, 0xc9, 0x97, 0x82, 0x39, - 0xa6, 0x3d, 0x7d, 0x96, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x56, - 0xfe, 0x4b, 0x04, 0x77, 0x05, 0xb1, 0x00, 0x1f, 0x00, 0x2e, 0x00, 0x00, - 0x05, 0x26, 0x27, 0x26, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, - 0x32, 0x17, 0x16, 0x17, 0x13, 0x17, 0x03, 0x16, 0x33, 0x32, 0x36, 0x37, - 0x15, 0x0e, 0x01, 0x23, 0x22, 0x27, 0x03, 0x27, 0x01, 0x35, 0x16, 0x05, - 0x16, 0x05, 0x15, 0x04, 0x07, 0x04, 0x07, 0x35, 0x00, 0x25, 0x24, 0x02, - 0x16, 0x1d, 0x17, 0x34, 0x33, 0x4f, 0x8d, 0x49, 0x4e, 0x92, 0x53, 0x36, - 0x31, 0x2d, 0x1d, 0x4e, 0x88, 0x53, 0x58, 0x49, 0x46, 0x89, 0x4a, 0x4b, - 0x8f, 0x4f, 0x51, 0x64, 0x53, 0x88, 0xfe, 0x98, 0xb7, 0x01, 0x1c, 0xed, - 0x01, 0x61, 0xfe, 0xa9, 0xf7, 0xfe, 0xe7, 0xba, 0x01, 0x23, 0x01, 0x94, - 0xfe, 0x6c, 0x13, 0x0b, 0x05, 0x0c, 0x3b, 0x40, 0xae, 0x3c, 0x37, 0x0b, - 0x0b, 0x0c, 0x01, 0x57, 0x1f, 0xfe, 0x91, 0x22, 0x3c, 0x3f, 0xaf, 0x3b, - 0x37, 0x29, 0xfe, 0x94, 0x1f, 0x06, 0x58, 0xef, 0xcb, 0x96, 0x7d, 0x3d, - 0xa6, 0x39, 0x82, 0x94, 0xcc, 0xef, 0x01, 0x22, 0x5d, 0x4f, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x50, 0x01, 0xea, 0x04, 0x7f, 0x03, 0x1b, 0x10, 0x07, - 0x07, 0x28, 0x00, 0x00, 0x01, 0xea, 0x00, 0x00, 0xff, 0xff, 0x00, 0x49, - 0x00, 0x62, 0x04, 0x8a, 0x04, 0xa3, 0x10, 0x06, 0x08, 0x14, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x72, 0x01, 0x4c, 0x04, 0x52, 0x03, 0x8c, 0x00, 0x07, - 0x00, 0x00, 0x01, 0x11, 0x01, 0x35, 0x05, 0x11, 0x01, 0x15, 0x02, 0xa2, - 0xfd, 0xd0, 0x01, 0xb0, 0x02, 0x30, 0x02, 0x7a, 0xfe, 0xd2, 0x01, 0x4a, - 0xc2, 0xfa, 0x01, 0x2e, 0xfe, 0xb6, 0xc2, 0x00, 0x00, 0x02, 0x00, 0x92, - 0x00, 0x00, 0x04, 0x3f, 0x04, 0xc4, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, - 0x33, 0x11, 0x09, 0x01, 0x11, 0x25, 0x21, 0x11, 0x09, 0x01, 0x92, 0x01, - 0xd6, 0x01, 0xd6, 0xfc, 0xce, 0x02, 0xb8, 0xfe, 0xa4, 0xfe, 0xa4, 0x02, - 0x87, 0x02, 0x3d, 0xfd, 0xc3, 0xfd, 0x79, 0x7a, 0x01, 0xd5, 0x01, 0xab, - 0xfe, 0x55, 0x00, 0x00, 0x00, 0x01, 0x00, 0x92, 0x03, 0x3f, 0x04, 0x3e, - 0x05, 0xf8, 0x00, 0x05, 0x00, 0x00, 0x09, 0x01, 0x23, 0x09, 0x01, 0x23, - 0x02, 0x68, 0x01, 0xd6, 0xa3, 0xfe, 0xcd, 0xfe, 0xcd, 0xa3, 0x05, 0xf8, - 0xfd, 0x47, 0x01, 0xc7, 0xfe, 0x39, 0x00, 0x00, 0x00, 0x01, 0x00, 0x92, - 0xfe, 0xf2, 0x04, 0x3e, 0x01, 0xac, 0x00, 0x05, 0x00, 0x00, 0x09, 0x01, - 0x33, 0x09, 0x01, 0x33, 0x02, 0x68, 0xfe, 0x2a, 0xa3, 0x01, 0x33, 0x01, - 0x33, 0xa3, 0xfe, 0xf2, 0x02, 0xba, 0xfe, 0x38, 0x01, 0xc8, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x92, 0x00, 0x00, 0x04, 0x3e, 0x03, 0x8e, 0x00, 0x03, - 0x00, 0x09, 0x00, 0x00, 0x13, 0x21, 0x15, 0x21, 0x05, 0x01, 0x23, 0x09, - 0x01, 0x23, 0x9c, 0x03, 0x99, 0xfc, 0x67, 0x01, 0xcc, 0x01, 0xd6, 0xa3, - 0xfe, 0xcd, 0xfe, 0xcd, 0xa3, 0x03, 0x8e, 0x72, 0x63, 0xfd, 0x47, 0x01, - 0xc7, 0xfe, 0x39, 0x00, 0x00, 0x03, 0x00, 0x92, 0x00, 0x00, 0x04, 0x3e, - 0x04, 0x88, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0d, 0x00, 0x00, 0x13, 0x21, - 0x15, 0x21, 0x15, 0x21, 0x15, 0x21, 0x05, 0x01, 0x23, 0x09, 0x01, 0x23, - 0x9c, 0x03, 0x99, 0xfc, 0x67, 0x03, 0x99, 0xfc, 0x67, 0x01, 0xcc, 0x01, - 0xd6, 0xa3, 0xfe, 0xcd, 0xfe, 0xcd, 0xa3, 0x04, 0x88, 0x72, 0x88, 0x72, - 0x63, 0xfd, 0x47, 0x01, 0xc7, 0xfe, 0x39, 0x00, 0x00, 0x01, 0x01, 0xcf, - 0xfe, 0xf2, 0x03, 0x77, 0x06, 0x14, 0x00, 0x05, 0x00, 0x00, 0x01, 0x21, - 0x15, 0x23, 0x11, 0x23, 0x01, 0xcf, 0x01, 0xa8, 0xf0, 0xb8, 0x06, 0x14, - 0x8f, 0xf9, 0x6d, 0x00, 0x00, 0x01, 0x01, 0x5a, 0xfe, 0xf2, 0x03, 0x02, - 0x06, 0x14, 0x00, 0x05, 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x23, 0x35, - 0x03, 0x02, 0xb8, 0xf0, 0x06, 0x14, 0xf8, 0xde, 0x06, 0x93, 0x8f, 0x00, - 0x00, 0x01, 0x01, 0xcf, 0xfe, 0xf2, 0x03, 0x77, 0x06, 0x14, 0x00, 0x05, - 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, 0x33, 0x15, 0x01, 0xcf, 0xb8, 0xf0, - 0xfe, 0xf2, 0x07, 0x22, 0xf9, 0x6d, 0x8f, 0x00, 0x00, 0x01, 0x01, 0x5a, - 0xfe, 0xf2, 0x03, 0x02, 0x06, 0x14, 0x00, 0x05, 0x00, 0x00, 0x01, 0x21, - 0x35, 0x33, 0x11, 0x33, 0x03, 0x02, 0xfe, 0x58, 0xf0, 0xb8, 0xfe, 0xf2, - 0x8f, 0x06, 0x93, 0x00, 0x00, 0x02, 0x02, 0x25, 0x00, 0x96, 0x04, 0xaf, - 0x03, 0x43, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x01, 0x21, 0x15, 0x21, - 0x07, 0x33, 0x11, 0x23, 0x02, 0xf2, 0x01, 0xbd, 0xfe, 0x43, 0xcd, 0x72, - 0x72, 0x03, 0x43, 0x72, 0x5b, 0xfe, 0x20, 0x00, 0x00, 0x02, 0x00, 0x0d, - 0x00, 0x96, 0x02, 0x97, 0x03, 0x43, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, - 0x13, 0x21, 0x15, 0x21, 0x05, 0x33, 0x11, 0x23, 0x0d, 0x01, 0xbd, 0xfe, - 0x43, 0x02, 0x18, 0x72, 0x72, 0x03, 0x43, 0x72, 0x5b, 0xfe, 0x20, 0x00, - 0x00, 0x02, 0x02, 0x25, 0x02, 0xd1, 0x04, 0xaf, 0x05, 0x7e, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x00, 0x01, 0x21, 0x15, 0x21, 0x03, 0x33, 0x11, 0x23, - 0x02, 0xf2, 0x01, 0xbd, 0xfe, 0x43, 0xcd, 0x72, 0x72, 0x03, 0x43, 0x72, - 0x02, 0xad, 0xfe, 0x20, 0x00, 0x02, 0x00, 0x0d, 0x02, 0xd1, 0x02, 0x97, - 0x05, 0x7e, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x13, 0x21, 0x15, 0x21, - 0x01, 0x33, 0x11, 0x23, 0x0d, 0x01, 0xbd, 0xfe, 0x43, 0x02, 0x18, 0x72, - 0x72, 0x03, 0x43, 0x72, 0x02, 0xad, 0xfe, 0x20, 0x00, 0x01, 0x00, 0x58, - 0x01, 0x73, 0x04, 0x79, 0x03, 0x5e, 0x00, 0x05, 0x00, 0x00, 0x01, 0x15, - 0x21, 0x11, 0x23, 0x11, 0x04, 0x79, 0xfc, 0x87, 0xa8, 0x03, 0x5e, 0xac, - 0xfe, 0xc1, 0x01, 0xeb, 0x00, 0x02, 0x00, 0x61, 0x01, 0x02, 0x04, 0x70, - 0x05, 0x12, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x00, 0x13, 0x24, 0x05, 0x02, - 0x13, 0x04, 0x25, 0x12, 0x01, 0x12, 0x03, 0x04, 0x25, 0x02, 0x13, 0x24, - 0xe7, 0x01, 0x81, 0x01, 0x81, 0x89, 0x89, 0xfe, 0x7f, 0xfe, 0x7f, 0x89, - 0xfe, 0xf1, 0xb8, 0xb8, 0x02, 0x07, 0x02, 0x08, 0xb8, 0xb8, 0xfd, 0xf8, - 0x01, 0x8a, 0x89, 0x89, 0x01, 0x80, 0x01, 0x82, 0x8a, 0x8a, 0xfe, 0x7e, - 0xfd, 0xf8, 0x01, 0xf4, 0x02, 0x1c, 0xb1, 0xb1, 0xfe, 0x0c, 0xfd, 0xe5, - 0xb1, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x06, 0x01, 0xb0, 0x04, 0xcb, - 0x04, 0x18, 0x10, 0x06, 0x0a, 0x04, 0x00, 0x9c, 0x00, 0x02, 0x00, 0x06, - 0x01, 0xb0, 0x04, 0xcb, 0x04, 0x18, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x00, - 0x13, 0x10, 0x25, 0x36, 0x20, 0x17, 0x04, 0x11, 0x25, 0x21, 0x26, 0x27, - 0x26, 0x22, 0x07, 0x06, 0x06, 0x01, 0x31, 0x98, 0x01, 0x31, 0x99, 0x01, - 0x32, 0xfb, 0xc0, 0x03, 0xbb, 0x2a, 0xc0, 0x7a, 0xf4, 0x7a, 0xc0, 0x01, - 0xb0, 0x01, 0x60, 0xb0, 0x58, 0x58, 0xb0, 0xfe, 0xa0, 0x72, 0xc5, 0x6f, - 0x47, 0x47, 0x6e, 0x00, 0x00, 0x02, 0x00, 0xb8, 0x01, 0x59, 0x04, 0x18, - 0x04, 0x18, 0x00, 0x08, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x20, 0x17, 0x16, - 0x17, 0x09, 0x01, 0x36, 0x37, 0x04, 0x22, 0x07, 0x09, 0x01, 0x01, 0xd2, - 0x01, 0x2c, 0x9b, 0x4a, 0x35, 0xfe, 0x50, 0xfe, 0x50, 0x35, 0x4a, 0x01, - 0xad, 0xf8, 0x85, 0x01, 0x02, 0x01, 0x00, 0x04, 0x18, 0x58, 0x2a, 0x37, - 0xfd, 0xfa, 0x02, 0x06, 0x37, 0x2a, 0x23, 0x4c, 0xfe, 0xc8, 0x01, 0x38, - 0x00, 0x02, 0x00, 0xa6, 0x00, 0xe5, 0x04, 0x15, 0x04, 0x50, 0x00, 0x07, - 0x00, 0x19, 0x00, 0x00, 0x00, 0x22, 0x06, 0x14, 0x16, 0x32, 0x36, 0x34, - 0x03, 0x32, 0x17, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x23, 0x22, 0x27, 0x07, - 0x27, 0x37, 0x26, 0x35, 0x34, 0x36, 0x03, 0x04, 0xc4, 0x8a, 0x87, 0xc7, - 0x8c, 0xee, 0x9e, 0x69, 0x35, 0x36, 0xd8, 0x9d, 0x7f, 0x5d, 0xcc, 0x51, - 0xcd, 0x42, 0xd6, 0x03, 0xc9, 0x89, 0xc7, 0x87, 0x89, 0xc3, 0x01, 0x12, - 0x6f, 0x33, 0x85, 0x4e, 0x98, 0xd6, 0x45, 0xcc, 0x51, 0xcc, 0x5c, 0x7c, - 0x9d, 0xd8, 0x00, 0x00, 0x00, 0x06, 0x00, 0x47, 0x00, 0xe9, 0x04, 0x8a, - 0x05, 0x2b, 0x00, 0x03, 0x00, 0x2d, 0x00, 0x37, 0x00, 0x41, 0x00, 0x4a, - 0x00, 0x54, 0x00, 0x00, 0x01, 0x33, 0x35, 0x23, 0x11, 0x15, 0x14, 0x06, - 0x22, 0x26, 0x35, 0x34, 0x36, 0x3b, 0x01, 0x35, 0x23, 0x22, 0x26, 0x34, - 0x36, 0x32, 0x16, 0x1d, 0x01, 0x33, 0x35, 0x34, 0x36, 0x32, 0x16, 0x14, - 0x06, 0x2b, 0x01, 0x15, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x22, 0x26, - 0x3d, 0x01, 0x01, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x14, 0x16, 0x33, - 0x13, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x32, 0x36, 0x35, 0x01, 0x33, - 0x32, 0x36, 0x34, 0x26, 0x22, 0x06, 0x15, 0x11, 0x15, 0x14, 0x16, 0x32, - 0x36, 0x35, 0x34, 0x26, 0x23, 0x02, 0x01, 0xcf, 0xcf, 0x82, 0xb7, 0x81, - 0x81, 0x59, 0x78, 0x78, 0x59, 0x81, 0x81, 0xb7, 0x82, 0xcf, 0x82, 0xb8, - 0x80, 0x80, 0x5a, 0x78, 0x78, 0x5a, 0x80, 0x80, 0xb8, 0x82, 0xfe, 0xc9, - 0x45, 0x31, 0x2f, 0x45, 0x45, 0x30, 0x75, 0x75, 0x30, 0x45, 0x45, 0x60, - 0x45, 0x01, 0x9f, 0x76, 0x2f, 0x45, 0x44, 0x61, 0x45, 0x45, 0x61, 0x44, - 0x45, 0x2f, 0x02, 0xa2, 0xd0, 0xfe, 0xc8, 0x77, 0x5a, 0x80, 0x81, 0x5c, - 0x5a, 0x82, 0xd0, 0x82, 0xb6, 0x81, 0x80, 0x5a, 0x77, 0x77, 0x5a, 0x80, - 0x81, 0xb6, 0x82, 0xd0, 0x82, 0x5a, 0x5c, 0x81, 0x80, 0x5a, 0x77, 0x01, - 0xa0, 0x75, 0x30, 0x45, 0x45, 0x60, 0x45, 0xfe, 0x60, 0x45, 0x2f, 0x31, - 0x45, 0x45, 0x30, 0x02, 0x15, 0x45, 0x60, 0x45, 0x45, 0x30, 0xfd, 0xeb, - 0x75, 0x30, 0x45, 0x45, 0x31, 0x2f, 0x45, 0x00, 0x00, 0x01, 0x00, 0x58, - 0x01, 0x73, 0x04, 0x79, 0x03, 0x5e, 0x00, 0x05, 0x00, 0x00, 0x01, 0x21, - 0x11, 0x33, 0x11, 0x21, 0x04, 0x79, 0xfb, 0xdf, 0xa8, 0x03, 0x79, 0x01, - 0x73, 0x01, 0xeb, 0xfe, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x2b, - 0x02, 0xd1, 0x03, 0xb5, 0x05, 0x7e, 0x00, 0x05, 0x00, 0x00, 0x01, 0x21, - 0x11, 0x23, 0x11, 0x21, 0x03, 0xb5, 0xfd, 0xe8, 0x72, 0x02, 0x8a, 0x05, - 0x0c, 0xfd, 0xc5, 0x02, 0xad, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x1c, - 0x02, 0xd1, 0x03, 0xa6, 0x05, 0x7e, 0x00, 0x05, 0x00, 0x00, 0x01, 0x35, - 0x21, 0x11, 0x23, 0x11, 0x01, 0x1c, 0x02, 0x8a, 0x72, 0x05, 0x0c, 0x72, - 0xfd, 0x53, 0x02, 0x3b, 0x00, 0x01, 0x01, 0x2b, 0xff, 0x8e, 0x03, 0xb5, - 0x02, 0x3b, 0x00, 0x05, 0x00, 0x00, 0x21, 0x15, 0x21, 0x11, 0x33, 0x11, - 0x03, 0xb5, 0xfd, 0x76, 0x72, 0x72, 0x02, 0xad, 0xfd, 0xc5, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x1c, 0xff, 0x8e, 0x03, 0xa6, 0x02, 0x3b, 0x00, 0x05, - 0x00, 0x00, 0x29, 0x01, 0x11, 0x33, 0x11, 0x21, 0x01, 0x1c, 0x02, 0x18, - 0x72, 0xfd, 0x76, 0x02, 0x3b, 0xfd, 0x53, 0x00, 0x00, 0x01, 0x02, 0x01, - 0xfe, 0x00, 0x04, 0x4c, 0x07, 0x6c, 0x00, 0x19, 0x00, 0x00, 0x01, 0x11, - 0x34, 0x37, 0x1a, 0x01, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, - 0x27, 0x26, 0x27, 0x2e, 0x01, 0x23, 0x22, 0x03, 0x02, 0x15, 0x30, 0x11, - 0x02, 0x01, 0x03, 0x0c, 0xbe, 0xca, 0x50, 0x64, 0x40, 0x37, 0x2b, 0x1c, - 0x18, 0x0f, 0x06, 0x09, 0x10, 0x68, 0x11, 0x08, 0xfe, 0x00, 0x05, 0x08, - 0x24, 0x81, 0x02, 0x03, 0x01, 0xbc, 0x54, 0x41, 0x36, 0x3f, 0x13, 0x10, - 0x26, 0x0f, 0x48, 0xfd, 0x95, 0xfe, 0xd3, 0x02, 0xfa, 0x98, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x7c, 0xfe, 0x1a, 0x02, 0xc7, 0x07, 0x89, 0x00, 0x19, - 0x00, 0x00, 0x01, 0x11, 0x14, 0x07, 0x0a, 0x01, 0x23, 0x22, 0x26, 0x35, - 0x34, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x1e, 0x01, 0x33, 0x32, 0x13, - 0x12, 0x35, 0x30, 0x11, 0x02, 0xc7, 0x03, 0x0c, 0xbe, 0xca, 0x50, 0x64, - 0x40, 0x37, 0x2b, 0x1c, 0x18, 0x0f, 0x06, 0x09, 0x10, 0x68, 0x11, 0x08, - 0x07, 0x89, 0xfa, 0xf5, 0x24, 0x81, 0xfd, 0xfd, 0xfe, 0x44, 0x54, 0x41, - 0x36, 0x3f, 0x13, 0x10, 0x26, 0x0f, 0x48, 0x02, 0x6b, 0x01, 0x2d, 0x02, - 0x05, 0x6b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x68, 0x00, 0xe9, 0x04, 0x69, - 0x04, 0xc9, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x00, 0x13, 0x21, 0x01, 0x21, - 0x15, 0x21, 0x01, 0x23, 0x25, 0x21, 0x15, 0x21, 0x68, 0x01, 0x5c, 0x01, - 0x91, 0x01, 0x14, 0xfe, 0x72, 0xfe, 0x6f, 0xe2, 0x02, 0x61, 0x01, 0xa0, - 0xfe, 0x60, 0x04, 0xc9, 0xfc, 0xde, 0xbe, 0x03, 0x22, 0xbe, 0xbe, 0x00, - 0x00, 0x05, 0x00, 0x06, 0x01, 0x28, 0x04, 0xcb, 0x04, 0x49, 0x00, 0x04, - 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x12, 0x00, 0x15, 0x00, 0x00, 0x09, 0x01, - 0x21, 0x11, 0x21, 0x09, 0x01, 0x23, 0x03, 0x13, 0x33, 0x01, 0x17, 0x37, - 0x21, 0x23, 0x11, 0x33, 0x1b, 0x01, 0x27, 0x07, 0x04, 0xcb, 0xfe, 0x51, - 0xfc, 0xea, 0x03, 0x16, 0x01, 0x05, 0xfe, 0xd3, 0x27, 0xc8, 0xc8, 0x27, - 0xfe, 0x48, 0x83, 0x83, 0xfe, 0x6f, 0x39, 0x39, 0xc8, 0xc9, 0x83, 0x83, - 0x02, 0xb9, 0xfe, 0x6f, 0x03, 0x21, 0xfe, 0x70, 0x01, 0x1e, 0xfe, 0xe1, - 0xfe, 0xe2, 0x02, 0x3d, 0xbb, 0xbb, 0xfd, 0xc3, 0x01, 0x1e, 0xfe, 0xe2, - 0xbb, 0xbb, 0x00, 0x00, 0x00, 0x05, 0x00, 0x7d, 0x01, 0x28, 0x04, 0x54, - 0x04, 0x49, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x10, 0x00, 0x13, - 0x00, 0x00, 0x01, 0x11, 0x23, 0x03, 0x13, 0x17, 0x21, 0x11, 0x21, 0x05, - 0x17, 0x37, 0x21, 0x23, 0x11, 0x33, 0x1b, 0x01, 0x27, 0x07, 0x03, 0xe2, - 0x6c, 0xc8, 0xc8, 0xde, 0xfc, 0x29, 0x03, 0xd7, 0xfd, 0x91, 0x83, 0x83, - 0xfe, 0x6f, 0x6b, 0x6b, 0xc8, 0xc9, 0x83, 0x83, 0x01, 0x9a, 0x02, 0x3d, - 0xfe, 0xe1, 0xfe, 0xe2, 0x72, 0x03, 0x21, 0x72, 0xbb, 0xbb, 0xfd, 0xc3, - 0x01, 0x1e, 0xfe, 0xe2, 0xbb, 0xbb, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x32, - 0x01, 0xb3, 0x04, 0x9f, 0x04, 0x22, 0x00, 0x0b, 0x00, 0x17, 0x00, 0x23, - 0x00, 0x2f, 0x00, 0x3b, 0x00, 0x47, 0x00, 0x53, 0x00, 0x5f, 0x00, 0x6b, - 0x00, 0x77, 0x00, 0x83, 0x00, 0x8f, 0x00, 0x9b, 0x00, 0xa7, 0x00, 0xb3, - 0x00, 0xbf, 0x00, 0xcb, 0x00, 0xd7, 0x00, 0xe3, 0x00, 0xef, 0x00, 0xfb, - 0x01, 0x07, 0x01, 0x13, 0x01, 0x1f, 0x01, 0x2b, 0x01, 0x37, 0x01, 0x43, - 0x01, 0x4f, 0x01, 0x5b, 0x01, 0x67, 0x01, 0x73, 0x01, 0x7f, 0x01, 0x8b, - 0x01, 0x97, 0x01, 0xa3, 0x01, 0xaf, 0x01, 0xbb, 0x01, 0xc7, 0x01, 0xd3, - 0x01, 0xe3, 0x01, 0xef, 0x01, 0xfb, 0x02, 0x07, 0x00, 0x00, 0x13, 0x21, - 0x32, 0x15, 0x11, 0x14, 0x23, 0x21, 0x22, 0x35, 0x11, 0x34, 0x17, 0x11, - 0x14, 0x33, 0x21, 0x32, 0x35, 0x11, 0x34, 0x23, 0x21, 0x22, 0x13, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x37, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x07, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x25, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x27, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x07, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x07, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x07, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x07, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x07, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x07, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x07, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x27, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x17, 0x15, - 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, 0x01, 0x32, 0x07, 0x32, - 0x1d, 0x01, 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x22, 0x3d, 0x01, - 0x34, 0x33, 0x13, 0x15, 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, - 0x01, 0x32, 0x17, 0x15, 0x14, 0x2b, 0x01, 0x22, 0x3d, 0x01, 0x34, 0x3b, - 0x01, 0x32, 0x05, 0x22, 0x3d, 0x01, 0x34, 0x33, 0x21, 0x32, 0x1d, 0x01, - 0x14, 0x23, 0x8e, 0x03, 0xb5, 0x5c, 0x5c, 0xfc, 0x4b, 0x5c, 0x3d, 0x1f, - 0x03, 0xb5, 0x1e, 0x1e, 0xfc, 0x4b, 0x1f, 0x6c, 0x0f, 0x1f, 0x0f, 0x0f, - 0x1f, 0x0f, 0x5d, 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x8a, 0x0f, 0x1f, - 0x10, 0x10, 0x1f, 0x0f, 0xb8, 0x10, 0x1f, 0x0f, 0x0f, 0x1f, 0x10, 0x5c, - 0x10, 0x1e, 0x10, 0x10, 0x1e, 0x10, 0xb8, 0x10, 0x1e, 0x10, 0x10, 0x1e, - 0x10, 0x5c, 0x0f, 0x1f, 0x10, 0x10, 0x1f, 0x0f, 0x5c, 0x0f, 0x1f, 0x10, - 0x10, 0x1f, 0x0f, 0x5c, 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x5d, 0x10, - 0x1f, 0x0f, 0x0f, 0x1f, 0x10, 0xa6, 0x10, 0x69, 0x0f, 0x0f, 0x69, 0x10, - 0xfc, 0xc5, 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x5c, 0x0f, 0x1f, 0x0f, - 0x0f, 0x1f, 0x0f, 0x5d, 0x10, 0x1f, 0x0f, 0x0f, 0x1f, 0x10, 0x5b, 0x0f, - 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x5d, 0x10, 0x1f, 0x0f, 0x0f, 0x1f, 0x10, - 0x5c, 0x10, 0x1f, 0x0f, 0x0f, 0x1f, 0x10, 0x5c, 0x0f, 0x1f, 0x10, 0x10, - 0x1f, 0x0f, 0x5c, 0x0f, 0x1f, 0x10, 0x10, 0x1f, 0x0f, 0x0f, 0x0f, 0x1f, - 0x10, 0x10, 0x1f, 0x0f, 0x5c, 0x0f, 0x1f, 0x10, 0x10, 0x1f, 0x0f, 0x5c, - 0x10, 0x1f, 0x0f, 0x0f, 0x1f, 0x10, 0x5c, 0x10, 0x1f, 0x0f, 0x0f, 0x1f, - 0x10, 0x5c, 0x10, 0x1e, 0x10, 0x10, 0x1e, 0x10, 0x5c, 0x10, 0x1f, 0x0f, - 0x0f, 0x1f, 0x10, 0x5d, 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x5c, 0x0f, - 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x0f, 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, - 0x5c, 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x5d, 0x10, 0x1f, 0x0f, 0x0f, - 0x1f, 0x10, 0x5c, 0x10, 0x1f, 0x0f, 0x0f, 0x1f, 0x10, 0x5c, 0x10, 0x1f, - 0x0f, 0x0f, 0x1f, 0x10, 0x5c, 0x10, 0x1f, 0x0f, 0x0f, 0x1f, 0x10, 0x5c, - 0x10, 0x1e, 0x10, 0x10, 0x1e, 0x10, 0x5c, 0x0f, 0x1f, 0x10, 0x10, 0x1f, - 0x0f, 0x5c, 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x78, 0x10, 0x3a, 0x0f, - 0x0f, 0x3a, 0x10, 0x10, 0x10, 0x10, 0x66, 0x12, 0x1e, 0x0f, 0x3e, 0x10, - 0x1f, 0x0f, 0x0f, 0x1f, 0x10, 0x5d, 0x10, 0x1f, 0x0f, 0x0f, 0x1f, 0x10, - 0xfd, 0x59, 0x0f, 0x0f, 0x01, 0xad, 0x0f, 0x0f, 0x04, 0x22, 0x5c, 0xfe, - 0x49, 0x5c, 0x5c, 0x01, 0xb7, 0x5c, 0x5c, 0xfe, 0x49, 0x1f, 0x1f, 0x01, - 0xb7, 0x1f, 0xfe, 0x60, 0x1e, 0x10, 0x10, 0x1e, 0x10, 0x0f, 0x1f, 0x10, - 0x10, 0x1f, 0x0f, 0x4c, 0x1f, 0x0f, 0x0f, 0x1f, 0x10, 0x10, 0x1f, 0x0f, - 0x0f, 0x1f, 0x10, 0x10, 0x1f, 0x0f, 0x0f, 0x1f, 0x10, 0x10, 0x1f, 0x0f, - 0x0f, 0x1f, 0x10, 0x10, 0x1f, 0x0f, 0x0f, 0x1f, 0x10, 0x10, 0x1f, 0x0f, - 0x0f, 0x1f, 0x10, 0x10, 0x1f, 0x0f, 0x0f, 0x1f, 0x10, 0x10, 0x1f, 0x0f, - 0x0f, 0x1f, 0x10, 0x10, 0x1f, 0x0f, 0x0f, 0x1f, 0x10, 0x4c, 0x1f, 0x0f, - 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, - 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, - 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, - 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x4d, 0x1f, 0x0f, - 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, - 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, - 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, - 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x0f, 0x1f, 0x0f, 0x4b, 0x1f, 0x0f, - 0x0f, 0x1f, 0x10, 0x10, 0x1f, 0x0f, 0x0f, 0x1f, 0x10, 0x10, 0x1f, 0x0f, - 0x0f, 0x1f, 0x10, 0x10, 0x1f, 0x0f, 0x0f, 0x1f, 0x10, 0x10, 0x1f, 0x0f, - 0x0f, 0x1f, 0x10, 0x10, 0x1f, 0x0f, 0x0f, 0x1f, 0x10, 0x10, 0x1f, 0x0f, - 0x0f, 0x1f, 0x10, 0x10, 0x1f, 0x0f, 0x0f, 0x1f, 0x10, 0x10, 0x1f, 0x0f, - 0x0f, 0x1f, 0x10, 0x10, 0x1f, 0x0f, 0x0f, 0x1f, 0x10, 0x5c, 0x0f, 0x79, - 0x0f, 0x0f, 0x3e, 0x0e, 0x0f, 0x1e, 0x10, 0xfe, 0xde, 0x1f, 0x10, 0x10, - 0x1f, 0x0f, 0x0f, 0x1f, 0x10, 0x10, 0x1f, 0x0f, 0x3e, 0x10, 0x1f, 0x0f, - 0x0f, 0x1f, 0x10, 0x00, 0x00, 0x05, 0x00, 0x06, 0x01, 0x28, 0x04, 0xcb, - 0x04, 0x49, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x12, 0x00, 0x15, - 0x00, 0x00, 0x13, 0x01, 0x21, 0x11, 0x21, 0x09, 0x01, 0x33, 0x13, 0x03, - 0x23, 0x29, 0x01, 0x17, 0x25, 0x03, 0x13, 0x33, 0x11, 0x01, 0x21, 0x27, - 0x06, 0x01, 0xaf, 0x03, 0x16, 0xfc, 0xea, 0xfe, 0xfb, 0x01, 0x2d, 0x27, - 0xc8, 0xc8, 0x27, 0x01, 0xb8, 0xfe, 0xfa, 0x83, 0x01, 0x0e, 0xc8, 0xc8, - 0x39, 0xfe, 0x36, 0x01, 0x06, 0x83, 0x02, 0xb9, 0x01, 0x90, 0xfc, 0xdf, - 0x01, 0x91, 0xfe, 0xe1, 0x01, 0x1e, 0x01, 0x1f, 0xbb, 0xbb, 0xfe, 0xe1, - 0xfe, 0xe2, 0x02, 0x3d, 0xfd, 0xc3, 0xbb, 0x00, 0x00, 0x01, 0x00, 0x48, - 0xff, 0xd3, 0x04, 0x88, 0x02, 0x4a, 0x00, 0x05, 0x00, 0x00, 0x05, 0x01, - 0x37, 0x09, 0x01, 0x17, 0x02, 0x68, 0xfd, 0xe0, 0x48, 0x01, 0xd8, 0x01, - 0xd8, 0x48, 0x2d, 0x02, 0x2d, 0x4a, 0xfe, 0x1c, 0x01, 0xe4, 0x4a, 0x00, - 0x00, 0x02, 0x01, 0x00, 0xff, 0x34, 0x03, 0xd1, 0x06, 0xa1, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x00, 0x05, 0x21, 0x11, 0x21, 0x03, 0x11, 0x21, 0x11, - 0x01, 0x72, 0x01, 0xed, 0xfe, 0x13, 0x72, 0x02, 0xd1, 0x5a, 0x06, 0x89, - 0xf9, 0x05, 0x07, 0x6d, 0xf8, 0x93, 0x00, 0x00, 0x00, 0x04, 0x00, 0x06, - 0xff, 0x34, 0x04, 0xcb, 0x06, 0xa1, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, - 0x00, 0x0f, 0x00, 0x00, 0x17, 0x11, 0x21, 0x11, 0x25, 0x21, 0x11, 0x21, - 0x35, 0x21, 0x35, 0x21, 0x35, 0x21, 0x11, 0x21, 0x06, 0x04, 0xc5, 0xfb, - 0xad, 0x03, 0xe1, 0xfc, 0x1f, 0x03, 0xe1, 0xfc, 0x1f, 0x03, 0xe1, 0xfc, - 0x1f, 0xcc, 0x07, 0x6d, 0xf8, 0x93, 0x72, 0x01, 0xba, 0xac, 0xec, 0xaa, - 0x02, 0x8d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0xff, 0x34, 0x04, 0xcb, - 0x06, 0xa1, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x13, - 0x00, 0x00, 0x01, 0x33, 0x15, 0x23, 0x11, 0x33, 0x15, 0x23, 0x01, 0x11, - 0x21, 0x11, 0x25, 0x21, 0x11, 0x21, 0x35, 0x21, 0x11, 0x21, 0x01, 0xee, - 0xf5, 0xf5, 0xf5, 0xf5, 0xfe, 0x18, 0x04, 0xc5, 0xfb, 0xad, 0x03, 0xe1, - 0xfc, 0x1f, 0x03, 0xe1, 0xfc, 0x1f, 0x04, 0x6f, 0xf6, 0xfe, 0x12, 0xf5, - 0xfe, 0x9e, 0x07, 0x6d, 0xf8, 0x93, 0x72, 0x02, 0x87, 0xaa, 0x03, 0x58, - 0x00, 0x04, 0x00, 0x06, 0xff, 0x34, 0x04, 0xcb, 0x06, 0xa1, 0x00, 0x03, - 0x00, 0x08, 0x00, 0x0c, 0x00, 0x11, 0x00, 0x00, 0x13, 0x09, 0x03, 0x21, - 0x11, 0x09, 0x02, 0x21, 0x11, 0x21, 0x09, 0x02, 0x11, 0x21, 0xc3, 0x01, - 0xa5, 0x01, 0xa6, 0xfe, 0x5a, 0xfe, 0x10, 0x03, 0xe1, 0xfe, 0x0f, 0xfe, - 0x10, 0x04, 0x53, 0xfb, 0x3b, 0x04, 0xc5, 0xfb, 0xad, 0x01, 0xf0, 0x01, - 0xf1, 0xfc, 0x1f, 0x02, 0xdc, 0xfe, 0x5a, 0x01, 0xa6, 0x01, 0xa6, 0xfb, - 0x24, 0x02, 0xc4, 0xfe, 0x10, 0x01, 0xf0, 0xfc, 0xca, 0x07, 0x6d, 0xfc, - 0xad, 0x01, 0xf0, 0xfe, 0x10, 0x02, 0xe1, 0x00, 0xff, 0xff, 0x00, 0x06, - 0xff, 0x34, 0x04, 0xcb, 0x06, 0xa1, 0x10, 0x26, 0x0c, 0xcf, 0x00, 0x00, - 0x10, 0x06, 0x09, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x06, - 0xff, 0x34, 0x04, 0xcb, 0x06, 0xa1, 0x00, 0x0d, 0x00, 0x18, 0x00, 0x1c, - 0x00, 0x27, 0x00, 0x00, 0x12, 0x10, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, - 0x10, 0x27, 0x26, 0x23, 0x22, 0x07, 0x03, 0x21, 0x11, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x27, 0x01, 0x21, 0x11, 0x21, 0x01, 0x36, 0x37, - 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x11, 0x21, 0x80, 0xf4, 0x7a, 0x7a, - 0x7a, 0x7a, 0xf5, 0xf5, 0x7a, 0x7a, 0x7a, 0x7a, 0xfc, 0x03, 0xe1, 0x49, - 0x77, 0x99, 0x98, 0x99, 0x98, 0x77, 0x48, 0x04, 0x53, 0xfb, 0x3b, 0x04, - 0xc5, 0xfb, 0xad, 0x48, 0x77, 0x98, 0x99, 0x98, 0x99, 0x77, 0x49, 0xfc, - 0x1f, 0x03, 0xf5, 0xfd, 0xce, 0x8d, 0x47, 0x47, 0x8d, 0x02, 0x32, 0x8d, - 0x47, 0x47, 0xfb, 0x24, 0x01, 0xca, 0x5f, 0x45, 0x58, 0x58, 0x45, 0x5e, - 0xfd, 0xc5, 0x07, 0x6d, 0xfd, 0xa8, 0x5f, 0x44, 0x58, 0x58, 0x45, 0x5f, - 0x01, 0xe7, 0x00, 0x00, 0x00, 0x03, 0x00, 0x06, 0xfe, 0xa2, 0x04, 0xcb, - 0x07, 0x33, 0x00, 0x13, 0x00, 0x1b, 0x00, 0x23, 0x00, 0x00, 0x12, 0x10, - 0x25, 0x36, 0x37, 0x11, 0x33, 0x11, 0x16, 0x17, 0x04, 0x10, 0x05, 0x06, - 0x07, 0x11, 0x23, 0x11, 0x26, 0x27, 0x02, 0x10, 0x17, 0x16, 0x17, 0x11, - 0x06, 0x07, 0x25, 0x11, 0x36, 0x37, 0x36, 0x10, 0x27, 0x26, 0x06, 0x01, - 0x31, 0x72, 0x73, 0x98, 0x72, 0x73, 0x01, 0x32, 0xfe, 0xce, 0x73, 0x72, - 0x98, 0x73, 0x72, 0xb7, 0xf4, 0x54, 0x54, 0x54, 0x54, 0x01, 0x40, 0x54, - 0x54, 0xf5, 0xf5, 0x54, 0x01, 0x7c, 0x02, 0xc0, 0xb0, 0x42, 0x11, 0x01, - 0xf4, 0xfe, 0x0c, 0x11, 0x42, 0xb0, 0xfd, 0x40, 0xb0, 0x42, 0x11, 0xfe, - 0x29, 0x01, 0xd7, 0x11, 0x42, 0x03, 0x29, 0xfd, 0xce, 0x8d, 0x31, 0x0f, - 0x03, 0xcc, 0x0f, 0x31, 0x40, 0xfc, 0x34, 0x0f, 0x31, 0x8d, 0x02, 0x32, - 0x8d, 0x31, 0x00, 0x00, 0xff, 0xff, 0x00, 0x06, 0x00, 0x74, 0x04, 0xcb, - 0x05, 0x44, 0x10, 0x26, 0x0c, 0xcf, 0x00, 0x00, 0x10, 0x07, 0x09, 0xef, - 0x00, 0x00, 0x00, 0xc8, 0x00, 0x03, 0x00, 0x06, 0xff, 0x34, 0x04, 0xcb, - 0x06, 0xa1, 0x00, 0x03, 0x00, 0x06, 0x00, 0x09, 0x00, 0x00, 0x17, 0x11, - 0x21, 0x11, 0x25, 0x01, 0x21, 0x05, 0x01, 0x21, 0x06, 0x04, 0xc5, 0xfb, - 0xad, 0x03, 0x59, 0xfc, 0xa7, 0x03, 0xe1, 0xfc, 0x9e, 0x03, 0x62, 0xcc, - 0x07, 0x6d, 0xf8, 0x93, 0xc6, 0x06, 0x35, 0x41, 0xf9, 0xb8, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x06, 0xff, 0x34, 0x04, 0xcb, 0x06, 0xa1, 0x00, 0x03, - 0x00, 0x06, 0x00, 0x09, 0x00, 0x00, 0x05, 0x21, 0x11, 0x21, 0x03, 0x11, - 0x21, 0x07, 0x11, 0x21, 0x04, 0xcb, 0xfb, 0x3b, 0x04, 0xc5, 0x72, 0xfc, - 0xa7, 0x88, 0x03, 0x62, 0xcc, 0x07, 0x6d, 0xf9, 0x59, 0x06, 0x35, 0x41, - 0xf9, 0xb8, 0x00, 0x00, 0x00, 0x04, 0x00, 0x06, 0xff, 0x34, 0x04, 0xcb, - 0x06, 0xa1, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x0e, 0x00, 0x00, - 0x17, 0x11, 0x21, 0x11, 0x25, 0x21, 0x11, 0x01, 0x35, 0x01, 0x11, 0x21, - 0x01, 0x11, 0x01, 0x06, 0x04, 0xc5, 0xfb, 0xad, 0x03, 0xe1, 0xfc, 0x1f, - 0x03, 0xe1, 0xfc, 0x1f, 0x03, 0xe1, 0xfc, 0xce, 0xcc, 0x07, 0x6d, 0xf8, - 0x93, 0x72, 0x01, 0x58, 0x01, 0x88, 0xc0, 0x01, 0x88, 0x01, 0x61, 0xfb, - 0x85, 0x02, 0x65, 0xfe, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x06, - 0xff, 0x34, 0x04, 0xcb, 0x06, 0xa1, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0a, - 0x00, 0x0e, 0x00, 0x00, 0x17, 0x11, 0x21, 0x11, 0x25, 0x21, 0x11, 0x01, - 0x19, 0x01, 0x09, 0x02, 0x11, 0x21, 0x06, 0x04, 0xc5, 0xfb, 0xad, 0x03, - 0xe1, 0xfc, 0x1f, 0x03, 0x32, 0xfc, 0xce, 0x03, 0xe1, 0xfc, 0x1f, 0xcc, - 0x07, 0x6d, 0xf8, 0x93, 0x72, 0x02, 0xe0, 0xfe, 0x78, 0x03, 0x1b, 0xfd, - 0x9b, 0x01, 0x31, 0x01, 0xe9, 0xfe, 0x78, 0x02, 0xe9, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x06, 0xff, 0x34, 0x04, 0xcb, 0x06, 0xa1, 0x00, 0x03, - 0x00, 0x0a, 0x00, 0x11, 0x00, 0x00, 0x17, 0x11, 0x21, 0x11, 0x25, 0x21, - 0x11, 0x21, 0x17, 0x07, 0x01, 0x35, 0x01, 0x17, 0x07, 0x21, 0x11, 0x21, - 0x06, 0x04, 0xc5, 0xfb, 0xad, 0x03, 0xe1, 0xfc, 0xee, 0xa0, 0x5a, 0xfe, - 0xeb, 0x01, 0x15, 0x5a, 0xa0, 0x03, 0x12, 0xfc, 0x1f, 0xcc, 0x07, 0x6d, - 0xf8, 0x93, 0x72, 0x02, 0xcf, 0xa0, 0x5a, 0x01, 0x15, 0x6e, 0x01, 0x15, - 0x5a, 0xa0, 0x03, 0x16, 0x00, 0x03, 0x00, 0x06, 0xff, 0x34, 0x04, 0xcb, - 0x06, 0xa1, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x11, 0x00, 0x00, 0x05, 0x21, - 0x11, 0x21, 0x03, 0x11, 0x01, 0x27, 0x37, 0x21, 0x11, 0x01, 0x11, 0x21, - 0x11, 0x21, 0x27, 0x37, 0x04, 0xcb, 0xfb, 0x3b, 0x04, 0xc5, 0x72, 0xfe, - 0xeb, 0x5a, 0xa0, 0xfc, 0xee, 0x03, 0xe1, 0xfc, 0x1f, 0x03, 0x12, 0xa0, - 0x5a, 0xcc, 0x07, 0x6d, 0xf9, 0x05, 0x02, 0xea, 0xfe, 0xeb, 0x5a, 0xa0, - 0xfd, 0x31, 0x03, 0x58, 0x03, 0x31, 0xfc, 0xea, 0xa0, 0x5a, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x06, 0xff, 0xc4, 0x04, 0xcb, 0x05, 0xd5, 0x00, 0x08, - 0x00, 0x1e, 0x00, 0x27, 0x00, 0x00, 0x13, 0x10, 0x17, 0x16, 0x33, 0x32, - 0x37, 0x01, 0x06, 0x01, 0x06, 0x23, 0x22, 0x27, 0x24, 0x11, 0x10, 0x25, - 0x27, 0x33, 0x17, 0x36, 0x33, 0x32, 0x17, 0x04, 0x11, 0x10, 0x05, 0x13, - 0x23, 0x09, 0x01, 0x36, 0x11, 0x10, 0x27, 0x26, 0x23, 0x22, 0x80, 0xf4, - 0x7a, 0x7a, 0x3d, 0x3e, 0xfe, 0x6c, 0xcf, 0x02, 0x96, 0x57, 0x57, 0x99, - 0x98, 0xfe, 0xcf, 0x01, 0x15, 0x73, 0xbf, 0x50, 0x59, 0x58, 0x98, 0x99, - 0x01, 0x32, 0xfe, 0xe7, 0x81, 0xbe, 0xfe, 0x76, 0x01, 0x94, 0xd2, 0xf5, - 0x7a, 0x7a, 0x3e, 0x02, 0xdc, 0xfe, 0xe7, 0x8d, 0x47, 0x12, 0x03, 0x6a, - 0x8c, 0xfc, 0xb2, 0x1d, 0x58, 0xb0, 0x01, 0x60, 0x01, 0x4f, 0xb0, 0xfa, - 0xae, 0x1d, 0x58, 0xb0, 0xfe, 0xa0, 0xfe, 0xaf, 0xb0, 0xfe, 0xe9, 0x04, - 0xf2, 0xfc, 0x95, 0x8c, 0x01, 0x05, 0x01, 0x19, 0x8d, 0x47, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x25, 0xfe, 0xa2, 0x04, 0xac, 0x07, 0x33, 0x00, 0x0b, - 0x00, 0x0e, 0x00, 0x11, 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, 0x33, 0x01, - 0x21, 0x11, 0x23, 0x11, 0x21, 0x01, 0x13, 0x11, 0x03, 0x21, 0x33, 0x03, - 0x02, 0x1c, 0x98, 0x2f, 0x01, 0xc9, 0xfe, 0x08, 0x98, 0xfe, 0x09, 0x01, - 0xc9, 0x2e, 0xf6, 0x01, 0x8e, 0xf6, 0xf6, 0x05, 0xd5, 0x01, 0x5e, 0xfe, - 0xa2, 0xfa, 0x2b, 0xfe, 0xa2, 0x01, 0x5e, 0x05, 0xd5, 0xfa, 0xd5, 0x03, - 0x6b, 0xfc, 0x95, 0x03, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x06, - 0xff, 0x34, 0x04, 0xcb, 0x06, 0xa1, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0e, - 0x00, 0x00, 0x13, 0x11, 0x09, 0x01, 0x11, 0x37, 0x11, 0x21, 0x11, 0x13, - 0x11, 0x21, 0x11, 0x01, 0x23, 0x78, 0x01, 0xf0, 0x01, 0xf1, 0x72, 0xfb, - 0x3b, 0x72, 0x03, 0xe1, 0xfe, 0x63, 0xa6, 0x06, 0x2f, 0xfe, 0xed, 0xfb, - 0xb3, 0x04, 0x4b, 0x01, 0x15, 0x72, 0xf8, 0x93, 0x07, 0x6d, 0xfc, 0xec, - 0xfc, 0x19, 0x03, 0xe5, 0xfc, 0x75, 0x00, 0x00, 0x00, 0x04, 0x00, 0x06, - 0xff, 0x34, 0x04, 0xcb, 0x06, 0xa1, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0b, - 0x00, 0x11, 0x00, 0x00, 0x25, 0x09, 0x02, 0x11, 0x21, 0x11, 0x25, 0x21, - 0x35, 0x30, 0x21, 0x35, 0x01, 0x33, 0x01, 0x11, 0x21, 0x03, 0x8a, 0xfe, - 0xde, 0xfe, 0xde, 0xfe, 0xc0, 0x04, 0xc5, 0xfb, 0xad, 0x03, 0xe1, 0xfc, - 0x1f, 0x01, 0x82, 0xdd, 0x01, 0x82, 0xfc, 0x1f, 0xaa, 0x04, 0x79, 0xfb, - 0x87, 0xfe, 0x8a, 0x07, 0x6d, 0xf8, 0x93, 0x72, 0x5a, 0x5b, 0x05, 0x7a, - 0xfa, 0x86, 0x05, 0xd4, 0x00, 0x03, 0x00, 0x06, 0xff, 0x34, 0x04, 0xcb, - 0x06, 0xa1, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x11, 0x00, 0x00, 0x13, 0x21, - 0x11, 0x21, 0x25, 0x21, 0x11, 0x21, 0x01, 0x07, 0x27, 0x03, 0x11, 0x07, - 0x27, 0x01, 0x21, 0x11, 0x06, 0x04, 0xc5, 0xfb, 0x3b, 0x02, 0xb4, 0x01, - 0x9f, 0xfe, 0x47, 0x01, 0x14, 0x5a, 0xa0, 0xa4, 0xa0, 0x5a, 0x01, 0x14, - 0xfe, 0x48, 0x06, 0xa1, 0xf8, 0x93, 0x72, 0x06, 0x89, 0xfe, 0xec, 0x5a, - 0xa0, 0xfa, 0x45, 0x05, 0xbb, 0xa0, 0x5a, 0x01, 0x14, 0xf9, 0x77, 0x00, - 0x00, 0x03, 0x00, 0x25, 0xfe, 0xa2, 0x04, 0xac, 0x07, 0x33, 0x00, 0x0b, - 0x00, 0x0e, 0x00, 0x11, 0x00, 0x00, 0x21, 0x23, 0x01, 0x21, 0x11, 0x33, - 0x11, 0x21, 0x01, 0x23, 0x11, 0x23, 0x11, 0x23, 0x1b, 0x01, 0x11, 0x13, - 0x02, 0x1c, 0x2e, 0xfe, 0x37, 0x01, 0xf7, 0x98, 0x01, 0xf8, 0xfe, 0x37, - 0x2f, 0x98, 0xf6, 0xf6, 0x98, 0xf6, 0x05, 0xd5, 0x01, 0x5e, 0xfe, 0xa2, - 0xfa, 0x2b, 0xfe, 0xa2, 0x06, 0x89, 0xfc, 0x95, 0x03, 0x6b, 0xfc, 0x95, - 0x03, 0x6b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x06, 0xff, 0x34, 0x04, 0xcb, - 0x06, 0xa1, 0x00, 0x04, 0x00, 0x08, 0x00, 0x0e, 0x00, 0x00, 0x17, 0x21, - 0x11, 0x09, 0x02, 0x21, 0x11, 0x21, 0x09, 0x01, 0x33, 0x01, 0x11, 0x21, - 0x78, 0x03, 0xe1, 0xfe, 0x0f, 0xfe, 0x10, 0x04, 0x53, 0xfb, 0x3b, 0x04, - 0xc5, 0xfb, 0xad, 0x01, 0x9e, 0xa6, 0x01, 0x9d, 0xfc, 0x1f, 0x5a, 0x01, - 0x15, 0x04, 0x4b, 0xfb, 0xb3, 0xfe, 0x7b, 0x07, 0x6d, 0xfb, 0xa7, 0x03, - 0x8d, 0xfc, 0x75, 0x03, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x06, - 0xff, 0x34, 0x04, 0xcb, 0x06, 0xa1, 0x00, 0x02, 0x00, 0x06, 0x00, 0x0c, - 0x00, 0x10, 0x00, 0x00, 0x01, 0x21, 0x09, 0x01, 0x11, 0x21, 0x11, 0x25, - 0x21, 0x11, 0x01, 0x23, 0x01, 0x35, 0x21, 0x35, 0x21, 0x03, 0x8a, 0xfd, - 0xbc, 0x01, 0x22, 0xfd, 0x9e, 0x04, 0xc5, 0xfb, 0xad, 0x03, 0xe1, 0xfe, - 0x7e, 0xdd, 0xfe, 0x7e, 0x03, 0xe1, 0xfc, 0x1f, 0x05, 0x2b, 0xfb, 0x87, - 0xfe, 0x82, 0x07, 0x6d, 0xf8, 0x93, 0x72, 0x05, 0xd4, 0xfa, 0x86, 0x05, - 0x7a, 0x5b, 0x5a, 0x00, 0x00, 0x03, 0x00, 0x06, 0xff, 0x34, 0x04, 0xcb, - 0x06, 0xa1, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x11, 0x00, 0x00, 0x17, 0x11, - 0x21, 0x11, 0x01, 0x11, 0x37, 0x17, 0x01, 0x21, 0x11, 0x29, 0x01, 0x11, - 0x21, 0x01, 0x37, 0x17, 0x06, 0x04, 0xc5, 0xfd, 0xef, 0xa0, 0x5a, 0xfe, - 0xec, 0x01, 0xb9, 0xfd, 0xbd, 0xfe, 0x62, 0x01, 0xb8, 0xfe, 0xec, 0x5a, - 0xa0, 0xcc, 0x07, 0x6d, 0xf8, 0x93, 0x06, 0xfb, 0xfa, 0x45, 0xa0, 0x5a, - 0xfe, 0xec, 0x06, 0x89, 0xf9, 0x77, 0x01, 0x14, 0x5a, 0xa0, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x00, 0xff, 0x34, 0x03, 0xd1, 0x05, 0xd5, 0x10, 0x26, - 0x0c, 0xce, 0x00, 0x00, 0x10, 0x06, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x06, 0xff, 0x34, 0x04, 0xcb, 0x05, 0xd5, 0x10, 0x26, - 0x0c, 0xcd, 0x00, 0x00, 0x10, 0x06, 0x02, 0xdd, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x06, 0xff, 0x34, 0x04, 0xcb, 0x05, 0x3f, 0x10, 0x26, - 0x0c, 0xcd, 0x00, 0x00, 0x10, 0x07, 0x09, 0xeb, 0x00, 0x00, 0x00, 0xc8, - 0xff, 0xff, 0x01, 0x00, 0xff, 0x34, 0x03, 0xd1, 0x03, 0xe9, 0x10, 0x26, - 0x0c, 0xce, 0x00, 0x00, 0x10, 0x06, 0x0c, 0xcf, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x06, 0xff, 0x34, 0x04, 0xcb, 0x05, 0x44, 0x10, 0x26, - 0x0c, 0xcd, 0x00, 0x00, 0x10, 0x07, 0x09, 0xef, 0x00, 0x00, 0x00, 0xc8, - 0xff, 0xff, 0x00, 0x06, 0xff, 0x34, 0x04, 0xcb, 0x06, 0xa1, 0x10, 0x26, - 0x00, 0x0a, 0x00, 0x00, 0x10, 0x06, 0x09, 0x0c, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x5a, 0x04, 0xe5, 0x05, 0x5e, 0x10, 0x27, - 0x0a, 0x13, 0x00, 0x00, 0x00, 0xc8, 0x10, 0x06, 0x08, 0x9b, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x06, 0xff, 0x34, 0x04, 0xcb, 0x06, 0xa1, 0x10, 0x26, - 0x00, 0x1d, 0x00, 0x00, 0x10, 0x06, 0x09, 0x0c, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x08, 0x01, 0x9b, 0x03, 0xc9, 0x05, 0x16, 0x10, 0x27, - 0x0c, 0xd0, 0x00, 0x00, 0xff, 0x06, 0x10, 0x06, 0x08, 0x9b, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x3f, 0x01, 0xd4, 0x03, 0x91, 0x05, 0x48, 0x10, 0x27, - 0x0c, 0xd0, 0x00, 0x00, 0xff, 0x38, 0x10, 0x06, 0x0c, 0xcf, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x06, 0x00, 0x74, 0x04, 0xcb, 0x06, 0xa6, 0x10, 0x27, - 0x0c, 0xd0, 0x00, 0x00, 0x00, 0x96, 0x10, 0x07, 0x09, 0xef, 0x00, 0x00, - 0x00, 0xc8, 0x00, 0x00, 0xff, 0xff, 0x00, 0x58, 0x01, 0xec, 0x04, 0x79, - 0x05, 0x48, 0x10, 0x27, 0x0c, 0xd0, 0x00, 0x00, 0xff, 0x38, 0x10, 0x06, - 0x00, 0x61, 0x00, 0x00, 0xff, 0xff, 0x00, 0x58, 0x00, 0x8d, 0x04, 0x79, - 0x05, 0x48, 0x10, 0x27, 0x0c, 0xd0, 0x00, 0x00, 0xff, 0x38, 0x10, 0x06, - 0x00, 0x21, 0x00, 0x00, 0x00, 0x03, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, - 0x05, 0xd5, 0x00, 0x0a, 0x00, 0x20, 0x00, 0x2a, 0x00, 0x00, 0x01, 0x21, - 0x13, 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x25, 0x15, 0x06, - 0x07, 0x06, 0x07, 0x03, 0x23, 0x03, 0x06, 0x07, 0x06, 0x07, 0x35, 0x36, - 0x37, 0x03, 0x21, 0x03, 0x36, 0x37, 0x36, 0x05, 0x1b, 0x01, 0x26, 0x27, - 0x26, 0x27, 0x26, 0x27, 0x26, 0x03, 0xaa, 0xfd, 0x7c, 0x7a, 0x2a, 0x28, - 0x32, 0x4a, 0x0b, 0x16, 0x45, 0x3c, 0x01, 0x69, 0x4b, 0x48, 0x23, 0x26, - 0xba, 0xf5, 0xd9, 0x17, 0x16, 0x47, 0x49, 0x4a, 0x45, 0xc2, 0x04, 0x87, - 0xd8, 0x0b, 0x0b, 0x45, 0xfd, 0xa2, 0x97, 0x7c, 0x2d, 0x32, 0x17, 0x0a, - 0x4d, 0x33, 0x0a, 0x05, 0x2b, 0xfe, 0x4f, 0x02, 0x09, 0x0b, 0x1f, 0x05, - 0x0a, 0x21, 0x0d, 0x72, 0xae, 0x3b, 0x1b, 0x0e, 0x07, 0xfd, 0x9f, 0x02, - 0xc6, 0x06, 0x0a, 0x1d, 0x3f, 0xae, 0x39, 0x1b, 0x02, 0x79, 0xfd, 0x3f, - 0x05, 0x05, 0x1e, 0x70, 0xfd, 0xe6, 0x01, 0xb8, 0x0d, 0x16, 0x0a, 0x04, - 0x21, 0x0c, 0x02, 0x00, 0x00, 0x03, 0x00, 0x58, 0xff, 0xe3, 0x04, 0x79, - 0x05, 0xf0, 0x00, 0x17, 0x00, 0x2a, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x20, - 0x17, 0x16, 0x13, 0x36, 0x37, 0x15, 0x06, 0x07, 0x02, 0x07, 0x06, 0x20, - 0x27, 0x26, 0x03, 0x06, 0x07, 0x35, 0x36, 0x37, 0x12, 0x37, 0x25, 0x22, - 0x07, 0x06, 0x07, 0x36, 0x33, 0x32, 0x16, 0x17, 0x16, 0x17, 0x16, 0x33, - 0x32, 0x37, 0x02, 0x27, 0x26, 0x01, 0x12, 0x17, 0x16, 0x33, 0x32, 0x37, - 0x36, 0x37, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x2e, 0x01, 0x23, 0x22, - 0x01, 0x79, 0x01, 0xde, 0x7b, 0x68, 0x0f, 0x18, 0x18, 0x17, 0x17, 0x09, - 0x70, 0x7b, 0xfe, 0x22, 0x7a, 0x69, 0x0f, 0x17, 0x18, 0x17, 0x17, 0x09, - 0x70, 0x01, 0x69, 0x8d, 0x45, 0x35, 0x0d, 0x1b, 0x1c, 0x35, 0x64, 0x4a, - 0x0b, 0x16, 0x74, 0x5d, 0x10, 0x11, 0x03, 0x42, 0x46, 0xfe, 0x5a, 0x03, - 0x43, 0x45, 0x8d, 0x8e, 0x46, 0x34, 0x0d, 0x16, 0x17, 0x5a, 0x71, 0x17, - 0x0a, 0x4d, 0x67, 0x33, 0x17, 0x05, 0xf0, 0xc4, 0xa7, 0xfe, 0xd0, 0x11, - 0x14, 0xae, 0x12, 0x0f, 0xfe, 0xb0, 0xb4, 0xc4, 0xc4, 0xa8, 0x01, 0x31, - 0x11, 0x15, 0xae, 0x12, 0x0f, 0x01, 0x50, 0xb3, 0x24, 0x98, 0x73, 0xce, - 0x03, 0x16, 0x1f, 0x05, 0x0a, 0x37, 0x02, 0x01, 0x25, 0x92, 0x98, 0xfd, - 0x82, 0xfe, 0xdb, 0x92, 0x98, 0x98, 0x73, 0xce, 0x02, 0x33, 0x0a, 0x04, - 0x21, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x58, 0xfe, 0xa2, 0x04, 0x79, - 0x07, 0x33, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x15, 0x0e, 0x01, 0x23, 0x22, - 0x27, 0x11, 0x23, 0x11, 0x26, 0x27, 0x26, 0x23, 0x22, 0x06, 0x07, 0x35, - 0x3e, 0x01, 0x33, 0x32, 0x17, 0x16, 0x17, 0x11, 0x33, 0x11, 0x16, 0x33, - 0x32, 0x36, 0x04, 0x79, 0x4b, 0x8f, 0x4f, 0x47, 0x55, 0x98, 0x1f, 0x19, - 0x34, 0x33, 0x4f, 0x8d, 0x49, 0x4e, 0x92, 0x53, 0x35, 0x32, 0x13, 0x17, - 0x98, 0x5e, 0x4e, 0x46, 0x89, 0x03, 0x7a, 0xae, 0x3b, 0x37, 0x20, 0xfc, - 0x28, 0x04, 0x15, 0x0b, 0x06, 0x0c, 0x3b, 0x3f, 0xae, 0x3c, 0x36, 0x0b, - 0x04, 0x07, 0x03, 0xcf, 0xfb, 0xf3, 0x27, 0x3d, 0x00, 0x02, 0x01, 0x00, - 0xfe, 0xe1, 0x03, 0xd1, 0x04, 0x27, 0x00, 0x03, 0x00, 0x11, 0x00, 0x00, - 0x01, 0x33, 0x11, 0x23, 0x13, 0x33, 0x15, 0x07, 0x21, 0x15, 0x21, 0x07, - 0x23, 0x37, 0x23, 0x35, 0x33, 0x37, 0x01, 0xe9, 0xfc, 0xfc, 0x0d, 0xfc, - 0x60, 0x01, 0x3f, 0xfe, 0x87, 0x2b, 0x9a, 0x15, 0xa8, 0xc6, 0x30, 0x04, - 0x27, 0xfe, 0xd1, 0xfe, 0x37, 0xcf, 0xba, 0x72, 0x53, 0x53, 0x72, 0xba, - 0x00, 0x03, 0x00, 0x06, 0xff, 0x34, 0x04, 0xcb, 0x06, 0xa1, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x1b, 0x00, 0x00, 0x17, 0x21, 0x11, 0x21, 0x03, 0x11, - 0x21, 0x11, 0x01, 0x21, 0x13, 0x17, 0x07, 0x33, 0x15, 0x21, 0x07, 0x21, - 0x15, 0x21, 0x03, 0x27, 0x37, 0x23, 0x35, 0x21, 0x37, 0x21, 0x78, 0x03, - 0xe1, 0xfc, 0x1f, 0x72, 0x04, 0xc5, 0xfb, 0xf7, 0x02, 0x05, 0xc5, 0x64, - 0x83, 0xa2, 0xfe, 0xf5, 0x93, 0x01, 0x9e, 0xfd, 0xfb, 0xc7, 0x64, 0x83, - 0xa0, 0x01, 0x08, 0x93, 0xfe, 0x65, 0x5a, 0x06, 0x89, 0xf9, 0x05, 0x07, - 0x6d, 0xf8, 0x93, 0x04, 0x6e, 0x01, 0x3b, 0x66, 0xd5, 0xaa, 0xec, 0xac, - 0xfe, 0xc5, 0x68, 0xd3, 0xac, 0xec, 0x00, 0x00, 0xff, 0xff, 0x00, 0x06, - 0xff, 0x34, 0x04, 0xcb, 0x06, 0xa1, 0x10, 0x26, 0x00, 0x22, 0x00, 0x00, - 0x10, 0x06, 0x09, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x36, - 0x00, 0x00, 0x03, 0xcf, 0x04, 0x60, 0x10, 0x06, 0x03, 0x01, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xbe, 0xfe, 0x56, 0x04, 0x54, 0x04, 0x7b, 0x10, 0x06, - 0x03, 0x09, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, 0xff, 0xe3, 0x04, 0x8c, - 0x04, 0x60, 0x10, 0x06, 0x03, 0x11, 0x00, 0x00, 0xff, 0xff, 0x00, 0x06, - 0xff, 0x34, 0x04, 0xcb, 0x04, 0x79, 0x10, 0x26, 0x0c, 0xcd, 0x00, 0x00, - 0x10, 0x06, 0x02, 0xf9, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x9c, - 0xff, 0x34, 0x04, 0x35, 0x04, 0x7b, 0x10, 0x26, 0x0c, 0xcc, 0x00, 0x00, - 0x10, 0x06, 0x03, 0x2e, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, - 0xff, 0x34, 0x03, 0xd1, 0x04, 0x60, 0x10, 0x26, 0x0c, 0xce, 0x00, 0x00, - 0x10, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x06, - 0xff, 0x34, 0x04, 0xcb, 0x04, 0x60, 0x10, 0x26, 0x0c, 0xcd, 0x00, 0x00, - 0x10, 0x06, 0x03, 0x11, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x46, - 0xff, 0xe7, 0x04, 0x95, 0x04, 0x79, 0x10, 0x06, 0x02, 0xf9, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x1a, 0xfe, 0x2e, 0x04, 0xb7, 0x00, 0xb5, 0x00, 0x0b, - 0x00, 0x21, 0xb7, 0x06, 0x06, 0x0a, 0x08, 0x05, 0x06, 0x01, 0x03, 0x2f, - 0xdc, 0xec, 0x2f, 0xdc, 0xec, 0x31, 0x00, 0xb7, 0x00, 0xb6, 0x06, 0x09, - 0x02, 0xb6, 0x07, 0x04, 0x2f, 0x3c, 0xec, 0x32, 0xdc, 0xec, 0x30, 0x13, - 0x11, 0x23, 0x35, 0x21, 0x11, 0x21, 0x11, 0x21, 0x15, 0x23, 0x11, 0xe1, - 0xc7, 0x01, 0x6f, 0x01, 0xbf, 0x01, 0x6f, 0xc7, 0xfe, 0x2e, 0x01, 0xda, - 0xad, 0xfe, 0x25, 0x01, 0xdb, 0xad, 0xfe, 0x26, 0x00, 0x03, 0x00, 0x48, - 0xff, 0xd3, 0x04, 0x88, 0x04, 0x3a, 0x00, 0x05, 0x00, 0x11, 0x00, 0x30, - 0x00, 0x00, 0x05, 0x01, 0x37, 0x09, 0x01, 0x17, 0x25, 0x23, 0x22, 0x06, - 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x3d, 0x01, 0x37, 0x11, 0x23, 0x35, - 0x0e, 0x01, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x3b, 0x01, 0x35, 0x34, - 0x26, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x17, 0x16, - 0x17, 0x1e, 0x01, 0x02, 0x68, 0xfd, 0xe0, 0x48, 0x01, 0xd8, 0x01, 0xd8, - 0x48, 0xfe, 0x18, 0x23, 0x5b, 0x5d, 0x45, 0x3e, 0x56, 0x63, 0x69, 0x69, - 0x21, 0x66, 0x48, 0x61, 0x74, 0x8e, 0x8a, 0x8c, 0x4c, 0x54, 0x35, 0x6d, - 0x34, 0x3a, 0x6a, 0x32, 0x4f, 0x38, 0x35, 0x25, 0x16, 0x12, 0x2d, 0x02, - 0x2d, 0x4a, 0xfe, 0x1c, 0x01, 0xe4, 0x4a, 0xf3, 0x3f, 0x3f, 0x38, 0x3f, - 0x76, 0x68, 0x17, 0x2b, 0xfe, 0x9a, 0x5d, 0x38, 0x35, 0x6c, 0x5b, 0x68, - 0x6d, 0x10, 0x4b, 0x44, 0x1e, 0x1d, 0x67, 0x15, 0x16, 0x17, 0x16, 0x2f, - 0x1c, 0x52, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0xda, 0x04, 0xcb, - 0x04, 0x3a, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x1b, - 0x00, 0x39, 0x00, 0x00, 0x01, 0x35, 0x33, 0x15, 0x33, 0x35, 0x33, 0x15, - 0x21, 0x35, 0x33, 0x15, 0x05, 0x21, 0x35, 0x21, 0x01, 0x23, 0x22, 0x06, - 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x3d, 0x01, 0x37, 0x11, 0x23, 0x35, - 0x0e, 0x01, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x3b, 0x01, 0x35, 0x34, - 0x26, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x17, - 0x1e, 0x01, 0x03, 0x61, 0x73, 0x37, 0x73, 0xfe, 0x39, 0x73, 0x01, 0xa1, - 0xfb, 0x3b, 0x04, 0xc5, 0xfc, 0xb7, 0x23, 0x5b, 0x5d, 0x45, 0x3e, 0x56, - 0x63, 0x69, 0x69, 0x21, 0x66, 0x48, 0x61, 0x74, 0x8e, 0x8a, 0x8c, 0x4c, - 0x54, 0x35, 0x6d, 0x34, 0x3a, 0x6a, 0x32, 0x4f, 0x70, 0x22, 0x16, 0x12, - 0x01, 0xb8, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0xde, 0x72, 0x01, 0xa7, - 0x3f, 0x3f, 0x38, 0x3f, 0x76, 0x68, 0x17, 0x2b, 0xfe, 0x9a, 0x5d, 0x38, - 0x35, 0x6c, 0x5b, 0x68, 0x6d, 0x10, 0x4b, 0x44, 0x1e, 0x1d, 0x67, 0x15, - 0x16, 0x2e, 0x2e, 0x1c, 0x52, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, - 0x00, 0xda, 0x04, 0xcb, 0x04, 0x3a, 0x00, 0x03, 0x00, 0x07, 0x00, 0x13, - 0x00, 0x31, 0x00, 0x3d, 0x00, 0x5b, 0x00, 0x00, 0x25, 0x35, 0x21, 0x15, - 0x21, 0x35, 0x21, 0x15, 0x03, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, - 0x32, 0x36, 0x3d, 0x01, 0x37, 0x11, 0x23, 0x35, 0x0e, 0x01, 0x23, 0x22, - 0x26, 0x35, 0x34, 0x36, 0x3b, 0x01, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, - 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x17, 0x1e, 0x01, 0x05, 0x23, - 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x37, 0x35, 0x37, 0x11, - 0x23, 0x35, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x3b, 0x01, - 0x35, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, - 0x16, 0x17, 0x1e, 0x01, 0x02, 0x9b, 0x02, 0x30, 0xfb, 0x3b, 0x02, 0x30, - 0xb4, 0x23, 0x5b, 0x5d, 0x45, 0x3e, 0x56, 0x63, 0x69, 0x69, 0x21, 0x66, - 0x48, 0x61, 0x74, 0x8e, 0x8a, 0x8c, 0x4c, 0x54, 0x35, 0x6d, 0x34, 0x3a, - 0x6a, 0x32, 0x4f, 0x70, 0x22, 0x16, 0x12, 0x01, 0x7f, 0x22, 0x5b, 0x5d, - 0x45, 0x3e, 0x56, 0x62, 0x01, 0x69, 0x69, 0x22, 0x65, 0x49, 0x61, 0x73, - 0x8e, 0x8a, 0x8c, 0x01, 0x4c, 0x53, 0x35, 0x6d, 0x34, 0x3a, 0x6a, 0x32, - 0x4f, 0x70, 0x22, 0x16, 0x12, 0xda, 0x72, 0x72, 0x72, 0x72, 0x02, 0x19, - 0x3f, 0x3f, 0x38, 0x3f, 0x76, 0x68, 0x17, 0x2b, 0xfe, 0x9a, 0x5d, 0x38, - 0x35, 0x6c, 0x5b, 0x68, 0x6d, 0x10, 0x4b, 0x44, 0x1e, 0x1d, 0x67, 0x15, - 0x16, 0x2e, 0x2e, 0x1c, 0x52, 0x7d, 0x3f, 0x3f, 0x38, 0x3f, 0x76, 0x68, - 0x17, 0x2b, 0xfe, 0x9a, 0x5d, 0x38, 0x35, 0x6c, 0x5b, 0x68, 0x6d, 0x10, - 0x4b, 0x44, 0x1e, 0x1d, 0x67, 0x15, 0x16, 0x2e, 0x2e, 0x1c, 0x52, 0x00, - 0x00, 0x08, 0x00, 0x06, 0x01, 0x6b, 0x04, 0xcb, 0x04, 0x8a, 0x00, 0x1e, - 0x00, 0x2a, 0x00, 0x2e, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3a, 0x00, 0x3e, - 0x00, 0x42, 0x00, 0x00, 0x01, 0x11, 0x23, 0x35, 0x0e, 0x01, 0x23, 0x22, - 0x26, 0x35, 0x34, 0x36, 0x3b, 0x01, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, - 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x17, 0x16, 0x17, 0x1e, 0x01, 0x07, - 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, 0x3d, 0x01, 0x01, - 0x15, 0x25, 0x3d, 0x01, 0x21, 0x15, 0x21, 0x11, 0x25, 0x15, 0x05, 0x25, - 0x15, 0x25, 0x35, 0x01, 0x15, 0x21, 0x35, 0x05, 0x15, 0x05, 0x35, 0x03, - 0x71, 0x69, 0x21, 0x66, 0x48, 0x61, 0x74, 0x8e, 0x8a, 0x8c, 0x4c, 0x54, - 0x35, 0x6d, 0x34, 0x3a, 0x6a, 0x32, 0x4f, 0x38, 0x35, 0x25, 0x16, 0x12, - 0xd1, 0x23, 0x5b, 0x5d, 0x45, 0x3e, 0x56, 0x63, 0x01, 0xca, 0xfe, 0xd4, - 0x01, 0x2c, 0xfe, 0xd4, 0x01, 0x2c, 0xfe, 0xd4, 0xfd, 0x93, 0xfe, 0xd4, - 0x01, 0x2c, 0xfe, 0xd4, 0x01, 0x2c, 0xfe, 0xd4, 0x03, 0x1e, 0xfe, 0x9a, - 0x5d, 0x38, 0x35, 0x6c, 0x5b, 0x68, 0x6d, 0x10, 0x4b, 0x44, 0x1e, 0x1d, - 0x67, 0x15, 0x16, 0x17, 0x16, 0x2f, 0x1c, 0x52, 0x7d, 0x3f, 0x3f, 0x38, - 0x3f, 0x76, 0x68, 0x17, 0xfe, 0xf1, 0x79, 0x8c, 0x79, 0xbc, 0x72, 0x01, - 0x44, 0x8c, 0x79, 0x8c, 0x79, 0x79, 0x8c, 0x79, 0xfe, 0xa2, 0x72, 0x72, - 0xbc, 0x79, 0x8c, 0x79, 0x00, 0x07, 0x00, 0x52, 0x00, 0x38, 0x04, 0x7e, - 0x04, 0xcf, 0x00, 0x34, 0x00, 0x3c, 0x00, 0x44, 0x00, 0x4c, 0x00, 0x54, - 0x00, 0x5a, 0x00, 0x60, 0x00, 0x00, 0x25, 0x23, 0x35, 0x26, 0x27, 0x26, - 0x27, 0x26, 0x27, 0x07, 0x27, 0x37, 0x26, 0x35, 0x34, 0x37, 0x35, 0x27, - 0x37, 0x17, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x35, 0x33, 0x15, 0x16, - 0x17, 0x16, 0x17, 0x16, 0x17, 0x37, 0x17, 0x07, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x15, 0x17, 0x07, 0x27, 0x06, 0x07, 0x06, 0x07, 0x06, 0x07, 0x35, - 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x27, 0x11, 0x15, 0x37, 0x26, 0x27, - 0x26, 0x27, 0x26, 0x27, 0x06, 0x07, 0x06, 0x07, 0x06, 0x07, 0x17, 0x11, - 0x35, 0x07, 0x16, 0x17, 0x16, 0x17, 0x16, 0x27, 0x37, 0x27, 0x06, 0x15, - 0x14, 0x25, 0x07, 0x17, 0x36, 0x35, 0x34, 0x02, 0x9a, 0x64, 0x33, 0x2f, - 0x44, 0x39, 0x13, 0x0f, 0xb1, 0x32, 0xb0, 0x1c, 0x1c, 0xb0, 0x32, 0xb1, - 0x10, 0x12, 0x39, 0x44, 0x2f, 0x33, 0x64, 0x34, 0x2e, 0x45, 0x39, 0x12, - 0x0f, 0xb1, 0x32, 0xb0, 0x01, 0x1c, 0x1c, 0xaf, 0x32, 0xb0, 0x10, 0x12, - 0x39, 0x45, 0x2e, 0x34, 0x1f, 0x1d, 0x32, 0x2a, 0x09, 0x07, 0xa8, 0xa8, - 0x07, 0x09, 0x2a, 0x32, 0x1d, 0x83, 0x1f, 0x1c, 0x32, 0x2a, 0x09, 0x08, - 0xa8, 0xa8, 0x08, 0x09, 0x2a, 0x32, 0x1c, 0xbc, 0xa9, 0xa9, 0x10, 0x02, - 0x2a, 0xa9, 0xa9, 0x11, 0x38, 0xcb, 0x06, 0x14, 0x1d, 0x38, 0x13, 0x13, - 0x66, 0x57, 0x66, 0x45, 0x4f, 0x50, 0x44, 0x01, 0x66, 0x57, 0x67, 0x14, - 0x13, 0x38, 0x1d, 0x14, 0x06, 0xcb, 0xcb, 0x06, 0x14, 0x1d, 0x38, 0x12, - 0x14, 0x66, 0x57, 0x65, 0x02, 0x44, 0x50, 0x4f, 0x45, 0x01, 0x65, 0x57, - 0x66, 0x14, 0x12, 0x38, 0x1d, 0x14, 0x06, 0x67, 0x05, 0x0c, 0x15, 0x2a, - 0x09, 0x09, 0x61, 0x01, 0x70, 0xc3, 0x61, 0x09, 0x09, 0x2a, 0x15, 0x0c, - 0x05, 0x05, 0x0c, 0x15, 0x2a, 0x09, 0x09, 0x61, 0xfe, 0x90, 0xc3, 0x61, - 0x09, 0x09, 0x2a, 0x15, 0x0c, 0xb3, 0x62, 0x61, 0x2e, 0x34, 0x33, 0x95, - 0x61, 0x62, 0x2d, 0x34, 0x35, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x46, - 0x00, 0x5e, 0x04, 0x8a, 0x04, 0xa2, 0x00, 0x0f, 0x00, 0x1e, 0x00, 0x27, - 0x00, 0x30, 0x00, 0x00, 0x12, 0x34, 0x3e, 0x02, 0x32, 0x1e, 0x02, 0x14, - 0x0e, 0x02, 0x22, 0x2e, 0x01, 0x13, 0x33, 0x1b, 0x01, 0x33, 0x26, 0x27, - 0x2e, 0x02, 0x22, 0x0e, 0x01, 0x07, 0x06, 0x05, 0x23, 0x03, 0x36, 0x37, - 0x3e, 0x01, 0x37, 0x36, 0x01, 0x03, 0x23, 0x16, 0x17, 0x1e, 0x01, 0x17, - 0x16, 0x46, 0x56, 0x93, 0xca, 0xde, 0xca, 0x93, 0x56, 0x56, 0x93, 0xca, - 0xde, 0xca, 0x93, 0x1c, 0xf0, 0xc0, 0xc1, 0xef, 0x07, 0x18, 0x22, 0x76, - 0xa0, 0xb2, 0xa0, 0x76, 0x22, 0x18, 0x03, 0x5a, 0xa4, 0xcf, 0x38, 0x33, - 0x50, 0x76, 0x22, 0x19, 0xfe, 0x18, 0xce, 0xa5, 0x07, 0x19, 0x22, 0x76, - 0x50, 0x33, 0x02, 0x11, 0xde, 0xca, 0x93, 0x56, 0x56, 0x93, 0xca, 0xde, - 0xca, 0x93, 0x56, 0x56, 0x93, 0x01, 0x6e, 0xfe, 0x98, 0x01, 0x68, 0x3c, - 0x38, 0x50, 0x76, 0x44, 0x44, 0x76, 0x50, 0x38, 0xa2, 0xfe, 0x82, 0x08, - 0x16, 0x22, 0x76, 0x50, 0x39, 0xfe, 0xc1, 0x01, 0x7e, 0x3f, 0x39, 0x50, - 0x76, 0x22, 0x16, 0x00, 0x00, 0x05, 0x00, 0x46, 0x00, 0x5e, 0x04, 0x8a, - 0x04, 0xa2, 0x00, 0x02, 0x00, 0x12, 0x00, 0x1c, 0x00, 0x26, 0x00, 0x30, - 0x00, 0x00, 0x01, 0x13, 0x21, 0x00, 0x34, 0x3e, 0x02, 0x32, 0x1e, 0x02, - 0x14, 0x0e, 0x02, 0x22, 0x2e, 0x01, 0x12, 0x14, 0x1e, 0x01, 0x17, 0x16, - 0x17, 0x01, 0x06, 0x07, 0x37, 0x21, 0x26, 0x27, 0x2e, 0x01, 0x22, 0x06, - 0x07, 0x06, 0x05, 0x01, 0x36, 0x37, 0x3e, 0x02, 0x34, 0x27, 0x26, 0x02, - 0x68, 0xf3, 0xfe, 0x1a, 0xfe, 0xd1, 0x56, 0x93, 0xca, 0xde, 0xca, 0x93, - 0x56, 0x56, 0x93, 0xca, 0xde, 0xca, 0x93, 0x19, 0x44, 0x76, 0x50, 0x34, - 0x37, 0xfe, 0xb4, 0x04, 0x03, 0x39, 0x02, 0xb0, 0x11, 0x13, 0x3b, 0xa0, - 0xb2, 0xa0, 0x3b, 0x13, 0x02, 0xd1, 0xfe, 0xb4, 0x37, 0x34, 0x50, 0x76, - 0x44, 0x22, 0x03, 0x01, 0x4d, 0x01, 0xc7, 0xfe, 0xfd, 0xde, 0xca, 0x93, - 0x56, 0x56, 0x93, 0xca, 0xde, 0xca, 0x93, 0x56, 0x56, 0x93, 0x01, 0x92, - 0xb2, 0xa0, 0x76, 0x22, 0x16, 0x08, 0x02, 0x69, 0x08, 0x09, 0x63, 0x15, - 0x13, 0x3b, 0x44, 0x44, 0x3b, 0x13, 0x67, 0xfd, 0x97, 0x08, 0x16, 0x22, - 0x76, 0xa0, 0xb2, 0x50, 0x09, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x46, - 0x00, 0x5e, 0x04, 0x8a, 0x04, 0xa2, 0x00, 0x02, 0x00, 0x09, 0x00, 0x25, - 0x00, 0x00, 0x01, 0x37, 0x27, 0x17, 0x01, 0x07, 0x01, 0x07, 0x03, 0x05, - 0x01, 0x33, 0x14, 0x1e, 0x02, 0x32, 0x3e, 0x02, 0x34, 0x2e, 0x02, 0x23, - 0x35, 0x32, 0x1e, 0x02, 0x14, 0x0e, 0x02, 0x22, 0x2e, 0x02, 0x01, 0x05, - 0x91, 0xae, 0xcd, 0x01, 0xee, 0x56, 0xfe, 0x12, 0x97, 0x46, 0x01, 0xca, - 0xfd, 0xfa, 0x6f, 0x44, 0x76, 0xa0, 0xb2, 0xa0, 0x76, 0x44, 0x44, 0x76, - 0xa0, 0x59, 0x6f, 0xca, 0x93, 0x56, 0x56, 0x93, 0xca, 0xde, 0xca, 0x93, - 0x56, 0x03, 0x53, 0x92, 0x1c, 0x77, 0xfe, 0x12, 0x56, 0x01, 0xee, 0x97, - 0x01, 0xca, 0x46, 0xfe, 0x5f, 0x59, 0xa0, 0x76, 0x44, 0x44, 0x76, 0xa0, - 0xb2, 0xa0, 0x76, 0x44, 0x6f, 0x56, 0x93, 0xca, 0xde, 0xca, 0x93, 0x56, - 0x56, 0x93, 0xca, 0x00, 0x00, 0x02, 0x00, 0x06, 0xff, 0x34, 0x04, 0xcb, - 0x06, 0xa1, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x17, 0x21, 0x11, 0x21, - 0x03, 0x11, 0x21, 0x11, 0x78, 0x03, 0xe1, 0xfc, 0x1f, 0x72, 0x04, 0xc5, - 0x5a, 0x06, 0x89, 0xf9, 0x05, 0x07, 0x6d, 0xf8, 0x93, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x18, 0xfd, 0xf0, 0x03, 0xb8, 0x07, 0x86, 0x00, 0x0b, - 0x00, 0x00, 0x01, 0x23, 0x35, 0x10, 0x13, 0x12, 0x13, 0x33, 0x00, 0x03, - 0x02, 0x11, 0x01, 0xdb, 0xc3, 0xa0, 0xba, 0xa6, 0xa0, 0xfe, 0xfc, 0x5a, - 0x7f, 0xfd, 0xf0, 0xea, 0x03, 0x97, 0x01, 0xe2, 0x02, 0x30, 0x01, 0x03, - 0xfd, 0xf3, 0xfe, 0x86, 0xfd, 0xee, 0xfc, 0xed, 0x00, 0x01, 0x01, 0x18, - 0xfd, 0xfc, 0x01, 0xdb, 0x07, 0x89, 0x00, 0x03, 0x00, 0x00, 0x01, 0x33, - 0x11, 0x23, 0x01, 0x18, 0xc3, 0xc3, 0x07, 0x89, 0xf6, 0x73, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x18, 0xfe, 0x14, 0x03, 0xb8, 0x07, 0x89, 0x00, 0x0b, - 0x00, 0x00, 0x01, 0x15, 0x10, 0x13, 0x12, 0x13, 0x23, 0x02, 0x03, 0x02, - 0x11, 0x35, 0x01, 0xdb, 0x7f, 0x93, 0xcb, 0xa0, 0xd0, 0x90, 0xa0, 0x07, - 0x89, 0xea, 0xfc, 0xa5, 0xfe, 0x57, 0xfe, 0x14, 0xfe, 0x65, 0x01, 0x45, - 0x01, 0xee, 0x02, 0x25, 0x03, 0x33, 0xea, 0x00, 0x00, 0x01, 0x01, 0x19, - 0xfd, 0xf0, 0x03, 0xb9, 0x07, 0x86, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x35, - 0x10, 0x03, 0x02, 0x01, 0x33, 0x12, 0x13, 0x12, 0x11, 0x15, 0x02, 0xf6, - 0x7f, 0x5a, 0xfe, 0xfc, 0xa0, 0xa6, 0xba, 0xa0, 0xfd, 0xf0, 0xea, 0x03, - 0x13, 0x02, 0x12, 0x01, 0x7a, 0x02, 0x0d, 0xfe, 0xfd, 0xfd, 0xd0, 0xfe, - 0x1e, 0xfc, 0x69, 0xea, 0x00, 0x01, 0x02, 0xf6, 0xfd, 0xfc, 0x03, 0xb9, - 0x07, 0x89, 0x00, 0x04, 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x30, 0x03, - 0xb9, 0xc3, 0x07, 0x89, 0xf6, 0x73, 0x09, 0x8d, 0x00, 0x01, 0x01, 0x19, - 0xfe, 0x14, 0x03, 0xb9, 0x07, 0x89, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x33, - 0x15, 0x10, 0x03, 0x02, 0x03, 0x23, 0x12, 0x13, 0x12, 0x11, 0x02, 0xf6, - 0xc3, 0xa0, 0x90, 0xd0, 0xa0, 0xcb, 0x93, 0x7f, 0x07, 0x89, 0xea, 0xfc, - 0xcd, 0xfd, 0xdb, 0xfe, 0x12, 0xfe, 0xbb, 0x01, 0x9b, 0x01, 0xec, 0x01, - 0xa9, 0x03, 0x5b, 0x00, 0x00, 0x01, 0x01, 0x18, 0xfd, 0xfc, 0x03, 0xb8, - 0x07, 0x6d, 0x00, 0x05, 0x00, 0x00, 0x01, 0x23, 0x11, 0x21, 0x15, 0x21, - 0x01, 0xdb, 0xc3, 0x02, 0xa0, 0xfe, 0x23, 0xfd, 0xfc, 0x09, 0x71, 0xc3, - 0x00, 0x01, 0x01, 0x18, 0xfd, 0xfc, 0x01, 0xdb, 0x07, 0x89, 0x00, 0x03, - 0x00, 0x00, 0x01, 0x33, 0x11, 0x23, 0x01, 0x18, 0xc3, 0xc3, 0x07, 0x89, - 0xf6, 0x73, 0x00, 0x00, 0x00, 0x01, 0x01, 0x18, 0xfe, 0x14, 0x03, 0xb8, - 0x07, 0x89, 0x00, 0x05, 0x00, 0x00, 0x01, 0x11, 0x21, 0x15, 0x21, 0x11, - 0x01, 0xdb, 0x01, 0xdd, 0xfd, 0x60, 0x07, 0x89, 0xf7, 0x4e, 0xc3, 0x09, - 0x75, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x18, 0xfd, 0xfc, 0x03, 0xb8, - 0x07, 0x6d, 0x00, 0x05, 0x00, 0x00, 0x01, 0x11, 0x21, 0x35, 0x21, 0x11, - 0x02, 0xf5, 0xfe, 0x23, 0x02, 0xa0, 0xfd, 0xfc, 0x08, 0xae, 0xc3, 0xf6, - 0x8f, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0xf5, 0xfd, 0xfc, 0x03, 0xb8, - 0x07, 0x7a, 0x00, 0x03, 0x00, 0x00, 0x01, 0x33, 0x11, 0x23, 0x02, 0xf5, - 0xc3, 0xc3, 0x07, 0x7a, 0xf6, 0x82, 0x00, 0x00, 0x00, 0x01, 0x01, 0x18, - 0xfe, 0x14, 0x03, 0xb8, 0x07, 0x7a, 0x00, 0x05, 0x00, 0x00, 0x01, 0x33, - 0x11, 0x21, 0x35, 0x21, 0x02, 0xf5, 0xc3, 0xfd, 0x60, 0x01, 0xdd, 0x07, - 0x7a, 0xf6, 0x9a, 0xc3, 0x00, 0x01, 0x02, 0x0c, 0xfd, 0xea, 0x04, 0xc1, - 0x07, 0x6d, 0x00, 0x0d, 0x00, 0x00, 0x01, 0x23, 0x11, 0x34, 0x37, 0x36, - 0x33, 0x21, 0x15, 0x21, 0x22, 0x07, 0x06, 0x15, 0x02, 0xc6, 0xba, 0x6f, - 0x79, 0xba, 0x01, 0x13, 0xfe, 0xe7, 0x65, 0x44, 0x39, 0xfd, 0xea, 0x07, - 0x75, 0xdf, 0x91, 0x9e, 0xb0, 0x66, 0x57, 0x99, 0x00, 0x01, 0x00, 0x11, - 0xfd, 0xfc, 0x02, 0xc6, 0x07, 0x86, 0x00, 0x18, 0x00, 0x00, 0x01, 0x16, - 0x17, 0x16, 0x19, 0x01, 0x23, 0x11, 0x10, 0x27, 0x26, 0x25, 0x27, 0x35, - 0x33, 0x20, 0x37, 0x36, 0x19, 0x01, 0x33, 0x11, 0x10, 0x07, 0x06, 0x01, - 0xfd, 0x3a, 0x2a, 0x65, 0xba, 0x6e, 0x4b, 0xfe, 0xfb, 0x3d, 0x3d, 0x01, - 0x03, 0x4d, 0x6e, 0xba, 0x65, 0x28, 0x02, 0xc1, 0x20, 0x3d, 0x93, 0xfe, - 0x43, 0xfd, 0xe8, 0x02, 0x0c, 0x01, 0xb7, 0x5f, 0x41, 0x04, 0x01, 0xbb, - 0x45, 0x63, 0x01, 0xb3, 0x02, 0x0c, 0xfd, 0xe8, 0xfe, 0x48, 0x98, 0x3c, - 0x00, 0x01, 0x02, 0x0c, 0xfe, 0x14, 0x04, 0xc1, 0x07, 0x86, 0x00, 0x0d, - 0x00, 0x00, 0x01, 0x11, 0x14, 0x17, 0x16, 0x33, 0x21, 0x15, 0x21, 0x22, - 0x27, 0x26, 0x35, 0x11, 0x02, 0xc6, 0x39, 0x44, 0x65, 0x01, 0x19, 0xfe, - 0xed, 0xb8, 0x7b, 0x6f, 0x07, 0x86, 0xf8, 0x94, 0x9a, 0x56, 0x66, 0xb0, - 0x9e, 0x8f, 0xe1, 0x07, 0x64, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x0c, - 0xfd, 0xf4, 0x02, 0xc6, 0x07, 0x8c, 0x00, 0x03, 0x00, 0x00, 0x01, 0x23, - 0x11, 0x33, 0x02, 0xc6, 0xba, 0xba, 0xfd, 0xf4, 0x09, 0x98, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x10, 0xfd, 0xea, 0x02, 0xc5, 0x07, 0x6d, 0x00, 0x0d, - 0x00, 0x00, 0x01, 0x11, 0x34, 0x27, 0x26, 0x23, 0x21, 0x35, 0x21, 0x32, - 0x17, 0x16, 0x15, 0x11, 0x02, 0x0b, 0x39, 0x44, 0x65, 0xfe, 0xe7, 0x01, - 0x13, 0xba, 0x79, 0x6f, 0xfd, 0xea, 0x07, 0x7d, 0x99, 0x57, 0x66, 0xb0, - 0x9e, 0x91, 0xdf, 0xf8, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x0b, - 0xfd, 0xfc, 0x04, 0xc0, 0x07, 0x86, 0x00, 0x18, 0x00, 0x00, 0x01, 0x26, - 0x27, 0x26, 0x19, 0x01, 0x33, 0x11, 0x10, 0x17, 0x16, 0x21, 0x33, 0x15, - 0x07, 0x04, 0x07, 0x06, 0x19, 0x01, 0x23, 0x11, 0x10, 0x37, 0x36, 0x02, - 0xd4, 0x3c, 0x28, 0x65, 0xba, 0x6e, 0x4d, 0x01, 0x03, 0x3d, 0x3d, 0xfe, - 0xfb, 0x4b, 0x6e, 0xba, 0x65, 0x2a, 0x02, 0xc1, 0x21, 0x3c, 0x98, 0x01, - 0xb8, 0x02, 0x18, 0xfd, 0xf4, 0xfe, 0x4d, 0x63, 0x45, 0xbb, 0x01, 0x04, - 0x41, 0x5f, 0xfe, 0x49, 0xfd, 0xf4, 0x02, 0x18, 0x01, 0xbd, 0x93, 0x3d, - 0x00, 0x01, 0x00, 0x10, 0xfe, 0x14, 0x02, 0xc5, 0x07, 0x86, 0x00, 0x0d, - 0x00, 0x00, 0x01, 0x33, 0x11, 0x14, 0x07, 0x06, 0x23, 0x21, 0x35, 0x21, - 0x32, 0x37, 0x36, 0x35, 0x02, 0x0b, 0xba, 0x6f, 0x7b, 0xb8, 0xfe, 0xed, - 0x01, 0x19, 0x65, 0x44, 0x39, 0x07, 0x86, 0xf8, 0x9c, 0xe1, 0x8f, 0x9e, - 0xb0, 0x66, 0x56, 0x9a, 0x00, 0x01, 0x02, 0x01, 0xfe, 0x00, 0x02, 0xc7, - 0x07, 0x89, 0x00, 0x03, 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, 0x02, 0x01, - 0xc6, 0xfe, 0x00, 0x09, 0x89, 0xf6, 0x77, 0x00, 0x00, 0x02, 0x00, 0x19, - 0x00, 0xbc, 0x04, 0x8f, 0x04, 0x76, 0x00, 0x08, 0x00, 0x11, 0x00, 0x00, - 0x25, 0x09, 0x01, 0x15, 0x21, 0x11, 0x21, 0x11, 0x21, 0x01, 0x21, 0x35, - 0x07, 0x17, 0x35, 0x21, 0x11, 0x23, 0x01, 0x8e, 0xfe, 0x8b, 0x01, 0x75, - 0x01, 0xa9, 0x01, 0x58, 0xfc, 0xff, 0x01, 0xef, 0xfd, 0xc2, 0xc2, 0xc2, - 0x03, 0x0a, 0xcc, 0xbc, 0x01, 0x75, 0x01, 0x75, 0xc9, 0x01, 0x99, 0xfd, - 0x0f, 0x01, 0x12, 0x5d, 0xc3, 0xc3, 0x5d, 0x02, 0x65, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x04, 0xcb, 0x04, 0xc4, 0x00, 0x02, - 0x00, 0x06, 0x00, 0x00, 0x01, 0x21, 0x09, 0x01, 0x21, 0x11, 0x21, 0x04, - 0xcb, 0xfb, 0x3b, 0x02, 0x62, 0x02, 0x63, 0xfb, 0x3b, 0x04, 0xc5, 0x02, - 0xa0, 0x02, 0x24, 0xfb, 0x3c, 0x01, 0xf8, 0x00, 0x00, 0x01, 0x00, 0x96, - 0xfe, 0x2e, 0x04, 0x3a, 0x00, 0xb5, 0x00, 0x07, 0x00, 0x1c, 0xb7, 0x04, - 0x06, 0x06, 0x09, 0x03, 0x06, 0x01, 0x08, 0x10, 0xdc, 0xec, 0x10, 0xdc, - 0xec, 0x31, 0x00, 0xb4, 0x00, 0xb6, 0x04, 0x06, 0x02, 0x2f, 0x3c, 0xdc, - 0xec, 0x30, 0x13, 0x11, 0x33, 0x11, 0x21, 0x11, 0x33, 0x11, 0x96, 0xa8, - 0x02, 0x54, 0xa8, 0xfe, 0x2e, 0x02, 0x87, 0xfe, 0x25, 0x01, 0xdb, 0xfd, - 0x79, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, 0x01, 0xf0, 0x04, 0xe5, - 0x02, 0x9c, 0x00, 0x03, 0x00, 0x00, 0x03, 0x35, 0x21, 0x15, 0x14, 0x04, - 0xf9, 0x01, 0xf0, 0xac, 0xac, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, - 0x01, 0x9a, 0x04, 0xe5, 0x02, 0xf2, 0x00, 0x03, 0x00, 0x00, 0x03, 0x11, - 0x21, 0x11, 0x14, 0x04, 0xf9, 0x01, 0x9a, 0x01, 0x58, 0xfe, 0xa8, 0x00, - 0x00, 0x01, 0x02, 0x18, 0xfd, 0x96, 0x02, 0xb8, 0x07, 0xc8, 0x00, 0x03, - 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, 0x02, 0x18, 0xa0, 0xfd, 0x96, 0x0a, - 0x32, 0xf5, 0xce, 0x00, 0x00, 0x01, 0x01, 0xc8, 0xfd, 0x96, 0x03, 0x08, - 0x07, 0xc8, 0x00, 0x03, 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x01, 0xc8, - 0x01, 0x40, 0xfd, 0x96, 0x0a, 0x32, 0xf5, 0xce, 0x00, 0x03, 0xff, 0xec, - 0x01, 0xf0, 0x04, 0xe5, 0x02, 0x9c, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, - 0x00, 0x00, 0x01, 0x35, 0x21, 0x15, 0x21, 0x35, 0x21, 0x15, 0x21, 0x35, - 0x21, 0x15, 0x03, 0xb1, 0x01, 0x34, 0xfc, 0xef, 0x01, 0x29, 0xfc, 0xef, - 0x01, 0x34, 0x01, 0xf0, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0x00, 0x00, - 0x00, 0x03, 0xff, 0xec, 0x01, 0x9a, 0x04, 0xe5, 0x02, 0xf2, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x21, 0x11, - 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x03, 0xb1, 0x01, 0x34, 0xfc, 0xef, - 0x01, 0x29, 0xfc, 0xef, 0x01, 0x34, 0x01, 0x9a, 0x01, 0x58, 0xfe, 0xa8, - 0x01, 0x58, 0xfe, 0xa8, 0x01, 0x58, 0xfe, 0xa8, 0x00, 0x03, 0x02, 0x18, - 0xfd, 0x96, 0x02, 0xb8, 0x07, 0xc8, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, - 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, 0x03, 0x11, 0x33, 0x11, 0x03, 0x11, - 0x33, 0x11, 0x02, 0x18, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xfd, 0x96, 0x03, - 0x0c, 0xfc, 0xf4, 0x03, 0xc0, 0x02, 0xb2, 0xfd, 0x4e, 0x03, 0x66, 0x03, - 0x0c, 0xfc, 0xf4, 0x00, 0x00, 0x03, 0x01, 0xc8, 0xfd, 0x96, 0x03, 0x08, - 0x07, 0xc8, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x11, 0x01, 0x11, 0x21, 0x11, 0x01, 0x11, 0x21, 0x11, 0x01, 0xc8, - 0x01, 0x40, 0xfe, 0xc0, 0x01, 0x40, 0xfe, 0xc0, 0x01, 0x40, 0xfd, 0x96, - 0x03, 0x0c, 0xfc, 0xf4, 0x03, 0xc0, 0x02, 0xb2, 0xfd, 0x4e, 0x03, 0x66, - 0x03, 0x0c, 0xfc, 0xf4, 0x00, 0x04, 0xff, 0xeb, 0x01, 0xf0, 0x04, 0xe5, - 0x02, 0x9c, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x00, - 0x03, 0x35, 0x33, 0x15, 0x33, 0x35, 0x33, 0x15, 0x33, 0x35, 0x33, 0x15, - 0x33, 0x35, 0x33, 0x15, 0x15, 0xbc, 0xb4, 0xb3, 0xb4, 0xb2, 0xb4, 0xbd, - 0x01, 0xf0, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0x00, 0x00, - 0x00, 0x04, 0xff, 0xec, 0x01, 0x9a, 0x04, 0xe6, 0x02, 0xf2, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x00, 0x03, 0x11, 0x33, 0x11, - 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, - 0x14, 0xbc, 0xb4, 0xb3, 0xb4, 0xb2, 0xb4, 0xbd, 0x01, 0x9a, 0x01, 0x58, - 0xfe, 0xa8, 0x01, 0x58, 0xfe, 0xa8, 0x01, 0x58, 0xfe, 0xa8, 0x01, 0x58, - 0xfe, 0xa8, 0x00, 0x00, 0x00, 0x04, 0x02, 0x18, 0xfd, 0x96, 0x02, 0xb8, - 0x07, 0xc8, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x00, - 0x01, 0x11, 0x33, 0x11, 0x03, 0x11, 0x33, 0x11, 0x03, 0x11, 0x33, 0x11, - 0x03, 0x11, 0x33, 0x11, 0x02, 0x18, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, - 0xa0, 0x05, 0x96, 0x02, 0x32, 0xfd, 0xce, 0xf8, 0x00, 0x02, 0x32, 0xfd, - 0xce, 0x05, 0x73, 0x01, 0xd9, 0xfe, 0x27, 0xfd, 0x73, 0x01, 0xd9, 0xfe, - 0x27, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0xc8, 0xfd, 0x96, 0x03, 0x08, - 0x07, 0xc8, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x00, - 0x01, 0x11, 0x21, 0x11, 0x01, 0x11, 0x21, 0x11, 0x01, 0x11, 0x21, 0x11, - 0x01, 0x11, 0x21, 0x11, 0x01, 0xc8, 0x01, 0x40, 0xfe, 0xc0, 0x01, 0x40, - 0xfe, 0xc0, 0x01, 0x40, 0xfe, 0xc0, 0x01, 0x40, 0x05, 0x96, 0x02, 0x32, - 0xfd, 0xce, 0xf8, 0x00, 0x02, 0x32, 0xfd, 0xce, 0x05, 0x73, 0x01, 0xd9, - 0xfe, 0x27, 0xfd, 0x73, 0x01, 0xd9, 0xfe, 0x27, 0x00, 0x01, 0x02, 0x18, - 0xfd, 0x96, 0x04, 0xe5, 0x02, 0x9c, 0x00, 0x05, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x15, 0x21, 0x11, 0x02, 0x18, 0x02, 0xcd, 0xfd, 0xd3, 0xfd, 0x96, - 0x05, 0x06, 0xac, 0xfb, 0xa6, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x18, - 0xfd, 0x96, 0x04, 0xe5, 0x02, 0xf2, 0x00, 0x05, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x11, 0x21, 0x11, 0x02, 0x18, 0x02, 0xcd, 0xfd, 0xd3, 0xfd, 0x96, - 0x05, 0x5c, 0xfe, 0xa8, 0xfb, 0xfc, 0x00, 0x00, 0x00, 0x01, 0x01, 0xc8, - 0xfd, 0x96, 0x04, 0xe5, 0x02, 0x9c, 0x00, 0x05, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x15, 0x21, 0x11, 0x01, 0xc8, 0x03, 0x1d, 0xfe, 0x23, 0xfd, 0x96, - 0x05, 0x06, 0xac, 0xfb, 0xa6, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0xc8, - 0xfd, 0x96, 0x04, 0xe5, 0x02, 0xf2, 0x00, 0x05, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x11, 0x21, 0x11, 0x01, 0xc8, 0x03, 0x1d, 0xfe, 0x23, 0xfd, 0x96, - 0x05, 0x5c, 0xfe, 0xa8, 0xfb, 0xfc, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, - 0xfd, 0x96, 0x02, 0xb8, 0x02, 0x9c, 0x00, 0x05, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x35, 0x21, 0x11, 0x02, 0x18, 0xfd, 0xd4, 0x02, 0xcc, 0xfd, 0x96, - 0x04, 0x5a, 0xac, 0xfa, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, - 0xfd, 0x96, 0x02, 0xb8, 0x02, 0xf2, 0x00, 0x05, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x11, 0x21, 0x11, 0x02, 0x18, 0xfd, 0xd4, 0x02, 0xcc, 0xfd, 0x96, - 0x04, 0x04, 0x01, 0x58, 0xfa, 0xa4, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, - 0xfd, 0x96, 0x03, 0x08, 0x02, 0x9c, 0x00, 0x05, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x35, 0x21, 0x11, 0x01, 0xc8, 0xfe, 0x24, 0x03, 0x1c, 0xfd, 0x96, - 0x04, 0x5a, 0xac, 0xfa, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, - 0xfd, 0x96, 0x03, 0x08, 0x02, 0xf2, 0x00, 0x05, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x11, 0x21, 0x11, 0x01, 0xc8, 0xfe, 0x24, 0x03, 0x1c, 0xfd, 0x96, - 0x04, 0x04, 0x01, 0x58, 0xfa, 0xa4, 0x00, 0x00, 0x00, 0x01, 0x02, 0x18, - 0x01, 0xf0, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x05, 0x00, 0x00, 0x01, 0x11, - 0x33, 0x11, 0x21, 0x15, 0x02, 0x18, 0xa0, 0x02, 0x2d, 0x01, 0xf0, 0x05, - 0xd8, 0xfa, 0xd4, 0xac, 0x00, 0x01, 0x02, 0x18, 0x01, 0x9a, 0x04, 0xe5, - 0x07, 0xc8, 0x00, 0x05, 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, 0x21, 0x11, - 0x02, 0x18, 0xa0, 0x02, 0x2d, 0x01, 0x9a, 0x06, 0x2e, 0xfb, 0x2a, 0xfe, - 0xa8, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0xc8, 0x01, 0xf0, 0x04, 0xe5, - 0x07, 0xc8, 0x00, 0x05, 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x21, 0x15, - 0x01, 0xc8, 0x01, 0x40, 0x01, 0xdd, 0x01, 0xf0, 0x05, 0xd8, 0xfa, 0xd4, - 0xac, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0xc8, 0x01, 0x9a, 0x04, 0xe5, - 0x07, 0xc8, 0x00, 0x05, 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x21, 0x11, - 0x01, 0xc8, 0x01, 0x40, 0x01, 0xdd, 0x01, 0x9a, 0x06, 0x2e, 0xfb, 0x2a, - 0xfe, 0xa8, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, 0x01, 0xf0, 0x02, 0xb8, - 0x07, 0xc8, 0x00, 0x05, 0x00, 0x00, 0x03, 0x35, 0x21, 0x11, 0x33, 0x11, - 0x14, 0x02, 0x2c, 0xa0, 0x01, 0xf0, 0xac, 0x05, 0x2c, 0xfa, 0x28, 0x00, - 0x00, 0x01, 0xff, 0xec, 0x01, 0x9a, 0x02, 0xb8, 0x07, 0xc8, 0x00, 0x05, - 0x00, 0x00, 0x03, 0x11, 0x21, 0x11, 0x33, 0x11, 0x14, 0x02, 0x2c, 0xa0, - 0x01, 0x9a, 0x01, 0x58, 0x04, 0xd6, 0xf9, 0xd2, 0x00, 0x01, 0xff, 0xec, - 0x01, 0xf0, 0x03, 0x08, 0x07, 0xc8, 0x00, 0x05, 0x00, 0x00, 0x03, 0x35, - 0x21, 0x11, 0x21, 0x11, 0x14, 0x01, 0xdc, 0x01, 0x40, 0x01, 0xf0, 0xac, - 0x05, 0x2c, 0xfa, 0x28, 0x00, 0x01, 0xff, 0xec, 0x01, 0x9a, 0x03, 0x08, - 0x07, 0xc8, 0x00, 0x05, 0x00, 0x00, 0x03, 0x11, 0x21, 0x11, 0x21, 0x11, - 0x14, 0x01, 0xdc, 0x01, 0x40, 0x01, 0x9a, 0x01, 0x58, 0x04, 0xd6, 0xf9, - 0xd2, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x18, 0xfd, 0x96, 0x04, 0xe5, - 0x07, 0xc8, 0x00, 0x07, 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, 0x21, 0x15, - 0x21, 0x11, 0x02, 0x18, 0xa0, 0x02, 0x2d, 0xfd, 0xd3, 0xfd, 0x96, 0x0a, - 0x32, 0xfa, 0xd4, 0xac, 0xfb, 0xa6, 0x00, 0x00, 0x00, 0x01, 0x02, 0x18, - 0xfd, 0x96, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x07, 0x00, 0x00, 0x01, 0x11, - 0x33, 0x11, 0x21, 0x11, 0x21, 0x11, 0x02, 0x18, 0xa0, 0x02, 0x2d, 0xfd, - 0xd3, 0xfd, 0x96, 0x0a, 0x32, 0xfb, 0x2a, 0xfe, 0xa8, 0xfb, 0xfc, 0x00, - 0x00, 0x01, 0x01, 0xc8, 0xfd, 0x96, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x09, - 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x21, 0x11, 0x21, 0x15, 0x21, 0x11, - 0x02, 0x18, 0x50, 0x01, 0x40, 0x01, 0xdd, 0xfd, 0xd3, 0xfd, 0x96, 0x04, - 0x5a, 0x05, 0xd8, 0xfa, 0xd4, 0xac, 0xfb, 0xa6, 0x00, 0x01, 0x01, 0xc8, - 0xfd, 0x96, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x09, 0x00, 0x00, 0x01, 0x11, - 0x33, 0x11, 0x33, 0x11, 0x21, 0x15, 0x21, 0x11, 0x01, 0xc8, 0x50, 0xa0, - 0x02, 0x2d, 0xfe, 0x23, 0xfd, 0x96, 0x05, 0x06, 0x05, 0x2c, 0xfa, 0xd4, - 0xac, 0xfb, 0xa6, 0x00, 0x00, 0x01, 0x01, 0xc8, 0xfd, 0x96, 0x04, 0xe5, - 0x07, 0xc8, 0x00, 0x07, 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x21, 0x15, - 0x21, 0x11, 0x01, 0xc8, 0x01, 0x40, 0x01, 0xdd, 0xfe, 0x23, 0xfd, 0x96, - 0x0a, 0x32, 0xfa, 0xd4, 0xac, 0xfb, 0xa6, 0x00, 0x00, 0x01, 0x01, 0xc8, - 0xfd, 0x96, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x09, 0x00, 0x00, 0x01, 0x11, - 0x23, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x02, 0x18, 0x50, 0x01, - 0x40, 0x01, 0xdd, 0xfd, 0xd3, 0xfd, 0x96, 0x04, 0x04, 0x06, 0x2e, 0xfb, - 0x2a, 0xfe, 0xa8, 0xfb, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0xc8, - 0xfd, 0x96, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x09, 0x00, 0x00, 0x01, 0x11, - 0x33, 0x11, 0x33, 0x11, 0x21, 0x11, 0x21, 0x11, 0x01, 0xc8, 0x50, 0xa0, - 0x02, 0x2d, 0xfe, 0x23, 0xfd, 0x96, 0x05, 0x5c, 0x04, 0xd6, 0xfb, 0x2a, - 0xfe, 0xa8, 0xfb, 0xfc, 0x00, 0x01, 0x01, 0xc8, 0xfd, 0x96, 0x04, 0xe5, - 0x07, 0xc8, 0x00, 0x07, 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x21, 0x11, - 0x21, 0x11, 0x01, 0xc8, 0x01, 0x40, 0x01, 0xdd, 0xfe, 0x23, 0xfd, 0x96, - 0x0a, 0x32, 0xfb, 0x2a, 0xfe, 0xa8, 0xfb, 0xfc, 0x00, 0x01, 0xff, 0xec, - 0xfd, 0x96, 0x02, 0xb8, 0x07, 0xc8, 0x00, 0x07, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x35, 0x21, 0x11, 0x33, 0x11, 0x02, 0x18, 0xfd, 0xd4, 0x02, 0x2c, - 0xa0, 0xfd, 0x96, 0x04, 0x5a, 0xac, 0x05, 0x2c, 0xf5, 0xce, 0x00, 0x00, - 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x02, 0xb8, 0x07, 0xc8, 0x00, 0x07, - 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x21, 0x11, 0x33, 0x11, 0x02, 0x18, - 0xfd, 0xd4, 0x02, 0x2c, 0xa0, 0xfd, 0x96, 0x04, 0x04, 0x01, 0x58, 0x04, - 0xd6, 0xf5, 0xce, 0x00, 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x03, 0x08, - 0x07, 0xc8, 0x00, 0x09, 0x00, 0x00, 0x01, 0x11, 0x21, 0x35, 0x21, 0x11, - 0x21, 0x11, 0x23, 0x11, 0x02, 0x18, 0xfd, 0xd4, 0x01, 0xdc, 0x01, 0x40, - 0x50, 0xfd, 0x96, 0x04, 0x5a, 0xac, 0x05, 0x2c, 0xfa, 0x28, 0xfb, 0xa6, - 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x03, 0x08, 0x07, 0xc8, 0x00, 0x09, - 0x00, 0x00, 0x01, 0x11, 0x21, 0x35, 0x21, 0x11, 0x33, 0x11, 0x33, 0x11, - 0x01, 0xc8, 0xfe, 0x24, 0x02, 0x2c, 0xa0, 0x50, 0xfd, 0x96, 0x04, 0x5a, - 0xac, 0x05, 0x2c, 0xfa, 0xd4, 0xfa, 0xfa, 0x00, 0x00, 0x01, 0xff, 0xec, - 0xfd, 0x96, 0x03, 0x08, 0x07, 0xc8, 0x00, 0x07, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x35, 0x21, 0x11, 0x21, 0x11, 0x01, 0xc8, 0xfe, 0x24, 0x01, 0xdc, - 0x01, 0x40, 0xfd, 0x96, 0x04, 0x5a, 0xac, 0x05, 0x2c, 0xf5, 0xce, 0x00, - 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x03, 0x08, 0x07, 0xc8, 0x00, 0x09, - 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x23, 0x11, - 0x02, 0x18, 0xfd, 0xd4, 0x01, 0xdc, 0x01, 0x40, 0x50, 0xfd, 0x96, 0x04, - 0x04, 0x01, 0x58, 0x04, 0xd6, 0xf9, 0xd2, 0xfb, 0xfc, 0x00, 0x00, 0x00, - 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x03, 0x08, 0x07, 0xc8, 0x00, 0x09, - 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x21, 0x11, 0x33, 0x11, 0x33, 0x11, - 0x01, 0xc8, 0xfe, 0x24, 0x02, 0x2c, 0xa0, 0x50, 0xfd, 0x96, 0x04, 0x04, - 0x01, 0x58, 0x04, 0xd6, 0xfb, 0x2a, 0xfa, 0xa4, 0x00, 0x01, 0xff, 0xec, - 0xfd, 0x96, 0x03, 0x08, 0x07, 0xc8, 0x00, 0x07, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x01, 0xc8, 0xfe, 0x24, 0x01, 0xdc, - 0x01, 0x40, 0xfd, 0x96, 0x04, 0x04, 0x01, 0x58, 0x04, 0xd6, 0xf5, 0xce, - 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x04, 0xe5, 0x02, 0x9c, 0x00, 0x07, - 0x00, 0x00, 0x01, 0x11, 0x21, 0x35, 0x21, 0x15, 0x21, 0x11, 0x02, 0x18, - 0xfd, 0xd4, 0x04, 0xf9, 0xfd, 0xd3, 0xfd, 0x96, 0x04, 0x5a, 0xac, 0xac, - 0xfb, 0xa6, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x04, 0xe5, - 0x02, 0xf2, 0x00, 0x09, 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x21, 0x15, - 0x21, 0x15, 0x21, 0x11, 0x02, 0x18, 0xfd, 0xd4, 0x02, 0xcc, 0x02, 0x2d, - 0xfd, 0xd3, 0xfd, 0x96, 0x04, 0x04, 0x01, 0x58, 0x56, 0xac, 0xfb, 0xa6, - 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x04, 0xe5, 0x02, 0xf2, 0x00, 0x09, - 0x00, 0x00, 0x01, 0x11, 0x21, 0x35, 0x21, 0x35, 0x21, 0x11, 0x21, 0x11, - 0x02, 0x18, 0xfd, 0xd4, 0x02, 0x2c, 0x02, 0xcd, 0xfd, 0xd3, 0xfd, 0x96, - 0x04, 0x5a, 0xac, 0x56, 0xfe, 0xa8, 0xfb, 0xfc, 0x00, 0x01, 0xff, 0xec, - 0xfd, 0x96, 0x04, 0xe5, 0x02, 0xf2, 0x00, 0x07, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x02, 0x18, 0xfd, 0xd4, 0x04, 0xf9, - 0xfd, 0xd3, 0xfd, 0x96, 0x04, 0x04, 0x01, 0x58, 0xfe, 0xa8, 0xfb, 0xfc, - 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x04, 0xe5, 0x02, 0x9c, 0x00, 0x07, - 0x00, 0x00, 0x01, 0x11, 0x21, 0x35, 0x21, 0x15, 0x21, 0x11, 0x01, 0xc8, - 0xfe, 0x24, 0x04, 0xf9, 0xfe, 0x23, 0xfd, 0x96, 0x04, 0x5a, 0xac, 0xac, - 0xfb, 0xa6, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x04, 0xe5, - 0x02, 0xf2, 0x00, 0x09, 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x21, 0x15, - 0x21, 0x15, 0x21, 0x11, 0x01, 0xc8, 0xfe, 0x24, 0x03, 0x1c, 0x01, 0xdd, - 0xfe, 0x23, 0xfd, 0x96, 0x04, 0x04, 0x01, 0x58, 0x56, 0xac, 0xfb, 0xa6, - 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x04, 0xe5, 0x02, 0xf2, 0x00, 0x09, - 0x00, 0x00, 0x01, 0x11, 0x21, 0x35, 0x21, 0x35, 0x21, 0x11, 0x21, 0x11, - 0x01, 0xc8, 0xfe, 0x24, 0x01, 0xdc, 0x03, 0x1d, 0xfe, 0x23, 0xfd, 0x96, - 0x04, 0x5a, 0xac, 0x56, 0xfe, 0xa8, 0xfb, 0xfc, 0x00, 0x01, 0xff, 0xec, - 0xfd, 0x96, 0x04, 0xe5, 0x02, 0xf2, 0x00, 0x07, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x01, 0xc8, 0xfe, 0x24, 0x04, 0xf9, - 0xfe, 0x23, 0xfd, 0x96, 0x04, 0x04, 0x01, 0x58, 0xfe, 0xa8, 0xfb, 0xfc, - 0x00, 0x01, 0xff, 0xec, 0x01, 0xf0, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x07, - 0x00, 0x00, 0x03, 0x35, 0x21, 0x11, 0x33, 0x11, 0x21, 0x15, 0x14, 0x02, - 0x2c, 0xa0, 0x02, 0x2d, 0x01, 0xf0, 0xac, 0x05, 0x2c, 0xfa, 0xd4, 0xac, - 0x00, 0x01, 0xff, 0xec, 0x01, 0x9a, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x09, - 0x00, 0x00, 0x03, 0x11, 0x21, 0x11, 0x33, 0x11, 0x21, 0x15, 0x21, 0x15, - 0x14, 0x02, 0x2c, 0xa0, 0x02, 0x2d, 0xfd, 0xd3, 0x01, 0x9a, 0x01, 0x58, - 0x04, 0xd6, 0xfa, 0xd4, 0xac, 0x56, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, - 0x01, 0x9a, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x09, 0x00, 0x00, 0x03, 0x35, - 0x21, 0x11, 0x33, 0x11, 0x21, 0x11, 0x21, 0x35, 0x14, 0x02, 0x2c, 0xa0, - 0x02, 0x2d, 0xfd, 0x33, 0x01, 0xf0, 0xac, 0x05, 0x2c, 0xfb, 0x2a, 0xfe, - 0xa8, 0x56, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, 0x01, 0x9a, 0x04, 0xe5, - 0x07, 0xc8, 0x00, 0x07, 0x00, 0x00, 0x03, 0x11, 0x21, 0x11, 0x33, 0x11, - 0x21, 0x11, 0x14, 0x02, 0x2c, 0xa0, 0x02, 0x2d, 0x01, 0x9a, 0x01, 0x58, - 0x04, 0xd6, 0xfb, 0x2a, 0xfe, 0xa8, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, - 0x01, 0xf0, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x07, 0x00, 0x00, 0x03, 0x35, - 0x21, 0x11, 0x21, 0x11, 0x21, 0x15, 0x14, 0x01, 0xdc, 0x01, 0x40, 0x01, - 0xdd, 0x01, 0xf0, 0xac, 0x05, 0x2c, 0xfa, 0xd4, 0xac, 0x00, 0x00, 0x00, - 0x00, 0x01, 0xff, 0xec, 0x01, 0x9a, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x09, - 0x00, 0x00, 0x03, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, 0x15, 0x21, 0x15, - 0x14, 0x01, 0xdc, 0x01, 0x40, 0x01, 0xdd, 0xfe, 0x23, 0x01, 0x9a, 0x01, - 0x58, 0x04, 0xd6, 0xfa, 0xd4, 0xac, 0x56, 0x00, 0x00, 0x01, 0xff, 0xec, - 0x01, 0x9a, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x09, 0x00, 0x00, 0x03, 0x35, - 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, 0x35, 0x14, 0x01, 0xdc, 0x01, - 0x40, 0x01, 0xdd, 0xfc, 0xe3, 0x01, 0xf0, 0xac, 0x05, 0x2c, 0xfb, 0x2a, - 0xfe, 0xa8, 0x56, 0x00, 0x00, 0x01, 0xff, 0xec, 0x01, 0x9a, 0x04, 0xe5, - 0x07, 0xc8, 0x00, 0x07, 0x00, 0x00, 0x03, 0x11, 0x21, 0x11, 0x21, 0x11, - 0x21, 0x11, 0x14, 0x01, 0xdc, 0x01, 0x40, 0x01, 0xdd, 0x01, 0x9a, 0x01, - 0x58, 0x04, 0xd6, 0xfb, 0x2a, 0xfe, 0xa8, 0x00, 0x00, 0x01, 0xff, 0xec, - 0xfd, 0x96, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, - 0x23, 0x11, 0x21, 0x35, 0x21, 0x11, 0x33, 0x11, 0x21, 0x15, 0x02, 0xb8, - 0xa0, 0xfd, 0xd4, 0x02, 0x2c, 0xa0, 0x02, 0x2d, 0x01, 0xf0, 0xfb, 0xa6, - 0x04, 0x5a, 0xac, 0x05, 0x2c, 0xfa, 0xd4, 0xac, 0x00, 0x01, 0xff, 0xec, - 0xfd, 0x96, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x11, 0x21, 0x11, 0x33, 0x11, 0x21, 0x15, 0x21, 0x11, 0x02, 0x18, - 0xfd, 0xd4, 0x02, 0x2c, 0xa0, 0x02, 0x2d, 0xfd, 0xd3, 0xfd, 0x96, 0x04, - 0x04, 0x01, 0x58, 0x04, 0xd6, 0xfa, 0xd4, 0xac, 0xfb, 0xa6, 0x00, 0x00, - 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x0b, - 0x00, 0x00, 0x01, 0x11, 0x21, 0x35, 0x21, 0x11, 0x33, 0x11, 0x21, 0x11, - 0x21, 0x11, 0x02, 0x18, 0xfd, 0xd4, 0x02, 0x2c, 0xa0, 0x02, 0x2d, 0xfd, - 0xd3, 0xfd, 0x96, 0x04, 0x5a, 0xac, 0x05, 0x2c, 0xfb, 0x2a, 0xfe, 0xa8, - 0xfb, 0xfc, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x04, 0xe5, - 0x07, 0xc8, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x21, 0x11, - 0x33, 0x11, 0x21, 0x11, 0x21, 0x11, 0x02, 0x18, 0xfd, 0xd4, 0x02, 0x2c, - 0xa0, 0x02, 0x2d, 0xfd, 0xd3, 0xfd, 0x96, 0x04, 0x04, 0x01, 0x58, 0x04, - 0xd6, 0xfb, 0x2a, 0xfe, 0xa8, 0xfb, 0xfc, 0x00, 0x00, 0x01, 0xff, 0xec, - 0xfd, 0x96, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x35, 0x21, 0x11, 0x21, 0x11, 0x21, 0x15, 0x21, 0x11, 0x02, 0x18, - 0xfd, 0xd4, 0x01, 0xdc, 0x01, 0x40, 0x01, 0xdd, 0xfd, 0xd3, 0xfd, 0x96, - 0x04, 0x5a, 0xac, 0x05, 0x2c, 0xfa, 0xd4, 0xac, 0xfb, 0xa6, 0x00, 0x00, - 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x0b, - 0x00, 0x00, 0x01, 0x11, 0x21, 0x35, 0x21, 0x11, 0x33, 0x11, 0x21, 0x15, - 0x21, 0x11, 0x01, 0xc8, 0xfe, 0x24, 0x02, 0x2c, 0xa0, 0x02, 0x2d, 0xfe, - 0x23, 0xfd, 0x96, 0x04, 0x5a, 0xac, 0x05, 0x2c, 0xfa, 0xd4, 0xac, 0xfb, - 0xa6, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x04, 0xe5, - 0x07, 0xc8, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, 0x21, 0x35, 0x21, 0x11, - 0x21, 0x11, 0x21, 0x15, 0x21, 0x11, 0x01, 0xc8, 0xfe, 0x24, 0x01, 0xdc, - 0x01, 0x40, 0x01, 0xdd, 0xfe, 0x23, 0xfd, 0x96, 0x04, 0x5a, 0xac, 0x05, - 0x2c, 0xfa, 0xd4, 0xac, 0xfb, 0xa6, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, - 0xfd, 0x96, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x0d, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, 0x15, 0x21, 0x15, 0x23, 0x11, - 0x02, 0x18, 0xfd, 0xd4, 0x01, 0xdc, 0x01, 0x40, 0x01, 0xdd, 0xfe, 0x23, - 0x50, 0xfd, 0x96, 0x04, 0x04, 0x01, 0x58, 0x04, 0xd6, 0xfa, 0xd4, 0xac, - 0x56, 0xfb, 0xfc, 0x00, 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x04, 0xe5, - 0x07, 0xc8, 0x00, 0x0d, 0x00, 0x00, 0x01, 0x11, 0x23, 0x35, 0x21, 0x35, - 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x02, 0x18, 0x50, 0xfe, - 0x24, 0x01, 0xdc, 0x01, 0x40, 0x01, 0xdd, 0xfd, 0xd3, 0xfd, 0x96, 0x04, - 0x04, 0x56, 0xac, 0x05, 0x2c, 0xfb, 0x2a, 0xfe, 0xa8, 0xfb, 0xfc, 0x00, - 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x0d, - 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x21, 0x11, 0x33, 0x11, 0x33, 0x15, - 0x21, 0x15, 0x21, 0x11, 0x01, 0xc8, 0xfe, 0x24, 0x02, 0x2c, 0xa0, 0x50, - 0x01, 0xdd, 0xfe, 0x23, 0xfd, 0x96, 0x04, 0x04, 0x01, 0x58, 0x04, 0xd6, - 0xfb, 0x2a, 0x56, 0xac, 0xfb, 0xa6, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, - 0xfd, 0x96, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x0d, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x35, 0x21, 0x35, 0x33, 0x11, 0x33, 0x11, 0x21, 0x11, 0x21, 0x11, - 0x01, 0xc8, 0xfe, 0x24, 0x01, 0xdc, 0x50, 0xa0, 0x02, 0x2d, 0xfe, 0x23, - 0xfd, 0x96, 0x04, 0x5a, 0xac, 0x56, 0x04, 0xd6, 0xfb, 0x2a, 0xfe, 0xa8, - 0xfb, 0xfc, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x04, 0xe5, - 0x07, 0xc8, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x21, 0x11, - 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x02, 0x18, 0xfd, 0xd4, 0x01, 0xdc, - 0x01, 0x40, 0x01, 0xdd, 0xfd, 0xd3, 0xfd, 0x96, 0x04, 0x04, 0x01, 0x58, - 0x04, 0xd6, 0xfb, 0x2a, 0xfe, 0xa8, 0xfb, 0xfc, 0x00, 0x01, 0xff, 0xec, - 0xfd, 0x96, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x11, 0x21, 0x11, 0x33, 0x11, 0x21, 0x11, 0x21, 0x11, 0x01, 0xc8, - 0xfe, 0x24, 0x02, 0x2c, 0xa0, 0x02, 0x2d, 0xfe, 0x23, 0xfd, 0x96, 0x04, - 0x04, 0x01, 0x58, 0x04, 0xd6, 0xfb, 0x2a, 0xfe, 0xa8, 0xfb, 0xfc, 0x00, - 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x0b, - 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, 0x15, - 0x21, 0x11, 0x01, 0xc8, 0xfe, 0x24, 0x01, 0xdc, 0x01, 0x40, 0x01, 0xdd, - 0xfe, 0x23, 0xfd, 0x96, 0x04, 0x04, 0x01, 0x58, 0x04, 0xd6, 0xfa, 0xd4, - 0xac, 0xfb, 0xa6, 0x00, 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x04, 0xe5, - 0x07, 0xc8, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, 0x21, 0x35, 0x21, 0x11, - 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x01, 0xc8, 0xfe, 0x24, 0x01, 0xdc, - 0x01, 0x40, 0x01, 0xdd, 0xfe, 0x23, 0xfd, 0x96, 0x04, 0x5a, 0xac, 0x05, - 0x2c, 0xfb, 0x2a, 0xfe, 0xa8, 0xfb, 0xfc, 0x00, 0x00, 0x01, 0xff, 0xec, - 0xfd, 0x96, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x01, 0xc8, - 0xfe, 0x24, 0x01, 0xdc, 0x01, 0x40, 0x01, 0xdd, 0xfe, 0x23, 0xfd, 0x96, - 0x04, 0x04, 0x01, 0x58, 0x04, 0xd6, 0xfb, 0x2a, 0xfe, 0xa8, 0xfb, 0xfc, - 0x00, 0x02, 0xff, 0xec, 0x01, 0xf0, 0x04, 0xe5, 0x02, 0x9c, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x00, 0x03, 0x35, 0x21, 0x15, 0x33, 0x35, 0x21, 0x15, - 0x14, 0x02, 0x2c, 0xa0, 0x02, 0x2d, 0x01, 0xf0, 0xac, 0xac, 0xac, 0xac, - 0x00, 0x02, 0xff, 0xec, 0x01, 0x9a, 0x04, 0xe5, 0x02, 0xf2, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, - 0x02, 0xb8, 0x02, 0x2d, 0xfb, 0x07, 0x02, 0x2c, 0x01, 0x9a, 0x01, 0x58, - 0xfe, 0xa8, 0x01, 0x58, 0xfe, 0xa8, 0x00, 0x00, 0x00, 0x02, 0x02, 0x18, - 0xfd, 0x96, 0x02, 0xb8, 0x07, 0xc8, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, - 0x01, 0x11, 0x33, 0x11, 0x03, 0x11, 0x33, 0x11, 0x02, 0x18, 0xa0, 0xa0, - 0xa0, 0x02, 0xf2, 0x04, 0xd6, 0xfb, 0x2a, 0xfa, 0xa4, 0x04, 0x04, 0xfb, - 0xfc, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0xc8, 0xfd, 0x96, 0x03, 0x08, - 0x07, 0xc8, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, - 0x01, 0x11, 0x21, 0x11, 0x01, 0xc8, 0x01, 0x40, 0xfe, 0xc0, 0x01, 0x40, - 0x02, 0xf2, 0x04, 0xd6, 0xfb, 0x2a, 0xfa, 0xa4, 0x04, 0x04, 0xfb, 0xfc, - 0x00, 0x02, 0xff, 0xec, 0x01, 0x44, 0x04, 0xe5, 0x03, 0x48, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x00, 0x03, 0x35, 0x21, 0x15, 0x01, 0x35, 0x21, 0x15, - 0x14, 0x04, 0xf9, 0xfb, 0x07, 0x04, 0xf9, 0x02, 0x9c, 0xac, 0xac, 0xfe, - 0xa8, 0xac, 0xac, 0x00, 0x00, 0x02, 0x01, 0x78, 0xfd, 0x96, 0x03, 0x58, - 0x07, 0xc8, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, - 0x33, 0x11, 0x33, 0x11, 0x01, 0x78, 0xa0, 0xa0, 0xa0, 0xfd, 0x96, 0x0a, - 0x32, 0xf5, 0xce, 0x0a, 0x32, 0xf5, 0xce, 0x00, 0x00, 0x01, 0x02, 0x18, - 0xfd, 0x96, 0x04, 0xe5, 0x03, 0x48, 0x00, 0x09, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x15, 0x21, 0x15, 0x21, 0x15, 0x21, 0x11, 0x02, 0x18, 0x02, 0xcd, - 0xfd, 0xd3, 0x02, 0x2d, 0xfd, 0xd3, 0xfd, 0x96, 0x05, 0xb2, 0xac, 0xac, - 0xac, 0xfc, 0x52, 0x00, 0x00, 0x01, 0x01, 0x78, 0xfd, 0x96, 0x04, 0xe5, - 0x02, 0x9c, 0x00, 0x09, 0x00, 0x00, 0x01, 0x11, 0x21, 0x15, 0x21, 0x11, - 0x23, 0x11, 0x23, 0x11, 0x01, 0x78, 0x03, 0x6d, 0xfe, 0x73, 0xa0, 0xa0, - 0xfd, 0x96, 0x05, 0x06, 0xac, 0xfb, 0xa6, 0x04, 0x5a, 0xfb, 0xa6, 0x00, - 0x00, 0x02, 0x01, 0x78, 0xfd, 0x96, 0x04, 0xe5, 0x03, 0x48, 0x00, 0x05, - 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, 0x21, 0x15, 0x21, 0x11, 0x33, 0x11, - 0x21, 0x15, 0x21, 0x11, 0x01, 0x78, 0x03, 0x6d, 0xfd, 0x33, 0xa0, 0x02, - 0x2d, 0xfe, 0x73, 0xfd, 0x96, 0x05, 0xb2, 0xac, 0xfa, 0xfa, 0x04, 0x5a, - 0xac, 0xfc, 0x52, 0x00, 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x02, 0xb8, - 0x03, 0x48, 0x00, 0x09, 0x00, 0x00, 0x01, 0x11, 0x21, 0x35, 0x21, 0x35, - 0x21, 0x35, 0x21, 0x11, 0x02, 0x18, 0xfd, 0xd4, 0x02, 0x2c, 0xfd, 0xd4, - 0x02, 0xcc, 0xfd, 0x96, 0x03, 0xae, 0xac, 0xac, 0xac, 0xfa, 0x4e, 0x00, - 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x03, 0x58, 0x02, 0x9c, 0x00, 0x09, - 0x00, 0x00, 0x03, 0x35, 0x21, 0x11, 0x23, 0x11, 0x23, 0x11, 0x23, 0x11, - 0x14, 0x03, 0x6c, 0xa0, 0xa0, 0xa0, 0x01, 0xf0, 0xac, 0xfa, 0xfa, 0x04, - 0x5a, 0xfb, 0xa6, 0x04, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, - 0xfd, 0x96, 0x03, 0x58, 0x03, 0x48, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, - 0x01, 0x11, 0x21, 0x35, 0x21, 0x11, 0x21, 0x11, 0x21, 0x35, 0x21, 0x11, - 0x02, 0xb8, 0xfd, 0x34, 0x03, 0x6c, 0xfe, 0x20, 0xfe, 0x74, 0x02, 0x2c, - 0xfd, 0x96, 0x05, 0x06, 0xac, 0xfa, 0x4e, 0x03, 0xae, 0xac, 0xfb, 0xa6, - 0x00, 0x01, 0x02, 0x18, 0x01, 0x44, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x09, - 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, 0x21, 0x15, 0x21, 0x15, 0x21, 0x15, - 0x02, 0x18, 0xa0, 0x02, 0x2d, 0xfd, 0xd3, 0x02, 0x2d, 0x01, 0x44, 0x06, - 0x84, 0xfb, 0x80, 0xac, 0xac, 0xac, 0x00, 0x00, 0x00, 0x01, 0x01, 0x78, - 0x01, 0xf0, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x09, 0x00, 0x00, 0x01, 0x11, - 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x21, 0x15, 0x01, 0x78, 0xa0, 0xa0, - 0xa0, 0x01, 0x8d, 0x01, 0xf0, 0x05, 0xd8, 0xfa, 0xd4, 0x05, 0x2c, 0xfa, - 0xd4, 0xac, 0x00, 0x00, 0x00, 0x02, 0x01, 0x78, 0x01, 0x44, 0x04, 0xe5, - 0x07, 0xc8, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, - 0x21, 0x15, 0x01, 0x11, 0x33, 0x11, 0x21, 0x15, 0x02, 0xb8, 0xa0, 0x01, - 0x8d, 0xfc, 0x93, 0xa0, 0x02, 0xcd, 0x02, 0x9c, 0x05, 0x2c, 0xfb, 0x80, - 0xac, 0xfe, 0xa8, 0x06, 0x84, 0xfa, 0x28, 0xac, 0x00, 0x01, 0xff, 0xec, - 0x01, 0x44, 0x02, 0xb8, 0x07, 0xc8, 0x00, 0x09, 0x00, 0x00, 0x03, 0x35, - 0x21, 0x35, 0x21, 0x35, 0x21, 0x11, 0x33, 0x11, 0x14, 0x02, 0x2c, 0xfd, - 0xd4, 0x02, 0x2c, 0xa0, 0x01, 0x44, 0xac, 0xac, 0xac, 0x04, 0x80, 0xf9, - 0x7c, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, 0x01, 0xf0, 0x03, 0x58, - 0x07, 0xc8, 0x00, 0x09, 0x00, 0x00, 0x03, 0x35, 0x21, 0x11, 0x33, 0x11, - 0x33, 0x11, 0x33, 0x11, 0x14, 0x01, 0x8c, 0xa0, 0xa0, 0xa0, 0x01, 0xf0, - 0xac, 0x05, 0x2c, 0xfa, 0xd4, 0x05, 0x2c, 0xfa, 0x28, 0x00, 0x00, 0x00, - 0x00, 0x02, 0xff, 0xec, 0x01, 0x44, 0x03, 0x58, 0x07, 0xc8, 0x00, 0x05, - 0x00, 0x0b, 0x00, 0x00, 0x03, 0x35, 0x21, 0x11, 0x33, 0x11, 0x01, 0x35, - 0x21, 0x11, 0x33, 0x11, 0x14, 0x01, 0x8c, 0xa0, 0xfd, 0xd4, 0x02, 0xcc, - 0xa0, 0x02, 0x9c, 0xac, 0x04, 0x80, 0xfa, 0xd4, 0xfe, 0xa8, 0xac, 0x05, - 0xd8, 0xf9, 0x7c, 0x00, 0x00, 0x01, 0x02, 0x18, 0xfd, 0x96, 0x04, 0xe5, - 0x07, 0xc8, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, 0x21, 0x15, - 0x21, 0x15, 0x21, 0x15, 0x21, 0x11, 0x02, 0x18, 0xa0, 0x02, 0x2d, 0xfd, - 0xd3, 0x02, 0x2d, 0xfd, 0xd3, 0xfd, 0x96, 0x0a, 0x32, 0xfb, 0x80, 0xac, - 0xac, 0xac, 0xfc, 0x52, 0x00, 0x02, 0x01, 0x78, 0xfd, 0x96, 0x04, 0xe5, - 0x07, 0xc8, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, - 0x33, 0x11, 0x33, 0x11, 0x21, 0x15, 0x21, 0x11, 0x01, 0x78, 0xa0, 0xa0, - 0xa0, 0x01, 0x8d, 0xfe, 0x73, 0xfd, 0x96, 0x0a, 0x32, 0xf5, 0xce, 0x0a, - 0x32, 0xfa, 0xd4, 0xac, 0xfb, 0xa6, 0x00, 0x00, 0x00, 0x03, 0x01, 0x78, - 0xfd, 0x96, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x05, 0x00, 0x09, 0x00, 0x0f, - 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, 0x21, 0x15, 0x01, 0x11, 0x33, 0x11, - 0x33, 0x11, 0x21, 0x15, 0x21, 0x11, 0x02, 0xb8, 0xa0, 0x01, 0x8d, 0xfc, - 0x93, 0xa0, 0xa0, 0x02, 0x2d, 0xfe, 0x73, 0x02, 0x9c, 0x05, 0x2c, 0xfb, - 0x80, 0xac, 0xfa, 0xfa, 0x0a, 0x32, 0xf5, 0xce, 0x04, 0x5a, 0xac, 0xfc, - 0x52, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x02, 0xb8, - 0x07, 0xc8, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, 0x21, 0x35, 0x21, 0x35, - 0x21, 0x35, 0x21, 0x11, 0x33, 0x11, 0x02, 0x18, 0xfd, 0xd4, 0x02, 0x2c, - 0xfd, 0xd4, 0x02, 0x2c, 0xa0, 0xfd, 0x96, 0x03, 0xae, 0xac, 0xac, 0xac, - 0x04, 0x80, 0xf5, 0xce, 0x00, 0x02, 0xff, 0xec, 0xfd, 0x96, 0x03, 0x58, - 0x07, 0xc8, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, 0x21, 0x35, - 0x21, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x01, 0x78, 0xfe, 0x74, - 0x01, 0x8c, 0xa0, 0xa0, 0xa0, 0xfd, 0x96, 0x04, 0x5a, 0xac, 0x05, 0x2c, - 0xf5, 0xce, 0x0a, 0x32, 0xf5, 0xce, 0x00, 0x00, 0x00, 0x03, 0xff, 0xec, - 0xfd, 0x96, 0x03, 0x58, 0x07, 0xc8, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x0f, - 0x00, 0x00, 0x03, 0x35, 0x21, 0x11, 0x33, 0x11, 0x03, 0x11, 0x21, 0x35, - 0x21, 0x11, 0x33, 0x11, 0x33, 0x11, 0x14, 0x01, 0x8c, 0xa0, 0xa0, 0xfe, - 0x74, 0x02, 0x2c, 0xa0, 0xa0, 0x02, 0x9c, 0xac, 0x04, 0x80, 0xfa, 0xd4, - 0xfa, 0xfa, 0x03, 0xae, 0xac, 0xfb, 0xa6, 0x0a, 0x32, 0xf5, 0xce, 0x00, - 0x00, 0x02, 0xff, 0xec, 0xfd, 0x96, 0x04, 0xe5, 0x03, 0x48, 0x00, 0x07, - 0x00, 0x0b, 0x00, 0x00, 0x01, 0x11, 0x21, 0x35, 0x21, 0x15, 0x21, 0x11, - 0x01, 0x35, 0x21, 0x15, 0x02, 0x18, 0xfd, 0xd4, 0x04, 0xf9, 0xfd, 0xd3, - 0xfd, 0x34, 0x04, 0xf9, 0xfd, 0x96, 0x03, 0xae, 0xac, 0xac, 0xfc, 0x52, - 0x05, 0x06, 0xac, 0xac, 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x04, 0xe5, - 0x02, 0x9c, 0x00, 0x0b, 0x00, 0x00, 0x03, 0x35, 0x21, 0x15, 0x21, 0x11, - 0x23, 0x11, 0x23, 0x11, 0x23, 0x11, 0x14, 0x04, 0xf9, 0xfe, 0x73, 0xa0, - 0xa0, 0xa0, 0x01, 0xf0, 0xac, 0xac, 0xfb, 0xa6, 0x04, 0x5a, 0xfb, 0xa6, - 0x04, 0x5a, 0x00, 0x00, 0x00, 0x03, 0xff, 0xec, 0xfd, 0x96, 0x04, 0xe5, - 0x03, 0x48, 0x00, 0x03, 0x00, 0x09, 0x00, 0x0f, 0x00, 0x00, 0x03, 0x35, - 0x21, 0x15, 0x01, 0x11, 0x21, 0x35, 0x21, 0x11, 0x33, 0x11, 0x21, 0x15, - 0x21, 0x11, 0x14, 0x04, 0xf9, 0xfc, 0x93, 0xfe, 0x74, 0x02, 0x2c, 0xa0, - 0x02, 0x2d, 0xfe, 0x73, 0x02, 0x9c, 0xac, 0xac, 0xfa, 0xfa, 0x03, 0xae, - 0xac, 0xfb, 0xa6, 0x04, 0x5a, 0xac, 0xfc, 0x52, 0x00, 0x02, 0xff, 0xec, - 0x01, 0x44, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x00, - 0x03, 0x35, 0x21, 0x15, 0x01, 0x35, 0x21, 0x11, 0x33, 0x11, 0x21, 0x15, - 0x14, 0x04, 0xf9, 0xfb, 0x07, 0x02, 0x2c, 0xa0, 0x02, 0x2d, 0x01, 0x44, - 0xac, 0xac, 0x01, 0x58, 0xac, 0x04, 0x80, 0xfb, 0x80, 0xac, 0x00, 0x00, - 0x00, 0x01, 0xff, 0xec, 0x01, 0xf0, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x0b, - 0x00, 0x00, 0x03, 0x35, 0x21, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, - 0x21, 0x15, 0x14, 0x01, 0x8c, 0xa0, 0xa0, 0xa0, 0x01, 0x8d, 0x01, 0xf0, - 0xac, 0x05, 0x2c, 0xfa, 0xd4, 0x05, 0x2c, 0xfa, 0xd4, 0xac, 0x00, 0x00, - 0x00, 0x03, 0xff, 0xec, 0x01, 0x44, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x03, - 0x00, 0x09, 0x00, 0x0f, 0x00, 0x00, 0x03, 0x35, 0x21, 0x15, 0x01, 0x35, - 0x21, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x21, 0x15, 0x14, 0x04, - 0xf9, 0xfb, 0x07, 0x01, 0x8c, 0xa0, 0xa0, 0xa0, 0x01, 0x8d, 0x01, 0x44, - 0xac, 0xac, 0x01, 0x58, 0xac, 0x04, 0x80, 0xfa, 0xd4, 0x05, 0x2c, 0xfb, - 0x80, 0xac, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x04, 0xe5, - 0x07, 0xc8, 0x00, 0x13, 0x00, 0x00, 0x01, 0x11, 0x21, 0x35, 0x21, 0x35, - 0x21, 0x35, 0x21, 0x11, 0x33, 0x11, 0x21, 0x15, 0x21, 0x15, 0x21, 0x15, - 0x21, 0x11, 0x02, 0x18, 0xfd, 0xd4, 0x02, 0x2c, 0xfd, 0xd4, 0x02, 0x2c, - 0xa0, 0x02, 0x2d, 0xfd, 0xd3, 0x02, 0x2d, 0xfd, 0xd3, 0xfd, 0x96, 0x03, - 0xae, 0xac, 0xac, 0xac, 0x04, 0x80, 0xfb, 0x80, 0xac, 0xac, 0xac, 0xfc, - 0x52, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x04, 0xe5, - 0x07, 0xc8, 0x00, 0x13, 0x00, 0x00, 0x03, 0x35, 0x21, 0x11, 0x33, 0x11, - 0x33, 0x11, 0x33, 0x11, 0x21, 0x15, 0x21, 0x11, 0x23, 0x11, 0x23, 0x11, - 0x23, 0x11, 0x14, 0x01, 0x8c, 0xa0, 0xa0, 0xa0, 0x01, 0x8d, 0xfe, 0x73, - 0xa0, 0xa0, 0xa0, 0x01, 0xf0, 0xac, 0x05, 0x2c, 0xfa, 0xd4, 0x05, 0x2c, - 0xfa, 0xd4, 0xac, 0xfb, 0xa6, 0x04, 0x5a, 0xfb, 0xa6, 0x04, 0x5a, 0x00, - 0x00, 0x04, 0xff, 0xec, 0xfd, 0x96, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x05, - 0x00, 0x0b, 0x00, 0x11, 0x00, 0x17, 0x00, 0x00, 0x01, 0x11, 0x21, 0x15, - 0x21, 0x11, 0x21, 0x11, 0x21, 0x35, 0x21, 0x11, 0x01, 0x35, 0x21, 0x11, - 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x21, 0x15, 0x02, 0xb8, 0x02, 0x2d, - 0xfe, 0x73, 0xfe, 0x20, 0xfe, 0x74, 0x02, 0x2c, 0xfd, 0xd4, 0x01, 0x8c, - 0xa0, 0xa0, 0xa0, 0x01, 0x8d, 0xfd, 0x96, 0x04, 0x5a, 0xac, 0xfc, 0x52, - 0x03, 0xae, 0xac, 0xfb, 0xa6, 0x05, 0x06, 0xac, 0x04, 0x80, 0xfa, 0xd4, - 0x05, 0x2c, 0xfb, 0x80, 0xac, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x18, - 0xfd, 0x96, 0x04, 0xe5, 0x02, 0x9c, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x11, - 0x34, 0x37, 0x36, 0x33, 0x21, 0x15, 0x21, 0x22, 0x06, 0x15, 0x11, 0x02, - 0x18, 0x51, 0x5b, 0xa8, 0x01, 0x79, 0xfe, 0x87, 0x59, 0x5b, 0xfd, 0x96, - 0x03, 0x60, 0xa1, 0x7f, 0x86, 0xac, 0x7e, 0x7c, 0xfc, 0xa0, 0x00, 0x00, - 0x00, 0x01, 0xff, 0xec, 0xfd, 0x96, 0x02, 0xb8, 0x02, 0x9c, 0x00, 0x0d, - 0x00, 0x00, 0x01, 0x11, 0x34, 0x27, 0x26, 0x23, 0x21, 0x35, 0x21, 0x32, - 0x17, 0x16, 0x15, 0x11, 0x02, 0x18, 0x2e, 0x2d, 0x59, 0xfe, 0x88, 0x01, - 0x78, 0xa8, 0x5b, 0x51, 0xfd, 0x96, 0x03, 0x60, 0x7e, 0x3d, 0x3f, 0xac, - 0x86, 0x78, 0xa8, 0xfc, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, - 0x01, 0xf0, 0x02, 0xb8, 0x07, 0xc8, 0x00, 0x0c, 0x00, 0x00, 0x03, 0x35, - 0x21, 0x32, 0x36, 0x35, 0x11, 0x33, 0x11, 0x14, 0x07, 0x06, 0x23, 0x14, - 0x01, 0x78, 0x59, 0x5b, 0xa0, 0x51, 0x5b, 0xa8, 0x01, 0xf0, 0xac, 0x7e, - 0x7c, 0x04, 0x32, 0xfb, 0xce, 0xa8, 0x78, 0x86, 0x00, 0x01, 0x02, 0x18, - 0x01, 0xf0, 0x04, 0xe5, 0x07, 0xc8, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x21, - 0x22, 0x27, 0x26, 0x35, 0x11, 0x33, 0x11, 0x14, 0x16, 0x33, 0x21, 0x04, - 0xe5, 0xfe, 0x87, 0xa8, 0x5b, 0x51, 0xa0, 0x5b, 0x59, 0x01, 0x79, 0x01, - 0xf0, 0x86, 0x78, 0xa8, 0x04, 0x32, 0xfb, 0xce, 0x7c, 0x7e, 0x00, 0x00, - 0x00, 0x01, 0xff, 0x93, 0xfd, 0x96, 0x05, 0x3e, 0x07, 0xc8, 0x00, 0x03, - 0x00, 0x00, 0x03, 0x01, 0x33, 0x01, 0x6d, 0x04, 0xf9, 0xb2, 0xfb, 0x07, - 0xfd, 0x96, 0x0a, 0x32, 0xf5, 0xce, 0x00, 0x00, 0x00, 0x01, 0xff, 0x93, - 0xfd, 0x96, 0x05, 0x3e, 0x07, 0xc8, 0x00, 0x03, 0x00, 0x00, 0x01, 0x23, - 0x01, 0x33, 0x05, 0x3e, 0xb2, 0xfb, 0x07, 0xb2, 0xfd, 0x96, 0x0a, 0x32, - 0x00, 0x01, 0xff, 0x93, 0xfd, 0x96, 0x05, 0x3e, 0x07, 0xc8, 0x00, 0x0b, - 0x00, 0x00, 0x01, 0x23, 0x09, 0x01, 0x23, 0x09, 0x01, 0x33, 0x09, 0x01, - 0x33, 0x01, 0x05, 0x3e, 0xb2, 0xfd, 0xdc, 0xfd, 0xdd, 0xb2, 0x02, 0x7d, - 0xfd, 0x83, 0xb2, 0x02, 0x23, 0x02, 0x24, 0xb2, 0xfd, 0x84, 0xfd, 0x96, - 0x04, 0x63, 0xfb, 0x9d, 0x05, 0x19, 0x05, 0x19, 0xfb, 0x9d, 0x04, 0x63, - 0xfa, 0xe7, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, 0x01, 0xf0, 0x02, 0x7c, - 0x02, 0x9c, 0x00, 0x03, 0x00, 0x00, 0x03, 0x35, 0x21, 0x15, 0x14, 0x02, - 0x90, 0x01, 0xf0, 0xac, 0xac, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x18, - 0x02, 0x46, 0x02, 0xb8, 0x07, 0xc8, 0x00, 0x03, 0x00, 0x00, 0x01, 0x11, - 0x33, 0x11, 0x02, 0x18, 0xa0, 0x02, 0x46, 0x05, 0x82, 0xfa, 0x7e, 0x00, - 0x00, 0x01, 0x02, 0x7c, 0x01, 0xf0, 0x04, 0xe5, 0x02, 0x9c, 0x00, 0x03, - 0x00, 0x00, 0x01, 0x35, 0x21, 0x15, 0x02, 0x7c, 0x02, 0x69, 0x01, 0xf0, - 0xac, 0xac, 0x00, 0x00, 0x00, 0x01, 0x02, 0x18, 0xfd, 0x96, 0x02, 0xb8, - 0x02, 0x46, 0x00, 0x03, 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, 0x02, 0x18, - 0xa0, 0xfd, 0x96, 0x04, 0xb0, 0xfb, 0x50, 0x00, 0x00, 0x01, 0xff, 0xec, - 0x01, 0x9a, 0x02, 0x7c, 0x02, 0xf2, 0x00, 0x03, 0x00, 0x00, 0x03, 0x11, - 0x21, 0x11, 0x14, 0x02, 0x90, 0x01, 0x9a, 0x01, 0x58, 0xfe, 0xa8, 0x00, - 0x00, 0x01, 0x01, 0xc8, 0x02, 0x46, 0x03, 0x08, 0x07, 0xc8, 0x00, 0x03, - 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x01, 0xc8, 0x01, 0x40, 0x02, 0x46, - 0x05, 0x82, 0xfa, 0x7e, 0x00, 0x01, 0x02, 0x7c, 0x01, 0x9a, 0x04, 0xe5, - 0x02, 0xf2, 0x00, 0x03, 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x02, 0x7c, - 0x02, 0x69, 0x01, 0x9a, 0x01, 0x58, 0xfe, 0xa8, 0x00, 0x01, 0x01, 0xc8, - 0xfd, 0x96, 0x03, 0x08, 0x02, 0x46, 0x00, 0x03, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x11, 0x01, 0xc8, 0x01, 0x40, 0xfd, 0x96, 0x04, 0xb0, 0xfb, 0x50, - 0x00, 0x01, 0xff, 0xec, 0x01, 0x9a, 0x04, 0xe5, 0x02, 0xf2, 0x00, 0x07, - 0x00, 0x00, 0x03, 0x35, 0x21, 0x35, 0x21, 0x11, 0x21, 0x35, 0x14, 0x02, - 0x90, 0x02, 0x69, 0xfd, 0x97, 0x01, 0xf0, 0xac, 0x56, 0xfe, 0xa8, 0x56, - 0x00, 0x01, 0x01, 0xc8, 0xfd, 0x96, 0x03, 0x08, 0x07, 0xc8, 0x00, 0x07, - 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x01, 0xc8, - 0x50, 0xa0, 0x50, 0xfd, 0x96, 0x04, 0xb0, 0x05, 0x82, 0xfa, 0x7e, 0xfb, - 0x50, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, 0x01, 0x9a, 0x04, 0xe5, - 0x02, 0xf2, 0x00, 0x07, 0x00, 0x00, 0x03, 0x11, 0x21, 0x15, 0x21, 0x15, - 0x21, 0x15, 0x14, 0x02, 0x90, 0x02, 0x69, 0xfd, 0x97, 0x01, 0x9a, 0x01, - 0x58, 0x56, 0xac, 0x56, 0x00, 0x01, 0x01, 0xc8, 0xfd, 0x96, 0x03, 0x08, - 0x07, 0xc8, 0x00, 0x07, 0x00, 0x00, 0x01, 0x11, 0x23, 0x11, 0x21, 0x11, - 0x23, 0x11, 0x02, 0x18, 0x50, 0x01, 0x40, 0x50, 0xfd, 0x96, 0x04, 0xb0, - 0x05, 0x82, 0xfa, 0x7e, 0xfb, 0x50, 0x00, 0x00, 0xff, 0xff, 0xff, 0xec, - 0x02, 0x14, 0x04, 0xe5, 0x06, 0x28, 0x10, 0x07, 0x09, 0xa8, 0x00, 0x00, - 0x04, 0x14, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, 0xfe, 0x00, 0x04, 0xe5, - 0xff, 0x05, 0x00, 0x03, 0x00, 0x00, 0x03, 0x11, 0x21, 0x11, 0x14, 0x04, - 0xf9, 0xfe, 0x00, 0x01, 0x05, 0xfe, 0xfb, 0x00, 0x00, 0x01, 0xff, 0xec, - 0xfe, 0x00, 0x04, 0xe5, 0x00, 0x0a, 0x00, 0x03, 0x00, 0x00, 0x03, 0x11, - 0x21, 0x11, 0x14, 0x04, 0xf9, 0xfe, 0x00, 0x02, 0x0a, 0xfd, 0xf6, 0x00, - 0x00, 0x01, 0xff, 0xec, 0xfe, 0x00, 0x04, 0xe5, 0x01, 0x0f, 0x00, 0x03, - 0x00, 0x00, 0x03, 0x11, 0x21, 0x11, 0x14, 0x04, 0xf9, 0xfe, 0x00, 0x03, - 0x0f, 0xfc, 0xf1, 0x00, 0x00, 0x01, 0xff, 0xec, 0xfe, 0x00, 0x04, 0xe5, - 0x02, 0x14, 0x00, 0x03, 0x00, 0x00, 0x03, 0x11, 0x21, 0x11, 0x14, 0x04, - 0xf9, 0xfe, 0x00, 0x04, 0x14, 0xfb, 0xec, 0x00, 0x00, 0x01, 0xff, 0xec, - 0xfe, 0x00, 0x04, 0xe5, 0x03, 0x19, 0x00, 0x03, 0x00, 0x00, 0x03, 0x11, - 0x21, 0x11, 0x14, 0x04, 0xf9, 0xfe, 0x00, 0x05, 0x19, 0xfa, 0xe7, 0x00, - 0x00, 0x01, 0xff, 0xec, 0xfe, 0x00, 0x04, 0xe5, 0x04, 0x1e, 0x00, 0x03, - 0x00, 0x00, 0x03, 0x11, 0x21, 0x11, 0x14, 0x04, 0xf9, 0xfe, 0x00, 0x06, - 0x1e, 0xf9, 0xe2, 0x00, 0x00, 0x01, 0xff, 0xec, 0xfe, 0x00, 0x04, 0xe5, - 0x05, 0x23, 0x00, 0x03, 0x00, 0x00, 0x03, 0x11, 0x21, 0x11, 0x14, 0x04, - 0xf9, 0xfe, 0x00, 0x07, 0x23, 0xf8, 0xdd, 0x00, 0x00, 0x01, 0xff, 0xec, - 0xfe, 0x00, 0x04, 0xe5, 0x06, 0x28, 0x00, 0x03, 0x00, 0x00, 0x03, 0x11, - 0x21, 0x11, 0x14, 0x04, 0xf9, 0xfe, 0x00, 0x08, 0x28, 0xf7, 0xd8, 0x00, - 0x00, 0x01, 0xff, 0xec, 0xfe, 0x00, 0x04, 0x46, 0x06, 0x28, 0x00, 0x03, - 0x00, 0x00, 0x03, 0x11, 0x21, 0x11, 0x14, 0x04, 0x5a, 0xfe, 0x00, 0x08, - 0x28, 0xf7, 0xd8, 0x00, 0x00, 0x01, 0xff, 0xec, 0xfe, 0x00, 0x03, 0xa7, - 0x06, 0x28, 0x00, 0x03, 0x00, 0x00, 0x03, 0x11, 0x21, 0x11, 0x14, 0x03, - 0xba, 0xfe, 0x00, 0x08, 0x28, 0xf7, 0xd8, 0x00, 0x00, 0x01, 0xff, 0xec, - 0xfe, 0x00, 0x03, 0x08, 0x06, 0x28, 0x00, 0x03, 0x00, 0x00, 0x03, 0x11, - 0x21, 0x11, 0x14, 0x03, 0x1b, 0xfe, 0x00, 0x08, 0x28, 0xf7, 0xd8, 0x00, - 0x00, 0x01, 0xff, 0xec, 0xfe, 0x00, 0x02, 0x68, 0x06, 0x28, 0x00, 0x03, - 0x00, 0x00, 0x03, 0x11, 0x21, 0x11, 0x14, 0x02, 0x7c, 0xfe, 0x00, 0x08, - 0x28, 0xf7, 0xd8, 0x00, 0x00, 0x01, 0xff, 0xec, 0xfe, 0x00, 0x01, 0xc9, - 0x06, 0x28, 0x00, 0x03, 0x00, 0x00, 0x03, 0x11, 0x21, 0x11, 0x14, 0x01, - 0xdd, 0xfe, 0x00, 0x08, 0x28, 0xf7, 0xd8, 0x00, 0x00, 0x01, 0xff, 0xec, - 0xfe, 0x00, 0x01, 0x2a, 0x06, 0x28, 0x00, 0x03, 0x00, 0x00, 0x03, 0x11, - 0x21, 0x11, 0x14, 0x01, 0x3e, 0xfe, 0x00, 0x08, 0x28, 0xf7, 0xd8, 0x00, - 0x00, 0x01, 0xff, 0xec, 0xfe, 0x00, 0x00, 0x8b, 0x06, 0x28, 0x00, 0x03, - 0x00, 0x00, 0x03, 0x11, 0x33, 0x11, 0x14, 0x9e, 0xfe, 0x00, 0x08, 0x28, - 0xf7, 0xd8, 0x00, 0x00, 0xff, 0xff, 0x02, 0x69, 0xfe, 0x00, 0x04, 0xe5, - 0x06, 0x28, 0x10, 0x07, 0x09, 0xb0, 0x02, 0x7d, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0c, 0xff, 0xec, 0xfe, 0x00, 0x04, 0x46, 0x06, 0x28, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x13, 0x00, 0x17, 0x00, 0x1b, - 0x00, 0x1f, 0x00, 0x23, 0x00, 0x27, 0x00, 0x2b, 0x00, 0x2f, 0x00, 0x00, - 0x01, 0x11, 0x33, 0x11, 0x21, 0x11, 0x33, 0x11, 0x13, 0x11, 0x33, 0x11, - 0x21, 0x11, 0x33, 0x11, 0x01, 0x11, 0x33, 0x11, 0x21, 0x11, 0x33, 0x11, - 0x13, 0x11, 0x33, 0x11, 0x21, 0x11, 0x33, 0x11, 0x01, 0x11, 0x33, 0x11, - 0x21, 0x11, 0x33, 0x11, 0x13, 0x11, 0x33, 0x11, 0x21, 0x11, 0x33, 0x11, - 0x03, 0xa6, 0xa0, 0xfc, 0xe4, 0x9f, 0x9f, 0x9f, 0xfc, 0xe5, 0x9e, 0x03, - 0x1c, 0xa0, 0xfc, 0xe4, 0x9f, 0x9f, 0x9f, 0xfc, 0xe5, 0x9e, 0x03, 0x1c, - 0xa0, 0xfc, 0xe4, 0x9f, 0x9f, 0x9f, 0xfc, 0xe5, 0x9e, 0xfe, 0x00, 0x01, - 0x05, 0xfe, 0xfb, 0x01, 0x05, 0xfe, 0xfb, 0x01, 0x6d, 0x01, 0x05, 0xfe, - 0xfb, 0x01, 0x05, 0xfe, 0xfb, 0x01, 0x6e, 0x01, 0x05, 0xfe, 0xfb, 0x01, - 0x05, 0xfe, 0xfb, 0x01, 0x6d, 0x01, 0x05, 0xfe, 0xfb, 0x01, 0x05, 0xfe, - 0xfb, 0x01, 0x6e, 0x01, 0x05, 0xfe, 0xfb, 0x01, 0x05, 0xfe, 0xfb, 0x01, - 0x6d, 0x01, 0x05, 0xfe, 0xfb, 0x01, 0x05, 0xfe, 0xfb, 0x00, 0x00, 0x00, - 0x00, 0x14, 0xff, 0xec, 0xfe, 0x00, 0x04, 0xe5, 0x06, 0x28, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x13, 0x00, 0x17, 0x00, 0x1b, - 0x00, 0x1f, 0x00, 0x27, 0x00, 0x2f, 0x00, 0x37, 0x00, 0x3f, 0x00, 0x47, - 0x00, 0x4f, 0x00, 0x57, 0x00, 0x5f, 0x00, 0x67, 0x00, 0x6f, 0x00, 0x77, - 0x00, 0x7f, 0x00, 0x00, 0x17, 0x33, 0x11, 0x23, 0x19, 0x01, 0x23, 0x11, - 0x13, 0x11, 0x33, 0x11, 0x03, 0x11, 0x23, 0x11, 0x13, 0x11, 0x33, 0x11, - 0x03, 0x11, 0x23, 0x11, 0x13, 0x11, 0x33, 0x11, 0x03, 0x11, 0x23, 0x11, - 0x01, 0x3b, 0x01, 0x11, 0x23, 0x19, 0x01, 0x23, 0x11, 0x3b, 0x01, 0x11, - 0x23, 0x19, 0x01, 0x23, 0x11, 0x3b, 0x01, 0x11, 0x23, 0x19, 0x01, 0x23, - 0x11, 0x3b, 0x01, 0x11, 0x23, 0x19, 0x01, 0x23, 0x01, 0x3b, 0x01, 0x11, - 0x23, 0x19, 0x01, 0x23, 0x11, 0x3b, 0x01, 0x11, 0x23, 0x19, 0x01, 0x23, - 0x11, 0x3b, 0x01, 0x11, 0x23, 0x19, 0x01, 0x23, 0x11, 0x3b, 0x01, 0x11, - 0x23, 0x19, 0x01, 0x23, 0x01, 0x3b, 0x01, 0x11, 0x23, 0x19, 0x01, 0x23, - 0x11, 0x3b, 0x01, 0x11, 0x23, 0x19, 0x01, 0x23, 0x11, 0x3b, 0x01, 0x11, - 0x23, 0x19, 0x01, 0x23, 0x11, 0x3b, 0x01, 0x11, 0x23, 0x19, 0x01, 0x23, - 0x8a, 0xa0, 0xa0, 0x9e, 0x9e, 0xa0, 0xa0, 0x9e, 0x9e, 0xa0, 0xa0, 0x9e, - 0x9e, 0xa0, 0xa0, 0x9e, 0x01, 0x3e, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, - 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x01, 0x3e, - 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, - 0x9f, 0x9f, 0x9f, 0x9f, 0x01, 0x3e, 0xa0, 0x9f, 0x9f, 0xa0, 0xa0, 0x9f, - 0x9f, 0xa0, 0xa0, 0x9f, 0x9f, 0xa0, 0xa0, 0x9f, 0x9f, 0xa0, 0xfb, 0xfe, - 0xfb, 0x01, 0x05, 0x01, 0x05, 0xfe, 0xfb, 0x01, 0x05, 0x01, 0x05, 0xfe, - 0xfb, 0x01, 0x05, 0x01, 0x05, 0xfe, 0xfb, 0x01, 0x05, 0x01, 0x05, 0xfe, - 0xfb, 0x01, 0x05, 0x01, 0x05, 0xfe, 0xfb, 0x01, 0x05, 0x01, 0x05, 0xfe, - 0xfb, 0x01, 0x05, 0x01, 0x05, 0xfe, 0xfb, 0xf9, 0xe2, 0xfe, 0xfb, 0x01, - 0x05, 0x01, 0x05, 0x01, 0x05, 0xfe, 0xfb, 0x01, 0x05, 0x01, 0x05, 0x01, - 0x05, 0xfe, 0xfb, 0x01, 0x05, 0x01, 0x05, 0x01, 0x05, 0xfe, 0xfb, 0x01, - 0x05, 0x01, 0x05, 0xf8, 0xdd, 0xfe, 0xfb, 0x01, 0x05, 0x01, 0x05, 0x01, - 0x05, 0xfe, 0xfb, 0x01, 0x05, 0x01, 0x05, 0x01, 0x05, 0xfe, 0xfb, 0x01, - 0x05, 0x01, 0x05, 0x01, 0x05, 0xfe, 0xfb, 0x01, 0x05, 0x01, 0x05, 0xf8, - 0xdd, 0xfe, 0xfb, 0x01, 0x05, 0x01, 0x05, 0x01, 0x05, 0xfe, 0xfb, 0x01, - 0x05, 0x01, 0x05, 0x01, 0x05, 0xfe, 0xfb, 0x01, 0x05, 0x01, 0x05, 0x01, - 0x05, 0xfe, 0xfb, 0x01, 0x05, 0x01, 0x05, 0x00, 0x00, 0x07, 0xff, 0xec, - 0xfe, 0x00, 0x04, 0xe5, 0x06, 0x28, 0x00, 0x19, 0x00, 0x1d, 0x00, 0x21, - 0x00, 0x25, 0x00, 0x29, 0x00, 0x2d, 0x00, 0x31, 0x00, 0x00, 0x03, 0x11, - 0x33, 0x11, 0x23, 0x11, 0x33, 0x11, 0x23, 0x11, 0x33, 0x11, 0x21, 0x11, - 0x33, 0x11, 0x21, 0x11, 0x23, 0x11, 0x23, 0x11, 0x21, 0x11, 0x23, 0x19, - 0x01, 0x33, 0x11, 0x23, 0x01, 0x33, 0x11, 0x23, 0x01, 0x33, 0x11, 0x23, - 0x01, 0x33, 0x11, 0x23, 0x01, 0x33, 0x11, 0x23, 0x01, 0x33, 0x11, 0x23, - 0x14, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x01, 0xde, 0x9f, 0x01, 0xde, 0x9f, - 0xa0, 0xfe, 0x23, 0x9f, 0x9f, 0x9f, 0x02, 0x7c, 0xa0, 0xa0, 0xfe, 0xc2, - 0x9f, 0x9f, 0xfe, 0xc2, 0x9f, 0x9f, 0x02, 0x7c, 0xa0, 0xa0, 0xfe, 0xc2, - 0x9f, 0x9f, 0xfe, 0x00, 0x01, 0x6d, 0x01, 0x05, 0x01, 0xd6, 0x01, 0x05, - 0x01, 0xd6, 0x01, 0x05, 0xfe, 0xfb, 0x01, 0x05, 0xf7, 0xd8, 0x01, 0x05, - 0xfe, 0xfb, 0x01, 0x05, 0xfe, 0xfb, 0x05, 0xb6, 0x01, 0x05, 0xfe, 0xfb, - 0x01, 0x05, 0xfd, 0x8d, 0x01, 0x05, 0xfd, 0x8e, 0x01, 0x05, 0xfe, 0xfb, - 0x01, 0x05, 0xfd, 0x8d, 0x01, 0x05, 0x00, 0x00, 0xff, 0xff, 0xff, 0xec, - 0x05, 0x23, 0x04, 0xe5, 0x06, 0x28, 0x10, 0x07, 0x09, 0xa5, 0x00, 0x00, - 0x07, 0x23, 0x00, 0x00, 0xff, 0xff, 0x04, 0x45, 0xfe, 0x00, 0x04, 0xe4, - 0x06, 0x28, 0x10, 0x07, 0x09, 0xb3, 0x04, 0x5a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0xff, 0xec, 0xfe, 0x00, 0x02, 0x69, 0x02, 0x14, 0x00, 0x03, - 0x00, 0x00, 0x03, 0x11, 0x21, 0x11, 0x14, 0x02, 0x7d, 0xfe, 0x00, 0x04, - 0x14, 0xfb, 0xec, 0x00, 0x00, 0x01, 0x02, 0x69, 0xfe, 0x00, 0x04, 0xe6, - 0x02, 0x14, 0x00, 0x03, 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x02, 0x69, - 0x02, 0x7d, 0xfe, 0x00, 0x04, 0x14, 0xfb, 0xec, 0x00, 0x01, 0xff, 0xec, - 0x02, 0x14, 0x02, 0x69, 0x06, 0x28, 0x00, 0x03, 0x00, 0x00, 0x03, 0x11, - 0x21, 0x11, 0x14, 0x02, 0x7d, 0x02, 0x14, 0x04, 0x14, 0xfb, 0xec, 0x00, - 0x00, 0x01, 0xff, 0xec, 0xfe, 0x00, 0x04, 0xe6, 0x06, 0x28, 0x00, 0x05, - 0x00, 0x00, 0x03, 0x11, 0x21, 0x11, 0x21, 0x11, 0x14, 0x02, 0x7d, 0x02, - 0x7d, 0xfe, 0x00, 0x08, 0x28, 0xfb, 0xec, 0xfb, 0xec, 0x00, 0x00, 0x00, - 0x00, 0x02, 0xff, 0xec, 0xfe, 0x00, 0x04, 0xe6, 0x06, 0x28, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x00, 0x03, 0x11, 0x21, 0x11, 0x31, 0x21, 0x11, 0x21, - 0x14, 0x02, 0x7d, 0x02, 0x7d, 0xfd, 0x83, 0x02, 0x14, 0x04, 0x14, 0xfb, - 0xec, 0xfb, 0xec, 0x00, 0x00, 0x01, 0xff, 0xec, 0xfe, 0x00, 0x04, 0xe6, - 0x06, 0x28, 0x00, 0x05, 0x00, 0x00, 0x03, 0x21, 0x11, 0x21, 0x11, 0x21, - 0x14, 0x04, 0xfa, 0xfd, 0x83, 0xfd, 0x83, 0x06, 0x28, 0xfb, 0xec, 0xfb, - 0xec, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, 0xfe, 0x00, 0x04, 0xe6, - 0x06, 0x28, 0x00, 0x05, 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x21, 0x11, - 0x04, 0xe6, 0xfd, 0x83, 0xfd, 0x83, 0x06, 0x28, 0xf7, 0xd8, 0x04, 0x14, - 0x04, 0x14, 0x00, 0x00, 0x00, 0x01, 0x02, 0x69, 0x02, 0x14, 0x04, 0xe6, - 0x06, 0x28, 0x00, 0x03, 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x02, 0x69, - 0x02, 0x7d, 0x02, 0x14, 0x04, 0x14, 0xfb, 0xec, 0x00, 0x02, 0xff, 0xec, - 0xfe, 0x00, 0x04, 0xe6, 0x06, 0x28, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, - 0x03, 0x21, 0x11, 0x21, 0x01, 0x11, 0x21, 0x11, 0x14, 0x02, 0x7d, 0xfd, - 0x83, 0x02, 0x7d, 0x02, 0x7d, 0x02, 0x14, 0xfb, 0xec, 0x04, 0x14, 0x04, - 0x14, 0xfb, 0xec, 0x00, 0x00, 0x01, 0xff, 0xec, 0xfe, 0x00, 0x04, 0xe6, - 0x06, 0x28, 0x00, 0x05, 0x00, 0x00, 0x01, 0x21, 0x11, 0x21, 0x11, 0x21, - 0x04, 0xe6, 0xfb, 0x06, 0x02, 0x7d, 0x02, 0x7d, 0xfe, 0x00, 0x04, 0x14, - 0x04, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, - 0x04, 0x77, 0x00, 0x03, 0x00, 0x00, 0x17, 0x11, 0x21, 0x11, 0x06, 0x04, - 0xc5, 0x4e, 0x04, 0xc4, 0xfb, 0x3c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, - 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, - 0x37, 0x21, 0x11, 0x21, 0x03, 0x11, 0x21, 0x11, 0x78, 0x03, 0xe1, 0xfc, - 0x1f, 0x72, 0x04, 0xc5, 0x24, 0x03, 0xe0, 0xfb, 0xae, 0x04, 0xc4, 0xfb, - 0x3c, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, - 0x04, 0x77, 0x00, 0x0b, 0x00, 0x17, 0x00, 0x00, 0x13, 0x14, 0x33, 0x21, - 0x32, 0x35, 0x11, 0x34, 0x23, 0x21, 0x22, 0x15, 0x03, 0x11, 0x10, 0x29, - 0x01, 0x20, 0x19, 0x01, 0x10, 0x29, 0x01, 0x20, 0x78, 0xe4, 0x02, 0x19, - 0xe4, 0xe4, 0xfd, 0xe7, 0xe4, 0x72, 0x01, 0x56, 0x02, 0x19, 0x01, 0x56, - 0xfe, 0xaa, 0xfd, 0xe7, 0xfe, 0xaa, 0x01, 0x08, 0xe4, 0xe4, 0x02, 0x18, - 0xe4, 0xe4, 0xfd, 0xe8, 0x02, 0x18, 0x01, 0x56, 0xfe, 0xaa, 0xfd, 0xe8, - 0xfe, 0xaa, 0x00, 0x00, 0xff, 0xff, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, - 0x04, 0x77, 0x10, 0x26, 0x09, 0xce, 0x00, 0x00, 0x10, 0x06, 0x09, 0xc5, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, - 0x04, 0x77, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x13, - 0x00, 0x17, 0x00, 0x00, 0x17, 0x11, 0x21, 0x11, 0x25, 0x21, 0x35, 0x21, - 0x35, 0x21, 0x35, 0x21, 0x35, 0x21, 0x35, 0x21, 0x35, 0x21, 0x35, 0x21, - 0x35, 0x21, 0x35, 0x21, 0x06, 0x04, 0xc5, 0xfb, 0xad, 0x03, 0xe1, 0xfc, - 0x1f, 0x03, 0xe1, 0xfc, 0x1f, 0x03, 0xe1, 0xfc, 0x1f, 0x03, 0xe1, 0xfc, - 0x1f, 0x03, 0xe1, 0xfc, 0x1f, 0x4e, 0x04, 0xc4, 0xfb, 0x3c, 0x72, 0x6e, - 0x72, 0x6a, 0x72, 0x6b, 0x72, 0x6b, 0x72, 0x6a, 0x00, 0x06, 0x00, 0x06, - 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, - 0x00, 0x0f, 0x00, 0x13, 0x00, 0x17, 0x00, 0x00, 0x17, 0x11, 0x21, 0x11, - 0x27, 0x33, 0x11, 0x23, 0x03, 0x33, 0x11, 0x23, 0x03, 0x33, 0x11, 0x23, - 0x03, 0x33, 0x11, 0x23, 0x03, 0x33, 0x11, 0x23, 0x06, 0x04, 0xc5, 0xe1, - 0x6e, 0x6e, 0xdc, 0x6a, 0x6a, 0xdc, 0x6a, 0x6a, 0xde, 0x6c, 0x6c, 0xdc, - 0x6a, 0x6a, 0x4e, 0x04, 0xc4, 0xfb, 0x3c, 0x72, 0x03, 0xe0, 0xfc, 0x20, - 0x03, 0xe0, 0xfc, 0x20, 0x03, 0xe0, 0xfc, 0x20, 0x03, 0xe0, 0xfc, 0x20, - 0x03, 0xe0, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, - 0x04, 0x77, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x13, - 0x00, 0x17, 0x00, 0x1b, 0x00, 0x1f, 0x00, 0x23, 0x00, 0x27, 0x00, 0x2b, - 0x00, 0x2f, 0x00, 0x33, 0x00, 0x37, 0x00, 0x3b, 0x00, 0x3f, 0x00, 0x43, - 0x00, 0x47, 0x00, 0x4b, 0x00, 0x4f, 0x00, 0x53, 0x00, 0x57, 0x00, 0x5b, - 0x00, 0x5f, 0x00, 0x63, 0x00, 0x67, 0x00, 0x00, 0x13, 0x33, 0x35, 0x23, - 0x11, 0x33, 0x35, 0x23, 0x11, 0x33, 0x35, 0x23, 0x11, 0x33, 0x35, 0x23, - 0x11, 0x33, 0x35, 0x23, 0x13, 0x33, 0x35, 0x23, 0x11, 0x33, 0x35, 0x23, - 0x11, 0x33, 0x35, 0x23, 0x11, 0x33, 0x35, 0x23, 0x11, 0x33, 0x35, 0x23, - 0x13, 0x33, 0x35, 0x23, 0x11, 0x33, 0x35, 0x23, 0x11, 0x33, 0x35, 0x23, - 0x11, 0x33, 0x35, 0x23, 0x11, 0x33, 0x35, 0x23, 0x13, 0x33, 0x35, 0x23, - 0x11, 0x33, 0x35, 0x23, 0x11, 0x33, 0x35, 0x23, 0x11, 0x33, 0x35, 0x23, - 0x11, 0x33, 0x35, 0x23, 0x13, 0x33, 0x35, 0x23, 0x11, 0x33, 0x35, 0x23, - 0x11, 0x33, 0x35, 0x23, 0x11, 0x33, 0x35, 0x23, 0x11, 0x33, 0x35, 0x23, - 0x05, 0x11, 0x21, 0x11, 0x78, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, - 0x6a, 0x6a, 0x6a, 0xdc, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, - 0x6c, 0x6c, 0xde, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, - 0x6a, 0xdc, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, - 0xdc, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0xfc, - 0x1c, 0x04, 0xc5, 0x03, 0x9a, 0x6a, 0xfe, 0xb9, 0x6b, 0xfe, 0xb8, 0x6b, - 0xfe, 0xb9, 0x6a, 0xfe, 0xb6, 0x6e, 0x03, 0x08, 0x6a, 0xfe, 0xb9, 0x6b, - 0xfe, 0xb8, 0x6b, 0xfe, 0xb9, 0x6a, 0xfe, 0xb6, 0x6e, 0x03, 0x08, 0x6a, - 0xfe, 0xb9, 0x6b, 0xfe, 0xb8, 0x6b, 0xfe, 0xb9, 0x6a, 0xfe, 0xb6, 0x6e, - 0x03, 0x08, 0x6a, 0xfe, 0xb9, 0x6b, 0xfe, 0xb8, 0x6b, 0xfe, 0xb9, 0x6a, - 0xfe, 0xb6, 0x6e, 0x03, 0x08, 0x6a, 0xfe, 0xb9, 0x6b, 0xfe, 0xb8, 0x6b, - 0xfe, 0xb9, 0x6a, 0xfe, 0xb6, 0x6e, 0xe0, 0x04, 0xc4, 0xfb, 0x3c, 0x00, - 0x00, 0x08, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x0b, 0x00, 0x11, 0x00, 0x15, 0x00, 0x19, 0x00, 0x1c, - 0x00, 0x1f, 0x00, 0x00, 0x17, 0x11, 0x21, 0x11, 0x01, 0x15, 0x01, 0x33, - 0x01, 0x15, 0x01, 0x37, 0x01, 0x15, 0x01, 0x33, 0x35, 0x01, 0x33, 0x01, - 0x35, 0x01, 0x33, 0x01, 0x35, 0x01, 0x33, 0x17, 0x35, 0x01, 0x15, 0x33, - 0x06, 0x04, 0xc5, 0xfb, 0xad, 0x01, 0x34, 0x8a, 0xfe, 0x42, 0x02, 0x60, - 0x95, 0xfd, 0x0b, 0x03, 0x97, 0x4a, 0xfc, 0x6c, 0xa1, 0x02, 0xf3, 0xfd, - 0xa4, 0xa2, 0x01, 0xba, 0xfe, 0xd0, 0xa2, 0x8e, 0xfc, 0x1f, 0x92, 0x4e, - 0x04, 0xc4, 0xfb, 0x3c, 0x02, 0x30, 0x8b, 0xfe, 0xcd, 0x02, 0xf5, 0x96, - 0xfd, 0xa0, 0x01, 0x03, 0xe0, 0x4a, 0xfc, 0x6a, 0x4c, 0x03, 0x94, 0xfd, - 0x0e, 0x97, 0x02, 0x5b, 0xfe, 0x46, 0x8b, 0x01, 0x2f, 0x8e, 0x8e, 0xfc, - 0xb2, 0x92, 0x00, 0x00, 0x00, 0x08, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, - 0x04, 0x77, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x11, 0x00, 0x15, - 0x00, 0x19, 0x00, 0x1c, 0x00, 0x1f, 0x00, 0x00, 0x17, 0x11, 0x21, 0x11, - 0x25, 0x33, 0x01, 0x35, 0x01, 0x17, 0x01, 0x35, 0x01, 0x33, 0x01, 0x35, - 0x23, 0x01, 0x35, 0x01, 0x23, 0x01, 0x35, 0x01, 0x23, 0x01, 0x35, 0x37, - 0x23, 0x01, 0x33, 0x35, 0x06, 0x04, 0xc5, 0xfd, 0xd0, 0x8a, 0x01, 0x34, - 0xfd, 0x0b, 0x95, 0x02, 0x60, 0xfc, 0x1f, 0x4a, 0x03, 0x97, 0x4d, 0xfc, - 0x6c, 0x02, 0xf3, 0x97, 0xfd, 0xa4, 0x01, 0xba, 0x8a, 0xfe, 0xd0, 0x8e, - 0x8e, 0x03, 0x4f, 0x92, 0x4e, 0x04, 0xc4, 0xfb, 0x3c, 0x72, 0x01, 0x33, - 0x8b, 0xfe, 0x42, 0x01, 0x02, 0x60, 0x96, 0xfd, 0x0b, 0x03, 0x96, 0x4a, - 0xfc, 0x6c, 0xa2, 0x02, 0xf2, 0xfd, 0xa5, 0xa1, 0x01, 0xba, 0xfe, 0xd1, - 0xa1, 0x8e, 0xfc, 0x20, 0x92, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x06, - 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x04, 0x00, 0x09, 0x00, 0x0e, - 0x00, 0x13, 0x00, 0x17, 0x00, 0x1c, 0x00, 0x21, 0x00, 0x25, 0x00, 0x29, - 0x00, 0x2d, 0x00, 0x32, 0x00, 0x37, 0x00, 0x3b, 0x00, 0x3f, 0x00, 0x43, - 0x00, 0x47, 0x00, 0x4b, 0x00, 0x50, 0x00, 0x54, 0x00, 0x58, 0x00, 0x5c, - 0x00, 0x61, 0x00, 0x66, 0x00, 0x6a, 0x00, 0x6f, 0x00, 0x73, 0x00, 0x00, - 0x25, 0x17, 0x33, 0x35, 0x27, 0x01, 0x17, 0x37, 0x27, 0x23, 0x11, 0x17, - 0x37, 0x27, 0x07, 0x01, 0x17, 0x37, 0x27, 0x23, 0x07, 0x17, 0x37, 0x27, - 0x03, 0x17, 0x37, 0x27, 0x07, 0x01, 0x17, 0x37, 0x27, 0x23, 0x07, 0x17, - 0x37, 0x27, 0x07, 0x17, 0x37, 0x27, 0x07, 0x17, 0x37, 0x27, 0x03, 0x33, - 0x37, 0x27, 0x07, 0x01, 0x17, 0x37, 0x35, 0x23, 0x07, 0x17, 0x37, 0x27, - 0x07, 0x17, 0x37, 0x27, 0x07, 0x17, 0x37, 0x27, 0x07, 0x17, 0x37, 0x27, - 0x07, 0x17, 0x37, 0x27, 0x01, 0x17, 0x37, 0x35, 0x27, 0x07, 0x17, 0x37, - 0x27, 0x07, 0x17, 0x37, 0x27, 0x07, 0x17, 0x37, 0x27, 0x07, 0x17, 0x33, - 0x37, 0x27, 0x25, 0x17, 0x37, 0x35, 0x27, 0x07, 0x17, 0x37, 0x27, 0x07, - 0x17, 0x33, 0x37, 0x27, 0x05, 0x11, 0x21, 0x11, 0x03, 0xeb, 0x24, 0x4a, - 0x23, 0xfc, 0x42, 0x22, 0x4c, 0x21, 0x4d, 0x1c, 0x4c, 0x46, 0x22, 0x01, - 0x0f, 0x45, 0x4c, 0x1b, 0x55, 0xbd, 0x45, 0x4c, 0x46, 0xbe, 0x23, 0x45, - 0x4b, 0x1d, 0x02, 0x41, 0x4c, 0x45, 0x21, 0x55, 0xb7, 0x4b, 0x4c, 0x4c, - 0xe7, 0x4b, 0x4c, 0x4c, 0xe7, 0x4c, 0x4b, 0x4c, 0xb8, 0x4a, 0x24, 0x4b, - 0x23, 0x03, 0x74, 0x4b, 0x22, 0x4d, 0xb6, 0x4b, 0x45, 0x4b, 0xe2, 0x4c, - 0x4b, 0x4b, 0xe8, 0x4b, 0x4c, 0x4c, 0xe6, 0x4b, 0x4b, 0x4c, 0xe0, 0x4b, - 0x45, 0x4b, 0x02, 0xc1, 0x4a, 0x1d, 0x22, 0xe2, 0x4b, 0x4c, 0x4b, 0xe8, - 0x4b, 0x4c, 0x4c, 0xe6, 0x4a, 0x4c, 0x4c, 0xe0, 0x24, 0x4e, 0x1e, 0x4b, - 0x02, 0x24, 0x45, 0x23, 0x1d, 0xe7, 0x45, 0x4b, 0x45, 0xe7, 0x1e, 0x4e, - 0x24, 0x45, 0xfd, 0x02, 0x04, 0xc5, 0x48, 0x24, 0x4c, 0x23, 0x03, 0x27, - 0x22, 0x4c, 0x20, 0xfe, 0x7f, 0x1d, 0x4c, 0x45, 0x22, 0x01, 0x0e, 0x45, - 0x4c, 0x1a, 0xbd, 0x45, 0x4c, 0x45, 0xfd, 0xc4, 0x22, 0x45, 0x4b, 0x1c, - 0x02, 0x41, 0x4c, 0x45, 0x21, 0xb7, 0x4b, 0x4b, 0x4c, 0xe8, 0x4b, 0x4b, - 0x4c, 0xe7, 0x4c, 0x4b, 0x4c, 0xfd, 0xc3, 0x24, 0x4b, 0x23, 0x03, 0x74, - 0x4c, 0x22, 0x4a, 0xb6, 0x4c, 0x45, 0x4c, 0xe2, 0x4b, 0x4b, 0x4c, 0xe8, - 0x4b, 0x4b, 0x4b, 0xe6, 0x4c, 0x4b, 0x4b, 0xe0, 0x4b, 0x45, 0x4b, 0x01, - 0x89, 0x4c, 0x1d, 0x52, 0x22, 0xe2, 0x4b, 0x4c, 0x4b, 0xe8, 0x4b, 0x4c, - 0x4a, 0xe6, 0x4c, 0x4c, 0x4a, 0xe0, 0x24, 0x1e, 0x4b, 0xed, 0x45, 0x22, - 0x52, 0x1c, 0xe7, 0x45, 0x4b, 0x45, 0xe7, 0x1e, 0x24, 0x45, 0xdb, 0x04, - 0xc4, 0xfb, 0x3c, 0x00, 0x00, 0x01, 0x00, 0xdb, 0x00, 0x87, 0x03, 0xf5, - 0x03, 0xa1, 0x00, 0x03, 0x00, 0x00, 0x37, 0x11, 0x21, 0x11, 0xdb, 0x03, - 0x1a, 0x87, 0x03, 0x1a, 0xfc, 0xe6, 0x00, 0x00, 0x00, 0x02, 0x00, 0xdb, - 0x00, 0x87, 0x03, 0xf5, 0x03, 0xa1, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, - 0x25, 0x21, 0x11, 0x21, 0x03, 0x11, 0x21, 0x11, 0x01, 0x4d, 0x02, 0x36, - 0xfd, 0xca, 0x72, 0x03, 0x1a, 0xf9, 0x02, 0x36, 0xfd, 0x58, 0x03, 0x1a, - 0xfc, 0xe6, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0xf0, 0x04, 0xcb, - 0x03, 0x38, 0x00, 0x03, 0x00, 0x00, 0x25, 0x21, 0x11, 0x21, 0x04, 0xcb, - 0xfb, 0x3b, 0x04, 0xc5, 0xf0, 0x02, 0x48, 0x00, 0x00, 0x02, 0x00, 0x06, - 0x00, 0xf0, 0x04, 0xcb, 0x03, 0x38, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, - 0x01, 0x11, 0x21, 0x11, 0x05, 0x21, 0x11, 0x21, 0x04, 0x59, 0xfc, 0x1f, - 0x04, 0x53, 0xfb, 0x3b, 0x04, 0xc5, 0x01, 0x62, 0x01, 0x64, 0xfe, 0x9c, - 0x72, 0x02, 0x48, 0x00, 0x00, 0x01, 0x01, 0x44, 0xff, 0xb1, 0x03, 0x8d, - 0x04, 0x77, 0x00, 0x03, 0x00, 0x00, 0x05, 0x11, 0x21, 0x11, 0x01, 0x44, - 0x02, 0x48, 0x4e, 0x04, 0xc4, 0xfb, 0x3c, 0x00, 0x00, 0x02, 0x01, 0x44, - 0xff, 0xb1, 0x03, 0x8d, 0x04, 0x77, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, - 0x25, 0x21, 0x11, 0x21, 0x03, 0x11, 0x21, 0x11, 0x01, 0xb6, 0x01, 0x64, - 0xfe, 0x9c, 0x72, 0x02, 0x48, 0x24, 0x03, 0xe0, 0xfb, 0xae, 0x04, 0xc4, - 0xfb, 0x3c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 0xf0, 0x04, 0xcb, - 0x03, 0x38, 0x00, 0x03, 0x00, 0x00, 0x25, 0x21, 0x01, 0x21, 0x03, 0x97, - 0xfc, 0x6f, 0x01, 0x34, 0x03, 0x91, 0xf0, 0x02, 0x48, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x06, 0x00, 0xf0, 0x04, 0xcb, 0x03, 0x38, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x00, 0x01, 0x13, 0x21, 0x03, 0x05, 0x21, 0x01, 0x21, - 0x03, 0x61, 0xbc, 0xfd, 0x53, 0xbc, 0x02, 0xe3, 0xfc, 0x6f, 0x01, 0x34, - 0x03, 0x91, 0x01, 0x62, 0x01, 0x64, 0xfe, 0x9c, 0x72, 0x02, 0x48, 0x00, - 0x00, 0x01, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x02, - 0x00, 0x00, 0x17, 0x09, 0x01, 0x06, 0x02, 0x62, 0x02, 0x63, 0x4e, 0x04, - 0xc4, 0xfb, 0x3c, 0x00, 0x00, 0x02, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, - 0x04, 0x77, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x37, 0x21, 0x09, 0x03, - 0xb1, 0x03, 0x6f, 0xfe, 0x48, 0xfd, 0x9e, 0x02, 0x62, 0x02, 0x63, 0x24, - 0x03, 0x6e, 0xfc, 0x20, 0x04, 0xc4, 0xfb, 0x3c, 0x00, 0x01, 0x00, 0xdb, - 0x00, 0x87, 0x03, 0xf5, 0x03, 0xa1, 0x00, 0x02, 0x00, 0x00, 0x37, 0x09, - 0x01, 0xdb, 0x01, 0x8d, 0x01, 0x8d, 0x87, 0x03, 0x1a, 0xfc, 0xe6, 0x00, - 0x00, 0x02, 0x00, 0xdb, 0x00, 0x87, 0x03, 0xf5, 0x03, 0xa1, 0x00, 0x02, - 0x00, 0x05, 0x00, 0x00, 0x25, 0x21, 0x03, 0x09, 0x02, 0x01, 0x86, 0x01, - 0xc4, 0xe2, 0xfe, 0x73, 0x01, 0x8d, 0x01, 0x8d, 0xf9, 0x01, 0xc4, 0xfd, - 0xca, 0x03, 0x1a, 0xfc, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, - 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x02, 0x00, 0x00, 0x17, 0x11, - 0x01, 0x06, 0x04, 0xc5, 0x4e, 0x04, 0xc4, 0xfd, 0x9e, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x02, - 0x00, 0x05, 0x00, 0x00, 0x37, 0x09, 0x01, 0x03, 0x11, 0x01, 0x78, 0x03, - 0x6f, 0xfc, 0x91, 0x72, 0x04, 0xc5, 0x5c, 0x01, 0xb8, 0x01, 0xb8, 0xfb, - 0xe6, 0x04, 0xc4, 0xfd, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xdb, - 0x00, 0x87, 0x03, 0xf5, 0x03, 0xa1, 0x00, 0x02, 0x00, 0x00, 0x37, 0x11, - 0x01, 0xdb, 0x03, 0x1a, 0x87, 0x03, 0x1a, 0xfe, 0x73, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0xdb, 0x00, 0x87, 0x03, 0xf5, 0x03, 0xa1, 0x00, 0x02, - 0x00, 0x05, 0x00, 0x00, 0x01, 0x2d, 0x01, 0x03, 0x11, 0x01, 0x01, 0x4d, - 0x01, 0xc4, 0xfe, 0x3c, 0x72, 0x03, 0x1a, 0x01, 0x32, 0xe2, 0xe2, 0xfd, - 0x91, 0x03, 0x1a, 0xfe, 0x73, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, - 0x00, 0x87, 0x04, 0xcb, 0x03, 0xa1, 0x00, 0x02, 0x00, 0x00, 0x37, 0x11, - 0x01, 0x06, 0x04, 0xc5, 0x87, 0x03, 0x1a, 0xfe, 0x73, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x06, 0x00, 0x87, 0x04, 0xcb, 0x03, 0xa1, 0x00, 0x02, - 0x00, 0x05, 0x00, 0x00, 0x13, 0x2d, 0x01, 0x03, 0x11, 0x01, 0x78, 0x03, - 0x36, 0xfc, 0xca, 0x72, 0x04, 0xc5, 0x01, 0x32, 0xe2, 0xe2, 0xfd, 0x91, - 0x03, 0x1a, 0xfe, 0x73, 0x00, 0x01, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, - 0x04, 0x77, 0x00, 0x02, 0x00, 0x00, 0x05, 0x01, 0x21, 0x02, 0x68, 0xfd, - 0x9e, 0x04, 0xc5, 0x4e, 0x04, 0xc4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, - 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, - 0x25, 0x01, 0x21, 0x09, 0x01, 0x21, 0x02, 0x68, 0x01, 0x95, 0xfc, 0xd7, - 0x01, 0x94, 0xfd, 0x9e, 0x04, 0xc5, 0xcd, 0x03, 0x28, 0xfb, 0xbd, 0x04, - 0xc4, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xdb, 0x00, 0x87, 0x03, 0xf5, - 0x03, 0xa1, 0x00, 0x02, 0x00, 0x00, 0x25, 0x01, 0x21, 0x02, 0x68, 0xfe, - 0x73, 0x03, 0x1a, 0x87, 0x03, 0x1a, 0x00, 0x00, 0x00, 0x02, 0x00, 0xdb, - 0x00, 0x87, 0x03, 0xf5, 0x03, 0xa1, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, - 0x01, 0x13, 0x21, 0x13, 0x01, 0x21, 0x02, 0x68, 0xe2, 0xfe, 0x3c, 0xe2, - 0xfe, 0x73, 0x03, 0x1a, 0x01, 0x6b, 0x01, 0xc4, 0xfd, 0x58, 0x03, 0x1a, - 0x00, 0x01, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x02, - 0x00, 0x00, 0x13, 0x01, 0x11, 0x06, 0x04, 0xc5, 0x02, 0x14, 0x02, 0x62, - 0xfb, 0x3c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, - 0x04, 0x77, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x13, 0x01, 0x11, 0x09, - 0x01, 0x11, 0xea, 0x03, 0x6f, 0xfb, 0xad, 0x04, 0xc5, 0x02, 0x14, 0xfe, - 0x48, 0x03, 0x70, 0xfe, 0x48, 0x02, 0x62, 0xfb, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xdb, 0x00, 0x87, 0x03, 0xf5, 0x03, 0xa1, 0x00, 0x02, - 0x00, 0x00, 0x13, 0x01, 0x11, 0xdb, 0x03, 0x1a, 0x02, 0x14, 0x01, 0x8d, - 0xfc, 0xe6, 0x00, 0x00, 0x00, 0x02, 0x00, 0xdb, 0x00, 0x87, 0x03, 0xf5, - 0x03, 0xa1, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x01, 0x05, 0x11, 0x05, - 0x01, 0x11, 0x01, 0xbf, 0x01, 0xc4, 0xfd, 0x58, 0x03, 0x1a, 0x02, 0x14, - 0xe2, 0x01, 0xc4, 0xe2, 0x01, 0x8d, 0xfc, 0xe6, 0x00, 0x01, 0x00, 0x06, - 0x00, 0x87, 0x04, 0xcb, 0x03, 0xa1, 0x00, 0x02, 0x00, 0x00, 0x13, 0x01, - 0x11, 0x06, 0x04, 0xc5, 0x02, 0x14, 0x01, 0x8d, 0xfc, 0xe6, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x06, 0x00, 0x87, 0x04, 0xcb, 0x03, 0xa1, 0x00, 0x02, - 0x00, 0x05, 0x00, 0x00, 0x01, 0x05, 0x11, 0x05, 0x01, 0x11, 0x01, 0x23, - 0x03, 0x36, 0xfb, 0xad, 0x04, 0xc5, 0x02, 0x14, 0xe2, 0x01, 0xc4, 0xe2, - 0x01, 0x8d, 0xfc, 0xe6, 0x00, 0x01, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, - 0x04, 0x77, 0x00, 0x03, 0x00, 0x00, 0x13, 0x09, 0x02, 0x06, 0x02, 0x62, - 0x02, 0x63, 0xfd, 0x9d, 0x02, 0x14, 0x02, 0x62, 0xfd, 0x9e, 0xfd, 0x9e, - 0x00, 0x02, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x00, 0x13, 0x09, 0x06, 0xc3, 0x01, 0xa5, 0x01, 0xa6, - 0xfe, 0x5a, 0xfd, 0x9e, 0x02, 0x62, 0x02, 0x63, 0xfd, 0x9d, 0x02, 0x14, - 0xfe, 0x5a, 0x01, 0xa6, 0x01, 0xa6, 0xfe, 0x5a, 0x02, 0x62, 0xfd, 0x9e, - 0xfd, 0x9e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, - 0x04, 0x77, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x00, 0x13, 0x09, - 0x0a, 0xfa, 0x01, 0x6e, 0x01, 0x6e, 0xfe, 0x92, 0xfe, 0x36, 0x01, 0xca, - 0x01, 0xcb, 0xfe, 0x35, 0xfd, 0x9e, 0x02, 0x62, 0x02, 0x63, 0xfd, 0x9d, - 0x02, 0x14, 0x01, 0x6e, 0xfe, 0x92, 0xfe, 0x92, 0x01, 0x6e, 0xfe, 0x36, - 0x01, 0xca, 0x01, 0xca, 0xfe, 0x36, 0x02, 0x62, 0xfd, 0x9e, 0xfd, 0x9e, - 0x00, 0x03, 0x00, 0x06, 0xff, 0xac, 0x04, 0xcb, 0x04, 0x7c, 0x00, 0x0d, - 0x00, 0x1b, 0x00, 0x29, 0x00, 0x00, 0x12, 0x10, 0x37, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x10, 0x07, 0x06, 0x23, 0x22, 0x27, 0x00, 0x10, 0x17, 0x16, - 0x33, 0x32, 0x37, 0x36, 0x10, 0x27, 0x26, 0x23, 0x22, 0x07, 0x00, 0x10, - 0x25, 0x36, 0x33, 0x32, 0x17, 0x04, 0x10, 0x05, 0x06, 0x23, 0x22, 0x27, - 0xdc, 0xc6, 0x63, 0x63, 0x63, 0x63, 0xc7, 0xc7, 0x63, 0x63, 0x63, 0x63, - 0xfe, 0xde, 0xf4, 0x7a, 0x7a, 0x7a, 0x7a, 0xf5, 0xf5, 0x7a, 0x7a, 0x7a, - 0x7a, 0xfe, 0x92, 0x01, 0x31, 0x98, 0x99, 0x98, 0x99, 0x01, 0x32, 0xfe, - 0xce, 0x99, 0x98, 0x99, 0x98, 0x01, 0x2f, 0x01, 0xca, 0x72, 0x39, 0x39, - 0x72, 0xfe, 0x36, 0x72, 0x39, 0x39, 0x02, 0x71, 0xfd, 0xcc, 0x8c, 0x47, - 0x47, 0x8d, 0x02, 0x32, 0x8d, 0x47, 0x47, 0xfc, 0xfa, 0x02, 0xc0, 0xb0, - 0x58, 0x58, 0xb0, 0xfd, 0x40, 0xb0, 0x58, 0x58, 0x00, 0x02, 0x00, 0x75, - 0xfe, 0x23, 0x04, 0x5c, 0x06, 0x75, 0x00, 0x03, 0x00, 0x07, 0x00, 0x22, - 0x40, 0x11, 0x02, 0x06, 0x00, 0x08, 0x04, 0x06, 0x08, 0x06, 0x04, 0x03, - 0x02, 0x01, 0x00, 0x06, 0x05, 0x07, 0x08, 0x10, 0xd4, 0xcc, 0x17, 0x39, - 0x31, 0x00, 0x10, 0xd4, 0xcc, 0x11, 0x39, 0x12, 0x39, 0x30, 0x09, 0x07, - 0x02, 0x68, 0xfe, 0x7f, 0x01, 0x81, 0x01, 0x81, 0xfe, 0x7f, 0x01, 0xf4, - 0xfe, 0x0c, 0xfe, 0x0d, 0x05, 0x81, 0xfc, 0xcf, 0xfc, 0xc7, 0x03, 0x39, - 0x04, 0x25, 0xfb, 0xdb, 0xfb, 0xd3, 0x04, 0x2d, 0x00, 0x02, 0x00, 0x06, - 0xff, 0xac, 0x04, 0xcb, 0x04, 0x7c, 0x00, 0x0d, 0x00, 0x1b, 0x00, 0x00, - 0x12, 0x10, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x10, 0x27, 0x26, 0x23, - 0x22, 0x07, 0x00, 0x10, 0x25, 0x36, 0x33, 0x32, 0x17, 0x04, 0x10, 0x05, - 0x06, 0x23, 0x22, 0x27, 0x80, 0xf4, 0x7a, 0x7a, 0x7a, 0x7a, 0xf5, 0xf5, - 0x7a, 0x7a, 0x7a, 0x7a, 0xfe, 0x92, 0x01, 0x31, 0x98, 0x99, 0x98, 0x99, - 0x01, 0x32, 0xfe, 0xce, 0x99, 0x98, 0x99, 0x98, 0x03, 0x2e, 0xfd, 0xcc, - 0x8c, 0x47, 0x47, 0x8d, 0x02, 0x32, 0x8d, 0x47, 0x47, 0xfc, 0xfa, 0x02, - 0xc0, 0xb0, 0x58, 0x58, 0xb0, 0xfd, 0x40, 0xb0, 0x58, 0x58, 0x00, 0x00, - 0x00, 0x08, 0x00, 0x06, 0xff, 0xac, 0x04, 0xcb, 0x04, 0x7c, 0x00, 0x09, - 0x00, 0x13, 0x00, 0x1d, 0x00, 0x27, 0x00, 0x2f, 0x00, 0x37, 0x00, 0x3f, - 0x00, 0x47, 0x00, 0x00, 0x37, 0x16, 0x17, 0x16, 0x17, 0x07, 0x26, 0x27, - 0x26, 0x27, 0x05, 0x36, 0x37, 0x36, 0x37, 0x17, 0x06, 0x07, 0x06, 0x07, - 0x13, 0x26, 0x27, 0x26, 0x27, 0x37, 0x16, 0x17, 0x16, 0x17, 0x25, 0x06, - 0x07, 0x06, 0x07, 0x27, 0x36, 0x37, 0x36, 0x37, 0x13, 0x16, 0x32, 0x37, - 0x17, 0x06, 0x22, 0x27, 0x01, 0x36, 0x34, 0x27, 0x37, 0x16, 0x14, 0x07, - 0x01, 0x26, 0x22, 0x07, 0x27, 0x36, 0x32, 0x17, 0x01, 0x06, 0x14, 0x17, - 0x07, 0x26, 0x34, 0x37, 0xd4, 0x22, 0x2e, 0x24, 0x2c, 0x3d, 0x37, 0x2d, - 0x3a, 0x2a, 0x02, 0xed, 0x2c, 0x24, 0x29, 0x27, 0x65, 0x31, 0x33, 0x2d, - 0x37, 0x63, 0x22, 0x2e, 0x24, 0x2c, 0x3d, 0x37, 0x2d, 0x3a, 0x2a, 0xfd, - 0x13, 0x2c, 0x24, 0x2e, 0x22, 0x65, 0x2a, 0x3a, 0x2d, 0x37, 0xb9, 0x3c, - 0x78, 0x3c, 0x1e, 0x4b, 0x96, 0x4b, 0x02, 0x72, 0x0d, 0x0d, 0x77, 0x10, - 0x10, 0xfe, 0x25, 0x3c, 0x78, 0x3c, 0x1e, 0x4b, 0x96, 0x4b, 0xfd, 0x8f, - 0x0d, 0x0d, 0x77, 0x10, 0x10, 0xfa, 0x2f, 0x26, 0x1e, 0x19, 0x6a, 0x20, - 0x25, 0x30, 0x3a, 0x45, 0x19, 0x1e, 0x22, 0x33, 0x46, 0x41, 0x2a, 0x25, - 0x20, 0x03, 0x2a, 0x2f, 0x26, 0x1e, 0x19, 0x6a, 0x20, 0x25, 0x30, 0x3a, - 0x45, 0x19, 0x1e, 0x26, 0x2f, 0x47, 0x3a, 0x30, 0x25, 0x20, 0xfc, 0x14, - 0x11, 0x11, 0x77, 0x15, 0x15, 0x01, 0xdb, 0x39, 0x7e, 0x39, 0x1e, 0x47, - 0x9e, 0x47, 0x02, 0x72, 0x11, 0x11, 0x77, 0x15, 0x15, 0xfe, 0x25, 0x39, - 0x7e, 0x39, 0x1e, 0x47, 0x9e, 0x47, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, - 0xff, 0xac, 0x04, 0xcb, 0x04, 0x7c, 0x00, 0x0d, 0x00, 0x17, 0x00, 0x1b, - 0x00, 0x25, 0x00, 0x2f, 0x00, 0x33, 0x00, 0x00, 0x36, 0x10, 0x25, 0x36, - 0x33, 0x32, 0x17, 0x04, 0x10, 0x05, 0x06, 0x23, 0x22, 0x27, 0x13, 0x11, - 0x16, 0x17, 0x16, 0x17, 0x11, 0x06, 0x07, 0x06, 0x07, 0x06, 0x10, 0x17, - 0x01, 0x11, 0x16, 0x33, 0x32, 0x37, 0x11, 0x26, 0x23, 0x22, 0x17, 0x11, - 0x36, 0x37, 0x36, 0x37, 0x11, 0x26, 0x27, 0x26, 0x17, 0x11, 0x36, 0x10, - 0x06, 0x01, 0x31, 0x98, 0x99, 0x98, 0x99, 0x01, 0x32, 0xfe, 0xce, 0x99, - 0x98, 0x99, 0x98, 0x1d, 0x0f, 0x11, 0x26, 0x26, 0x26, 0x26, 0x11, 0x81, - 0x62, 0x62, 0x01, 0x50, 0x1b, 0x1b, 0x1a, 0x1a, 0x1a, 0x1a, 0x1b, 0xc1, - 0x27, 0x27, 0x0e, 0x0e, 0x0e, 0x0e, 0x27, 0xb5, 0x67, 0xb4, 0x02, 0xc0, - 0xb0, 0x58, 0x58, 0xb0, 0xfd, 0x40, 0xb0, 0x58, 0x58, 0x03, 0xa3, 0xfc, - 0xda, 0x0a, 0x09, 0x16, 0x0f, 0x03, 0x96, 0x0f, 0x16, 0x09, 0x71, 0x7a, - 0xfe, 0x9c, 0x7a, 0x03, 0x15, 0xfc, 0x2e, 0x04, 0x03, 0x03, 0xd4, 0x03, - 0x21, 0xfc, 0x68, 0x0f, 0x17, 0x08, 0x09, 0x03, 0x2a, 0x09, 0x08, 0x17, - 0x8b, 0xfd, 0x9c, 0x7c, 0x01, 0x6c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x06, - 0xff, 0xac, 0x04, 0xcb, 0x04, 0x7c, 0x00, 0x0d, 0x00, 0x1b, 0x00, 0x29, - 0x00, 0x37, 0x00, 0x00, 0x00, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, - 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x02, 0x10, 0x37, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x10, 0x07, 0x06, 0x23, 0x22, 0x27, 0x00, 0x10, 0x17, 0x16, - 0x33, 0x32, 0x37, 0x36, 0x10, 0x27, 0x26, 0x23, 0x22, 0x07, 0x00, 0x10, - 0x25, 0x36, 0x33, 0x32, 0x17, 0x04, 0x10, 0x05, 0x06, 0x23, 0x22, 0x27, - 0x01, 0xe2, 0x43, 0x22, 0x21, 0x22, 0x21, 0x44, 0x44, 0x21, 0x22, 0x21, - 0x22, 0xb1, 0x7a, 0x3d, 0x3d, 0x3d, 0x3d, 0x7b, 0x7b, 0x3d, 0x3d, 0x3d, - 0x3d, 0xfe, 0x92, 0xf4, 0x7a, 0x7a, 0x7a, 0x7a, 0xf5, 0xf5, 0x7a, 0x7a, - 0x7a, 0x7a, 0xfe, 0x92, 0x01, 0x31, 0x98, 0x99, 0x98, 0x99, 0x01, 0x32, - 0xfe, 0xce, 0x99, 0x98, 0x99, 0x98, 0x02, 0x61, 0x9a, 0x27, 0x14, 0x14, - 0x27, 0x9a, 0x27, 0x14, 0x14, 0xfe, 0xff, 0x01, 0x1a, 0x46, 0x23, 0x23, - 0x46, 0xfe, 0xe6, 0x46, 0x23, 0x23, 0x01, 0xed, 0xfd, 0xcc, 0x8c, 0x47, - 0x47, 0x8d, 0x02, 0x32, 0x8d, 0x47, 0x47, 0xfc, 0xfa, 0x02, 0xc0, 0xb0, - 0x58, 0x58, 0xb0, 0xfd, 0x40, 0xb0, 0x58, 0x58, 0x00, 0x01, 0x00, 0x06, - 0xff, 0xac, 0x04, 0xcb, 0x04, 0x7c, 0x00, 0x0d, 0x00, 0x00, 0x36, 0x10, - 0x25, 0x36, 0x33, 0x32, 0x17, 0x04, 0x10, 0x05, 0x06, 0x23, 0x22, 0x27, - 0x06, 0x01, 0x31, 0x98, 0x99, 0x98, 0x99, 0x01, 0x32, 0xfe, 0xce, 0x99, - 0x98, 0x99, 0x98, 0xb4, 0x02, 0xc0, 0xb0, 0x58, 0x58, 0xb0, 0xfd, 0x40, - 0xb0, 0x58, 0x58, 0x00, 0x00, 0x02, 0x00, 0x06, 0xff, 0xac, 0x04, 0xcb, - 0x04, 0x7c, 0x00, 0x07, 0x00, 0x15, 0x00, 0x00, 0x25, 0x32, 0x37, 0x36, - 0x10, 0x27, 0x26, 0x23, 0x00, 0x10, 0x25, 0x36, 0x33, 0x32, 0x17, 0x04, - 0x10, 0x05, 0x06, 0x23, 0x22, 0x27, 0x02, 0x68, 0x7a, 0x7a, 0xf5, 0xf5, - 0x7a, 0x7a, 0xfd, 0x9e, 0x01, 0x31, 0x98, 0x99, 0x98, 0x99, 0x01, 0x32, - 0xfe, 0xce, 0x99, 0x98, 0x99, 0x98, 0x27, 0x47, 0x8d, 0x02, 0x32, 0x8d, - 0x47, 0xfc, 0xb3, 0x02, 0xc0, 0xb0, 0x58, 0x58, 0xb0, 0xfd, 0x40, 0xb0, - 0x58, 0x58, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0xff, 0xac, 0x04, 0xcb, - 0x04, 0x7c, 0x00, 0x07, 0x00, 0x15, 0x00, 0x00, 0x01, 0x22, 0x07, 0x06, - 0x10, 0x17, 0x16, 0x33, 0x24, 0x10, 0x25, 0x36, 0x33, 0x32, 0x17, 0x04, - 0x10, 0x05, 0x06, 0x23, 0x22, 0x27, 0x02, 0x68, 0x7a, 0x7a, 0xf4, 0xf4, - 0x7a, 0x7a, 0xfd, 0x9e, 0x01, 0x31, 0x98, 0x99, 0x98, 0x99, 0x01, 0x32, - 0xfe, 0xce, 0x99, 0x98, 0x99, 0x98, 0x04, 0x01, 0x47, 0x8c, 0xfd, 0xcc, - 0x8c, 0x47, 0x8d, 0x02, 0xc0, 0xb0, 0x58, 0x58, 0xb0, 0xfd, 0x40, 0xb0, - 0x58, 0x58, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0xff, 0xac, 0x04, 0xcb, - 0x04, 0x7c, 0x00, 0x08, 0x00, 0x16, 0x00, 0x00, 0x01, 0x10, 0x27, 0x26, - 0x23, 0x22, 0x07, 0x06, 0x11, 0x02, 0x10, 0x25, 0x36, 0x33, 0x32, 0x17, - 0x04, 0x10, 0x05, 0x06, 0x23, 0x22, 0x27, 0x04, 0x51, 0xf5, 0x7a, 0x7a, - 0x7a, 0x7a, 0xf4, 0x7a, 0x01, 0x31, 0x98, 0x99, 0x98, 0x99, 0x01, 0x32, - 0xfe, 0xce, 0x99, 0x98, 0x99, 0x98, 0x02, 0x14, 0x01, 0x19, 0x8d, 0x47, - 0x47, 0x8c, 0xfe, 0xe6, 0xfe, 0xa0, 0x02, 0xc0, 0xb0, 0x58, 0x58, 0xb0, - 0xfd, 0x40, 0xb0, 0x58, 0x58, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, - 0xff, 0xac, 0x04, 0xcb, 0x04, 0x7c, 0x00, 0x08, 0x00, 0x16, 0x00, 0x00, - 0x13, 0x10, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x11, 0x00, 0x10, 0x25, - 0x36, 0x33, 0x32, 0x17, 0x04, 0x10, 0x05, 0x06, 0x23, 0x22, 0x27, 0x80, - 0xf4, 0x7a, 0x7a, 0x7a, 0x7a, 0xf5, 0xfb, 0xb5, 0x01, 0x31, 0x98, 0x99, - 0x98, 0x99, 0x01, 0x32, 0xfe, 0xce, 0x99, 0x98, 0x99, 0x98, 0x02, 0x14, - 0xfe, 0xe6, 0x8c, 0x47, 0x47, 0x8d, 0x01, 0x19, 0xfe, 0xa0, 0x02, 0xc0, - 0xb0, 0x58, 0x58, 0xb0, 0xfd, 0x40, 0xb0, 0x58, 0x58, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x06, 0xff, 0xac, 0x04, 0xcb, 0x04, 0x7c, 0x00, 0x0c, - 0x00, 0x1a, 0x00, 0x00, 0x01, 0x22, 0x07, 0x06, 0x10, 0x17, 0x16, 0x33, - 0x32, 0x37, 0x36, 0x11, 0x21, 0x00, 0x10, 0x25, 0x36, 0x33, 0x32, 0x17, - 0x04, 0x10, 0x05, 0x06, 0x23, 0x22, 0x27, 0x02, 0x68, 0x7a, 0x7a, 0xf4, - 0xf4, 0x7a, 0x7a, 0x7a, 0x7a, 0xf5, 0xfe, 0x17, 0xfd, 0x9e, 0x01, 0x31, - 0x98, 0x99, 0x98, 0x99, 0x01, 0x32, 0xfe, 0xce, 0x99, 0x98, 0x99, 0x98, - 0x04, 0x01, 0x47, 0x8c, 0xfd, 0xcc, 0x8c, 0x47, 0x47, 0x8d, 0x01, 0x19, - 0xfe, 0xa0, 0x02, 0xc0, 0xb0, 0x58, 0x58, 0xb0, 0xfd, 0x40, 0xb0, 0x58, - 0x58, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0xff, 0xac, 0x04, 0xcb, - 0x04, 0x7c, 0x00, 0x05, 0x00, 0x13, 0x00, 0x00, 0x01, 0x22, 0x07, 0x06, - 0x11, 0x21, 0x00, 0x10, 0x25, 0x36, 0x33, 0x32, 0x17, 0x04, 0x10, 0x05, - 0x06, 0x23, 0x22, 0x27, 0x02, 0x68, 0x7a, 0x7a, 0xf4, 0x01, 0xe8, 0xfd, - 0x9e, 0x01, 0x31, 0x98, 0x99, 0x98, 0x99, 0x01, 0x32, 0xfe, 0xce, 0x99, - 0x98, 0x99, 0x98, 0x04, 0x01, 0x47, 0x8c, 0xfe, 0xe6, 0xfe, 0xa0, 0x02, - 0xc0, 0xb0, 0x58, 0x58, 0xb0, 0xfd, 0x40, 0xb0, 0x58, 0x58, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x37, 0xff, 0xac, 0x03, 0x9a, 0x04, 0x7c, 0x00, 0x07, - 0x00, 0x00, 0x05, 0x22, 0x27, 0x24, 0x10, 0x25, 0x36, 0x33, 0x03, 0x9a, - 0x9a, 0x98, 0xfe, 0xd0, 0x01, 0x30, 0x98, 0x9a, 0x54, 0x58, 0xb0, 0x02, - 0xc0, 0xb0, 0x58, 0x00, 0x00, 0x01, 0x01, 0x37, 0xff, 0xac, 0x03, 0x9a, - 0x04, 0x7c, 0x00, 0x07, 0x00, 0x00, 0x01, 0x32, 0x17, 0x04, 0x10, 0x05, - 0x06, 0x23, 0x01, 0x38, 0x96, 0x9a, 0x01, 0x32, 0xfe, 0xce, 0x9a, 0x96, - 0x04, 0x7c, 0x58, 0xb0, 0xfd, 0x40, 0xae, 0x5a, 0x00, 0x02, 0xff, 0xec, - 0xff, 0xec, 0x04, 0xe5, 0x06, 0x28, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x00, - 0x01, 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, - 0x01, 0x11, 0x21, 0x11, 0x01, 0x3f, 0xab, 0x7c, 0x7d, 0xae, 0xad, 0x7c, - 0x7d, 0xac, 0xfe, 0xad, 0x04, 0xf9, 0x02, 0xfa, 0x7e, 0xab, 0xad, 0x7c, - 0x7b, 0xac, 0xab, 0xfc, 0x76, 0x06, 0x3c, 0xf9, 0xc4, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xff, 0xec, 0xfe, 0x00, 0x04, 0xe5, 0x06, 0x28, 0x00, 0x0d, - 0x00, 0x1b, 0x00, 0x1f, 0x00, 0x00, 0x36, 0x10, 0x37, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x10, 0x07, 0x06, 0x23, 0x22, 0x27, 0x00, 0x10, 0x05, 0x16, - 0x33, 0x32, 0x37, 0x24, 0x10, 0x25, 0x26, 0x23, 0x22, 0x07, 0x01, 0x11, - 0x21, 0x11, 0x80, 0xf4, 0x7a, 0x7a, 0x7a, 0x7a, 0xf5, 0xf5, 0x7a, 0x7a, - 0x7a, 0x7a, 0xfe, 0x92, 0x01, 0x31, 0x98, 0x99, 0x98, 0x99, 0x01, 0x32, - 0xfe, 0xce, 0x99, 0x98, 0x99, 0x98, 0xfe, 0xb5, 0x04, 0xf9, 0xfa, 0x02, - 0x34, 0x8c, 0x47, 0x47, 0x8d, 0xfd, 0xce, 0x8d, 0x47, 0x47, 0x03, 0x06, - 0xfd, 0x40, 0xb0, 0x58, 0x58, 0xb0, 0x02, 0xc0, 0xb0, 0x58, 0x58, 0xf9, - 0xdc, 0x08, 0x28, 0xf7, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, - 0x02, 0x14, 0x04, 0xe5, 0x06, 0x28, 0x00, 0x0c, 0x00, 0x15, 0x00, 0x00, - 0x03, 0x11, 0x21, 0x11, 0x23, 0x10, 0x25, 0x26, 0x23, 0x22, 0x07, 0x04, - 0x11, 0x29, 0x01, 0x10, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x14, 0x04, - 0xf9, 0x1a, 0xfe, 0xce, 0x99, 0x98, 0x99, 0x98, 0xfe, 0xcf, 0x04, 0x4b, - 0xfc, 0x2f, 0xf4, 0x7a, 0x7a, 0x7a, 0x7a, 0xf5, 0x02, 0x14, 0x04, 0x14, - 0xfb, 0xec, 0x01, 0x60, 0xb0, 0x58, 0x58, 0xb0, 0xfe, 0xa0, 0x01, 0x19, - 0x8d, 0x47, 0x47, 0x8d, 0x00, 0x02, 0xff, 0xec, 0xfe, 0x00, 0x04, 0xe5, - 0x02, 0x14, 0x00, 0x0c, 0x00, 0x15, 0x00, 0x00, 0x03, 0x11, 0x33, 0x10, - 0x05, 0x16, 0x33, 0x32, 0x37, 0x24, 0x11, 0x33, 0x11, 0x01, 0x21, 0x10, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x14, 0x1a, 0x01, 0x31, 0x98, 0x99, - 0x98, 0x99, 0x01, 0x32, 0x1a, 0xfb, 0x9b, 0x03, 0xd1, 0xf5, 0x7a, 0x7a, - 0x7a, 0x7a, 0xf4, 0xfe, 0x00, 0x04, 0x14, 0xfe, 0xa0, 0xb0, 0x58, 0x58, - 0xb0, 0x01, 0x60, 0xfb, 0xec, 0x04, 0x14, 0xfe, 0xe7, 0x8d, 0x47, 0x47, - 0x8d, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x37, 0x02, 0x14, 0x03, 0x9a, - 0x04, 0x7c, 0x00, 0x09, 0x00, 0x00, 0x01, 0x10, 0x25, 0x36, 0x33, 0x17, - 0x22, 0x07, 0x06, 0x11, 0x01, 0x37, 0x01, 0x31, 0x98, 0x99, 0x01, 0x7b, - 0x79, 0xf4, 0x02, 0x14, 0x01, 0x60, 0xb0, 0x58, 0x7b, 0x47, 0x8c, 0xfe, - 0xe6, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x37, 0x02, 0x14, 0x03, 0x9a, - 0x04, 0x7c, 0x00, 0x09, 0x00, 0x00, 0x01, 0x32, 0x17, 0x04, 0x11, 0x23, - 0x10, 0x27, 0x26, 0x23, 0x01, 0x38, 0x96, 0x9a, 0x01, 0x32, 0x7b, 0xf4, - 0x7b, 0x78, 0x04, 0x7c, 0x58, 0xb0, 0xfe, 0xa0, 0x01, 0x19, 0x8d, 0x47, - 0x00, 0x01, 0x01, 0x37, 0xff, 0xac, 0x03, 0x9a, 0x02, 0x14, 0x00, 0x09, - 0x00, 0x00, 0x05, 0x35, 0x32, 0x37, 0x36, 0x11, 0x33, 0x10, 0x05, 0x06, - 0x01, 0x38, 0x78, 0x7b, 0xf4, 0x7b, 0xfe, 0xce, 0x9a, 0x54, 0x7b, 0x47, - 0x8d, 0x01, 0x19, 0xfe, 0xa0, 0xae, 0x5a, 0x00, 0x00, 0x01, 0x01, 0x37, - 0xff, 0xac, 0x03, 0x9a, 0x02, 0x14, 0x00, 0x09, 0x00, 0x00, 0x05, 0x22, - 0x27, 0x24, 0x11, 0x33, 0x10, 0x17, 0x16, 0x33, 0x03, 0x99, 0x99, 0x98, - 0xfe, 0xcf, 0x7b, 0xf4, 0x79, 0x7b, 0x54, 0x58, 0xb0, 0x01, 0x60, 0xfe, - 0xe6, 0x8c, 0x47, 0x00, 0x00, 0x01, 0x00, 0x06, 0x02, 0x14, 0x04, 0xcb, - 0x04, 0x7c, 0x00, 0x11, 0x00, 0x00, 0x13, 0x10, 0x25, 0x36, 0x33, 0x32, - 0x17, 0x04, 0x11, 0x23, 0x10, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x11, - 0x06, 0x01, 0x31, 0x98, 0x99, 0x98, 0x99, 0x01, 0x32, 0x7a, 0xf5, 0x7a, - 0x7a, 0x7a, 0x7a, 0xf4, 0x02, 0x14, 0x01, 0x60, 0xb0, 0x58, 0x58, 0xb0, - 0xfe, 0xa0, 0x01, 0x19, 0x8d, 0x47, 0x47, 0x8c, 0xfe, 0xe6, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x06, 0xff, 0xac, 0x04, 0xcb, 0x02, 0x14, 0x00, 0x12, - 0x00, 0x00, 0x13, 0x30, 0x33, 0x10, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, - 0x11, 0x33, 0x10, 0x05, 0x06, 0x23, 0x22, 0x27, 0x24, 0x06, 0x7a, 0xf4, - 0x7a, 0x7a, 0x7a, 0x7a, 0xf5, 0x7a, 0xfe, 0xce, 0x99, 0x98, 0x99, 0x98, - 0xfe, 0xcf, 0x02, 0x14, 0xfe, 0xe6, 0x8c, 0x47, 0x47, 0x8d, 0x01, 0x19, - 0xfe, 0xa0, 0xb0, 0x58, 0x58, 0xb0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, - 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x02, 0x00, 0x00, 0x17, 0x01, - 0x11, 0x06, 0x04, 0xc5, 0x4e, 0x04, 0xc4, 0xfb, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x02, - 0x00, 0x00, 0x17, 0x11, 0x01, 0x06, 0x04, 0xc5, 0x4e, 0x04, 0xc4, 0xfb, - 0x3c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, - 0x04, 0x77, 0x00, 0x02, 0x00, 0x00, 0x17, 0x11, 0x21, 0x06, 0x04, 0xc5, - 0x4e, 0x04, 0xc4, 0x00, 0x00, 0x01, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, - 0x04, 0x77, 0x00, 0x02, 0x00, 0x00, 0x13, 0x21, 0x11, 0x06, 0x04, 0xc5, - 0x04, 0x76, 0xfb, 0x3c, 0x00, 0x02, 0x01, 0x3f, 0x01, 0xd1, 0x03, 0x91, - 0x04, 0x21, 0x00, 0x0b, 0x00, 0x17, 0x00, 0x00, 0x01, 0x14, 0x16, 0x33, - 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x34, 0x36, 0x33, - 0x32, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x01, 0x7a, 0x89, 0x63, - 0x64, 0x8c, 0x8b, 0x63, 0x64, 0x8a, 0x3b, 0xac, 0x7d, 0x7c, 0xad, 0xae, - 0x7d, 0x7c, 0xab, 0x02, 0xfa, 0x65, 0x89, 0x8b, 0x63, 0x62, 0x8a, 0x89, - 0x63, 0x7c, 0xab, 0xac, 0x7b, 0x7c, 0xad, 0xab, 0x00, 0x02, 0x00, 0x06, - 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, - 0x25, 0x21, 0x11, 0x21, 0x01, 0x11, 0x21, 0x11, 0x02, 0x68, 0x01, 0xf0, - 0xfe, 0x10, 0xfd, 0x9e, 0x04, 0xc5, 0x24, 0x03, 0xe0, 0xfb, 0xae, 0x04, - 0xc4, 0xfb, 0x3c, 0x00, 0x00, 0x02, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, - 0x04, 0x77, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x37, 0x21, 0x11, 0x21, - 0x03, 0x11, 0x21, 0x11, 0x78, 0x01, 0xf0, 0xfe, 0x10, 0x72, 0x04, 0xc5, - 0x24, 0x03, 0xe0, 0xfb, 0xae, 0x04, 0xc4, 0xfb, 0x3c, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x02, - 0x00, 0x06, 0x00, 0x00, 0x37, 0x21, 0x11, 0x01, 0x11, 0x21, 0x11, 0x78, - 0x03, 0xe0, 0xfb, 0xae, 0x04, 0xc5, 0x24, 0x03, 0xe0, 0xfb, 0xae, 0x04, - 0xc4, 0xfb, 0x3c, 0x00, 0x00, 0x02, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, - 0x04, 0x77, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x37, 0x01, 0x21, 0x03, - 0x11, 0x21, 0x11, 0x78, 0x03, 0xe1, 0xfc, 0x1f, 0x72, 0x04, 0xc5, 0x24, - 0x03, 0xe0, 0xfb, 0xae, 0x04, 0xc4, 0xfb, 0x3c, 0x00, 0x03, 0x00, 0x06, - 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, - 0x00, 0x00, 0x25, 0x21, 0x11, 0x21, 0x01, 0x21, 0x11, 0x21, 0x03, 0x11, - 0x21, 0x11, 0x02, 0xa1, 0x01, 0xb7, 0xfe, 0x49, 0xfd, 0xd7, 0x01, 0xb7, - 0xfe, 0x49, 0x72, 0x04, 0xc5, 0x24, 0x03, 0xe0, 0xfc, 0x20, 0x03, 0xe0, - 0xfb, 0xae, 0x04, 0xc4, 0xfb, 0x3c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x06, - 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x0b, 0x00, 0x0e, 0x00, 0x11, - 0x00, 0x00, 0x01, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, 0x23, - 0x22, 0x26, 0x01, 0x21, 0x09, 0x03, 0x01, 0xe2, 0x4e, 0x38, 0x38, 0x4e, - 0x4f, 0x38, 0x38, 0x4d, 0xfe, 0xcf, 0x03, 0x6f, 0xfe, 0x48, 0xfd, 0x9e, - 0x02, 0x62, 0x02, 0x63, 0x01, 0x6a, 0x38, 0x4d, 0x4d, 0x38, 0x37, 0x4e, - 0x4d, 0xfe, 0xf2, 0x03, 0x6e, 0xfc, 0x20, 0x04, 0xc4, 0xfb, 0x3c, 0x00, - 0x00, 0x02, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x02, - 0x00, 0x05, 0x00, 0x00, 0x25, 0x21, 0x09, 0x03, 0x02, 0x68, 0x01, 0xb8, - 0xfe, 0x48, 0xfd, 0x9e, 0x02, 0x62, 0x02, 0x63, 0x24, 0x03, 0x6e, 0xfc, - 0x20, 0x04, 0xc4, 0xfb, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, - 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, - 0x37, 0x21, 0x11, 0x09, 0x02, 0xb1, 0x01, 0xb7, 0xfd, 0x9e, 0x02, 0x62, - 0x02, 0x63, 0x24, 0x03, 0x6e, 0xfc, 0x20, 0x04, 0xc4, 0xfb, 0x3c, 0x00, - 0x00, 0x02, 0xff, 0xec, 0xff, 0x92, 0x04, 0xe5, 0x04, 0x96, 0x00, 0x0d, - 0x00, 0x1b, 0x00, 0x00, 0x12, 0x10, 0x05, 0x16, 0x33, 0x32, 0x37, 0x24, - 0x10, 0x27, 0x26, 0x23, 0x22, 0x07, 0x00, 0x10, 0x25, 0x36, 0x33, 0x32, - 0x17, 0x04, 0x10, 0x05, 0x06, 0x23, 0x22, 0x27, 0x6b, 0x00, 0xff, 0x7e, - 0x80, 0x7f, 0x80, 0x00, 0xff, 0xff, 0x80, 0x7f, 0x80, 0x7e, 0xfe, 0x82, - 0x01, 0x3e, 0x9e, 0xa0, 0x9f, 0x9f, 0x01, 0x3f, 0xfe, 0xc1, 0x9f, 0x9f, - 0xa0, 0x9e, 0x03, 0x3a, 0xfd, 0xb4, 0x93, 0x49, 0x49, 0x93, 0x02, 0x4c, - 0x93, 0x49, 0x49, 0xfc, 0xd8, 0x02, 0xde, 0xb8, 0x5b, 0x5b, 0xb8, 0xfd, - 0x22, 0xb8, 0x5b, 0x5b, 0x00, 0x03, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, - 0x04, 0x77, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0d, 0x00, 0x00, 0x17, 0x11, - 0x21, 0x11, 0x01, 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, - 0x06, 0x04, 0xc5, 0xfb, 0xad, 0x01, 0xb7, 0xfe, 0x49, 0x03, 0xe0, 0xfe, - 0x49, 0xfd, 0xd7, 0x4e, 0x04, 0xc4, 0xfb, 0x3c, 0x02, 0x9a, 0x01, 0xb8, - 0xfc, 0x20, 0x03, 0xe0, 0xfd, 0xd6, 0x00, 0x00, 0x00, 0x03, 0x00, 0x06, - 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0d, - 0x00, 0x00, 0x17, 0x11, 0x21, 0x11, 0x25, 0x21, 0x11, 0x21, 0x35, 0x21, - 0x11, 0x21, 0x11, 0x21, 0x06, 0x04, 0xc5, 0xfb, 0xad, 0x01, 0xb7, 0xfe, - 0x49, 0x02, 0x29, 0x01, 0xb7, 0xfc, 0x20, 0x4e, 0x04, 0xc4, 0xfb, 0x3c, - 0x72, 0x01, 0xb6, 0x72, 0xfd, 0xd8, 0x03, 0xe0, 0x00, 0x03, 0x00, 0x06, - 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0d, - 0x00, 0x00, 0x17, 0x11, 0x21, 0x11, 0x25, 0x21, 0x11, 0x21, 0x01, 0x21, - 0x11, 0x21, 0x11, 0x21, 0x06, 0x04, 0xc5, 0xfd, 0xd6, 0x01, 0xb7, 0xfe, - 0x49, 0xfd, 0xd7, 0x01, 0xb7, 0x02, 0x29, 0xfc, 0x20, 0x4e, 0x04, 0xc4, - 0xfb, 0x3c, 0x72, 0x01, 0xb6, 0xfe, 0x4a, 0x02, 0x28, 0x01, 0xb8, 0x00, - 0x00, 0x03, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x0d, 0x00, 0x00, 0x17, 0x11, 0x21, 0x11, 0x01, 0x21, - 0x11, 0x21, 0x01, 0x21, 0x11, 0x21, 0x11, 0x21, 0x06, 0x04, 0xc5, 0xfd, - 0xd6, 0x01, 0xb7, 0xfe, 0x49, 0xfd, 0xd7, 0x03, 0xe0, 0xfd, 0xd7, 0xfe, - 0x49, 0x4e, 0x04, 0xc4, 0xfb, 0x3c, 0x02, 0x9a, 0x01, 0xb8, 0xfc, 0x20, - 0x01, 0xb6, 0x02, 0x2a, 0x00, 0x03, 0x00, 0x06, 0xff, 0xac, 0x04, 0xcb, - 0x04, 0x7c, 0x00, 0x0d, 0x00, 0x13, 0x00, 0x20, 0x00, 0x00, 0x36, 0x10, - 0x25, 0x36, 0x33, 0x32, 0x17, 0x04, 0x10, 0x05, 0x06, 0x23, 0x22, 0x27, - 0x13, 0x06, 0x07, 0x06, 0x07, 0x21, 0x05, 0x16, 0x17, 0x16, 0x33, 0x32, - 0x37, 0x36, 0x10, 0x27, 0x26, 0x27, 0x11, 0x06, 0x01, 0x31, 0x98, 0x99, - 0x98, 0x99, 0x01, 0x32, 0xfe, 0xce, 0x99, 0x98, 0x99, 0x98, 0xf8, 0x5e, - 0x5d, 0xdb, 0x16, 0x01, 0xac, 0xfe, 0x54, 0x17, 0xda, 0x7a, 0x7a, 0x7a, - 0x7a, 0xf5, 0xf5, 0x5e, 0x5d, 0xb4, 0x02, 0xc0, 0xb0, 0x58, 0x58, 0xb0, - 0xfd, 0x40, 0xb0, 0x58, 0x58, 0x03, 0xf9, 0x0d, 0x36, 0x7e, 0xf0, 0x72, - 0xee, 0x7e, 0x47, 0x47, 0x8d, 0x02, 0x32, 0x8d, 0x36, 0x0d, 0xfd, 0xdd, - 0x00, 0x03, 0x00, 0x06, 0xff, 0xac, 0x04, 0xcb, 0x04, 0x7c, 0x00, 0x0d, - 0x00, 0x1a, 0x00, 0x20, 0x00, 0x00, 0x36, 0x10, 0x25, 0x36, 0x33, 0x32, - 0x17, 0x04, 0x10, 0x05, 0x06, 0x23, 0x22, 0x27, 0x25, 0x36, 0x37, 0x36, - 0x10, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x21, 0x05, 0x16, 0x17, - 0x16, 0x17, 0x11, 0x06, 0x01, 0x31, 0x98, 0x99, 0x98, 0x99, 0x01, 0x32, - 0xfe, 0xce, 0x99, 0x98, 0x99, 0x98, 0x01, 0x6a, 0x5d, 0x5e, 0xf5, 0xf5, - 0x7a, 0x7a, 0x7a, 0x7a, 0xdb, 0x16, 0x02, 0x1e, 0xfd, 0xe2, 0x17, 0xda, - 0x5d, 0x5e, 0xb4, 0x02, 0xc0, 0xb0, 0x58, 0x58, 0xb0, 0xfd, 0x40, 0xb0, - 0x58, 0x58, 0x27, 0x0d, 0x36, 0x8d, 0x02, 0x32, 0x8d, 0x47, 0x47, 0x7e, - 0xf0, 0x72, 0xee, 0x7e, 0x36, 0x0d, 0x01, 0xaf, 0x00, 0x03, 0x00, 0x06, - 0xff, 0xac, 0x04, 0xcb, 0x04, 0x7c, 0x00, 0x0d, 0x00, 0x1a, 0x00, 0x20, - 0x00, 0x00, 0x36, 0x10, 0x25, 0x36, 0x33, 0x32, 0x17, 0x04, 0x10, 0x05, - 0x06, 0x23, 0x22, 0x27, 0x02, 0x10, 0x17, 0x16, 0x17, 0x11, 0x21, 0x26, - 0x27, 0x26, 0x23, 0x22, 0x07, 0x01, 0x36, 0x37, 0x36, 0x37, 0x21, 0x06, - 0x01, 0x31, 0x98, 0x99, 0x98, 0x99, 0x01, 0x32, 0xfe, 0xce, 0x99, 0x98, - 0x99, 0x98, 0xb7, 0xf4, 0x5d, 0x5e, 0x02, 0x1f, 0x16, 0xdc, 0x7a, 0x7a, - 0x7a, 0x7a, 0x01, 0x2d, 0x5d, 0x5e, 0xdb, 0x17, 0xfe, 0x53, 0xb4, 0x02, - 0xc0, 0xb0, 0x58, 0x58, 0xb0, 0xfd, 0x40, 0xb0, 0x58, 0x58, 0x03, 0x29, - 0xfd, 0xce, 0x8d, 0x36, 0x0d, 0x02, 0x21, 0xf0, 0x7e, 0x47, 0x47, 0xfc, - 0x71, 0x0d, 0x36, 0x7e, 0xee, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x06, - 0xff, 0xac, 0x04, 0xcb, 0x04, 0x7c, 0x00, 0x0d, 0x00, 0x1a, 0x00, 0x20, - 0x00, 0x00, 0x36, 0x10, 0x25, 0x36, 0x33, 0x32, 0x17, 0x04, 0x10, 0x05, - 0x06, 0x23, 0x22, 0x27, 0x02, 0x10, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, - 0x37, 0x21, 0x11, 0x06, 0x07, 0x01, 0x26, 0x27, 0x26, 0x27, 0x11, 0x06, - 0x01, 0x31, 0x98, 0x99, 0x98, 0x99, 0x01, 0x32, 0xfe, 0xce, 0x99, 0x98, - 0x99, 0x98, 0xb7, 0xf4, 0x7a, 0x7a, 0x7a, 0x7a, 0xdb, 0x17, 0xfd, 0xe1, - 0x5e, 0x5d, 0x02, 0xda, 0x16, 0xdc, 0x5e, 0x5d, 0xb4, 0x02, 0xc0, 0xb0, - 0x58, 0x58, 0xb0, 0xfd, 0x40, 0xb0, 0x58, 0x58, 0x03, 0x29, 0xfd, 0xce, - 0x8d, 0x47, 0x47, 0x7e, 0xee, 0x02, 0x23, 0x0d, 0x36, 0xfe, 0x92, 0xf0, - 0x7e, 0x36, 0x0d, 0xfe, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, - 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, - 0x37, 0x01, 0x21, 0x03, 0x11, 0x21, 0x78, 0x03, 0x36, 0xfc, 0xca, 0x72, - 0x04, 0xc5, 0xce, 0x03, 0x36, 0xfb, 0xae, 0x04, 0xc4, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x02, - 0x00, 0x05, 0x00, 0x00, 0x09, 0x01, 0x11, 0x25, 0x21, 0x11, 0x01, 0x23, - 0x03, 0x36, 0xfb, 0xad, 0x04, 0xc5, 0x04, 0x04, 0xfc, 0xca, 0x03, 0x36, - 0x72, 0xfb, 0x3c, 0x00, 0x00, 0x02, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, - 0x04, 0x77, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x37, 0x21, 0x01, 0x03, - 0x11, 0x01, 0x78, 0x03, 0x36, 0xfc, 0xca, 0x72, 0x04, 0xc5, 0x24, 0x03, - 0x36, 0xfc, 0x58, 0x04, 0xc4, 0xfb, 0x3c, 0x00, 0x00, 0x02, 0x00, 0x61, - 0x00, 0x0d, 0x04, 0x6f, 0x04, 0x1b, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, - 0x37, 0x21, 0x11, 0x21, 0x03, 0x11, 0x21, 0x11, 0xd3, 0x03, 0x2a, 0xfc, - 0xd6, 0x72, 0x04, 0x0e, 0x7f, 0x03, 0x2a, 0xfc, 0x64, 0x04, 0x0e, 0xfb, - 0xf2, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x61, 0x00, 0x0d, 0x04, 0x6f, - 0x04, 0x1b, 0x00, 0x03, 0x00, 0x00, 0x37, 0x11, 0x21, 0x11, 0x61, 0x04, - 0x0e, 0x0d, 0x04, 0x0e, 0xfb, 0xf2, 0x00, 0x00, 0x00, 0x02, 0x00, 0xaf, - 0x00, 0x5b, 0x04, 0x21, 0x03, 0xcd, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, - 0x25, 0x21, 0x11, 0x21, 0x03, 0x11, 0x21, 0x11, 0x01, 0x21, 0x02, 0x8e, - 0xfd, 0x72, 0x72, 0x03, 0x72, 0xcd, 0x02, 0x8e, 0xfd, 0x00, 0x03, 0x72, - 0xfc, 0x8e, 0x00, 0x00, 0x00, 0x01, 0x00, 0xaf, 0x00, 0x5b, 0x04, 0x21, - 0x03, 0xcd, 0x00, 0x03, 0x00, 0x00, 0x37, 0x11, 0x21, 0x11, 0xaf, 0x03, - 0x72, 0x5b, 0x03, 0x72, 0xfc, 0x8e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, - 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, - 0x25, 0x21, 0x11, 0x09, 0x01, 0x11, 0x01, 0x23, 0x03, 0x36, 0xfb, 0xad, - 0x04, 0xc5, 0x24, 0x03, 0x36, 0xfc, 0x58, 0x04, 0xc4, 0xfb, 0x3c, 0x00, - 0x00, 0x09, 0x00, 0x22, 0x00, 0xa4, 0x04, 0xaf, 0x05, 0x31, 0x00, 0x07, - 0x00, 0x0c, 0x00, 0x13, 0x00, 0x22, 0x00, 0x2a, 0x00, 0x32, 0x00, 0x3a, - 0x00, 0x41, 0x00, 0x49, 0x00, 0x00, 0x01, 0x33, 0x17, 0x11, 0x07, 0x23, - 0x27, 0x11, 0x05, 0x17, 0x15, 0x07, 0x27, 0x25, 0x17, 0x07, 0x23, 0x26, - 0x27, 0x35, 0x05, 0x32, 0x1f, 0x01, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, - 0x26, 0x35, 0x34, 0x37, 0x36, 0x05, 0x21, 0x17, 0x15, 0x07, 0x21, 0x27, - 0x35, 0x25, 0x21, 0x17, 0x15, 0x07, 0x21, 0x27, 0x35, 0x07, 0x33, 0x16, - 0x17, 0x15, 0x07, 0x27, 0x35, 0x25, 0x33, 0x17, 0x15, 0x07, 0x27, 0x35, - 0x25, 0x33, 0x17, 0x11, 0x07, 0x23, 0x27, 0x11, 0x02, 0x4e, 0x3c, 0x04, - 0x04, 0x3c, 0x05, 0x01, 0xba, 0x2e, 0xc2, 0x30, 0xfd, 0xa7, 0xc4, 0x2f, - 0x02, 0x9d, 0x23, 0x01, 0xb5, 0xa3, 0x45, 0x0a, 0x94, 0x37, 0x24, 0x89, - 0x4c, 0x1c, 0x8f, 0x34, 0xfd, 0xe4, 0x01, 0x08, 0x05, 0x05, 0xfe, 0xf8, - 0x05, 0x03, 0x7a, 0x01, 0x0e, 0x05, 0x05, 0xfe, 0xf2, 0x04, 0x38, 0x03, - 0x68, 0x59, 0x2f, 0xc2, 0xfe, 0x36, 0x02, 0x2e, 0xc0, 0x30, 0x01, 0xa5, - 0x3c, 0x04, 0x04, 0x3c, 0x05, 0x05, 0x31, 0x05, 0xfe, 0xef, 0x04, 0x04, - 0x01, 0x11, 0x79, 0x31, 0x02, 0xc6, 0x31, 0xba, 0xc7, 0x32, 0x9c, 0x2b, - 0x03, 0x8d, 0xb0, 0x4b, 0x93, 0x4f, 0x11, 0x82, 0x31, 0x48, 0x8d, 0x50, - 0x16, 0xd7, 0x05, 0x3d, 0x05, 0x05, 0x3d, 0x05, 0x05, 0x3d, 0x05, 0x05, - 0x3d, 0xda, 0x66, 0x5e, 0x02, 0x31, 0xc6, 0x03, 0x20, 0x2e, 0x03, 0xc6, - 0x31, 0x03, 0x5c, 0x04, 0xfe, 0xef, 0x05, 0x05, 0x01, 0x11, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x32, 0x00, 0x08, 0x04, 0x9f, 0x01, 0xd1, 0x00, 0x22, - 0x00, 0x00, 0x01, 0x33, 0x32, 0x1f, 0x01, 0x36, 0x33, 0x16, 0x15, 0x14, - 0x07, 0x16, 0x1d, 0x01, 0x06, 0x23, 0x21, 0x35, 0x32, 0x37, 0x36, 0x3b, - 0x01, 0x27, 0x34, 0x3f, 0x01, 0x17, 0x27, 0x34, 0x3f, 0x01, 0x32, 0x17, - 0x36, 0x03, 0x00, 0x0d, 0x86, 0x48, 0x0c, 0x18, 0x22, 0x53, 0x15, 0x3f, - 0x0b, 0x31, 0xfb, 0xd1, 0x23, 0x52, 0x1d, 0x20, 0x14, 0x07, 0x62, 0x18, - 0x1a, 0x03, 0x7d, 0x29, 0x1e, 0x1c, 0x4a, 0x01, 0xd1, 0x8f, 0x35, 0x16, - 0x11, 0x43, 0x1e, 0x20, 0x0e, 0x2c, 0x10, 0x3f, 0x06, 0x6b, 0x18, 0x1e, - 0x43, 0x1e, 0x02, 0x02, 0x07, 0x5b, 0x37, 0x05, 0x1b, 0x3e, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x22, 0x00, 0x06, 0x04, 0xaf, 0x04, 0x2d, 0x00, 0x3f, - 0x00, 0x00, 0x01, 0x33, 0x17, 0x15, 0x33, 0x20, 0x13, 0x16, 0x1d, 0x01, - 0x23, 0x26, 0x27, 0x26, 0x2b, 0x01, 0x22, 0x07, 0x15, 0x14, 0x07, 0x27, - 0x26, 0x23, 0x11, 0x14, 0x0f, 0x01, 0x22, 0x2f, 0x01, 0x35, 0x37, 0x33, - 0x17, 0x15, 0x16, 0x3b, 0x01, 0x32, 0x3f, 0x01, 0x11, 0x22, 0x07, 0x06, - 0x23, 0x27, 0x35, 0x37, 0x23, 0x26, 0x27, 0x23, 0x22, 0x0f, 0x01, 0x23, - 0x35, 0x36, 0x37, 0x36, 0x33, 0x35, 0x02, 0x61, 0x29, 0x04, 0x02, 0x01, - 0x38, 0xc7, 0x1f, 0x01, 0x10, 0x0e, 0x18, 0x29, 0x1f, 0x6b, 0x4f, 0x06, - 0x18, 0x6b, 0x61, 0x4b, 0x15, 0x41, 0x1a, 0x02, 0x04, 0x1f, 0x04, 0x07, - 0x2d, 0x07, 0x27, 0x0e, 0x04, 0x96, 0x3d, 0x0c, 0x0a, 0x05, 0x05, 0x03, - 0x2f, 0x8d, 0x2f, 0x47, 0x18, 0x0e, 0x02, 0x29, 0x89, 0xaa, 0xdd, 0x04, - 0x2c, 0x04, 0x59, 0xfe, 0xa6, 0x3d, 0x09, 0x06, 0x0b, 0x21, 0x11, 0x48, - 0x24, 0x0b, 0x01, 0x2f, 0x2b, 0xfe, 0x19, 0x48, 0x11, 0x01, 0x44, 0x14, - 0x12, 0x05, 0x05, 0x08, 0x48, 0x29, 0x1d, 0x01, 0xe1, 0x2b, 0x29, 0x04, - 0x09, 0x24, 0x2e, 0x13, 0x2c, 0x0c, 0x01, 0x66, 0x9b, 0x9f, 0x59, 0x00, - 0x00, 0x0f, 0x00, 0x59, 0xff, 0xfa, 0x04, 0x78, 0x05, 0xab, 0x00, 0x09, - 0x00, 0x11, 0x00, 0x19, 0x00, 0x21, 0x00, 0x3d, 0x00, 0x5a, 0x00, 0x85, - 0x00, 0xb1, 0x00, 0xdc, 0x01, 0x08, 0x01, 0x10, 0x01, 0x18, 0x01, 0x20, - 0x01, 0x4c, 0x01, 0x78, 0x00, 0x00, 0x01, 0x16, 0x37, 0x33, 0x06, 0x07, - 0x26, 0x27, 0x33, 0x16, 0x37, 0x26, 0x27, 0x36, 0x37, 0x16, 0x17, 0x06, - 0x05, 0x26, 0x27, 0x36, 0x37, 0x16, 0x17, 0x06, 0x03, 0x26, 0x27, 0x36, - 0x37, 0x16, 0x17, 0x06, 0x27, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, - 0x35, 0x34, 0x27, 0x26, 0x27, 0x16, 0x37, 0x36, 0x35, 0x34, 0x26, 0x23, - 0x22, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x06, 0x13, 0x36, 0x37, 0x32, - 0x1f, 0x01, 0x16, 0x14, 0x07, 0x06, 0x07, 0x16, 0x17, 0x16, 0x15, 0x14, - 0x04, 0x20, 0x24, 0x35, 0x34, 0x37, 0x36, 0x37, 0x26, 0x27, 0x26, 0x34, - 0x37, 0x01, 0x17, 0x27, 0x26, 0x32, 0x0f, 0x01, 0x37, 0x36, 0x33, 0x32, - 0x15, 0x14, 0x0f, 0x01, 0x17, 0x16, 0x15, 0x14, 0x23, 0x22, 0x2f, 0x01, - 0x17, 0x16, 0x23, 0x22, 0x3f, 0x01, 0x07, 0x06, 0x23, 0x22, 0x35, 0x34, - 0x3f, 0x01, 0x27, 0x26, 0x35, 0x34, 0x33, 0x32, 0x03, 0x17, 0x27, 0x26, - 0x33, 0x32, 0x0f, 0x01, 0x37, 0x36, 0x33, 0x32, 0x15, 0x14, 0x0f, 0x01, - 0x17, 0x16, 0x15, 0x14, 0x23, 0x22, 0x2f, 0x01, 0x17, 0x16, 0x23, 0x22, - 0x3f, 0x01, 0x07, 0x06, 0x23, 0x22, 0x35, 0x34, 0x3f, 0x01, 0x27, 0x26, - 0x35, 0x34, 0x33, 0x32, 0x01, 0x17, 0x27, 0x26, 0x33, 0x32, 0x0f, 0x01, - 0x37, 0x36, 0x33, 0x32, 0x15, 0x14, 0x0f, 0x01, 0x17, 0x16, 0x14, 0x23, - 0x22, 0x2f, 0x01, 0x17, 0x16, 0x23, 0x22, 0x3f, 0x01, 0x07, 0x06, 0x23, - 0x22, 0x35, 0x34, 0x3f, 0x01, 0x27, 0x26, 0x35, 0x34, 0x33, 0x30, 0x1f, - 0x01, 0x27, 0x26, 0x33, 0x32, 0x0f, 0x01, 0x37, 0x36, 0x33, 0x32, 0x15, - 0x14, 0x0f, 0x01, 0x17, 0x16, 0x15, 0x14, 0x23, 0x22, 0x2f, 0x01, 0x17, - 0x16, 0x23, 0x22, 0x3f, 0x01, 0x07, 0x06, 0x23, 0x22, 0x35, 0x34, 0x3f, - 0x01, 0x27, 0x26, 0x35, 0x34, 0x33, 0x32, 0x01, 0x26, 0x35, 0x34, 0x33, - 0x32, 0x15, 0x14, 0x05, 0x26, 0x35, 0x36, 0x33, 0x32, 0x15, 0x14, 0x37, - 0x26, 0x35, 0x34, 0x33, 0x32, 0x15, 0x14, 0x13, 0x17, 0x27, 0x26, 0x33, - 0x32, 0x0f, 0x01, 0x37, 0x36, 0x33, 0x32, 0x15, 0x14, 0x0f, 0x01, 0x17, - 0x16, 0x15, 0x14, 0x23, 0x22, 0x2f, 0x01, 0x17, 0x16, 0x23, 0x22, 0x3f, - 0x01, 0x07, 0x06, 0x23, 0x22, 0x35, 0x34, 0x3f, 0x01, 0x27, 0x26, 0x35, - 0x34, 0x33, 0x32, 0x01, 0x17, 0x27, 0x26, 0x33, 0x32, 0x0f, 0x01, 0x37, - 0x36, 0x33, 0x32, 0x15, 0x14, 0x0f, 0x01, 0x17, 0x16, 0x15, 0x14, 0x23, - 0x22, 0x2f, 0x01, 0x17, 0x16, 0x23, 0x22, 0x3f, 0x01, 0x07, 0x06, 0x23, - 0x22, 0x35, 0x34, 0x3f, 0x01, 0x27, 0x26, 0x35, 0x34, 0x33, 0x32, 0x02, - 0x50, 0x4f, 0x1c, 0x19, 0x05, 0x80, 0x7e, 0x09, 0x18, 0x29, 0xb9, 0x2a, - 0x01, 0x03, 0x2b, 0x27, 0x03, 0x03, 0xfe, 0xeb, 0x29, 0x03, 0x03, 0x2b, - 0x28, 0x03, 0x03, 0x40, 0x26, 0x02, 0x03, 0x27, 0x24, 0x02, 0x02, 0xca, - 0x7c, 0xf7, 0xaf, 0xae, 0xf8, 0x7c, 0x65, 0x8b, 0x3f, 0x2f, 0x41, 0x7d, - 0x5d, 0x5c, 0x8a, 0x42, 0x2d, 0x37, 0x90, 0x15, 0x1a, 0x93, 0x84, 0x31, - 0x02, 0x53, 0x4c, 0x14, 0x18, 0x6f, 0x57, 0x8e, 0xfe, 0xe4, 0xfe, 0x6a, - 0xfe, 0xe3, 0x8f, 0x5c, 0x76, 0x15, 0x13, 0x4c, 0x4c, 0x02, 0x72, 0x25, - 0x06, 0x01, 0x1c, 0x01, 0x06, 0x25, 0x04, 0x04, 0x0e, 0x07, 0x2c, 0x2a, - 0x07, 0x0c, 0x06, 0x02, 0x23, 0x04, 0x01, 0x0e, 0x0e, 0x01, 0x05, 0x24, - 0x02, 0x05, 0x0d, 0x08, 0x29, 0x2a, 0x08, 0x0e, 0x03, 0x6e, 0x24, 0x05, - 0x01, 0x0d, 0x10, 0x02, 0x06, 0x25, 0x04, 0x04, 0x0d, 0x07, 0x2b, 0x29, - 0x08, 0x0c, 0x06, 0x02, 0x24, 0x05, 0x01, 0x0f, 0x0d, 0x01, 0x04, 0x23, - 0x02, 0x05, 0x0e, 0x08, 0x2a, 0x2b, 0x08, 0x0f, 0x04, 0xfd, 0x1c, 0x15, - 0x03, 0x01, 0x09, 0x09, 0x01, 0x04, 0x16, 0x02, 0x02, 0x09, 0x04, 0x1a, - 0x18, 0x05, 0x08, 0x03, 0x01, 0x16, 0x04, 0x01, 0x09, 0x09, 0x01, 0x03, - 0x15, 0x01, 0x03, 0x08, 0x04, 0x19, 0x1a, 0x04, 0x09, 0x3f, 0x13, 0x04, - 0x01, 0x08, 0x09, 0x01, 0x04, 0x13, 0x02, 0x03, 0x08, 0x05, 0x16, 0x16, - 0x04, 0x07, 0x02, 0x03, 0x13, 0x03, 0x01, 0x08, 0x08, 0x01, 0x04, 0x13, - 0x03, 0x02, 0x07, 0x04, 0x16, 0x16, 0x05, 0x08, 0x03, 0x01, 0xf9, 0x27, - 0x2b, 0x26, 0xfe, 0xb4, 0x28, 0x01, 0x29, 0x26, 0xfb, 0x28, 0x2b, 0x26, - 0x70, 0x17, 0x04, 0x01, 0x09, 0x09, 0x01, 0x03, 0x15, 0x02, 0x02, 0x08, - 0x03, 0x1a, 0x19, 0x04, 0x08, 0x03, 0x01, 0x15, 0x02, 0x01, 0x08, 0x09, - 0x01, 0x03, 0x16, 0x01, 0x03, 0x08, 0x06, 0x18, 0x19, 0x05, 0x09, 0x02, - 0xfc, 0xf2, 0x25, 0x05, 0x01, 0x0d, 0x0e, 0x01, 0x05, 0x25, 0x04, 0x04, - 0x0d, 0x07, 0x2b, 0x29, 0x08, 0x0c, 0x04, 0x04, 0x24, 0x04, 0x01, 0x0e, - 0x0d, 0x01, 0x04, 0x24, 0x04, 0x02, 0x0e, 0x08, 0x2a, 0x2b, 0x08, 0x0f, - 0x02, 0x03, 0x84, 0x05, 0x2a, 0x45, 0x05, 0x07, 0x43, 0x2a, 0x5a, 0x02, - 0x2a, 0x2c, 0x03, 0x03, 0x29, 0x2d, 0x04, 0x02, 0x29, 0x2d, 0x03, 0x03, - 0x2a, 0x2c, 0xfe, 0x12, 0x02, 0x25, 0x26, 0x02, 0x02, 0x25, 0x26, 0x9e, - 0x66, 0x93, 0x91, 0xd0, 0xd0, 0x91, 0x93, 0x66, 0x55, 0x20, 0x02, 0x35, - 0x48, 0x68, 0x66, 0x65, 0x65, 0x66, 0x68, 0x48, 0x32, 0x1e, 0x01, 0xd9, - 0x70, 0x18, 0x75, 0x13, 0x5e, 0xe8, 0x51, 0x18, 0x10, 0x1c, 0x46, 0x73, - 0xa5, 0xa3, 0xe6, 0xe6, 0xa3, 0xa5, 0x73, 0x4b, 0x1a, 0x0f, 0x16, 0x51, - 0xe8, 0x47, 0xfe, 0x81, 0x1f, 0x34, 0x0d, 0x0d, 0x34, 0x1f, 0x03, 0x10, - 0x09, 0x03, 0x14, 0x13, 0x03, 0x09, 0x0e, 0x02, 0x1e, 0x32, 0x0f, 0x0f, - 0x32, 0x1e, 0x02, 0x0e, 0x08, 0x04, 0x13, 0x14, 0x04, 0x08, 0x10, 0x01, - 0x30, 0x1f, 0x34, 0x0e, 0x0e, 0x34, 0x1f, 0x03, 0x10, 0x07, 0x03, 0x15, - 0x13, 0x04, 0x09, 0x0e, 0x02, 0x1e, 0x32, 0x0e, 0x0e, 0x32, 0x1e, 0x02, - 0x0e, 0x09, 0x04, 0x13, 0x15, 0x04, 0x06, 0x10, 0x01, 0x39, 0x11, 0x1d, - 0x0a, 0x0a, 0x1d, 0x11, 0x03, 0x0a, 0x04, 0x02, 0x0d, 0x0a, 0x02, 0x0e, - 0x01, 0x11, 0x1e, 0x07, 0x07, 0x1e, 0x11, 0x01, 0x07, 0x07, 0x02, 0x0a, - 0x0d, 0x02, 0x04, 0x0a, 0xfb, 0x10, 0x1c, 0x07, 0x07, 0x1c, 0x10, 0x02, - 0x07, 0x06, 0x02, 0x09, 0x0b, 0x02, 0x05, 0x08, 0x02, 0x0f, 0x1a, 0x08, - 0x08, 0x1a, 0x0f, 0x02, 0x08, 0x05, 0x02, 0x0b, 0x09, 0x02, 0x06, 0x07, - 0xfd, 0x4c, 0x02, 0x25, 0x28, 0x27, 0x2a, 0xde, 0x02, 0x25, 0x29, 0x28, - 0x2a, 0x02, 0x02, 0x25, 0x29, 0x28, 0x2a, 0x04, 0x74, 0x11, 0x1e, 0x08, - 0x08, 0x1e, 0x11, 0x02, 0x08, 0x07, 0x01, 0x0b, 0x0c, 0x02, 0x05, 0x09, - 0x01, 0x11, 0x1c, 0x09, 0x09, 0x1c, 0x11, 0x01, 0x09, 0x04, 0x03, 0x0c, - 0x0b, 0x02, 0x06, 0x08, 0xfe, 0x31, 0x1f, 0x34, 0x0e, 0x0e, 0x34, 0x1f, - 0x03, 0x10, 0x08, 0x03, 0x14, 0x13, 0x04, 0x09, 0x0e, 0x03, 0x1d, 0x32, - 0x0e, 0x0e, 0x32, 0x1d, 0x03, 0x0e, 0x09, 0x04, 0x13, 0x14, 0x04, 0x07, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x1d, 0x00, 0x30, 0x04, 0xb4, - 0x05, 0x72, 0x00, 0x13, 0x00, 0x21, 0x00, 0x32, 0x00, 0x43, 0x00, 0x54, - 0x00, 0x65, 0x00, 0x76, 0x00, 0x87, 0x00, 0x98, 0x00, 0xa9, 0x00, 0xba, - 0x00, 0xcb, 0x00, 0xdc, 0x00, 0xed, 0x00, 0xfe, 0x00, 0x00, 0x01, 0x16, - 0x07, 0x06, 0x0f, 0x01, 0x06, 0x2b, 0x01, 0x26, 0x27, 0x26, 0x35, 0x34, - 0x3f, 0x02, 0x36, 0x17, 0x16, 0x07, 0x06, 0x17, 0x16, 0x1f, 0x01, 0x16, - 0x3f, 0x01, 0x36, 0x2f, 0x01, 0x26, 0x07, 0x13, 0x32, 0x17, 0x16, 0x1d, - 0x01, 0x14, 0x07, 0x06, 0x23, 0x22, 0x2f, 0x01, 0x35, 0x34, 0x37, 0x36, - 0x37, 0x32, 0x17, 0x16, 0x1d, 0x01, 0x14, 0x07, 0x06, 0x23, 0x22, 0x2f, - 0x01, 0x35, 0x34, 0x37, 0x36, 0x37, 0x32, 0x17, 0x16, 0x1d, 0x01, 0x14, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x3d, 0x01, 0x34, 0x37, 0x36, 0x37, 0x32, - 0x17, 0x16, 0x1d, 0x01, 0x14, 0x07, 0x06, 0x23, 0x22, 0x2f, 0x01, 0x35, - 0x34, 0x37, 0x36, 0x13, 0x32, 0x17, 0x16, 0x1d, 0x01, 0x14, 0x07, 0x06, - 0x23, 0x22, 0x2f, 0x01, 0x35, 0x34, 0x37, 0x36, 0x07, 0x32, 0x17, 0x16, - 0x1d, 0x01, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x3d, 0x01, 0x34, 0x37, - 0x36, 0x01, 0x32, 0x17, 0x16, 0x1d, 0x01, 0x14, 0x07, 0x06, 0x23, 0x22, - 0x2f, 0x01, 0x35, 0x34, 0x37, 0x36, 0x37, 0x32, 0x17, 0x16, 0x1d, 0x01, - 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x3d, 0x01, 0x34, 0x37, 0x36, 0x37, - 0x32, 0x17, 0x16, 0x1d, 0x01, 0x14, 0x07, 0x06, 0x23, 0x22, 0x2f, 0x01, - 0x35, 0x34, 0x37, 0x36, 0x01, 0x32, 0x17, 0x16, 0x1d, 0x01, 0x14, 0x07, - 0x06, 0x23, 0x22, 0x2f, 0x01, 0x35, 0x34, 0x37, 0x36, 0x37, 0x32, 0x17, - 0x16, 0x1d, 0x01, 0x14, 0x07, 0x06, 0x23, 0x22, 0x2f, 0x01, 0x35, 0x34, - 0x37, 0x36, 0x37, 0x32, 0x17, 0x16, 0x1d, 0x01, 0x14, 0x07, 0x06, 0x23, - 0x22, 0x2f, 0x01, 0x35, 0x34, 0x37, 0x36, 0x37, 0x32, 0x17, 0x16, 0x1d, - 0x01, 0x14, 0x07, 0x06, 0x23, 0x22, 0x2f, 0x01, 0x35, 0x34, 0x37, 0x36, - 0x01, 0x6c, 0x3d, 0x2e, 0x0f, 0x25, 0x10, 0x47, 0x5c, 0x11, 0x26, 0x1d, - 0x23, 0x2d, 0x1f, 0x09, 0x4c, 0x6a, 0x2e, 0xc4, 0x4e, 0x1a, 0x04, 0x0a, - 0x0b, 0x30, 0x64, 0x26, 0x4b, 0x11, 0x18, 0x34, 0x69, 0xb9, 0x15, 0x0b, - 0x06, 0x14, 0x08, 0x0a, 0x1b, 0x09, 0x01, 0x13, 0x0a, 0x7d, 0x16, 0x0b, - 0x05, 0x13, 0x08, 0x0a, 0x1b, 0x09, 0x01, 0x13, 0x0a, 0x67, 0x15, 0x0b, - 0x05, 0x13, 0x08, 0x0a, 0x1a, 0x0b, 0x13, 0x0a, 0x73, 0x15, 0x0b, 0x06, - 0x14, 0x07, 0x0b, 0x1a, 0x0a, 0x01, 0x13, 0x0a, 0x02, 0x15, 0x0c, 0x05, - 0x14, 0x07, 0x0b, 0x1a, 0x0a, 0x01, 0x14, 0x09, 0x8d, 0x16, 0x0b, 0x05, - 0x13, 0x08, 0x0a, 0x1b, 0x0a, 0x13, 0x0a, 0x01, 0x26, 0x15, 0x0b, 0x05, - 0x13, 0x08, 0x0a, 0x1a, 0x0b, 0x01, 0x14, 0x0a, 0x90, 0x16, 0x0b, 0x05, - 0x13, 0x08, 0x0a, 0x1b, 0x0a, 0x13, 0x0a, 0x91, 0x15, 0x0b, 0x06, 0x14, - 0x08, 0x0a, 0x1b, 0x09, 0x01, 0x13, 0x0a, 0xfe, 0x02, 0x16, 0x0b, 0x06, - 0x14, 0x08, 0x0a, 0x1b, 0x09, 0x01, 0x13, 0x0a, 0xcc, 0x15, 0x0c, 0x05, - 0x14, 0x07, 0x0b, 0x1a, 0x0a, 0x01, 0x14, 0x09, 0xd9, 0x15, 0x0b, 0x06, - 0x14, 0x08, 0x0a, 0x1a, 0x0a, 0x01, 0x13, 0x0a, 0xc1, 0x15, 0x0c, 0x05, - 0x14, 0x07, 0x0b, 0x1a, 0x0a, 0x01, 0x14, 0x09, 0x01, 0xc6, 0x48, 0x83, - 0x35, 0x2d, 0x13, 0x56, 0x05, 0x22, 0x2a, 0x3c, 0x43, 0x5a, 0x2b, 0x0a, - 0x5d, 0x02, 0x09, 0x5f, 0x5f, 0x66, 0x11, 0x0c, 0x0d, 0x38, 0x41, 0x25, - 0x5c, 0x6d, 0x24, 0x3d, 0x46, 0x01, 0x0e, 0x17, 0x09, 0x0c, 0x04, 0x17, - 0x0e, 0x05, 0x21, 0x0a, 0x03, 0x17, 0x0f, 0x06, 0xea, 0x16, 0x09, 0x0c, - 0x05, 0x16, 0x0e, 0x06, 0x22, 0x09, 0x04, 0x16, 0x0f, 0x06, 0xe6, 0x17, - 0x09, 0x0b, 0x05, 0x16, 0x0f, 0x05, 0x22, 0x09, 0x04, 0x16, 0x0f, 0x06, - 0xec, 0x17, 0x09, 0x0b, 0x04, 0x17, 0x0e, 0x05, 0x21, 0x09, 0x03, 0x18, - 0x0e, 0x06, 0xfd, 0xc5, 0x17, 0x09, 0x0b, 0x05, 0x17, 0x0e, 0x05, 0x21, - 0x0b, 0x02, 0x18, 0x0e, 0x06, 0xc2, 0x17, 0x09, 0x0b, 0x04, 0x18, 0x0e, - 0x05, 0x22, 0x0a, 0x03, 0x17, 0x0e, 0x06, 0x01, 0x83, 0x16, 0x09, 0x0b, - 0x06, 0x16, 0x0e, 0x05, 0x21, 0x09, 0x04, 0x16, 0x10, 0x05, 0xbb, 0x17, - 0x09, 0x0b, 0x05, 0x17, 0x0e, 0x05, 0x22, 0x09, 0x03, 0x17, 0x0f, 0x06, - 0xc2, 0x18, 0x09, 0x0b, 0x04, 0x17, 0x0e, 0x06, 0x22, 0x0a, 0x03, 0x17, - 0x0e, 0x07, 0xfc, 0x4d, 0x16, 0x09, 0x0b, 0x05, 0x17, 0x0e, 0x06, 0x22, - 0x09, 0x04, 0x17, 0x0e, 0x06, 0x9e, 0x16, 0x09, 0x0b, 0x05, 0x16, 0x0f, - 0x06, 0x23, 0x09, 0x03, 0x17, 0x0f, 0x05, 0xac, 0x17, 0x09, 0x0a, 0x05, - 0x18, 0x0d, 0x05, 0x21, 0x0a, 0x02, 0x18, 0x0e, 0x06, 0x97, 0x17, 0x09, - 0x0b, 0x04, 0x18, 0x0d, 0x06, 0x22, 0x0a, 0x02, 0x18, 0x0e, 0x06, 0x00, - 0x00, 0x01, 0x00, 0x3a, 0x00, 0x0f, 0x04, 0x97, 0x04, 0x33, 0x00, 0x09, - 0x00, 0x00, 0x13, 0x21, 0x1b, 0x01, 0x21, 0x05, 0x13, 0x25, 0x05, 0x13, - 0x3a, 0x01, 0xaa, 0x84, 0x85, 0x01, 0xaa, 0xfe, 0xa7, 0x85, 0xfe, 0xa5, - 0xfe, 0xa7, 0x84, 0x02, 0x9e, 0x01, 0x95, 0xfe, 0x6b, 0xfb, 0xfe, 0x6c, - 0xfa, 0xfa, 0x01, 0x94, 0x00, 0x02, 0x00, 0x3a, 0x00, 0x14, 0x04, 0x97, - 0x04, 0x39, 0x00, 0x09, 0x00, 0x13, 0x00, 0x00, 0x13, 0x21, 0x1b, 0x01, - 0x21, 0x05, 0x13, 0x25, 0x05, 0x13, 0x37, 0x03, 0x25, 0x05, 0x03, 0x25, - 0x21, 0x0b, 0x01, 0x21, 0x3a, 0x01, 0xaa, 0x84, 0x85, 0x01, 0xaa, 0xfe, - 0xa7, 0x85, 0xfe, 0xa5, 0xfe, 0xa7, 0x84, 0x30, 0x64, 0x01, 0x09, 0x01, - 0x12, 0x6d, 0x01, 0x1c, 0xfe, 0xa7, 0x68, 0x64, 0xfe, 0xa5, 0x02, 0xa4, - 0x01, 0x94, 0xfe, 0x6c, 0xfb, 0xfe, 0x6c, 0xfa, 0xfa, 0x01, 0x94, 0x0f, - 0xfe, 0xcb, 0xbf, 0xc9, 0x01, 0x40, 0xc7, 0x01, 0x38, 0xfe, 0xc8, 0x00, - 0x00, 0x01, 0x00, 0xc8, 0x00, 0x05, 0x04, 0x09, 0x05, 0xd6, 0x00, 0x11, - 0x00, 0x00, 0x01, 0x16, 0x17, 0x14, 0x07, 0x09, 0x01, 0x37, 0x13, 0x25, - 0x37, 0x01, 0x26, 0x35, 0x34, 0x37, 0x01, 0x36, 0x03, 0xce, 0x39, 0x02, - 0x09, 0xfd, 0x7d, 0x01, 0xee, 0x56, 0x26, 0xfe, 0x37, 0xe0, 0xfd, 0xdd, - 0x13, 0x41, 0x02, 0x93, 0x0b, 0x05, 0xd6, 0x02, 0x36, 0x24, 0x0c, 0xfd, - 0x85, 0xfd, 0xf4, 0xe6, 0xfe, 0x38, 0x27, 0x5e, 0x02, 0x34, 0x17, 0x17, - 0x1b, 0x3f, 0x02, 0x86, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x3b, - 0x00, 0x00, 0x04, 0x96, 0x05, 0xd9, 0x00, 0x19, 0x00, 0x00, 0x13, 0x21, - 0x32, 0x15, 0x14, 0x07, 0x09, 0x01, 0x37, 0x13, 0x25, 0x37, 0x01, 0x26, - 0x35, 0x34, 0x37, 0x01, 0x21, 0x11, 0x14, 0x23, 0x22, 0x35, 0x11, 0x34, - 0x7a, 0x03, 0xd6, 0x3c, 0x1a, 0xfd, 0xe5, 0x01, 0xc9, 0x53, 0x23, 0xfe, - 0x4e, 0xd8, 0xfe, 0x10, 0x0e, 0x31, 0x01, 0xc7, 0xfd, 0x0c, 0x44, 0x43, - 0x05, 0xd9, 0x53, 0x22, 0x1b, 0xfd, 0xc5, 0xfe, 0x1b, 0xd5, 0xfe, 0x3d, - 0x22, 0x6c, 0x02, 0x16, 0x0f, 0x2e, 0x1b, 0x33, 0x01, 0xdf, 0xfa, 0xfc, - 0x45, 0x44, 0x05, 0x5b, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x2b, - 0x00, 0x07, 0x04, 0xa6, 0x04, 0x81, 0x00, 0x0d, 0x00, 0x19, 0x00, 0x26, - 0x00, 0x00, 0x01, 0x14, 0x00, 0x23, 0x22, 0x00, 0x35, 0x34, 0x12, 0x24, - 0x33, 0x32, 0x04, 0x12, 0x05, 0x14, 0x00, 0x20, 0x00, 0x35, 0x34, 0x2e, - 0x01, 0x20, 0x0e, 0x01, 0x05, 0x14, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, - 0x3e, 0x01, 0x32, 0x1e, 0x01, 0x04, 0xa5, 0xfe, 0xb1, 0xee, 0xed, 0xfe, - 0xb1, 0x9a, 0x01, 0x13, 0x8f, 0x90, 0x01, 0x14, 0x99, 0xfb, 0xbf, 0x01, - 0x2d, 0x01, 0xad, 0x01, 0x2e, 0x8a, 0xf8, 0xfe, 0xfc, 0xf8, 0x8a, 0x02, - 0x94, 0x54, 0x3c, 0x3a, 0x55, 0x27, 0x45, 0x47, 0x45, 0x27, 0x02, 0x44, - 0xee, 0xfe, 0xb2, 0x01, 0x4e, 0xee, 0x95, 0x01, 0x14, 0x94, 0x94, 0xfe, - 0xed, 0x96, 0xd6, 0xfe, 0xd3, 0x01, 0x2d, 0xd6, 0x88, 0xf6, 0x85, 0x85, - 0xf6, 0x88, 0x3c, 0x53, 0x53, 0x3c, 0x26, 0x45, 0x24, 0x24, 0x45, 0x00, - 0x00, 0x03, 0x00, 0x0f, 0x00, 0x05, 0x04, 0xc2, 0x05, 0x1d, 0x00, 0x0a, - 0x00, 0x16, 0x00, 0x43, 0x00, 0x00, 0x00, 0x22, 0x06, 0x15, 0x14, 0x16, - 0x33, 0x32, 0x36, 0x35, 0x34, 0x25, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, - 0x32, 0x36, 0x35, 0x34, 0x26, 0x25, 0x16, 0x17, 0x16, 0x15, 0x14, 0x06, - 0x23, 0x22, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x24, - 0x20, 0x04, 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x14, 0x06, 0x23, 0x22, - 0x26, 0x34, 0x37, 0x36, 0x37, 0x26, 0x35, 0x34, 0x00, 0x33, 0x32, 0x00, - 0x15, 0x14, 0x04, 0x0b, 0x71, 0x4f, 0x4f, 0x39, 0x38, 0x4f, 0xfc, 0xa4, - 0x38, 0x50, 0x50, 0x38, 0x38, 0x4f, 0x4f, 0x03, 0x22, 0x13, 0x11, 0x46, - 0x8c, 0x63, 0x63, 0x8b, 0x44, 0x3e, 0x55, 0x5d, 0xff, 0x00, 0xfe, 0x90, - 0xff, 0x00, 0x5c, 0x60, 0x43, 0x44, 0x8b, 0x63, 0x62, 0x8d, 0x46, 0x0e, - 0x0e, 0x5d, 0x01, 0x57, 0xf6, 0xf8, 0x01, 0x57, 0x01, 0xb1, 0x5a, 0x41, - 0x40, 0x5a, 0x5a, 0x40, 0x41, 0x5a, 0x5a, 0x41, 0x40, 0x5b, 0x5b, 0x40, - 0x41, 0x5a, 0x4b, 0x0f, 0x14, 0x50, 0x72, 0x71, 0xa0, 0xa0, 0x71, 0x72, - 0x50, 0x47, 0x08, 0x65, 0x86, 0x9d, 0xde, 0xde, 0x9d, 0x86, 0x64, 0x03, - 0x4d, 0x50, 0xe4, 0xa0, 0xa0, 0xe4, 0x50, 0x0f, 0x0d, 0x7d, 0x9f, 0xd9, - 0x01, 0x32, 0xfe, 0xce, 0xd9, 0x9b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x12, - 0xff, 0xfe, 0x04, 0xbf, 0x05, 0x6b, 0x00, 0x0a, 0x00, 0x16, 0x00, 0x41, - 0x00, 0x00, 0x01, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x32, - 0x36, 0x25, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, - 0x36, 0x01, 0x14, 0x00, 0x23, 0x22, 0x00, 0x35, 0x34, 0x37, 0x26, 0x27, - 0x26, 0x34, 0x36, 0x33, 0x32, 0x16, 0x14, 0x07, 0x06, 0x07, 0x06, 0x15, - 0x14, 0x04, 0x20, 0x24, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x34, 0x36, - 0x33, 0x32, 0x16, 0x14, 0x07, 0x06, 0x07, 0x16, 0x04, 0x58, 0x50, 0x37, - 0x39, 0x4e, 0x4e, 0x71, 0x4f, 0xfd, 0x2e, 0x4e, 0x39, 0x37, 0x4f, 0x4f, - 0x37, 0x39, 0x4e, 0x03, 0x27, 0xfe, 0xab, 0xf7, 0xf5, 0xfe, 0xab, 0x5d, - 0x0e, 0x0e, 0x45, 0x8b, 0x61, 0x63, 0x8b, 0x44, 0x43, 0x5f, 0x5c, 0x00, - 0xff, 0x01, 0x6e, 0x00, 0xff, 0x5c, 0x55, 0x3e, 0x44, 0x8b, 0x62, 0x63, - 0x8a, 0x45, 0x11, 0x13, 0x58, 0x04, 0x46, 0x44, 0x62, 0x62, 0x44, 0x45, - 0x61, 0x61, 0x45, 0x45, 0x61, 0x61, 0x45, 0x44, 0x61, 0x61, 0xfe, 0x2b, - 0xe8, 0xfe, 0xb9, 0x01, 0x47, 0xe8, 0xa9, 0x84, 0x0e, 0x11, 0x55, 0xf2, - 0xab, 0xab, 0xf2, 0x55, 0x53, 0x03, 0x6a, 0x8e, 0xa9, 0xeb, 0xeb, 0xa9, - 0x8f, 0x69, 0x09, 0x4c, 0x56, 0xf2, 0xab, 0xab, 0xf2, 0x56, 0x15, 0x10, - 0x82, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x36, 0x00, 0x01, 0x04, 0x9b, - 0x05, 0xca, 0x00, 0x0b, 0x00, 0x1b, 0x00, 0x00, 0x01, 0x22, 0x06, 0x15, - 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x37, 0x16, 0x17, 0x16, - 0x10, 0x00, 0x23, 0x22, 0x00, 0x10, 0x00, 0x33, 0x32, 0x17, 0x01, 0x17, - 0x02, 0x3f, 0x8f, 0xc9, 0xc9, 0x8f, 0x8e, 0xc9, 0xc7, 0xbe, 0x13, 0x12, - 0x98, 0xfe, 0xce, 0xd9, 0xd7, 0xfe, 0xce, 0x01, 0x2f, 0xda, 0x60, 0x54, - 0x01, 0x0e, 0x9a, 0x03, 0x63, 0xc8, 0x90, 0x8e, 0xc9, 0xc9, 0x8e, 0x90, - 0xc8, 0x3b, 0x10, 0x13, 0x99, 0xfe, 0x50, 0xfe, 0xcf, 0x01, 0x31, 0x01, - 0xb0, 0x01, 0x32, 0x1d, 0x01, 0xd3, 0x59, 0x00, 0x00, 0x03, 0x00, 0x2e, - 0x00, 0x03, 0x04, 0xa3, 0x05, 0xcb, 0x00, 0x08, 0x00, 0x11, 0x00, 0x31, - 0x00, 0x00, 0x01, 0x22, 0x06, 0x14, 0x16, 0x32, 0x36, 0x34, 0x26, 0x00, - 0x22, 0x06, 0x14, 0x16, 0x33, 0x32, 0x36, 0x34, 0x01, 0x16, 0x15, 0x14, - 0x02, 0x23, 0x22, 0x02, 0x35, 0x34, 0x12, 0x33, 0x32, 0x17, 0x16, 0x17, - 0x37, 0x26, 0x35, 0x34, 0x12, 0x33, 0x32, 0x12, 0x15, 0x14, 0x02, 0x23, - 0x22, 0x27, 0x26, 0x27, 0x01, 0x40, 0x4b, 0x6a, 0x6a, 0x96, 0x6a, 0x69, - 0x02, 0x4f, 0x97, 0x69, 0x69, 0x4c, 0x4b, 0x69, 0xfd, 0xf7, 0x18, 0xa1, - 0x72, 0x71, 0xa1, 0xa0, 0x72, 0x74, 0x50, 0x01, 0x01, 0x8a, 0x12, 0x9f, - 0x73, 0x73, 0xa0, 0xa1, 0x72, 0x71, 0x51, 0x07, 0x07, 0x02, 0xdc, 0xa9, - 0xf0, 0xa9, 0xa9, 0xf0, 0xa9, 0x02, 0x5a, 0xa9, 0xf0, 0xa9, 0xa9, 0xf0, - 0xfd, 0xe4, 0x54, 0x64, 0xb5, 0xfe, 0xff, 0x01, 0x01, 0xb5, 0xb7, 0x01, - 0x01, 0x80, 0x03, 0x02, 0x89, 0x49, 0x55, 0xb7, 0x01, 0x01, 0xfe, 0xff, - 0xb7, 0xb5, 0xfe, 0xff, 0x81, 0x0b, 0x0c, 0x00, 0x00, 0x0e, 0x00, 0x14, - 0xff, 0xff, 0x04, 0xbd, 0x04, 0xc8, 0x00, 0x17, 0x00, 0x29, 0x00, 0x35, - 0x00, 0x41, 0x00, 0x4d, 0x00, 0x59, 0x00, 0x64, 0x00, 0x70, 0x00, 0x7b, - 0x00, 0x86, 0x00, 0x91, 0x00, 0x9d, 0x00, 0xa9, 0x00, 0xb5, 0x00, 0x00, - 0x01, 0x33, 0x04, 0x17, 0x16, 0x15, 0x06, 0x2f, 0x01, 0x26, 0x37, 0x36, - 0x27, 0x21, 0x06, 0x17, 0x16, 0x0f, 0x01, 0x06, 0x27, 0x34, 0x37, 0x36, - 0x01, 0x35, 0x33, 0x15, 0x14, 0x17, 0x16, 0x15, 0x11, 0x21, 0x11, 0x34, - 0x37, 0x36, 0x3d, 0x01, 0x33, 0x15, 0x03, 0x14, 0x16, 0x33, 0x32, 0x36, - 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x05, 0x14, 0x06, 0x23, 0x22, 0x26, - 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x27, 0x14, 0x06, 0x23, 0x22, 0x26, - 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x11, 0x14, 0x06, 0x23, 0x22, 0x26, - 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x02, 0x16, 0x06, 0x07, 0x06, 0x26, - 0x27, 0x26, 0x36, 0x37, 0x36, 0x13, 0x16, 0x06, 0x07, 0x06, 0x26, 0x27, - 0x26, 0x36, 0x37, 0x36, 0x16, 0x01, 0x1e, 0x01, 0x0e, 0x01, 0x27, 0x2e, - 0x01, 0x37, 0x3e, 0x01, 0x04, 0x1e, 0x01, 0x07, 0x0e, 0x01, 0x27, 0x2e, - 0x01, 0x37, 0x36, 0x24, 0x36, 0x16, 0x17, 0x16, 0x06, 0x07, 0x06, 0x26, - 0x27, 0x26, 0x25, 0x36, 0x16, 0x17, 0x16, 0x06, 0x07, 0x06, 0x26, 0x27, - 0x26, 0x36, 0x01, 0x3e, 0x01, 0x17, 0x1e, 0x01, 0x07, 0x0e, 0x01, 0x27, - 0x2e, 0x01, 0x13, 0x3e, 0x01, 0x17, 0x1e, 0x01, 0x07, 0x0e, 0x01, 0x27, - 0x2e, 0x01, 0x02, 0x66, 0x05, 0x01, 0x3c, 0x87, 0x8e, 0x14, 0x3b, 0xd6, - 0x2e, 0x15, 0x3d, 0x2b, 0xfd, 0xb2, 0x2c, 0x3e, 0x15, 0x2f, 0xd6, 0x3b, - 0x14, 0x8e, 0x87, 0x01, 0xbb, 0x4b, 0x7f, 0x79, 0xfc, 0x81, 0x7a, 0x7e, - 0x4c, 0x5a, 0x7c, 0x57, 0x58, 0x7b, 0x7b, 0x58, 0x58, 0x7b, 0x01, 0x49, - 0x45, 0x31, 0x31, 0x45, 0x45, 0x31, 0x31, 0x45, 0x54, 0x11, 0x0c, 0x0c, - 0x12, 0x12, 0x0c, 0x0c, 0x11, 0x11, 0x0c, 0x0c, 0x12, 0x12, 0x0c, 0x0c, - 0x11, 0x6d, 0x0d, 0x03, 0x0a, 0x0a, 0x18, 0x07, 0x08, 0x04, 0x0a, 0x0a, - 0xe2, 0x07, 0x03, 0x0b, 0x0a, 0x17, 0x08, 0x07, 0x04, 0x0a, 0x0a, 0x18, - 0xfe, 0xf9, 0x0d, 0x0a, 0x07, 0x16, 0x0c, 0x0b, 0x0c, 0x04, 0x04, 0x16, - 0x01, 0x3b, 0x17, 0x0b, 0x04, 0x04, 0x16, 0x0b, 0x0c, 0x0b, 0x04, 0x04, - 0xfe, 0xc9, 0x17, 0x16, 0x04, 0x03, 0x0a, 0x0c, 0x0c, 0x16, 0x04, 0x04, - 0x01, 0x52, 0x0b, 0x16, 0x04, 0x04, 0x0b, 0x0c, 0x0b, 0x17, 0x03, 0x04, - 0x0b, 0xfe, 0xff, 0x07, 0x18, 0x0a, 0x0a, 0x04, 0x08, 0x06, 0x19, 0x0a, - 0x0a, 0x04, 0xca, 0x08, 0x17, 0x0a, 0x0b, 0x03, 0x07, 0x07, 0x18, 0x0a, - 0x0a, 0x04, 0x04, 0xc8, 0x0e, 0x7f, 0x87, 0x8b, 0x85, 0x08, 0x73, 0x16, - 0x40, 0x64, 0x06, 0x06, 0x64, 0x40, 0x16, 0x73, 0x08, 0x85, 0x8b, 0x87, - 0x7d, 0xfe, 0xbd, 0x3e, 0x7d, 0x3d, 0x2f, 0x4e, 0xea, 0xfe, 0x6e, 0x01, - 0x92, 0xea, 0x4e, 0x2f, 0x3d, 0x7d, 0x3e, 0xfe, 0x40, 0x89, 0xc0, 0xc0, - 0x89, 0x88, 0xc1, 0xc1, 0x87, 0x4d, 0x6c, 0x6c, 0x4d, 0x4e, 0x6b, 0x6b, - 0xb6, 0x12, 0x1c, 0x1c, 0x12, 0x13, 0x1c, 0x1c, 0xfd, 0xe9, 0x14, 0x1b, - 0x1b, 0x14, 0x13, 0x1c, 0x1c, 0x01, 0xeb, 0x1f, 0x26, 0x0b, 0x0c, 0x06, - 0x0f, 0x11, 0x25, 0x0c, 0x0b, 0xfe, 0x49, 0x10, 0x25, 0x0d, 0x0a, 0x05, - 0x11, 0x0f, 0x25, 0x0c, 0x0a, 0x05, 0x01, 0x22, 0x07, 0x21, 0x24, 0x12, - 0x05, 0x06, 0x23, 0x12, 0x12, 0x12, 0xa0, 0x0c, 0x22, 0x12, 0x12, 0x11, - 0x06, 0x06, 0x21, 0x13, 0x12, 0x05, 0x0c, 0x11, 0x12, 0x13, 0x22, 0x07, - 0x04, 0x11, 0x12, 0x12, 0xc8, 0x06, 0x12, 0x12, 0x12, 0x21, 0x07, 0x06, - 0x12, 0x12, 0x12, 0x21, 0xfe, 0xd6, 0x0f, 0x05, 0x0a, 0x0c, 0x26, 0x0e, - 0x11, 0x05, 0x0a, 0x0d, 0x25, 0x01, 0xb1, 0x10, 0x06, 0x0b, 0x0c, 0x25, - 0x11, 0x0f, 0x06, 0x0c, 0x0b, 0x26, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08, - 0x00, 0x0b, 0x04, 0xc9, 0x04, 0xc9, 0x00, 0x11, 0x00, 0x1d, 0x00, 0x25, - 0x00, 0x2d, 0x00, 0x35, 0x00, 0x41, 0x00, 0x4d, 0x00, 0x59, 0x00, 0x64, - 0x00, 0x70, 0x00, 0x7c, 0x00, 0x88, 0x00, 0x94, 0x00, 0xa6, 0x00, 0xc0, - 0x00, 0xda, 0x00, 0x00, 0x01, 0x35, 0x23, 0x15, 0x06, 0x07, 0x06, 0x15, - 0x11, 0x21, 0x11, 0x34, 0x27, 0x26, 0x27, 0x35, 0x23, 0x15, 0x07, 0x32, - 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x16, 0x22, - 0x06, 0x14, 0x16, 0x32, 0x36, 0x34, 0x26, 0x22, 0x06, 0x14, 0x16, 0x32, - 0x36, 0x34, 0x02, 0x22, 0x06, 0x14, 0x16, 0x32, 0x36, 0x34, 0x03, 0x0e, - 0x01, 0x17, 0x1e, 0x01, 0x37, 0x3e, 0x01, 0x27, 0x2e, 0x01, 0x13, 0x0e, - 0x01, 0x17, 0x1e, 0x01, 0x37, 0x3e, 0x01, 0x27, 0x2e, 0x01, 0x25, 0x06, - 0x16, 0x17, 0x16, 0x36, 0x37, 0x36, 0x26, 0x27, 0x26, 0x06, 0x05, 0x06, - 0x16, 0x17, 0x16, 0x3e, 0x01, 0x26, 0x27, 0x26, 0x06, 0x05, 0x1e, 0x01, - 0x37, 0x3e, 0x01, 0x27, 0x2e, 0x01, 0x07, 0x0e, 0x01, 0x25, 0x1e, 0x01, - 0x37, 0x3e, 0x01, 0x27, 0x2e, 0x01, 0x07, 0x0e, 0x01, 0x03, 0x16, 0x36, - 0x37, 0x36, 0x26, 0x27, 0x26, 0x06, 0x07, 0x06, 0x16, 0x13, 0x16, 0x36, - 0x37, 0x36, 0x26, 0x27, 0x26, 0x06, 0x07, 0x06, 0x16, 0x37, 0x35, 0x33, - 0x15, 0x14, 0x17, 0x16, 0x15, 0x11, 0x21, 0x11, 0x34, 0x37, 0x36, 0x3d, - 0x01, 0x33, 0x15, 0x27, 0x06, 0x17, 0x16, 0x0f, 0x01, 0x06, 0x27, 0x36, - 0x37, 0x36, 0x25, 0x16, 0x32, 0x37, 0x04, 0x17, 0x16, 0x17, 0x06, 0x2f, - 0x01, 0x26, 0x37, 0x36, 0x27, 0x37, 0x16, 0x07, 0x06, 0x1f, 0x01, 0x16, - 0x37, 0x26, 0x27, 0x26, 0x2f, 0x01, 0x15, 0x23, 0x06, 0x07, 0x06, 0x07, - 0x16, 0x3f, 0x01, 0x36, 0x27, 0x26, 0x37, 0x01, 0xd4, 0x1a, 0x08, 0x6c, - 0x69, 0x03, 0x01, 0x69, 0x6c, 0x04, 0x1e, 0x8c, 0x59, 0x7a, 0x7b, 0x58, - 0x57, 0x7c, 0x7b, 0x89, 0x62, 0x45, 0x45, 0x62, 0x45, 0x64, 0x19, 0x11, - 0x11, 0x19, 0x11, 0x11, 0x19, 0x11, 0x11, 0x19, 0x11, 0x91, 0x0a, 0x04, - 0x07, 0x08, 0x18, 0x0a, 0x0a, 0x03, 0x07, 0x07, 0x18, 0xb9, 0x0a, 0x04, - 0x07, 0x07, 0x19, 0x0a, 0x0a, 0x04, 0x08, 0x07, 0x18, 0xfe, 0xec, 0x04, - 0x0c, 0x0b, 0x0c, 0x16, 0x04, 0x03, 0x0a, 0x0d, 0x0b, 0x16, 0x01, 0x38, - 0x04, 0x0b, 0x0b, 0x0c, 0x16, 0x07, 0x0b, 0x0b, 0x0c, 0x16, 0xfe, 0xc1, - 0x04, 0x16, 0x0c, 0x0c, 0x0a, 0x03, 0x04, 0x16, 0x0c, 0x0b, 0x0c, 0x01, - 0x40, 0x03, 0x16, 0x0c, 0x0b, 0x0b, 0x04, 0x03, 0x16, 0x0c, 0x0b, 0x0b, - 0xf1, 0x0a, 0x18, 0x07, 0x08, 0x04, 0x0a, 0x0a, 0x18, 0x08, 0x07, 0x04, - 0xcd, 0x0a, 0x18, 0x07, 0x08, 0x04, 0x0a, 0x0a, 0x19, 0x07, 0x07, 0x04, - 0x2e, 0x48, 0x78, 0x74, 0xfc, 0xac, 0x74, 0x78, 0x48, 0xb8, 0x25, 0x3f, - 0x25, 0x35, 0xc8, 0x45, 0x24, 0x07, 0x84, 0x85, 0x01, 0x36, 0x0d, 0x1a, - 0x0c, 0x01, 0x36, 0x85, 0x84, 0x07, 0x24, 0x44, 0xc9, 0x35, 0x25, 0x3f, - 0x25, 0x0e, 0x2d, 0x35, 0x21, 0x21, 0xae, 0x31, 0x28, 0x05, 0x7f, 0xa7, - 0xff, 0x1a, 0x1d, 0xff, 0xa7, 0x7e, 0x06, 0x28, 0x31, 0xaf, 0x20, 0x20, - 0x35, 0x2c, 0x03, 0x1a, 0x34, 0x74, 0x34, 0x28, 0x34, 0xc4, 0xfe, 0xb2, - 0x01, 0x4e, 0xc4, 0x34, 0x28, 0x34, 0x74, 0x34, 0x3b, 0xbc, 0x84, 0x85, - 0xbb, 0xbb, 0x85, 0x84, 0xbc, 0x8d, 0x68, 0x96, 0x68, 0x68, 0x96, 0xe0, - 0x1a, 0x25, 0x1a, 0x1a, 0x25, 0xfe, 0x23, 0x1a, 0x25, 0x1a, 0x1a, 0x25, - 0x01, 0xd8, 0x0b, 0x24, 0x10, 0x0e, 0x07, 0x0b, 0x0c, 0x25, 0x0f, 0x0e, - 0x06, 0xfe, 0x5f, 0x0c, 0x24, 0x10, 0x0f, 0x06, 0x0c, 0x0b, 0x24, 0x0f, - 0x10, 0x05, 0xf8, 0x12, 0x21, 0x06, 0x05, 0x10, 0x13, 0x11, 0x22, 0x05, - 0x06, 0x12, 0xad, 0x11, 0x21, 0x06, 0x06, 0x11, 0x24, 0x21, 0x06, 0x06, - 0x10, 0x2f, 0x12, 0x11, 0x06, 0x06, 0x21, 0x11, 0x12, 0x12, 0x06, 0x06, - 0x21, 0x8a, 0x12, 0x11, 0x05, 0x06, 0x21, 0x12, 0x11, 0x12, 0x06, 0x05, - 0x22, 0xfe, 0xbf, 0x0c, 0x06, 0x0f, 0x10, 0x24, 0x0b, 0x0b, 0x05, 0x10, - 0x0f, 0x24, 0x01, 0x8b, 0x0b, 0x07, 0x0e, 0x10, 0x24, 0x0b, 0x0c, 0x06, - 0x0f, 0x0f, 0x25, 0xea, 0x3a, 0x7f, 0x2d, 0x2c, 0x47, 0xd9, 0xfe, 0x8c, - 0x01, 0x74, 0xd9, 0x47, 0x2c, 0x2d, 0x7f, 0x3a, 0xba, 0x0d, 0x58, 0x4c, - 0x0f, 0x86, 0x08, 0xac, 0xa2, 0x52, 0x71, 0x0e, 0x01, 0x01, 0x0e, 0x71, - 0x52, 0xa2, 0xac, 0x08, 0x86, 0x0f, 0x4c, 0x58, 0x0d, 0x17, 0x21, 0x5b, - 0x24, 0x1f, 0x6e, 0x1e, 0x93, 0x80, 0x5b, 0x69, 0x14, 0x01, 0x01, 0x14, - 0x69, 0x5b, 0x80, 0x93, 0x1e, 0x6e, 0x1f, 0x24, 0x5b, 0x21, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x6f, 0x00, 0x04, 0x04, 0x62, 0x04, 0x08, 0x00, 0x07, - 0x00, 0x0b, 0x00, 0x00, 0x13, 0x21, 0x17, 0x11, 0x07, 0x21, 0x27, 0x11, - 0x17, 0x11, 0x21, 0x11, 0x74, 0x03, 0xe9, 0x04, 0x04, 0xfc, 0x17, 0x04, - 0x4b, 0x03, 0x5a, 0x04, 0x07, 0x05, 0xfc, 0x07, 0x04, 0x04, 0x03, 0xf9, - 0x47, 0xfc, 0x95, 0x03, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x63, - 0xff, 0xfd, 0x04, 0x6e, 0x04, 0x18, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x22, - 0x00, 0x00, 0x13, 0x21, 0x17, 0x11, 0x07, 0x21, 0x27, 0x11, 0x17, 0x11, - 0x21, 0x11, 0x07, 0x15, 0x06, 0x07, 0x02, 0x07, 0x06, 0x23, 0x06, 0x23, - 0x26, 0x2b, 0x01, 0x35, 0x37, 0x32, 0x17, 0x33, 0x36, 0x37, 0x36, 0x37, - 0x36, 0x68, 0x04, 0x01, 0x05, 0x05, 0xfb, 0xff, 0x05, 0x4e, 0x03, 0x6e, - 0x5f, 0x35, 0x1d, 0xe6, 0x2c, 0x04, 0x0b, 0x53, 0x09, 0x47, 0x90, 0x10, - 0x72, 0x6a, 0x33, 0x05, 0x23, 0x2d, 0x45, 0x6d, 0x44, 0x04, 0x18, 0x04, - 0xfb, 0xef, 0x05, 0x05, 0x04, 0x11, 0x4a, 0xfc, 0x82, 0x03, 0x7e, 0x6f, - 0x04, 0x2e, 0x28, 0xfe, 0xc9, 0xe3, 0x2a, 0x21, 0xb6, 0x04, 0x34, 0x5c, - 0x74, 0x52, 0x7e, 0x83, 0x55, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x85, - 0x00, 0x05, 0x04, 0x4c, 0x03, 0xda, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x1a, - 0x00, 0x00, 0x13, 0x21, 0x17, 0x11, 0x07, 0x21, 0x27, 0x11, 0x17, 0x11, - 0x21, 0x11, 0x05, 0x09, 0x01, 0x17, 0x09, 0x01, 0x15, 0x07, 0x01, 0x23, - 0x01, 0x23, 0x27, 0x09, 0x01, 0x8a, 0x03, 0xbd, 0x04, 0x04, 0xfc, 0x43, - 0x04, 0x49, 0x03, 0x33, 0xfd, 0x5a, 0x01, 0x0d, 0x01, 0x0c, 0x3e, 0xfe, - 0xf4, 0x01, 0x0c, 0x3c, 0xfe, 0xf2, 0x02, 0xfe, 0xf5, 0x03, 0x3c, 0x01, - 0x0c, 0xfe, 0xf4, 0x03, 0xd9, 0x04, 0xfc, 0x35, 0x05, 0x05, 0x03, 0xcb, - 0x44, 0xfc, 0xbd, 0x03, 0x43, 0x58, 0xfe, 0xf5, 0x01, 0x0b, 0x3c, 0xfe, - 0xf3, 0xfe, 0xf2, 0x01, 0x3c, 0x01, 0x0b, 0xfe, 0xf7, 0x3b, 0x01, 0x0e, - 0x01, 0x0d, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc9, 0x00, 0x59, 0x04, 0x08, - 0x05, 0x44, 0x00, 0x14, 0x00, 0x00, 0x01, 0x33, 0x01, 0x36, 0x01, 0x32, - 0x37, 0x33, 0x17, 0x09, 0x01, 0x15, 0x07, 0x01, 0x23, 0x01, 0x23, 0x27, - 0x01, 0x00, 0x35, 0x01, 0x26, 0x05, 0x01, 0x3c, 0x0c, 0x01, 0x2b, 0x04, - 0x07, 0x04, 0x5a, 0xfe, 0xc0, 0x01, 0x40, 0x5c, 0xfe, 0xc1, 0x02, 0xfe, - 0xbf, 0x03, 0x5c, 0x01, 0x44, 0xfe, 0xbc, 0x05, 0x43, 0xfd, 0xec, 0x09, - 0x01, 0xfb, 0x10, 0x5a, 0xfd, 0xe4, 0xfd, 0xe8, 0x03, 0x59, 0x02, 0x17, - 0xfd, 0xeb, 0x5c, 0x02, 0x18, 0x02, 0x15, 0x07, 0x00, 0x08, 0x00, 0x1c, - 0xff, 0xfc, 0x04, 0xb5, 0x05, 0x35, 0x00, 0x08, 0x00, 0x11, 0x00, 0x1a, - 0x00, 0x23, 0x00, 0x2c, 0x00, 0x35, 0x00, 0x3e, 0x00, 0x7e, 0x00, 0x00, - 0x01, 0x33, 0x06, 0x2b, 0x01, 0x26, 0x3d, 0x01, 0x34, 0x25, 0x33, 0x06, - 0x2b, 0x01, 0x26, 0x3d, 0x01, 0x34, 0x25, 0x33, 0x06, 0x2b, 0x01, 0x26, - 0x3d, 0x01, 0x34, 0x17, 0x33, 0x06, 0x2b, 0x01, 0x26, 0x3d, 0x01, 0x34, - 0x25, 0x33, 0x06, 0x2b, 0x01, 0x26, 0x3d, 0x01, 0x34, 0x17, 0x33, 0x06, - 0x2b, 0x01, 0x26, 0x3d, 0x01, 0x34, 0x17, 0x33, 0x06, 0x2b, 0x01, 0x26, - 0x3d, 0x01, 0x34, 0x25, 0x33, 0x17, 0x15, 0x33, 0x20, 0x13, 0x16, 0x1d, - 0x01, 0x23, 0x26, 0x27, 0x26, 0x2b, 0x01, 0x22, 0x07, 0x15, 0x14, 0x07, - 0x27, 0x26, 0x23, 0x11, 0x14, 0x0f, 0x01, 0x22, 0x2f, 0x01, 0x35, 0x37, - 0x33, 0x17, 0x15, 0x16, 0x3b, 0x01, 0x32, 0x3f, 0x01, 0x11, 0x22, 0x07, - 0x06, 0x23, 0x27, 0x35, 0x37, 0x23, 0x26, 0x27, 0x23, 0x22, 0x0f, 0x01, - 0x23, 0x35, 0x36, 0x37, 0x36, 0x33, 0x35, 0x01, 0x1f, 0x02, 0x15, 0x40, - 0x04, 0x29, 0x01, 0xa3, 0x01, 0x14, 0x41, 0x04, 0x28, 0x01, 0x7b, 0x02, - 0x15, 0x40, 0x05, 0x28, 0xad, 0x02, 0x15, 0x40, 0x04, 0x29, 0x01, 0x7b, - 0x03, 0x15, 0x41, 0x04, 0x29, 0xce, 0x01, 0x13, 0x41, 0x05, 0x28, 0x40, - 0x02, 0x15, 0x41, 0x04, 0x28, 0xfe, 0x5e, 0x29, 0x04, 0x01, 0x01, 0x34, - 0xc4, 0x1e, 0x01, 0x10, 0x0d, 0x19, 0x27, 0x1f, 0x69, 0x4f, 0x05, 0x17, - 0x6a, 0x5f, 0x4a, 0x15, 0x40, 0x1a, 0x01, 0x04, 0x1e, 0x04, 0x07, 0x2c, - 0x07, 0x26, 0x0e, 0x04, 0x93, 0x3c, 0x0c, 0x0a, 0x05, 0x05, 0x03, 0x2f, - 0x89, 0x2f, 0x46, 0x17, 0x0e, 0x02, 0x28, 0x86, 0xa8, 0xda, 0x04, 0x30, - 0x91, 0x07, 0x19, 0x01, 0x27, 0xf9, 0x90, 0x05, 0x19, 0x02, 0x26, 0x9f, - 0x91, 0x06, 0x19, 0x02, 0x26, 0x82, 0x90, 0x05, 0x19, 0x02, 0x27, 0xdc, - 0x90, 0x05, 0x19, 0x02, 0x27, 0x4a, 0x90, 0x04, 0x1a, 0x02, 0x26, 0xa4, - 0x91, 0x06, 0x19, 0x01, 0x28, 0x6c, 0x04, 0x4e, 0xfe, 0xd2, 0x35, 0x09, - 0x05, 0x09, 0x1d, 0x0f, 0x3e, 0x21, 0x09, 0x01, 0x29, 0x26, 0xfe, 0x56, - 0x3f, 0x0f, 0x01, 0x3c, 0x11, 0x10, 0x04, 0x04, 0x07, 0x3f, 0x24, 0x19, - 0x01, 0xa5, 0x26, 0x24, 0x04, 0x08, 0x20, 0x27, 0x11, 0x26, 0x0b, 0x01, - 0x5a, 0x87, 0x8b, 0x4e, 0x00, 0x09, 0x00, 0x4e, 0x00, 0x06, 0x04, 0x83, - 0x05, 0x82, 0x00, 0x09, 0x00, 0x0f, 0x00, 0x18, 0x00, 0x2f, 0x00, 0x3e, - 0x00, 0x45, 0x00, 0x71, 0x00, 0x77, 0x00, 0x86, 0x00, 0x00, 0x13, 0x06, - 0x17, 0x21, 0x36, 0x37, 0x34, 0x23, 0x21, 0x06, 0x13, 0x16, 0x17, 0x21, - 0x36, 0x3f, 0x01, 0x06, 0x07, 0x36, 0x37, 0x36, 0x27, 0x34, 0x23, 0x27, - 0x06, 0x07, 0x33, 0x32, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x33, - 0x32, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x23, 0x01, 0x33, - 0x14, 0x06, 0x07, 0x14, 0x16, 0x17, 0x23, 0x26, 0x27, 0x26, 0x27, 0x26, - 0x36, 0x03, 0x16, 0x25, 0x36, 0x37, 0x21, 0x16, 0x05, 0x36, 0x37, 0x32, - 0x17, 0x15, 0x14, 0x0f, 0x01, 0x17, 0x14, 0x07, 0x21, 0x26, 0x3d, 0x01, - 0x37, 0x35, 0x24, 0x2f, 0x01, 0x35, 0x36, 0x33, 0x16, 0x17, 0x26, 0x11, - 0x34, 0x33, 0x21, 0x16, 0x15, 0x33, 0x32, 0x15, 0x14, 0x07, 0x06, 0x07, - 0x06, 0x2b, 0x01, 0x27, 0x01, 0x16, 0x17, 0x21, 0x36, 0x37, 0x03, 0x06, - 0x07, 0x06, 0x07, 0x23, 0x3e, 0x01, 0x35, 0x34, 0x26, 0x35, 0x33, 0x1e, - 0x01, 0xb0, 0x01, 0x0c, 0x03, 0x2a, 0x08, 0x02, 0x15, 0xfc, 0xec, 0x13, - 0x2c, 0x04, 0x0b, 0x02, 0xc7, 0x0a, 0x06, 0x33, 0x06, 0x29, 0x3d, 0x22, - 0x16, 0x02, 0x17, 0x28, 0x01, 0x01, 0x26, 0x29, 0x30, 0x1f, 0x39, 0x16, - 0x24, 0x05, 0x29, 0x1b, 0x0d, 0x4c, 0x26, 0x15, 0x10, 0x54, 0xfe, 0x06, - 0x06, 0x45, 0x01, 0x60, 0x03, 0x06, 0x0d, 0x4d, 0x17, 0x07, 0x02, 0x50, - 0xce, 0xf8, 0x01, 0x05, 0x18, 0x41, 0xfd, 0x5b, 0x1a, 0x02, 0x4d, 0xb2, - 0x48, 0x0d, 0x04, 0xfc, 0x59, 0x01, 0x0b, 0xfe, 0x8e, 0x0c, 0x03, 0xfe, - 0xdf, 0x24, 0x02, 0x03, 0x0d, 0x3b, 0x97, 0x8d, 0x26, 0x03, 0x18, 0x17, - 0x26, 0x65, 0x3d, 0x18, 0x4f, 0x25, 0x2f, 0x05, 0x0c, 0xfd, 0x4e, 0x04, - 0x07, 0x02, 0xff, 0x08, 0x03, 0xfd, 0x05, 0x0d, 0x2c, 0x08, 0x04, 0x02, - 0x38, 0x28, 0x04, 0x07, 0x2e, 0x02, 0x8f, 0x37, 0x4c, 0x31, 0x52, 0x15, - 0x04, 0xfe, 0xe0, 0x18, 0x11, 0x15, 0x14, 0xbb, 0x66, 0x7e, 0x01, 0x48, - 0x38, 0x53, 0x10, 0x51, 0x1b, 0x1e, 0x2c, 0x7a, 0x48, 0x25, 0x01, 0x39, - 0x44, 0x36, 0x0d, 0x1d, 0x29, 0x6a, 0x47, 0x50, 0x40, 0x02, 0xf6, 0x34, - 0x80, 0x52, 0x6a, 0x64, 0xa6, 0x89, 0x5f, 0x2a, 0x4b, 0x66, 0x73, 0xfb, - 0x44, 0x16, 0x14, 0x0f, 0x8e, 0x49, 0x52, 0x17, 0x09, 0x09, 0x0a, 0x0f, - 0x39, 0x21, 0x0a, 0x0e, 0x07, 0x06, 0x0f, 0x06, 0x02, 0x02, 0x4f, 0x11, - 0x0c, 0x04, 0x0a, 0x08, 0x13, 0xee, 0x01, 0x1c, 0x2d, 0x02, 0x16, 0x5d, - 0x91, 0x90, 0x26, 0x15, 0x43, 0x04, 0x01, 0x2b, 0x19, 0x11, 0x12, 0x18, - 0x01, 0xd5, 0x2f, 0x1a, 0x3c, 0x55, 0x67, 0x40, 0x41, 0x35, 0x4f, 0x21, - 0x2b, 0x47, 0x00, 0x00, 0x00, 0x02, 0x00, 0x38, 0x00, 0x07, 0x04, 0x99, - 0x05, 0xdf, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x00, 0x09, 0x01, 0x13, 0x07, - 0x21, 0x27, 0x13, 0x09, 0x01, 0x03, 0x21, 0x03, 0x01, 0x02, 0x6e, 0x01, - 0xeb, 0x3f, 0x02, 0xfb, 0xa7, 0x04, 0x42, 0x01, 0xf1, 0xfe, 0x5a, 0x39, - 0x03, 0xb7, 0x36, 0xfe, 0x5c, 0x05, 0xdf, 0xfe, 0x77, 0xfb, 0xb4, 0x03, - 0x06, 0x04, 0x4c, 0x01, 0x86, 0xfe, 0x35, 0xfc, 0x5f, 0x03, 0xa1, 0x01, - 0x4b, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x2f, 0x00, 0x02, 0x04, 0xa2, - 0x05, 0xd2, 0x00, 0x09, 0x00, 0x00, 0x09, 0x01, 0x13, 0x17, 0x07, 0x21, - 0x27, 0x13, 0x00, 0x37, 0x02, 0x6c, 0x01, 0xf1, 0x42, 0x02, 0x02, 0xfb, - 0x95, 0x04, 0x44, 0x01, 0xe6, 0x10, 0x05, 0xd2, 0xfe, 0x77, 0xfb, 0xbf, - 0x03, 0x03, 0x06, 0x04, 0x44, 0x01, 0x80, 0x06, 0x00, 0x01, 0x00, 0x26, - 0x00, 0x07, 0x04, 0xab, 0x04, 0xc4, 0x00, 0x42, 0x00, 0x00, 0x01, 0x27, - 0x26, 0x35, 0x34, 0x37, 0x36, 0x33, 0x32, 0x16, 0x36, 0x33, 0x32, 0x17, - 0x16, 0x15, 0x14, 0x0f, 0x01, 0x37, 0x36, 0x17, 0x16, 0x17, 0x16, 0x15, - 0x14, 0x07, 0x0e, 0x01, 0x16, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, - 0x26, 0x2f, 0x01, 0x12, 0x07, 0x23, 0x36, 0x03, 0x07, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x36, 0x26, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x36, 0x37, 0x36, 0x17, 0x02, 0x52, 0xa5, 0x38, 0x43, 0x1c, 0x1d, - 0x43, 0x42, 0x43, 0x2c, 0x47, 0x2a, 0x0a, 0x45, 0x98, 0xf8, 0x68, 0x5d, - 0x1b, 0x1a, 0x36, 0x06, 0x0d, 0x65, 0x3b, 0x16, 0x08, 0x19, 0x2c, 0x30, - 0x19, 0x1b, 0x51, 0x3a, 0x9d, 0x1f, 0x6e, 0x48, 0x88, 0x1e, 0x9d, 0x3b, - 0x50, 0x1b, 0x19, 0x30, 0x2b, 0x1a, 0x09, 0x15, 0x3b, 0x65, 0x0d, 0x06, - 0x36, 0x1a, 0x1b, 0x5c, 0x69, 0x02, 0x7e, 0xfa, 0x54, 0x5a, 0x57, 0x34, - 0x12, 0x58, 0x58, 0x5c, 0x22, 0x1f, 0x67, 0x5e, 0xe1, 0x52, 0x29, 0x20, - 0x0a, 0x16, 0x35, 0x36, 0x11, 0x11, 0x2e, 0x27, 0x5f, 0x45, 0x1e, 0x16, - 0x21, 0x0a, 0x1b, 0x53, 0xe2, 0xfe, 0xbe, 0xf1, 0xf1, 0x01, 0x42, 0xe2, - 0x53, 0x1b, 0x0a, 0x21, 0x16, 0x1e, 0x45, 0x5f, 0x27, 0x2e, 0x11, 0x10, - 0x37, 0x35, 0x16, 0x0a, 0x20, 0x29, 0x00, 0x00, 0x00, 0x02, 0x00, 0x2f, - 0x01, 0xa0, 0x04, 0xa2, 0x04, 0x74, 0x00, 0x39, 0x00, 0x3e, 0x00, 0x00, - 0x01, 0x16, 0x17, 0x14, 0x07, 0x06, 0x07, 0x16, 0x17, 0x33, 0x17, 0x07, - 0x23, 0x06, 0x07, 0x22, 0x27, 0x34, 0x33, 0x16, 0x37, 0x32, 0x37, 0x26, - 0x27, 0x23, 0x22, 0x07, 0x16, 0x15, 0x06, 0x07, 0x24, 0x03, 0x34, 0x37, - 0x16, 0x17, 0x15, 0x07, 0x14, 0x17, 0x32, 0x37, 0x12, 0x37, 0x16, 0x07, - 0x14, 0x07, 0x36, 0x37, 0x32, 0x35, 0x36, 0x37, 0x36, 0x26, 0x03, 0x06, - 0x17, 0x35, 0x26, 0x03, 0xfb, 0x55, 0x0f, 0x38, 0x86, 0x0f, 0xc3, 0x29, - 0x15, 0x0f, 0x24, 0x02, 0x0d, 0x74, 0x4a, 0x13, 0x0f, 0x0c, 0x2e, 0x3b, - 0x09, 0xc7, 0x05, 0x03, 0x64, 0x33, 0x66, 0x07, 0xff, 0xfe, 0x2c, 0x22, - 0x33, 0x27, 0x06, 0x0a, 0x56, 0x44, 0x0a, 0x28, 0xe3, 0x99, 0x04, 0x20, - 0x47, 0x4c, 0x2f, 0x37, 0x3b, 0x3b, 0x2c, 0x67, 0x0b, 0xb9, 0x18, 0x04, - 0x74, 0x04, 0x5e, 0x46, 0x15, 0x1d, 0x24, 0x16, 0xdd, 0x3c, 0x0a, 0x8e, - 0x07, 0x4c, 0x44, 0x26, 0x01, 0x3f, 0x3e, 0xc4, 0x58, 0x34, 0x52, 0xc8, - 0x0d, 0x02, 0x01, 0x21, 0x2f, 0x08, 0x03, 0x23, 0x13, 0x20, 0x49, 0x0a, - 0x3f, 0x01, 0x84, 0x10, 0x04, 0x89, 0x20, 0x50, 0x3f, 0x10, 0x1f, 0x44, - 0x21, 0x29, 0x4d, 0xfe, 0xe6, 0x76, 0x3e, 0x02, 0x93, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x2f, 0x01, 0x0e, 0x04, 0xa2, 0x04, 0x7a, 0x00, 0x32, - 0x00, 0x00, 0x01, 0x21, 0x22, 0x26, 0x35, 0x34, 0x36, 0x37, 0x36, 0x37, - 0x33, 0x37, 0x23, 0x26, 0x27, 0x26, 0x35, 0x34, 0x3e, 0x01, 0x3b, 0x01, - 0x37, 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x37, 0x36, 0x37, 0x21, 0x37, - 0x21, 0x22, 0x26, 0x35, 0x34, 0x3e, 0x01, 0x33, 0x21, 0x36, 0x37, 0x36, - 0x33, 0x21, 0x32, 0x16, 0x15, 0x04, 0x68, 0xfd, 0xf4, 0x21, 0x2e, 0x15, - 0x13, 0x0e, 0x0e, 0x29, 0x03, 0x67, 0x24, 0x13, 0x18, 0x16, 0x27, 0x13, - 0x89, 0x01, 0xc4, 0x33, 0x30, 0x17, 0x13, 0x0f, 0x11, 0x01, 0x01, 0x02, - 0xfd, 0xb9, 0x21, 0x2f, 0x16, 0x26, 0x14, 0x02, 0x6a, 0x06, 0x0d, 0x17, - 0x21, 0x01, 0x1d, 0x20, 0x2f, 0x01, 0x0e, 0x3a, 0x28, 0x1a, 0x2f, 0x0c, - 0x09, 0x03, 0x0b, 0x02, 0x18, 0x1d, 0x29, 0x19, 0x2f, 0x1a, 0x0a, 0x39, - 0x29, 0x18, 0x2f, 0x0d, 0x0b, 0x02, 0x09, 0x39, 0x29, 0x1a, 0x30, 0x18, - 0x15, 0x10, 0x1d, 0x3a, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x2f, - 0x01, 0x0e, 0x04, 0xa2, 0x04, 0x7a, 0x00, 0x32, 0x00, 0x00, 0x13, 0x03, - 0x34, 0x36, 0x33, 0x21, 0x32, 0x17, 0x16, 0x17, 0x21, 0x32, 0x1e, 0x01, - 0x15, 0x14, 0x06, 0x23, 0x21, 0x17, 0x21, 0x16, 0x17, 0x1e, 0x01, 0x15, - 0x14, 0x06, 0x2b, 0x01, 0x17, 0x33, 0x32, 0x1e, 0x01, 0x15, 0x14, 0x07, - 0x06, 0x07, 0x23, 0x17, 0x33, 0x16, 0x17, 0x1e, 0x01, 0x15, 0x14, 0x06, - 0x23, 0x69, 0x39, 0x2f, 0x20, 0x01, 0x1d, 0x21, 0x17, 0x0d, 0x06, 0x02, - 0x6a, 0x14, 0x26, 0x16, 0x2f, 0x21, 0xfd, 0xb9, 0x02, 0x01, 0x01, 0x11, - 0x0f, 0x13, 0x17, 0x30, 0x33, 0xc4, 0x01, 0x89, 0x13, 0x27, 0x16, 0x18, - 0x13, 0x24, 0x67, 0x03, 0x29, 0x0e, 0x0e, 0x13, 0x15, 0x2e, 0x21, 0x01, - 0x0e, 0x03, 0x08, 0x2a, 0x3a, 0x1d, 0x10, 0x15, 0x18, 0x30, 0x1a, 0x29, - 0x39, 0x09, 0x02, 0x0b, 0x0d, 0x2f, 0x18, 0x29, 0x39, 0x0a, 0x1a, 0x2f, - 0x19, 0x29, 0x1d, 0x18, 0x02, 0x0b, 0x03, 0x09, 0x0c, 0x2f, 0x1a, 0x28, - 0x3a, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0e, 0x01, 0x1a, 0x04, 0xc3, - 0x04, 0x21, 0x00, 0x21, 0x00, 0x43, 0x00, 0x00, 0x01, 0x13, 0x34, 0x26, - 0x23, 0x21, 0x22, 0x07, 0x21, 0x26, 0x15, 0x14, 0x33, 0x21, 0x07, 0x21, - 0x22, 0x15, 0x14, 0x33, 0x21, 0x07, 0x23, 0x22, 0x15, 0x14, 0x3b, 0x01, - 0x07, 0x23, 0x22, 0x15, 0x14, 0x33, 0x07, 0x26, 0x27, 0x36, 0x37, 0x33, - 0x37, 0x23, 0x26, 0x27, 0x36, 0x37, 0x33, 0x37, 0x21, 0x22, 0x27, 0x36, - 0x37, 0x21, 0x37, 0x21, 0x22, 0x27, 0x36, 0x33, 0x21, 0x36, 0x37, 0x21, - 0x32, 0x16, 0x15, 0x03, 0x04, 0x65, 0x3b, 0x27, 0x1b, 0xfe, 0xe1, 0x2b, - 0x13, 0xfd, 0x70, 0x43, 0x43, 0x02, 0x6f, 0x0a, 0xfe, 0xe0, 0x43, 0x43, - 0x00, 0xff, 0x07, 0xb4, 0x43, 0x43, 0x8e, 0x10, 0x32, 0x43, 0x43, 0x17, - 0x4b, 0x01, 0x01, 0x4b, 0x3c, 0x04, 0x8b, 0x4c, 0x01, 0x01, 0x4c, 0xb9, - 0x02, 0xff, 0x00, 0x4b, 0x01, 0x01, 0x4b, 0x01, 0x25, 0x03, 0xfd, 0x93, - 0x4a, 0x01, 0x01, 0x4a, 0x02, 0x94, 0x1a, 0x36, 0x01, 0x30, 0x22, 0x32, - 0x3d, 0x01, 0x32, 0x02, 0x81, 0x1e, 0x29, 0x2e, 0x02, 0x3d, 0x3c, 0x3d, - 0x3d, 0x3c, 0x40, 0x3d, 0x3a, 0x3e, 0x3d, 0x3b, 0x18, 0x01, 0x54, 0x54, - 0x01, 0x0b, 0x01, 0x55, 0x53, 0x01, 0x0f, 0x55, 0x54, 0x01, 0x0c, 0x55, - 0x54, 0x38, 0x01, 0x33, 0x24, 0xfd, 0x51, 0x00, 0x00, 0x02, 0x00, 0x8c, - 0x00, 0x00, 0x04, 0x45, 0x05, 0xca, 0x00, 0x21, 0x00, 0x44, 0x00, 0x00, - 0x37, 0x05, 0x32, 0x36, 0x35, 0x11, 0x34, 0x27, 0x11, 0x36, 0x23, 0x22, - 0x15, 0x11, 0x27, 0x11, 0x34, 0x23, 0x22, 0x15, 0x11, 0x27, 0x35, 0x34, - 0x23, 0x22, 0x1d, 0x01, 0x27, 0x35, 0x34, 0x23, 0x22, 0x15, 0x27, 0x36, - 0x37, 0x16, 0x17, 0x15, 0x17, 0x35, 0x36, 0x37, 0x16, 0x17, 0x15, 0x17, - 0x11, 0x34, 0x37, 0x16, 0x17, 0x11, 0x17, 0x11, 0x36, 0x37, 0x16, 0x15, - 0x11, 0x16, 0x17, 0x11, 0x14, 0x06, 0x23, 0x25, 0x13, 0xaa, 0x03, 0x15, - 0x24, 0x34, 0x3a, 0x02, 0x4a, 0x49, 0x4c, 0x4c, 0x48, 0x4f, 0x4b, 0x48, - 0x4c, 0x4b, 0x49, 0x1d, 0x01, 0x68, 0x67, 0x01, 0x0e, 0x01, 0x68, 0x67, - 0x01, 0x12, 0x69, 0x67, 0x01, 0x0f, 0x01, 0x68, 0x67, 0x44, 0x02, 0x3e, - 0x2d, 0xfc, 0xb2, 0x01, 0x73, 0x4a, 0x31, 0x20, 0x01, 0x62, 0x36, 0x16, - 0x03, 0x27, 0x53, 0x53, 0xfd, 0x02, 0x0d, 0x01, 0x63, 0x52, 0x52, 0xfe, - 0xc4, 0x09, 0xdf, 0x53, 0x53, 0xae, 0x12, 0x3f, 0x53, 0x53, 0x1c, 0x5c, - 0x01, 0x01, 0x5c, 0x4b, 0x04, 0xac, 0x5c, 0x01, 0x01, 0x5c, 0xe4, 0x03, - 0x01, 0x3b, 0x5c, 0x01, 0x01, 0x5c, 0xfe, 0x96, 0x04, 0x02, 0xfd, 0x5d, - 0x01, 0x01, 0x5d, 0xfc, 0xd4, 0x21, 0x41, 0xfe, 0x8a, 0x2a, 0x3e, 0x4b, - 0x02, 0x9b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0e, 0x01, 0x1a, 0x04, 0xc3, - 0x04, 0x21, 0x00, 0x21, 0x00, 0x44, 0x00, 0x00, 0x13, 0x21, 0x32, 0x35, - 0x34, 0x2b, 0x01, 0x27, 0x33, 0x32, 0x35, 0x34, 0x2b, 0x01, 0x27, 0x21, - 0x32, 0x35, 0x34, 0x23, 0x21, 0x27, 0x21, 0x32, 0x35, 0x34, 0x07, 0x21, - 0x26, 0x23, 0x21, 0x22, 0x06, 0x15, 0x01, 0x30, 0x21, 0x03, 0x34, 0x36, - 0x33, 0x21, 0x16, 0x17, 0x21, 0x32, 0x17, 0x06, 0x23, 0x21, 0x17, 0x21, - 0x16, 0x17, 0x06, 0x23, 0x21, 0x17, 0x33, 0x16, 0x17, 0x06, 0x07, 0x23, - 0x17, 0x33, 0x16, 0x17, 0x06, 0x6c, 0x02, 0x1f, 0x43, 0x43, 0x32, 0x10, - 0x8e, 0x43, 0x43, 0xb4, 0x07, 0x00, 0xff, 0x43, 0x43, 0xfe, 0xe0, 0x0a, - 0x02, 0x6f, 0x43, 0x43, 0xfd, 0x70, 0x13, 0x2b, 0xfe, 0xe1, 0x1b, 0x27, - 0x02, 0x71, 0xfd, 0xaa, 0x3d, 0x32, 0x22, 0x01, 0x30, 0x36, 0x1a, 0x02, - 0x94, 0x4a, 0x01, 0x01, 0x4a, 0xfd, 0x93, 0x03, 0x01, 0x25, 0x4b, 0x01, - 0x01, 0x4b, 0xff, 0x00, 0x02, 0xb9, 0x4c, 0x01, 0x01, 0x4c, 0x8b, 0x04, - 0x3c, 0x4b, 0x01, 0x01, 0x01, 0x32, 0x3b, 0x3d, 0x3e, 0x3a, 0x3d, 0x40, - 0x3c, 0x3d, 0x3d, 0x3c, 0x3d, 0x02, 0x2e, 0x29, 0x1e, 0xfd, 0x67, 0x02, - 0xaf, 0x24, 0x33, 0x01, 0x38, 0x54, 0x55, 0x0c, 0x01, 0x54, 0x55, 0x0f, - 0x01, 0x53, 0x55, 0x01, 0x0b, 0x01, 0x54, 0x54, 0x00, 0x02, 0x00, 0x8c, - 0xff, 0xf9, 0x04, 0x45, 0x05, 0xc2, 0x00, 0x21, 0x00, 0x43, 0x00, 0x00, - 0x13, 0x14, 0x33, 0x32, 0x3d, 0x01, 0x37, 0x15, 0x14, 0x33, 0x32, 0x3d, - 0x01, 0x37, 0x11, 0x14, 0x33, 0x32, 0x35, 0x11, 0x37, 0x11, 0x14, 0x33, - 0x32, 0x27, 0x11, 0x36, 0x35, 0x11, 0x34, 0x26, 0x23, 0x05, 0x27, 0x25, - 0x32, 0x16, 0x15, 0x11, 0x06, 0x07, 0x11, 0x14, 0x07, 0x26, 0x27, 0x11, - 0x07, 0x11, 0x06, 0x07, 0x26, 0x35, 0x11, 0x07, 0x15, 0x06, 0x07, 0x26, - 0x27, 0x35, 0x07, 0x15, 0x06, 0x07, 0x26, 0x27, 0xaa, 0x49, 0x4b, 0x4c, - 0x48, 0x4b, 0x4f, 0x48, 0x4c, 0x4c, 0x49, 0x4a, 0x02, 0x3a, 0x34, 0x24, - 0xfc, 0xeb, 0x1e, 0x03, 0x4e, 0x2d, 0x3e, 0x02, 0x44, 0x67, 0x68, 0x01, - 0x0f, 0x01, 0x67, 0x69, 0x12, 0x01, 0x67, 0x68, 0x01, 0x0e, 0x01, 0x67, - 0x68, 0x01, 0x02, 0xb3, 0x53, 0x53, 0x3d, 0x14, 0xae, 0x53, 0x53, 0xdd, - 0x09, 0xfe, 0xc6, 0x53, 0x53, 0x01, 0x62, 0x0d, 0xfd, 0x01, 0x53, 0x53, - 0x03, 0x27, 0x17, 0x36, 0x01, 0x61, 0x21, 0x30, 0x4a, 0x29, 0x4b, 0x3e, - 0x2a, 0xfe, 0x8a, 0x42, 0x20, 0xfc, 0xd4, 0x5c, 0x01, 0x01, 0x5c, 0x02, - 0xfc, 0x04, 0xfe, 0x98, 0x5d, 0x01, 0x01, 0x5d, 0x01, 0x3a, 0x02, 0xe4, - 0x5d, 0x01, 0x01, 0x5d, 0xab, 0x04, 0x4a, 0x5d, 0x01, 0x01, 0x5d, 0x00, - 0x00, 0x1d, 0x00, 0x0c, 0xff, 0xfe, 0x04, 0xc5, 0x04, 0xbf, 0x00, 0x4f, - 0x00, 0x80, 0x00, 0x88, 0x00, 0x90, 0x00, 0x9f, 0x00, 0xae, 0x00, 0xb5, - 0x00, 0xbc, 0x00, 0xcd, 0x00, 0xd3, 0x00, 0xda, 0x00, 0xde, 0x00, 0xe2, - 0x00, 0xe6, 0x00, 0xea, 0x00, 0xee, 0x00, 0xf2, 0x00, 0xf6, 0x00, 0xfa, - 0x00, 0xfe, 0x01, 0x02, 0x01, 0x11, 0x01, 0x1d, 0x01, 0x21, 0x01, 0x25, - 0x01, 0x29, 0x01, 0x2d, 0x01, 0x31, 0x01, 0x35, 0x00, 0x00, 0x01, 0x32, - 0x17, 0x16, 0x1d, 0x01, 0x14, 0x07, 0x17, 0x15, 0x14, 0x07, 0x33, 0x36, - 0x35, 0x36, 0x3b, 0x01, 0x32, 0x15, 0x16, 0x1d, 0x01, 0x06, 0x23, 0x27, - 0x06, 0x07, 0x15, 0x17, 0x37, 0x16, 0x15, 0x14, 0x07, 0x14, 0x2b, 0x01, - 0x22, 0x2f, 0x01, 0x06, 0x23, 0x22, 0x27, 0x06, 0x15, 0x06, 0x2b, 0x01, - 0x22, 0x35, 0x26, 0x35, 0x34, 0x37, 0x17, 0x37, 0x35, 0x27, 0x07, 0x22, - 0x27, 0x35, 0x34, 0x37, 0x36, 0x3b, 0x01, 0x32, 0x1f, 0x01, 0x35, 0x27, - 0x37, 0x26, 0x35, 0x36, 0x37, 0x36, 0x01, 0x14, 0x17, 0x33, 0x35, 0x26, - 0x35, 0x36, 0x3b, 0x01, 0x17, 0x07, 0x17, 0x15, 0x07, 0x15, 0x14, 0x17, - 0x16, 0x1d, 0x01, 0x17, 0x33, 0x37, 0x34, 0x37, 0x36, 0x35, 0x27, 0x37, - 0x35, 0x27, 0x37, 0x16, 0x1d, 0x01, 0x07, 0x17, 0x36, 0x3d, 0x01, 0x34, - 0x27, 0x26, 0x2b, 0x01, 0x20, 0x07, 0x06, 0x05, 0x16, 0x07, 0x06, 0x27, - 0x22, 0x27, 0x34, 0x21, 0x16, 0x17, 0x06, 0x23, 0x22, 0x27, 0x26, 0x13, - 0x33, 0x36, 0x33, 0x17, 0x36, 0x35, 0x26, 0x35, 0x26, 0x23, 0x06, 0x07, - 0x06, 0x15, 0x25, 0x06, 0x23, 0x06, 0x15, 0x17, 0x37, 0x16, 0x17, 0x35, - 0x34, 0x27, 0x26, 0x35, 0x26, 0x05, 0x17, 0x15, 0x07, 0x26, 0x35, 0x34, - 0x37, 0x16, 0x15, 0x14, 0x07, 0x27, 0x35, 0x03, 0x16, 0x33, 0x36, 0x37, - 0x26, 0x37, 0x06, 0x07, 0x06, 0x2b, 0x01, 0x26, 0x27, 0x26, 0x27, 0x16, - 0x37, 0x16, 0x17, 0x33, 0x35, 0x26, 0x05, 0x15, 0x32, 0x3f, 0x01, 0x22, - 0x07, 0x05, 0x15, 0x17, 0x35, 0x37, 0x15, 0x37, 0x35, 0x07, 0x15, 0x17, - 0x35, 0x33, 0x15, 0x37, 0x27, 0x07, 0x15, 0x37, 0x27, 0x07, 0x15, 0x33, - 0x35, 0x33, 0x15, 0x33, 0x35, 0x07, 0x15, 0x17, 0x35, 0x17, 0x15, 0x33, - 0x35, 0x07, 0x15, 0x33, 0x35, 0x05, 0x27, 0x07, 0x15, 0x16, 0x15, 0x16, - 0x33, 0x32, 0x37, 0x36, 0x37, 0x26, 0x35, 0x06, 0x25, 0x07, 0x16, 0x15, - 0x14, 0x17, 0x32, 0x3f, 0x01, 0x26, 0x23, 0x07, 0x25, 0x07, 0x17, 0x35, - 0x07, 0x15, 0x17, 0x35, 0x27, 0x15, 0x17, 0x35, 0x17, 0x15, 0x37, 0x35, - 0x37, 0x15, 0x37, 0x35, 0x37, 0x15, 0x37, 0x35, 0x02, 0x75, 0xe9, 0x6f, - 0x2c, 0x4d, 0x05, 0x13, 0x04, 0x7a, 0x22, 0x1b, 0x06, 0x30, 0x36, 0x14, - 0x30, 0x44, 0xbd, 0x2f, 0xb2, 0x35, 0x49, 0x3a, 0x32, 0x04, 0x27, 0x35, - 0x90, 0x3a, 0x83, 0x86, 0x36, 0xa0, 0x26, 0x22, 0x0b, 0x2a, 0x3a, 0x44, - 0x3a, 0xad, 0xe7, 0x53, 0x34, 0x06, 0x36, 0x03, 0x1e, 0x19, 0x24, 0x2e, - 0x65, 0x13, 0x09, 0x51, 0x1a, 0xc9, 0x4e, 0xfe, 0xf0, 0x35, 0x05, 0x17, - 0x08, 0x0a, 0x0a, 0x0e, 0x0a, 0x19, 0x0f, 0x75, 0x34, 0x4d, 0x44, 0x61, - 0x95, 0x19, 0x14, 0x1a, 0x0a, 0x17, 0x13, 0x17, 0x04, 0x36, 0xaa, 0x62, - 0x55, 0x1d, 0xfe, 0xfe, 0x50, 0x0f, 0x01, 0x19, 0x2b, 0x0a, 0x2c, 0x48, - 0x3b, 0x1b, 0x01, 0x60, 0x9b, 0x04, 0x1c, 0x49, 0x32, 0x33, 0x02, 0xb5, - 0x04, 0xd6, 0x12, 0x4e, 0x18, 0x35, 0x06, 0x0f, 0x15, 0x28, 0xbd, 0xfd, - 0x0d, 0x0d, 0x0a, 0x28, 0x23, 0x49, 0x30, 0xb7, 0x4d, 0x9a, 0x13, 0x01, - 0xd3, 0x0a, 0x27, 0x1d, 0x5e, 0x35, 0x1f, 0x25, 0xcc, 0x23, 0xa3, 0xa5, - 0x21, 0x05, 0x19, 0x1b, 0x15, 0x3a, 0x58, 0x2b, 0x91, 0x09, 0x06, 0x22, - 0x16, 0x07, 0x0f, 0x13, 0x05, 0x07, 0x01, 0x2a, 0x0b, 0x03, 0x13, 0x0a, - 0x12, 0xfe, 0xec, 0x0e, 0xde, 0x14, 0xe3, 0x13, 0x9b, 0x15, 0x02, 0x36, - 0x12, 0x03, 0x57, 0x18, 0x0f, 0x13, 0x7d, 0x13, 0x57, 0x13, 0x3a, 0x18, - 0xfe, 0x75, 0x57, 0x05, 0x34, 0x05, 0x0a, 0x0f, 0x35, 0x76, 0x1a, 0x0e, - 0x8e, 0x02, 0x54, 0x0d, 0xad, 0x26, 0x10, 0x09, 0x2f, 0x04, 0x18, 0x48, - 0xfe, 0x33, 0x03, 0x17, 0x13, 0x13, 0x56, 0x13, 0x9c, 0x14, 0x0c, 0x13, - 0x0f, 0x14, 0x04, 0xbe, 0x9c, 0x58, 0x44, 0x39, 0x5c, 0x53, 0x4c, 0x05, - 0x2b, 0x26, 0x33, 0x31, 0x2e, 0x64, 0x2b, 0x1c, 0x13, 0x25, 0x06, 0x58, - 0x21, 0x0f, 0x51, 0x0a, 0x0e, 0x24, 0x1f, 0x32, 0x60, 0x60, 0x4b, 0x50, - 0x50, 0x50, 0x14, 0x47, 0x5b, 0x36, 0x25, 0x23, 0x0a, 0x0a, 0x51, 0x0f, - 0x79, 0x06, 0x2d, 0x0b, 0x16, 0x36, 0x5b, 0x5b, 0x33, 0x05, 0x47, 0x4b, - 0x5b, 0xaf, 0xbb, 0x4f, 0x17, 0xfe, 0xc2, 0x60, 0x5f, 0x41, 0x5b, 0x2d, - 0x29, 0x0f, 0x24, 0x74, 0x37, 0x88, 0x0a, 0x4c, 0x19, 0x2d, 0x24, 0x14, - 0x0a, 0x15, 0x4c, 0x36, 0x1d, 0x3d, 0x98, 0x7f, 0x0f, 0x22, 0x11, 0x09, - 0x1c, 0x28, 0x8d, 0x14, 0x43, 0x4a, 0x23, 0xab, 0x52, 0x22, 0xc4, 0x30, - 0xa9, 0x0d, 0x3a, 0x82, 0x04, 0x7e, 0x47, 0x08, 0x42, 0x7b, 0x7e, 0x45, - 0xfe, 0x6f, 0x6a, 0x04, 0x06, 0x08, 0x3c, 0x1e, 0x34, 0x08, 0x53, 0x5b, - 0x10, 0xbf, 0x5a, 0x1e, 0x15, 0x08, 0x04, 0x0f, 0x61, 0x0b, 0x4c, 0x15, - 0x43, 0x35, 0x1d, 0x0b, 0x05, 0x81, 0x29, 0x0a, 0x2e, 0x55, 0x25, 0x2b, - 0x5a, 0x26, 0x07, 0x29, 0x83, 0xfe, 0xcd, 0xa2, 0x0c, 0x9b, 0x37, 0x65, - 0x1f, 0x8d, 0x3c, 0x12, 0x49, 0x4c, 0x41, 0x61, 0x4d, 0x1e, 0x6f, 0x4b, - 0x33, 0x33, 0x4b, 0x40, 0x47, 0x36, 0x0b, 0x24, 0x04, 0x24, 0x04, 0x28, - 0x08, 0x26, 0x0c, 0x28, 0x04, 0x27, 0x27, 0x06, 0x26, 0x05, 0x31, 0x02, - 0x2f, 0x04, 0x2d, 0x2d, 0x2d, 0x2d, 0x32, 0x29, 0x04, 0x28, 0x0b, 0x28, - 0x2d, 0x05, 0x28, 0x28, 0x64, 0x04, 0x04, 0x10, 0x2e, 0x27, 0x2d, 0x54, - 0x3f, 0x18, 0x1e, 0x18, 0x4f, 0x4b, 0x38, 0x54, 0x24, 0x0c, 0x21, 0x54, - 0x33, 0x0f, 0x04, 0xa6, 0x28, 0x05, 0x2d, 0x3c, 0x28, 0x05, 0x28, 0x1a, - 0x27, 0x06, 0x29, 0x14, 0x29, 0x05, 0x29, 0x03, 0x28, 0x04, 0x29, 0x08, - 0x29, 0x06, 0x28, 0x00, 0x00, 0x01, 0x00, 0x09, 0xff, 0xfb, 0x04, 0xc8, - 0x05, 0xd3, 0x00, 0x26, 0x00, 0x00, 0x01, 0x32, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x01, 0x07, 0x14, 0x17, 0x25, 0x32, 0x17, 0x15, 0x14, 0x23, 0x05, - 0x22, 0x27, 0x26, 0x3d, 0x01, 0x34, 0x37, 0x00, 0x37, 0x36, 0x35, 0x34, - 0x27, 0x23, 0x05, 0x22, 0x27, 0x35, 0x34, 0x37, 0x33, 0x02, 0xf4, 0x74, - 0x5c, 0x2a, 0x65, 0xfd, 0xe8, 0x09, 0x4f, 0x02, 0xc9, 0x40, 0x07, 0x55, - 0xfd, 0x43, 0x83, 0x58, 0x16, 0x71, 0x01, 0xf9, 0x10, 0x09, 0x50, 0x09, - 0xfd, 0x53, 0x2e, 0x09, 0x50, 0x0b, 0x05, 0xd3, 0x8d, 0x4d, 0x4f, 0x8a, - 0x62, 0xfd, 0xa0, 0x3e, 0x59, 0x1a, 0xd1, 0x61, 0x03, 0x59, 0xc6, 0xae, - 0x35, 0x38, 0x18, 0x8a, 0x6c, 0x02, 0x37, 0x1b, 0x1b, 0x16, 0x50, 0x20, - 0xcc, 0x50, 0x1e, 0x40, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, - 0x00, 0x02, 0x04, 0xc9, 0x04, 0xc3, 0x00, 0x11, 0x00, 0x24, 0x00, 0x30, - 0x00, 0x3c, 0x00, 0x46, 0x00, 0x58, 0x00, 0x00, 0x01, 0x20, 0x13, 0x16, - 0x15, 0x10, 0x05, 0x06, 0x2b, 0x01, 0x20, 0x03, 0x26, 0x3d, 0x01, 0x10, - 0x25, 0x36, 0x05, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x10, 0x17, 0x16, - 0x33, 0x20, 0x13, 0x36, 0x3d, 0x01, 0x10, 0x25, 0x26, 0x03, 0x23, 0x22, - 0x27, 0x13, 0x16, 0x3b, 0x01, 0x32, 0x37, 0x13, 0x06, 0x03, 0x06, 0x1d, - 0x01, 0x21, 0x35, 0x34, 0x37, 0x36, 0x37, 0x13, 0x06, 0x25, 0x16, 0x17, - 0x21, 0x26, 0x27, 0x26, 0x27, 0x13, 0x16, 0x05, 0x32, 0x17, 0x16, 0x15, - 0x14, 0x07, 0x06, 0x2b, 0x01, 0x22, 0x27, 0x26, 0x3d, 0x01, 0x34, 0x37, - 0x36, 0x02, 0x5e, 0x01, 0x37, 0xd7, 0x5c, 0xfe, 0xff, 0x9e, 0xac, 0x1a, - 0xfe, 0xcb, 0xd5, 0x50, 0x01, 0x12, 0x97, 0x01, 0xb8, 0x87, 0x87, 0xf4, - 0xbf, 0x67, 0xe3, 0x91, 0xb5, 0x01, 0x15, 0xbe, 0x48, 0xfe, 0xec, 0x04, - 0xf4, 0x16, 0x89, 0x72, 0xa9, 0x27, 0x2e, 0x06, 0x29, 0x25, 0xad, 0x73, - 0xea, 0x4d, 0xfe, 0xa7, 0xe9, 0x0e, 0x10, 0xaa, 0x05, 0x02, 0x0d, 0x4d, - 0x02, 0xfe, 0xa6, 0x01, 0x19, 0x1b, 0x23, 0xaa, 0x66, 0xfe, 0x9b, 0x43, - 0x2d, 0x14, 0x37, 0x21, 0x25, 0x06, 0x41, 0x2e, 0x11, 0x3b, 0x20, 0x04, - 0xc2, 0xfe, 0xd3, 0x8e, 0xae, 0xfe, 0xef, 0xce, 0x77, 0x01, 0x3a, 0x8e, - 0x90, 0x17, 0x01, 0x13, 0xd2, 0x6b, 0x8b, 0x4b, 0xf0, 0x8f, 0x9e, 0xfe, - 0xff, 0xb7, 0x71, 0x01, 0x1a, 0x7a, 0x86, 0x0d, 0x01, 0x18, 0xb6, 0x03, - 0xfc, 0x2b, 0x48, 0x01, 0x2a, 0x19, 0x18, 0xfe, 0xd6, 0x47, 0x02, 0x90, - 0x3b, 0x4d, 0x04, 0x0d, 0xea, 0xb2, 0x0a, 0x0a, 0xfe, 0xd6, 0x03, 0x74, - 0x75, 0x8f, 0x2f, 0x26, 0x28, 0x15, 0x01, 0x28, 0x41, 0xf7, 0x41, 0x1e, - 0x26, 0x3a, 0x2b, 0x1a, 0x43, 0x1e, 0x1f, 0x04, 0x3b, 0x2e, 0x17, 0x00, - 0x00, 0x06, 0x00, 0x22, 0x00, 0x07, 0x04, 0xaf, 0x04, 0x2f, 0x00, 0x09, - 0x00, 0x13, 0x00, 0x1d, 0x00, 0x38, 0x00, 0x50, 0x00, 0x69, 0x00, 0x00, - 0x01, 0x3e, 0x01, 0x27, 0x36, 0x37, 0x16, 0x06, 0x07, 0x26, 0x03, 0x26, - 0x06, 0x07, 0x26, 0x27, 0x36, 0x16, 0x17, 0x06, 0x05, 0x14, 0x16, 0x17, - 0x06, 0x07, 0x2e, 0x01, 0x37, 0x16, 0x01, 0x06, 0x23, 0x22, 0x27, 0x26, - 0x27, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x16, 0x36, 0x37, 0x36, - 0x27, 0x37, 0x16, 0x37, 0x17, 0x06, 0x17, 0x1e, 0x01, 0x03, 0x16, 0x17, - 0x16, 0x07, 0x33, 0x16, 0x17, 0x16, 0x1d, 0x01, 0x2e, 0x01, 0x23, 0x06, - 0x07, 0x27, 0x36, 0x27, 0x35, 0x36, 0x37, 0x36, 0x26, 0x01, 0x26, 0x35, - 0x34, 0x37, 0x36, 0x17, 0x27, 0x26, 0x27, 0x36, 0x37, 0x0e, 0x01, 0x17, - 0x16, 0x1f, 0x01, 0x06, 0x17, 0x07, 0x26, 0x07, 0x26, 0x06, 0x02, 0xdc, - 0x30, 0x37, 0x05, 0x1a, 0x1a, 0x09, 0x5e, 0x3c, 0x0c, 0x05, 0x31, 0x78, - 0x2c, 0x17, 0x0f, 0x42, 0xb1, 0x35, 0x12, 0xfe, 0xb1, 0x40, 0x32, 0x02, - 0x0b, 0x4a, 0x56, 0x08, 0x1e, 0x02, 0xab, 0x4d, 0x76, 0x21, 0x23, 0x75, - 0x41, 0x01, 0x2b, 0x55, 0x42, 0x44, 0x58, 0x5b, 0x66, 0xb9, 0x2a, 0x3b, - 0x2d, 0x31, 0x30, 0x29, 0x2e, 0x2e, 0x43, 0x2c, 0x9d, 0xb7, 0x73, 0x42, - 0x23, 0x48, 0x02, 0x4b, 0x55, 0x8b, 0x09, 0x95, 0x50, 0x82, 0x5d, 0x31, - 0x05, 0x32, 0x81, 0x3c, 0x30, 0x1b, 0xfc, 0xd1, 0x03, 0x56, 0x51, 0x89, - 0x01, 0x1f, 0x02, 0x0c, 0xc4, 0x7d, 0x25, 0x27, 0x48, 0x88, 0x01, 0x36, - 0x08, 0x2d, 0x54, 0x7d, 0x5e, 0x80, 0x01, 0x24, 0x1d, 0x6b, 0x37, 0x0a, - 0x04, 0x52, 0x97, 0x1a, 0x1b, 0x01, 0x87, 0x1b, 0x05, 0x1f, 0x10, 0x14, - 0x32, 0x07, 0x27, 0x17, 0xc6, 0x37, 0x66, 0x17, 0x1b, 0x18, 0x21, 0x9d, - 0x41, 0x04, 0xfe, 0x5c, 0x3b, 0x05, 0x19, 0x79, 0x01, 0x3f, 0x31, 0x21, - 0x35, 0x30, 0x42, 0x45, 0x74, 0x84, 0x1e, 0x22, 0x21, 0x1c, 0x7a, 0x6b, - 0x51, 0x3b, 0x04, 0x0f, 0x30, 0x9a, 0x71, 0x75, 0x07, 0x30, 0x5c, 0xb7, - 0x07, 0x6f, 0x82, 0x07, 0x69, 0x1d, 0x3a, 0x13, 0x35, 0x16, 0x6f, 0x50, - 0xa5, 0xfd, 0x5a, 0x11, 0x11, 0x6a, 0x73, 0x58, 0x04, 0x01, 0x46, 0x61, - 0xc0, 0x50, 0x4a, 0xc2, 0x47, 0x6c, 0x1b, 0x3b, 0x18, 0x34, 0x1a, 0x65, - 0x04, 0x01, 0x6a, 0x00, 0x00, 0x17, 0x00, 0x4e, 0xff, 0xff, 0x04, 0x83, - 0x05, 0x5e, 0x00, 0x03, 0x00, 0x13, 0x00, 0x19, 0x00, 0x1d, 0x00, 0x31, - 0x00, 0x46, 0x00, 0x5b, 0x00, 0x71, 0x00, 0x8b, 0x00, 0x95, 0x00, 0x9a, - 0x00, 0x9f, 0x00, 0xa4, 0x00, 0xa9, 0x00, 0xae, 0x00, 0xb3, 0x00, 0xb8, - 0x00, 0xbd, 0x00, 0xc2, 0x00, 0xc7, 0x00, 0xcc, 0x00, 0xd1, 0x00, 0xfc, - 0x00, 0x00, 0x01, 0x06, 0x37, 0x26, 0x17, 0x26, 0x07, 0x06, 0x27, 0x37, - 0x27, 0x36, 0x17, 0x16, 0x17, 0x06, 0x07, 0x26, 0x27, 0x24, 0x01, 0x06, - 0x07, 0x23, 0x26, 0x37, 0x03, 0x16, 0x27, 0x26, 0x13, 0x15, 0x06, 0x23, - 0x22, 0x27, 0x35, 0x26, 0x37, 0x36, 0x37, 0x16, 0x17, 0x06, 0x07, 0x06, - 0x04, 0x07, 0x23, 0x26, 0x27, 0x15, 0x27, 0x35, 0x24, 0x27, 0x36, 0x37, - 0x16, 0x17, 0x06, 0x07, 0x06, 0x04, 0x17, 0x16, 0x07, 0x27, 0x36, 0x27, - 0x36, 0x03, 0x15, 0x27, 0x35, 0x24, 0x27, 0x36, 0x37, 0x16, 0x17, 0x06, - 0x17, 0x06, 0x04, 0x17, 0x06, 0x07, 0x27, 0x36, 0x35, 0x36, 0x07, 0x26, - 0x27, 0x36, 0x37, 0x16, 0x17, 0x06, 0x15, 0x14, 0x04, 0x17, 0x06, 0x07, - 0x26, 0x27, 0x36, 0x27, 0x26, 0x27, 0x15, 0x27, 0x13, 0x15, 0x27, 0x35, - 0x24, 0x37, 0x36, 0x37, 0x36, 0x17, 0x07, 0x17, 0x06, 0x27, 0x26, 0x07, - 0x06, 0x04, 0x17, 0x06, 0x07, 0x26, 0x27, 0x36, 0x27, 0x36, 0x01, 0x14, - 0x1e, 0x01, 0x33, 0x26, 0x37, 0x22, 0x0e, 0x01, 0x05, 0x16, 0x17, 0x37, - 0x26, 0x27, 0x16, 0x17, 0x37, 0x26, 0x27, 0x16, 0x17, 0x37, 0x26, 0x27, - 0x16, 0x07, 0x37, 0x26, 0x27, 0x16, 0x07, 0x17, 0x36, 0x27, 0x06, 0x07, - 0x17, 0x36, 0x25, 0x17, 0x36, 0x37, 0x06, 0x07, 0x17, 0x36, 0x37, 0x06, - 0x07, 0x17, 0x36, 0x37, 0x06, 0x1f, 0x01, 0x26, 0x37, 0x06, 0x17, 0x37, - 0x26, 0x37, 0x06, 0x17, 0x37, 0x26, 0x27, 0x06, 0x17, 0x15, 0x27, 0x35, - 0x26, 0x07, 0x22, 0x27, 0x36, 0x25, 0x16, 0x17, 0x16, 0x33, 0x35, 0x26, - 0x27, 0x2e, 0x01, 0x35, 0x34, 0x3e, 0x01, 0x32, 0x1e, 0x01, 0x15, 0x14, - 0x06, 0x07, 0x06, 0x07, 0x33, 0x14, 0x23, 0x15, 0x36, 0x37, 0x04, 0x17, - 0x06, 0x23, 0x26, 0x03, 0x05, 0x10, 0x38, 0x09, 0x70, 0x0a, 0x2b, 0x57, - 0x44, 0x54, 0x63, 0x27, 0x48, 0xbc, 0x0c, 0x02, 0x82, 0x40, 0x91, 0x01, - 0x01, 0xfe, 0xa2, 0x58, 0x1c, 0x0e, 0x01, 0x4f, 0x60, 0x3d, 0x13, 0x20, - 0xdc, 0x0a, 0x18, 0x1f, 0x03, 0xa1, 0x01, 0x04, 0x3b, 0x2a, 0x29, 0x38, - 0x01, 0x02, 0x01, 0x20, 0x02, 0x0e, 0x18, 0x6b, 0x44, 0xfe, 0xff, 0x04, - 0x02, 0x76, 0x2f, 0x50, 0x9d, 0x03, 0x05, 0x01, 0x92, 0x05, 0x04, 0x6b, - 0x2d, 0x4a, 0x0c, 0x01, 0x4b, 0x44, 0xfe, 0xb0, 0x02, 0x04, 0x68, 0x47, - 0x61, 0xca, 0x0d, 0x09, 0x02, 0x44, 0x01, 0x04, 0x8a, 0x60, 0x96, 0x02, - 0xeb, 0xf7, 0x05, 0x01, 0x67, 0x42, 0x44, 0x96, 0x01, 0xea, 0x03, 0x04, - 0xa0, 0x1e, 0x36, 0xa6, 0x05, 0x02, 0xac, 0x44, 0x44, 0x44, 0xfe, 0x9f, - 0x01, 0x0c, 0xbc, 0x3d, 0x33, 0x64, 0x54, 0x44, 0x57, 0x2c, 0x09, 0x03, - 0x02, 0x9b, 0x06, 0x06, 0xa0, 0x3a, 0x67, 0xf2, 0x01, 0x0b, 0xfe, 0x95, - 0x11, 0x1e, 0x11, 0x1c, 0x1c, 0x10, 0x1f, 0x11, 0x01, 0x97, 0x6a, 0x29, - 0x19, 0x59, 0x8a, 0x69, 0x23, 0x27, 0x57, 0x74, 0x49, 0x10, 0x2d, 0x39, - 0x77, 0x31, 0x01, 0x38, 0x24, 0x5e, 0x02, 0x17, 0x38, 0x02, 0x3b, 0x2e, - 0x2f, 0x37, 0x2d, 0xfd, 0x49, 0x19, 0x29, 0x6a, 0x53, 0x29, 0x27, 0x23, - 0x69, 0x5c, 0x12, 0x2d, 0x10, 0x49, 0x4d, 0x0f, 0x39, 0x02, 0x31, 0x44, - 0x3b, 0x38, 0x17, 0x02, 0x25, 0x61, 0x37, 0x2f, 0x2e, 0x07, 0xd8, 0x44, - 0x3d, 0x75, 0xf6, 0x52, 0x4e, 0x01, 0x42, 0x16, 0x52, 0x01, 0x01, 0x02, - 0x02, 0x13, 0x15, 0x15, 0x26, 0x27, 0x25, 0x16, 0x15, 0x12, 0x03, 0x03, - 0x01, 0x01, 0x51, 0x16, 0x01, 0x42, 0x4e, 0x52, 0xf6, 0x71, 0x03, 0xcf, - 0x20, 0x16, 0x12, 0x64, 0x32, 0x0a, 0x1f, 0x0e, 0x15, 0x17, 0x44, 0x0d, - 0x03, 0x73, 0x39, 0x1e, 0x10, 0x08, 0x12, 0xfd, 0x10, 0x1f, 0x38, 0x43, - 0x20, 0x03, 0x5b, 0x18, 0x22, 0x08, 0xfc, 0x7c, 0x34, 0x18, 0x34, 0x26, - 0x1b, 0x33, 0x2c, 0x16, 0x0c, 0x05, 0x14, 0x11, 0x27, 0x32, 0x5e, 0x33, - 0x9f, 0x52, 0x0c, 0x54, 0x28, 0x42, 0x3f, 0x1d, 0x12, 0x08, 0x17, 0x23, - 0x27, 0x39, 0x43, 0x2d, 0x0d, 0x0b, 0x12, 0x21, 0x15, 0x01, 0x79, 0x81, - 0x0c, 0x7e, 0x23, 0x5a, 0x31, 0x14, 0x13, 0x06, 0x0f, 0x1d, 0x30, 0x3e, - 0x4e, 0x3f, 0x1e, 0x19, 0x24, 0x17, 0x25, 0x97, 0x1e, 0x59, 0x34, 0x1c, - 0x0b, 0x07, 0x1e, 0x29, 0x25, 0x46, 0x4e, 0x3f, 0x13, 0x0d, 0x0a, 0x1d, - 0x28, 0x1c, 0x1b, 0x7b, 0x0b, 0x01, 0xdb, 0x75, 0x08, 0x73, 0x13, 0x69, - 0x73, 0x04, 0x03, 0x3c, 0x16, 0x15, 0x0e, 0x20, 0x0a, 0x33, 0x28, 0x26, - 0x5e, 0x54, 0x12, 0x0f, 0x0e, 0x19, 0x30, 0x1d, 0x02, 0x35, 0x11, 0x1d, - 0x10, 0x3c, 0x3e, 0x0f, 0x1e, 0x37, 0x3b, 0x2c, 0x23, 0x34, 0x14, 0x5b, - 0x3a, 0x1f, 0x4f, 0x28, 0x76, 0x41, 0x11, 0x66, 0x47, 0x87, 0x45, 0x07, - 0x74, 0x59, 0x8f, 0x42, 0x0a, 0x7a, 0x5e, 0x7e, 0x34, 0x17, 0x6a, 0x0a, - 0x23, 0x2c, 0x3b, 0x10, 0x62, 0x1f, 0x3a, 0x5b, 0x27, 0x7e, 0x11, 0x41, - 0x76, 0x40, 0x7e, 0x07, 0x45, 0x87, 0x51, 0x82, 0x0a, 0x42, 0x8f, 0x61, - 0x6b, 0x17, 0x34, 0x7e, 0x5f, 0xaa, 0xbe, 0x06, 0xb2, 0x48, 0x23, 0x98, - 0x54, 0x06, 0x32, 0x1b, 0x01, 0x16, 0x01, 0x01, 0x0a, 0x24, 0x14, 0x13, - 0x24, 0x14, 0x14, 0x24, 0x13, 0x14, 0x24, 0x0a, 0x01, 0x01, 0x01, 0x14, - 0x1b, 0x32, 0x06, 0x54, 0x98, 0x22, 0x00, 0x00, 0x00, 0x02, 0x00, 0x60, - 0xff, 0xff, 0x04, 0x71, 0x05, 0xd8, 0x00, 0x07, 0x00, 0x24, 0x00, 0x00, - 0x01, 0x26, 0x27, 0x06, 0x07, 0x16, 0x17, 0x36, 0x07, 0x26, 0x27, 0x36, - 0x37, 0x16, 0x17, 0x16, 0x07, 0x33, 0x32, 0x37, 0x11, 0x26, 0x07, 0x23, - 0x11, 0x14, 0x17, 0x21, 0x36, 0x35, 0x11, 0x23, 0x26, 0x07, 0x11, 0x16, - 0x33, 0x02, 0xd6, 0x02, 0x6a, 0x6a, 0x01, 0x07, 0x64, 0x6e, 0xaf, 0x68, - 0x0a, 0x02, 0xb1, 0xb1, 0x03, 0x04, 0x77, 0x8f, 0x9e, 0x98, 0x96, 0xa0, - 0x8f, 0x57, 0xfe, 0xd1, 0x56, 0x93, 0x9f, 0x96, 0x98, 0x9e, 0x04, 0xdd, - 0xb1, 0x02, 0x02, 0xb1, 0x8e, 0x71, 0x5a, 0x72, 0x65, 0xb8, 0xf3, 0x02, - 0x02, 0xf3, 0xc2, 0x5b, 0x63, 0xfe, 0xf7, 0x37, 0x01, 0xfe, 0x0c, 0xb5, - 0xae, 0xae, 0xb5, 0x01, 0xf4, 0x01, 0x37, 0x01, 0x09, 0x63, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x79, 0xff, 0xfe, 0x04, 0x58, 0x05, 0xda, 0x00, 0x03, - 0x00, 0x20, 0x00, 0x2c, 0x00, 0x00, 0x01, 0x15, 0x33, 0x35, 0x27, 0x35, - 0x33, 0x15, 0x33, 0x15, 0x23, 0x15, 0x33, 0x05, 0x15, 0x21, 0x11, 0x17, - 0x15, 0x27, 0x03, 0x23, 0x03, 0x27, 0x35, 0x17, 0x11, 0x21, 0x35, 0x21, - 0x35, 0x23, 0x35, 0x13, 0x33, 0x11, 0x21, 0x35, 0x21, 0x35, 0x23, 0x15, - 0x21, 0x15, 0x21, 0x01, 0xfc, 0xca, 0xb6, 0xaa, 0x7e, 0x7e, 0x0a, 0x01, - 0x94, 0xfe, 0x62, 0x90, 0x88, 0x02, 0xb0, 0x02, 0x86, 0x86, 0xfe, 0x6c, - 0x01, 0x96, 0x76, 0xa4, 0x46, 0x01, 0x0c, 0xfe, 0xf4, 0x46, 0xfe, 0xf4, - 0x01, 0x0c, 0x05, 0x41, 0x3c, 0x3c, 0x33, 0x66, 0x66, 0xa2, 0x58, 0x01, - 0xaf, 0xfd, 0xe8, 0x8b, 0x9c, 0x85, 0xfe, 0xee, 0x01, 0xbc, 0x86, 0x9b, - 0x82, 0x01, 0x71, 0xb0, 0x58, 0xa2, 0xfc, 0xcf, 0x01, 0xbb, 0x47, 0x63, - 0x63, 0x47, 0x00, 0x00, 0x00, 0x02, 0x00, 0x61, 0x00, 0x07, 0x04, 0x70, - 0x06, 0x02, 0x00, 0x07, 0x00, 0x20, 0x00, 0x00, 0x01, 0x11, 0x33, 0x32, - 0x36, 0x34, 0x26, 0x23, 0x01, 0x11, 0x21, 0x32, 0x16, 0x15, 0x14, 0x06, - 0x2b, 0x01, 0x15, 0x37, 0x33, 0x09, 0x01, 0x23, 0x27, 0x15, 0x23, 0x35, - 0x07, 0x23, 0x09, 0x01, 0x33, 0x02, 0x6d, 0xab, 0x60, 0x68, 0x68, 0x60, - 0xfe, 0xce, 0x01, 0x32, 0xa9, 0xae, 0xae, 0xa9, 0xab, 0xb3, 0xb4, 0xfe, - 0xb1, 0x01, 0x60, 0xb3, 0xc4, 0x88, 0xd1, 0xb3, 0x01, 0x68, 0xfe, 0xb6, - 0xb5, 0x05, 0x7c, 0xfe, 0x3b, 0x76, 0xd9, 0x76, 0xfc, 0xbc, 0x03, 0xca, - 0xb7, 0xb1, 0xb2, 0xb6, 0xfc, 0xc2, 0xfe, 0x93, 0xfe, 0x7d, 0xd6, 0xd6, - 0xe4, 0xe4, 0x01, 0x8a, 0x01, 0x66, 0x00, 0x00, 0x00, 0x01, 0x00, 0xcc, - 0xff, 0xfb, 0x04, 0x05, 0x05, 0xcd, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x33, - 0x17, 0x15, 0x33, 0x17, 0x15, 0x07, 0x23, 0x15, 0x21, 0x17, 0x15, 0x07, - 0x21, 0x11, 0x07, 0x23, 0x27, 0x11, 0x21, 0x27, 0x35, 0x37, 0x21, 0x35, - 0x23, 0x27, 0x35, 0x37, 0x33, 0x35, 0x02, 0x0c, 0xb6, 0x06, 0xaf, 0x06, - 0x06, 0xaf, 0x01, 0x36, 0x07, 0x07, 0xfe, 0xca, 0x06, 0xb6, 0x06, 0xfe, - 0xcc, 0x06, 0x06, 0x01, 0x34, 0xae, 0x05, 0x05, 0xae, 0x05, 0xcd, 0x05, - 0x9a, 0x06, 0x94, 0x06, 0x70, 0x06, 0x98, 0x05, 0xfc, 0x86, 0x05, 0x05, - 0x03, 0x7a, 0x05, 0x98, 0x06, 0x70, 0x06, 0x94, 0x06, 0x9a, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x37, 0x00, 0x01, 0x04, 0x9a, 0x04, 0x64, 0x00, 0x2b, - 0x00, 0x00, 0x01, 0x21, 0x17, 0x15, 0x07, 0x23, 0x11, 0x21, 0x35, 0x37, - 0x33, 0x17, 0x11, 0x07, 0x23, 0x27, 0x35, 0x21, 0x11, 0x33, 0x17, 0x15, - 0x07, 0x21, 0x27, 0x35, 0x37, 0x33, 0x11, 0x21, 0x15, 0x07, 0x23, 0x27, - 0x11, 0x37, 0x33, 0x17, 0x15, 0x21, 0x11, 0x23, 0x27, 0x35, 0x01, 0xc4, - 0x01, 0x49, 0x04, 0x04, 0x78, 0x01, 0xac, 0x05, 0x4f, 0x05, 0x05, 0x4f, - 0x05, 0xfe, 0x54, 0x78, 0x04, 0x04, 0xfe, 0xb7, 0x04, 0x04, 0x80, 0xfe, - 0x53, 0x05, 0x56, 0x04, 0x04, 0x56, 0x05, 0x01, 0xad, 0x80, 0x04, 0x04, - 0x64, 0x05, 0x59, 0x04, 0xfe, 0x5c, 0x79, 0x05, 0x05, 0xfe, 0xb7, 0x05, - 0x05, 0x76, 0xfe, 0x56, 0x04, 0x50, 0x04, 0x04, 0x50, 0x04, 0x01, 0xaa, - 0x76, 0x05, 0x05, 0x01, 0x49, 0x05, 0x05, 0x79, 0x01, 0xa4, 0x04, 0x59, - 0x00, 0x02, 0x00, 0x1e, 0x00, 0x03, 0x04, 0xb3, 0x05, 0x27, 0x00, 0x1b, - 0x00, 0x2c, 0x00, 0x00, 0x01, 0x33, 0x32, 0x17, 0x23, 0x27, 0x20, 0x03, - 0x06, 0x15, 0x10, 0x05, 0x16, 0x33, 0x37, 0x15, 0x06, 0x07, 0x06, 0x2b, - 0x01, 0x20, 0x03, 0x26, 0x35, 0x10, 0x25, 0x36, 0x01, 0x33, 0x32, 0x17, - 0x33, 0x15, 0x07, 0x16, 0x15, 0x27, 0x07, 0x23, 0x35, 0x37, 0x27, 0x35, - 0x33, 0x02, 0x6d, 0x10, 0xaf, 0xa6, 0x04, 0xbd, 0xfe, 0xf0, 0xa5, 0x4a, - 0x01, 0x0e, 0x6c, 0x7b, 0xcb, 0x7e, 0x6d, 0x40, 0x2b, 0x16, 0xfe, 0xdd, - 0xbc, 0x68, 0x01, 0x34, 0x88, 0x01, 0xfa, 0x02, 0x05, 0x31, 0xa5, 0x85, - 0x34, 0x8c, 0x86, 0x02, 0x34, 0x88, 0xa8, 0x05, 0x27, 0x81, 0x30, 0xfe, - 0xef, 0x8a, 0xa3, 0xfe, 0xbe, 0xbc, 0x3e, 0x2c, 0x05, 0x5f, 0x16, 0x0a, - 0x01, 0x17, 0xa9, 0xcd, 0x01, 0x76, 0xd2, 0x4e, 0xfe, 0x6b, 0xb1, 0x03, - 0x6e, 0xa5, 0x0f, 0x6d, 0x6d, 0x03, 0xb1, 0x6e, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x04, 0xc9, 0x04, 0xc1, 0x00, 0x16, - 0x00, 0x4f, 0x00, 0x62, 0x00, 0x73, 0x00, 0x00, 0x01, 0x16, 0x33, 0x32, - 0x37, 0x16, 0x33, 0x32, 0x37, 0x35, 0x33, 0x17, 0x15, 0x14, 0x0f, 0x01, - 0x22, 0x27, 0x06, 0x23, 0x22, 0x27, 0x34, 0x17, 0x33, 0x16, 0x17, 0x32, - 0x15, 0x03, 0x33, 0x36, 0x11, 0x34, 0x27, 0x35, 0x16, 0x1d, 0x01, 0x14, - 0x07, 0x06, 0x07, 0x15, 0x16, 0x3b, 0x01, 0x15, 0x06, 0x2b, 0x01, 0x22, - 0x07, 0x27, 0x23, 0x22, 0x27, 0x35, 0x33, 0x32, 0x37, 0x35, 0x27, 0x26, - 0x27, 0x26, 0x35, 0x34, 0x3f, 0x01, 0x15, 0x06, 0x15, 0x10, 0x17, 0x35, - 0x03, 0x35, 0x37, 0x32, 0x27, 0x15, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, - 0x15, 0x23, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x33, 0x34, 0x25, - 0x16, 0x17, 0x16, 0x1d, 0x01, 0x14, 0x07, 0x06, 0x07, 0x34, 0x37, 0x36, - 0x3d, 0x01, 0x10, 0x27, 0x01, 0xdc, 0x16, 0x34, 0x26, 0x1a, 0x1f, 0x23, - 0x36, 0x11, 0x04, 0x02, 0x38, 0x19, 0x24, 0x1c, 0x1b, 0x24, 0x42, 0x0d, - 0x90, 0x02, 0x29, 0x1b, 0x07, 0x08, 0x01, 0xee, 0x5a, 0xb5, 0xb6, 0x3e, - 0x26, 0x41, 0x86, 0x15, 0x5f, 0x3b, 0x69, 0x11, 0x38, 0x38, 0x75, 0x2d, - 0x6f, 0x31, 0x62, 0x46, 0x47, 0x66, 0x1d, 0x51, 0xa2, 0x1b, 0x5f, 0xef, - 0x0f, 0x03, 0x1c, 0xd0, 0x4d, 0x35, 0x6d, 0x77, 0x02, 0x80, 0x4c, 0x1f, - 0xda, 0x62, 0x1d, 0x02, 0x04, 0x6b, 0x6a, 0x8f, 0x87, 0x49, 0x19, 0x2c, - 0x4b, 0xf2, 0x04, 0xc0, 0x3d, 0x27, 0x27, 0x38, 0x05, 0x20, 0x04, 0x30, - 0x16, 0x03, 0x23, 0x23, 0x52, 0x1b, 0x6d, 0x34, 0x09, 0x04, 0xfc, 0xda, - 0xb9, 0x01, 0x2b, 0x9e, 0xa8, 0x02, 0xaf, 0xe1, 0x1d, 0xdc, 0xb4, 0x35, - 0x12, 0x04, 0x21, 0x04, 0x1b, 0x50, 0x50, 0x17, 0x04, 0x22, 0x03, 0x34, - 0x5c, 0x3d, 0x8f, 0x90, 0xd1, 0xbb, 0x19, 0x04, 0x9c, 0xb8, 0xfe, 0xe8, - 0xc7, 0x02, 0x02, 0x8e, 0x12, 0x8a, 0x22, 0x05, 0x38, 0x51, 0xa5, 0xc3, - 0xbd, 0xae, 0x01, 0x3c, 0xbd, 0x57, 0x54, 0xda, 0xa6, 0x39, 0x03, 0x02, - 0x19, 0x5b, 0x94, 0xb0, 0x26, 0xac, 0x94, 0x42, 0x05, 0x06, 0x43, 0x8e, - 0x9b, 0x02, 0x01, 0x28, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x67, - 0xff, 0xf9, 0x04, 0x6a, 0x05, 0x5b, 0x00, 0x54, 0x00, 0x5f, 0x00, 0x67, - 0x00, 0x00, 0x01, 0x32, 0x17, 0x0f, 0x01, 0x16, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x15, 0x23, 0x15, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x37, 0x33, - 0x16, 0x15, 0x10, 0x03, 0x26, 0x23, 0x22, 0x15, 0x14, 0x17, 0x16, 0x07, - 0x06, 0x23, 0x06, 0x27, 0x26, 0x27, 0x15, 0x06, 0x17, 0x14, 0x23, 0x22, - 0x35, 0x36, 0x3d, 0x01, 0x06, 0x15, 0x06, 0x27, 0x22, 0x27, 0x34, 0x36, - 0x27, 0x34, 0x23, 0x22, 0x07, 0x02, 0x11, 0x34, 0x37, 0x33, 0x17, 0x06, - 0x15, 0x14, 0x17, 0x16, 0x17, 0x35, 0x23, 0x35, 0x26, 0x35, 0x34, 0x37, - 0x2f, 0x01, 0x36, 0x03, 0x14, 0x17, 0x33, 0x36, 0x35, 0x34, 0x27, 0x06, - 0x07, 0x06, 0x25, 0x06, 0x15, 0x14, 0x17, 0x36, 0x35, 0x34, 0x02, 0x69, - 0x3d, 0x4b, 0x11, 0x0e, 0x75, 0x2f, 0x33, 0xbc, 0x6e, 0x6f, 0x83, 0x7c, - 0x73, 0x14, 0x04, 0xd7, 0x89, 0x6e, 0x49, 0x33, 0x6e, 0x1e, 0x02, 0x0c, - 0x27, 0x3b, 0x06, 0x36, 0x57, 0x04, 0x4e, 0x60, 0x66, 0x49, 0x8d, 0x07, - 0x3a, 0x25, 0x0d, 0x8d, 0x03, 0x2b, 0x4b, 0x6b, 0x8d, 0xd1, 0x05, 0x13, - 0x73, 0xc5, 0x3a, 0x6f, 0x6d, 0xbc, 0xdb, 0x16, 0x0f, 0x50, 0xbd, 0x7c, - 0x04, 0x40, 0x1a, 0x52, 0x2f, 0x25, 0x01, 0x53, 0x20, 0x3c, 0x85, 0x05, - 0x5b, 0x45, 0x0e, 0x72, 0x2a, 0x4a, 0x4b, 0x4e, 0xb7, 0x5a, 0x45, 0x6e, - 0x76, 0x91, 0xb6, 0xa2, 0x69, 0x11, 0x98, 0xed, 0xfe, 0xf7, 0xfe, 0xe2, - 0xa0, 0x29, 0x1a, 0x87, 0x25, 0x2a, 0x36, 0x08, 0x26, 0xdb, 0x2d, 0x8a, - 0x43, 0x6c, 0x36, 0x37, 0x6a, 0x47, 0x87, 0x56, 0xb0, 0x22, 0x02, 0x36, - 0x3b, 0x9b, 0x1e, 0x25, 0x9f, 0x01, 0x0a, 0x01, 0x32, 0xd6, 0x99, 0x11, - 0x70, 0xa0, 0xe7, 0x96, 0x2b, 0x10, 0x6e, 0x45, 0x55, 0xbb, 0xaf, 0x5f, - 0x72, 0x11, 0x42, 0xfe, 0x28, 0x86, 0x45, 0x61, 0x80, 0x4c, 0x74, 0x17, - 0x44, 0x3a, 0x95, 0x6a, 0x5b, 0x7e, 0x5e, 0x39, 0x9a, 0x8c, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x0f, 0x00, 0x05, 0x04, 0xc2, 0x05, 0x22, 0x00, 0x32, - 0x00, 0x00, 0x01, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x17, 0x07, 0x23, - 0x27, 0x06, 0x23, 0x22, 0x27, 0x15, 0x03, 0x23, 0x26, 0x27, 0x36, 0x01, - 0x36, 0x33, 0x16, 0x33, 0x32, 0x37, 0x27, 0x07, 0x23, 0x26, 0x27, 0x37, - 0x16, 0x15, 0x07, 0x16, 0x17, 0x35, 0x36, 0x3d, 0x01, 0x34, 0x27, 0x26, - 0x2b, 0x01, 0x22, 0x07, 0x36, 0x02, 0xab, 0xbe, 0xa9, 0x78, 0x64, 0x9c, - 0x71, 0x02, 0x95, 0x85, 0xaf, 0x89, 0x73, 0xd1, 0x02, 0xa5, 0x03, 0x15, - 0x01, 0x16, 0x13, 0x06, 0x5b, 0x7f, 0x9a, 0x79, 0xae, 0x57, 0x05, 0x97, - 0x07, 0xbc, 0xe3, 0x65, 0xb9, 0x17, 0x36, 0xca, 0x6f, 0x60, 0x1d, 0x4f, - 0x61, 0x89, 0x05, 0x21, 0xa5, 0x88, 0xbc, 0xb0, 0x79, 0x81, 0x73, 0x95, - 0x60, 0x4d, 0x03, 0xfe, 0x6b, 0x7b, 0x06, 0x16, 0x01, 0x65, 0x1a, 0x4b, - 0x5b, 0xae, 0x65, 0x66, 0x0a, 0xe2, 0x0c, 0x05, 0x8b, 0x99, 0x0c, 0x01, - 0x4f, 0x6d, 0x1f, 0xde, 0x59, 0x3c, 0x30, 0x7d, 0x00, 0x05, 0x00, 0x1b, - 0x00, 0x05, 0x04, 0xb6, 0x04, 0xa0, 0x00, 0x0b, 0x00, 0x12, 0x00, 0x16, - 0x00, 0x1a, 0x00, 0x21, 0x00, 0x00, 0x13, 0x34, 0x00, 0x33, 0x32, 0x00, - 0x15, 0x14, 0x00, 0x23, 0x22, 0x00, 0x37, 0x14, 0x17, 0x01, 0x03, 0x06, - 0x00, 0x13, 0x16, 0x17, 0x1b, 0x01, 0x36, 0x37, 0x09, 0x01, 0x36, 0x35, - 0x34, 0x00, 0x27, 0x11, 0x1b, 0x01, 0x59, 0xf4, 0xf5, 0x01, 0x59, 0xfe, - 0xa7, 0xf5, 0xf4, 0xfe, 0xa7, 0x78, 0x5f, 0x01, 0x50, 0x02, 0x9a, 0xfe, - 0xed, 0x88, 0x8b, 0x97, 0x02, 0x4b, 0xa1, 0x86, 0xfe, 0xd9, 0x01, 0x5c, - 0x59, 0xfe, 0xec, 0xa6, 0x02, 0x51, 0xf5, 0x01, 0x5a, 0xfe, 0xa6, 0xf5, - 0xf4, 0xfe, 0xa9, 0x01, 0x57, 0xf4, 0xb4, 0x5f, 0x01, 0x8b, 0x01, 0x62, - 0x03, 0xfe, 0xed, 0xfd, 0xf1, 0x8c, 0x04, 0x01, 0xe5, 0xfe, 0x19, 0x06, - 0x81, 0x01, 0x59, 0xfe, 0xe4, 0x58, 0xc1, 0xc4, 0x01, 0x13, 0x03, 0xfe, - 0xa1, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x05, 0x04, 0xc3, - 0x04, 0xba, 0x00, 0x12, 0x00, 0x1e, 0x00, 0x28, 0x00, 0x34, 0x00, 0x00, - 0x01, 0x15, 0x1e, 0x01, 0x33, 0x32, 0x36, 0x35, 0x34, 0x00, 0x23, 0x22, - 0x00, 0x07, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x05, 0x14, 0x06, 0x23, 0x22, - 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x05, 0x34, 0x26, 0x22, 0x06, - 0x15, 0x14, 0x16, 0x32, 0x36, 0x25, 0x14, 0x00, 0x23, 0x22, 0x00, 0x35, - 0x34, 0x00, 0x33, 0x32, 0x00, 0x02, 0x69, 0x08, 0x9e, 0x74, 0x76, 0xa1, - 0xfe, 0xb3, 0xe4, 0xea, 0xfe, 0xc7, 0x10, 0x13, 0x8f, 0x78, 0x73, 0x9f, - 0x01, 0x71, 0x31, 0x1f, 0x22, 0x30, 0x30, 0x22, 0x20, 0x30, 0xfd, 0xcd, - 0x2f, 0x42, 0x2f, 0x2f, 0x42, 0x2f, 0x03, 0x23, 0xfe, 0xa0, 0xfa, 0xfa, - 0xfe, 0x9f, 0x01, 0x61, 0xfa, 0xfa, 0x01, 0x60, 0x02, 0x69, 0x15, 0x72, - 0x9b, 0xa6, 0x7c, 0xe0, 0x01, 0x48, 0xfe, 0xc7, 0xfa, 0x8a, 0x90, 0x9b, - 0x7f, 0x21, 0x2f, 0x2f, 0x21, 0x22, 0x30, 0x30, 0x22, 0x22, 0x30, 0x30, - 0x22, 0x21, 0x2f, 0x30, 0x20, 0xfa, 0xfe, 0xa1, 0x01, 0x5f, 0xfa, 0xfa, - 0x01, 0x62, 0xfe, 0x9e, 0x00, 0x0a, 0x00, 0x1b, 0x00, 0xa8, 0x04, 0xb6, - 0x05, 0x23, 0x00, 0x0e, 0x00, 0x3e, 0x00, 0x44, 0x00, 0x4a, 0x00, 0x50, - 0x00, 0x56, 0x00, 0x5c, 0x00, 0x62, 0x00, 0x68, 0x00, 0x6e, 0x00, 0x00, - 0x01, 0x14, 0x17, 0x16, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, - 0x22, 0x07, 0x06, 0x05, 0x26, 0x37, 0x33, 0x36, 0x37, 0x27, 0x36, 0x37, - 0x17, 0x36, 0x37, 0x35, 0x36, 0x17, 0x15, 0x16, 0x17, 0x37, 0x16, 0x17, - 0x07, 0x16, 0x17, 0x33, 0x16, 0x07, 0x23, 0x06, 0x07, 0x17, 0x06, 0x07, - 0x27, 0x06, 0x07, 0x15, 0x06, 0x27, 0x35, 0x26, 0x27, 0x07, 0x26, 0x27, - 0x37, 0x26, 0x27, 0x25, 0x36, 0x37, 0x27, 0x06, 0x07, 0x05, 0x16, 0x17, - 0x37, 0x26, 0x27, 0x01, 0x36, 0x37, 0x27, 0x06, 0x07, 0x25, 0x16, 0x17, - 0x37, 0x26, 0x27, 0x01, 0x26, 0x27, 0x07, 0x16, 0x17, 0x25, 0x06, 0x07, - 0x17, 0x36, 0x37, 0x05, 0x06, 0x07, 0x17, 0x36, 0x37, 0x25, 0x26, 0x27, - 0x07, 0x16, 0x17, 0x01, 0xea, 0x26, 0x24, 0x68, 0x25, 0x24, 0x25, 0x25, - 0x33, 0x34, 0x24, 0x26, 0xfe, 0x31, 0x2b, 0x2b, 0x58, 0x15, 0x53, 0x41, - 0x0b, 0x4e, 0x40, 0x60, 0x98, 0x3d, 0x3d, 0x8e, 0x6b, 0x3e, 0x50, 0x0d, - 0x43, 0x52, 0x16, 0x58, 0x2b, 0x2b, 0x58, 0x0f, 0x59, 0x43, 0x0d, 0x50, - 0x3e, 0x6b, 0x8e, 0x3d, 0x3d, 0x8d, 0x6c, 0x3f, 0x4c, 0x0d, 0x3f, 0x51, - 0x15, 0x01, 0x8b, 0x1a, 0x1c, 0x09, 0x6f, 0x4c, 0x01, 0x2b, 0x20, 0x17, - 0x8f, 0x4e, 0x6e, 0xfe, 0xf9, 0x07, 0x11, 0x9f, 0x3b, 0x12, 0x02, 0x50, - 0x13, 0x05, 0xd6, 0x0f, 0x3f, 0xfd, 0xfc, 0x10, 0x08, 0xd4, 0x11, 0x3b, - 0x02, 0x1c, 0x06, 0x12, 0xa0, 0x40, 0x0d, 0xfe, 0xcb, 0x1a, 0x1d, 0x0a, - 0x6e, 0x4d, 0xfe, 0xd3, 0x16, 0x1f, 0x8f, 0x4e, 0x6e, 0x02, 0xe4, 0x33, - 0x25, 0x25, 0x25, 0x25, 0x33, 0x34, 0x25, 0x26, 0x26, 0x25, 0x73, 0x3d, - 0x3d, 0x8f, 0x60, 0x3f, 0x4a, 0x0c, 0x3e, 0x50, 0x17, 0x57, 0x2c, 0x2c, - 0x57, 0x11, 0x57, 0x3f, 0x0b, 0x4b, 0x3f, 0x5f, 0x90, 0x3d, 0x3d, 0x89, - 0x66, 0x3f, 0x48, 0x08, 0x3f, 0x50, 0x17, 0x57, 0x2c, 0x2c, 0x57, 0x12, - 0x55, 0x3f, 0x08, 0x48, 0x3f, 0x5e, 0x91, 0xea, 0x0f, 0x08, 0xd2, 0x11, - 0x3c, 0x85, 0x08, 0x0f, 0x9b, 0x3d, 0x10, 0xfe, 0xa1, 0x1d, 0x15, 0x85, - 0x4b, 0x65, 0x2b, 0x18, 0x1a, 0x08, 0x63, 0x4c, 0xfe, 0xab, 0x18, 0x20, - 0x0d, 0x6d, 0x43, 0xbe, 0x1d, 0x1b, 0x86, 0x50, 0x60, 0x6b, 0x0e, 0x08, - 0xd5, 0x18, 0x3c, 0x81, 0x07, 0x0f, 0x97, 0x3c, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x05, 0x00, 0x21, 0x00, 0xa4, 0x04, 0xb0, 0x05, 0x34, 0x00, 0x0f, - 0x00, 0x1e, 0x00, 0x28, 0x00, 0x30, 0x00, 0x38, 0x00, 0x00, 0x13, 0x34, - 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, - 0x27, 0x26, 0x37, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, - 0x00, 0x23, 0x22, 0x07, 0x06, 0x01, 0x26, 0x07, 0x23, 0x12, 0x25, 0x04, - 0x13, 0x23, 0x26, 0x37, 0x26, 0x27, 0x36, 0x37, 0x16, 0x17, 0x06, 0x05, - 0x26, 0x27, 0x36, 0x37, 0x16, 0x17, 0x06, 0x21, 0xab, 0xab, 0xf1, 0xf3, - 0xab, 0xaa, 0xaa, 0xab, 0xf3, 0xf1, 0xab, 0xab, 0x76, 0x89, 0x88, 0xc0, - 0xc1, 0x89, 0x89, 0xfe, 0xee, 0xc1, 0xc0, 0x88, 0x89, 0x01, 0xd3, 0xa4, - 0x3d, 0x36, 0x0f, 0x01, 0x0c, 0x01, 0x04, 0x0f, 0x35, 0x4e, 0x27, 0x56, - 0x03, 0x04, 0x5b, 0x53, 0x04, 0x04, 0xfe, 0x2e, 0x55, 0x04, 0x05, 0x5b, - 0x52, 0x05, 0x05, 0x02, 0xea, 0xf3, 0xab, 0xac, 0xac, 0xab, 0xf3, 0xf1, - 0xab, 0xaa, 0xaa, 0xab, 0xf1, 0xbf, 0x89, 0x8a, 0x8a, 0x89, 0xbf, 0xc3, - 0x01, 0x10, 0x88, 0x88, 0xfe, 0xde, 0x0a, 0xcc, 0x01, 0x10, 0x0e, 0x12, - 0xfe, 0xf5, 0xca, 0xaf, 0x04, 0x58, 0x5b, 0x05, 0x07, 0x56, 0x5b, 0x04, - 0x04, 0x58, 0x5b, 0x05, 0x07, 0x56, 0x5b, 0x00, 0x00, 0x05, 0x00, 0x21, - 0x00, 0xa4, 0x04, 0xb0, 0x05, 0x34, 0x00, 0x0f, 0x00, 0x1e, 0x00, 0x28, - 0x00, 0x30, 0x00, 0x38, 0x00, 0x00, 0x13, 0x34, 0x37, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x37, 0x14, - 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x00, 0x23, 0x22, 0x07, - 0x06, 0x01, 0x16, 0x37, 0x33, 0x02, 0x05, 0x24, 0x03, 0x33, 0x16, 0x01, - 0x26, 0x27, 0x36, 0x37, 0x16, 0x17, 0x06, 0x05, 0x26, 0x27, 0x36, 0x37, - 0x16, 0x17, 0x06, 0x21, 0xab, 0xab, 0xf1, 0xf3, 0xab, 0xaa, 0xaa, 0xab, - 0xf3, 0xf1, 0xab, 0xab, 0x76, 0x89, 0x88, 0xc0, 0xc1, 0x89, 0x89, 0xfe, - 0xee, 0xc1, 0xc0, 0x88, 0x89, 0x01, 0xd1, 0xa6, 0x3d, 0x36, 0x0f, 0xfe, - 0xf3, 0xfe, 0xfd, 0x0f, 0x33, 0x51, 0x01, 0x4e, 0x56, 0x03, 0x04, 0x5b, - 0x53, 0x04, 0x04, 0xfe, 0x2e, 0x55, 0x04, 0x05, 0x5b, 0x52, 0x05, 0x05, - 0x02, 0xea, 0xf3, 0xab, 0xac, 0xac, 0xab, 0xf3, 0xf1, 0xab, 0xaa, 0xaa, - 0xab, 0xf1, 0xbf, 0x89, 0x8a, 0x8a, 0x89, 0xbf, 0xc3, 0x01, 0x10, 0x88, - 0x88, 0xfe, 0x77, 0x09, 0xcc, 0xfe, 0xf0, 0x0e, 0x13, 0x01, 0x0a, 0xca, - 0x01, 0x27, 0x04, 0x58, 0x5b, 0x05, 0x07, 0x56, 0x5b, 0x04, 0x04, 0x58, - 0x5b, 0x05, 0x07, 0x56, 0x5b, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x21, - 0x00, 0xa4, 0x04, 0xb0, 0x05, 0x34, 0x00, 0x0f, 0x00, 0x19, 0x00, 0x21, - 0x00, 0x29, 0x00, 0x00, 0x13, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x25, 0x23, 0x12, 0x05, - 0x24, 0x13, 0x27, 0x06, 0x27, 0x06, 0x01, 0x26, 0x27, 0x06, 0x07, 0x16, - 0x17, 0x36, 0x25, 0x26, 0x27, 0x06, 0x07, 0x16, 0x17, 0x36, 0x21, 0xab, - 0xab, 0xf1, 0xf3, 0xab, 0xaa, 0xaa, 0xab, 0xf3, 0xf1, 0xab, 0xab, 0x01, - 0x34, 0x3e, 0x12, 0x01, 0x3b, 0x01, 0x44, 0x12, 0x40, 0x4b, 0xc7, 0xb2, - 0x02, 0x06, 0x06, 0x63, 0x6e, 0x06, 0x05, 0x67, 0x6b, 0xfe, 0x3f, 0x05, - 0x64, 0x6e, 0x05, 0x04, 0x68, 0x6b, 0x02, 0xea, 0xf3, 0xab, 0xac, 0xac, - 0xab, 0xf3, 0xf1, 0xab, 0xaa, 0xaa, 0xab, 0xed, 0xfe, 0xbd, 0x16, 0x11, - 0x01, 0x49, 0x02, 0xf8, 0x0b, 0x0a, 0x01, 0xd6, 0x6b, 0x08, 0x06, 0x70, - 0x69, 0x07, 0x07, 0x6e, 0x69, 0x08, 0x06, 0x70, 0x69, 0x07, 0x07, 0x00, - 0x00, 0x0a, 0x00, 0x21, 0x00, 0xa4, 0x04, 0xb0, 0x05, 0x34, 0x00, 0x07, - 0x00, 0x0c, 0x00, 0x13, 0x00, 0x22, 0x00, 0x2a, 0x00, 0x32, 0x00, 0x3a, - 0x00, 0x41, 0x00, 0x49, 0x00, 0x58, 0x00, 0x00, 0x01, 0x33, 0x17, 0x11, - 0x07, 0x23, 0x27, 0x11, 0x05, 0x17, 0x15, 0x07, 0x27, 0x25, 0x17, 0x07, - 0x23, 0x26, 0x27, 0x35, 0x05, 0x32, 0x1f, 0x01, 0x14, 0x07, 0x06, 0x23, - 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x05, 0x21, 0x17, 0x15, 0x07, - 0x21, 0x27, 0x35, 0x25, 0x21, 0x17, 0x15, 0x07, 0x21, 0x27, 0x35, 0x07, - 0x33, 0x16, 0x17, 0x15, 0x07, 0x27, 0x35, 0x25, 0x33, 0x17, 0x15, 0x07, - 0x27, 0x35, 0x25, 0x33, 0x17, 0x11, 0x07, 0x23, 0x27, 0x11, 0x03, 0x06, - 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x27, 0x26, 0x23, - 0x22, 0x02, 0x4d, 0x3d, 0x05, 0x05, 0x3d, 0x04, 0x01, 0xbc, 0x2c, 0xc2, - 0x2f, 0xfd, 0xa5, 0xc5, 0x30, 0x03, 0x9c, 0x23, 0x01, 0xb6, 0xa8, 0x48, - 0x0a, 0x99, 0x38, 0x26, 0x8d, 0x4f, 0x1d, 0x94, 0x36, 0xfd, 0xe3, 0x01, - 0x09, 0x05, 0x05, 0xfe, 0xf7, 0x04, 0x03, 0x7c, 0x01, 0x0e, 0x05, 0x05, - 0xfe, 0xf2, 0x05, 0x37, 0x02, 0x69, 0x59, 0x30, 0xc2, 0xfe, 0x36, 0x02, - 0x2e, 0xc1, 0x2f, 0x01, 0xa4, 0x3d, 0x05, 0x05, 0x3d, 0x04, 0x1d, 0x65, - 0x13, 0x36, 0x61, 0x19, 0x26, 0x69, 0x07, 0x31, 0x72, 0x1f, 0x05, 0x34, - 0x05, 0xfe, 0xee, 0x05, 0x05, 0x01, 0x12, 0x7a, 0x30, 0x02, 0xc7, 0x31, - 0xb9, 0xc6, 0x32, 0x9c, 0x2b, 0x03, 0x8e, 0xb0, 0x4b, 0x93, 0x4e, 0x13, - 0x83, 0x32, 0x48, 0x8c, 0x51, 0x15, 0xd6, 0x05, 0x3e, 0x05, 0x05, 0x3e, - 0x05, 0x05, 0x3e, 0x05, 0x05, 0x3e, 0xdb, 0x66, 0x5e, 0x02, 0x32, 0xc6, - 0x03, 0x22, 0x2f, 0x03, 0xc6, 0x31, 0x03, 0x5d, 0x05, 0xfe, 0xee, 0x05, - 0x05, 0x01, 0x12, 0x01, 0xd3, 0x38, 0x60, 0x31, 0x22, 0x59, 0x0d, 0x34, - 0x66, 0x32, 0x79, 0x00, 0x00, 0x02, 0x00, 0x9c, 0x00, 0x05, 0x04, 0x35, - 0x05, 0xc6, 0x00, 0x17, 0x00, 0x2b, 0x00, 0x00, 0x01, 0x20, 0x01, 0x16, - 0x15, 0x10, 0x05, 0x06, 0x2b, 0x01, 0x22, 0x27, 0x35, 0x24, 0x37, 0x36, - 0x11, 0x10, 0x25, 0x26, 0x27, 0x35, 0x34, 0x37, 0x17, 0x15, 0x04, 0x11, - 0x10, 0x05, 0x07, 0x15, 0x33, 0x32, 0x37, 0x36, 0x37, 0x36, 0x3d, 0x01, - 0x10, 0x01, 0x26, 0x23, 0x01, 0x3b, 0x01, 0x85, 0x01, 0x0c, 0x68, 0xfe, - 0x7a, 0xb0, 0xad, 0x30, 0x2f, 0x4f, 0x01, 0x10, 0x7b, 0x99, 0xfe, 0xb7, - 0x86, 0x5b, 0x92, 0x28, 0x01, 0xc2, 0xfe, 0xb4, 0x2a, 0x06, 0x54, 0x9c, - 0xe5, 0x51, 0x1c, 0xfe, 0xab, 0xa1, 0x9b, 0x05, 0xc5, 0xfe, 0x8d, 0xaa, - 0xc3, 0xfe, 0x7e, 0xfd, 0x60, 0x0e, 0x06, 0x4e, 0xae, 0xc7, 0x01, 0x08, - 0x01, 0x8a, 0xdc, 0x4f, 0x10, 0x03, 0x0a, 0x0e, 0x3d, 0x03, 0xc2, 0xfe, - 0x1c, 0xfe, 0x74, 0xe4, 0x18, 0x04, 0x52, 0x96, 0xf0, 0x5b, 0x5c, 0x09, - 0x01, 0x38, 0x01, 0x01, 0x64, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x95, - 0x00, 0x07, 0x04, 0x3c, 0x05, 0xdf, 0x00, 0x17, 0x00, 0x2b, 0x00, 0x00, - 0x25, 0x20, 0x01, 0x26, 0x35, 0x10, 0x01, 0x36, 0x3b, 0x01, 0x32, 0x17, - 0x15, 0x04, 0x07, 0x06, 0x11, 0x10, 0x05, 0x16, 0x17, 0x15, 0x14, 0x07, - 0x27, 0x35, 0x24, 0x11, 0x10, 0x25, 0x37, 0x35, 0x23, 0x22, 0x07, 0x06, - 0x07, 0x06, 0x1d, 0x01, 0x10, 0x01, 0x16, 0x33, 0x03, 0x9a, 0xfe, 0x76, - 0xfe, 0xee, 0x68, 0x01, 0x8c, 0xb2, 0xb2, 0x30, 0x2e, 0x50, 0xfe, 0xec, - 0x7e, 0x9a, 0x01, 0x4e, 0x88, 0x5e, 0x96, 0x28, 0xfe, 0x38, 0x01, 0x50, - 0x2c, 0x06, 0x56, 0xa0, 0xe8, 0x52, 0x1c, 0x01, 0x5a, 0xa4, 0x9e, 0x07, - 0x01, 0x79, 0xad, 0xc6, 0x01, 0x88, 0x01, 0x01, 0x63, 0x0f, 0x07, 0x4f, - 0xb1, 0xcb, 0xfe, 0xf5, 0xfe, 0x70, 0xe1, 0x4f, 0x10, 0x04, 0x0a, 0x0e, - 0x3e, 0x03, 0xc5, 0x01, 0xed, 0x01, 0x91, 0xe8, 0x18, 0x03, 0x53, 0x96, - 0xf5, 0x5c, 0x5e, 0x09, 0xfe, 0xc2, 0xfe, 0xfc, 0x66, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0xbd, 0xff, 0x60, 0x04, 0x14, 0x05, 0xab, 0x00, 0x31, - 0x00, 0x42, 0x00, 0x00, 0x01, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, - 0x07, 0x15, 0x37, 0x15, 0x07, 0x17, 0x23, 0x35, 0x23, 0x35, 0x33, 0x27, - 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x26, 0x27, 0x26, 0x3d, - 0x01, 0x33, 0x15, 0x14, 0x17, 0x16, 0x17, 0x33, 0x36, 0x37, 0x36, 0x3d, - 0x01, 0x33, 0x15, 0x14, 0x07, 0x06, 0x07, 0x23, 0x06, 0x07, 0x06, 0x15, - 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x03, - 0x4f, 0x26, 0x22, 0x7d, 0x7c, 0x66, 0x87, 0xcc, 0xd0, 0x01, 0x7a, 0xbf, - 0xbf, 0x02, 0x8b, 0x67, 0x7d, 0x7d, 0x22, 0x26, 0x26, 0x22, 0x7d, 0x86, - 0x55, 0x51, 0x6e, 0x24, 0x6d, 0x51, 0x55, 0x86, 0x7d, 0x22, 0xfa, 0x24, - 0x6e, 0x51, 0x55, 0x56, 0x56, 0x7b, 0x78, 0x56, 0x56, 0x55, 0x51, 0x04, - 0x3c, 0x19, 0x22, 0x7b, 0xb3, 0xb1, 0x75, 0x5e, 0x0e, 0xc5, 0x02, 0x5e, - 0x01, 0xbf, 0xc0, 0x5c, 0xc5, 0x0d, 0x5f, 0x75, 0xb1, 0xb3, 0x7b, 0x22, - 0x19, 0x17, 0x23, 0x7c, 0xb1, 0x08, 0x0a, 0x7a, 0x55, 0x4f, 0x06, 0x06, - 0x4f, 0x55, 0x7a, 0x0a, 0x08, 0xb1, 0x7c, 0x23, 0x59, 0x06, 0x4f, 0x54, - 0x7b, 0x7a, 0x51, 0x50, 0x50, 0x51, 0x7a, 0x7b, 0x54, 0x4f, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x91, 0xff, 0x9b, 0x04, 0x40, 0x05, 0x3e, 0x00, 0x0e, - 0x00, 0x29, 0x00, 0x00, 0x01, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, - 0x15, 0x14, 0x16, 0x33, 0x32, 0x37, 0x36, 0x05, 0x26, 0x35, 0x34, 0x37, - 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x15, 0x37, - 0x15, 0x07, 0x17, 0x23, 0x27, 0x23, 0x35, 0x33, 0x27, 0x26, 0x03, 0xad, - 0x60, 0x5f, 0x84, 0x87, 0x5f, 0x5f, 0xbe, 0x87, 0x84, 0x5f, 0x60, 0xfd, - 0x6f, 0x8b, 0x8a, 0x8a, 0xc5, 0xc2, 0x8a, 0x8a, 0x89, 0x71, 0x93, 0xdf, - 0xe4, 0x02, 0x87, 0x02, 0xd1, 0xd1, 0x01, 0x99, 0x03, 0x6b, 0x87, 0x5d, - 0x5e, 0x5e, 0x5d, 0x87, 0x86, 0xb2, 0x59, 0x59, 0xc1, 0x81, 0xc3, 0xc5, - 0x88, 0x89, 0x89, 0x88, 0xc5, 0xc3, 0x81, 0x68, 0x0f, 0xd9, 0x01, 0x67, - 0x02, 0xd1, 0xd3, 0x66, 0xd9, 0x0e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x91, - 0xff, 0x9b, 0x04, 0x40, 0x05, 0x3e, 0x00, 0x0c, 0x00, 0x27, 0x00, 0x00, - 0x01, 0x22, 0x07, 0x06, 0x10, 0x16, 0x33, 0x32, 0x37, 0x36, 0x10, 0x27, - 0x26, 0x27, 0x37, 0x23, 0x35, 0x33, 0x37, 0x33, 0x07, 0x17, 0x15, 0x27, - 0x15, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, - 0x35, 0x34, 0x37, 0x36, 0x02, 0x6a, 0x87, 0x5f, 0x5f, 0xbe, 0x87, 0x84, - 0x5f, 0x60, 0x60, 0x5f, 0xc8, 0x01, 0xd1, 0xd1, 0x02, 0x87, 0x02, 0xe4, - 0xdf, 0x93, 0x71, 0x89, 0x8a, 0x8a, 0xc2, 0xc5, 0x8a, 0x8a, 0x8b, 0x71, - 0x02, 0xa5, 0x59, 0x58, 0xfe, 0xf2, 0xba, 0x5d, 0x5d, 0x01, 0x0e, 0x58, - 0x59, 0x86, 0xda, 0x66, 0xd3, 0xd2, 0x01, 0x68, 0x02, 0xda, 0x0f, 0x68, - 0x81, 0xc3, 0xc4, 0x88, 0x89, 0x89, 0x88, 0xc4, 0xc3, 0x81, 0x6a, 0x00, - 0x00, 0x02, 0x00, 0x15, 0x00, 0x9a, 0x04, 0xbc, 0x05, 0x30, 0x00, 0x0d, - 0x00, 0x27, 0x00, 0x00, 0x01, 0x26, 0x27, 0x26, 0x07, 0x06, 0x14, 0x17, - 0x16, 0x33, 0x16, 0x37, 0x36, 0x26, 0x13, 0x06, 0x2b, 0x01, 0x22, 0x27, - 0x26, 0x35, 0x27, 0x34, 0x37, 0x36, 0x17, 0x16, 0x17, 0x01, 0x25, 0x37, - 0x21, 0x11, 0x07, 0x11, 0x01, 0x16, 0x17, 0x16, 0x02, 0xa2, 0x5a, 0x7b, - 0x7a, 0x5b, 0x5a, 0x5a, 0x5b, 0x7e, 0x7f, 0x5c, 0x59, 0x08, 0x10, 0x83, - 0xb6, 0x01, 0xb9, 0x82, 0x81, 0x02, 0x83, 0x82, 0xb2, 0xb2, 0x57, 0x01, - 0x1a, 0xfe, 0xde, 0x6d, 0x01, 0x82, 0x70, 0xfe, 0xe7, 0x4e, 0x07, 0x06, - 0x03, 0x23, 0x5a, 0x04, 0x04, 0x58, 0x5b, 0xfe, 0x5b, 0x59, 0x01, 0x5a, - 0x5b, 0xf6, 0xfe, 0x50, 0x80, 0x80, 0x81, 0xb7, 0x03, 0xb6, 0x83, 0x81, - 0x07, 0x06, 0x51, 0x01, 0x10, 0x02, 0x6d, 0xfe, 0x80, 0x70, 0x01, 0x23, - 0xfe, 0xef, 0x54, 0xb2, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x47, - 0x00, 0x2a, 0x04, 0x8a, 0x05, 0xae, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x35, - 0x32, 0x37, 0x36, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x1d, 0x01, - 0x23, 0x34, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x33, 0x11, - 0x33, 0x11, 0x23, 0x11, 0x21, 0x35, 0x01, 0xe8, 0x73, 0x50, 0x51, 0x50, - 0x50, 0x74, 0x72, 0x51, 0x50, 0x8e, 0xf4, 0xad, 0xb1, 0x79, 0x7a, 0x67, - 0xd6, 0x8f, 0x8f, 0xfc, 0x4c, 0x02, 0x1f, 0x01, 0x51, 0x51, 0xe4, 0x51, - 0x50, 0x50, 0x51, 0x72, 0x02, 0xae, 0xf6, 0x7b, 0x7b, 0xae, 0x9f, 0x74, - 0x03, 0x8f, 0xfa, 0x7c, 0x01, 0x67, 0x8e, 0x00, 0x00, 0x01, 0x00, 0xae, - 0x00, 0x2a, 0x04, 0x23, 0x05, 0xae, 0x00, 0x22, 0x00, 0x00, 0x01, 0x23, - 0x35, 0x33, 0x35, 0x33, 0x15, 0x33, 0x15, 0x23, 0x11, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x15, 0x14, 0x06, 0x1d, 0x01, 0x23, 0x34, 0x37, 0x36, 0x35, - 0x34, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x11, 0x23, 0x01, 0x12, 0x64, - 0x64, 0x8f, 0xa8, 0xa8, 0x69, 0x90, 0xa7, 0x71, 0x71, 0x84, 0x8f, 0x43, - 0x42, 0x92, 0x69, 0x67, 0x49, 0x49, 0x8f, 0x04, 0x75, 0x8f, 0xaa, 0xaa, - 0x8f, 0xfe, 0x93, 0x67, 0x7a, 0x79, 0xb1, 0x55, 0xd8, 0x72, 0x02, 0x7d, - 0x70, 0x70, 0x44, 0x74, 0xa0, 0x50, 0x51, 0x73, 0xfe, 0x5f, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x43, 0x00, 0x85, 0x04, 0x8e, 0x05, 0x53, 0x00, 0x0d, - 0x00, 0x37, 0x00, 0x00, 0x01, 0x22, 0x07, 0x06, 0x15, 0x14, 0x16, 0x32, - 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x37, 0x16, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x11, 0x23, - 0x11, 0x23, 0x35, 0x33, 0x11, 0x23, 0x35, 0x33, 0x11, 0x33, 0x11, 0x33, - 0x11, 0x33, 0x11, 0x33, 0x15, 0x23, 0x11, 0x33, 0x15, 0x23, 0x11, 0x23, - 0x02, 0x68, 0x2e, 0x20, 0x20, 0x40, 0x5c, 0x20, 0x21, 0x20, 0x20, 0x10, - 0x32, 0x28, 0x3e, 0x3e, 0x3f, 0x5a, 0x57, 0x7e, 0x3e, 0x27, 0x33, 0xed, - 0xfb, 0x7f, 0x7f, 0xfb, 0xed, 0x7c, 0xed, 0xfa, 0x7d, 0x7d, 0xfa, 0xed, - 0x01, 0xcb, 0x21, 0x20, 0x2d, 0x2f, 0x40, 0x20, 0x20, 0x2f, 0x2d, 0x20, - 0x21, 0x5e, 0x0f, 0x27, 0x3f, 0x58, 0x59, 0x3f, 0x3f, 0x7e, 0x59, 0x58, - 0x3f, 0x28, 0x0e, 0x01, 0x46, 0xfe, 0x98, 0x7d, 0x02, 0x52, 0x7d, 0xfe, - 0x98, 0x01, 0x68, 0xfe, 0x98, 0x01, 0x68, 0x7d, 0xfd, 0xae, 0x7d, 0x01, - 0x68, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x4c, 0x00, 0x85, 0x04, 0x85, - 0x05, 0x53, 0x00, 0x3c, 0x00, 0x00, 0x01, 0x15, 0x23, 0x35, 0x23, 0x35, - 0x33, 0x35, 0x26, 0x27, 0x26, 0x27, 0x35, 0x07, 0x27, 0x37, 0x33, 0x17, - 0x15, 0x27, 0x15, 0x33, 0x15, 0x23, 0x16, 0x17, 0x16, 0x17, 0x11, 0x07, - 0x27, 0x37, 0x33, 0x17, 0x15, 0x27, 0x11, 0x36, 0x37, 0x36, 0x3d, 0x01, - 0x33, 0x35, 0x07, 0x27, 0x37, 0x33, 0x17, 0x15, 0x27, 0x15, 0x31, 0x15, - 0x14, 0x07, 0x06, 0x07, 0x15, 0x33, 0x15, 0x02, 0xa7, 0x7c, 0x90, 0x90, - 0x87, 0x65, 0x7b, 0x01, 0x76, 0x01, 0x77, 0x7d, 0x77, 0x77, 0x02, 0x02, - 0x01, 0x55, 0x41, 0x54, 0x77, 0x01, 0x78, 0x7c, 0x78, 0x78, 0x53, 0x40, - 0x57, 0x01, 0x77, 0x01, 0x78, 0x7d, 0x76, 0x76, 0x7c, 0x64, 0x88, 0x90, - 0x01, 0x1f, 0x9a, 0x9a, 0x7c, 0x72, 0x12, 0x65, 0x7b, 0xb1, 0x45, 0x75, - 0x73, 0x7e, 0x7e, 0x73, 0x75, 0x45, 0x02, 0x7c, 0x56, 0x41, 0x10, 0x02, - 0x4b, 0x74, 0x72, 0x7f, 0x7f, 0x72, 0x74, 0xfd, 0xb6, 0x10, 0x40, 0x58, - 0x7b, 0x01, 0x49, 0x75, 0x73, 0x7e, 0x7e, 0x73, 0x75, 0x49, 0x04, 0xad, - 0x7b, 0x64, 0x13, 0x72, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xd7, - 0x00, 0x2a, 0x03, 0xfa, 0x05, 0xae, 0x00, 0x12, 0x00, 0x1d, 0x00, 0x00, - 0x13, 0x21, 0x20, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x21, 0x11, - 0x21, 0x17, 0x15, 0x07, 0x21, 0x27, 0x11, 0x17, 0x11, 0x21, 0x32, 0x37, - 0x36, 0x37, 0x34, 0x27, 0x26, 0x23, 0xdf, 0x01, 0x81, 0x01, 0x1d, 0x5f, - 0x1e, 0xed, 0x38, 0x32, 0xfe, 0xbd, 0x02, 0x56, 0x08, 0x08, 0xfd, 0x29, - 0x08, 0x89, 0x01, 0x33, 0x7b, 0x44, 0x0f, 0x08, 0x99, 0x23, 0x4d, 0x05, - 0xae, 0xc5, 0x48, 0x5a, 0xfb, 0x57, 0x10, 0xfd, 0xcf, 0x07, 0x7b, 0x08, - 0x08, 0x05, 0x73, 0x7b, 0xfe, 0x3f, 0x7a, 0x19, 0x4b, 0x9b, 0x38, 0x10, - 0x00, 0x01, 0x00, 0x18, 0x00, 0x01, 0x04, 0xb9, 0x05, 0x21, 0x00, 0x20, - 0x00, 0x00, 0x25, 0x10, 0x02, 0x23, 0x22, 0x02, 0x17, 0x23, 0x26, 0x35, - 0x34, 0x36, 0x33, 0x20, 0x13, 0x16, 0x17, 0x36, 0x37, 0x12, 0x21, 0x32, - 0x16, 0x15, 0x14, 0x07, 0x23, 0x36, 0x02, 0x23, 0x22, 0x02, 0x11, 0x02, - 0x3b, 0xcd, 0x7a, 0x5c, 0x29, 0x4d, 0x61, 0x42, 0x75, 0x68, 0x01, 0x0b, - 0x5f, 0x05, 0x04, 0x03, 0x05, 0x5f, 0x01, 0x0b, 0x69, 0x74, 0x42, 0x61, - 0x4d, 0x28, 0x5d, 0x79, 0xcd, 0x02, 0x02, 0x0d, 0x02, 0xa4, 0xfe, 0xe4, - 0x8e, 0x74, 0x8c, 0x74, 0xa4, 0xfd, 0x5b, 0x2b, 0x23, 0x23, 0x2b, 0x02, - 0xa5, 0xa4, 0x74, 0x8c, 0x74, 0x8e, 0x01, 0x1c, 0xfd, 0x5c, 0xfd, 0xf3, - 0x00, 0x02, 0x00, 0x35, 0xff, 0xf8, 0x04, 0x9c, 0x04, 0xc4, 0x00, 0x08, - 0x00, 0x2e, 0x00, 0x00, 0x01, 0x22, 0x06, 0x14, 0x16, 0x32, 0x36, 0x34, - 0x26, 0x27, 0x36, 0x37, 0x3e, 0x02, 0x33, 0x15, 0x22, 0x02, 0x07, 0x06, - 0x07, 0x16, 0x17, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, 0x35, 0x34, - 0x37, 0x36, 0x37, 0x26, 0x27, 0x26, 0x02, 0x23, 0x35, 0x32, 0x1e, 0x01, - 0x17, 0x16, 0x02, 0x68, 0x71, 0x9e, 0x9e, 0xe1, 0x9f, 0x9d, 0x72, 0x64, - 0x3a, 0x42, 0x4a, 0x7c, 0x8d, 0x5e, 0x80, 0x64, 0x10, 0x12, 0x23, 0x21, - 0x70, 0xe2, 0xa1, 0xa0, 0xe2, 0x71, 0x20, 0x24, 0x12, 0x10, 0x63, 0x83, - 0x5d, 0x8d, 0x8f, 0x37, 0x41, 0x3b, 0x02, 0xba, 0xaa, 0xf1, 0xa9, 0xa9, - 0xf1, 0xaa, 0x7b, 0x04, 0x32, 0x36, 0x94, 0x8e, 0x58, 0xff, 0x00, 0x59, - 0x0f, 0x0d, 0x18, 0x22, 0x7a, 0xac, 0xac, 0xf2, 0xf2, 0xac, 0xac, 0x7a, - 0x22, 0x19, 0x0c, 0x0f, 0x59, 0x01, 0x00, 0x58, 0x8e, 0x94, 0x36, 0x32, - 0x00, 0x02, 0x00, 0x1b, 0x00, 0x0c, 0x04, 0xb6, 0x04, 0xce, 0x00, 0x13, - 0x00, 0x19, 0x00, 0x00, 0x01, 0x26, 0x27, 0x35, 0x04, 0x20, 0x25, 0x15, - 0x06, 0x07, 0x11, 0x16, 0x17, 0x15, 0x24, 0x20, 0x05, 0x35, 0x36, 0x3f, - 0x01, 0x36, 0x17, 0x11, 0x06, 0x27, 0x01, 0x2e, 0x88, 0x8b, 0x01, 0x1a, - 0x02, 0x6a, 0x01, 0x17, 0x8f, 0x87, 0x87, 0x8f, 0xfe, 0xe9, 0xfd, 0x96, - 0xfe, 0xe6, 0x8b, 0x88, 0x7c, 0xbd, 0xbd, 0xbd, 0xbd, 0x04, 0x19, 0x12, - 0x2a, 0x78, 0x49, 0x49, 0x7a, 0x27, 0x13, 0xfc, 0xa8, 0x13, 0x26, 0x7c, - 0x4a, 0x4a, 0x78, 0x2c, 0x11, 0x09, 0x15, 0x15, 0x03, 0x46, 0x15, 0x15, - 0x00, 0x04, 0x00, 0x34, 0x00, 0x32, 0x04, 0x9d, 0x05, 0x0f, 0x00, 0x08, - 0x00, 0x1b, 0x00, 0x24, 0x00, 0x38, 0x00, 0x00, 0x00, 0x22, 0x06, 0x14, - 0x16, 0x33, 0x32, 0x36, 0x34, 0x01, 0x2c, 0x01, 0x27, 0x35, 0x16, 0x04, - 0x27, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x10, 0x07, 0x0e, 0x01, - 0x01, 0x32, 0x36, 0x34, 0x26, 0x22, 0x06, 0x14, 0x16, 0x13, 0x0c, 0x01, - 0x17, 0x15, 0x26, 0x24, 0x17, 0x16, 0x15, 0x14, 0x06, 0x23, 0x22, 0x26, - 0x35, 0x34, 0x37, 0x3e, 0x01, 0x03, 0xc8, 0x9c, 0x6d, 0x6d, 0x4e, 0x4d, - 0x6d, 0xfe, 0xa9, 0xff, 0x00, 0xfe, 0xd5, 0x7d, 0xcf, 0x01, 0xc9, 0x09, - 0x6c, 0xa8, 0x79, 0x7a, 0xa9, 0x55, 0x3c, 0xca, 0xfe, 0x16, 0x4d, 0x6e, - 0x6e, 0x9a, 0x6e, 0x6d, 0xea, 0x01, 0x01, 0x01, 0x2b, 0x7d, 0xcf, 0xfe, - 0x37, 0x09, 0x6c, 0xa8, 0x79, 0x7a, 0xa9, 0x55, 0x3c, 0xc9, 0x02, 0x83, - 0x7c, 0xb2, 0x7c, 0x7c, 0xb2, 0xfe, 0x2c, 0x01, 0x26, 0x28, 0x75, 0x4f, - 0x1f, 0x23, 0x65, 0x9c, 0x8a, 0xc2, 0xc2, 0xfe, 0xed, 0x61, 0x48, 0x47, - 0x02, 0x8a, 0x7c, 0xb2, 0x7c, 0x7c, 0xb2, 0x7c, 0x02, 0x51, 0x02, 0x27, - 0x28, 0x73, 0x4f, 0x1e, 0x23, 0x65, 0x9c, 0x8b, 0xc2, 0xc2, 0x8b, 0x89, - 0x60, 0x49, 0x48, 0x00, 0x00, 0x02, 0x00, 0x3d, 0xff, 0xfd, 0x04, 0x94, - 0x05, 0x21, 0x00, 0x0a, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x3e, 0x01, 0x27, - 0x2e, 0x01, 0x07, 0x0e, 0x01, 0x17, 0x16, 0x13, 0x34, 0x36, 0x33, 0x32, - 0x16, 0x15, 0x14, 0x02, 0x15, 0x16, 0x17, 0x32, 0x37, 0x17, 0x06, 0x23, - 0x22, 0x26, 0x35, 0x34, 0x12, 0x35, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, - 0x14, 0x16, 0x17, 0x1e, 0x01, 0x07, 0x06, 0x07, 0x06, 0x26, 0x27, 0x26, - 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x17, 0x36, 0x26, 0x01, 0x44, 0x84, - 0x39, 0x19, 0x1a, 0x82, 0x42, 0x42, 0x38, 0x1a, 0x1a, 0xcd, 0xc4, 0x9e, - 0x97, 0xc0, 0xff, 0x03, 0x76, 0x3f, 0x57, 0x3a, 0x70, 0x62, 0x57, 0x7e, - 0xfc, 0x90, 0x74, 0x70, 0x84, 0x29, 0x16, 0x20, 0x0e, 0x22, 0x2d, 0x66, - 0x66, 0xc9, 0x29, 0x14, 0x18, 0x2d, 0x67, 0x74, 0x70, 0x15, 0x51, 0x01, - 0x40, 0x33, 0x83, 0x41, 0x41, 0x3a, 0x1a, 0x1a, 0x81, 0x41, 0x43, 0x02, - 0x6a, 0x8d, 0xb1, 0xc2, 0x9b, 0xa5, 0xfe, 0x47, 0x9e, 0x6d, 0x03, 0x4e, - 0x3f, 0x69, 0x6a, 0x62, 0xaf, 0x01, 0xa6, 0xab, 0x76, 0x91, 0x88, 0x72, - 0x35, 0x7f, 0x36, 0x57, 0xc0, 0x47, 0x65, 0x28, 0x28, 0x57, 0x69, 0x30, - 0x31, 0x35, 0x34, 0x64, 0x29, 0x2d, 0x3f, 0x01, 0xc3, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x2f, 0xfe, 0xea, 0x04, 0xa2, 0x04, 0x7f, 0x00, 0x36, - 0x00, 0x3f, 0x00, 0x00, 0x01, 0x32, 0x16, 0x15, 0x3e, 0x01, 0x33, 0x32, - 0x16, 0x1d, 0x01, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x15, 0x10, 0x05, 0x14, - 0x17, 0x23, 0x26, 0x27, 0x06, 0x07, 0x35, 0x36, 0x37, 0x27, 0x11, 0x36, - 0x27, 0x0e, 0x01, 0x07, 0x11, 0x23, 0x11, 0x34, 0x26, 0x07, 0x26, 0x06, - 0x07, 0x11, 0x23, 0x11, 0x34, 0x27, 0x33, 0x16, 0x17, 0x3e, 0x01, 0x01, - 0x11, 0x36, 0x13, 0x34, 0x26, 0x07, 0x22, 0x06, 0x01, 0xc1, 0x2d, 0x53, - 0x1d, 0x8b, 0x35, 0x2c, 0x39, 0x22, 0x5c, 0x30, 0x2b, 0x46, 0xfe, 0xf4, - 0x67, 0x76, 0x21, 0x34, 0x75, 0x7c, 0x87, 0x57, 0x06, 0x02, 0x22, 0x29, - 0x5e, 0x2c, 0x6b, 0x16, 0x19, 0x1d, 0x7f, 0x0d, 0x69, 0x6b, 0x64, 0x53, - 0x1a, 0x10, 0x81, 0x01, 0xf2, 0xb6, 0x11, 0x21, 0x15, 0x15, 0x65, 0x04, - 0x7f, 0x98, 0x62, 0x5b, 0x9f, 0x80, 0xa8, 0x9a, 0x5f, 0x5b, 0xb1, 0xd1, - 0xfe, 0xc7, 0xf5, 0x48, 0x94, 0x1f, 0x7c, 0x4e, 0x05, 0x59, 0x15, 0x43, - 0xa6, 0x02, 0x8e, 0xf2, 0x01, 0x01, 0xa6, 0x99, 0xfd, 0x3a, 0x02, 0xc2, - 0xf6, 0x52, 0x01, 0x01, 0xae, 0xa4, 0xfd, 0x48, 0x03, 0x42, 0x92, 0x92, - 0x3d, 0x86, 0x47, 0x90, 0xfd, 0x60, 0xfe, 0x53, 0xbf, 0x01, 0x03, 0x94, - 0x6e, 0x04, 0x9e, 0x00, 0x00, 0x02, 0x00, 0x55, 0x00, 0xb5, 0x04, 0x7c, - 0x04, 0xea, 0x00, 0x03, 0x00, 0x23, 0x00, 0x00, 0x13, 0x21, 0x15, 0x21, - 0x01, 0x21, 0x35, 0x33, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x15, - 0x14, 0x07, 0x21, 0x15, 0x21, 0x35, 0x23, 0x36, 0x37, 0x36, 0x35, 0x34, - 0x26, 0x22, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x55, 0x04, 0x27, 0xfb, - 0xd9, 0x01, 0x8c, 0xfe, 0x74, 0xfc, 0x30, 0xb7, 0x84, 0x84, 0xb8, 0x30, - 0x01, 0x14, 0xfe, 0x5a, 0x01, 0x0d, 0x0c, 0x3d, 0x79, 0xad, 0x79, 0x3d, - 0x0b, 0x0d, 0x01, 0x3a, 0x85, 0x01, 0x5d, 0x86, 0x5a, 0x73, 0xa2, 0xe3, - 0xe3, 0xa2, 0x73, 0x5a, 0x86, 0x86, 0x0b, 0x0f, 0x4a, 0x6a, 0x6b, 0x95, - 0x95, 0x6b, 0x6a, 0x4a, 0x0f, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x32, - 0xff, 0x66, 0x04, 0x9f, 0x04, 0xc6, 0x00, 0x34, 0x00, 0x00, 0x25, 0x14, - 0x16, 0x17, 0x33, 0x35, 0x33, 0x17, 0x07, 0x27, 0x35, 0x23, 0x22, 0x27, - 0x26, 0x27, 0x03, 0x12, 0x27, 0x0e, 0x01, 0x07, 0x11, 0x23, 0x11, 0x10, - 0x26, 0x07, 0x26, 0x06, 0x07, 0x11, 0x23, 0x11, 0x34, 0x27, 0x33, 0x16, - 0x17, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x15, 0x3e, 0x01, 0x33, 0x32, 0x16, - 0x1d, 0x01, 0x11, 0x03, 0x59, 0x45, 0x3b, 0x3c, 0x02, 0x88, 0x88, 0x02, - 0x3c, 0x87, 0x2d, 0x1e, 0x05, 0x0e, 0x02, 0x21, 0x26, 0x59, 0x2a, 0x64, - 0x15, 0x18, 0x1b, 0x78, 0x0d, 0x63, 0x66, 0x5f, 0x4f, 0x18, 0x0f, 0x7a, - 0x2e, 0x2a, 0x4f, 0x1b, 0x84, 0x32, 0x29, 0x37, 0xe2, 0x5a, 0x65, 0x01, - 0x60, 0x8d, 0x8e, 0x03, 0x60, 0x62, 0x3c, 0x60, 0x02, 0x81, 0x01, 0x01, - 0x01, 0x01, 0xb0, 0xa3, 0xfd, 0x0f, 0x02, 0xed, 0x01, 0x05, 0x57, 0x01, - 0x01, 0xb8, 0xaf, 0xfd, 0x1e, 0x03, 0x75, 0x9a, 0x9c, 0x41, 0x8f, 0x4c, - 0x99, 0xa1, 0x68, 0x60, 0xa9, 0x88, 0xb2, 0xa4, 0xfd, 0xfb, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x38, 0x00, 0x06, 0x04, 0x99, 0x04, 0xc7, 0x00, 0x13, - 0x00, 0x00, 0x01, 0x21, 0x35, 0x21, 0x15, 0x31, 0x15, 0x11, 0x23, 0x11, - 0x07, 0x11, 0x23, 0x11, 0x01, 0x27, 0x01, 0x21, 0x35, 0x21, 0x03, 0xd5, - 0xfe, 0x5f, 0x02, 0x64, 0x72, 0xc0, 0x72, 0xfd, 0x95, 0x50, 0x02, 0x6b, - 0xfe, 0x5e, 0x02, 0x13, 0x04, 0x4b, 0x7b, 0x55, 0x01, 0xfd, 0xbe, 0x01, - 0xc7, 0xd1, 0xfd, 0xbe, 0x01, 0xc6, 0xfd, 0x5f, 0x57, 0x02, 0xa1, 0x7b, - 0x00, 0x02, 0x00, 0x15, 0x00, 0x03, 0x04, 0xbc, 0x04, 0xcf, 0x00, 0x27, - 0x00, 0x2f, 0x00, 0x00, 0x01, 0x32, 0x12, 0x37, 0x36, 0x33, 0x32, 0x16, - 0x15, 0x14, 0x06, 0x23, 0x22, 0x27, 0x0e, 0x01, 0x07, 0x23, 0x35, 0x37, - 0x36, 0x13, 0x26, 0x02, 0x23, 0x22, 0x02, 0x17, 0x07, 0x34, 0x02, 0x27, - 0x35, 0x32, 0x16, 0x17, 0x36, 0x37, 0x3e, 0x01, 0x01, 0x16, 0x33, 0x32, - 0x37, 0x26, 0x27, 0x22, 0x02, 0x32, 0x58, 0x43, 0x14, 0x5a, 0x9f, 0x64, - 0x7d, 0x75, 0x75, 0x7f, 0x64, 0x24, 0x67, 0x71, 0x8a, 0x7e, 0x64, 0x56, - 0x29, 0x34, 0x30, 0x1d, 0x84, 0x05, 0x81, 0x74, 0x6c, 0x78, 0x84, 0x21, - 0x26, 0x25, 0x22, 0x64, 0x01, 0x19, 0x4c, 0x6b, 0x84, 0x07, 0x05, 0x83, - 0x7d, 0x04, 0xce, 0xfd, 0x3a, 0x03, 0xb5, 0x9b, 0x55, 0x77, 0x8c, 0x6d, - 0x83, 0xb1, 0x03, 0x61, 0x01, 0x03, 0x01, 0x34, 0x0d, 0x02, 0x88, 0xfe, - 0x73, 0xaa, 0x02, 0xd0, 0x01, 0x97, 0x05, 0x4f, 0xb6, 0xe2, 0xa5, 0x48, - 0x4b, 0x7b, 0xfc, 0xd7, 0x77, 0xa2, 0x81, 0x0f, 0x00, 0x02, 0x00, 0x59, - 0x01, 0x40, 0x04, 0x78, 0x03, 0xae, 0x00, 0x20, 0x00, 0x41, 0x00, 0x00, - 0x13, 0x36, 0x33, 0x32, 0x17, 0x16, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x37, 0x36, 0x33, 0x32, 0x17, 0x07, 0x26, 0x07, 0x06, 0x22, 0x27, 0x26, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x06, 0x23, 0x27, 0x11, 0x36, 0x33, - 0x32, 0x17, 0x16, 0x37, 0x36, 0x32, 0x17, 0x16, 0x37, 0x36, 0x33, 0x32, - 0x17, 0x07, 0x26, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x07, 0x06, 0x23, - 0x22, 0x27, 0x26, 0x06, 0x23, 0x27, 0x59, 0xe7, 0x52, 0x20, 0x09, 0x23, - 0x7b, 0x3d, 0x28, 0x27, 0x11, 0x25, 0x7b, 0x1f, 0x1d, 0x58, 0x4e, 0x43, - 0x45, 0x7a, 0x3e, 0x4f, 0x12, 0x26, 0x7a, 0x3e, 0x27, 0x28, 0x11, 0x23, - 0xf3, 0x04, 0x26, 0xe7, 0x52, 0x1f, 0x0a, 0x23, 0x7b, 0x3d, 0x4f, 0x10, - 0x26, 0x7b, 0x1e, 0x1d, 0x59, 0x4e, 0x43, 0x45, 0x7a, 0x3e, 0x27, 0x28, - 0x13, 0x25, 0x7b, 0x3d, 0x28, 0x27, 0x11, 0x23, 0xf3, 0x04, 0x26, 0x01, - 0x88, 0xc0, 0x1c, 0x65, 0x65, 0x32, 0x32, 0x65, 0x65, 0x19, 0xe0, 0x24, - 0xc9, 0x6c, 0x36, 0x36, 0x6b, 0x64, 0x32, 0x33, 0x64, 0xc9, 0x45, 0x01, - 0x50, 0xc0, 0x1c, 0x64, 0x64, 0x33, 0x33, 0x64, 0x64, 0x19, 0xe0, 0x24, - 0xca, 0x6c, 0x37, 0x36, 0x6b, 0x64, 0x33, 0x34, 0x65, 0xca, 0x45, 0x00, - 0x00, 0x01, 0x00, 0x5e, 0x00, 0x05, 0x04, 0x73, 0x05, 0x23, 0x00, 0x1c, - 0x00, 0x00, 0x01, 0x07, 0x02, 0x03, 0x07, 0x00, 0x13, 0x21, 0x35, 0x21, - 0x02, 0x01, 0x17, 0x12, 0x13, 0x33, 0x12, 0x13, 0x37, 0x00, 0x03, 0x21, - 0x07, 0x21, 0x12, 0x01, 0x27, 0x02, 0x03, 0x02, 0xd2, 0xd3, 0x1c, 0xf3, - 0x91, 0x01, 0x0d, 0x18, 0xfe, 0xfd, 0x01, 0x03, 0x19, 0xfe, 0xf4, 0x91, - 0xf3, 0x1c, 0xd4, 0x1b, 0xf4, 0x90, 0xfe, 0xf4, 0x18, 0x01, 0x02, 0x01, - 0xfe, 0xfd, 0x1a, 0x01, 0x0c, 0x91, 0xf4, 0x1b, 0x02, 0x4c, 0x03, 0xfe, - 0xd8, 0xfe, 0xe7, 0x02, 0x01, 0x33, 0x01, 0x10, 0x97, 0x01, 0x0f, 0x01, - 0x34, 0x03, 0xfe, 0xe8, 0xfe, 0xd8, 0x01, 0x28, 0x01, 0x18, 0x03, 0xfe, - 0xcc, 0xfe, 0xf1, 0x97, 0xfe, 0xf0, 0xfe, 0xcd, 0x02, 0x01, 0x19, 0x01, - 0x28, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x43, 0x00, 0x05, 0x04, 0x8e, - 0x04, 0x80, 0x00, 0x0f, 0x00, 0x20, 0x00, 0x24, 0x00, 0x54, 0x00, 0x64, - 0x00, 0x00, 0x01, 0x36, 0x37, 0x26, 0x27, 0x26, 0x22, 0x0e, 0x01, 0x15, - 0x14, 0x16, 0x17, 0x16, 0x17, 0x21, 0x33, 0x21, 0x36, 0x37, 0x3e, 0x01, - 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x07, 0x06, 0x07, 0x16, 0x17, 0x01, - 0x15, 0x21, 0x35, 0x01, 0x11, 0x26, 0x27, 0x2e, 0x01, 0x35, 0x34, 0x3e, - 0x01, 0x33, 0x32, 0x17, 0x35, 0x34, 0x36, 0x37, 0x36, 0x37, 0x35, 0x23, - 0x35, 0x33, 0x35, 0x33, 0x15, 0x33, 0x15, 0x23, 0x15, 0x16, 0x17, 0x1e, - 0x01, 0x1d, 0x01, 0x36, 0x33, 0x32, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x07, - 0x06, 0x07, 0x11, 0x01, 0x14, 0x1e, 0x01, 0x33, 0x32, 0x3e, 0x01, 0x35, - 0x34, 0x2e, 0x01, 0x23, 0x22, 0x0e, 0x01, 0x02, 0x33, 0x01, 0x01, 0x1b, - 0x27, 0x38, 0x78, 0x70, 0x41, 0x3f, 0x39, 0x11, 0x11, 0x01, 0x07, 0x6c, - 0x01, 0x06, 0x12, 0x11, 0x39, 0x3e, 0x40, 0x71, 0x3c, 0x3b, 0x39, 0x27, - 0x1a, 0x01, 0x01, 0xfe, 0xa8, 0x02, 0x44, 0xfd, 0x7d, 0x20, 0x1d, 0x35, - 0x52, 0x54, 0x97, 0x50, 0x3d, 0x3a, 0x1c, 0x18, 0x0a, 0x0d, 0x53, 0x53, - 0x50, 0x53, 0x53, 0x0c, 0x0a, 0x18, 0x1c, 0x3b, 0x3c, 0x50, 0x97, 0x54, - 0x52, 0x34, 0x1e, 0x20, 0xfe, 0x58, 0x13, 0x23, 0x11, 0x13, 0x22, 0x13, - 0x13, 0x22, 0x13, 0x11, 0x23, 0x13, 0x02, 0xea, 0x03, 0x02, 0x21, 0x15, - 0x20, 0x3e, 0x72, 0x3e, 0x3e, 0x70, 0x1e, 0x0b, 0x06, 0x06, 0x0b, 0x1e, - 0x70, 0x3e, 0x3e, 0x72, 0x3e, 0x20, 0x15, 0x21, 0x02, 0x03, 0xfe, 0x41, - 0xe8, 0xe8, 0xfe, 0xdb, 0x01, 0x25, 0x0a, 0x11, 0x29, 0x96, 0x52, 0x53, - 0x97, 0x51, 0x18, 0x02, 0x1b, 0x31, 0x0d, 0x06, 0x03, 0x29, 0x36, 0x42, - 0x42, 0x36, 0x29, 0x03, 0x06, 0x0d, 0x31, 0x1b, 0x02, 0x18, 0x51, 0x97, - 0x53, 0x52, 0x96, 0x29, 0x11, 0x0a, 0xfe, 0xdb, 0x03, 0x70, 0x14, 0x20, - 0x14, 0x14, 0x20, 0x14, 0x12, 0x22, 0x12, 0x12, 0x22, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x00, 0x56, 0x00, 0x00, 0x04, 0x7b, 0x04, 0x7a, 0x00, 0x48, - 0x00, 0x4e, 0x00, 0x52, 0x00, 0x68, 0x00, 0x7c, 0x00, 0x90, 0x00, 0xa5, - 0x00, 0xbb, 0x00, 0x00, 0x13, 0x26, 0x27, 0x34, 0x3e, 0x01, 0x33, 0x32, - 0x1e, 0x01, 0x15, 0x06, 0x07, 0x13, 0x03, 0x22, 0x27, 0x34, 0x3e, 0x01, - 0x33, 0x32, 0x1e, 0x01, 0x15, 0x06, 0x07, 0x1b, 0x01, 0x26, 0x27, 0x34, - 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x15, 0x06, 0x07, 0x1b, 0x01, 0x26, - 0x35, 0x34, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x15, 0x06, 0x07, 0x03, - 0x13, 0x26, 0x35, 0x34, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x15, 0x06, - 0x23, 0x03, 0x11, 0x21, 0x11, 0x05, 0x35, 0x07, 0x21, 0x27, 0x1d, 0x02, - 0x21, 0x35, 0x01, 0x17, 0x03, 0x36, 0x37, 0x3e, 0x01, 0x35, 0x34, 0x2e, - 0x01, 0x23, 0x22, 0x0e, 0x01, 0x15, 0x14, 0x1e, 0x01, 0x33, 0x32, 0x33, - 0x13, 0x17, 0x03, 0x36, 0x37, 0x3e, 0x01, 0x34, 0x2e, 0x01, 0x23, 0x22, - 0x0e, 0x01, 0x14, 0x1e, 0x01, 0x33, 0x32, 0x33, 0x01, 0x37, 0x13, 0x16, - 0x33, 0x32, 0x3e, 0x01, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x0e, 0x01, 0x14, - 0x16, 0x17, 0x16, 0x17, 0x01, 0x33, 0x03, 0x32, 0x37, 0x3e, 0x01, 0x35, - 0x34, 0x2e, 0x01, 0x23, 0x22, 0x0e, 0x01, 0x15, 0x14, 0x16, 0x17, 0x16, - 0x17, 0x13, 0x37, 0x13, 0x16, 0x33, 0x32, 0x3e, 0x01, 0x35, 0x34, 0x2e, - 0x01, 0x23, 0x22, 0x0e, 0x01, 0x15, 0x14, 0x16, 0x17, 0x16, 0x17, 0xa9, - 0x49, 0x09, 0x16, 0x29, 0x16, 0x16, 0x29, 0x16, 0x03, 0x2c, 0xb7, 0x28, - 0x3f, 0x0e, 0x16, 0x29, 0x17, 0x16, 0x28, 0x17, 0x02, 0x23, 0x90, 0x21, - 0x33, 0x01, 0x17, 0x28, 0x15, 0x16, 0x29, 0x17, 0x03, 0x33, 0x1d, 0x8e, - 0x24, 0x17, 0x29, 0x15, 0x17, 0x29, 0x16, 0x08, 0x42, 0x47, 0xc5, 0x21, - 0x17, 0x28, 0x16, 0x17, 0x28, 0x16, 0x0a, 0x4b, 0x7b, 0xfd, 0x6d, 0x02, - 0x67, 0x8a, 0xfe, 0xea, 0x8c, 0x02, 0x2c, 0xfd, 0xb4, 0x3b, 0xb1, 0x05, - 0x05, 0x0e, 0x10, 0x10, 0x1b, 0x0f, 0x0e, 0x1a, 0x11, 0x10, 0x1b, 0x0e, - 0x06, 0x06, 0xee, 0x68, 0x8f, 0x04, 0x04, 0x0d, 0x0f, 0x0f, 0x1b, 0x0e, - 0x0f, 0x1b, 0x0f, 0x0f, 0x1b, 0x0f, 0x05, 0x06, 0x01, 0x49, 0x58, 0x49, - 0x04, 0x04, 0x0e, 0x1d, 0x0e, 0x10, 0x1b, 0x0e, 0x0e, 0x1b, 0x10, 0x10, - 0x0d, 0x06, 0x06, 0xfe, 0xee, 0x4c, 0x24, 0x0e, 0x0c, 0x0d, 0x10, 0x10, - 0x1a, 0x0f, 0x0e, 0x1c, 0x0f, 0x0f, 0x0e, 0x0b, 0x0c, 0xe3, 0x50, 0x7f, - 0x08, 0x09, 0x0e, 0x1b, 0x0f, 0x10, 0x1a, 0x0e, 0x10, 0x1a, 0x0f, 0x0f, - 0x0d, 0x03, 0x03, 0x03, 0x0c, 0x02, 0x48, 0x16, 0x27, 0x15, 0x15, 0x27, - 0x16, 0x31, 0x10, 0xfe, 0x7c, 0x02, 0x1a, 0x47, 0x15, 0x27, 0x15, 0x15, - 0x27, 0x15, 0x23, 0x1a, 0xfd, 0xc4, 0x02, 0x73, 0x17, 0x25, 0x16, 0x27, - 0x14, 0x14, 0x27, 0x16, 0x29, 0x13, 0xfd, 0x8b, 0x02, 0x37, 0x24, 0x20, - 0x15, 0x27, 0x15, 0x15, 0x27, 0x15, 0x41, 0x0c, 0xfd, 0xec, 0x01, 0x8a, - 0x1b, 0x20, 0x16, 0x27, 0x15, 0x15, 0x27, 0x16, 0x48, 0xfe, 0x9e, 0xfe, - 0x54, 0x01, 0xac, 0xdd, 0xac, 0x39, 0x2e, 0xa1, 0x25, 0x7e, 0x7e, 0x01, - 0x04, 0x20, 0x01, 0x93, 0x02, 0x03, 0x08, 0x1b, 0x0e, 0x10, 0x1a, 0x10, - 0x10, 0x1a, 0x10, 0x0e, 0x1b, 0x0f, 0xfe, 0x72, 0x18, 0x02, 0x46, 0x02, - 0x02, 0x08, 0x1b, 0x1d, 0x1b, 0x0f, 0x0f, 0x1b, 0x1d, 0x1b, 0x0f, 0xfd, - 0xc3, 0x14, 0x02, 0x29, 0x01, 0x0f, 0x1b, 0x1d, 0x1c, 0x0e, 0x0e, 0x1c, - 0x1d, 0x1b, 0x08, 0x03, 0x02, 0xfd, 0xbc, 0x02, 0x7e, 0x08, 0x08, 0x1a, - 0x10, 0x0e, 0x1b, 0x0f, 0x0f, 0x1b, 0x0e, 0x10, 0x1a, 0x08, 0x06, 0x02, - 0xfd, 0x97, 0x20, 0x01, 0x77, 0x02, 0x10, 0x1a, 0x10, 0x0e, 0x1c, 0x0e, - 0x0e, 0x1c, 0x0e, 0x10, 0x1a, 0x08, 0x02, 0x01, 0x00, 0x05, 0x00, 0x70, - 0x00, 0x00, 0x04, 0x61, 0x05, 0x1d, 0x00, 0x1d, 0x00, 0x21, 0x00, 0x27, - 0x00, 0x2d, 0x00, 0x32, 0x00, 0x00, 0x01, 0x33, 0x15, 0x33, 0x35, 0x33, - 0x15, 0x23, 0x15, 0x07, 0x11, 0x17, 0x15, 0x33, 0x15, 0x21, 0x35, 0x33, - 0x35, 0x37, 0x33, 0x11, 0x23, 0x27, 0x35, 0x23, 0x35, 0x33, 0x15, 0x33, - 0x01, 0x35, 0x21, 0x15, 0x01, 0x37, 0x35, 0x21, 0x15, 0x17, 0x11, 0x07, - 0x15, 0x21, 0x35, 0x27, 0x35, 0x11, 0x37, 0x21, 0x11, 0x01, 0xed, 0xf2, - 0x96, 0xec, 0x65, 0x50, 0x50, 0x65, 0xfc, 0x0f, 0x65, 0x51, 0x01, 0x01, - 0x51, 0x65, 0xe8, 0x95, 0x02, 0x44, 0xfc, 0x70, 0x02, 0xe1, 0x48, 0xfd, - 0x3e, 0x48, 0x40, 0x02, 0xb2, 0x41, 0x01, 0xfd, 0xce, 0x05, 0x1d, 0x88, - 0x88, 0x8e, 0x7e, 0x83, 0xfe, 0x00, 0x82, 0x7d, 0x8f, 0x8f, 0x7d, 0x85, - 0x01, 0xfc, 0x84, 0x7e, 0x8e, 0x88, 0xfb, 0x9c, 0x30, 0x30, 0x03, 0x6d, - 0x72, 0x54, 0x54, 0x72, 0xfd, 0xc7, 0x65, 0x70, 0x70, 0x65, 0x2d, 0x01, - 0xdd, 0x02, 0xfe, 0x21, 0x00, 0x04, 0x00, 0xde, 0xff, 0xf8, 0x03, 0xf3, - 0x04, 0xc5, 0x00, 0x37, 0x00, 0x43, 0x00, 0x51, 0x00, 0x5e, 0x00, 0x00, - 0x01, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x26, 0x27, 0x26, 0x27, 0x35, - 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x26, 0x27, 0x26, 0x35, 0x34, 0x3e, - 0x01, 0x33, 0x32, 0x1e, 0x01, 0x15, 0x14, 0x07, 0x06, 0x07, 0x16, 0x17, - 0x16, 0x17, 0x16, 0x17, 0x15, 0x06, 0x07, 0x06, 0x07, 0x16, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x06, 0x07, 0x13, 0x21, 0x1b, 0x01, 0x35, 0x33, 0x35, - 0x23, 0x35, 0x23, 0x15, 0x23, 0x15, 0x33, 0x15, 0x13, 0x36, 0x35, 0x34, - 0x2e, 0x01, 0x22, 0x0e, 0x01, 0x15, 0x14, 0x17, 0x03, 0x21, 0x00, 0x14, - 0x1e, 0x01, 0x32, 0x3e, 0x01, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x01, - 0xc2, 0x19, 0x1a, 0x06, 0x09, 0x31, 0x1d, 0x22, 0x01, 0x01, 0x22, 0x23, - 0x40, 0x17, 0x18, 0x15, 0x0e, 0x12, 0x25, 0x40, 0x23, 0x21, 0x40, 0x25, - 0x11, 0x0d, 0x16, 0x17, 0x18, 0x3f, 0x24, 0x23, 0x01, 0x01, 0x23, 0x1e, - 0x30, 0x09, 0x07, 0x19, 0x1a, 0x01, 0x02, 0xe7, 0xfc, 0xed, 0xde, 0xdc, - 0x8d, 0x8d, 0x61, 0x8d, 0x8d, 0x85, 0x31, 0x25, 0x3f, 0x45, 0x3f, 0x25, - 0x34, 0xb6, 0x02, 0x15, 0xfe, 0x99, 0x18, 0x2c, 0x2f, 0x2d, 0x17, 0x18, - 0x2d, 0x16, 0x18, 0x2b, 0x01, 0x44, 0x2c, 0x2f, 0x31, 0x2b, 0x0e, 0x0c, - 0x1f, 0x34, 0x3b, 0x41, 0x03, 0x42, 0x3c, 0x3e, 0x22, 0x0b, 0x09, 0x0e, - 0x18, 0x20, 0x22, 0x23, 0x3e, 0x22, 0x22, 0x3e, 0x23, 0x22, 0x20, 0x18, - 0x0f, 0x08, 0x0b, 0x22, 0x3e, 0x3c, 0x42, 0x03, 0x41, 0x3b, 0x33, 0x20, - 0x0c, 0x0e, 0x2b, 0x31, 0x30, 0x2c, 0x03, 0x03, 0xfe, 0xbc, 0x01, 0x4b, - 0x01, 0x12, 0x66, 0x59, 0x65, 0x65, 0x59, 0x66, 0xfe, 0xee, 0x25, 0x3c, - 0x23, 0x40, 0x22, 0x22, 0x40, 0x23, 0x34, 0x2d, 0xfe, 0xe9, 0x04, 0x2f, - 0x30, 0x2b, 0x17, 0x17, 0x2b, 0x30, 0x2b, 0x17, 0x17, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x90, 0x00, 0x06, 0x04, 0x41, 0x04, 0xc7, 0x00, 0x1e, - 0x00, 0x2a, 0x00, 0x33, 0x00, 0x56, 0x00, 0x00, 0x01, 0x36, 0x26, 0x37, - 0x16, 0x07, 0x00, 0x13, 0x21, 0x26, 0x35, 0x34, 0x24, 0x27, 0x06, 0x07, - 0x06, 0x07, 0x27, 0x07, 0x26, 0x27, 0x36, 0x27, 0x36, 0x37, 0x2e, 0x01, - 0x37, 0x16, 0x17, 0x07, 0x36, 0x3b, 0x01, 0x06, 0x15, 0x14, 0x2b, 0x01, - 0x22, 0x27, 0x35, 0x03, 0x17, 0x14, 0x07, 0x23, 0x22, 0x3d, 0x01, 0x36, - 0x13, 0x26, 0x27, 0x06, 0x16, 0x07, 0x06, 0x07, 0x16, 0x07, 0x16, 0x17, - 0x37, 0x07, 0x36, 0x37, 0x36, 0x37, 0x16, 0x04, 0x17, 0x14, 0x17, 0x25, - 0x02, 0x01, 0x32, 0x35, 0x23, 0x36, 0x26, 0x27, 0x06, 0x16, 0x07, 0x02, - 0x07, 0x0b, 0x2a, 0x49, 0x7d, 0x20, 0x01, 0x8e, 0x25, 0xfc, 0xeb, 0x0a, - 0x01, 0x47, 0x07, 0x49, 0x2e, 0x25, 0x80, 0x08, 0x23, 0x71, 0x1a, 0x4a, - 0x0c, 0x27, 0x3b, 0x11, 0x0a, 0x1f, 0x54, 0x2c, 0x84, 0x1f, 0x4e, 0x04, - 0x23, 0x38, 0x11, 0x06, 0x03, 0x05, 0x05, 0x3a, 0x08, 0x17, 0x21, 0xb0, - 0x1d, 0x3e, 0x23, 0x31, 0x14, 0x30, 0x24, 0x11, 0x49, 0x14, 0x54, 0x4e, - 0x1c, 0x6e, 0x17, 0x56, 0x42, 0x2c, 0xfe, 0xa5, 0x02, 0x09, 0x02, 0xc7, - 0x1f, 0xfe, 0x6e, 0x01, 0x03, 0x20, 0x11, 0x3f, 0x25, 0x23, 0x0f, 0x04, - 0x03, 0x14, 0x4e, 0x61, 0x6a, 0x69, 0xfe, 0xf9, 0xfd, 0x1b, 0x2d, 0x2f, - 0x82, 0xf6, 0x34, 0x5e, 0x02, 0x74, 0x0e, 0x12, 0x19, 0x26, 0x41, 0xea, - 0xab, 0x59, 0x63, 0x1a, 0x1b, 0x67, 0x15, 0x62, 0xe1, 0x33, 0x25, 0x1d, - 0x27, 0x18, 0x0c, 0xfe, 0xbb, 0x1c, 0x2b, 0x0c, 0x19, 0x12, 0x28, 0x02, - 0x28, 0x4e, 0x1f, 0x56, 0x38, 0x1b, 0x4f, 0x51, 0xc4, 0xbf, 0x3e, 0x13, - 0x3a, 0x3c, 0x08, 0x75, 0x03, 0x8d, 0x79, 0xfa, 0x67, 0x2a, 0x2a, 0x01, - 0x02, 0x9c, 0x01, 0x35, 0x01, 0x0a, 0x6b, 0x3c, 0x58, 0x3e, 0x1b, 0x00, - 0x00, 0x04, 0x00, 0x9c, 0x00, 0x06, 0x04, 0x35, 0x04, 0x68, 0x00, 0x0d, - 0x00, 0x1d, 0x00, 0x50, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x14, 0x1e, 0x01, - 0x33, 0x32, 0x3e, 0x01, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x37, 0x14, - 0x1e, 0x01, 0x33, 0x32, 0x3e, 0x01, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, - 0x0e, 0x01, 0x01, 0x15, 0x21, 0x35, 0x07, 0x26, 0x35, 0x34, 0x36, 0x37, - 0x36, 0x37, 0x26, 0x27, 0x26, 0x35, 0x34, 0x36, 0x37, 0x36, 0x37, 0x26, - 0x27, 0x26, 0x34, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x14, 0x07, 0x06, - 0x07, 0x16, 0x17, 0x1e, 0x01, 0x15, 0x14, 0x07, 0x06, 0x07, 0x16, 0x17, - 0x1e, 0x01, 0x15, 0x14, 0x07, 0x27, 0x26, 0x27, 0x2e, 0x01, 0x23, 0x22, - 0x06, 0x07, 0x06, 0x07, 0x01, 0xc8, 0x2b, 0x4c, 0x29, 0x2b, 0x4c, 0x2a, - 0x2b, 0x4d, 0x29, 0x28, 0x4c, 0x48, 0x0c, 0x15, 0x0b, 0x0c, 0x15, 0x0c, - 0x0c, 0x16, 0x0b, 0x0a, 0x16, 0x0c, 0x01, 0xc4, 0xfc, 0xe3, 0x3e, 0x09, - 0x7c, 0x6e, 0x1c, 0x1e, 0x16, 0x10, 0x20, 0x40, 0x3a, 0x14, 0x16, 0x14, - 0x0b, 0x11, 0x21, 0x3a, 0x1f, 0x1e, 0x3b, 0x21, 0x0f, 0x0d, 0x13, 0x14, - 0x17, 0x38, 0x41, 0x1f, 0x11, 0x16, 0x1c, 0x1d, 0x6e, 0x7d, 0x09, 0x45, - 0x03, 0x30, 0x34, 0xb8, 0x60, 0x61, 0xb7, 0x33, 0x30, 0x03, 0x02, 0xd8, - 0x54, 0x4c, 0x2a, 0x2a, 0x4c, 0x54, 0x4d, 0x28, 0x28, 0xca, 0x0c, 0x14, - 0x0b, 0x0b, 0x14, 0x0c, 0x0b, 0x16, 0x0c, 0x0c, 0x16, 0xfc, 0x0d, 0x01, - 0x01, 0x01, 0x2b, 0x2b, 0x78, 0xdc, 0x3a, 0x10, 0x0c, 0x15, 0x1d, 0x38, - 0x3e, 0x3e, 0x71, 0x1f, 0x0b, 0x07, 0x0f, 0x15, 0x1e, 0x3f, 0x39, 0x20, - 0x20, 0x39, 0x3f, 0x1e, 0x15, 0x0f, 0x07, 0x0b, 0x1f, 0x71, 0x3e, 0x3e, - 0x38, 0x1d, 0x15, 0x0c, 0x10, 0x3a, 0xdc, 0x78, 0x2b, 0x2b, 0x63, 0x5e, - 0x55, 0x5a, 0x62, 0x62, 0x5a, 0x55, 0x5e, 0x00, 0x00, 0x08, 0x00, 0x6a, - 0xff, 0xfc, 0x04, 0x67, 0x04, 0x25, 0x00, 0x0f, 0x00, 0x20, 0x00, 0x24, - 0x00, 0x54, 0x00, 0x64, 0x00, 0x68, 0x00, 0x79, 0x00, 0x8a, 0x00, 0x00, - 0x01, 0x34, 0x37, 0x26, 0x27, 0x26, 0x22, 0x0e, 0x01, 0x15, 0x14, 0x16, - 0x17, 0x16, 0x17, 0x3b, 0x02, 0x36, 0x37, 0x3e, 0x01, 0x35, 0x34, 0x2e, - 0x01, 0x23, 0x22, 0x07, 0x06, 0x07, 0x16, 0x17, 0x01, 0x15, 0x21, 0x35, - 0x01, 0x11, 0x26, 0x27, 0x2e, 0x01, 0x35, 0x34, 0x3e, 0x01, 0x33, 0x32, - 0x17, 0x35, 0x34, 0x36, 0x37, 0x36, 0x37, 0x35, 0x23, 0x35, 0x33, 0x35, - 0x33, 0x15, 0x33, 0x15, 0x23, 0x15, 0x16, 0x17, 0x1e, 0x01, 0x1d, 0x01, - 0x36, 0x33, 0x32, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x07, 0x06, 0x07, 0x11, - 0x01, 0x14, 0x1e, 0x01, 0x33, 0x32, 0x3e, 0x01, 0x35, 0x34, 0x2e, 0x01, - 0x23, 0x22, 0x0e, 0x01, 0x01, 0x15, 0x21, 0x35, 0x37, 0x23, 0x26, 0x27, - 0x2e, 0x01, 0x35, 0x34, 0x3e, 0x01, 0x33, 0x32, 0x17, 0x16, 0x17, 0x06, - 0x15, 0x33, 0x34, 0x27, 0x36, 0x37, 0x36, 0x33, 0x32, 0x1e, 0x01, 0x15, - 0x14, 0x06, 0x07, 0x06, 0x07, 0x23, 0x02, 0x37, 0x02, 0x19, 0x24, 0x35, - 0x6f, 0x68, 0x3c, 0x3a, 0x35, 0x10, 0x10, 0xf4, 0x64, 0xf3, 0x11, 0x10, - 0x34, 0x3a, 0x3b, 0x69, 0x38, 0x36, 0x35, 0x25, 0x18, 0x01, 0x01, 0xfe, - 0xc1, 0x02, 0x1a, 0xfd, 0xab, 0x1d, 0x1b, 0x31, 0x4d, 0x4e, 0x8d, 0x4a, - 0x39, 0x36, 0x19, 0x17, 0x09, 0x0c, 0x4d, 0x4d, 0x4a, 0x4d, 0x4d, 0x0c, - 0x09, 0x16, 0x1a, 0x36, 0x38, 0x4a, 0x8d, 0x4e, 0x4d, 0x30, 0x1c, 0x1d, - 0xfe, 0x76, 0x12, 0x20, 0x10, 0x12, 0x20, 0x11, 0x11, 0x20, 0x12, 0x10, - 0x20, 0x12, 0x01, 0x2b, 0xfe, 0x30, 0x92, 0xc7, 0x0d, 0x0c, 0x2b, 0x2f, - 0x30, 0x55, 0x2d, 0x2c, 0x2c, 0x1d, 0x15, 0x02, 0xac, 0x02, 0x15, 0x1d, - 0x2b, 0x2c, 0x2e, 0x54, 0x31, 0x2f, 0x2c, 0x0c, 0x0d, 0xc6, 0x02, 0xac, - 0x02, 0x03, 0x1e, 0x14, 0x1d, 0x39, 0x6a, 0x39, 0x3a, 0x68, 0x1c, 0x0a, - 0x06, 0x06, 0x0a, 0x1c, 0x68, 0x3a, 0x39, 0x6a, 0x39, 0x1d, 0x14, 0x1e, - 0x03, 0x02, 0xfe, 0x61, 0xd7, 0xd7, 0xfe, 0xf0, 0x01, 0x10, 0x09, 0x10, - 0x26, 0x8c, 0x4c, 0x4d, 0x8c, 0x4b, 0x16, 0x01, 0x1a, 0x2d, 0x0d, 0x05, - 0x02, 0x27, 0x32, 0x3d, 0x3d, 0x32, 0x27, 0x02, 0x05, 0x0d, 0x2d, 0x1a, - 0x01, 0x16, 0x4b, 0x8c, 0x4d, 0x4c, 0x8c, 0x26, 0x10, 0x09, 0xfe, 0xf0, - 0x03, 0x31, 0x12, 0x1f, 0x11, 0x11, 0x1f, 0x12, 0x11, 0x20, 0x10, 0x10, - 0x20, 0xfd, 0xa9, 0x8e, 0x8e, 0x93, 0x05, 0x08, 0x18, 0x56, 0x2f, 0x2f, - 0x58, 0x2f, 0x17, 0x11, 0x19, 0x02, 0x02, 0x02, 0x02, 0x19, 0x11, 0x17, - 0x2f, 0x58, 0x2f, 0x2f, 0x56, 0x18, 0x08, 0x05, 0x00, 0x03, 0x00, 0x36, - 0x00, 0x04, 0x04, 0x9b, 0x04, 0xc5, 0x00, 0x48, 0x00, 0x4c, 0x00, 0x50, - 0x00, 0x00, 0x13, 0x26, 0x27, 0x34, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, - 0x15, 0x06, 0x07, 0x13, 0x03, 0x22, 0x27, 0x34, 0x3e, 0x01, 0x33, 0x32, - 0x1e, 0x01, 0x15, 0x06, 0x07, 0x1b, 0x01, 0x26, 0x27, 0x34, 0x3e, 0x01, - 0x33, 0x32, 0x1e, 0x01, 0x15, 0x06, 0x07, 0x1b, 0x01, 0x26, 0x35, 0x34, - 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x15, 0x06, 0x07, 0x03, 0x13, 0x26, - 0x35, 0x34, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x15, 0x06, 0x23, 0x03, - 0x11, 0x21, 0x11, 0x05, 0x35, 0x21, 0x15, 0x05, 0x35, 0x21, 0x15, 0x8d, - 0x4d, 0x0a, 0x18, 0x2c, 0x17, 0x17, 0x2c, 0x17, 0x04, 0x2e, 0xc2, 0x2a, - 0x43, 0x0f, 0x17, 0x2c, 0x19, 0x17, 0x2b, 0x17, 0x02, 0x25, 0x9a, 0x23, - 0x37, 0x01, 0x18, 0x2b, 0x16, 0x17, 0x2c, 0x18, 0x02, 0x37, 0x1f, 0x96, - 0x25, 0x17, 0x2c, 0x16, 0x19, 0x2b, 0x18, 0x09, 0x46, 0x4b, 0xd1, 0x23, - 0x18, 0x2b, 0x17, 0x18, 0x2b, 0x18, 0x0b, 0x50, 0x82, 0xfd, 0x44, 0x02, - 0x8d, 0xfd, 0xb2, 0x02, 0x4e, 0xfd, 0xb2, 0x03, 0x41, 0x01, 0x4d, 0x17, - 0x2a, 0x16, 0x16, 0x2a, 0x17, 0x34, 0x11, 0xfe, 0x64, 0x02, 0x3b, 0x4b, - 0x17, 0x29, 0x16, 0x16, 0x29, 0x17, 0x24, 0x1c, 0xfd, 0xa0, 0x02, 0x9b, - 0x18, 0x27, 0x17, 0x2a, 0x15, 0x15, 0x2a, 0x17, 0x2c, 0x13, 0xfd, 0x64, - 0x02, 0x59, 0x26, 0x22, 0x16, 0x2a, 0x16, 0x16, 0x2a, 0x16, 0x45, 0x0d, - 0xfd, 0xcc, 0x01, 0xa3, 0x1b, 0x23, 0x17, 0x2a, 0x16, 0x16, 0x2a, 0x17, - 0x4c, 0xfe, 0x88, 0xfe, 0x3a, 0x01, 0xc6, 0xa5, 0x3f, 0x3f, 0xf2, 0x40, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x94, 0x00, 0x05, 0x04, 0x3d, - 0x04, 0xc5, 0x00, 0x03, 0x00, 0x07, 0x00, 0x25, 0x00, 0x29, 0x00, 0x00, - 0x01, 0x35, 0x21, 0x15, 0x01, 0x35, 0x21, 0x15, 0x13, 0x33, 0x15, 0x33, - 0x35, 0x33, 0x15, 0x23, 0x15, 0x07, 0x11, 0x17, 0x15, 0x33, 0x15, 0x21, - 0x35, 0x33, 0x35, 0x37, 0x33, 0x11, 0x23, 0x27, 0x35, 0x23, 0x35, 0x33, - 0x15, 0x33, 0x01, 0x35, 0x21, 0x15, 0x03, 0x6d, 0xfd, 0xf8, 0x02, 0x44, - 0xfd, 0x80, 0xcd, 0xe1, 0x8b, 0xdb, 0x5e, 0x4a, 0x4a, 0x5e, 0xfc, 0x57, - 0x5e, 0x4b, 0x01, 0x01, 0x4b, 0x5e, 0xd7, 0x8b, 0x02, 0x1a, 0xfc, 0xb2, - 0x03, 0xb2, 0x4c, 0x4c, 0xfc, 0xe6, 0x5a, 0x5a, 0x04, 0x2c, 0x7d, 0x7d, - 0x83, 0x75, 0x7a, 0xfe, 0x25, 0x79, 0x75, 0x84, 0x84, 0x75, 0x7b, 0x01, - 0xd8, 0x7b, 0x75, 0x83, 0x7d, 0xfb, 0xeb, 0x2d, 0x2d, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0xe2, 0x00, 0x06, 0x03, 0xef, 0x04, 0xc7, 0x00, 0x34, - 0x00, 0x40, 0x00, 0x00, 0x01, 0x34, 0x37, 0x36, 0x37, 0x26, 0x27, 0x26, - 0x27, 0x35, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x26, 0x27, 0x26, 0x35, - 0x34, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x15, 0x14, 0x07, 0x06, 0x07, - 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x15, 0x06, 0x07, 0x06, 0x07, 0x16, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x13, 0x21, 0x13, 0x26, 0x37, 0x35, 0x33, - 0x35, 0x23, 0x35, 0x23, 0x15, 0x23, 0x15, 0x33, 0x15, 0x01, 0xaa, 0x1a, - 0x07, 0x09, 0x31, 0x1d, 0x21, 0x01, 0x01, 0x21, 0x23, 0x3f, 0x17, 0x18, - 0x15, 0x0e, 0x12, 0x25, 0x3f, 0x23, 0x21, 0x3f, 0x25, 0x11, 0x0d, 0x15, - 0x16, 0x18, 0x3e, 0x24, 0x22, 0x01, 0x01, 0x22, 0x1e, 0x2f, 0x09, 0x06, - 0x1a, 0x1a, 0xe1, 0xfc, 0xf5, 0xdc, 0x15, 0xee, 0x8c, 0x8c, 0x5f, 0x8c, - 0x8c, 0x01, 0xa8, 0x31, 0x2b, 0x0e, 0x0c, 0x1e, 0x34, 0x3a, 0x41, 0x03, - 0x41, 0x3c, 0x3d, 0x22, 0x0b, 0x08, 0x0f, 0x17, 0x20, 0x21, 0x23, 0x3d, - 0x22, 0x22, 0x3d, 0x23, 0x21, 0x20, 0x17, 0x10, 0x07, 0x0b, 0x22, 0x3d, - 0x3c, 0x41, 0x03, 0x41, 0x3a, 0x33, 0x1f, 0x0c, 0x0e, 0x2b, 0x31, 0x2f, - 0x2b, 0xfe, 0xb9, 0x01, 0x48, 0x2b, 0xe4, 0x65, 0x58, 0x65, 0x65, 0x58, - 0x65, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x67, 0x00, 0x02, 0x04, 0x6a, - 0x05, 0x20, 0x00, 0x22, 0x00, 0x2e, 0x00, 0x37, 0x00, 0x3d, 0x00, 0x00, - 0x01, 0x36, 0x26, 0x37, 0x1e, 0x01, 0x07, 0x33, 0x14, 0x23, 0x00, 0x13, - 0x21, 0x26, 0x35, 0x34, 0x00, 0x27, 0x06, 0x27, 0x06, 0x27, 0x37, 0x07, - 0x26, 0x27, 0x36, 0x27, 0x36, 0x37, 0x36, 0x26, 0x37, 0x16, 0x17, 0x07, - 0x15, 0x16, 0x3b, 0x01, 0x32, 0x35, 0x34, 0x37, 0x23, 0x22, 0x07, 0x03, - 0x15, 0x14, 0x3b, 0x01, 0x36, 0x35, 0x27, 0x22, 0x01, 0x17, 0x04, 0x13, - 0x33, 0x02, 0x01, 0xf8, 0x36, 0x47, 0x4a, 0x4b, 0x15, 0x26, 0x04, 0x02, - 0x01, 0xd5, 0x27, 0xfc, 0xaf, 0x0b, 0x01, 0x6e, 0x0c, 0x3d, 0x6c, 0x52, - 0x5d, 0x2a, 0x5e, 0x64, 0x17, 0x57, 0x0c, 0x2a, 0x57, 0x09, 0x3e, 0x21, - 0x5b, 0x31, 0x94, 0x03, 0x07, 0x12, 0x3d, 0x25, 0x05, 0x54, 0x20, 0x65, - 0x19, 0x09, 0x3e, 0x06, 0x36, 0x01, 0x90, 0x2e, 0x01, 0x48, 0x05, 0x43, - 0x27, 0x04, 0x4c, 0x22, 0x8b, 0x27, 0x47, 0x80, 0x0d, 0x01, 0xfe, 0xd7, - 0xfc, 0xe1, 0x31, 0x32, 0x8c, 0x01, 0x00, 0x68, 0x98, 0x06, 0x84, 0x04, - 0x5b, 0x46, 0x19, 0x48, 0xe5, 0xb8, 0x60, 0x5b, 0x24, 0x25, 0x6f, 0x17, - 0x6b, 0xdf, 0x0e, 0x1a, 0x2b, 0x1d, 0x2a, 0x38, 0xfe, 0x64, 0x15, 0x19, - 0x0d, 0x2e, 0x1e, 0x01, 0xf8, 0x4e, 0xeb, 0xfd, 0x63, 0x02, 0xe8, 0x00, - 0x00, 0x01, 0x00, 0x76, 0x00, 0x05, 0x04, 0x5b, 0x04, 0xc6, 0x00, 0x2e, - 0x00, 0x00, 0x37, 0x26, 0x35, 0x34, 0x36, 0x37, 0x36, 0x37, 0x26, 0x27, - 0x26, 0x35, 0x34, 0x36, 0x37, 0x36, 0x37, 0x26, 0x27, 0x26, 0x34, 0x3e, - 0x01, 0x33, 0x32, 0x1e, 0x01, 0x14, 0x07, 0x06, 0x07, 0x16, 0x17, 0x1e, - 0x01, 0x15, 0x14, 0x07, 0x06, 0x07, 0x16, 0x17, 0x1e, 0x01, 0x15, 0x14, - 0x07, 0x7f, 0x09, 0x86, 0x77, 0x1f, 0x20, 0x18, 0x11, 0x22, 0x45, 0x3e, - 0x16, 0x18, 0x15, 0x0d, 0x12, 0x23, 0x40, 0x21, 0x21, 0x3f, 0x25, 0x12, - 0x0d, 0x15, 0x16, 0x19, 0x3d, 0x45, 0x21, 0x12, 0x18, 0x1f, 0x1f, 0x77, - 0x87, 0x0a, 0x06, 0x2e, 0x2f, 0x82, 0xee, 0x40, 0x11, 0x0c, 0x18, 0x1e, - 0x3d, 0x43, 0x44, 0x7a, 0x22, 0x0c, 0x08, 0x0f, 0x18, 0x1f, 0x45, 0x3e, - 0x22, 0x22, 0x3e, 0x45, 0x1f, 0x18, 0x10, 0x07, 0x0c, 0x22, 0x7a, 0x44, - 0x43, 0x3d, 0x1e, 0x18, 0x0d, 0x10, 0x40, 0xee, 0x82, 0x2f, 0x2e, 0x00, - 0x00, 0x01, 0x00, 0x80, 0x00, 0x85, 0x04, 0x51, 0x05, 0x4f, 0x00, 0x23, - 0x00, 0x00, 0x01, 0x16, 0x17, 0x16, 0x17, 0x16, 0x1d, 0x01, 0x14, 0x07, - 0x06, 0x23, 0x22, 0x27, 0x23, 0x15, 0x14, 0x17, 0x23, 0x35, 0x36, 0x35, - 0x27, 0x23, 0x07, 0x06, 0x23, 0x22, 0x2f, 0x01, 0x35, 0x34, 0x37, 0x00, - 0x3f, 0x01, 0x02, 0x6b, 0x4d, 0xb1, 0xc3, 0x05, 0x20, 0x85, 0x2c, 0x34, - 0x7f, 0x4e, 0x22, 0x44, 0xb1, 0x46, 0x02, 0x20, 0x26, 0x46, 0x69, 0x99, - 0x3f, 0x07, 0x9a, 0x01, 0x02, 0x4a, 0x02, 0x05, 0x4f, 0x89, 0xe3, 0xe4, - 0x2f, 0x46, 0x42, 0x21, 0x89, 0x4f, 0x12, 0xb6, 0x0a, 0xe9, 0x7b, 0x05, - 0x7c, 0xea, 0x03, 0x49, 0x6d, 0xac, 0x3c, 0x26, 0x96, 0xa7, 0x01, 0x3d, - 0x88, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0e, 0x00, 0x85, 0x04, 0xc3, - 0x05, 0x4d, 0x00, 0x18, 0x00, 0x32, 0x00, 0x00, 0x01, 0x32, 0x17, 0x16, - 0x15, 0x32, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x1d, 0x01, 0x14, 0x07, - 0x00, 0x07, 0x23, 0x01, 0x26, 0x35, 0x34, 0x37, 0x36, 0x03, 0x15, 0x14, - 0x17, 0x01, 0x33, 0x01, 0x36, 0x3d, 0x01, 0x34, 0x27, 0x26, 0x23, 0x22, - 0x03, 0x06, 0x15, 0x23, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x01, - 0x3d, 0xb3, 0x60, 0x17, 0x05, 0x0a, 0x5d, 0xc1, 0xac, 0x64, 0x1f, 0xb6, - 0xfe, 0x8e, 0x32, 0x05, 0xfe, 0x0d, 0x63, 0xa4, 0x42, 0xbc, 0xab, 0x01, - 0x86, 0x03, 0x01, 0xd8, 0x55, 0x9b, 0x3b, 0x2f, 0xd9, 0x47, 0x08, 0x05, - 0x3b, 0x53, 0x9c, 0x8f, 0x58, 0x1e, 0x05, 0x4d, 0xe2, 0x42, 0x14, 0x3a, - 0xfe, 0xae, 0x40, 0x42, 0x0a, 0xd5, 0xbd, 0xfe, 0x3b, 0x37, 0x02, 0x68, - 0x92, 0x96, 0xad, 0x66, 0x25, 0xfe, 0xd0, 0x0d, 0xb4, 0xbb, 0xfe, 0x23, - 0x02, 0x3e, 0x85, 0x7c, 0x1f, 0x8e, 0x5c, 0x17, 0xfe, 0x90, 0x1f, 0x15, - 0x40, 0xac, 0xb8, 0x92, 0x39, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x91, - 0x00, 0x85, 0x04, 0x40, 0x05, 0x4f, 0x00, 0x08, 0x00, 0x0d, 0x00, 0x00, - 0x09, 0x01, 0x15, 0x00, 0x07, 0x26, 0x01, 0x26, 0x35, 0x09, 0x04, 0x02, - 0x69, 0x01, 0xd7, 0xfe, 0x43, 0x1a, 0x0c, 0xfe, 0x6e, 0x3a, 0x01, 0xd5, - 0xfe, 0x5e, 0x01, 0xa5, 0x01, 0xa6, 0xfe, 0xa8, 0x05, 0x4f, 0xfd, 0x9e, - 0x05, 0xfd, 0xb9, 0x1c, 0x09, 0x02, 0x0e, 0x47, 0x0a, 0x02, 0x20, 0xfd, - 0xde, 0xfd, 0xdb, 0x02, 0x25, 0x01, 0xbd, 0x00, 0x00, 0x01, 0x00, 0x32, - 0x00, 0x85, 0x04, 0x9f, 0x05, 0x4f, 0x00, 0x37, 0x00, 0x00, 0x01, 0x32, - 0x17, 0x16, 0x17, 0x14, 0x0f, 0x01, 0x33, 0x36, 0x3b, 0x01, 0x32, 0x17, - 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x22, 0x27, 0x23, 0x15, 0x10, 0x17, - 0x15, 0x23, 0x27, 0x36, 0x11, 0x35, 0x23, 0x06, 0x23, 0x22, 0x27, 0x26, - 0x35, 0x34, 0x37, 0x36, 0x3b, 0x01, 0x32, 0x17, 0x33, 0x35, 0x26, 0x27, - 0x26, 0x3d, 0x01, 0x34, 0x37, 0x36, 0x02, 0x6a, 0xb0, 0x53, 0x0a, 0x03, - 0x63, 0x31, 0x02, 0x3d, 0x45, 0x10, 0xc3, 0x4f, 0x13, 0xac, 0x20, 0x3b, - 0xc7, 0x53, 0x02, 0x43, 0xab, 0x05, 0x46, 0x02, 0x52, 0xca, 0x9d, 0x54, - 0x14, 0xca, 0x36, 0x2a, 0x08, 0x46, 0x40, 0x03, 0x45, 0x18, 0x31, 0xb0, - 0x3b, 0x05, 0x4f, 0xba, 0x2b, 0x2e, 0x60, 0x84, 0x31, 0x17, 0xa6, 0x36, - 0x32, 0xa8, 0x56, 0x0a, 0x05, 0xe2, 0x08, 0xfe, 0xe6, 0x59, 0x05, 0x05, - 0x69, 0x01, 0x12, 0x02, 0xe4, 0xa6, 0x38, 0x2f, 0xc0, 0x44, 0x0a, 0x17, - 0x02, 0x3b, 0x38, 0x5b, 0x42, 0x0c, 0xa5, 0x56, 0x0f, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x7f, 0x00, 0x86, 0x04, 0x52, 0x05, 0x50, 0x00, 0x22, - 0x00, 0x3c, 0x00, 0x42, 0x00, 0x00, 0x01, 0x16, 0x01, 0x16, 0x1d, 0x01, - 0x14, 0x07, 0x06, 0x2b, 0x01, 0x22, 0x27, 0x23, 0x15, 0x14, 0x17, 0x23, - 0x35, 0x36, 0x35, 0x23, 0x07, 0x06, 0x2b, 0x01, 0x22, 0x27, 0x26, 0x35, - 0x37, 0x35, 0x34, 0x37, 0x12, 0x37, 0x06, 0x01, 0x06, 0x15, 0x16, 0x17, - 0x16, 0x3b, 0x01, 0x32, 0x37, 0x33, 0x32, 0x17, 0x16, 0x3b, 0x01, 0x32, - 0x37, 0x36, 0x3d, 0x01, 0x34, 0x27, 0x26, 0x03, 0x33, 0x26, 0x27, 0x22, - 0x07, 0x02, 0x69, 0x68, 0x01, 0x3b, 0x46, 0x94, 0x1c, 0x28, 0x12, 0x77, - 0x51, 0x22, 0x44, 0xb1, 0x47, 0x22, 0x2e, 0x46, 0x57, 0x12, 0x83, 0x43, - 0x14, 0x02, 0xa9, 0xef, 0x4e, 0x66, 0xfe, 0xea, 0x42, 0x08, 0x79, 0x12, - 0x22, 0x0d, 0x62, 0x4f, 0x96, 0x06, 0x1a, 0x44, 0x55, 0x0f, 0x71, 0x35, - 0x08, 0xa6, 0xbd, 0x75, 0x34, 0x0b, 0x0c, 0x05, 0x0d, 0x05, 0x50, 0xb9, - 0xfe, 0x88, 0x72, 0x6f, 0x02, 0xac, 0x40, 0x0d, 0xb3, 0x0b, 0xe6, 0x7f, - 0x05, 0x7c, 0xef, 0x53, 0x60, 0x8f, 0x36, 0x34, 0x0b, 0x02, 0xa4, 0xaf, - 0x01, 0x27, 0x3c, 0xa4, 0xfe, 0xb7, 0x6b, 0x6e, 0x99, 0x2c, 0x07, 0xb3, - 0x3a, 0x79, 0x89, 0x21, 0x19, 0x19, 0x91, 0xaa, 0xec, 0xfc, 0x40, 0x13, - 0x4a, 0x44, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0b, 0x00, 0x85, 0x04, 0xc6, - 0x05, 0x4f, 0x00, 0x17, 0x00, 0x00, 0x01, 0x32, 0x17, 0x16, 0x17, 0x33, - 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x01, 0x23, - 0x01, 0x26, 0x35, 0x34, 0x37, 0x36, 0x01, 0x3b, 0xa7, 0x5f, 0x23, 0x02, - 0x02, 0x1d, 0x4b, 0x59, 0x6f, 0xac, 0x68, 0x1a, 0xab, 0xfe, 0x4d, 0x05, - 0xfe, 0x32, 0x8a, 0xa4, 0x45, 0x05, 0x4f, 0xc1, 0x4c, 0x29, 0x85, 0x58, - 0x59, 0xb8, 0x44, 0x3c, 0xce, 0xba, 0xfd, 0xf6, 0x02, 0x36, 0xa9, 0xb3, - 0xad, 0x66, 0x25, 0x00, 0x00, 0x01, 0x00, 0x91, 0x00, 0x85, 0x04, 0x40, - 0x05, 0x4f, 0x00, 0x08, 0x00, 0x00, 0x09, 0x01, 0x16, 0x15, 0x01, 0x26, - 0x01, 0x34, 0x37, 0x02, 0x69, 0x01, 0x9e, 0x39, 0xfe, 0x29, 0x0a, 0xfe, - 0x32, 0x5c, 0x05, 0x4f, 0xfd, 0xe7, 0x45, 0x0b, 0xfd, 0x9f, 0x06, 0x02, - 0x5b, 0x0b, 0x72, 0x00, 0x00, 0x03, 0x00, 0x31, 0x00, 0x86, 0x04, 0xa0, - 0x05, 0x56, 0x00, 0x32, 0x00, 0x60, 0x00, 0x67, 0x00, 0x00, 0x01, 0x32, - 0x17, 0x16, 0x15, 0x14, 0x0f, 0x01, 0x36, 0x3b, 0x01, 0x32, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x06, 0x07, 0x22, 0x27, 0x23, 0x15, 0x10, 0x17, 0x15, - 0x23, 0x27, 0x36, 0x11, 0x35, 0x23, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, - 0x34, 0x37, 0x36, 0x3b, 0x01, 0x32, 0x17, 0x26, 0x27, 0x35, 0x34, 0x37, - 0x36, 0x03, 0x14, 0x1f, 0x01, 0x15, 0x26, 0x2b, 0x01, 0x22, 0x0f, 0x01, - 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x33, 0x16, 0x17, 0x16, - 0x33, 0x32, 0x37, 0x36, 0x3d, 0x01, 0x34, 0x2f, 0x01, 0x23, 0x22, 0x07, - 0x35, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x13, - 0x14, 0x07, 0x33, 0x35, 0x26, 0x35, 0x02, 0x6d, 0xa6, 0x56, 0x15, 0x5e, - 0x12, 0x19, 0x32, 0x22, 0xcc, 0x4c, 0x0d, 0xad, 0x1c, 0x3c, 0xc6, 0x54, - 0x02, 0x43, 0xac, 0x05, 0x46, 0x02, 0x52, 0xcb, 0x9d, 0x55, 0x15, 0xcb, - 0x37, 0x2a, 0x20, 0x32, 0x19, 0x51, 0x17, 0xb1, 0x3b, 0xc6, 0x8b, 0x0a, - 0x58, 0x61, 0x07, 0xc8, 0x32, 0x06, 0x70, 0x32, 0x40, 0xad, 0x5e, 0x0d, - 0x12, 0x06, 0x1e, 0x44, 0x4a, 0x82, 0x8a, 0x46, 0x0a, 0xd0, 0x2c, 0x05, - 0x61, 0x58, 0x6a, 0x1a, 0x15, 0x99, 0x2d, 0x21, 0x98, 0x44, 0xd8, 0x17, - 0x32, 0x17, 0x05, 0x56, 0xa9, 0x39, 0x2f, 0x6d, 0x88, 0x13, 0x05, 0xb1, - 0x2e, 0x30, 0xad, 0x52, 0x0a, 0x06, 0xe3, 0x07, 0xfe, 0xe4, 0x5a, 0x04, - 0x04, 0x6a, 0x01, 0x13, 0x03, 0xe6, 0xa7, 0x39, 0x2f, 0xc2, 0x43, 0x0a, - 0x05, 0x5c, 0x91, 0x20, 0xa7, 0x56, 0x0f, 0xfe, 0xef, 0x80, 0xa7, 0x0a, - 0x03, 0x08, 0xaf, 0x37, 0x79, 0x4d, 0x1f, 0xf3, 0x16, 0x35, 0x62, 0x6f, - 0x6d, 0x9c, 0x26, 0x23, 0x05, 0xb7, 0x27, 0x03, 0x08, 0x03, 0x70, 0x5b, - 0x3f, 0x24, 0x96, 0x47, 0x0e, 0xa5, 0xfc, 0x8d, 0x17, 0x4f, 0x03, 0x51, - 0x12, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x2e, 0x00, 0x07, 0x04, 0xa3, - 0x04, 0xc6, 0x00, 0x0e, 0x00, 0x1d, 0x00, 0x2c, 0x00, 0x48, 0x00, 0x00, - 0x01, 0x33, 0x14, 0x06, 0x07, 0x14, 0x16, 0x17, 0x23, 0x26, 0x27, 0x26, - 0x27, 0x26, 0x36, 0x25, 0x33, 0x14, 0x06, 0x07, 0x14, 0x16, 0x17, 0x23, - 0x26, 0x27, 0x26, 0x27, 0x26, 0x36, 0x05, 0x33, 0x14, 0x06, 0x07, 0x14, - 0x16, 0x17, 0x23, 0x26, 0x27, 0x26, 0x27, 0x26, 0x36, 0x13, 0x1e, 0x01, - 0x15, 0x14, 0x06, 0x04, 0x20, 0x24, 0x26, 0x35, 0x34, 0x36, 0x37, 0x33, - 0x06, 0x07, 0x06, 0x14, 0x1e, 0x01, 0x20, 0x3e, 0x01, 0x34, 0x27, 0x26, - 0x27, 0x01, 0x7e, 0x0b, 0x76, 0x01, 0xa5, 0x06, 0x0b, 0x17, 0x85, 0x27, - 0x0c, 0x04, 0x8a, 0x01, 0x05, 0x0b, 0x77, 0x02, 0xa7, 0x05, 0x0b, 0x17, - 0x84, 0x28, 0x0c, 0x03, 0x8a, 0x01, 0x18, 0x0b, 0x77, 0x01, 0xa6, 0x05, - 0x0a, 0x17, 0x85, 0x27, 0x0d, 0x03, 0x8a, 0x24, 0x88, 0x9b, 0x96, 0xfe, - 0xef, 0xfe, 0xd9, 0xfe, 0xef, 0x96, 0x9a, 0x88, 0x03, 0x6b, 0x3d, 0x46, - 0x88, 0xf5, 0x01, 0x0d, 0xf6, 0x87, 0x46, 0x3e, 0x6a, 0x04, 0x47, 0x33, - 0x7e, 0x50, 0x6a, 0x62, 0xa4, 0x87, 0x5e, 0x2a, 0x49, 0x65, 0x72, 0xc0, - 0x4e, 0xc0, 0x7b, 0xa0, 0x98, 0xf9, 0xcc, 0x91, 0x3f, 0x71, 0x9a, 0xae, - 0x4a, 0x41, 0x9f, 0x65, 0x83, 0x7d, 0xce, 0xa9, 0x76, 0x36, 0x5c, 0x7e, - 0x90, 0xfe, 0x78, 0x28, 0x8f, 0x4f, 0x4e, 0x8f, 0x50, 0x50, 0x8f, 0x4e, - 0x4f, 0x8f, 0x28, 0x21, 0x38, 0x3f, 0x88, 0x7c, 0x45, 0x45, 0x7c, 0x88, - 0x3f, 0x38, 0x21, 0x00, 0x00, 0x01, 0x01, 0x72, 0x00, 0x21, 0x03, 0x5f, - 0x05, 0xaa, 0x00, 0x11, 0x00, 0x00, 0x01, 0x33, 0x17, 0x11, 0x14, 0x0f, - 0x01, 0x23, 0x22, 0x2f, 0x01, 0x34, 0x3f, 0x01, 0x32, 0x17, 0x33, 0x11, - 0x03, 0x15, 0x44, 0x06, 0xb9, 0x2d, 0x21, 0xc8, 0x1a, 0x04, 0xc7, 0x1f, - 0x5d, 0x55, 0x04, 0x05, 0xaa, 0x07, 0xfb, 0x46, 0x9a, 0x2b, 0x03, 0x7d, - 0x1d, 0x7b, 0x17, 0x04, 0x3c, 0x04, 0x8e, 0x00, 0x00, 0x01, 0x00, 0xa2, - 0x00, 0x21, 0x04, 0x2f, 0x05, 0xaa, 0x00, 0x1d, 0x00, 0x00, 0x01, 0x33, - 0x17, 0x15, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x23, 0x27, 0x36, 0x35, - 0x34, 0x27, 0x26, 0x27, 0x11, 0x14, 0x07, 0x23, 0x22, 0x35, 0x34, 0x37, - 0x33, 0x32, 0x17, 0x11, 0x02, 0x36, 0x52, 0x08, 0x19, 0xa3, 0xe3, 0x73, - 0x04, 0x1c, 0x39, 0xd7, 0x57, 0x17, 0xd4, 0x35, 0xe5, 0xc8, 0x16, 0x5b, - 0x53, 0x05, 0xaa, 0x06, 0x25, 0x33, 0x3b, 0x42, 0x83, 0x89, 0x5b, 0x1e, - 0x2f, 0x4f, 0x42, 0x43, 0x27, 0x19, 0xfc, 0x12, 0x90, 0x2a, 0x9e, 0x7c, - 0x15, 0x3c, 0x04, 0x90, 0x00, 0x01, 0x00, 0x6a, 0xff, 0x5f, 0x04, 0x67, - 0x05, 0xa5, 0x00, 0x1e, 0x00, 0x00, 0x01, 0x05, 0x17, 0x11, 0x14, 0x07, - 0x23, 0x22, 0x3d, 0x01, 0x34, 0x3f, 0x01, 0x32, 0x17, 0x11, 0x25, 0x11, - 0x14, 0x0f, 0x01, 0x23, 0x22, 0x3d, 0x01, 0x34, 0x3f, 0x01, 0x32, 0x17, - 0x11, 0x01, 0xd9, 0x02, 0x8c, 0x02, 0xb5, 0x33, 0xc9, 0xa7, 0x25, 0x51, - 0x4d, 0xfd, 0xfb, 0x8e, 0x3f, 0x19, 0xcb, 0xa0, 0x29, 0x54, 0x4b, 0x05, - 0xa5, 0xbf, 0x04, 0xfb, 0x37, 0x92, 0x28, 0x9b, 0x04, 0x77, 0x14, 0x03, - 0x37, 0x03, 0xd1, 0x9f, 0xfc, 0x17, 0x81, 0x35, 0x07, 0x92, 0x07, 0x73, - 0x20, 0x03, 0x3f, 0x04, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x11, - 0x00, 0x7c, 0x04, 0xc0, 0x05, 0x4f, 0x00, 0x18, 0x00, 0x1c, 0x00, 0x00, - 0x01, 0x17, 0x11, 0x14, 0x07, 0x22, 0x27, 0x34, 0x37, 0x32, 0x17, 0x33, - 0x11, 0x21, 0x11, 0x06, 0x07, 0x23, 0x22, 0x35, 0x34, 0x37, 0x32, 0x17, - 0x11, 0x17, 0x15, 0x21, 0x35, 0x04, 0xbd, 0x03, 0xd6, 0xc0, 0x0f, 0xc0, - 0x59, 0x41, 0x03, 0xfd, 0x3e, 0x07, 0xc7, 0x03, 0xd4, 0xc2, 0x52, 0x48, - 0x49, 0x02, 0xc2, 0x05, 0x4f, 0x03, 0xfb, 0xf3, 0xb0, 0x11, 0x87, 0x71, - 0x0c, 0x31, 0x02, 0x20, 0xfd, 0xd3, 0xab, 0x1d, 0x91, 0x67, 0x0d, 0x34, - 0x04, 0x02, 0xaa, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x44, - 0x00, 0x25, 0x03, 0x8d, 0x05, 0xae, 0x00, 0x0c, 0x00, 0x13, 0x00, 0x00, - 0x01, 0x33, 0x17, 0x11, 0x33, 0x36, 0x33, 0x16, 0x17, 0x02, 0x05, 0x27, - 0x11, 0x13, 0x11, 0x24, 0x11, 0x36, 0x27, 0x22, 0x01, 0x49, 0x2b, 0x04, - 0x03, 0xa1, 0x88, 0xd7, 0x12, 0x1b, 0xfd, 0xd4, 0x02, 0x34, 0x01, 0x8b, - 0x0c, 0x98, 0x70, 0x05, 0xae, 0x05, 0xfc, 0x75, 0xe0, 0x03, 0xf2, 0xfe, - 0x6f, 0x53, 0x02, 0x05, 0x82, 0xfc, 0x10, 0xfe, 0xb1, 0x5e, 0x01, 0x1f, - 0xa3, 0x08, 0x00, 0x00, 0x00, 0x02, 0x01, 0xb1, 0x00, 0x2a, 0x03, 0x20, - 0x05, 0xaf, 0x00, 0x0d, 0x00, 0x13, 0x00, 0x00, 0x01, 0x33, 0x17, 0x11, - 0x25, 0x17, 0x11, 0x07, 0x23, 0x27, 0x11, 0x05, 0x23, 0x11, 0x13, 0x11, - 0x33, 0x25, 0x11, 0x23, 0x01, 0xb6, 0x27, 0x06, 0x01, 0x3b, 0x02, 0x04, - 0x26, 0x05, 0xfe, 0xc2, 0x02, 0x32, 0x01, 0x01, 0x0d, 0x02, 0x05, 0xaf, - 0x05, 0xfe, 0x49, 0x98, 0x02, 0xfb, 0xa6, 0x05, 0x05, 0x01, 0xca, 0x97, - 0x04, 0x48, 0xfd, 0xbc, 0xfe, 0x93, 0x87, 0x01, 0x6a, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x01, 0x37, 0x00, 0x2a, 0x03, 0x9a, 0x05, 0xaf, 0x00, 0x28, - 0x00, 0x2c, 0x00, 0x00, 0x01, 0x33, 0x17, 0x11, 0x37, 0x17, 0x15, 0x06, - 0x07, 0x11, 0x37, 0x15, 0x06, 0x07, 0x11, 0x07, 0x23, 0x27, 0x11, 0x05, - 0x11, 0x07, 0x23, 0x27, 0x11, 0x07, 0x35, 0x34, 0x37, 0x11, 0x23, 0x07, - 0x35, 0x37, 0x11, 0x37, 0x33, 0x17, 0x15, 0x25, 0x11, 0x01, 0x11, 0x25, - 0x11, 0x02, 0xf6, 0x2c, 0x05, 0x70, 0x03, 0x03, 0x70, 0x73, 0x01, 0x72, - 0x05, 0x2c, 0x04, 0xfe, 0xf0, 0x05, 0x27, 0x05, 0x7a, 0x7a, 0x02, 0x78, - 0x7a, 0x05, 0x27, 0x05, 0x01, 0x10, 0xfe, 0xf0, 0x01, 0x10, 0x05, 0xaf, - 0x05, 0xfe, 0xe1, 0x39, 0x02, 0x85, 0x07, 0x38, 0xfe, 0xa0, 0x34, 0x80, - 0x04, 0x3f, 0xfe, 0xe8, 0x04, 0x04, 0x01, 0x02, 0x84, 0xfe, 0xb9, 0x04, - 0x04, 0x01, 0x2f, 0x39, 0x86, 0x06, 0x39, 0x01, 0x65, 0x35, 0x83, 0x3e, - 0x01, 0x0f, 0x03, 0x03, 0xf8, 0x7f, 0x01, 0x3a, 0xfd, 0xb9, 0xfe, 0x9c, - 0x83, 0x01, 0x5f, 0x00, 0x00, 0x01, 0x00, 0x60, 0xff, 0xfe, 0x04, 0x71, - 0x05, 0x1c, 0x00, 0x45, 0x00, 0x00, 0x01, 0x23, 0x26, 0x07, 0x23, 0x22, - 0x27, 0x35, 0x36, 0x35, 0x34, 0x27, 0x35, 0x36, 0x37, 0x33, 0x16, 0x3b, - 0x01, 0x35, 0x34, 0x27, 0x35, 0x36, 0x37, 0x33, 0x16, 0x32, 0x37, 0x33, - 0x16, 0x17, 0x15, 0x06, 0x1d, 0x01, 0x33, 0x32, 0x37, 0x33, 0x16, 0x17, - 0x15, 0x06, 0x15, 0x14, 0x17, 0x15, 0x06, 0x2b, 0x01, 0x26, 0x07, 0x23, - 0x11, 0x14, 0x17, 0x15, 0x06, 0x07, 0x23, 0x26, 0x22, 0x07, 0x23, 0x26, - 0x27, 0x35, 0x36, 0x35, 0x02, 0x2a, 0x94, 0x9f, 0x47, 0x31, 0x15, 0x09, - 0x56, 0x56, 0x01, 0x1c, 0x32, 0x49, 0x9e, 0x93, 0x73, 0x03, 0x19, 0x33, - 0x27, 0x7b, 0x27, 0x33, 0x19, 0x03, 0x73, 0x8f, 0x9e, 0x49, 0x31, 0x1c, - 0x02, 0x56, 0x56, 0x09, 0x16, 0x30, 0x47, 0xa0, 0x8f, 0x73, 0x03, 0x19, - 0x33, 0x27, 0x7b, 0x27, 0x33, 0x19, 0x03, 0x73, 0x02, 0xad, 0x01, 0x50, - 0x1f, 0x33, 0x2b, 0x31, 0x3d, 0x27, 0x33, 0x19, 0x03, 0x73, 0x99, 0x9f, - 0x48, 0x31, 0x1d, 0x02, 0x57, 0x57, 0x02, 0x1d, 0x31, 0x48, 0x9f, 0x99, - 0x73, 0x03, 0x19, 0x33, 0x27, 0x3d, 0x31, 0x2b, 0x33, 0x1f, 0x50, 0x01, - 0xfe, 0x88, 0x9f, 0x48, 0x32, 0x1c, 0x02, 0x57, 0x57, 0x02, 0x1c, 0x32, - 0x48, 0x9f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x2e, 0xff, 0xf0, 0x04, 0xa3, - 0x05, 0x0f, 0x00, 0x06, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x1b, 0x00, 0x3b, - 0x00, 0x47, 0x00, 0x00, 0x13, 0x06, 0x07, 0x16, 0x17, 0x37, 0x35, 0x05, - 0x15, 0x17, 0x36, 0x37, 0x26, 0x27, 0x01, 0x26, 0x27, 0x06, 0x07, 0x17, - 0x33, 0x03, 0x23, 0x07, 0x16, 0x17, 0x36, 0x37, 0x03, 0x33, 0x37, 0x16, - 0x17, 0x06, 0x07, 0x27, 0x23, 0x11, 0x17, 0x06, 0x07, 0x26, 0x27, 0x37, - 0x11, 0x23, 0x07, 0x26, 0x27, 0x36, 0x37, 0x17, 0x33, 0x35, 0x27, 0x36, - 0x37, 0x16, 0x17, 0x0f, 0x01, 0x15, 0x23, 0x15, 0x33, 0x11, 0x33, 0x11, - 0x33, 0x35, 0x23, 0x35, 0xce, 0x13, 0x2a, 0x29, 0x14, 0x53, 0x02, 0x90, - 0x52, 0x14, 0x29, 0x29, 0x14, 0xfe, 0xb5, 0x26, 0x2a, 0x26, 0x27, 0x3b, - 0x28, 0x01, 0x28, 0x3a, 0x27, 0x26, 0x29, 0x27, 0x06, 0xc8, 0xb6, 0x08, - 0x6b, 0x6b, 0x08, 0xb6, 0xc8, 0x6e, 0x5c, 0x5c, 0x5b, 0x5b, 0x6e, 0xc8, - 0xb6, 0x09, 0x6b, 0x6b, 0x09, 0xb6, 0xc8, 0x6e, 0x5b, 0x5b, 0x5c, 0x5c, - 0x6e, 0x60, 0x66, 0x66, 0x2f, 0x65, 0x65, 0x03, 0x2e, 0x28, 0x28, 0x26, - 0x28, 0x3b, 0x28, 0x01, 0x28, 0x3a, 0x28, 0x26, 0x28, 0x28, 0x01, 0x40, - 0x14, 0x29, 0x29, 0x14, 0x53, 0xfc, 0xc8, 0x53, 0x14, 0x2a, 0x2a, 0x14, - 0x02, 0x98, 0x6e, 0x5c, 0x5d, 0x5b, 0x5b, 0x6f, 0xfe, 0x84, 0xb6, 0x0a, - 0x6a, 0x6a, 0x0a, 0xb6, 0x01, 0x7c, 0x6f, 0x5b, 0x5c, 0x5c, 0x5c, 0x6e, - 0xbb, 0xb7, 0x0a, 0x6a, 0x6a, 0x0a, 0xb7, 0x65, 0x8b, 0x28, 0xfe, 0xb0, - 0x01, 0x50, 0x28, 0x8b, 0x00, 0x0c, 0x00, 0x2f, 0xff, 0xfb, 0x04, 0xa2, - 0x04, 0x4e, 0x00, 0x14, 0x00, 0x23, 0x00, 0x2e, 0x00, 0x36, 0x00, 0x43, - 0x00, 0x4d, 0x00, 0x68, 0x00, 0x77, 0x00, 0x8c, 0x00, 0x97, 0x00, 0xa6, - 0x00, 0xaf, 0x00, 0x00, 0x01, 0x21, 0x32, 0x1f, 0x01, 0x37, 0x33, 0x32, - 0x15, 0x07, 0x21, 0x27, 0x35, 0x36, 0x37, 0x35, 0x26, 0x27, 0x26, 0x3d, - 0x01, 0x07, 0x33, 0x32, 0x17, 0x16, 0x15, 0x06, 0x07, 0x23, 0x26, 0x27, - 0x35, 0x36, 0x37, 0x36, 0x17, 0x15, 0x13, 0x07, 0x15, 0x33, 0x37, 0x07, - 0x26, 0x2f, 0x01, 0x05, 0x17, 0x37, 0x26, 0x2b, 0x01, 0x22, 0x07, 0x05, - 0x16, 0x1f, 0x01, 0x15, 0x14, 0x07, 0x06, 0x2b, 0x01, 0x26, 0x27, 0x35, - 0x1f, 0x01, 0x33, 0x32, 0x3f, 0x01, 0x34, 0x2f, 0x01, 0x06, 0x25, 0x33, - 0x32, 0x17, 0x16, 0x15, 0x07, 0x23, 0x27, 0x06, 0x0f, 0x01, 0x17, 0x07, - 0x23, 0x26, 0x27, 0x26, 0x3d, 0x01, 0x34, 0x3f, 0x01, 0x23, 0x27, 0x35, - 0x37, 0x17, 0x15, 0x17, 0x33, 0x15, 0x14, 0x07, 0x15, 0x16, 0x17, 0x13, - 0x33, 0x17, 0x35, 0x27, 0x05, 0x33, 0x17, 0x15, 0x21, 0x32, 0x37, 0x33, - 0x17, 0x15, 0x06, 0x07, 0x06, 0x2b, 0x01, 0x15, 0x07, 0x23, 0x26, 0x3d, - 0x01, 0x27, 0x17, 0x11, 0x07, 0x23, 0x22, 0x2f, 0x01, 0x35, 0x34, 0x37, - 0x05, 0x07, 0x17, 0x33, 0x35, 0x34, 0x3b, 0x01, 0x32, 0x3f, 0x01, 0x21, - 0x26, 0x3d, 0x01, 0x05, 0x06, 0x07, 0x15, 0x14, 0x1f, 0x01, 0x33, 0x35, - 0x02, 0x14, 0x01, 0x2d, 0x2c, 0x16, 0x3b, 0x4b, 0x06, 0x04, 0x84, 0xfe, - 0xf7, 0x04, 0x0e, 0x3e, 0x8e, 0x0c, 0x23, 0x57, 0x12, 0x55, 0x2a, 0x17, - 0x86, 0x0c, 0x03, 0xe5, 0x03, 0x79, 0x0c, 0x22, 0xd1, 0x9a, 0x11, 0x9a, - 0x48, 0x15, 0x56, 0x0d, 0x0f, 0xfd, 0xce, 0xb7, 0x7a, 0x2f, 0x3b, 0x15, - 0x40, 0x22, 0x02, 0xbf, 0x0e, 0x71, 0x04, 0x3d, 0x11, 0x1c, 0x6f, 0x09, - 0x89, 0x29, 0x77, 0x65, 0x29, 0x1c, 0x01, 0x24, 0x49, 0xad, 0xfd, 0xc5, - 0x0f, 0x07, 0x59, 0x27, 0x04, 0x04, 0x4c, 0x89, 0x0b, 0x03, 0x04, 0x05, - 0x02, 0x11, 0x84, 0x0f, 0x41, 0x0f, 0x02, 0x4c, 0x04, 0x61, 0x0e, 0x02, - 0x58, 0x01, 0x77, 0x98, 0x02, 0x15, 0x48, 0x01, 0xe5, 0x04, 0x03, 0x01, - 0x1b, 0x20, 0x1b, 0x02, 0x04, 0x05, 0x95, 0x13, 0x1a, 0x95, 0x03, 0x07, - 0x83, 0x3e, 0x06, 0x04, 0xe3, 0x58, 0x25, 0x04, 0x43, 0x01, 0xc9, 0x49, - 0x49, 0x04, 0x06, 0xb0, 0x10, 0x24, 0x50, 0xfe, 0xcc, 0x06, 0xfe, 0x43, - 0x2f, 0x04, 0x44, 0x17, 0xce, 0x04, 0x4e, 0x36, 0x67, 0x2b, 0x05, 0xe5, - 0x04, 0x04, 0x0d, 0x20, 0x04, 0xf8, 0x0f, 0x11, 0x03, 0x04, 0x0a, 0x62, - 0x25, 0x08, 0xef, 0x0d, 0x83, 0x06, 0x02, 0xd7, 0x06, 0x23, 0x12, 0x01, - 0xfe, 0xf1, 0x0b, 0x02, 0x83, 0x09, 0x96, 0x0a, 0x03, 0xe6, 0x6a, 0xd5, - 0x6e, 0x4e, 0xcb, 0x0d, 0xd0, 0x20, 0x0f, 0x3a, 0x33, 0x0e, 0x08, 0xf2, - 0x03, 0x0b, 0xd4, 0x4f, 0x14, 0x2b, 0x35, 0x7b, 0x62, 0x51, 0xa4, 0x3c, - 0x0a, 0x04, 0x2c, 0xeb, 0x1a, 0x10, 0x1e, 0x04, 0x15, 0xe5, 0x14, 0x17, - 0x06, 0x15, 0x64, 0x1f, 0x2d, 0x04, 0x04, 0x1d, 0x04, 0x0a, 0x02, 0x06, - 0x96, 0x08, 0x14, 0xc1, 0x01, 0x09, 0x06, 0x03, 0x83, 0xe5, 0x04, 0x58, - 0x19, 0x04, 0x01, 0x10, 0xff, 0x16, 0x5d, 0x03, 0xdc, 0x0a, 0x03, 0x88, - 0x05, 0xfe, 0xf7, 0x03, 0x66, 0x1d, 0x09, 0x27, 0x5e, 0x09, 0x83, 0x82, - 0x06, 0x16, 0x4a, 0x89, 0x01, 0x0f, 0x06, 0x16, 0x4a, 0x1c, 0x07, 0x41, - 0x21, 0x04, 0xd3, 0x00, 0x00, 0x04, 0x00, 0x3c, 0x00, 0x0a, 0x04, 0x95, - 0x04, 0x38, 0x00, 0x0a, 0x00, 0x1f, 0x00, 0x32, 0x00, 0x45, 0x00, 0x00, - 0x01, 0x33, 0x11, 0x07, 0x35, 0x37, 0x33, 0x11, 0x33, 0x15, 0x21, 0x05, - 0x26, 0x35, 0x34, 0x3f, 0x01, 0x27, 0x37, 0x17, 0x27, 0x07, 0x06, 0x17, - 0x16, 0x37, 0x21, 0x15, 0x21, 0x22, 0x27, 0x26, 0x25, 0x06, 0x07, 0x23, - 0x15, 0x27, 0x37, 0x15, 0x33, 0x36, 0x37, 0x36, 0x27, 0x03, 0x37, 0x13, - 0x16, 0x15, 0x14, 0x01, 0x16, 0x1f, 0x01, 0x37, 0x07, 0x27, 0x37, 0x27, - 0x26, 0x07, 0x06, 0x07, 0x03, 0x27, 0x13, 0x36, 0x37, 0x36, 0x01, 0xdc, - 0x7d, 0x88, 0x93, 0x5d, 0x7d, 0xfe, 0x9e, 0xfe, 0x81, 0x20, 0x1c, 0x3d, - 0x2d, 0xab, 0x12, 0x2d, 0x48, 0x0f, 0x1b, 0x1d, 0x57, 0x01, 0x28, 0xfe, - 0x9f, 0x37, 0x2a, 0x21, 0x04, 0x0b, 0x3e, 0x80, 0x79, 0x9a, 0x9a, 0x90, - 0x2a, 0x13, 0x12, 0x31, 0x93, 0x63, 0xb1, 0x1b, 0xfd, 0xbd, 0x7b, 0x46, - 0x3d, 0x2e, 0x12, 0xab, 0x2c, 0x48, 0x1c, 0x2d, 0x2e, 0x27, 0x94, 0x64, - 0xb0, 0x1d, 0x28, 0x23, 0x01, 0x59, 0x01, 0x2b, 0x13, 0x47, 0x16, 0xfe, - 0x8b, 0x43, 0x86, 0x38, 0x39, 0x35, 0x37, 0x6a, 0x1a, 0x4e, 0xbb, 0x1a, - 0x7d, 0x29, 0x25, 0x25, 0x06, 0x74, 0x18, 0x14, 0x47, 0x6c, 0x07, 0x35, - 0x6e, 0x6d, 0x33, 0x08, 0x28, 0x2c, 0x48, 0x01, 0x01, 0x3a, 0xfe, 0xce, - 0x30, 0x2f, 0x28, 0x03, 0x5f, 0x01, 0x6b, 0x69, 0x1a, 0xbc, 0x4e, 0x1a, - 0x7d, 0x21, 0x04, 0x07, 0x4e, 0xff, 0x00, 0x39, 0x01, 0x32, 0x30, 0x18, - 0x14, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x4b, 0x00, 0x09, 0x04, 0x86, - 0x04, 0x1c, 0x00, 0x1c, 0x00, 0x31, 0x00, 0x44, 0x00, 0x57, 0x00, 0x00, - 0x01, 0x33, 0x15, 0x21, 0x35, 0x3e, 0x01, 0x37, 0x3e, 0x01, 0x35, 0x34, - 0x26, 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x15, - 0x14, 0x06, 0x07, 0x0e, 0x01, 0x05, 0x26, 0x35, 0x34, 0x3f, 0x01, 0x27, - 0x37, 0x17, 0x27, 0x07, 0x06, 0x17, 0x16, 0x37, 0x21, 0x15, 0x21, 0x22, - 0x27, 0x26, 0x25, 0x06, 0x07, 0x23, 0x15, 0x27, 0x37, 0x15, 0x33, 0x36, - 0x37, 0x36, 0x2f, 0x01, 0x37, 0x13, 0x16, 0x15, 0x14, 0x01, 0x16, 0x1f, - 0x01, 0x37, 0x07, 0x27, 0x37, 0x27, 0x26, 0x07, 0x06, 0x0f, 0x01, 0x27, - 0x13, 0x36, 0x37, 0x36, 0x02, 0x40, 0xf2, 0xfe, 0x89, 0x2e, 0x92, 0x11, - 0x23, 0x1a, 0x35, 0x2a, 0x22, 0x49, 0x3f, 0x36, 0x4f, 0x22, 0x5b, 0x6d, - 0x1b, 0x22, 0x0a, 0x63, 0xfd, 0xe5, 0x1f, 0x1b, 0x3c, 0x2c, 0xa7, 0x11, - 0x2b, 0x47, 0x0e, 0x1a, 0x1c, 0x55, 0x01, 0x20, 0xfe, 0xa8, 0x35, 0x29, - 0x20, 0x03, 0xf0, 0x3c, 0x7c, 0x77, 0x95, 0x95, 0x8d, 0x29, 0x12, 0x11, - 0x2f, 0x90, 0x61, 0xad, 0x1a, 0xfd, 0xcb, 0x79, 0x44, 0x3c, 0x2c, 0x11, - 0xa7, 0x2b, 0x47, 0x1b, 0x2c, 0x2c, 0x26, 0x91, 0x61, 0xab, 0x1c, 0x28, - 0x21, 0x01, 0x3e, 0x42, 0x3c, 0x23, 0x71, 0x0f, 0x1d, 0x27, 0x13, 0x1c, - 0x25, 0x11, 0x1b, 0x4e, 0x12, 0x0e, 0x47, 0x39, 0x1b, 0x31, 0x20, 0x09, - 0x4d, 0xe8, 0x37, 0x38, 0x33, 0x35, 0x68, 0x1a, 0x4c, 0xb7, 0x1a, 0x7b, - 0x27, 0x24, 0x24, 0x05, 0x71, 0x18, 0x13, 0x45, 0x68, 0x08, 0x33, 0x6b, - 0x6a, 0x32, 0x08, 0x27, 0x2b, 0x47, 0xfa, 0x38, 0xfe, 0xd6, 0x2f, 0x2e, - 0x26, 0x03, 0x48, 0x01, 0x67, 0x68, 0x1a, 0xb7, 0x4c, 0x19, 0x7b, 0x20, - 0x05, 0x06, 0x4c, 0xfa, 0x38, 0x01, 0x2a, 0x2f, 0x17, 0x13, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x44, 0x00, 0x0a, 0x04, 0x8d, 0x04, 0x2a, 0x00, 0x28, - 0x00, 0x3d, 0x00, 0x50, 0x00, 0x63, 0x00, 0x00, 0x01, 0x1e, 0x01, 0x15, - 0x14, 0x06, 0x23, 0x22, 0x26, 0x27, 0x35, 0x1e, 0x01, 0x33, 0x32, 0x36, - 0x35, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, - 0x23, 0x22, 0x06, 0x07, 0x35, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x15, 0x14, - 0x06, 0x01, 0x26, 0x35, 0x34, 0x3f, 0x01, 0x27, 0x37, 0x17, 0x27, 0x07, - 0x06, 0x17, 0x16, 0x37, 0x21, 0x15, 0x21, 0x22, 0x27, 0x26, 0x25, 0x06, - 0x07, 0x23, 0x15, 0x27, 0x37, 0x15, 0x33, 0x36, 0x37, 0x36, 0x2f, 0x01, - 0x37, 0x13, 0x16, 0x15, 0x14, 0x01, 0x16, 0x1f, 0x01, 0x37, 0x07, 0x27, - 0x37, 0x27, 0x26, 0x07, 0x06, 0x0f, 0x01, 0x27, 0x13, 0x36, 0x37, 0x36, - 0x02, 0xf6, 0x08, 0x44, 0x7c, 0x71, 0x25, 0x4e, 0x32, 0x34, 0x48, 0x27, - 0x43, 0x42, 0x3d, 0x39, 0x50, 0x53, 0x33, 0x34, 0x36, 0x34, 0x1e, 0x45, - 0x3e, 0x36, 0x4f, 0x23, 0x5d, 0x6f, 0x3c, 0xfd, 0x6b, 0x20, 0x1c, 0x3c, - 0x2d, 0xaa, 0x11, 0x2c, 0x47, 0x0f, 0x1a, 0x1d, 0x56, 0x01, 0x24, 0xfe, - 0xa4, 0x36, 0x29, 0x22, 0x03, 0xfe, 0x3d, 0x7e, 0x78, 0x98, 0x98, 0x8e, - 0x2a, 0x12, 0x12, 0x30, 0x92, 0x62, 0xaf, 0x1b, 0xfd, 0xc4, 0x7a, 0x45, - 0x3c, 0x2e, 0x12, 0xa9, 0x2b, 0x47, 0x1b, 0x2d, 0x2d, 0x26, 0x93, 0x62, - 0xad, 0x1c, 0x29, 0x22, 0x01, 0xed, 0x01, 0x3c, 0x2b, 0x42, 0x49, 0x0a, - 0x0d, 0x4e, 0x16, 0x0d, 0x24, 0x25, 0x20, 0x24, 0x42, 0x1c, 0x1b, 0x1c, - 0x1e, 0x0a, 0x0f, 0x47, 0x0b, 0x09, 0x40, 0x36, 0x25, 0x36, 0xfe, 0xa1, - 0x37, 0x39, 0x34, 0x36, 0x69, 0x1a, 0x4d, 0xb9, 0x1a, 0x7c, 0x28, 0x24, - 0x25, 0x06, 0x73, 0x18, 0x14, 0x45, 0x69, 0x08, 0x34, 0x6d, 0x6b, 0x33, - 0x08, 0x28, 0x2c, 0x47, 0xfe, 0x39, 0xfe, 0xd2, 0x30, 0x2e, 0x27, 0x03, - 0x53, 0x01, 0x69, 0x69, 0x1a, 0xb9, 0x4d, 0x1a, 0x7b, 0x21, 0x05, 0x06, - 0x4d, 0xfd, 0x38, 0x01, 0x2f, 0x2f, 0x17, 0x14, 0x00, 0x05, 0x00, 0x24, - 0x00, 0x07, 0x04, 0xad, 0x04, 0x64, 0x00, 0x02, 0x00, 0x0d, 0x00, 0x22, - 0x00, 0x35, 0x00, 0x48, 0x00, 0x00, 0x01, 0x07, 0x33, 0x03, 0x33, 0x11, - 0x33, 0x15, 0x23, 0x15, 0x23, 0x35, 0x21, 0x35, 0x01, 0x26, 0x35, 0x34, - 0x3f, 0x01, 0x27, 0x37, 0x17, 0x27, 0x07, 0x06, 0x17, 0x16, 0x37, 0x21, - 0x15, 0x21, 0x22, 0x27, 0x26, 0x25, 0x06, 0x07, 0x23, 0x15, 0x27, 0x37, - 0x15, 0x33, 0x36, 0x37, 0x36, 0x27, 0x03, 0x37, 0x13, 0x16, 0x15, 0x14, - 0x01, 0x16, 0x1f, 0x01, 0x37, 0x07, 0x27, 0x37, 0x27, 0x26, 0x07, 0x06, - 0x07, 0x03, 0x27, 0x13, 0x36, 0x37, 0x36, 0x02, 0x81, 0xaf, 0xaf, 0x0f, - 0x87, 0x5c, 0x5c, 0x78, 0xfe, 0xdd, 0xfe, 0xe8, 0x22, 0x1d, 0x40, 0x2f, - 0xb3, 0x12, 0x2e, 0x4b, 0x10, 0x1c, 0x1e, 0x5b, 0x01, 0x35, 0xfe, 0x8f, - 0x39, 0x2b, 0x23, 0x04, 0x39, 0x41, 0x85, 0x80, 0x9f, 0x9f, 0x97, 0x2c, - 0x14, 0x13, 0x33, 0x9a, 0x67, 0xb9, 0x1d, 0xfd, 0xa3, 0x80, 0x4a, 0x40, - 0x30, 0x13, 0xb3, 0x2e, 0x4b, 0x1d, 0x30, 0x30, 0x28, 0x9b, 0x68, 0xb8, - 0x1d, 0x2b, 0x24, 0x02, 0x77, 0xc4, 0x01, 0x2c, 0xfe, 0xd4, 0x48, 0x6d, - 0x6d, 0x49, 0xfe, 0xde, 0x3b, 0x3c, 0x37, 0x39, 0x6f, 0x1c, 0x51, 0xc4, - 0x1c, 0x83, 0x2b, 0x26, 0x27, 0x06, 0x79, 0x19, 0x15, 0x4a, 0x70, 0x08, - 0x37, 0x73, 0x71, 0x35, 0x08, 0x2a, 0x2f, 0x4b, 0x01, 0x0c, 0x3c, 0xfe, - 0xc1, 0x32, 0x32, 0x29, 0x03, 0x85, 0x01, 0x6f, 0x6f, 0x1c, 0xc4, 0x51, - 0x1b, 0x83, 0x22, 0x04, 0x07, 0x52, 0xfe, 0xf5, 0x3b, 0x01, 0x40, 0x32, - 0x19, 0x15, 0x00, 0x00, 0x00, 0x04, 0x00, 0x3e, 0x00, 0x09, 0x04, 0x93, - 0x04, 0x33, 0x00, 0x1d, 0x00, 0x32, 0x00, 0x45, 0x00, 0x58, 0x00, 0x00, - 0x01, 0x21, 0x15, 0x23, 0x15, 0x32, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, - 0x06, 0x23, 0x22, 0x26, 0x27, 0x35, 0x1e, 0x01, 0x33, 0x32, 0x36, 0x35, - 0x34, 0x26, 0x23, 0x22, 0x06, 0x07, 0x01, 0x26, 0x35, 0x34, 0x3f, 0x01, - 0x27, 0x37, 0x17, 0x27, 0x07, 0x06, 0x17, 0x16, 0x37, 0x21, 0x15, 0x21, - 0x22, 0x27, 0x26, 0x25, 0x06, 0x07, 0x23, 0x15, 0x27, 0x37, 0x15, 0x33, - 0x36, 0x37, 0x36, 0x27, 0x03, 0x37, 0x13, 0x16, 0x15, 0x14, 0x01, 0x16, - 0x1f, 0x01, 0x37, 0x07, 0x27, 0x37, 0x27, 0x26, 0x07, 0x06, 0x0f, 0x01, - 0x27, 0x13, 0x36, 0x37, 0x36, 0x01, 0xca, 0x01, 0x48, 0xe6, 0x04, 0x1f, - 0x11, 0x65, 0x76, 0x79, 0x6e, 0x24, 0x4c, 0x32, 0x37, 0x43, 0x27, 0x3c, - 0x43, 0x43, 0x3c, 0x1c, 0x3b, 0x32, 0xfe, 0x95, 0x20, 0x1b, 0x3d, 0x2d, - 0xab, 0x12, 0x2d, 0x48, 0x0e, 0x1a, 0x1d, 0x57, 0x01, 0x27, 0xfe, 0xa0, - 0x37, 0x29, 0x22, 0x04, 0x09, 0x3e, 0x80, 0x79, 0x99, 0x99, 0x90, 0x2a, - 0x12, 0x13, 0x31, 0x93, 0x63, 0xb1, 0x1a, 0xfd, 0xbf, 0x7b, 0x46, 0x3d, - 0x2e, 0x13, 0xaa, 0x2c, 0x48, 0x1c, 0x2d, 0x2e, 0x26, 0x95, 0x63, 0xb0, - 0x1c, 0x29, 0x22, 0x02, 0xb8, 0x45, 0x52, 0x05, 0x55, 0x48, 0x48, 0x53, - 0x0a, 0x0b, 0x53, 0x17, 0x0d, 0x2f, 0x28, 0x2a, 0x2e, 0x09, 0x12, 0xfe, - 0xc8, 0x38, 0x39, 0x35, 0x36, 0x6a, 0x1a, 0x4e, 0xbb, 0x1b, 0x7e, 0x28, - 0x25, 0x25, 0x06, 0x74, 0x18, 0x14, 0x47, 0x6b, 0x08, 0x35, 0x6e, 0x6d, - 0x33, 0x08, 0x28, 0x2c, 0x48, 0x01, 0x00, 0x3a, 0xfe, 0xcf, 0x30, 0x30, - 0x27, 0x03, 0x5c, 0x01, 0x6a, 0x69, 0x1a, 0xbb, 0x4e, 0x19, 0x7d, 0x21, - 0x04, 0x07, 0x4e, 0xff, 0x39, 0x01, 0x31, 0x2f, 0x18, 0x14, 0x00, 0x00, - 0x00, 0x05, 0x00, 0x4b, 0x00, 0x00, 0x04, 0x86, 0x04, 0x12, 0x00, 0x09, - 0x00, 0x22, 0x00, 0x37, 0x00, 0x4a, 0x00, 0x5d, 0x00, 0x00, 0x01, 0x22, - 0x06, 0x14, 0x16, 0x33, 0x32, 0x36, 0x34, 0x26, 0x37, 0x15, 0x2e, 0x01, - 0x23, 0x22, 0x06, 0x07, 0x06, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x06, - 0x23, 0x22, 0x26, 0x35, 0x34, 0x36, 0x33, 0x32, 0x16, 0x01, 0x26, 0x35, - 0x34, 0x3f, 0x01, 0x27, 0x37, 0x17, 0x27, 0x07, 0x06, 0x17, 0x16, 0x37, - 0x21, 0x15, 0x21, 0x22, 0x27, 0x26, 0x25, 0x06, 0x07, 0x23, 0x15, 0x27, - 0x37, 0x15, 0x33, 0x36, 0x37, 0x36, 0x2f, 0x01, 0x37, 0x13, 0x16, 0x15, - 0x14, 0x01, 0x16, 0x1f, 0x01, 0x37, 0x07, 0x27, 0x37, 0x27, 0x26, 0x07, - 0x06, 0x0f, 0x01, 0x27, 0x13, 0x36, 0x37, 0x36, 0x02, 0x5d, 0x27, 0x30, - 0x30, 0x27, 0x2a, 0x2f, 0x2f, 0x6c, 0x2b, 0x32, 0x18, 0x3e, 0x41, 0x02, - 0x05, 0x42, 0x28, 0x53, 0x60, 0x64, 0x54, 0x5e, 0x64, 0x79, 0x67, 0x1b, - 0x37, 0xfd, 0x9d, 0x1f, 0x1b, 0x3c, 0x2c, 0xa7, 0x11, 0x2b, 0x47, 0x0e, - 0x1a, 0x1c, 0x55, 0x01, 0x20, 0xfe, 0xa8, 0x35, 0x29, 0x20, 0x03, 0xf0, - 0x3c, 0x7c, 0x77, 0x95, 0x95, 0x8d, 0x29, 0x12, 0x11, 0x2f, 0x90, 0x61, - 0xad, 0x1a, 0xfd, 0xcb, 0x79, 0x44, 0x3c, 0x2c, 0x11, 0xa7, 0x2b, 0x47, - 0x1b, 0x2c, 0x2c, 0x26, 0x91, 0x61, 0xab, 0x1c, 0x28, 0x21, 0x01, 0xdb, - 0x2e, 0x54, 0x2d, 0x2d, 0x54, 0x2e, 0xc0, 0x48, 0x0f, 0x0a, 0x44, 0x26, - 0x05, 0x1d, 0x52, 0x45, 0x43, 0x53, 0x75, 0x6b, 0x66, 0x7b, 0x08, 0xfd, - 0xdc, 0x37, 0x38, 0x33, 0x35, 0x68, 0x1a, 0x4c, 0xb7, 0x1a, 0x7b, 0x28, - 0x23, 0x24, 0x05, 0x71, 0x18, 0x13, 0x45, 0x69, 0x07, 0x34, 0x6c, 0x6a, - 0x32, 0x08, 0x27, 0x2b, 0x47, 0xfa, 0x38, 0xfe, 0xd6, 0x2f, 0x2e, 0x26, - 0x03, 0x48, 0x01, 0x68, 0x67, 0x1a, 0xb7, 0x4c, 0x19, 0x7a, 0x20, 0x04, - 0x06, 0x4c, 0xfa, 0x38, 0x01, 0x2a, 0x2e, 0x18, 0x13, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x2d, 0x00, 0x0c, 0x04, 0xa4, 0x04, 0x58, 0x00, 0x06, - 0x00, 0x1b, 0x00, 0x2e, 0x00, 0x41, 0x00, 0x00, 0x01, 0x21, 0x15, 0x03, - 0x23, 0x13, 0x21, 0x01, 0x26, 0x35, 0x34, 0x3f, 0x01, 0x27, 0x37, 0x17, - 0x27, 0x07, 0x06, 0x17, 0x16, 0x37, 0x21, 0x15, 0x21, 0x22, 0x27, 0x26, - 0x25, 0x06, 0x07, 0x23, 0x15, 0x27, 0x37, 0x15, 0x33, 0x36, 0x37, 0x36, - 0x27, 0x03, 0x37, 0x13, 0x16, 0x15, 0x14, 0x01, 0x16, 0x1f, 0x01, 0x37, - 0x07, 0x27, 0x37, 0x27, 0x26, 0x07, 0x06, 0x07, 0x03, 0x27, 0x13, 0x36, - 0x37, 0x36, 0x01, 0xb2, 0x01, 0x81, 0xcc, 0x6e, 0xbf, 0xfe, 0xfa, 0xfe, - 0x9c, 0x21, 0x1d, 0x3f, 0x2f, 0xb1, 0x12, 0x2e, 0x4a, 0x0f, 0x1b, 0x1e, - 0x59, 0x01, 0x30, 0xfe, 0x95, 0x38, 0x2b, 0x22, 0x04, 0x28, 0x40, 0x83, - 0x7d, 0x9e, 0x9e, 0x94, 0x2c, 0x13, 0x12, 0x32, 0x97, 0x66, 0xb6, 0x1c, - 0xfd, 0xac, 0x7f, 0x48, 0x3f, 0x2f, 0x13, 0xaf, 0x2d, 0x4a, 0x1d, 0x2e, - 0x30, 0x27, 0x99, 0x66, 0xb4, 0x1e, 0x2a, 0x23, 0x02, 0xc0, 0x26, 0xfe, - 0x4b, 0x01, 0x94, 0xfe, 0x1c, 0x3a, 0x3b, 0x36, 0x38, 0x6e, 0x1b, 0x50, - 0xc1, 0x1b, 0x81, 0x2a, 0x25, 0x27, 0x06, 0x77, 0x19, 0x14, 0x49, 0x6e, - 0x08, 0x37, 0x72, 0x70, 0x35, 0x08, 0x29, 0x2e, 0x4a, 0x01, 0x08, 0x3c, - 0xfe, 0xc6, 0x32, 0x31, 0x28, 0x03, 0x76, 0x01, 0x6d, 0x6d, 0x1b, 0xc1, - 0x51, 0x1a, 0x81, 0x22, 0x05, 0x07, 0x50, 0xfe, 0xf9, 0x3b, 0x01, 0x3a, - 0x31, 0x19, 0x14, 0x00, 0x00, 0x03, 0x00, 0x2d, 0x00, 0x00, 0x04, 0xa4, - 0x04, 0x4b, 0x00, 0x14, 0x00, 0x27, 0x00, 0x3a, 0x00, 0x00, 0x37, 0x26, - 0x35, 0x34, 0x3f, 0x01, 0x27, 0x37, 0x17, 0x27, 0x07, 0x06, 0x17, 0x16, - 0x37, 0x21, 0x15, 0x21, 0x22, 0x27, 0x26, 0x25, 0x06, 0x07, 0x23, 0x15, - 0x27, 0x37, 0x15, 0x33, 0x36, 0x37, 0x36, 0x27, 0x03, 0x37, 0x13, 0x16, - 0x15, 0x14, 0x01, 0x16, 0x1f, 0x01, 0x37, 0x07, 0x27, 0x37, 0x27, 0x26, - 0x07, 0x06, 0x07, 0x03, 0x27, 0x13, 0x36, 0x37, 0x36, 0x4e, 0x21, 0x1d, - 0x3f, 0x2f, 0xb1, 0x12, 0x2e, 0x4a, 0x0f, 0x1b, 0x1e, 0x59, 0x01, 0x30, - 0xfe, 0x95, 0x38, 0x2b, 0x22, 0x04, 0x28, 0x40, 0x83, 0x7d, 0x9e, 0x9e, - 0x94, 0x2c, 0x13, 0x12, 0x32, 0x97, 0x66, 0xb6, 0x1c, 0xfd, 0xac, 0x7f, - 0x48, 0x3f, 0x2f, 0x13, 0xaf, 0x2d, 0x4a, 0x1d, 0x2e, 0x30, 0x27, 0x99, - 0x66, 0xb4, 0x1e, 0x2a, 0x23, 0x88, 0x3a, 0x3c, 0x36, 0x38, 0x6d, 0x1b, - 0x50, 0xc0, 0x1b, 0x81, 0x2a, 0x26, 0x26, 0x06, 0x77, 0x19, 0x14, 0x48, - 0x6e, 0x07, 0x37, 0x71, 0x70, 0x35, 0x09, 0x29, 0x2e, 0x4a, 0x01, 0x08, - 0x3b, 0xfe, 0xc6, 0x31, 0x31, 0x29, 0x03, 0x77, 0x01, 0x6e, 0x6c, 0x1b, - 0xc1, 0x50, 0x1a, 0x82, 0x21, 0x04, 0x07, 0x50, 0xfe, 0xf8, 0x3b, 0x01, - 0x3b, 0x31, 0x19, 0x14, 0x00, 0x06, 0x00, 0x39, 0xff, 0xff, 0x04, 0x98, - 0x04, 0x39, 0x00, 0x10, 0x00, 0x1a, 0x00, 0x27, 0x00, 0x39, 0x00, 0x48, - 0x00, 0x52, 0x00, 0x00, 0x01, 0x21, 0x32, 0x1f, 0x01, 0x37, 0x33, 0x15, - 0x06, 0x07, 0x21, 0x35, 0x36, 0x37, 0x03, 0x26, 0x23, 0x07, 0x32, 0x1f, - 0x01, 0x07, 0x26, 0x27, 0x36, 0x37, 0x36, 0x01, 0x16, 0x15, 0x17, 0x14, - 0x07, 0x06, 0x2b, 0x01, 0x26, 0x27, 0x36, 0x37, 0x05, 0x16, 0x17, 0x27, - 0x06, 0x0f, 0x01, 0x17, 0x23, 0x03, 0x27, 0x36, 0x37, 0x36, 0x35, 0x27, - 0x35, 0x33, 0x01, 0x33, 0x15, 0x21, 0x32, 0x37, 0x33, 0x14, 0x03, 0x06, - 0x2b, 0x01, 0x15, 0x23, 0x2f, 0x01, 0x17, 0x11, 0x07, 0x23, 0x22, 0x2f, - 0x01, 0x34, 0x37, 0x02, 0x18, 0x01, 0x24, 0x2c, 0x19, 0x37, 0x4a, 0x05, - 0x76, 0x0c, 0xfe, 0xff, 0x49, 0x03, 0x94, 0x1a, 0x0a, 0x4d, 0x4f, 0x20, - 0x24, 0x90, 0xc9, 0x14, 0x70, 0x10, 0x25, 0x02, 0x84, 0x7c, 0x02, 0x49, - 0x0b, 0x1e, 0x5e, 0x0b, 0x83, 0x12, 0x97, 0xfd, 0x5b, 0x80, 0x01, 0x54, - 0x90, 0x03, 0x02, 0x04, 0x04, 0x97, 0x06, 0x03, 0x3c, 0x14, 0x4b, 0xab, - 0x02, 0x22, 0x01, 0x01, 0x28, 0x19, 0x16, 0x02, 0x96, 0x12, 0x18, 0x99, - 0x03, 0x7e, 0x47, 0x04, 0x04, 0xd9, 0x57, 0x24, 0x03, 0x3f, 0x04, 0x38, - 0x3f, 0x5d, 0x29, 0x02, 0xce, 0x10, 0x04, 0x28, 0x07, 0x01, 0x09, 0x13, - 0x03, 0x45, 0x41, 0xf7, 0x73, 0x0f, 0xc2, 0x16, 0x23, 0xfe, 0xc0, 0xd0, - 0x11, 0x1e, 0x4c, 0x2c, 0x06, 0x0c, 0xeb, 0x11, 0x54, 0x14, 0xd8, 0x0a, - 0x30, 0xf8, 0x0c, 0x1f, 0x15, 0x01, 0x04, 0x18, 0x18, 0x60, 0x1e, 0x09, - 0x2b, 0x02, 0xfe, 0xfc, 0x57, 0x14, 0x07, 0xfe, 0xfb, 0x11, 0x56, 0xdb, - 0x84, 0x04, 0xfe, 0xff, 0x04, 0x60, 0x24, 0x24, 0x61, 0x00, 0x00, 0x00, - 0x00, 0x07, 0x00, 0x2e, 0x00, 0x07, 0x04, 0xa3, 0x04, 0x7c, 0x00, 0x13, - 0x00, 0x25, 0x00, 0x32, 0x00, 0x3c, 0x00, 0x4a, 0x00, 0x5c, 0x00, 0x65, - 0x00, 0x00, 0x01, 0x33, 0x20, 0x13, 0x16, 0x1d, 0x01, 0x10, 0x05, 0x06, - 0x2b, 0x01, 0x20, 0x03, 0x26, 0x3d, 0x01, 0x10, 0x37, 0x36, 0x17, 0x15, - 0x32, 0x1f, 0x01, 0x15, 0x06, 0x07, 0x15, 0x33, 0x36, 0x37, 0x23, 0x07, - 0x26, 0x27, 0x26, 0x23, 0x05, 0x16, 0x33, 0x36, 0x37, 0x26, 0x23, 0x26, - 0x23, 0x22, 0x07, 0x06, 0x07, 0x05, 0x15, 0x17, 0x33, 0x32, 0x37, 0x34, - 0x2f, 0x01, 0x22, 0x05, 0x17, 0x06, 0x07, 0x14, 0x1f, 0x01, 0x33, 0x34, - 0x3f, 0x01, 0x33, 0x17, 0x27, 0x05, 0x07, 0x16, 0x17, 0x33, 0x35, 0x37, - 0x33, 0x32, 0x3f, 0x01, 0x35, 0x23, 0x06, 0x2b, 0x01, 0x27, 0x35, 0x05, - 0x06, 0x1d, 0x01, 0x14, 0x1f, 0x01, 0x33, 0x35, 0x02, 0x5e, 0x15, 0x01, - 0x2d, 0xb9, 0x4a, 0xfe, 0xce, 0x7c, 0x8b, 0x03, 0xfe, 0xb7, 0xb0, 0x40, - 0xf1, 0x91, 0x68, 0x1d, 0x27, 0x5c, 0x14, 0x2d, 0xd6, 0x07, 0x65, 0x02, - 0x40, 0x3c, 0x0e, 0x10, 0x13, 0xfe, 0x1e, 0xb9, 0x06, 0x03, 0x72, 0x32, - 0x12, 0x16, 0x26, 0x48, 0x29, 0x3b, 0x0a, 0x01, 0xe8, 0x75, 0x5a, 0x4a, - 0x14, 0x4d, 0x1f, 0x0b, 0xfc, 0xcd, 0x3d, 0x39, 0x08, 0x6a, 0x16, 0x02, - 0x15, 0x6c, 0x07, 0x3a, 0x6a, 0x01, 0x80, 0x67, 0x05, 0x62, 0x03, 0x04, - 0x83, 0x1c, 0x2e, 0x51, 0x02, 0x11, 0x1a, 0xf1, 0x04, 0xfe, 0x69, 0x32, - 0x51, 0x14, 0xc0, 0x04, 0x7c, 0xfe, 0xe9, 0x85, 0x9d, 0x05, 0xfe, 0xb6, - 0xb3, 0x3a, 0x01, 0x2a, 0x7f, 0x7d, 0x28, 0x01, 0x0b, 0xb8, 0x64, 0x70, - 0x02, 0x52, 0x9d, 0x02, 0x11, 0x18, 0x02, 0x06, 0xb7, 0x21, 0x68, 0x11, - 0x09, 0xdc, 0x6a, 0x0b, 0xc4, 0x60, 0x0e, 0x5d, 0x5f, 0x17, 0xa9, 0x03, - 0xcc, 0x69, 0x24, 0x78, 0x3a, 0x2d, 0x28, 0x5e, 0x25, 0x11, 0xb1, 0x2c, - 0x33, 0x13, 0xbd, 0x22, 0xb8, 0xd8, 0xbf, 0x02, 0xb4, 0x45, 0x05, 0x61, - 0x87, 0x02, 0x0c, 0x05, 0x48, 0x4d, 0x50, 0x1e, 0x09, 0x45, 0x1f, 0x03, - 0xde, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x37, 0x00, 0x04, 0x04, 0x9a, - 0x04, 0x67, 0x00, 0x0f, 0x00, 0x20, 0x00, 0x2f, 0x00, 0x3a, 0x00, 0x42, - 0x00, 0x52, 0x00, 0x60, 0x00, 0x6a, 0x00, 0x00, 0x01, 0x20, 0x13, 0x16, - 0x15, 0x10, 0x05, 0x06, 0x23, 0x20, 0x03, 0x26, 0x35, 0x10, 0x25, 0x36, - 0x01, 0x10, 0x05, 0x16, 0x3b, 0x01, 0x20, 0x13, 0x36, 0x35, 0x10, 0x25, - 0x26, 0x23, 0x20, 0x03, 0x06, 0x01, 0x33, 0x32, 0x1f, 0x01, 0x37, 0x15, - 0x06, 0x07, 0x23, 0x35, 0x37, 0x26, 0x2f, 0x01, 0x23, 0x32, 0x1f, 0x01, - 0x07, 0x23, 0x26, 0x27, 0x36, 0x37, 0x36, 0x01, 0x16, 0x1d, 0x01, 0x06, - 0x2b, 0x01, 0x27, 0x25, 0x33, 0x17, 0x07, 0x23, 0x27, 0x23, 0x06, 0x07, - 0x15, 0x26, 0x2f, 0x01, 0x34, 0x37, 0x27, 0x05, 0x33, 0x15, 0x33, 0x32, - 0x37, 0x15, 0x0f, 0x01, 0x23, 0x07, 0x15, 0x23, 0x27, 0x25, 0x33, 0x17, - 0x15, 0x07, 0x23, 0x22, 0x2f, 0x01, 0x36, 0x02, 0x6a, 0x01, 0x31, 0xb2, - 0x4d, 0xfe, 0xe3, 0x7b, 0x9d, 0xfe, 0xc7, 0xae, 0x47, 0x01, 0x26, 0x80, - 0xfe, 0x7a, 0x01, 0x0a, 0x76, 0x7f, 0x24, 0x01, 0x0e, 0xac, 0x45, 0xfe, - 0xf0, 0x78, 0x8a, 0xfe, 0xdd, 0xa8, 0x45, 0x01, 0xc5, 0xeb, 0x28, 0x12, - 0x2b, 0x3d, 0x52, 0x14, 0xcc, 0x3a, 0x6e, 0x13, 0x14, 0x3a, 0x44, 0x17, - 0x21, 0x73, 0x02, 0xab, 0x0d, 0x59, 0x15, 0x21, 0x01, 0xfa, 0x67, 0x10, - 0x51, 0x4b, 0x75, 0xfd, 0xa2, 0xcf, 0x6d, 0x02, 0x02, 0x3b, 0x02, 0x7d, - 0x04, 0x09, 0x75, 0x02, 0x41, 0x3b, 0x02, 0x3e, 0x05, 0xf5, 0x0f, 0x12, - 0x82, 0x11, 0x7f, 0x04, 0x05, 0x65, 0xfe, 0xe7, 0xe1, 0x04, 0x04, 0xb8, - 0x3d, 0x1d, 0x05, 0x01, 0x04, 0x67, 0xfe, 0xf1, 0x86, 0x9e, 0xfe, 0xc2, - 0xaf, 0x43, 0x01, 0x17, 0x79, 0xa5, 0x01, 0x3f, 0xb0, 0x3f, 0xfd, 0xcd, - 0xfe, 0xd4, 0xa2, 0x42, 0x01, 0x03, 0x7c, 0x93, 0x01, 0x2a, 0xa8, 0x3e, - 0xfe, 0xfc, 0x77, 0x01, 0x12, 0x34, 0x49, 0x20, 0x02, 0x99, 0x1a, 0x02, - 0x27, 0xbf, 0x1d, 0x09, 0x35, 0x40, 0xc2, 0x60, 0x0c, 0xa0, 0x13, 0x18, - 0xfe, 0xfd, 0xa9, 0x19, 0x11, 0x62, 0xc7, 0x43, 0xb7, 0x02, 0x24, 0xd0, - 0x10, 0x14, 0x09, 0xcd, 0x0d, 0x15, 0x6a, 0x24, 0xce, 0x48, 0x0f, 0x04, - 0xdb, 0x07, 0x05, 0x3f, 0xb2, 0x69, 0x04, 0xcf, 0x04, 0x4d, 0x21, 0x25, - 0x00, 0x05, 0x00, 0x2e, 0x00, 0x07, 0x04, 0xa3, 0x04, 0x7c, 0x00, 0x07, - 0x00, 0x17, 0x00, 0x1f, 0x00, 0x37, 0x00, 0x48, 0x00, 0x00, 0x01, 0x16, - 0x17, 0x32, 0x37, 0x26, 0x27, 0x06, 0x01, 0x20, 0x13, 0x16, 0x15, 0x10, - 0x05, 0x06, 0x23, 0x20, 0x03, 0x26, 0x35, 0x10, 0x25, 0x36, 0x01, 0x06, - 0x07, 0x16, 0x33, 0x36, 0x37, 0x26, 0x05, 0x15, 0x23, 0x06, 0x27, 0x2e, - 0x01, 0x37, 0x26, 0x36, 0x37, 0x32, 0x17, 0x36, 0x33, 0x1e, 0x01, 0x07, - 0x16, 0x06, 0x07, 0x06, 0x27, 0x23, 0x25, 0x10, 0x05, 0x16, 0x3b, 0x01, - 0x20, 0x13, 0x36, 0x35, 0x10, 0x25, 0x26, 0x23, 0x20, 0x03, 0x06, 0x01, - 0x04, 0x01, 0x8c, 0x6d, 0x4a, 0x42, 0x7c, 0x85, 0x01, 0x65, 0x01, 0x36, - 0xb4, 0x4f, 0xfe, 0xde, 0x7d, 0x9f, 0xfe, 0xc2, 0xb0, 0x49, 0x01, 0x2b, - 0x81, 0x01, 0x6f, 0x7c, 0x42, 0x4a, 0x6e, 0x8b, 0x02, 0x02, 0xfe, 0x9b, - 0x02, 0x5e, 0x8f, 0x6a, 0x61, 0x05, 0x03, 0x79, 0x67, 0x77, 0x61, 0x61, - 0x79, 0x67, 0x78, 0x02, 0x04, 0x61, 0x6a, 0x8f, 0x5e, 0x02, 0xfd, 0xe5, - 0x01, 0x0e, 0x77, 0x82, 0x24, 0x01, 0x13, 0xae, 0x46, 0xfe, 0xec, 0x79, - 0x8d, 0xfe, 0xd8, 0xaa, 0x46, 0x02, 0x47, 0x9c, 0x02, 0x9b, 0x94, 0x03, - 0x02, 0x01, 0xa2, 0xfe, 0xed, 0x87, 0xa2, 0xfe, 0xbd, 0xb1, 0x44, 0x01, - 0x1c, 0x7b, 0xa7, 0x01, 0x43, 0xb4, 0x3f, 0xfe, 0x60, 0x03, 0x94, 0x9b, - 0x02, 0x9c, 0x92, 0xcd, 0x16, 0x96, 0x06, 0x0c, 0x93, 0x42, 0x5d, 0x77, - 0x01, 0x82, 0x82, 0x01, 0x77, 0x5d, 0x42, 0x93, 0x0c, 0x06, 0x96, 0x4a, - 0xfe, 0xd0, 0xa5, 0x43, 0x01, 0x07, 0x7d, 0x96, 0x01, 0x2e, 0xab, 0x3f, - 0xfe, 0xf8, 0x79, 0x00, 0x00, 0x02, 0x00, 0x50, 0x00, 0x08, 0x04, 0x81, - 0x05, 0x25, 0x00, 0x18, 0x00, 0x2e, 0x00, 0x00, 0x01, 0x32, 0x15, 0x06, - 0x07, 0x17, 0x33, 0x32, 0x17, 0x07, 0x23, 0x17, 0x21, 0x16, 0x13, 0x37, - 0x17, 0x06, 0x07, 0x26, 0x03, 0x21, 0x22, 0x03, 0x34, 0x01, 0x06, 0x23, - 0x22, 0x2e, 0x01, 0x35, 0x34, 0x37, 0x36, 0x37, 0x17, 0x06, 0x07, 0x14, - 0x1e, 0x01, 0x32, 0x36, 0x37, 0x17, 0x06, 0x01, 0x8c, 0x86, 0x01, 0x70, - 0x15, 0xf1, 0x0b, 0x0e, 0x04, 0xf1, 0x0b, 0x01, 0x85, 0x0b, 0x7b, 0x75, - 0x2a, 0x04, 0xf0, 0x0e, 0x82, 0xfe, 0x5f, 0x0b, 0x4a, 0x01, 0xb9, 0x63, - 0x6c, 0x6c, 0xc6, 0x6d, 0x38, 0x1c, 0x2a, 0x23, 0x16, 0x02, 0x49, 0x85, - 0x91, 0x84, 0x25, 0x3c, 0x28, 0x05, 0x24, 0x7c, 0x8f, 0x01, 0xca, 0x80, - 0x03, 0x58, 0x06, 0xfe, 0xa4, 0x23, 0x7b, 0x07, 0x4e, 0x15, 0x01, 0x77, - 0x02, 0xc0, 0x74, 0xfb, 0x1b, 0x37, 0x6d, 0xc5, 0x6e, 0x6c, 0x64, 0x34, - 0x29, 0xbe, 0x35, 0x3a, 0x49, 0x85, 0x49, 0x49, 0x42, 0x93, 0x2c, 0x00, - 0x00, 0x03, 0x00, 0x3c, 0x00, 0x05, 0x04, 0x95, 0x04, 0x5f, 0x00, 0x17, - 0x00, 0x1b, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x34, 0x37, 0x36, 0x37, 0x36, - 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x01, 0x11, 0x21, 0x11, 0x25, 0x21, - 0x11, 0x21, 0x01, 0xff, 0x0e, 0x10, 0x17, 0x14, 0x20, 0x20, 0x15, 0x16, - 0x10, 0x0e, 0x0e, 0x0f, 0x17, 0x15, 0x20, 0x1f, 0x15, 0x17, 0x10, 0x0e, - 0xfe, 0x3e, 0x04, 0x57, 0xfc, 0x24, 0x03, 0x60, 0xfc, 0xa0, 0x02, 0x34, - 0x1f, 0x15, 0x17, 0x10, 0x0e, 0x0e, 0x10, 0x17, 0x14, 0x20, 0x20, 0x15, - 0x16, 0x10, 0x0e, 0x0e, 0x0f, 0x17, 0x15, 0xfd, 0xf1, 0x04, 0x5a, 0xfb, - 0xa6, 0x7c, 0x03, 0x62, 0x00, 0x04, 0x00, 0x3c, 0x00, 0x05, 0x04, 0x95, - 0x04, 0x5f, 0x00, 0x17, 0x00, 0x2f, 0x00, 0x33, 0x00, 0x37, 0x00, 0x00, - 0x01, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, - 0x01, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, - 0x01, 0x11, 0x21, 0x11, 0x25, 0x21, 0x11, 0x21, 0x01, 0x17, 0x0e, 0x10, - 0x17, 0x14, 0x20, 0x20, 0x15, 0x16, 0x10, 0x0e, 0x0e, 0x0f, 0x17, 0x15, - 0x20, 0x1f, 0x15, 0x17, 0x10, 0x0e, 0x01, 0xd1, 0x0e, 0x0f, 0x17, 0x15, - 0x20, 0x1f, 0x15, 0x17, 0x10, 0x0e, 0x0e, 0x10, 0x17, 0x14, 0x20, 0x20, - 0x15, 0x16, 0x10, 0x0e, 0xfd, 0x55, 0x04, 0x57, 0xfc, 0x24, 0x03, 0x60, - 0xfc, 0xa0, 0x01, 0x48, 0x1f, 0x15, 0x17, 0x0f, 0x0e, 0x0e, 0x0f, 0x17, - 0x15, 0x1f, 0x20, 0x15, 0x17, 0x0f, 0x0f, 0x0f, 0x0f, 0x17, 0x15, 0x01, - 0xf4, 0x20, 0x15, 0x16, 0x10, 0x0e, 0x0e, 0x0f, 0x17, 0x15, 0x20, 0x1f, - 0x15, 0x17, 0x10, 0x0e, 0x0e, 0x10, 0x17, 0x14, 0xfd, 0x09, 0x04, 0x5a, - 0xfb, 0xa6, 0x7c, 0x03, 0x62, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x3c, - 0x00, 0x05, 0x04, 0x95, 0x04, 0x5f, 0x00, 0x17, 0x00, 0x2f, 0x00, 0x47, - 0x00, 0x4b, 0x00, 0x4f, 0x00, 0x00, 0x01, 0x34, 0x37, 0x36, 0x37, 0x36, - 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x13, 0x34, 0x37, 0x36, 0x37, 0x36, - 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x13, 0x34, 0x37, 0x36, 0x37, 0x36, - 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x01, 0x11, 0x21, 0x11, 0x25, 0x21, - 0x11, 0x21, 0x01, 0x17, 0x0e, 0x10, 0x17, 0x14, 0x20, 0x20, 0x15, 0x16, - 0x10, 0x0e, 0x0e, 0x0f, 0x17, 0x15, 0x20, 0x1f, 0x15, 0x17, 0x10, 0x0e, - 0xe8, 0x0e, 0x10, 0x17, 0x14, 0x20, 0x20, 0x15, 0x16, 0x10, 0x0e, 0x0e, - 0x0f, 0x17, 0x15, 0x20, 0x1f, 0x15, 0x17, 0x10, 0x0e, 0xe9, 0x0e, 0x0f, - 0x17, 0x15, 0x20, 0x1f, 0x15, 0x17, 0x10, 0x0e, 0x0e, 0x10, 0x17, 0x14, - 0x20, 0x20, 0x15, 0x16, 0x10, 0x0e, 0xfd, 0x55, 0x04, 0x57, 0xfc, 0x24, - 0x03, 0x60, 0xfc, 0xa0, 0x01, 0x48, 0x1f, 0x15, 0x17, 0x0f, 0x0e, 0x0e, - 0x0f, 0x17, 0x15, 0x1f, 0x20, 0x15, 0x17, 0x0f, 0x0f, 0x0f, 0x0f, 0x17, - 0x15, 0x01, 0x0c, 0x1f, 0x15, 0x17, 0x10, 0x0e, 0x0e, 0x10, 0x17, 0x14, - 0x20, 0x20, 0x15, 0x16, 0x10, 0x0e, 0x0e, 0x0f, 0x17, 0x15, 0x01, 0x08, - 0x20, 0x15, 0x16, 0x10, 0x0e, 0x0e, 0x0f, 0x17, 0x15, 0x20, 0x1f, 0x15, - 0x17, 0x10, 0x0e, 0x0e, 0x10, 0x17, 0x14, 0xfd, 0x09, 0x04, 0x5a, 0xfb, - 0xa6, 0x7c, 0x03, 0x62, 0x00, 0x06, 0x00, 0x3c, 0x00, 0x01, 0x04, 0x95, - 0x04, 0x5b, 0x00, 0x17, 0x00, 0x2f, 0x00, 0x47, 0x00, 0x5f, 0x00, 0x63, - 0x00, 0x67, 0x00, 0x00, 0x01, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, - 0x27, 0x26, 0x27, 0x26, 0x01, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, - 0x27, 0x26, 0x27, 0x26, 0x25, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, - 0x27, 0x26, 0x27, 0x26, 0x01, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, - 0x27, 0x26, 0x27, 0x26, 0x01, 0x11, 0x21, 0x11, 0x25, 0x21, 0x11, 0x21, - 0x01, 0x17, 0x0e, 0x10, 0x17, 0x14, 0x20, 0x20, 0x15, 0x16, 0x10, 0x0e, - 0x0e, 0x0f, 0x17, 0x15, 0x20, 0x1f, 0x15, 0x17, 0x10, 0x0e, 0x01, 0xd1, - 0x0e, 0x0f, 0x17, 0x15, 0x20, 0x1f, 0x15, 0x17, 0x10, 0x0e, 0x0e, 0x10, - 0x17, 0x14, 0x20, 0x20, 0x15, 0x16, 0x10, 0x0e, 0xfe, 0x2f, 0x0e, 0x10, - 0x17, 0x14, 0x20, 0x20, 0x15, 0x16, 0x10, 0x0e, 0x0e, 0x0f, 0x17, 0x15, - 0x20, 0x1f, 0x15, 0x17, 0x10, 0x0e, 0x01, 0xd1, 0x0e, 0x0f, 0x17, 0x15, - 0x20, 0x1f, 0x15, 0x17, 0x10, 0x0e, 0x0e, 0x10, 0x17, 0x14, 0x20, 0x20, - 0x15, 0x16, 0x10, 0x0e, 0xfd, 0x55, 0x04, 0x57, 0xfc, 0x24, 0x03, 0x60, - 0xfc, 0xa0, 0x03, 0x18, 0x20, 0x15, 0x17, 0x0f, 0x0f, 0x0f, 0x0f, 0x17, - 0x15, 0x20, 0x1f, 0x15, 0x17, 0x0f, 0x0e, 0x0e, 0x0f, 0x17, 0x15, 0xfe, - 0x4b, 0x1f, 0x15, 0x17, 0x10, 0x0e, 0x0e, 0x10, 0x17, 0x14, 0x20, 0x20, - 0x15, 0x16, 0x10, 0x0e, 0x0e, 0x0f, 0x17, 0x15, 0x20, 0x1f, 0x15, 0x17, - 0x10, 0x0e, 0x0e, 0x10, 0x17, 0x14, 0x20, 0x20, 0x15, 0x16, 0x10, 0x0e, - 0x0e, 0x0f, 0x17, 0x15, 0x01, 0xf4, 0x20, 0x15, 0x17, 0x0f, 0x0f, 0x0f, - 0x0f, 0x17, 0x15, 0x20, 0x1f, 0x15, 0x17, 0x0f, 0x0e, 0x0e, 0x0f, 0x17, - 0x15, 0xfd, 0x08, 0x04, 0x5a, 0xfb, 0xa6, 0x7c, 0x03, 0x62, 0x00, 0x00, - 0x00, 0x07, 0x00, 0x3c, 0x00, 0x05, 0x04, 0x95, 0x04, 0x5f, 0x00, 0x17, - 0x00, 0x2f, 0x00, 0x47, 0x00, 0x5f, 0x00, 0x77, 0x00, 0x7b, 0x00, 0x7f, - 0x00, 0x00, 0x01, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, - 0x27, 0x26, 0x01, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, - 0x27, 0x26, 0x25, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, - 0x27, 0x26, 0x01, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, - 0x27, 0x26, 0x07, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, - 0x27, 0x26, 0x01, 0x11, 0x21, 0x11, 0x25, 0x21, 0x11, 0x21, 0x01, 0x17, - 0x0e, 0x10, 0x17, 0x14, 0x20, 0x20, 0x15, 0x16, 0x10, 0x0e, 0x0e, 0x0f, - 0x17, 0x15, 0x20, 0x1f, 0x15, 0x17, 0x10, 0x0e, 0x01, 0xd1, 0x0e, 0x0f, - 0x17, 0x15, 0x20, 0x1f, 0x15, 0x17, 0x10, 0x0e, 0x0e, 0x10, 0x17, 0x14, - 0x20, 0x20, 0x15, 0x16, 0x10, 0x0e, 0xfe, 0x2f, 0x0e, 0x10, 0x17, 0x14, - 0x20, 0x20, 0x15, 0x16, 0x10, 0x0e, 0x0e, 0x0f, 0x17, 0x15, 0x20, 0x1f, - 0x15, 0x17, 0x10, 0x0e, 0x01, 0xd1, 0x0e, 0x0f, 0x17, 0x15, 0x20, 0x1f, - 0x15, 0x17, 0x10, 0x0e, 0x0e, 0x10, 0x17, 0x14, 0x20, 0x20, 0x15, 0x16, - 0x10, 0x0e, 0xe9, 0x0e, 0x10, 0x17, 0x14, 0x20, 0x20, 0x15, 0x16, 0x10, - 0x0e, 0x0e, 0x0f, 0x17, 0x15, 0x20, 0x1f, 0x15, 0x17, 0x10, 0x0e, 0xfe, - 0x3e, 0x04, 0x57, 0xfc, 0x24, 0x03, 0x60, 0xfc, 0xa0, 0x03, 0x1c, 0x20, - 0x15, 0x16, 0x10, 0x0e, 0x0e, 0x0f, 0x17, 0x15, 0x20, 0x1f, 0x15, 0x17, - 0x10, 0x0e, 0x0e, 0x10, 0x17, 0x14, 0xfe, 0x4c, 0x1f, 0x15, 0x17, 0x0f, - 0x0e, 0x0e, 0x0f, 0x17, 0x15, 0x1f, 0x20, 0x15, 0x17, 0x0f, 0x0f, 0x0f, - 0x0f, 0x17, 0x15, 0x20, 0x1f, 0x15, 0x17, 0x0f, 0x0e, 0x0e, 0x0f, 0x17, - 0x15, 0x1f, 0x20, 0x15, 0x17, 0x0f, 0x0f, 0x0f, 0x0f, 0x17, 0x15, 0x01, - 0xf4, 0x20, 0x15, 0x16, 0x10, 0x0e, 0x0e, 0x0f, 0x17, 0x15, 0x20, 0x1f, - 0x15, 0x17, 0x10, 0x0e, 0x0e, 0x10, 0x17, 0x14, 0xc8, 0x1f, 0x15, 0x17, - 0x10, 0x0e, 0x0e, 0x10, 0x17, 0x14, 0x20, 0x20, 0x15, 0x16, 0x10, 0x0e, - 0x0e, 0x0f, 0x17, 0x15, 0xfd, 0xf1, 0x04, 0x5a, 0xfb, 0xa6, 0x7c, 0x03, - 0x62, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x3c, 0xff, 0xfc, 0x04, 0x95, - 0x04, 0x56, 0x00, 0x17, 0x00, 0x2f, 0x00, 0x47, 0x00, 0x5f, 0x00, 0x77, - 0x00, 0x8f, 0x00, 0x93, 0x00, 0x97, 0x00, 0x00, 0x01, 0x34, 0x37, 0x36, - 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x25, 0x34, 0x37, 0x36, - 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x11, 0x34, 0x37, 0x36, - 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x01, 0x34, 0x37, 0x36, - 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x25, 0x34, 0x37, 0x36, - 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x01, 0x34, 0x37, 0x36, - 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x01, 0x11, 0x21, 0x11, - 0x25, 0x21, 0x11, 0x21, 0x02, 0xe7, 0x0e, 0x10, 0x17, 0x14, 0x20, 0x20, - 0x15, 0x16, 0x10, 0x0e, 0x0e, 0x0f, 0x17, 0x15, 0x20, 0x1f, 0x15, 0x17, - 0x10, 0x0e, 0xfe, 0x30, 0x0e, 0x0f, 0x18, 0x14, 0x20, 0x20, 0x14, 0x17, - 0x10, 0x0e, 0x0e, 0x0f, 0x18, 0x14, 0x20, 0x20, 0x14, 0x17, 0x10, 0x0e, - 0x0e, 0x10, 0x17, 0x14, 0x20, 0x20, 0x15, 0x16, 0x10, 0x0e, 0x0e, 0x0f, - 0x17, 0x15, 0x20, 0x1f, 0x15, 0x17, 0x10, 0x0e, 0x01, 0xd1, 0x0e, 0x0f, - 0x17, 0x15, 0x20, 0x1f, 0x15, 0x17, 0x10, 0x0e, 0x0e, 0x10, 0x17, 0x14, - 0x20, 0x20, 0x15, 0x16, 0x10, 0x0e, 0xfe, 0x2f, 0x0e, 0x10, 0x17, 0x14, - 0x20, 0x20, 0x15, 0x16, 0x10, 0x0e, 0x0e, 0x0f, 0x17, 0x15, 0x20, 0x1f, - 0x15, 0x17, 0x10, 0x0e, 0x01, 0xd1, 0x0e, 0x0f, 0x17, 0x15, 0x20, 0x1f, - 0x15, 0x17, 0x10, 0x0e, 0x0e, 0x10, 0x17, 0x14, 0x20, 0x20, 0x15, 0x16, - 0x10, 0x0e, 0xfd, 0x55, 0x04, 0x57, 0xfc, 0x24, 0x03, 0x60, 0xfc, 0xa0, - 0x02, 0x2b, 0x20, 0x15, 0x16, 0x10, 0x0e, 0x0e, 0x0f, 0x17, 0x15, 0x20, - 0x20, 0x15, 0x16, 0x10, 0x0e, 0x0e, 0x0f, 0x17, 0x15, 0x20, 0x20, 0x15, - 0x16, 0x10, 0x0e, 0x0e, 0x0f, 0x17, 0x15, 0x20, 0x20, 0x15, 0x16, 0x10, - 0x0e, 0x0e, 0x0f, 0x17, 0x15, 0x01, 0x2e, 0x20, 0x15, 0x16, 0x10, 0x0e, - 0x0e, 0x0f, 0x17, 0x15, 0x20, 0x20, 0x15, 0x16, 0x10, 0x0e, 0x0e, 0x0f, - 0x17, 0x15, 0xfe, 0x00, 0x20, 0x15, 0x16, 0x10, 0x0e, 0x0e, 0x0f, 0x17, - 0x15, 0x20, 0x1f, 0x15, 0x17, 0x10, 0x0e, 0x0e, 0x10, 0x17, 0x14, 0x20, - 0x20, 0x15, 0x16, 0x10, 0x0e, 0x0e, 0x0f, 0x17, 0x15, 0x20, 0x1f, 0x15, - 0x17, 0x10, 0x0e, 0x0e, 0x10, 0x17, 0x14, 0x02, 0x40, 0x20, 0x15, 0x16, - 0x10, 0x0e, 0x0e, 0x0f, 0x17, 0x15, 0x20, 0x20, 0x15, 0x16, 0x10, 0x0e, - 0x0e, 0x0f, 0x17, 0x15, 0xfc, 0xe3, 0x04, 0x5a, 0xfb, 0xa6, 0x7c, 0x03, - 0x62, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x2e, 0x00, 0x00, 0x04, 0xa3, - 0x04, 0x74, 0x00, 0x0c, 0x00, 0x1b, 0x00, 0x29, 0x00, 0x00, 0x01, 0x32, - 0x04, 0x12, 0x10, 0x02, 0x04, 0x20, 0x24, 0x02, 0x10, 0x12, 0x24, 0x01, - 0x14, 0x1e, 0x01, 0x20, 0x3e, 0x01, 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, - 0x0e, 0x01, 0x04, 0x34, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x14, 0x0e, - 0x01, 0x23, 0x22, 0x26, 0x02, 0x68, 0x90, 0x01, 0x10, 0x9a, 0x96, 0xfe, - 0xf0, 0xfe, 0xd9, 0xfe, 0xf0, 0x96, 0x99, 0x01, 0x10, 0xfe, 0x98, 0x85, - 0xf0, 0x01, 0x07, 0xf0, 0x85, 0x89, 0xf0, 0x80, 0x7f, 0xf2, 0x87, 0x02, - 0xb9, 0x1a, 0x2e, 0x19, 0x18, 0x2e, 0x1a, 0x1b, 0x2d, 0x18, 0x19, 0x2d, - 0x04, 0x74, 0x93, 0xfe, 0xee, 0xfe, 0xd6, 0xfe, 0xf2, 0x97, 0x97, 0x01, - 0x0e, 0x01, 0x2a, 0x01, 0x12, 0x93, 0xfd, 0xc6, 0x84, 0xf0, 0x84, 0x84, - 0xf0, 0x84, 0x83, 0xf3, 0x82, 0x82, 0xf3, 0x9c, 0x32, 0x2e, 0x19, 0x19, - 0x2e, 0x32, 0x2f, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x2e, - 0x00, 0x05, 0x04, 0xa3, 0x04, 0x79, 0x00, 0x0c, 0x00, 0x1b, 0x00, 0x29, - 0x00, 0x36, 0x00, 0x00, 0x01, 0x32, 0x04, 0x12, 0x10, 0x02, 0x04, 0x20, - 0x24, 0x02, 0x10, 0x12, 0x24, 0x01, 0x14, 0x1e, 0x01, 0x20, 0x3e, 0x01, - 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x0e, 0x01, 0x04, 0x34, 0x3e, 0x01, - 0x33, 0x32, 0x1e, 0x01, 0x14, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x24, 0x32, - 0x1e, 0x01, 0x14, 0x0e, 0x01, 0x23, 0x22, 0x2e, 0x01, 0x34, 0x36, 0x02, - 0x68, 0x90, 0x01, 0x10, 0x9a, 0x96, 0xfe, 0xf0, 0xfe, 0xd9, 0xfe, 0xf0, - 0x96, 0x99, 0x01, 0x10, 0xfe, 0x98, 0x85, 0xf0, 0x01, 0x07, 0xf0, 0x85, - 0x89, 0xf0, 0x80, 0x7f, 0xf2, 0x87, 0x02, 0xb9, 0x1a, 0x2e, 0x19, 0x18, - 0x2e, 0x1a, 0x1b, 0x2d, 0x18, 0x19, 0x2d, 0xfd, 0xe6, 0x31, 0x2e, 0x1a, - 0x1a, 0x2d, 0x1a, 0x18, 0x2e, 0x1a, 0x1b, 0x04, 0x79, 0x93, 0xfe, 0xee, - 0xfe, 0xd6, 0xfe, 0xf2, 0x97, 0x97, 0x01, 0x0e, 0x01, 0x2a, 0x01, 0x12, - 0x93, 0xfd, 0xc6, 0x84, 0xf0, 0x84, 0x84, 0xf0, 0x84, 0x83, 0xf3, 0x82, - 0x82, 0xf3, 0x9c, 0x32, 0x2e, 0x19, 0x19, 0x2e, 0x32, 0x2f, 0x18, 0x18, - 0xa8, 0x18, 0x2f, 0x32, 0x2e, 0x19, 0x19, 0x2e, 0x32, 0x2f, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x2e, 0x00, 0x00, 0x04, 0xa3, 0x04, 0x74, 0x00, 0x0c, - 0x00, 0x1a, 0x00, 0x00, 0x01, 0x32, 0x04, 0x12, 0x10, 0x02, 0x04, 0x20, - 0x24, 0x02, 0x10, 0x12, 0x24, 0x01, 0x32, 0x3e, 0x01, 0x34, 0x2e, 0x01, - 0x23, 0x22, 0x0e, 0x01, 0x14, 0x1e, 0x01, 0x02, 0x68, 0x90, 0x01, 0x10, - 0x9a, 0x96, 0xfe, 0xf0, 0xfe, 0xd9, 0xfe, 0xf0, 0x96, 0x99, 0x01, 0x10, - 0x01, 0xb2, 0x18, 0x2d, 0x1b, 0x1a, 0x2e, 0x18, 0x19, 0x2e, 0x1a, 0x1b, - 0x2d, 0x04, 0x74, 0x93, 0xfe, 0xee, 0xfe, 0xd6, 0xfe, 0xf2, 0x97, 0x97, - 0x01, 0x0e, 0x01, 0x2a, 0x01, 0x12, 0x93, 0xfd, 0x66, 0x18, 0x2f, 0x32, - 0x2e, 0x19, 0x19, 0x2e, 0x32, 0x2f, 0x18, 0x00, 0x00, 0x03, 0x00, 0x2e, - 0xff, 0xf6, 0x04, 0xa3, 0x04, 0x6a, 0x00, 0x0c, 0x00, 0x1a, 0x00, 0x27, - 0x00, 0x00, 0x01, 0x32, 0x04, 0x12, 0x10, 0x02, 0x04, 0x20, 0x24, 0x02, - 0x10, 0x12, 0x24, 0x01, 0x32, 0x3e, 0x01, 0x34, 0x2e, 0x01, 0x23, 0x22, - 0x0e, 0x01, 0x14, 0x1e, 0x01, 0x24, 0x14, 0x1e, 0x01, 0x33, 0x32, 0x3e, - 0x01, 0x34, 0x2e, 0x01, 0x22, 0x06, 0x02, 0x68, 0x90, 0x01, 0x10, 0x9a, - 0x96, 0xfe, 0xf0, 0xfe, 0xd9, 0xfe, 0xf0, 0x96, 0x99, 0x01, 0x10, 0x01, - 0xb2, 0x18, 0x2d, 0x1b, 0x1a, 0x2e, 0x18, 0x19, 0x2e, 0x1a, 0x1b, 0x2d, - 0xfd, 0x71, 0x1a, 0x2e, 0x18, 0x1a, 0x2d, 0x1a, 0x1a, 0x2e, 0x31, 0x2d, - 0x04, 0x6a, 0x93, 0xfe, 0xee, 0xfe, 0xd6, 0xfe, 0xf2, 0x97, 0x97, 0x01, - 0x0e, 0x01, 0x2a, 0x01, 0x12, 0x93, 0xfd, 0x66, 0x18, 0x2f, 0x32, 0x2e, - 0x19, 0x19, 0x2e, 0x32, 0x2f, 0x18, 0x79, 0x32, 0x2e, 0x19, 0x19, 0x2e, - 0x32, 0x2f, 0x18, 0x18, 0x00, 0x01, 0x00, 0x52, 0x00, 0x07, 0x04, 0x7f, - 0x00, 0x96, 0x00, 0x03, 0x00, 0x00, 0x37, 0x21, 0x15, 0x21, 0x52, 0x04, - 0x2d, 0xfb, 0xd3, 0x96, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x52, - 0x00, 0x07, 0x04, 0x7f, 0x00, 0x96, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, - 0x37, 0x21, 0x15, 0x21, 0x25, 0x21, 0x15, 0x21, 0x52, 0x01, 0xb3, 0xfe, - 0x4d, 0x02, 0x7a, 0x01, 0xb3, 0xfe, 0x4d, 0x96, 0x8f, 0x8f, 0x8f, 0x00, - 0x00, 0x02, 0x00, 0x96, 0xff, 0xfe, 0x04, 0x3b, 0x04, 0xbb, 0x00, 0x09, - 0x00, 0x1a, 0x00, 0x00, 0x01, 0x36, 0x04, 0x37, 0x11, 0x06, 0x27, 0x26, - 0x07, 0x2f, 0x01, 0x23, 0x27, 0x33, 0x15, 0x23, 0x15, 0x36, 0x17, 0x16, - 0x37, 0x11, 0x06, 0x24, 0x07, 0x11, 0x23, 0x01, 0x25, 0x87, 0x01, 0x80, - 0xd7, 0xaf, 0xbe, 0x8f, 0xd2, 0x10, 0x50, 0x3d, 0x01, 0xdb, 0x3d, 0xcd, - 0xb0, 0xcc, 0xbc, 0xe7, 0xfe, 0x62, 0x92, 0x4e, 0x02, 0x1b, 0x2b, 0xbb, - 0x23, 0x01, 0xf0, 0x21, 0x66, 0x81, 0x22, 0x02, 0x4b, 0x2b, 0x2b, 0x15, - 0x21, 0x7c, 0x6f, 0x35, 0xfd, 0x9b, 0x3c, 0xc9, 0x3f, 0xfe, 0x31, 0x00, - 0x00, 0x01, 0x00, 0x73, 0x00, 0x05, 0x04, 0x5e, 0x05, 0x1e, 0x00, 0x10, - 0x00, 0x00, 0x13, 0x23, 0x27, 0x33, 0x15, 0x23, 0x15, 0x36, 0x17, 0x16, - 0x37, 0x11, 0x06, 0x24, 0x07, 0x11, 0x23, 0xb6, 0x42, 0x01, 0xec, 0x42, - 0xdd, 0xbd, 0xdc, 0xcb, 0xf9, 0xfe, 0x42, 0x9d, 0x54, 0x04, 0xf0, 0x2e, - 0x2e, 0x17, 0x23, 0x85, 0x78, 0x3a, 0xfd, 0x6b, 0x41, 0xd9, 0x44, 0xfe, - 0x0d, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x27, 0xff, 0xff, 0x04, 0xaa, - 0x04, 0x28, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x27, 0x07, 0x27, 0x37, 0x27, - 0x37, 0x17, 0x37, 0x17, 0x07, 0x17, 0x37, 0x27, 0x37, 0x17, 0x37, 0x17, - 0x07, 0x16, 0x13, 0x27, 0x07, 0x1f, 0x01, 0x07, 0x2f, 0x01, 0x0f, 0x01, - 0x27, 0x37, 0x02, 0x25, 0xed, 0x84, 0x8c, 0x84, 0x21, 0x62, 0x1f, 0x83, - 0x8c, 0x82, 0xec, 0xed, 0x83, 0x8d, 0x83, 0x1f, 0x61, 0x20, 0x32, 0x18, - 0xd6, 0xec, 0x7e, 0xe3, 0x83, 0xc0, 0x80, 0x7e, 0xc0, 0x83, 0xe1, 0x01, - 0xc4, 0xef, 0x84, 0x8d, 0x85, 0x1f, 0x62, 0x1f, 0x84, 0x8e, 0x84, 0xef, - 0xee, 0x85, 0x8e, 0x85, 0x20, 0x62, 0x1f, 0x50, 0xfe, 0xe6, 0xdc, 0xf0, - 0x7f, 0xc1, 0x84, 0xe4, 0x7f, 0x7f, 0xe4, 0x84, 0xc1, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x1f, 0x00, 0x00, 0x04, 0xb2, 0x04, 0xd3, 0x00, 0x0f, - 0x00, 0x52, 0x00, 0x00, 0x01, 0x14, 0x1e, 0x01, 0x33, 0x32, 0x3e, 0x01, - 0x35, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x0e, 0x01, 0x13, 0x15, 0x23, 0x06, - 0x23, 0x22, 0x27, 0x35, 0x23, 0x15, 0x23, 0x22, 0x26, 0x27, 0x26, 0x27, - 0x07, 0x03, 0x17, 0x07, 0x30, 0x17, 0x16, 0x17, 0x16, 0x17, 0x11, 0x21, - 0x35, 0x21, 0x35, 0x26, 0x27, 0x2e, 0x01, 0x34, 0x3e, 0x01, 0x33, 0x32, - 0x1e, 0x01, 0x14, 0x06, 0x07, 0x06, 0x07, 0x15, 0x21, 0x15, 0x21, 0x11, - 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x27, 0x37, 0x03, 0x27, 0x06, 0x07, - 0x06, 0x07, 0x06, 0x01, 0xfc, 0x20, 0x3a, 0x1f, 0x21, 0x39, 0x21, 0x22, - 0x39, 0x20, 0x1e, 0x3a, 0x21, 0xb8, 0x06, 0x1e, 0x20, 0x02, 0x03, 0x05, - 0x06, 0x89, 0xfb, 0x46, 0x0d, 0x0b, 0x47, 0x17, 0xf9, 0x46, 0x05, 0x3b, - 0x6b, 0x59, 0x5f, 0xfe, 0xcf, 0x01, 0x31, 0x15, 0x15, 0x32, 0x37, 0x38, - 0x65, 0x35, 0x36, 0x64, 0x3a, 0x38, 0x31, 0x16, 0x16, 0x01, 0x29, 0xfe, - 0xd7, 0x52, 0x4c, 0x6b, 0x3c, 0x02, 0x03, 0x47, 0xfa, 0x18, 0x47, 0x0a, - 0x0e, 0x45, 0x7e, 0x5e, 0x03, 0xff, 0x20, 0x3a, 0x20, 0x20, 0x3a, 0x20, - 0x20, 0x3b, 0x20, 0x20, 0x3b, 0xfb, 0xe5, 0x01, 0x02, 0x01, 0x01, 0x01, - 0x4e, 0x47, 0x0e, 0x0d, 0x35, 0x01, 0x0d, 0x65, 0x34, 0x05, 0x47, 0x28, - 0x20, 0x06, 0x02, 0x4c, 0x69, 0x29, 0x07, 0x0b, 0x1c, 0x65, 0x6e, 0x66, - 0x37, 0x37, 0x66, 0x6e, 0x65, 0x1c, 0x0b, 0x07, 0x29, 0x69, 0xfd, 0xb6, - 0x09, 0x1b, 0x28, 0x47, 0x03, 0x02, 0x34, 0x65, 0xfe, 0xf3, 0x35, 0x0d, - 0x0e, 0x47, 0x28, 0x1d, 0x00, 0x04, 0x00, 0x81, 0x00, 0x0c, 0x04, 0x50, - 0x04, 0x6d, 0x00, 0x04, 0x00, 0x09, 0x00, 0x39, 0x00, 0x59, 0x00, 0x00, - 0x25, 0x26, 0x27, 0x07, 0x16, 0x25, 0x17, 0x36, 0x37, 0x26, 0x01, 0x17, - 0x36, 0x37, 0x33, 0x06, 0x07, 0x17, 0x16, 0x17, 0x0e, 0x01, 0x07, 0x26, - 0x2f, 0x01, 0x06, 0x07, 0x27, 0x36, 0x37, 0x27, 0x07, 0x16, 0x17, 0x07, - 0x26, 0x27, 0x07, 0x06, 0x07, 0x22, 0x26, 0x27, 0x34, 0x3f, 0x01, 0x26, - 0x27, 0x33, 0x16, 0x17, 0x37, 0x01, 0x27, 0x09, 0x01, 0x07, 0x01, 0x15, - 0x27, 0x01, 0x37, 0x09, 0x01, 0x17, 0x01, 0x03, 0x26, 0x2f, 0x01, 0x1e, - 0x01, 0x17, 0x37, 0x26, 0x27, 0x13, 0x17, 0x23, 0x17, 0x06, 0x07, 0x17, - 0x3e, 0x01, 0x37, 0x07, 0x06, 0x07, 0x04, 0x0e, 0x24, 0x0f, 0x07, 0x03, - 0xfc, 0xb1, 0x06, 0x0f, 0x25, 0x38, 0x02, 0x18, 0xd0, 0x38, 0x14, 0x45, - 0x13, 0x46, 0x75, 0x2f, 0x01, 0x04, 0x2d, 0x20, 0x36, 0x03, 0x75, 0x4e, - 0x44, 0x1d, 0x4c, 0x32, 0xb7, 0xb6, 0x32, 0x4c, 0x1d, 0x45, 0x4e, 0x75, - 0x01, 0x2f, 0x1e, 0x38, 0x03, 0x30, 0x75, 0x46, 0x13, 0x44, 0x15, 0x38, - 0xd1, 0xfe, 0x6a, 0x18, 0x01, 0xe6, 0x01, 0xe7, 0x19, 0xfe, 0x55, 0x18, - 0x01, 0xbd, 0x04, 0xfe, 0x34, 0xfe, 0x35, 0x03, 0x01, 0xbf, 0xef, 0x42, - 0x25, 0x11, 0x1f, 0x79, 0x85, 0x06, 0x5c, 0x41, 0xea, 0x1b, 0x01, 0xcc, - 0x40, 0x59, 0x07, 0x84, 0x79, 0x1f, 0x10, 0x24, 0x46, 0x18, 0x0a, 0x30, - 0x06, 0x3d, 0x2f, 0x06, 0x30, 0x0a, 0x09, 0x01, 0x9f, 0xe4, 0x2c, 0x2d, - 0x58, 0x37, 0x88, 0x02, 0x30, 0x20, 0x19, 0x01, 0x03, 0x3b, 0x7e, 0x2a, - 0x06, 0x32, 0x0c, 0x25, 0xda, 0xda, 0x25, 0x0c, 0x32, 0x06, 0x2a, 0x7e, - 0x36, 0x08, 0x16, 0x1b, 0x39, 0x02, 0x88, 0x37, 0x58, 0x2d, 0x2c, 0xe4, - 0x01, 0xe3, 0x6f, 0xfd, 0xec, 0x02, 0x14, 0x6f, 0xfe, 0x03, 0x01, 0x1b, - 0x02, 0x10, 0x0b, 0xfd, 0xf2, 0x02, 0x0e, 0x0b, 0xfd, 0xf4, 0xfe, 0xf3, - 0x2b, 0x46, 0x01, 0x39, 0x64, 0x31, 0x0c, 0x1c, 0x29, 0x01, 0x0c, 0x1e, - 0xf0, 0x28, 0x1b, 0x0c, 0x31, 0x64, 0x39, 0x01, 0x43, 0x31, 0x00, 0x00, - 0x00, 0x05, 0x00, 0xbc, 0xff, 0xfd, 0x04, 0x15, 0x05, 0xec, 0x00, 0x03, - 0x00, 0x16, 0x00, 0x2a, 0x00, 0x43, 0x00, 0x54, 0x00, 0x00, 0x01, 0x16, - 0x27, 0x26, 0x13, 0x15, 0x06, 0x23, 0x22, 0x27, 0x35, 0x26, 0x37, 0x36, - 0x37, 0x15, 0x06, 0x15, 0x06, 0x04, 0x07, 0x23, 0x26, 0x03, 0x24, 0x27, - 0x26, 0x25, 0x15, 0x06, 0x15, 0x14, 0x04, 0x17, 0x06, 0x05, 0x27, 0x36, - 0x27, 0x26, 0x27, 0x11, 0x27, 0x13, 0x11, 0x27, 0x11, 0x24, 0x27, 0x36, - 0x37, 0x36, 0x17, 0x07, 0x17, 0x06, 0x27, 0x26, 0x07, 0x06, 0x04, 0x17, - 0x06, 0x05, 0x35, 0x24, 0x27, 0x36, 0x25, 0x27, 0x03, 0x2e, 0x01, 0x35, - 0x34, 0x3e, 0x01, 0x33, 0x32, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x07, 0x01, - 0x94, 0x44, 0x16, 0x24, 0xfa, 0x0c, 0x1c, 0x22, 0x04, 0xb6, 0x02, 0x06, - 0x9e, 0x40, 0x04, 0x01, 0x46, 0x02, 0x0e, 0x1c, 0xc6, 0xfe, 0xe8, 0x06, - 0x02, 0x01, 0x10, 0xaa, 0x02, 0x2c, 0x02, 0x04, 0xfe, 0xee, 0x02, 0xbc, - 0x06, 0x02, 0xc2, 0x4e, 0x4e, 0x4e, 0xfe, 0x76, 0x04, 0x0e, 0xd4, 0x46, - 0x38, 0x70, 0x5e, 0x4c, 0x62, 0x32, 0x0a, 0x04, 0x02, 0xf2, 0x06, 0x06, - 0xfe, 0x96, 0x01, 0x12, 0x02, 0x0c, 0xfe, 0xd8, 0x4e, 0x04, 0x16, 0x18, - 0x18, 0x2a, 0x16, 0x18, 0x2a, 0x18, 0x18, 0x14, 0x04, 0xb5, 0x1e, 0x2b, - 0x0b, 0xfb, 0x94, 0x42, 0x1d, 0x40, 0x30, 0x22, 0x41, 0x52, 0x19, 0x2f, - 0x18, 0x16, 0x30, 0x3f, 0x77, 0x41, 0x01, 0xb7, 0x25, 0x6f, 0x64, 0x2f, - 0x44, 0x26, 0x33, 0x2e, 0x59, 0x61, 0x51, 0x2f, 0x35, 0x23, 0x33, 0x24, - 0x22, 0xfe, 0xb4, 0x13, 0x03, 0x01, 0xfe, 0x81, 0x10, 0x01, 0x75, 0x13, - 0x8a, 0x90, 0x05, 0x04, 0x49, 0x1e, 0x19, 0x12, 0x27, 0x0d, 0x40, 0x33, - 0x2f, 0x75, 0x8a, 0x10, 0x3d, 0x20, 0x3d, 0x23, 0x6e, 0x07, 0x01, 0x2d, - 0x0b, 0x2e, 0x18, 0x19, 0x2e, 0x18, 0x18, 0x2e, 0x19, 0x18, 0x2e, 0x0b, - 0x00, 0x03, 0x00, 0x13, 0x00, 0x03, 0x04, 0xbe, 0x04, 0x77, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x33, 0x00, 0x00, 0x25, 0x0b, 0x01, 0x16, 0x25, 0x0b, - 0x01, 0x16, 0x01, 0x33, 0x32, 0x1d, 0x01, 0x14, 0x2b, 0x01, 0x13, 0x06, - 0x07, 0x0e, 0x01, 0x23, 0x22, 0x2e, 0x01, 0x37, 0x13, 0x21, 0x13, 0x16, - 0x0e, 0x01, 0x22, 0x26, 0x27, 0x26, 0x27, 0x13, 0x23, 0x26, 0x3d, 0x01, - 0x34, 0x3b, 0x01, 0x37, 0x17, 0x33, 0x37, 0x17, 0x33, 0x37, 0x04, 0x80, - 0xcf, 0xcf, 0xcf, 0xfe, 0x44, 0xcf, 0xcf, 0xcf, 0x02, 0xaf, 0xa0, 0x2a, - 0x1f, 0x91, 0xcf, 0x02, 0x24, 0x23, 0x82, 0x47, 0x46, 0x81, 0x48, 0x02, - 0xcc, 0xfd, 0xfa, 0xcd, 0x02, 0x48, 0x81, 0x8d, 0x82, 0x25, 0x23, 0x01, - 0xce, 0x99, 0x18, 0x2b, 0xa1, 0x28, 0x26, 0xbd, 0x61, 0x61, 0xbd, 0x27, - 0xc4, 0x02, 0x6d, 0xfd, 0x93, 0x39, 0x39, 0x02, 0x6d, 0xfd, 0x93, 0x39, - 0x02, 0xf9, 0x20, 0x12, 0x1e, 0xfd, 0x95, 0x33, 0x2e, 0x30, 0x35, 0x35, - 0x5f, 0x34, 0x02, 0x69, 0xfd, 0x97, 0x34, 0x5f, 0x35, 0x35, 0x30, 0x2e, - 0x33, 0x02, 0x6b, 0x0c, 0x16, 0x0b, 0x23, 0x74, 0x74, 0xf2, 0xf2, 0x74, - 0x00, 0x02, 0x00, 0x16, 0x00, 0x06, 0x04, 0xbb, 0x04, 0x6b, 0x00, 0x16, - 0x00, 0x22, 0x00, 0x00, 0x01, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x26, 0x27, 0x2e, 0x01, 0x07, 0x06, - 0x07, 0x27, 0x12, 0x01, 0x13, 0x23, 0x03, 0x23, 0x11, 0x23, 0x03, 0x23, - 0x03, 0x23, 0x13, 0x01, 0xd6, 0x8a, 0x76, 0x29, 0x25, 0x97, 0x38, 0x1b, - 0x0d, 0x20, 0x5f, 0x5e, 0xa8, 0x3e, 0x19, 0x3a, 0x6b, 0x7b, 0x95, 0x5a, - 0xac, 0x03, 0xb2, 0x47, 0x5f, 0x3f, 0xd7, 0x67, 0x01, 0xd6, 0x40, 0x60, - 0x48, 0x04, 0x2c, 0x3e, 0x06, 0x1e, 0x7c, 0x3a, 0x3d, 0x2b, 0x2c, 0x6a, - 0x2c, 0x2c, 0x3c, 0x86, 0x36, 0x4f, 0x2f, 0x32, 0xd9, 0x33, 0x01, 0x33, - 0xfe, 0x1d, 0xfe, 0x3c, 0x01, 0x62, 0xfe, 0x9e, 0x01, 0x62, 0xfe, 0x9e, - 0x01, 0xc4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x4a, 0xff, 0xfd, 0x04, 0x87, - 0x05, 0x1e, 0x00, 0x0d, 0x00, 0x31, 0x00, 0x00, 0x00, 0x14, 0x1e, 0x01, - 0x33, 0x32, 0x3e, 0x01, 0x34, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x13, 0x15, - 0x33, 0x16, 0x36, 0x37, 0x14, 0x04, 0x07, 0x06, 0x07, 0x23, 0x26, 0x37, - 0x26, 0x24, 0x03, 0x1e, 0x01, 0x37, 0x33, 0x35, 0x26, 0x27, 0x2e, 0x01, - 0x34, 0x3e, 0x01, 0x32, 0x1e, 0x01, 0x14, 0x06, 0x07, 0x06, 0x01, 0xcf, - 0x2c, 0x50, 0x2a, 0x2b, 0x50, 0x2c, 0x2e, 0x4e, 0x2b, 0x29, 0x50, 0xa4, - 0x05, 0x85, 0xc6, 0x97, 0xfe, 0x64, 0x22, 0x2f, 0x01, 0x25, 0x28, 0x02, - 0x04, 0xfe, 0x4d, 0x4d, 0xae, 0xd8, 0x7e, 0x06, 0x39, 0x35, 0x44, 0x4c, - 0x4d, 0x89, 0x91, 0x8b, 0x4e, 0x4d, 0x44, 0x32, 0x04, 0x29, 0x57, 0x4e, - 0x2c, 0x2c, 0x4e, 0x57, 0x50, 0x2a, 0x2a, 0xfe, 0x67, 0x88, 0x01, 0xa8, - 0x21, 0xca, 0x87, 0x84, 0x77, 0xd6, 0x9c, 0x8f, 0x73, 0x7e, 0x01, 0x0a, - 0x01, 0xd7, 0x0c, 0x87, 0x06, 0x1f, 0x26, 0x88, 0x97, 0x8a, 0x4a, 0x4a, - 0x8a, 0x97, 0x88, 0x26, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x1e, - 0x00, 0x00, 0x04, 0xb3, 0x04, 0xd3, 0x00, 0x3f, 0x00, 0x47, 0x00, 0x4f, - 0x00, 0x00, 0x00, 0x32, 0x1f, 0x01, 0x16, 0x17, 0x37, 0x16, 0x17, 0x07, - 0x16, 0x17, 0x37, 0x16, 0x17, 0x07, 0x16, 0x14, 0x07, 0x17, 0x06, 0x07, - 0x27, 0x06, 0x07, 0x17, 0x06, 0x07, 0x27, 0x06, 0x0f, 0x01, 0x06, 0x22, - 0x2f, 0x01, 0x26, 0x27, 0x07, 0x26, 0x27, 0x37, 0x26, 0x27, 0x07, 0x26, - 0x27, 0x37, 0x26, 0x34, 0x37, 0x27, 0x36, 0x37, 0x17, 0x36, 0x37, 0x27, - 0x36, 0x37, 0x17, 0x36, 0x3f, 0x01, 0x12, 0x20, 0x06, 0x10, 0x16, 0x20, - 0x36, 0x10, 0x06, 0x14, 0x06, 0x22, 0x26, 0x34, 0x36, 0x32, 0x02, 0x45, - 0x47, 0x23, 0x1a, 0x39, 0x36, 0x5c, 0x3e, 0x34, 0x32, 0x28, 0x1c, 0x70, - 0x1e, 0x0d, 0x5f, 0x04, 0x04, 0x5f, 0x0d, 0x1e, 0x70, 0x1c, 0x28, 0x32, - 0x34, 0x3e, 0x5c, 0x36, 0x39, 0x1a, 0x23, 0x47, 0x23, 0x1a, 0x3a, 0x35, - 0x5c, 0x3e, 0x34, 0x32, 0x28, 0x1c, 0x70, 0x1e, 0x0d, 0x5f, 0x04, 0x04, - 0x5f, 0x0d, 0x1e, 0x70, 0x1c, 0x28, 0x32, 0x34, 0x3e, 0x5c, 0x35, 0x3a, - 0x1a, 0xda, 0xfe, 0xd9, 0xd1, 0xd1, 0x01, 0x27, 0xd1, 0xe0, 0x4e, 0x6d, - 0x4e, 0x4e, 0x6d, 0x04, 0xd3, 0x04, 0x80, 0x0b, 0x19, 0x55, 0x25, 0x34, - 0x6d, 0x2b, 0x33, 0x0d, 0x45, 0x4a, 0x35, 0x1e, 0x3a, 0x1d, 0x36, 0x4a, - 0x45, 0x0d, 0x33, 0x2b, 0x6d, 0x34, 0x25, 0x54, 0x18, 0x0c, 0x7f, 0x05, - 0x05, 0x7f, 0x0c, 0x18, 0x54, 0x25, 0x34, 0x6d, 0x2b, 0x33, 0x0d, 0x45, - 0x4a, 0x36, 0x1d, 0x3a, 0x1e, 0x35, 0x4a, 0x45, 0x0d, 0x33, 0x2c, 0x6c, - 0x34, 0x25, 0x54, 0x18, 0x0b, 0x80, 0xff, 0x00, 0xd2, 0xfe, 0xd9, 0xd0, - 0xd0, 0x01, 0x27, 0x5c, 0x6e, 0x4d, 0x4d, 0x6e, 0x4d, 0x00, 0x00, 0x00, - 0x00, 0x0f, 0x00, 0x2a, 0x00, 0x0c, 0x04, 0xa7, 0x05, 0x3f, 0x00, 0x08, - 0x00, 0x0d, 0x00, 0x12, 0x00, 0x17, 0x00, 0x1c, 0x00, 0x21, 0x00, 0x26, - 0x00, 0x2b, 0x00, 0x30, 0x00, 0x35, 0x00, 0x3a, 0x00, 0x3f, 0x00, 0x44, - 0x00, 0x50, 0x00, 0x91, 0x00, 0x00, 0x00, 0x14, 0x1e, 0x01, 0x33, 0x26, - 0x37, 0x22, 0x06, 0x05, 0x16, 0x17, 0x37, 0x26, 0x27, 0x16, 0x17, 0x37, - 0x26, 0x27, 0x16, 0x17, 0x37, 0x26, 0x27, 0x16, 0x07, 0x37, 0x26, 0x27, - 0x16, 0x07, 0x17, 0x36, 0x27, 0x06, 0x07, 0x17, 0x36, 0x25, 0x17, 0x36, - 0x37, 0x06, 0x07, 0x17, 0x36, 0x37, 0x06, 0x07, 0x17, 0x36, 0x37, 0x06, - 0x1f, 0x01, 0x26, 0x37, 0x06, 0x17, 0x37, 0x26, 0x37, 0x06, 0x17, 0x37, - 0x26, 0x27, 0x06, 0x17, 0x22, 0x06, 0x15, 0x14, 0x16, 0x33, 0x32, 0x36, - 0x35, 0x34, 0x26, 0x27, 0x35, 0x26, 0x27, 0x2e, 0x01, 0x34, 0x3e, 0x01, - 0x33, 0x32, 0x1e, 0x01, 0x14, 0x06, 0x07, 0x06, 0x07, 0x33, 0x14, 0x23, - 0x15, 0x16, 0x17, 0x16, 0x17, 0x36, 0x37, 0x04, 0x17, 0x06, 0x23, 0x26, - 0x07, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x03, 0x15, 0x06, 0x23, 0x22, - 0x27, 0x35, 0x03, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x26, 0x07, 0x22, - 0x27, 0x36, 0x25, 0x16, 0x17, 0x36, 0x37, 0x36, 0x02, 0x31, 0x0f, 0x1b, - 0x10, 0x1a, 0x1a, 0x0f, 0x1c, 0x01, 0xb4, 0x61, 0x24, 0x17, 0x4f, 0x7f, - 0x60, 0x20, 0x22, 0x4e, 0x69, 0x42, 0x0e, 0x2a, 0x34, 0x6c, 0x2c, 0x01, - 0x34, 0x22, 0x55, 0x02, 0x15, 0x34, 0x02, 0x37, 0x29, 0x2c, 0x33, 0x28, - 0xfc, 0xe0, 0x17, 0x24, 0x61, 0x4d, 0x23, 0x22, 0x1f, 0x61, 0x54, 0x11, - 0x2a, 0x0e, 0x42, 0x46, 0x0d, 0x34, 0x01, 0x2c, 0x3d, 0x34, 0x34, 0x16, - 0x03, 0x23, 0x59, 0x33, 0x2c, 0x29, 0x06, 0xfd, 0x30, 0x42, 0x42, 0x30, - 0x2f, 0x43, 0x42, 0x4f, 0x03, 0x02, 0x10, 0x13, 0x13, 0x22, 0x12, 0x12, - 0x21, 0x13, 0x12, 0x11, 0x01, 0x03, 0x01, 0x01, 0x2d, 0x24, 0x03, 0x03, - 0x46, 0x13, 0x01, 0x24, 0x46, 0x4a, 0xdf, 0x46, 0x31, 0x04, 0x2e, 0x23, - 0x2d, 0x01, 0x0a, 0x14, 0x16, 0x07, 0x02, 0x2d, 0x23, 0x2d, 0x02, 0x32, - 0x4d, 0xdf, 0x4a, 0x46, 0x01, 0x24, 0x13, 0x47, 0x06, 0x08, 0x23, 0x05, - 0x09, 0x1e, 0x1b, 0x10, 0x38, 0x3c, 0x0f, 0x67, 0x37, 0x2a, 0x21, 0x32, - 0x11, 0x55, 0x36, 0x1d, 0x4a, 0x25, 0x6e, 0x3d, 0x11, 0x5f, 0x43, 0x7f, - 0x42, 0x07, 0x6e, 0x54, 0x87, 0x3e, 0x09, 0x72, 0x59, 0x77, 0x30, 0x17, - 0x64, 0x09, 0x22, 0x2a, 0x37, 0x0e, 0x5d, 0x1d, 0x36, 0x55, 0x24, 0x75, - 0x11, 0x3d, 0x6e, 0x3b, 0x77, 0x07, 0x42, 0x7f, 0x4c, 0x7a, 0x09, 0x3e, - 0x87, 0x5c, 0x65, 0x17, 0x30, 0x77, 0x5a, 0x33, 0x43, 0x2e, 0x31, 0x42, - 0x42, 0x31, 0x2e, 0x43, 0x28, 0x4e, 0x01, 0x02, 0x09, 0x22, 0x25, 0x22, - 0x12, 0x12, 0x22, 0x25, 0x22, 0x09, 0x02, 0x01, 0x01, 0x4d, 0x08, 0x23, - 0x03, 0x03, 0x70, 0x2e, 0x05, 0x50, 0x8f, 0x16, 0x16, 0x11, 0x12, 0x41, - 0x2e, 0x24, 0x07, 0xfd, 0x3b, 0x51, 0x13, 0x19, 0x57, 0x02, 0xb9, 0x07, - 0x24, 0x2e, 0x41, 0x0f, 0x0f, 0x1c, 0x17, 0x8e, 0x50, 0x05, 0x2d, 0x7b, - 0x09, 0x08, 0x22, 0x00, 0x00, 0x0f, 0x00, 0x52, 0x00, 0x0b, 0x04, 0x7f, - 0x04, 0xc7, 0x00, 0x0f, 0x00, 0x1a, 0x00, 0x26, 0x00, 0x2e, 0x00, 0x46, - 0x00, 0x52, 0x00, 0x8a, 0x00, 0x96, 0x00, 0x9e, 0x00, 0xa6, 0x00, 0xb2, - 0x00, 0xba, 0x00, 0xc2, 0x00, 0xca, 0x00, 0xd6, 0x00, 0x00, 0x01, 0x32, - 0x1e, 0x01, 0x15, 0x14, 0x0e, 0x01, 0x23, 0x22, 0x2e, 0x01, 0x35, 0x34, - 0x3e, 0x01, 0x07, 0x26, 0x27, 0x06, 0x07, 0x06, 0x16, 0x37, 0x36, 0x37, - 0x26, 0x25, 0x06, 0x07, 0x16, 0x17, 0x16, 0x37, 0x36, 0x27, 0x26, 0x27, - 0x06, 0x27, 0x16, 0x15, 0x14, 0x07, 0x36, 0x37, 0x26, 0x27, 0x26, 0x27, - 0x26, 0x27, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, - 0x16, 0x17, 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x37, 0x16, 0x17, - 0x16, 0x17, 0x36, 0x37, 0x36, 0x27, 0x26, 0x07, 0x06, 0x05, 0x37, 0x3e, - 0x01, 0x33, 0x32, 0x16, 0x17, 0x15, 0x36, 0x17, 0x16, 0x17, 0x16, 0x15, - 0x14, 0x07, 0x06, 0x07, 0x33, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x0e, - 0x01, 0x27, 0x23, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x06, - 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x26, 0x27, 0x26, 0x35, - 0x34, 0x37, 0x36, 0x37, 0x36, 0x05, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, - 0x06, 0x07, 0x16, 0x17, 0x36, 0x17, 0x06, 0x07, 0x16, 0x17, 0x16, 0x17, - 0x26, 0x25, 0x06, 0x07, 0x36, 0x37, 0x36, 0x37, 0x26, 0x27, 0x26, 0x27, - 0x26, 0x07, 0x06, 0x17, 0x16, 0x17, 0x36, 0x37, 0x36, 0x07, 0x06, 0x07, - 0x16, 0x17, 0x26, 0x35, 0x34, 0x17, 0x16, 0x17, 0x36, 0x37, 0x26, 0x27, - 0x26, 0x17, 0x16, 0x17, 0x36, 0x37, 0x06, 0x07, 0x06, 0x07, 0x06, 0x07, - 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x26, 0x02, 0x68, 0x10, - 0x1d, 0x10, 0x10, 0x1d, 0x10, 0x10, 0x1d, 0x10, 0x10, 0x1d, 0xb7, 0x40, - 0x39, 0x68, 0x29, 0x2c, 0x29, 0x52, 0x50, 0x7c, 0x0c, 0x01, 0x88, 0x05, - 0x0b, 0x7c, 0x50, 0x52, 0x15, 0x15, 0x2d, 0x2a, 0x67, 0x3a, 0x3e, 0x02, - 0x02, 0x2f, 0x2a, 0x2a, 0x59, 0x26, 0x28, 0x29, 0x28, 0x28, 0x27, 0x29, - 0x26, 0x01, 0x01, 0x26, 0x29, 0x27, 0x29, 0x28, 0x28, 0x29, 0x25, 0x03, - 0x14, 0x0c, 0x05, 0x40, 0x39, 0x66, 0x2b, 0x2e, 0x15, 0x15, 0x54, 0x52, - 0xfe, 0x22, 0x01, 0x1c, 0x60, 0x33, 0x33, 0x60, 0x1b, 0x8a, 0x5c, 0x5f, - 0x1a, 0x09, 0x1c, 0x2e, 0x6e, 0x01, 0x70, 0x2c, 0x1b, 0x09, 0x1a, 0xb7, - 0x8c, 0x01, 0x1b, 0x30, 0x30, 0x34, 0x34, 0x31, 0x2f, 0x1c, 0x8b, 0xb8, - 0x19, 0x09, 0x1a, 0x2c, 0x70, 0x6e, 0x2c, 0x1c, 0x09, 0x1a, 0x5d, 0x5d, - 0x01, 0xc2, 0x16, 0x26, 0x26, 0x28, 0x29, 0x26, 0x26, 0x15, 0x45, 0x45, - 0x45, 0x4a, 0x30, 0x33, 0x1c, 0x1d, 0x1b, 0x1b, 0x04, 0xfe, 0xd9, 0x07, - 0x05, 0x1b, 0x1c, 0x1c, 0x1c, 0x32, 0x57, 0x79, 0x51, 0x54, 0x14, 0x16, - 0x2e, 0x2c, 0x64, 0x39, 0x40, 0x05, 0x07, 0x2e, 0x2a, 0x2a, 0x2e, 0x01, - 0x2e, 0x05, 0x07, 0x31, 0x32, 0x1c, 0x1c, 0x1d, 0xae, 0x33, 0x30, 0x08, - 0x04, 0x1a, 0x1c, 0x1d, 0x49, 0x44, 0x45, 0x15, 0x25, 0x26, 0x2a, 0x2a, - 0x25, 0x26, 0x15, 0x46, 0x02, 0xa6, 0x0f, 0x1e, 0x11, 0x10, 0x1c, 0x11, - 0x11, 0x1c, 0x10, 0x11, 0x1e, 0x0f, 0xb0, 0x2b, 0x2e, 0x53, 0x45, 0x46, - 0x45, 0x03, 0x03, 0x2e, 0x49, 0x4d, 0x4d, 0x49, 0x2e, 0x03, 0x03, 0x22, - 0x23, 0x46, 0x45, 0x53, 0x2e, 0x88, 0x20, 0x21, 0x1f, 0x20, 0x1f, 0x20, - 0x22, 0x3b, 0x18, 0x17, 0x17, 0x15, 0x15, 0x17, 0x17, 0x18, 0x2d, 0x30, - 0x2e, 0x2d, 0x19, 0x17, 0x17, 0x15, 0x15, 0x17, 0x17, 0x19, 0x2d, 0x2e, - 0x30, 0xd9, 0x49, 0x4d, 0x2b, 0x2e, 0x52, 0x45, 0x46, 0x24, 0x24, 0x04, - 0x04, 0x08, 0x02, 0x91, 0x9c, 0x9c, 0x91, 0x02, 0x31, 0x01, 0x02, 0x2e, - 0x10, 0x16, 0x25, 0x32, 0x53, 0x5f, 0x60, 0x51, 0x32, 0x25, 0x16, 0x10, - 0x2d, 0x04, 0x31, 0x8f, 0x4f, 0x51, 0x51, 0x4f, 0x8f, 0x32, 0x05, 0x2d, - 0x10, 0x16, 0x24, 0x33, 0x51, 0x60, 0x5f, 0x52, 0x33, 0x26, 0x15, 0x10, - 0x2e, 0x02, 0x01, 0x3e, 0x83, 0x47, 0x49, 0x49, 0x47, 0x83, 0x1a, 0x22, - 0x22, 0x0d, 0x15, 0x17, 0x0f, 0x10, 0x11, 0x10, 0x37, 0x34, 0x34, 0x37, - 0x10, 0x11, 0x10, 0x0f, 0x17, 0x23, 0x2e, 0x04, 0x04, 0x24, 0x24, 0x46, - 0x45, 0x52, 0x2f, 0x2b, 0x4c, 0x7f, 0x1f, 0x22, 0x20, 0x1f, 0x20, 0x1f, - 0x21, 0xae, 0x37, 0x35, 0x14, 0x18, 0x0e, 0x11, 0x10, 0x2f, 0x18, 0x14, - 0x35, 0x37, 0x11, 0x10, 0x11, 0x25, 0x22, 0x1b, 0x80, 0x49, 0x4a, 0x4a, - 0x49, 0x80, 0x1b, 0x00, 0x00, 0x07, 0x00, 0x2a, 0xff, 0xfe, 0x04, 0xa7, - 0x05, 0x1a, 0x00, 0x0b, 0x00, 0x14, 0x00, 0x1d, 0x00, 0x29, 0x00, 0x70, - 0x00, 0x7e, 0x00, 0x8c, 0x00, 0x00, 0x01, 0x14, 0x17, 0x36, 0x37, 0x26, - 0x27, 0x36, 0x37, 0x26, 0x27, 0x06, 0x05, 0x34, 0x26, 0x15, 0x06, 0x15, - 0x16, 0x17, 0x36, 0x25, 0x06, 0x17, 0x36, 0x37, 0x2e, 0x01, 0x27, 0x06, - 0x05, 0x34, 0x27, 0x06, 0x07, 0x16, 0x17, 0x06, 0x07, 0x16, 0x17, 0x36, - 0x03, 0x26, 0x07, 0x06, 0x07, 0x26, 0x27, 0x36, 0x37, 0x16, 0x17, 0x36, - 0x37, 0x26, 0x35, 0x34, 0x3f, 0x01, 0x15, 0x16, 0x15, 0x14, 0x07, 0x1e, - 0x01, 0x17, 0x36, 0x37, 0x16, 0x17, 0x06, 0x07, 0x26, 0x27, 0x26, 0x07, - 0x16, 0x17, 0x16, 0x14, 0x07, 0x06, 0x07, 0x16, 0x17, 0x06, 0x23, 0x26, - 0x27, 0x06, 0x07, 0x06, 0x07, 0x23, 0x26, 0x27, 0x35, 0x26, 0x27, 0x06, - 0x07, 0x22, 0x27, 0x36, 0x37, 0x26, 0x27, 0x26, 0x34, 0x37, 0x36, 0x06, - 0x14, 0x1e, 0x01, 0x33, 0x32, 0x3e, 0x01, 0x34, 0x2e, 0x01, 0x23, 0x22, - 0x06, 0x37, 0x32, 0x1e, 0x01, 0x14, 0x0e, 0x01, 0x23, 0x22, 0x2e, 0x01, - 0x34, 0x3e, 0x01, 0x02, 0x9a, 0x22, 0x30, 0x27, 0x2d, 0x08, 0x03, 0x2c, - 0x20, 0x29, 0x2a, 0xff, 0x00, 0x23, 0x27, 0x07, 0x30, 0x13, 0x01, 0xa3, - 0x06, 0x14, 0x35, 0x03, 0x03, 0x25, 0x01, 0x22, 0xff, 0x00, 0x2a, 0x25, - 0x25, 0x2c, 0x03, 0x0c, 0x29, 0x2c, 0x2c, 0x22, 0xe8, 0x47, 0x1a, 0x1c, - 0x4e, 0x59, 0x02, 0x02, 0xa0, 0x94, 0x49, 0x27, 0x2b, 0x22, 0x90, 0x01, - 0x8f, 0x22, 0x24, 0x28, 0x05, 0x4a, 0x93, 0xa1, 0x01, 0x02, 0x59, 0x4e, - 0x1c, 0x12, 0x4f, 0x17, 0x11, 0x32, 0x31, 0x15, 0x1c, 0x1e, 0x2c, 0x01, - 0x0c, 0x39, 0x2c, 0x34, 0x3d, 0x53, 0x16, 0x1c, 0x1c, 0x4d, 0x3a, 0x37, - 0x2c, 0x3a, 0x0c, 0x01, 0x2d, 0x1e, 0x1c, 0x14, 0x31, 0x32, 0x11, 0x2d, - 0x5b, 0xa5, 0x5b, 0x5a, 0xa5, 0x5b, 0x5d, 0xa6, 0x57, 0x58, 0xa6, 0xfe, - 0x49, 0x8b, 0x4f, 0x4d, 0x8b, 0x4b, 0x4c, 0x8b, 0x4d, 0x4e, 0x8c, 0x02, - 0x32, 0x8e, 0x93, 0x0d, 0x1f, 0x59, 0x7b, 0x95, 0x5c, 0x19, 0x0d, 0x62, - 0xb3, 0x43, 0x57, 0x01, 0x44, 0x4a, 0x67, 0x41, 0x42, 0x63, 0x70, 0x37, - 0x4c, 0x5e, 0x42, 0x4d, 0x01, 0x4c, 0x30, 0x94, 0x62, 0x0b, 0x1b, 0x5c, - 0x95, 0x75, 0x5d, 0x21, 0x0d, 0x93, 0x01, 0x40, 0x52, 0x25, 0x4b, 0x02, - 0x02, 0x6c, 0x68, 0x02, 0x06, 0x68, 0x16, 0x0f, 0x4f, 0x2b, 0x77, 0xd5, - 0x01, 0x01, 0xd5, 0x77, 0x2b, 0x4f, 0x0b, 0x17, 0x03, 0x68, 0x06, 0x02, - 0x68, 0x6c, 0x02, 0x02, 0x4b, 0x24, 0x50, 0x1b, 0x1e, 0x5a, 0xc0, 0x58, - 0x27, 0x1f, 0x40, 0x44, 0x0a, 0x30, 0x3a, 0x29, 0x13, 0x1e, 0x77, 0x77, - 0x1e, 0x01, 0x12, 0x2a, 0x3b, 0x30, 0x0a, 0x45, 0x41, 0x1e, 0x26, 0x58, - 0xc0, 0x5a, 0x1e, 0x77, 0xb4, 0xa5, 0x5b, 0x5b, 0xa5, 0xb4, 0xa7, 0x5b, - 0x5b, 0x47, 0x4a, 0x8c, 0x98, 0x8a, 0x4d, 0x4d, 0x8a, 0x98, 0x8c, 0x4a, - 0x00, 0x04, 0x00, 0x22, 0x00, 0x02, 0x04, 0xaf, 0x04, 0x28, 0x00, 0x07, - 0x00, 0x0d, 0x00, 0x15, 0x00, 0x25, 0x00, 0x00, 0x01, 0x33, 0x01, 0x15, - 0x21, 0x27, 0x23, 0x00, 0x17, 0x01, 0x15, 0x21, 0x35, 0x00, 0x07, 0x32, - 0x15, 0x02, 0x23, 0x22, 0x03, 0x36, 0x13, 0x32, 0x1e, 0x01, 0x15, 0x14, - 0x0e, 0x01, 0x23, 0x22, 0x2e, 0x01, 0x35, 0x34, 0x3e, 0x01, 0x02, 0x6f, - 0x05, 0x02, 0x3a, 0xfb, 0x81, 0x06, 0x06, 0x02, 0x35, 0x10, 0xfe, 0x28, - 0x03, 0xb7, 0xfe, 0x36, 0x0e, 0x37, 0x25, 0x12, 0x10, 0x27, 0x12, 0x24, - 0x0e, 0x1a, 0x0f, 0x0e, 0x1b, 0x0e, 0x0e, 0x1a, 0x0f, 0x0f, 0x1a, 0x04, - 0x28, 0xfb, 0xe1, 0x06, 0x06, 0x04, 0x07, 0x6e, 0xfc, 0xaa, 0x0c, 0x06, - 0x03, 0x48, 0x8a, 0x30, 0xfe, 0x4c, 0x01, 0xba, 0x2a, 0xfd, 0xe7, 0x0e, - 0x19, 0x0f, 0x0f, 0x19, 0x0e, 0x0e, 0x19, 0x0f, 0x0f, 0x19, 0x0e, 0x00, - 0x00, 0x01, 0x00, 0x88, 0x00, 0x08, 0x04, 0x49, 0x05, 0x22, 0x00, 0x13, - 0x00, 0x00, 0x01, 0x33, 0x17, 0x15, 0x01, 0x14, 0x33, 0x04, 0x15, 0x17, - 0x01, 0x27, 0x35, 0x00, 0x35, 0x34, 0x23, 0x24, 0x2f, 0x01, 0x04, 0x2a, - 0x0c, 0x13, 0xfd, 0xdc, 0x50, 0x01, 0x52, 0x07, 0xfc, 0xc6, 0x0c, 0x02, - 0x36, 0x68, 0xfe, 0xc1, 0x0e, 0x06, 0x05, 0x22, 0x13, 0x06, 0xfe, 0x26, - 0x3e, 0x49, 0x0c, 0x3e, 0xfd, 0xaa, 0x13, 0x06, 0x02, 0x0c, 0x0b, 0x3e, - 0x41, 0x0f, 0x3e, 0x00, 0x00, 0x01, 0x00, 0xf3, 0x00, 0x00, 0x03, 0xdf, - 0x05, 0xd8, 0x00, 0x05, 0x00, 0x00, 0x01, 0x21, 0x13, 0x03, 0x21, 0x03, - 0x01, 0xae, 0x01, 0x75, 0xbc, 0xbc, 0xfe, 0x8b, 0xbb, 0x05, 0xd8, 0xfe, - 0x89, 0xfb, 0x9f, 0x04, 0x61, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xde, - 0x00, 0x00, 0x03, 0xf3, 0x04, 0xc1, 0x00, 0x13, 0x00, 0x00, 0x01, 0x16, - 0x15, 0x14, 0x07, 0x03, 0x21, 0x03, 0x26, 0x35, 0x34, 0x37, 0x36, 0x27, - 0x23, 0x35, 0x21, 0x17, 0x07, 0x16, 0x03, 0x2b, 0xc8, 0x07, 0xc1, 0xfe, - 0x7b, 0xc0, 0x08, 0xc8, 0x68, 0x06, 0x5f, 0x01, 0x81, 0x01, 0x61, 0x01, - 0x03, 0xf6, 0x36, 0x91, 0x1a, 0x1d, 0xfd, 0x08, 0x02, 0xf8, 0x1f, 0x1b, - 0x8e, 0x36, 0x15, 0x6d, 0x48, 0x48, 0x01, 0x6d, 0x00, 0x03, 0x00, 0x2e, - 0x01, 0x72, 0x04, 0xa3, 0x03, 0xf3, 0x00, 0x5a, 0x00, 0x79, 0x00, 0x99, - 0x00, 0x00, 0x01, 0x27, 0x23, 0x22, 0x27, 0x26, 0x07, 0x06, 0x15, 0x14, - 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, - 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, - 0x1f, 0x01, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x27, - 0x26, 0x27, 0x26, 0x27, 0x26, 0x2f, 0x01, 0x26, 0x27, 0x26, 0x27, 0x26, - 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x32, 0x16, 0x17, 0x16, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x17, 0x16, - 0x1f, 0x01, 0x21, 0x32, 0x17, 0x16, 0x17, 0x21, 0x17, 0x25, 0x16, 0x33, - 0x32, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, - 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, - 0x14, 0x17, 0x1e, 0x01, 0x13, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x06, - 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, - 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, - 0x02, 0xcb, 0x97, 0x50, 0x7a, 0x14, 0x1e, 0x02, 0x01, 0x07, 0x09, 0x12, - 0x10, 0x19, 0x14, 0x1e, 0x19, 0x1a, 0x19, 0x12, 0x0f, 0x10, 0x0d, 0x09, - 0x09, 0x11, 0x11, 0x19, 0x14, 0x1e, 0x18, 0x1a, 0x2c, 0x44, 0x40, 0x1a, - 0x09, 0x10, 0x0d, 0x0d, 0x02, 0x02, 0x03, 0x02, 0x09, 0x08, 0x10, 0x37, - 0x3b, 0x2b, 0x1a, 0x12, 0x14, 0x0a, 0x0e, 0x09, 0x09, 0x12, 0x13, 0x16, - 0x19, 0x32, 0x33, 0x12, 0x16, 0x09, 0x0d, 0x09, 0x06, 0x09, 0x0c, 0x02, - 0x04, 0x18, 0x1d, 0x4d, 0x39, 0x01, 0x16, 0xa3, 0x38, 0x47, 0x0c, 0xfe, - 0x29, 0x95, 0xfd, 0x3a, 0x0e, 0x0e, 0x11, 0x0c, 0x0e, 0x09, 0x0c, 0x03, - 0x04, 0x09, 0x07, 0x0a, 0x0d, 0x0d, 0x11, 0x0c, 0x0e, 0x0e, 0x0f, 0x09, - 0x09, 0x05, 0x04, 0x09, 0x07, 0x15, 0xd6, 0x0d, 0x10, 0x14, 0x08, 0x0f, - 0x09, 0x0c, 0x03, 0x04, 0x09, 0x07, 0x0a, 0x0b, 0x0f, 0x0f, 0x0e, 0x11, - 0x0b, 0x0f, 0x09, 0x0b, 0x03, 0x05, 0x0a, 0x07, 0x0a, 0x08, 0x01, 0x72, - 0x91, 0x04, 0x06, 0x0a, 0x05, 0x11, 0x0c, 0x10, 0x17, 0x11, 0x0f, 0x09, - 0x08, 0x0a, 0x0a, 0x12, 0x0e, 0x1a, 0x14, 0x1b, 0x1a, 0x14, 0x17, 0x10, - 0x10, 0x09, 0x08, 0x0a, 0x12, 0x1b, 0x02, 0x03, 0x09, 0x0b, 0x05, 0x05, - 0x11, 0x10, 0x0d, 0x0e, 0x0d, 0x30, 0x18, 0x11, 0x0b, 0x11, 0x13, 0x15, - 0x1a, 0x15, 0x1a, 0x14, 0x17, 0x11, 0x11, 0x07, 0x08, 0x15, 0x11, 0x15, - 0x14, 0x19, 0x17, 0x18, 0x15, 0x11, 0x08, 0x0c, 0x05, 0x09, 0x0f, 0x13, - 0x4c, 0x3a, 0x16, 0x1d, 0x35, 0x92, 0x55, 0x06, 0x04, 0x05, 0x07, 0x09, - 0x0c, 0x0c, 0x0c, 0x09, 0x11, 0x0c, 0x09, 0x0c, 0x05, 0x06, 0x04, 0x05, - 0x07, 0x09, 0x0c, 0x0c, 0x0c, 0x0a, 0x10, 0x0c, 0x14, 0x01, 0xe7, 0x07, - 0x04, 0x05, 0x07, 0x0b, 0x0a, 0x0c, 0x0c, 0x0b, 0x0f, 0x0c, 0x0a, 0x09, - 0x07, 0x06, 0x03, 0x05, 0x08, 0x0a, 0x0a, 0x0c, 0x0d, 0x0a, 0x0f, 0x0d, - 0x0a, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x2e, 0x01, 0x5c, 0x04, 0xa3, - 0x04, 0x0b, 0x00, 0x19, 0x00, 0x72, 0x00, 0x8c, 0x00, 0x00, 0x12, 0x32, - 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x2e, 0x01, - 0x22, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, - 0x01, 0x05, 0x06, 0x23, 0x22, 0x27, 0x25, 0x07, 0x0e, 0x01, 0x15, 0x14, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x22, 0x27, - 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, - 0x36, 0x3b, 0x01, 0x32, 0x37, 0x3e, 0x01, 0x37, 0x36, 0x34, 0x27, 0x2e, - 0x01, 0x27, 0x26, 0x2b, 0x01, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, - 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x32, 0x17, 0x16, 0x17, - 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x15, 0x14, 0x16, 0x1f, 0x01, - 0x25, 0x36, 0x33, 0x32, 0x17, 0x24, 0x22, 0x06, 0x07, 0x06, 0x07, 0x06, - 0x15, 0x14, 0x17, 0x16, 0x17, 0x1e, 0x01, 0x32, 0x36, 0x37, 0x36, 0x37, - 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0xac, 0x23, 0x1c, 0x0c, 0x0d, - 0x06, 0x06, 0x06, 0x06, 0x0d, 0x0c, 0x1c, 0x23, 0x1c, 0x0c, 0x0d, 0x06, - 0x06, 0x06, 0x06, 0x0d, 0x0c, 0x02, 0x40, 0x01, 0xd2, 0x21, 0x52, 0x3c, - 0xa5, 0xfe, 0xed, 0x4f, 0x71, 0x3c, 0x08, 0x05, 0x0b, 0x0a, 0x15, 0x11, - 0x1e, 0x18, 0x3b, 0x19, 0x19, 0x15, 0x14, 0x0c, 0x0a, 0x0a, 0x0b, 0x15, - 0x10, 0x1e, 0x19, 0x1d, 0x33, 0x40, 0x4d, 0x14, 0x1c, 0x09, 0x09, 0x09, - 0x09, 0x1c, 0x14, 0x4a, 0x43, 0x33, 0x1d, 0x19, 0x1e, 0x10, 0x15, 0x0b, - 0x0a, 0x0a, 0x0c, 0x14, 0x15, 0x19, 0x19, 0x3b, 0x18, 0x1e, 0x11, 0x15, - 0x0a, 0x0b, 0x05, 0x08, 0x3c, 0x71, 0x4f, 0x01, 0x13, 0xa5, 0x3c, 0x52, - 0x21, 0xfc, 0x2d, 0x23, 0x1c, 0x0c, 0x0d, 0x06, 0x06, 0x06, 0x06, 0x0d, - 0x0c, 0x1c, 0x23, 0x1c, 0x0c, 0x0d, 0x06, 0x06, 0x06, 0x06, 0x0d, 0x0c, - 0x01, 0x98, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0e, 0x0e, 0x0c, 0x0b, 0x0b, - 0x09, 0x0b, 0x0b, 0x09, 0x0b, 0x0b, 0x0c, 0x0e, 0x0e, 0x0c, 0x0b, 0x0b, - 0x0a, 0x01, 0x12, 0xbe, 0x2f, 0x41, 0x6e, 0x21, 0x2f, 0x0a, 0x0a, 0x06, - 0x11, 0x0c, 0x13, 0x1a, 0x17, 0x16, 0x13, 0x10, 0x0c, 0x0a, 0x0a, 0x0a, - 0x12, 0x0f, 0x1a, 0x17, 0x1a, 0x1a, 0x17, 0x16, 0x13, 0x10, 0x0c, 0x0a, - 0x19, 0x07, 0x14, 0x0e, 0x10, 0x0c, 0x0f, 0x0f, 0x13, 0x07, 0x19, 0x0a, - 0x0c, 0x10, 0x13, 0x16, 0x17, 0x1a, 0x1a, 0x17, 0x1a, 0x10, 0x11, 0x0a, - 0x0a, 0x0a, 0x0c, 0x0f, 0x14, 0x16, 0x17, 0x1a, 0x13, 0x0c, 0x10, 0x06, - 0x0b, 0x0b, 0x2e, 0x21, 0x6d, 0x42, 0x30, 0x5f, 0x0b, 0x09, 0x0b, 0x0b, - 0x0c, 0x0e, 0x0e, 0x0c, 0x0b, 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x0a, 0x0b, - 0x0c, 0x0e, 0x0e, 0x0c, 0x0b, 0x0b, 0x09, 0x00, 0x00, 0x03, 0x00, 0x3a, - 0x01, 0x3f, 0x04, 0x97, 0x03, 0xb2, 0x00, 0x59, 0x00, 0x78, 0x00, 0x97, - 0x00, 0x00, 0x01, 0x33, 0x07, 0x21, 0x06, 0x07, 0x06, 0x23, 0x21, 0x07, - 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, - 0x06, 0x07, 0x0e, 0x01, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, - 0x34, 0x37, 0x36, 0x37, 0x36, 0x3f, 0x01, 0x36, 0x37, 0x36, 0x37, 0x36, - 0x37, 0x36, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x23, 0x22, 0x0f, 0x01, - 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, - 0x3e, 0x01, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, - 0x15, 0x14, 0x17, 0x16, 0x37, 0x36, 0x3b, 0x01, 0x25, 0x06, 0x07, 0x06, - 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, - 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x27, - 0x26, 0x23, 0x22, 0x13, 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, - 0x26, 0x27, 0x26, 0x27, 0x26, 0x23, 0x22, 0x06, 0x07, 0x06, 0x07, 0x06, - 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x02, 0xc9, - 0x93, 0x93, 0x01, 0xcd, 0x0c, 0x45, 0x37, 0x9f, 0xfe, 0xf1, 0x39, 0x45, - 0x22, 0x14, 0x0e, 0x09, 0x06, 0x08, 0x0c, 0x09, 0x15, 0x12, 0x32, 0x31, - 0x18, 0x16, 0x13, 0x13, 0x07, 0x08, 0x0d, 0x08, 0x15, 0x12, 0x19, 0x2b, - 0x39, 0x36, 0x0f, 0x08, 0x09, 0x02, 0x03, 0x02, 0x02, 0x0d, 0x07, 0x15, - 0x05, 0x1e, 0x3e, 0x42, 0x2b, 0x19, 0x18, 0x1e, 0x13, 0x19, 0x10, 0x11, - 0x09, 0x08, 0x0c, 0x0d, 0x23, 0x19, 0x19, 0x19, 0x1d, 0x13, 0x19, 0x10, - 0x11, 0x09, 0x06, 0x02, 0x04, 0x1b, 0x11, 0x7a, 0x4f, 0xfe, 0x6f, 0x0f, - 0x0a, 0x06, 0x0b, 0x09, 0x04, 0x05, 0x09, 0x07, 0x10, 0x0c, 0x10, 0x0e, - 0x1d, 0x0a, 0x0b, 0x07, 0x08, 0x04, 0x04, 0x0a, 0x05, 0x13, 0x0b, 0x10, - 0x0e, 0xb4, 0x0f, 0x0a, 0x06, 0x0b, 0x09, 0x04, 0x05, 0x09, 0x0a, 0x0d, - 0x0c, 0x0f, 0x0f, 0x1d, 0x0a, 0x0a, 0x07, 0x09, 0x04, 0x05, 0x09, 0x0b, - 0x0d, 0x0d, 0x0e, 0x0a, 0x03, 0xb2, 0x8e, 0x34, 0x1c, 0x16, 0x39, 0x44, - 0x18, 0x0e, 0x0b, 0x03, 0x0d, 0x08, 0x10, 0x17, 0x18, 0x12, 0x1b, 0x13, - 0x14, 0x11, 0x14, 0x07, 0x07, 0x11, 0x12, 0x15, 0x17, 0x15, 0x12, 0x1d, - 0x13, 0x14, 0x11, 0x0a, 0x11, 0x17, 0x2f, 0x0d, 0x0d, 0x0e, 0x0f, 0x10, - 0x06, 0x05, 0x0a, 0x05, 0x07, 0x02, 0x1b, 0x11, 0x0a, 0x08, 0x09, 0x0f, - 0x10, 0x16, 0x16, 0x17, 0x18, 0x17, 0x16, 0x22, 0x0a, 0x0a, 0x08, 0x09, - 0x0f, 0x10, 0x16, 0x10, 0x0c, 0x13, 0x03, 0x0a, 0x07, 0x04, 0x3a, 0x06, - 0x09, 0x06, 0x10, 0x0e, 0x0b, 0x0e, 0x0a, 0x0c, 0x08, 0x06, 0x06, 0x04, - 0x0c, 0x0a, 0x09, 0x0c, 0x0f, 0x0d, 0x0b, 0x0a, 0x0c, 0x08, 0x07, 0x05, - 0x04, 0xfe, 0x18, 0x06, 0x09, 0x05, 0x11, 0x0d, 0x0b, 0x0f, 0x0a, 0x0b, - 0x09, 0x08, 0x04, 0x03, 0x0c, 0x09, 0x0a, 0x0c, 0x0d, 0x0c, 0x0f, 0x09, - 0x0b, 0x09, 0x09, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x3d, - 0x01, 0x4a, 0x04, 0x94, 0x04, 0x03, 0x00, 0x5a, 0x00, 0x78, 0x00, 0x96, - 0x00, 0xb4, 0x00, 0xd2, 0x00, 0xfe, 0x01, 0x2d, 0x01, 0x34, 0x01, 0x48, - 0x00, 0x00, 0x01, 0x36, 0x37, 0x26, 0x27, 0x26, 0x27, 0x26, 0x2b, 0x01, - 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x34, 0x37, 0x36, 0x37, 0x36, - 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x16, 0x1f, 0x01, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x0d, 0x01, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x2f, 0x01, - 0x07, 0x06, 0x07, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, - 0x37, 0x36, 0x37, 0x36, 0x3b, 0x01, 0x32, 0x37, 0x36, 0x06, 0x32, 0x37, - 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x27, - 0x26, 0x22, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, - 0x17, 0x16, 0x17, 0x12, 0x32, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, - 0x34, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x22, 0x07, 0x06, 0x07, 0x06, - 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x17, 0x12, 0x22, 0x27, - 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, - 0x36, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, - 0x07, 0x06, 0x07, 0x02, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, - 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x32, 0x17, 0x16, 0x17, 0x16, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x05, 0x27, 0x26, - 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, - 0x27, 0x26, 0x27, 0x26, 0x22, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, - 0x14, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x3b, 0x01, 0x32, 0x17, 0x16, - 0x17, 0x16, 0x17, 0x37, 0x36, 0x07, 0x2d, 0x01, 0x26, 0x23, 0x22, 0x0f, - 0x01, 0x06, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x2b, 0x01, 0x22, 0x07, - 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x17, - 0x16, 0x32, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, - 0x35, 0x34, 0x37, 0x36, 0x25, 0x17, 0x16, 0x33, 0x32, 0x37, 0x25, 0x26, - 0x14, 0x07, 0x06, 0x07, 0x06, 0x22, 0x27, 0x26, 0x27, 0x26, 0x34, 0x37, - 0x36, 0x37, 0x36, 0x32, 0x17, 0x16, 0x17, 0x01, 0x9d, 0x08, 0x05, 0x05, - 0x08, 0x06, 0x11, 0x38, 0x3f, 0x2e, 0x1f, 0x1f, 0x19, 0x1c, 0x17, 0x0d, - 0x0d, 0x0d, 0x0b, 0x1b, 0x13, 0x20, 0x1d, 0x21, 0x20, 0x1e, 0x1d, 0x18, - 0x1b, 0x09, 0x0d, 0x05, 0x21, 0x61, 0x3d, 0xf0, 0x9b, 0x3f, 0x5e, 0x27, - 0x06, 0x15, 0xfe, 0xa1, 0x01, 0x5f, 0x15, 0x06, 0x29, 0x5c, 0x3f, 0x9b, - 0xf0, 0x3d, 0x61, 0x21, 0x05, 0x0d, 0x0d, 0x17, 0x19, 0x1c, 0x21, 0x1d, - 0x23, 0x1b, 0x1c, 0x17, 0x1d, 0x09, 0x0d, 0x0d, 0x0b, 0x19, 0x13, 0x22, - 0x1d, 0x21, 0x2e, 0x38, 0x3f, 0x10, 0xbf, 0x14, 0x07, 0x08, 0x07, 0x06, - 0x03, 0x02, 0x02, 0x03, 0x06, 0x07, 0x08, 0x07, 0x14, 0x07, 0x08, 0x07, - 0x07, 0x02, 0x02, 0x02, 0x02, 0x07, 0x07, 0x08, 0x07, 0x14, 0x07, 0x08, - 0x07, 0x06, 0x03, 0x02, 0x02, 0x03, 0x06, 0x07, 0x08, 0x07, 0x14, 0x07, - 0x08, 0x07, 0x07, 0x02, 0x02, 0x02, 0x02, 0x07, 0x07, 0x08, 0x22, 0x22, - 0x0f, 0x0e, 0x0c, 0x0d, 0x06, 0x06, 0x06, 0x06, 0x0d, 0x0c, 0x0e, 0x0f, - 0x22, 0x0f, 0x0e, 0x0c, 0x0d, 0x06, 0x06, 0x06, 0x06, 0x0d, 0x0c, 0x0e, - 0x0f, 0x22, 0x0f, 0x0e, 0x0c, 0x0d, 0x06, 0x06, 0x06, 0x06, 0x0d, 0x0c, - 0x0e, 0x0f, 0x22, 0x0f, 0x0e, 0x0c, 0x0d, 0x06, 0x06, 0x06, 0x06, 0x0d, - 0x0c, 0x0e, 0x01, 0x0c, 0x1a, 0x66, 0x1b, 0x0f, 0x08, 0x0b, 0x08, 0x04, - 0x09, 0x09, 0x12, 0x0e, 0x1a, 0x16, 0x32, 0x16, 0x16, 0x12, 0x11, 0x0a, - 0x09, 0x09, 0x09, 0x12, 0x0e, 0x1a, 0x16, 0x19, 0x2e, 0x3f, 0x45, 0x15, - 0x0c, 0x10, 0x05, 0x18, 0x13, 0x82, 0x01, 0x53, 0x01, 0xa1, 0x1d, 0x40, - 0x36, 0x95, 0xfc, 0x66, 0x0c, 0x0c, 0x10, 0x0e, 0x13, 0x47, 0x3d, 0x2e, - 0x19, 0x16, 0x1a, 0x0e, 0x12, 0x09, 0x09, 0x09, 0x0a, 0x11, 0x12, 0x16, - 0x16, 0x32, 0x16, 0x1a, 0x0e, 0x12, 0x09, 0x09, 0x04, 0x08, 0x0b, 0x09, - 0x01, 0x15, 0xc5, 0x95, 0x36, 0x40, 0x1d, 0xfe, 0x88, 0x95, 0x03, 0x05, - 0x06, 0x06, 0x0f, 0x06, 0x06, 0x05, 0x03, 0x03, 0x05, 0x06, 0x06, 0x0f, - 0x06, 0x06, 0x05, 0x02, 0x98, 0x06, 0x08, 0x0a, 0x05, 0x04, 0x07, 0x16, - 0x0b, 0x09, 0x17, 0x13, 0x1d, 0x1a, 0x42, 0x1a, 0x17, 0x1b, 0x12, 0x0c, - 0x0b, 0x0b, 0x0b, 0x15, 0x19, 0x17, 0x20, 0x1b, 0x14, 0x0d, 0x06, 0x29, - 0x19, 0x5f, 0x3e, 0x39, 0x09, 0x0c, 0x15, 0x08, 0x8f, 0x8e, 0x08, 0x1a, - 0x08, 0x08, 0x39, 0x3e, 0x5f, 0x19, 0x29, 0x07, 0x10, 0x10, 0x20, 0x1b, - 0x1d, 0x14, 0x16, 0x09, 0x0b, 0x0b, 0x0b, 0x13, 0x18, 0x19, 0x25, 0x17, - 0x1f, 0x1c, 0x18, 0x18, 0x13, 0x0d, 0x0b, 0x16, 0x06, 0xcf, 0x02, 0x04, - 0x05, 0x05, 0x05, 0x03, 0x05, 0x05, 0x03, 0x05, 0x05, 0x05, 0x03, 0x03, - 0x03, 0x03, 0x06, 0x04, 0x05, 0x03, 0x05, 0x05, 0x04, 0x04, 0x05, 0x05, - 0x04, 0x01, 0x89, 0x03, 0x03, 0x06, 0x04, 0x05, 0x03, 0x05, 0x05, 0x04, - 0x04, 0x05, 0x05, 0x04, 0x02, 0x02, 0x04, 0x05, 0x05, 0x05, 0x03, 0x05, - 0x05, 0x03, 0x05, 0x05, 0x05, 0x03, 0xfe, 0x49, 0x05, 0x05, 0x0a, 0x0b, - 0x0c, 0x0c, 0x0f, 0x0f, 0x0c, 0x0c, 0x0b, 0x09, 0x06, 0x05, 0x05, 0x06, - 0x09, 0x0b, 0x0c, 0x0c, 0x0f, 0x0f, 0x0c, 0x0c, 0x0b, 0x0a, 0x05, 0x01, - 0x86, 0x05, 0x06, 0x09, 0x0b, 0x0c, 0x0c, 0x0f, 0x0f, 0x0c, 0x0c, 0x0b, - 0x0a, 0x05, 0x05, 0x05, 0x05, 0x0a, 0x0b, 0x0c, 0x0c, 0x0f, 0x0f, 0x0c, - 0x0c, 0x0b, 0x09, 0x06, 0x3f, 0x0a, 0x2a, 0x05, 0x03, 0x04, 0x05, 0x0a, - 0x07, 0x10, 0x0a, 0x10, 0x16, 0x14, 0x12, 0x11, 0x0d, 0x0c, 0x08, 0x08, - 0x0a, 0x0f, 0x0d, 0x16, 0x14, 0x16, 0x16, 0x14, 0x12, 0x11, 0x0d, 0x0b, - 0x09, 0x17, 0x07, 0x09, 0x0c, 0x06, 0x11, 0x0c, 0xba, 0x85, 0xaa, 0x20, - 0x3b, 0x64, 0x2e, 0x15, 0x14, 0x0b, 0x09, 0x07, 0x18, 0x08, 0x0b, 0x0d, - 0x11, 0x13, 0x13, 0x16, 0x17, 0x13, 0x16, 0x0d, 0x0f, 0x0a, 0x08, 0x08, - 0x0b, 0x0d, 0x12, 0x12, 0x13, 0x17, 0x10, 0x09, 0x11, 0x07, 0x0e, 0x01, - 0x01, 0x3f, 0x50, 0x3c, 0x21, 0x9a, 0x1e, 0x0f, 0x06, 0x07, 0x04, 0x03, - 0x03, 0x04, 0x07, 0x06, 0x0f, 0x06, 0x06, 0x04, 0x04, 0x04, 0x04, 0x06, - 0x00, 0x03, 0x00, 0x34, 0x00, 0x47, 0x04, 0x9d, 0x04, 0xb4, 0x00, 0x6e, - 0x00, 0x80, 0x00, 0x92, 0x00, 0x00, 0x01, 0x06, 0x07, 0x06, 0x15, 0x14, - 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x36, - 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x23, 0x22, - 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x15, - 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, - 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, - 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x2e, 0x02, 0x35, 0x34, 0x37, 0x36, - 0x37, 0x26, 0x35, 0x34, 0x37, 0x12, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x06, 0x23, 0x22, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x17, 0x36, 0x37, 0x36, - 0x37, 0x36, 0x37, 0x16, 0x17, 0x16, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, - 0x27, 0x26, 0x01, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x36, 0x37, 0x36, 0x35, 0x34, 0x01, 0x7a, 0x03, 0x01, - 0x07, 0x07, 0x08, 0x0e, 0x0f, 0x11, 0x51, 0x6b, 0x64, 0x59, 0x57, 0x47, - 0x4a, 0x23, 0x23, 0x23, 0x22, 0x4b, 0x45, 0x59, 0x58, 0x65, 0x61, 0x5b, - 0x57, 0x47, 0x4a, 0x23, 0x23, 0x23, 0x15, 0x20, 0x4e, 0x2a, 0x29, 0x29, - 0x27, 0x55, 0x4f, 0x67, 0x67, 0x71, 0x71, 0x68, 0x62, 0x54, 0x51, 0x2b, - 0x29, 0x29, 0x27, 0x55, 0x51, 0x65, 0x67, 0x72, 0x73, 0x65, 0x1e, 0x32, - 0x1a, 0x0d, 0x0a, 0x14, 0x02, 0x4e, 0x85, 0x7b, 0x3b, 0x05, 0x0b, 0x1a, - 0x19, 0x06, 0x28, 0x1f, 0x16, 0x32, 0x2e, 0x0c, 0x0d, 0x10, 0x19, 0x27, - 0x1c, 0x0d, 0x0c, 0x37, 0x11, 0x1e, 0x24, 0x12, 0x11, 0x02, 0x21, 0x05, - 0x0d, 0x02, 0x07, 0x0e, 0x14, 0x19, 0x1b, 0x0f, 0x14, 0x01, 0x2f, 0x2d, - 0x10, 0x0c, 0x0f, 0x0a, 0x16, 0x07, 0x15, 0x07, 0x2a, 0x0c, 0x15, 0x16, - 0x01, 0x40, 0x04, 0x05, 0x11, 0x14, 0x15, 0x11, 0x13, 0x0d, 0x0e, 0x08, - 0x25, 0x25, 0x24, 0x48, 0x49, 0x56, 0x57, 0x63, 0x67, 0x57, 0x53, 0x4d, - 0x46, 0x26, 0x25, 0x25, 0x24, 0x48, 0x49, 0x57, 0x57, 0x67, 0x62, 0x58, - 0x31, 0x2e, 0x6f, 0x50, 0x62, 0x65, 0x71, 0x73, 0x67, 0x60, 0x57, 0x50, - 0x2c, 0x2b, 0x2b, 0x29, 0x53, 0x51, 0x66, 0x64, 0x76, 0x6f, 0x67, 0x5f, - 0x57, 0x52, 0x2a, 0x2b, 0x2b, 0x0d, 0x30, 0x3f, 0x23, 0x22, 0x20, 0x18, - 0x17, 0x0c, 0x0b, 0x96, 0xae, 0x01, 0x24, 0x06, 0x0e, 0x29, 0x2a, 0x32, - 0x2f, 0x1f, 0x16, 0x5b, 0x54, 0x47, 0x17, 0x10, 0x14, 0x16, 0x06, 0x21, - 0x33, 0x1e, 0x14, 0x28, 0x09, 0x18, 0x1f, 0x2d, 0x29, 0x12, 0x1c, 0x06, - 0x0f, 0x0b, 0x23, 0x18, 0x25, 0x15, 0x17, 0x03, 0x05, 0x03, 0x03, 0x10, - 0x0c, 0x09, 0x24, 0x21, 0x27, 0x1a, 0x1c, 0x08, 0x07, 0x0d, 0x28, 0x2a, - 0x30, 0x26, 0x00, 0x00, 0x00, 0x06, 0x00, 0x25, 0x00, 0x3f, 0x04, 0xac, - 0x04, 0xc9, 0x00, 0x0f, 0x00, 0x1c, 0x00, 0x2c, 0x00, 0x4a, 0x00, 0x69, - 0x00, 0x89, 0x00, 0x00, 0x01, 0x26, 0x27, 0x26, 0x27, 0x37, 0x06, 0x15, - 0x14, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x13, 0x26, 0x27, 0x26, - 0x22, 0x07, 0x06, 0x07, 0x13, 0x36, 0x33, 0x32, 0x17, 0x13, 0x17, 0x06, - 0x07, 0x06, 0x07, 0x25, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, - 0x34, 0x26, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, - 0x06, 0x07, 0x06, 0x07, 0x06, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, - 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x13, 0x22, 0x07, 0x06, 0x07, - 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x1e, 0x01, 0x33, 0x32, - 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, - 0x27, 0x26, 0x27, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, - 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x01, 0x24, - 0x30, 0x18, 0x05, 0x03, 0xdf, 0x06, 0x0e, 0x0f, 0x1a, 0x19, 0x24, 0x0f, - 0x06, 0xb6, 0x1a, 0x22, 0x20, 0x4e, 0x21, 0x21, 0x1c, 0x35, 0x26, 0x29, - 0x2a, 0x26, 0x66, 0xe0, 0x02, 0x07, 0x18, 0x30, 0xfe, 0xee, 0x0a, 0x0b, - 0x24, 0x18, 0x1b, 0x0f, 0x0e, 0xd3, 0x2f, 0x13, 0x15, 0x10, 0x10, 0x09, - 0x08, 0x08, 0x09, 0x10, 0x10, 0x15, 0x13, 0x2f, 0x13, 0x14, 0x11, 0x11, - 0x08, 0x08, 0x08, 0x08, 0x11, 0x11, 0x14, 0x2a, 0x64, 0x5d, 0x59, 0x4a, - 0x4b, 0x24, 0x25, 0x25, 0x25, 0x4a, 0x48, 0xb6, 0x66, 0x66, 0x5c, 0x59, - 0x4a, 0x4b, 0x24, 0x24, 0x24, 0x23, 0x4c, 0x47, 0x5c, 0x5a, 0x68, 0x74, - 0x6a, 0x65, 0x56, 0x54, 0x2c, 0x2b, 0x2b, 0x28, 0x58, 0x52, 0x69, 0x69, - 0x75, 0x73, 0x6b, 0x64, 0x56, 0x54, 0x2c, 0x2a, 0x2a, 0x28, 0x58, 0x51, - 0x69, 0x6a, 0x01, 0x6e, 0x37, 0x3c, 0x0b, 0x0c, 0xbd, 0x16, 0x1a, 0x25, - 0x22, 0x23, 0x1b, 0x18, 0x10, 0x07, 0x01, 0x01, 0x3b, 0x19, 0x0f, 0x0f, - 0x0f, 0x0f, 0x19, 0x01, 0x22, 0x07, 0x07, 0xfe, 0x88, 0xbd, 0x06, 0x11, - 0x3c, 0x37, 0x62, 0x04, 0x04, 0x10, 0x18, 0x1b, 0x23, 0x22, 0x25, 0x19, - 0x58, 0x08, 0x09, 0x0f, 0x12, 0x13, 0x15, 0x17, 0x16, 0x15, 0x13, 0x11, - 0x10, 0x09, 0x08, 0x08, 0x09, 0x10, 0x11, 0x13, 0x15, 0x16, 0x17, 0x15, - 0x13, 0x12, 0x0f, 0x09, 0x01, 0x90, 0x26, 0x25, 0x4a, 0x4b, 0x59, 0x59, - 0x6a, 0x64, 0x5b, 0x59, 0x4a, 0x49, 0x4d, 0x26, 0x25, 0x4b, 0x4a, 0x59, - 0x59, 0x66, 0x6a, 0x59, 0x55, 0x4f, 0x48, 0x27, 0x26, 0x4b, 0x2c, 0x2a, - 0x56, 0x53, 0x68, 0x67, 0x79, 0x72, 0x6a, 0x62, 0x59, 0x54, 0x2b, 0x2d, - 0x2d, 0x2a, 0x55, 0x53, 0x68, 0x67, 0x75, 0x76, 0x6a, 0x62, 0x59, 0x53, - 0x2d, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x3d, 0x00, 0x3c, 0x04, 0x94, - 0x04, 0x5b, 0x00, 0x2d, 0x00, 0x00, 0x13, 0x35, 0x37, 0x27, 0x33, 0x17, - 0x36, 0x37, 0x26, 0x03, 0x33, 0x17, 0x33, 0x15, 0x23, 0x17, 0x33, 0x15, - 0x23, 0x17, 0x33, 0x32, 0x17, 0x16, 0x14, 0x07, 0x06, 0x2b, 0x01, 0x07, - 0x33, 0x15, 0x23, 0x07, 0x33, 0x15, 0x23, 0x07, 0x23, 0x12, 0x37, 0x26, - 0x27, 0x07, 0x23, 0x37, 0x52, 0x1b, 0x30, 0x4b, 0x6e, 0x6d, 0xd7, 0x28, - 0x80, 0x5c, 0x56, 0x6f, 0x40, 0x4b, 0x73, 0x46, 0x72, 0xc6, 0x35, 0x24, - 0x18, 0x18, 0x24, 0x35, 0xc6, 0x72, 0x46, 0x73, 0x4b, 0x40, 0x6f, 0x56, - 0x5c, 0x80, 0x28, 0xd7, 0x6d, 0x6e, 0x4b, 0x30, 0x02, 0x3d, 0x1e, 0x03, - 0xa4, 0x97, 0x0a, 0x07, 0xd0, 0x01, 0x0f, 0x71, 0x3c, 0x61, 0x3c, 0x95, - 0x13, 0x0d, 0x21, 0x0d, 0x13, 0x95, 0x3c, 0x61, 0x3c, 0x71, 0x01, 0x08, - 0xd7, 0x08, 0x09, 0x96, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x3f, - 0x00, 0x73, 0x04, 0x92, 0x03, 0x96, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x22, - 0x00, 0x29, 0x00, 0x2d, 0x00, 0x00, 0x01, 0x25, 0x21, 0x05, 0x36, 0x37, - 0x36, 0x37, 0x36, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x05, 0x11, 0x05, - 0x16, 0x15, 0x14, 0x0d, 0x01, 0x21, 0x25, 0x06, 0x07, 0x06, 0x07, 0x06, - 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x25, 0x11, 0x25, 0x26, 0x35, 0x34, - 0x01, 0x11, 0x21, 0x11, 0x02, 0xdf, 0x01, 0x4f, 0xfc, 0x75, 0x01, 0x4f, - 0x05, 0x06, 0x16, 0x1c, 0x1a, 0x3f, 0x1a, 0x21, 0x11, 0x06, 0x24, 0x01, - 0x47, 0xfe, 0xb9, 0x02, 0xfe, 0xf3, 0xfe, 0xb0, 0x03, 0x8b, 0xfe, 0xb0, - 0x05, 0x05, 0x16, 0x1c, 0x1a, 0x3f, 0x1a, 0x1c, 0x16, 0x05, 0x26, 0xfe, - 0xba, 0x01, 0x46, 0x02, 0xfe, 0x6f, 0x04, 0x53, 0x02, 0x64, 0xe5, 0xe5, - 0x07, 0x06, 0x15, 0x0d, 0x0b, 0x0b, 0x0f, 0x13, 0x07, 0x81, 0xdd, 0x01, - 0xf1, 0xdd, 0x0d, 0x0e, 0x0f, 0x51, 0xe5, 0xe5, 0x06, 0x06, 0x15, 0x0c, - 0x0b, 0x0b, 0x0c, 0x15, 0x06, 0x81, 0xdd, 0xfe, 0x0f, 0xdc, 0x0e, 0x0f, - 0x0e, 0xfe, 0x60, 0x03, 0x23, 0xfc, 0xdd, 0x00, 0x00, 0x04, 0x01, 0x44, - 0x00, 0x0b, 0x03, 0x8d, 0x04, 0xea, 0x00, 0x4b, 0x00, 0xc6, 0x00, 0xd9, - 0x00, 0xe9, 0x00, 0x00, 0x01, 0x34, 0x37, 0x36, 0x3f, 0x01, 0x36, 0x37, - 0x32, 0x3b, 0x01, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, - 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x1f, 0x01, 0x16, 0x17, 0x36, 0x37, - 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x37, 0x36, 0x33, - 0x32, 0x17, 0x16, 0x17, 0x16, 0x0f, 0x01, 0x06, 0x1f, 0x01, 0x16, 0x15, - 0x14, 0x07, 0x17, 0x14, 0x07, 0x06, 0x15, 0x14, 0x17, 0x21, 0x35, 0x34, - 0x27, 0x26, 0x27, 0x26, 0x37, 0x36, 0x27, 0x26, 0x01, 0x26, 0x23, 0x22, - 0x0f, 0x01, 0x06, 0x0f, 0x01, 0x06, 0x0f, 0x01, 0x27, 0x26, 0x2f, 0x01, - 0x26, 0x27, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, - 0x16, 0x1f, 0x02, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, - 0x27, 0x26, 0x27, 0x26, 0x2f, 0x01, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, - 0x06, 0x07, 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, - 0x06, 0x07, 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x26, 0x27, 0x26, 0x27, 0x26, 0x3f, 0x01, 0x36, 0x27, 0x26, 0x27, - 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x23, 0x22, 0x17, 0x16, 0x17, - 0x16, 0x1f, 0x01, 0x16, 0x15, 0x07, 0x21, 0x27, 0x34, 0x37, 0x36, 0x2f, - 0x01, 0x36, 0x35, 0x34, 0x27, 0x26, 0x37, 0x13, 0x36, 0x27, 0x01, 0x07, - 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, - 0x34, 0x27, 0x26, 0x27, 0x26, 0x07, 0x06, 0x07, 0x16, 0x17, 0x16, 0x33, - 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x2f, 0x01, 0x01, 0x44, 0x1f, - 0x12, 0x0e, 0x2b, 0x11, 0x1f, 0x02, 0x02, 0x03, 0x15, 0x22, 0x19, 0x10, - 0x1c, 0x13, 0x16, 0x1e, 0x0d, 0x0e, 0x28, 0x0e, 0x3c, 0x3e, 0x1f, 0x0c, - 0x0c, 0x0f, 0x05, 0x04, 0x09, 0x04, 0x0a, 0x04, 0x01, 0x05, 0x1e, 0x16, - 0x21, 0x2d, 0x18, 0x0b, 0x01, 0x09, 0x02, 0x07, 0x01, 0x02, 0x02, 0x03, - 0x01, 0x03, 0x11, 0x03, 0x01, 0xfe, 0x40, 0x04, 0x07, 0x1f, 0x28, 0x01, - 0x02, 0x18, 0x0f, 0x02, 0x13, 0x03, 0x20, 0x1c, 0x04, 0x04, 0x01, 0x08, - 0x1d, 0x04, 0x12, 0x2c, 0x14, 0x08, 0x23, 0x0e, 0x25, 0x3e, 0x16, 0x10, - 0x0e, 0x0b, 0x0e, 0x07, 0x06, 0x18, 0x0b, 0x0f, 0x4e, 0x70, 0x4e, 0x4d, - 0x03, 0x10, 0x04, 0x04, 0x12, 0x0f, 0x04, 0x03, 0x26, 0x5f, 0x2a, 0x06, - 0x23, 0x18, 0x10, 0x0a, 0x05, 0x04, 0x03, 0x07, 0x28, 0x21, 0x0a, 0x07, - 0x26, 0x29, 0x11, 0x0c, 0x01, 0x2c, 0x13, 0x14, 0x2c, 0x08, 0x02, 0x17, - 0x66, 0x26, 0x05, 0x06, 0x0b, 0x01, 0x06, 0x02, 0x06, 0x06, 0x0c, 0x17, - 0x21, 0x0b, 0x0d, 0x13, 0x0e, 0x28, 0x08, 0x03, 0x02, 0x08, 0x06, 0x03, - 0x08, 0x4b, 0x01, 0x01, 0x01, 0x5f, 0x01, 0x0a, 0x0b, 0x01, 0x01, 0x02, - 0x07, 0x05, 0x01, 0x09, 0x01, 0x02, 0xfe, 0x5a, 0x0e, 0x1d, 0x30, 0x2d, - 0x0e, 0x03, 0x01, 0x0e, 0x08, 0x09, 0x03, 0x02, 0x0a, 0x04, 0x05, 0x59, - 0x69, 0x0c, 0x02, 0x44, 0x1f, 0x0c, 0x09, 0x0d, 0x07, 0x03, 0x0a, 0x06, - 0x09, 0x63, 0x02, 0x70, 0x2d, 0x29, 0x05, 0x1a, 0x4c, 0x1e, 0x09, 0x26, - 0x67, 0x4b, 0x1d, 0x31, 0x1e, 0x16, 0x17, 0x1a, 0x04, 0x0a, 0x15, 0x5b, - 0x9a, 0x4e, 0x1e, 0x11, 0x0e, 0x33, 0x24, 0x1a, 0x0d, 0x6e, 0x2f, 0x05, - 0x09, 0x09, 0x22, 0x21, 0x18, 0x30, 0x15, 0x0f, 0x7b, 0x49, 0xf6, 0x17, - 0x22, 0x12, 0x1d, 0x48, 0x1e, 0x23, 0x66, 0x18, 0x6d, 0x0f, 0x74, 0x32, - 0x3e, 0x95, 0x0f, 0x1b, 0x2c, 0x37, 0x48, 0x1f, 0x42, 0x49, 0x2e, 0x02, - 0x3b, 0x2f, 0x38, 0x5b, 0x18, 0x2c, 0xa0, 0x17, 0x05, 0x0d, 0x09, 0x0b, - 0x51, 0x1f, 0x5b, 0x7a, 0x29, 0x0c, 0x0a, 0x09, 0x05, 0x09, 0x19, 0x2e, - 0x16, 0x29, 0xd1, 0x53, 0x39, 0x4c, 0x0a, 0x07, 0x0f, 0x03, 0x01, 0x10, - 0x05, 0x06, 0x2a, 0x45, 0x1f, 0x03, 0x19, 0x12, 0x08, 0x06, 0x09, 0x12, - 0x20, 0x1a, 0x0f, 0x09, 0x27, 0x2b, 0x28, 0x1d, 0x34, 0x25, 0x1a, 0x02, - 0x28, 0x34, 0x17, 0x0d, 0x20, 0x0e, 0x05, 0x04, 0x0d, 0x07, 0x2a, 0x58, - 0x0d, 0x08, 0x13, 0x12, 0x3e, 0x0c, 0x09, 0x09, 0x04, 0x15, 0x03, 0x04, - 0x0a, 0x37, 0x03, 0x1c, 0x41, 0x29, 0x12, 0xaf, 0x08, 0x09, 0x82, 0x96, - 0x30, 0x27, 0x2d, 0x35, 0x37, 0x30, 0x2b, 0x49, 0x3b, 0x2d, 0x25, 0x01, - 0x0a, 0x0e, 0x2a, 0xfe, 0xa7, 0x11, 0x23, 0x25, 0x28, 0x30, 0x0a, 0x0a, - 0x0e, 0x0d, 0x07, 0x08, 0x11, 0x13, 0x07, 0x04, 0x5d, 0x0f, 0x10, 0x27, - 0x35, 0x2e, 0x07, 0x0e, 0x09, 0x08, 0x0f, 0x0e, 0x09, 0x04, 0x55, 0x00, - 0x00, 0x08, 0x00, 0x2d, 0x00, 0x95, 0x04, 0xa4, 0x03, 0xfc, 0x00, 0x06, - 0x00, 0x39, 0x00, 0x4c, 0x00, 0x70, 0x00, 0x7b, 0x00, 0x7f, 0x00, 0x89, - 0x00, 0x8d, 0x00, 0x00, 0x13, 0x16, 0x37, 0x36, 0x35, 0x34, 0x27, 0x05, - 0x22, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x2b, 0x01, 0x22, 0x27, 0x0f, - 0x01, 0x37, 0x26, 0x35, 0x34, 0x3f, 0x01, 0x36, 0x37, 0x36, 0x37, 0x36, - 0x37, 0x36, 0x33, 0x32, 0x17, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, - 0x07, 0x17, 0x16, 0x33, 0x32, 0x37, 0x33, 0x16, 0x15, 0x14, 0x07, 0x23, - 0x35, 0x06, 0x25, 0x36, 0x37, 0x36, 0x37, 0x13, 0x27, 0x26, 0x23, 0x22, - 0x07, 0x06, 0x0f, 0x01, 0x16, 0x15, 0x14, 0x07, 0x36, 0x25, 0x22, 0x2f, - 0x01, 0x07, 0x14, 0x07, 0x36, 0x37, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, - 0x22, 0x07, 0x16, 0x15, 0x14, 0x07, 0x32, 0x37, 0x36, 0x33, 0x32, 0x17, - 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x06, 0x37, 0x16, 0x15, - 0x14, 0x07, 0x15, 0x33, 0x36, 0x35, 0x34, 0x27, 0x05, 0x36, 0x37, 0x0f, - 0x01, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x36, 0x35, 0x34, 0x0f, 0x01, - 0x37, 0x26, 0xa9, 0x13, 0x0f, 0x0b, 0x0c, 0x02, 0x74, 0x21, 0x4d, 0x23, - 0x14, 0x1b, 0x6c, 0x35, 0x17, 0x47, 0x3b, 0x1a, 0x40, 0xbc, 0x5c, 0x05, - 0x0a, 0x32, 0x14, 0x12, 0x42, 0x58, 0x2d, 0x30, 0x19, 0x19, 0x25, 0x2d, - 0x6d, 0x20, 0x2a, 0x1b, 0x15, 0x09, 0x87, 0x91, 0x20, 0x1c, 0x27, 0x04, - 0xa1, 0x3f, 0x2c, 0xb1, 0x4e, 0xfd, 0xab, 0x18, 0x15, 0x06, 0x03, 0xef, - 0x1a, 0x0c, 0x16, 0x3f, 0xa8, 0x27, 0x18, 0x0e, 0x21, 0x1f, 0x1c, 0x02, - 0x9f, 0x26, 0x11, 0xad, 0x52, 0x3b, 0x2d, 0x3e, 0x0b, 0x1a, 0x3c, 0x5c, - 0x2d, 0x11, 0x18, 0x0e, 0x52, 0x35, 0x2d, 0x36, 0x1c, 0x45, 0x21, 0x22, - 0x24, 0x62, 0x1f, 0x24, 0x12, 0x36, 0x24, 0x21, 0x71, 0x22, 0x2c, 0xfd, - 0xa2, 0x3b, 0x0a, 0x74, 0x40, 0x50, 0x22, 0x16, 0x1f, 0x10, 0xfb, 0x23, - 0x43, 0x05, 0x01, 0x7f, 0x02, 0x1c, 0x16, 0x16, 0x16, 0x0c, 0xdf, 0x0a, - 0x03, 0x0b, 0x06, 0x2a, 0x46, 0x53, 0xc0, 0x0d, 0x17, 0x12, 0x22, 0xa5, - 0x44, 0x18, 0x58, 0x40, 0x21, 0x13, 0x09, 0x25, 0x7a, 0x24, 0x28, 0x12, - 0x15, 0x9c, 0x60, 0x15, 0x15, 0x5d, 0x81, 0x94, 0x6a, 0x4d, 0x1a, 0xa6, - 0x1a, 0x50, 0x14, 0x0b, 0x01, 0x0a, 0x15, 0x0a, 0xa6, 0x26, 0x4f, 0x2f, - 0x2b, 0x1c, 0x40, 0x19, 0x06, 0xfc, 0x0c, 0x70, 0x5f, 0x75, 0x3c, 0x02, - 0x1e, 0x0a, 0x0f, 0x0d, 0x0b, 0x1c, 0x01, 0x1c, 0x33, 0x1e, 0x20, 0x09, - 0x08, 0x09, 0x04, 0x1a, 0x44, 0x4d, 0x4b, 0x5a, 0x05, 0x15, 0x52, 0x64, - 0x59, 0x4c, 0x36, 0x44, 0x95, 0x5f, 0x59, 0xab, 0x42, 0x49, 0x8b, 0x35, - 0x13, 0x2e, 0x21, 0x16, 0x0e, 0x02, 0x21, 0x27, 0x27, 0x6b, 0x47, 0x1c, - 0x1a, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x57, 0x00, 0x84, 0x04, 0x7a, - 0x04, 0xa6, 0x00, 0x15, 0x00, 0x1b, 0x00, 0x22, 0x00, 0x29, 0x00, 0x33, - 0x00, 0x53, 0x00, 0x5a, 0x00, 0x00, 0x01, 0x36, 0x37, 0x36, 0x35, 0x34, - 0x2f, 0x01, 0x06, 0x23, 0x14, 0x07, 0x06, 0x23, 0x14, 0x07, 0x17, 0x16, - 0x33, 0x32, 0x37, 0x36, 0x01, 0x3f, 0x01, 0x0f, 0x02, 0x13, 0x37, 0x01, - 0x13, 0x25, 0x01, 0x37, 0x05, 0x01, 0x16, 0x35, 0x34, 0x27, 0x01, 0x00, - 0x36, 0x35, 0x34, 0x27, 0x01, 0x07, 0x01, 0x16, 0x33, 0x01, 0x36, 0x37, - 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, - 0x06, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, - 0x34, 0x37, 0x36, 0x37, 0x36, 0x17, 0x07, 0x01, 0x16, 0x33, 0x32, 0x27, - 0x03, 0xf2, 0x07, 0x04, 0x05, 0x01, 0x30, 0x13, 0x18, 0x2c, 0x2c, 0x3b, - 0x12, 0xc0, 0x07, 0x06, 0x08, 0x0c, 0x09, 0xfd, 0x28, 0x7c, 0x0b, 0x77, - 0x7c, 0x0b, 0x6b, 0xd7, 0x02, 0x06, 0x95, 0xfd, 0xe4, 0xfd, 0xfb, 0x0e, - 0x01, 0x69, 0x01, 0xab, 0x35, 0x02, 0xfe, 0x2e, 0x01, 0x55, 0x2c, 0x05, - 0xfe, 0x5c, 0x5c, 0x01, 0xa4, 0x0e, 0x0c, 0xfd, 0xea, 0x0a, 0x0d, 0x0c, - 0x0d, 0x0b, 0x08, 0x0b, 0x08, 0x06, 0x04, 0x05, 0x07, 0x08, 0x0c, 0x0b, - 0x0c, 0x0c, 0x0d, 0x0c, 0x07, 0x0b, 0x08, 0x05, 0x03, 0x04, 0x08, 0x08, - 0x25, 0x67, 0x01, 0xd2, 0x09, 0x08, 0x2e, 0x01, 0x01, 0x0b, 0x06, 0x0a, - 0x0d, 0x08, 0x04, 0x07, 0xc1, 0x12, 0x3b, 0x2c, 0x2d, 0x16, 0x14, 0x30, - 0x01, 0x05, 0x04, 0x02, 0x6a, 0x7b, 0x77, 0x0b, 0x7b, 0x77, 0x01, 0x33, - 0x0f, 0xfd, 0xfb, 0xfd, 0xe4, 0x96, 0x02, 0x04, 0xd8, 0x11, 0xfe, 0x56, - 0x01, 0x2e, 0x08, 0x0a, 0x01, 0xd2, 0xfd, 0x54, 0x2c, 0x1b, 0x0c, 0x0e, - 0x01, 0xa5, 0x5c, 0xfe, 0x5b, 0x05, 0x02, 0x5e, 0x0b, 0x09, 0x08, 0x04, - 0x03, 0x06, 0x07, 0x0b, 0x08, 0x0b, 0x0d, 0x0c, 0x0e, 0x0a, 0x0c, 0x08, - 0x08, 0x04, 0x03, 0x06, 0x05, 0x0d, 0x09, 0x0b, 0x0d, 0x0b, 0x0d, 0xc6, - 0x0b, 0xfe, 0x2d, 0x01, 0x35, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x26, - 0x00, 0xe0, 0x04, 0xab, 0x02, 0xc4, 0x00, 0x13, 0x00, 0x19, 0x00, 0x20, - 0x00, 0x27, 0x00, 0x2d, 0x00, 0x45, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x34, - 0x27, 0x26, 0x27, 0x26, 0x2f, 0x01, 0x14, 0x07, 0x16, 0x14, 0x07, 0x16, - 0x15, 0x37, 0x36, 0x37, 0x36, 0x37, 0x05, 0x35, 0x27, 0x07, 0x15, 0x17, - 0x03, 0x37, 0x21, 0x0d, 0x01, 0x21, 0x27, 0x37, 0x21, 0x36, 0x35, 0x34, - 0x27, 0x21, 0x04, 0x34, 0x27, 0x21, 0x15, 0x21, 0x24, 0x34, 0x37, 0x36, - 0x37, 0x3e, 0x01, 0x32, 0x16, 0x17, 0x16, 0x17, 0x16, 0x14, 0x07, 0x06, - 0x07, 0x0e, 0x01, 0x22, 0x26, 0x27, 0x26, 0x27, 0x17, 0x07, 0x21, 0x36, - 0x35, 0x34, 0x27, 0x04, 0x03, 0x03, 0x02, 0x05, 0x03, 0x08, 0x95, 0x0f, - 0x24, 0x24, 0x0f, 0x95, 0x08, 0x03, 0x05, 0x02, 0xfc, 0xe6, 0x43, 0x43, - 0x43, 0x7c, 0x7c, 0x02, 0x5d, 0x01, 0xaa, 0xfe, 0x56, 0xfd, 0xa3, 0x7c, - 0xea, 0x01, 0xec, 0x12, 0x19, 0xfd, 0xe2, 0x02, 0x56, 0x23, 0xfe, 0x1b, - 0x01, 0xe5, 0xfd, 0x75, 0x03, 0x02, 0x05, 0x05, 0x0d, 0x0e, 0x0d, 0x05, - 0x06, 0x02, 0x03, 0x03, 0x02, 0x06, 0x05, 0x0d, 0x0e, 0x0d, 0x05, 0x05, - 0x02, 0x8e, 0x39, 0x02, 0x1e, 0x19, 0x12, 0x01, 0xca, 0x11, 0x08, 0x07, - 0x06, 0x05, 0x04, 0x5a, 0x17, 0x0f, 0x28, 0x66, 0x28, 0x0e, 0x17, 0x59, - 0x04, 0x05, 0x07, 0x07, 0x3c, 0x99, 0x50, 0x50, 0x99, 0x50, 0x01, 0x00, - 0x8e, 0xf2, 0xf1, 0x8e, 0xd5, 0x12, 0x10, 0x13, 0x12, 0xe1, 0x50, 0x11, - 0x72, 0x2b, 0x1c, 0x0d, 0x0c, 0x0b, 0x0a, 0x0b, 0x0b, 0x0a, 0x0b, 0x0c, - 0x0d, 0x1c, 0x0d, 0x0c, 0x0a, 0x0a, 0x0c, 0x0c, 0x0a, 0x0a, 0x0c, 0x56, - 0x48, 0x12, 0x14, 0x10, 0x12, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x57, - 0x00, 0xbb, 0x04, 0x7a, 0x04, 0xdd, 0x00, 0x15, 0x00, 0x1b, 0x00, 0x22, - 0x00, 0x29, 0x00, 0x33, 0x00, 0x53, 0x00, 0x5a, 0x00, 0x00, 0x01, 0x26, - 0x27, 0x26, 0x23, 0x22, 0x0f, 0x01, 0x16, 0x15, 0x32, 0x17, 0x16, 0x15, - 0x32, 0x17, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x01, 0x27, 0x1f, 0x02, - 0x27, 0x07, 0x2f, 0x01, 0x01, 0x25, 0x03, 0x01, 0x27, 0x17, 0x01, 0x36, - 0x35, 0x34, 0x07, 0x2e, 0x01, 0x23, 0x22, 0x07, 0x01, 0x17, 0x01, 0x36, - 0x35, 0x01, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x33, - 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, - 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x37, 0x01, 0x36, - 0x23, 0x22, 0x07, 0x01, 0x03, 0xf2, 0x07, 0x09, 0x0c, 0x08, 0x06, 0x07, - 0xc0, 0x12, 0x3b, 0x2c, 0x2c, 0x18, 0x13, 0x30, 0x01, 0x05, 0x04, 0xfd, - 0x1a, 0x77, 0x0b, 0x7c, 0x77, 0x0b, 0x88, 0xa1, 0x0e, 0x02, 0x05, 0x02, - 0x1c, 0x95, 0xfd, 0xfa, 0x0f, 0x0c, 0x01, 0xd2, 0x02, 0x35, 0x1e, 0x2c, - 0x1b, 0x0c, 0x0e, 0xfe, 0x5c, 0x5c, 0x01, 0xa4, 0x05, 0xfd, 0xa3, 0x0c, - 0x08, 0x08, 0x04, 0x03, 0x05, 0x08, 0x0b, 0x07, 0x0c, 0x0d, 0x0c, 0x0c, - 0x0b, 0x0c, 0x08, 0x07, 0x05, 0x04, 0x06, 0x08, 0x0b, 0x08, 0x0b, 0x0d, - 0x0c, 0x0d, 0x0f, 0x01, 0xa9, 0x01, 0x2e, 0x08, 0x09, 0xfe, 0x2e, 0x04, - 0x56, 0x07, 0x05, 0x04, 0x01, 0x30, 0x14, 0x16, 0x2d, 0x2c, 0x3a, 0x13, - 0xc1, 0x07, 0x04, 0x08, 0x0d, 0x0a, 0xfd, 0xa3, 0x0b, 0x77, 0x7b, 0x0b, - 0x77, 0xad, 0xa0, 0xd8, 0x02, 0x05, 0x95, 0xfd, 0xe5, 0xfd, 0xfa, 0xc0, - 0x68, 0x01, 0xd3, 0x0a, 0x08, 0x2e, 0x01, 0x6f, 0x2c, 0x05, 0xfe, 0x5b, - 0x5c, 0x01, 0xa5, 0x0e, 0x0c, 0xfd, 0xe8, 0x0c, 0x0d, 0x0b, 0x0d, 0x0b, - 0x09, 0x0d, 0x05, 0x06, 0x03, 0x04, 0x08, 0x08, 0x0c, 0x0a, 0x0e, 0x0c, - 0x0d, 0x0b, 0x08, 0x0b, 0x07, 0x06, 0x03, 0x04, 0x08, 0x09, 0xdc, 0x01, - 0xaa, 0x36, 0x02, 0xfe, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x3b, - 0x01, 0x2b, 0x04, 0x96, 0x03, 0x5d, 0x00, 0x23, 0x00, 0x43, 0x00, 0x00, - 0x12, 0x34, 0x27, 0x16, 0x25, 0x05, 0x15, 0x25, 0x2e, 0x01, 0x27, 0x26, - 0x22, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x14, 0x17, 0x16, 0x17, 0x16, - 0x17, 0x16, 0x32, 0x37, 0x3e, 0x01, 0x37, 0x25, 0x15, 0x05, 0x24, 0x07, - 0x36, 0x14, 0x07, 0x36, 0x05, 0x25, 0x05, 0x06, 0x07, 0x06, 0x22, 0x27, - 0x26, 0x27, 0x26, 0x27, 0x26, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, - 0x32, 0x17, 0x16, 0x17, 0x05, 0x25, 0x04, 0x27, 0x62, 0x26, 0xe0, 0x01, - 0xa2, 0x01, 0xd7, 0xfe, 0x49, 0x04, 0x0b, 0x0d, 0x0a, 0x17, 0x0a, 0x0b, - 0x08, 0x08, 0x04, 0x05, 0x05, 0x06, 0x06, 0x08, 0x0b, 0x0a, 0x17, 0x0a, - 0x0d, 0x0b, 0x04, 0x01, 0xb7, 0xfe, 0x29, 0xfe, 0x5e, 0xe0, 0x74, 0x11, - 0x83, 0x01, 0x9c, 0x01, 0x4e, 0xfe, 0xf1, 0x11, 0x14, 0x14, 0x2f, 0x14, - 0x15, 0x10, 0x11, 0x09, 0x08, 0x08, 0x09, 0x11, 0x10, 0x15, 0x14, 0x2f, - 0x14, 0x14, 0x11, 0x01, 0x0f, 0xfe, 0xb2, 0xfe, 0x64, 0x83, 0x01, 0xc9, - 0xf7, 0x49, 0x03, 0x57, 0xd2, 0x3f, 0x15, 0x06, 0x0c, 0x07, 0x04, 0x04, - 0x05, 0x08, 0x06, 0x0d, 0x0a, 0x18, 0x0a, 0x0e, 0x05, 0x08, 0x04, 0x05, - 0x05, 0x06, 0x0c, 0x06, 0x16, 0x40, 0xd1, 0x56, 0x02, 0xf9, 0x69, 0x44, - 0x02, 0x56, 0x8d, 0x12, 0x10, 0x09, 0x09, 0x09, 0x09, 0x10, 0x11, 0x14, - 0x15, 0x2f, 0x14, 0x14, 0x12, 0x10, 0x09, 0x08, 0x08, 0x09, 0x10, 0x13, - 0x8d, 0x56, 0x03, 0x00, 0x00, 0x01, 0x00, 0x25, 0x01, 0x11, 0x04, 0xac, - 0x03, 0x1b, 0x00, 0x26, 0x00, 0x00, 0x01, 0x25, 0x15, 0x05, 0x24, 0x07, - 0x36, 0x34, 0x27, 0x16, 0x25, 0x05, 0x15, 0x25, 0x26, 0x27, 0x26, 0x27, - 0x26, 0x22, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, - 0x17, 0x16, 0x17, 0x16, 0x32, 0x37, 0x36, 0x37, 0x36, 0x02, 0xe8, 0x01, - 0xc4, 0xfe, 0x04, 0xfe, 0x40, 0xcb, 0x29, 0x29, 0xcb, 0x01, 0xc0, 0x01, - 0xfc, 0xfe, 0x3c, 0x05, 0x0d, 0x0b, 0x0f, 0x0e, 0x22, 0x0e, 0x0f, 0x0b, - 0x0d, 0x05, 0x07, 0x07, 0x05, 0x0d, 0x0b, 0x0f, 0x0e, 0x22, 0x0e, 0x0f, - 0x0b, 0x0d, 0x01, 0xf7, 0x17, 0x1b, 0xe2, 0x5d, 0x02, 0x4e, 0xb8, 0x4f, - 0x03, 0x5d, 0xe2, 0x1b, 0x18, 0x0e, 0x0c, 0x0c, 0x06, 0x07, 0x07, 0x06, - 0x0c, 0x0c, 0x0e, 0x0f, 0x11, 0x10, 0x0f, 0x0e, 0x0c, 0x0c, 0x06, 0x07, - 0x07, 0x06, 0x0c, 0x0c, 0x00, 0x01, 0x00, 0x98, 0x00, 0xc0, 0x04, 0x39, - 0x04, 0x7c, 0x00, 0x1c, 0x00, 0x00, 0x01, 0x32, 0x17, 0x16, 0x33, 0x32, - 0x37, 0x12, 0x37, 0x36, 0x33, 0x32, 0x16, 0x15, 0x14, 0x07, 0x00, 0x01, - 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x01, - 0x18, 0x22, 0x12, 0x23, 0x0f, 0x0c, 0x0c, 0xf5, 0xd2, 0x36, 0x76, 0x1c, - 0x13, 0x1d, 0xfe, 0xae, 0xfe, 0xe0, 0x14, 0x3e, 0x3f, 0x0c, 0x1e, 0x28, - 0x2d, 0x3d, 0x25, 0x02, 0x50, 0x38, 0x6a, 0x12, 0x01, 0x8a, 0xf3, 0x3f, - 0x0a, 0x08, 0x0d, 0x23, 0xfe, 0x6a, 0xfe, 0x3c, 0x20, 0x06, 0x0d, 0x79, - 0x86, 0x22, 0x24, 0x22, 0x16, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x4a, - 0x00, 0x72, 0x04, 0x87, 0x04, 0x42, 0x00, 0x1d, 0x00, 0x00, 0x01, 0x32, - 0x17, 0x16, 0x33, 0x32, 0x37, 0x12, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x00, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, - 0x35, 0x34, 0x37, 0x36, 0x01, 0x07, 0x22, 0x12, 0x22, 0x0f, 0x0c, 0x0c, - 0xf6, 0xd1, 0x59, 0x54, 0x6f, 0x16, 0x0a, 0x14, 0xfd, 0xcd, 0x6b, 0x25, - 0x85, 0x2c, 0x30, 0x14, 0x32, 0x3f, 0x3d, 0x56, 0x02, 0x8e, 0x38, 0x6a, - 0x12, 0x01, 0x69, 0x99, 0x41, 0x07, 0x02, 0x14, 0x0f, 0x18, 0xfd, 0x7b, - 0xc3, 0x43, 0x17, 0x0b, 0x7b, 0x9c, 0x75, 0x2b, 0x1c, 0x27, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x81, 0x00, 0x71, 0x04, 0x50, 0x04, 0x3f, 0x00, 0x0b, - 0x00, 0x00, 0x09, 0x01, 0x07, 0x09, 0x01, 0x27, 0x09, 0x01, 0x37, 0x09, - 0x01, 0x17, 0x02, 0xdb, 0x01, 0x73, 0x73, 0xfe, 0x8d, 0xfe, 0x8d, 0x73, - 0x01, 0x73, 0xfe, 0x8d, 0x73, 0x01, 0x73, 0x01, 0x74, 0x73, 0x02, 0x58, - 0xfe, 0x8c, 0x72, 0x01, 0x73, 0xfe, 0x8d, 0x72, 0x01, 0x74, 0x01, 0x73, - 0x73, 0xfe, 0x8d, 0x01, 0x73, 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40, - 0x00, 0xbc, 0x04, 0x51, 0x04, 0xcf, 0x00, 0x0b, 0x00, 0x00, 0x09, 0x01, - 0x07, 0x09, 0x01, 0x27, 0x09, 0x01, 0x37, 0x09, 0x01, 0x17, 0x03, 0x35, - 0x01, 0x1c, 0xed, 0xfe, 0xe4, 0xfe, 0xe5, 0xed, 0x01, 0x1c, 0xfe, 0xe4, - 0xed, 0x01, 0x1b, 0x01, 0x1c, 0xed, 0x02, 0xc5, 0xfe, 0xe5, 0xed, 0x01, - 0x1b, 0xfe, 0xe5, 0xed, 0x01, 0x1b, 0x01, 0x1b, 0xed, 0xfe, 0xe5, 0x01, - 0x1c, 0xed, 0x00, 0x00, 0x00, 0x01, 0x00, 0x83, 0xff, 0xec, 0x04, 0x4e, - 0x04, 0xbe, 0x00, 0x42, 0x00, 0x00, 0x01, 0x32, 0x17, 0x16, 0x17, 0x36, - 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x16, 0x17, 0x16, - 0x15, 0x14, 0x0f, 0x01, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, - 0x26, 0x27, 0x06, 0x03, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, - 0x36, 0x37, 0x12, 0x37, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x33, - 0x32, 0x17, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x36, 0x37, - 0x36, 0x03, 0xc9, 0x08, 0x0d, 0x0e, 0x0e, 0x18, 0x0e, 0x0c, 0x15, 0x0d, - 0x12, 0xa9, 0x9f, 0x42, 0x74, 0x0a, 0x19, 0x1a, 0x03, 0x11, 0x16, 0x09, - 0x15, 0x11, 0x61, 0x68, 0x8c, 0xb4, 0x1a, 0x3e, 0x1d, 0x04, 0x29, 0x09, - 0x04, 0x16, 0xa6, 0xb9, 0x63, 0x21, 0x07, 0x0f, 0x0f, 0x0d, 0x0c, 0x13, - 0x07, 0x0b, 0x0e, 0x17, 0x1a, 0x08, 0x2c, 0x48, 0x73, 0xa6, 0x13, 0x04, - 0xbe, 0x0d, 0x0d, 0x16, 0x2a, 0x16, 0x0e, 0x11, 0x16, 0x13, 0xb7, 0xdc, - 0xa1, 0xc2, 0x11, 0x09, 0x13, 0x14, 0x12, 0x0a, 0x10, 0x19, 0x0d, 0x0e, - 0x15, 0x7d, 0xa9, 0xb6, 0xfe, 0xd0, 0x2c, 0x22, 0x17, 0x32, 0x41, 0x19, - 0x0b, 0x22, 0x01, 0x03, 0xd8, 0xec, 0x7f, 0x1c, 0x09, 0x0b, 0x15, 0x15, - 0x17, 0x0e, 0x09, 0x0d, 0x18, 0x89, 0x7b, 0x95, 0xa6, 0x14, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x33, 0xff, 0xfd, 0x04, 0x9e, 0x05, 0x2b, 0x00, 0x51, - 0x00, 0x00, 0x01, 0x32, 0x17, 0x16, 0x17, 0x36, 0x17, 0x16, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x06, 0x03, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, - 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x06, 0x07, 0x06, 0x23, 0x22, - 0x27, 0x26, 0x27, 0x06, 0x07, 0x06, 0x23, 0x06, 0x27, 0x26, 0x27, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x26, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x36, 0x37, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x33, 0x32, - 0x17, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x36, 0x37, 0x36, - 0x04, 0x00, 0x1a, 0x17, 0x12, 0x07, 0x16, 0x09, 0x1c, 0x0d, 0x0c, 0x0e, - 0xd3, 0xce, 0x82, 0x81, 0x0f, 0x1a, 0x12, 0x20, 0x02, 0x0c, 0x15, 0x1c, - 0x20, 0x1a, 0x07, 0x0c, 0x1f, 0x18, 0x14, 0x17, 0x4e, 0x6a, 0xc9, 0x4d, - 0x0f, 0x12, 0x11, 0x10, 0x0d, 0x02, 0x11, 0x10, 0x16, 0x19, 0x20, 0x1b, - 0x08, 0x08, 0x10, 0x15, 0x72, 0xac, 0x6b, 0x57, 0x13, 0x14, 0x0e, 0x13, - 0x17, 0x2a, 0x01, 0x0a, 0x14, 0x0e, 0x26, 0x0c, 0x5c, 0x84, 0xca, 0xda, - 0x0a, 0x05, 0x2a, 0x1a, 0x13, 0x33, 0x01, 0x05, 0x0a, 0x0c, 0x0c, 0x12, - 0x23, 0x0e, 0xc0, 0xfe, 0xef, 0xb3, 0x8e, 0x0f, 0x16, 0x2a, 0x17, 0x0f, - 0x02, 0x0f, 0x1e, 0x33, 0x15, 0x10, 0x09, 0x18, 0x18, 0x54, 0xa7, 0xe5, - 0x76, 0x16, 0x02, 0x21, 0x1b, 0x0c, 0x0b, 0x1a, 0x1f, 0x0f, 0x17, 0x28, - 0x02, 0x0c, 0x15, 0x15, 0x12, 0x1b, 0x9a, 0xba, 0xa5, 0xea, 0x35, 0x19, - 0x16, 0x2b, 0x1c, 0x22, 0x0c, 0x16, 0x2c, 0x17, 0xab, 0xa3, 0xe7, 0xbf, - 0x0a, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, 0x00, 0x05, 0x04, 0x91, - 0x04, 0x56, 0x00, 0x0b, 0x00, 0x17, 0x00, 0x23, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x25, 0x21, - 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, 0x03, 0x21, - 0x15, 0x21, 0x11, 0x23, 0x11, 0x21, 0x35, 0x21, 0x11, 0x33, 0x03, 0x0b, - 0xfe, 0xbb, 0xfe, 0xc5, 0x01, 0x3b, 0x01, 0x45, 0x01, 0x3b, 0xff, 0x00, - 0x01, 0x4a, 0xfe, 0xb6, 0xfe, 0x45, 0xfe, 0xb6, 0x01, 0x4a, 0x01, 0xbb, - 0x94, 0x01, 0x4a, 0xfe, 0xb6, 0x93, 0xfe, 0xb6, 0x01, 0x4a, 0x93, 0x02, - 0xd0, 0x01, 0x3c, 0xfe, 0xc4, 0xfe, 0xbb, 0xfe, 0xc5, 0x01, 0x3b, 0x01, - 0x45, 0x3b, 0xfe, 0x45, 0xfe, 0xb6, 0x01, 0x4a, 0x01, 0xbb, 0x01, 0x4b, - 0xfe, 0x21, 0x94, 0xfe, 0xb7, 0x01, 0x49, 0x94, 0x01, 0x4b, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x56, 0x00, 0x07, 0x04, 0x7b, 0x04, 0x06, 0x00, 0x0b, - 0x00, 0x00, 0x01, 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, - 0x11, 0x21, 0x02, 0xf7, 0x01, 0x84, 0xfe, 0x7c, 0xfe, 0xe3, 0xfe, 0x7c, - 0x01, 0x84, 0x01, 0x1d, 0x02, 0x8f, 0xfe, 0xee, 0xfe, 0x8b, 0x01, 0x75, - 0x01, 0x12, 0x01, 0x76, 0x00, 0x02, 0x00, 0x39, 0x00, 0x06, 0x04, 0x98, - 0x04, 0x66, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x00, 0x01, 0x21, 0x15, 0x21, - 0x11, 0x23, 0x11, 0x21, 0x35, 0x21, 0x11, 0x33, 0x03, 0x33, 0x35, 0x23, - 0x02, 0xc2, 0x01, 0xd6, 0xfe, 0x2a, 0xb4, 0xfe, 0x2b, 0x01, 0xd5, 0xb4, - 0xb3, 0xb2, 0xb2, 0x02, 0x90, 0xb4, 0xfe, 0x2a, 0x01, 0xd6, 0xb4, 0x01, - 0xd6, 0xfd, 0x77, 0xb2, 0x00, 0x02, 0x00, 0x30, 0x00, 0x00, 0x04, 0xa1, - 0x04, 0x72, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x00, 0x01, 0x21, 0x11, 0x21, - 0x25, 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, 0x11, 0x21, - 0x01, 0xd1, 0x01, 0x2f, 0xfe, 0xd1, 0x01, 0x30, 0x01, 0xa0, 0xfe, 0x60, - 0xfe, 0xcf, 0xfe, 0x60, 0x01, 0xa0, 0x01, 0x31, 0x01, 0xa1, 0x01, 0x2f, - 0x01, 0xfe, 0xcf, 0xfe, 0x60, 0x01, 0xa0, 0x01, 0x31, 0x01, 0xa0, 0x00, - 0x00, 0x01, 0x00, 0x9b, 0x00, 0x03, 0x04, 0x29, 0x05, 0x1e, 0x00, 0x0b, - 0x00, 0x00, 0x01, 0x21, 0x15, 0x21, 0x11, 0x23, 0x11, 0x21, 0x35, 0x21, - 0x11, 0x33, 0x02, 0xcb, 0x01, 0x5e, 0xfe, 0xa2, 0xd2, 0xfe, 0xa2, 0x01, - 0x5e, 0xd2, 0x03, 0xc0, 0xd2, 0xfd, 0x16, 0x02, 0xea, 0xd2, 0x01, 0x5e, - 0x00, 0x02, 0x00, 0x7e, 0x00, 0x01, 0x04, 0x53, 0x05, 0x1c, 0x00, 0x0f, - 0x00, 0x1b, 0x00, 0x00, 0x01, 0x33, 0x17, 0x11, 0x21, 0x11, 0x21, 0x27, - 0x11, 0x23, 0x27, 0x11, 0x21, 0x11, 0x21, 0x17, 0x07, 0x11, 0x23, 0x11, - 0x21, 0x15, 0x21, 0x11, 0x33, 0x11, 0x21, 0x35, 0x03, 0x4c, 0x83, 0x83, - 0xfe, 0xfa, 0xfe, 0xbc, 0x83, 0x83, 0x84, 0x01, 0x07, 0x01, 0x44, 0x83, - 0xaf, 0xc1, 0xfe, 0xfa, 0x01, 0x06, 0xc1, 0x01, 0x07, 0x04, 0x15, 0x83, - 0xfe, 0xbc, 0xfd, 0xb3, 0x83, 0x01, 0xca, 0x83, 0x01, 0x44, 0x01, 0x07, - 0x84, 0xda, 0x01, 0x06, 0xfe, 0xfa, 0xc1, 0xfd, 0xb3, 0x02, 0x4d, 0xc1, - 0x00, 0x03, 0x00, 0x90, 0x00, 0x04, 0x04, 0x41, 0x04, 0xc2, 0x00, 0x0b, - 0x00, 0x17, 0x00, 0x23, 0x00, 0x00, 0x01, 0x35, 0x21, 0x15, 0x23, 0x11, - 0x33, 0x11, 0x21, 0x11, 0x33, 0x11, 0x27, 0x33, 0x11, 0x23, 0x11, 0x21, - 0x11, 0x23, 0x11, 0x33, 0x35, 0x21, 0x03, 0x33, 0x15, 0x23, 0x11, 0x23, - 0x11, 0x23, 0x35, 0x33, 0x35, 0x33, 0x03, 0x06, 0xfe, 0xc5, 0xf5, 0xf5, - 0x01, 0x3b, 0xf5, 0xaf, 0xf5, 0xf5, 0xfe, 0x39, 0xf5, 0xf5, 0x01, 0xc7, - 0x8c, 0xf5, 0xf5, 0xaf, 0xf5, 0xf5, 0xaf, 0x03, 0x9d, 0xe3, 0xe3, 0xfe, - 0xcb, 0xfd, 0xdd, 0x02, 0x23, 0x01, 0x35, 0x41, 0xfe, 0x49, 0xfd, 0xdd, - 0x02, 0x23, 0x01, 0xb7, 0xe4, 0xfe, 0x9a, 0xb3, 0xfd, 0xdd, 0x02, 0x23, - 0xb3, 0xe4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x30, 0x00, 0x03, 0x04, 0xa1, - 0x04, 0x76, 0x00, 0x51, 0x00, 0x00, 0x01, 0x23, 0x22, 0x07, 0x06, 0x07, - 0x06, 0x07, 0x06, 0x15, 0x23, 0x11, 0x33, 0x14, 0x17, 0x16, 0x17, 0x16, - 0x17, 0x16, 0x3b, 0x01, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, - 0x23, 0x35, 0x21, 0x15, 0x22, 0x07, 0x06, 0x07, 0x0e, 0x01, 0x1d, 0x01, - 0x33, 0x32, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, 0x33, 0x11, 0x23, - 0x34, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x2b, 0x01, 0x15, 0x14, 0x17, - 0x16, 0x17, 0x16, 0x17, 0x16, 0x33, 0x15, 0x21, 0x35, 0x32, 0x37, 0x36, - 0x37, 0x3e, 0x01, 0x35, 0x02, 0x2f, 0x5d, 0x4c, 0x45, 0x44, 0x37, 0x33, - 0x21, 0x1c, 0x26, 0x26, 0x1c, 0x1f, 0x35, 0x34, 0x47, 0x42, 0x4f, 0x5d, - 0x1c, 0x1e, 0x36, 0x33, 0x48, 0x3e, 0x53, 0x03, 0x6b, 0x53, 0x3e, 0x48, - 0x33, 0x38, 0x38, 0x5d, 0x4f, 0x42, 0x47, 0x34, 0x35, 0x1f, 0x1c, 0x26, - 0x26, 0x1c, 0x21, 0x33, 0x35, 0x46, 0x45, 0x4c, 0x5d, 0x1c, 0x1e, 0x36, - 0x33, 0x48, 0x3e, 0x53, 0xfc, 0x95, 0x53, 0x3e, 0x48, 0x33, 0x38, 0x38, - 0x02, 0x04, 0x1d, 0x1c, 0x38, 0x32, 0x49, 0x3c, 0x55, 0x03, 0x6a, 0x54, - 0x3c, 0x46, 0x36, 0x36, 0x1e, 0x1b, 0x5d, 0x4c, 0x45, 0x46, 0x36, 0x32, - 0x21, 0x1c, 0x26, 0x26, 0x1c, 0x21, 0x32, 0x38, 0x89, 0x4c, 0x5d, 0x1b, - 0x1e, 0x36, 0x36, 0x46, 0x3c, 0x54, 0xfc, 0x96, 0x55, 0x3c, 0x49, 0x32, - 0x37, 0x1d, 0x1d, 0x5e, 0x4c, 0x45, 0x46, 0x36, 0x32, 0x21, 0x1c, 0x26, - 0x26, 0x1c, 0x21, 0x32, 0x38, 0x89, 0x4c, 0x00, 0x00, 0x08, 0x00, 0x47, - 0x00, 0x02, 0x04, 0x8a, 0x04, 0xee, 0x00, 0x0b, 0x00, 0x11, 0x00, 0x14, - 0x00, 0x17, 0x00, 0x1a, 0x00, 0x1d, 0x00, 0x20, 0x00, 0x23, 0x00, 0x00, - 0x01, 0x13, 0x21, 0x03, 0x13, 0x21, 0x0b, 0x01, 0x21, 0x13, 0x03, 0x21, - 0x17, 0x07, 0x17, 0x21, 0x37, 0x2f, 0x01, 0x07, 0x33, 0x1f, 0x01, 0x37, - 0x03, 0x07, 0x33, 0x05, 0x23, 0x17, 0x2f, 0x01, 0x07, 0x13, 0x37, 0x23, - 0x02, 0x68, 0xb6, 0x01, 0x6c, 0xb6, 0xb6, 0xfe, 0x94, 0xb6, 0xb6, 0xfe, - 0x95, 0xb6, 0xb6, 0x01, 0x6b, 0x30, 0x87, 0x87, 0x01, 0x0d, 0x87, 0x87, - 0x87, 0x57, 0xaf, 0x8d, 0x58, 0x58, 0x58, 0x58, 0xb0, 0xfe, 0xc3, 0xaf, - 0x57, 0xe4, 0x58, 0x58, 0x58, 0x58, 0xb0, 0x04, 0xee, 0xfe, 0xc4, 0xfe, - 0xc6, 0xfe, 0xc5, 0xfe, 0xc5, 0x01, 0x3b, 0x01, 0x3b, 0x01, 0x3a, 0x51, - 0xe9, 0xea, 0xea, 0xe9, 0xe9, 0x98, 0x51, 0x98, 0x98, 0xfe, 0xc6, 0x99, - 0x51, 0x98, 0xe9, 0x99, 0x99, 0x01, 0x3b, 0x98, 0x00, 0x01, 0x00, 0x1f, - 0xff, 0xec, 0x04, 0xb2, 0x04, 0x7f, 0x00, 0x43, 0x00, 0x00, 0x01, 0x35, - 0x34, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x32, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x06, 0x1d, 0x01, 0x33, 0x32, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x2b, 0x01, 0x15, 0x14, 0x17, - 0x16, 0x15, 0x14, 0x07, 0x06, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, - 0x3d, 0x01, 0x23, 0x22, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x34, 0x37, - 0x36, 0x33, 0x32, 0x17, 0x16, 0x33, 0x02, 0x43, 0x3a, 0x21, 0x29, 0x2a, - 0x5b, 0x2a, 0x29, 0x21, 0x3a, 0x18, 0x8d, 0x5c, 0x35, 0x59, 0x4c, 0x24, - 0x24, 0x24, 0x24, 0x4c, 0x59, 0x35, 0x5c, 0x8d, 0x18, 0x3a, 0x21, 0x29, - 0x2a, 0x5b, 0x2a, 0x29, 0x21, 0x3a, 0x18, 0x8d, 0x5c, 0x35, 0x59, 0x4c, - 0x24, 0x24, 0x24, 0x24, 0x4c, 0x59, 0x35, 0x5c, 0x8d, 0x02, 0x5b, 0x18, - 0x8d, 0x5c, 0x35, 0x59, 0x4c, 0x24, 0x24, 0x24, 0x24, 0x4c, 0x59, 0x35, - 0x5c, 0x8d, 0x18, 0x3a, 0x21, 0x29, 0x2a, 0x5b, 0x2a, 0x29, 0x21, 0x3a, - 0x19, 0x8d, 0x5b, 0x35, 0x59, 0x4c, 0x24, 0x25, 0x25, 0x24, 0x4c, 0x59, - 0x35, 0x5b, 0x8d, 0x19, 0x3a, 0x21, 0x29, 0x2a, 0x5b, 0x2a, 0x29, 0x21, - 0x3a, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0xff, 0xef, 0x04, 0xb5, - 0x04, 0x89, 0x00, 0x83, 0x00, 0x00, 0x01, 0x26, 0x27, 0x23, 0x06, 0x07, - 0x06, 0x07, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x27, 0x26, 0x27, 0x26, 0x34, - 0x37, 0x36, 0x37, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x17, 0x16, 0x17, 0x16, - 0x17, 0x33, 0x36, 0x37, 0x36, 0x37, 0x35, 0x26, 0x27, 0x26, 0x27, 0x2e, - 0x01, 0x35, 0x34, 0x36, 0x37, 0x36, 0x37, 0x36, 0x32, 0x17, 0x16, 0x17, - 0x1e, 0x01, 0x15, 0x14, 0x06, 0x07, 0x06, 0x07, 0x06, 0x07, 0x15, 0x16, - 0x17, 0x16, 0x17, 0x33, 0x36, 0x37, 0x36, 0x37, 0x3e, 0x01, 0x33, 0x32, - 0x16, 0x17, 0x16, 0x17, 0x16, 0x14, 0x07, 0x06, 0x07, 0x0e, 0x01, 0x23, - 0x22, 0x26, 0x27, 0x26, 0x27, 0x26, 0x27, 0x23, 0x06, 0x07, 0x06, 0x07, - 0x15, 0x16, 0x17, 0x16, 0x17, 0x1e, 0x01, 0x15, 0x14, 0x06, 0x07, 0x06, - 0x07, 0x06, 0x22, 0x27, 0x26, 0x27, 0x2e, 0x01, 0x35, 0x34, 0x36, 0x37, - 0x36, 0x37, 0x36, 0x37, 0x35, 0x26, 0x02, 0x25, 0x0c, 0x07, 0xa2, 0x01, - 0x08, 0x0f, 0x16, 0x19, 0x3e, 0x23, 0x22, 0x3f, 0x18, 0x18, 0x0e, 0x0d, - 0x0d, 0x0e, 0x18, 0x18, 0x3f, 0x22, 0x23, 0x3e, 0x19, 0x1a, 0x0b, 0x07, - 0x02, 0xa2, 0x07, 0x0c, 0x0d, 0x10, 0x0c, 0x0f, 0x20, 0x17, 0x19, 0x1a, - 0x1a, 0x19, 0x19, 0x1e, 0x1e, 0x47, 0x1e, 0x1e, 0x19, 0x19, 0x1a, 0x1a, - 0x19, 0x1b, 0x1c, 0x12, 0x09, 0x10, 0x0d, 0x0c, 0x07, 0xa2, 0x02, 0x07, - 0x0b, 0x1a, 0x19, 0x3e, 0x23, 0x22, 0x3f, 0x18, 0x18, 0x0e, 0x0d, 0x0d, - 0x0e, 0x18, 0x18, 0x3f, 0x22, 0x23, 0x3e, 0x19, 0x16, 0x0f, 0x08, 0x01, - 0xa2, 0x07, 0x0c, 0x0d, 0x10, 0x09, 0x12, 0x1c, 0x1b, 0x19, 0x1a, 0x1a, - 0x19, 0x19, 0x1e, 0x1e, 0x47, 0x1e, 0x1e, 0x19, 0x19, 0x1a, 0x1a, 0x19, - 0x17, 0x20, 0x0f, 0x0c, 0x10, 0x01, 0xf9, 0x0d, 0x10, 0x0c, 0x10, 0x20, - 0x16, 0x1a, 0x19, 0x19, 0x1a, 0x18, 0x1e, 0x1f, 0x46, 0x1e, 0x1f, 0x18, - 0x19, 0x1a, 0x1a, 0x19, 0x1a, 0x1d, 0x11, 0x0a, 0x10, 0x0d, 0x0c, 0x08, - 0xa2, 0x02, 0x07, 0x0f, 0x16, 0x19, 0x3e, 0x23, 0x23, 0x3e, 0x18, 0x18, - 0x0e, 0x0d, 0x0d, 0x0e, 0x18, 0x18, 0x3e, 0x23, 0x23, 0x3e, 0x19, 0x19, - 0x0c, 0x07, 0x02, 0xa2, 0x08, 0x0c, 0x0d, 0x10, 0x0a, 0x11, 0x1d, 0x1a, - 0x19, 0x1a, 0x1a, 0x19, 0x18, 0x1f, 0x1e, 0x46, 0x1f, 0x1e, 0x18, 0x1a, - 0x19, 0x19, 0x1a, 0x16, 0x20, 0x10, 0x0c, 0x10, 0x0d, 0x0c, 0x08, 0xa1, - 0x03, 0x07, 0x0b, 0x1a, 0x18, 0x3f, 0x23, 0x22, 0x3e, 0x19, 0x17, 0x0e, - 0x0d, 0x0d, 0x0e, 0x17, 0x19, 0x3e, 0x22, 0x23, 0x3f, 0x18, 0x16, 0x0f, - 0x08, 0x02, 0xa1, 0x08, 0x00, 0x01, 0x00, 0x1a, 0xff, 0xed, 0x04, 0xb7, - 0x04, 0x8a, 0x00, 0x9b, 0x00, 0x00, 0x01, 0x34, 0x27, 0x26, 0x27, 0x26, - 0x27, 0x26, 0x27, 0x2e, 0x01, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, - 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, - 0x06, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x32, 0x37, - 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, - 0x16, 0x17, 0x16, 0x17, 0x16, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, - 0x23, 0x14, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x22, 0x27, 0x26, 0x27, - 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, - 0x36, 0x37, 0x36, 0x35, 0x22, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x07, - 0x0e, 0x01, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, - 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x02, 0x42, 0x0f, 0x12, 0x1c, 0x0a, - 0x0c, 0x13, 0x07, 0x1f, 0x1e, 0x0f, 0x11, 0x1d, 0x18, 0x2c, 0x23, 0x2c, - 0x2b, 0x25, 0x29, 0x1b, 0x1d, 0x11, 0x0f, 0x0f, 0x11, 0x1d, 0x07, 0x14, - 0x06, 0x0f, 0x20, 0x0e, 0x0f, 0x33, 0x21, 0x2c, 0x19, 0x0a, 0x09, 0x0e, - 0x08, 0x1e, 0x26, 0x26, 0x2a, 0x2d, 0x23, 0x27, 0x1d, 0x1c, 0x12, 0x10, - 0x10, 0x12, 0x1c, 0x1d, 0x27, 0x23, 0x2d, 0x2a, 0x26, 0x26, 0x1e, 0x08, - 0x0e, 0x09, 0x0a, 0x1f, 0x26, 0x24, 0x30, 0x0f, 0x14, 0x1a, 0x09, 0x0d, - 0x13, 0x07, 0x1e, 0x10, 0x0f, 0x0f, 0x11, 0x1d, 0x1b, 0x29, 0x24, 0x57, - 0x24, 0x29, 0x1b, 0x1d, 0x11, 0x0f, 0x0f, 0x10, 0x1e, 0x07, 0x13, 0x0d, - 0x09, 0x1e, 0x10, 0x0f, 0x30, 0x24, 0x27, 0x1e, 0x0a, 0x09, 0x0e, 0x08, - 0x1d, 0x4c, 0x2b, 0x2c, 0x24, 0x26, 0x1d, 0x1a, 0x14, 0x11, 0x11, 0x12, - 0x1c, 0x1d, 0x26, 0x24, 0x2c, 0x2f, 0x22, 0x26, 0x1d, 0x08, 0x0e, 0x04, - 0x0f, 0x1f, 0x26, 0x24, 0x02, 0x62, 0x33, 0x22, 0x29, 0x1a, 0x0b, 0x09, - 0x0e, 0x07, 0x1d, 0x4d, 0x2a, 0x2c, 0x25, 0x26, 0x1d, 0x18, 0x16, 0x10, - 0x10, 0x13, 0x1b, 0x1d, 0x26, 0x25, 0x2c, 0x2e, 0x22, 0x27, 0x1d, 0x07, - 0x0e, 0x04, 0x10, 0x1e, 0x25, 0x25, 0x30, 0x0f, 0x15, 0x19, 0x0a, 0x0c, - 0x13, 0x08, 0x1d, 0x10, 0x10, 0x10, 0x10, 0x1d, 0x1c, 0x29, 0x24, 0x57, - 0x23, 0x29, 0x1c, 0x1d, 0x11, 0x0f, 0x0f, 0x10, 0x1e, 0x08, 0x13, 0x0c, - 0x0a, 0x1e, 0x10, 0x0f, 0x34, 0x21, 0x2c, 0x19, 0x0a, 0x09, 0x0e, 0x07, - 0x1e, 0x26, 0x26, 0x2b, 0x2c, 0x24, 0x27, 0x1d, 0x1b, 0x12, 0x10, 0x10, - 0x12, 0x1b, 0x1d, 0x27, 0x24, 0x2c, 0x2b, 0x26, 0x26, 0x1e, 0x07, 0x0e, - 0x09, 0x0a, 0x1f, 0x26, 0x24, 0x31, 0x0f, 0x10, 0x1e, 0x0b, 0x0c, 0x12, - 0x08, 0x1e, 0x1f, 0x0f, 0x11, 0x1d, 0x19, 0x2c, 0x23, 0x2c, 0x2b, 0x24, - 0x29, 0x1c, 0x1d, 0x10, 0x10, 0x10, 0x10, 0x1d, 0x08, 0x14, 0x06, 0x0f, - 0x1f, 0x0f, 0x0f, 0x00, 0x00, 0x01, 0x00, 0x17, 0xff, 0xe5, 0x04, 0xba, - 0x04, 0x88, 0x01, 0x30, 0x00, 0x00, 0x01, 0x32, 0x17, 0x16, 0x17, 0x16, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x36, 0x37, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x0e, 0x01, 0x07, - 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x15, 0x33, 0x26, 0x27, - 0x26, 0x27, 0x26, 0x35, 0x34, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x36, - 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x16, - 0x17, 0x16, 0x15, 0x14, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, - 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, - 0x23, 0x15, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, - 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, - 0x22, 0x27, 0x26, 0x27, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, - 0x06, 0x07, 0x06, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x36, 0x37, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, - 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, - 0x16, 0x17, 0x16, 0x17, 0x35, 0x23, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, - 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, - 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x06, 0x07, 0x06, 0x23, - 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x34, 0x37, 0x36, 0x37, 0x36, - 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x26, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x33, 0x35, 0x06, - 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x2e, 0x01, 0x27, 0x26, 0x35, - 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, - 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x02, - 0x68, 0x17, 0x12, 0x15, 0x0e, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, - 0x0f, 0x13, 0x16, 0x17, 0x12, 0x14, 0x0f, 0x0f, 0x08, 0x08, 0x08, 0x08, - 0x1f, 0x13, 0x13, 0x16, 0x17, 0x12, 0x13, 0x0f, 0x0b, 0x08, 0xe2, 0x0d, - 0x0b, 0x0f, 0x08, 0x09, 0x11, 0x0f, 0x0f, 0x14, 0x13, 0x16, 0x16, 0x13, - 0x14, 0x0f, 0x0f, 0x08, 0x09, 0x09, 0x06, 0x07, 0x0f, 0x14, 0x13, 0x15, - 0x19, 0x11, 0x13, 0x10, 0x0e, 0x09, 0x08, 0x08, 0x09, 0x0e, 0x11, 0x12, - 0x14, 0x16, 0x15, 0x13, 0x14, 0x0f, 0x07, 0x06, 0x09, 0x11, 0x0f, 0x0d, - 0x16, 0x13, 0x16, 0x13, 0x16, 0x14, 0x0f, 0x0f, 0x08, 0x09, 0x09, 0x08, - 0x0f, 0x0b, 0x0d, 0xe1, 0x07, 0x0b, 0x0d, 0x16, 0x12, 0x17, 0x16, 0x12, - 0x14, 0x0f, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x0e, 0x15, 0x11, 0x17, - 0x14, 0x15, 0x0f, 0x09, 0x0f, 0x08, 0x09, 0x09, 0x08, 0x0f, 0x0e, 0x15, - 0x12, 0x2d, 0x12, 0x15, 0x0e, 0x0f, 0x08, 0x09, 0x09, 0x08, 0x0f, 0x09, - 0x0f, 0x12, 0x17, 0x17, 0x11, 0x15, 0x0e, 0x0f, 0x08, 0x08, 0x08, 0x08, - 0x0f, 0x0f, 0x14, 0x12, 0x16, 0x15, 0x28, 0x0f, 0x0b, 0x07, 0xe1, 0x0d, - 0x0a, 0x11, 0x07, 0x08, 0x08, 0x08, 0x10, 0x10, 0x12, 0x14, 0x15, 0x17, - 0x13, 0x13, 0x0f, 0x0f, 0x09, 0x08, 0x08, 0x06, 0x08, 0x11, 0x12, 0x13, - 0x16, 0x16, 0x13, 0x14, 0x0f, 0x0e, 0x09, 0x08, 0x08, 0x09, 0x0e, 0x0d, - 0x16, 0x13, 0x16, 0x16, 0x13, 0x14, 0x0f, 0x08, 0x06, 0x08, 0x08, 0x09, - 0x0f, 0x0e, 0x14, 0x13, 0x17, 0x15, 0x14, 0x13, 0x0f, 0x10, 0x08, 0x08, - 0x08, 0x09, 0x0f, 0x0a, 0x0d, 0xe1, 0x08, 0x0b, 0x0f, 0x13, 0x12, 0x17, - 0x16, 0x12, 0x14, 0x1f, 0x07, 0x09, 0x09, 0x07, 0x10, 0x0e, 0x15, 0x11, - 0x17, 0x17, 0x12, 0x0f, 0x09, 0x10, 0x08, 0x08, 0x08, 0x08, 0x10, 0x0e, - 0x14, 0x12, 0x04, 0x87, 0x08, 0x09, 0x0e, 0x0f, 0x14, 0x13, 0x17, 0x15, - 0x13, 0x14, 0x0f, 0x07, 0x06, 0x08, 0x08, 0x09, 0x0e, 0x0f, 0x14, 0x13, - 0x16, 0x18, 0x12, 0x13, 0x1e, 0x09, 0x07, 0x07, 0x09, 0x0f, 0x0a, 0x0d, - 0xe0, 0x07, 0x0b, 0x0f, 0x13, 0x12, 0x17, 0x16, 0x27, 0x0f, 0x0f, 0x09, - 0x07, 0x07, 0x09, 0x0f, 0x0f, 0x14, 0x12, 0x17, 0x15, 0x14, 0x0f, 0x08, - 0x0f, 0x08, 0x08, 0x08, 0x08, 0x0f, 0x0e, 0x15, 0x12, 0x16, 0x17, 0x13, - 0x14, 0x0e, 0x11, 0x07, 0x07, 0x07, 0x09, 0x0f, 0x09, 0x0f, 0x13, 0x15, - 0x14, 0x2a, 0x0e, 0x0d, 0x0a, 0x09, 0x09, 0x07, 0x10, 0x0f, 0x14, 0x12, - 0x17, 0x17, 0x11, 0x13, 0x10, 0x0a, 0x08, 0xe1, 0x0e, 0x0a, 0x0c, 0x0b, - 0x08, 0x08, 0x09, 0x0e, 0x10, 0x14, 0x13, 0x15, 0x16, 0x13, 0x14, 0x10, - 0x0e, 0x09, 0x08, 0x08, 0x06, 0x07, 0x0e, 0x14, 0x13, 0x16, 0x16, 0x14, - 0x13, 0x0f, 0x0f, 0x09, 0x08, 0x08, 0x09, 0x0f, 0x0f, 0x13, 0x14, 0x16, - 0x16, 0x13, 0x14, 0x0e, 0x07, 0x06, 0x08, 0x08, 0x09, 0x0e, 0x10, 0x14, - 0x13, 0x16, 0x15, 0x13, 0x14, 0x10, 0x0e, 0x09, 0x08, 0x11, 0x0e, 0x0a, - 0x0e, 0xe0, 0x07, 0x0a, 0x12, 0x11, 0x12, 0x17, 0x16, 0x13, 0x14, 0x0e, - 0x11, 0x07, 0x08, 0x08, 0x08, 0x10, 0x0e, 0x14, 0x12, 0x17, 0x16, 0x13, - 0x0f, 0x09, 0x11, 0x07, 0x07, 0x07, 0x09, 0x0f, 0x0e, 0x14, 0x12, 0x2e, - 0x12, 0x14, 0x0f, 0x0d, 0x0a, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x0f, 0x13, - 0x16, 0x17, 0x12, 0x14, 0x0e, 0x0f, 0x09, 0x08, 0x08, 0x09, 0x0f, 0x0e, - 0x14, 0x13, 0x16, 0x17, 0x12, 0x13, 0x0f, 0x0b, 0x07, 0xe0, 0x0d, 0x0a, - 0x0f, 0x09, 0x07, 0x07, 0x09, 0x1e, 0x13, 0x14, 0x16, 0x13, 0x16, 0x14, - 0x0f, 0x0e, 0x09, 0x08, 0x08, 0x06, 0x07, 0x0f, 0x14, 0x13, 0x15, 0x17, - 0x13, 0x14, 0x0f, 0x0e, 0x09, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x2b, - 0xff, 0xe7, 0x04, 0xa6, 0x04, 0x6a, 0x00, 0x1f, 0x00, 0x00, 0x13, 0x32, - 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, 0x14, 0x17, 0x16, 0x17, 0x16, - 0x17, 0x16, 0x33, 0x22, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x34, - 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x2b, 0x73, 0x69, 0x64, 0x55, 0x53, - 0x2b, 0x2a, 0x2b, 0x27, 0x57, 0x50, 0x69, 0x68, 0x74, 0x74, 0x68, 0x69, - 0x50, 0x57, 0x27, 0x2b, 0x2a, 0x2b, 0x53, 0x55, 0x64, 0x69, 0x02, 0x29, - 0x2c, 0x29, 0x55, 0x52, 0x68, 0x65, 0x78, 0x75, 0x68, 0x62, 0x58, 0x52, - 0x2c, 0x2c, 0x2c, 0x2c, 0x52, 0x59, 0x61, 0x69, 0x74, 0x77, 0x66, 0x67, - 0x53, 0x55, 0x29, 0x2c, 0x00, 0x02, 0x00, 0x25, 0xff, 0xe6, 0x04, 0xac, - 0x04, 0x74, 0x00, 0x1f, 0x00, 0x3f, 0x00, 0x00, 0x13, 0x32, 0x17, 0x16, - 0x17, 0x16, 0x17, 0x16, 0x15, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, - 0x33, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x14, 0x07, 0x06, - 0x07, 0x06, 0x07, 0x06, 0x21, 0x32, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, - 0x35, 0x14, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x33, 0x22, 0x07, 0x06, - 0x07, 0x06, 0x07, 0x06, 0x15, 0x34, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, - 0xf0, 0x4c, 0x45, 0x41, 0x38, 0x36, 0x1d, 0x1b, 0x1c, 0x1a, 0x3a, 0x34, - 0x44, 0x44, 0x4d, 0x4d, 0x44, 0x44, 0x34, 0x3a, 0x1a, 0x1c, 0x1b, 0x1d, - 0x36, 0x38, 0x41, 0x45, 0xfe, 0xea, 0x74, 0x6a, 0x64, 0x56, 0x54, 0x2c, - 0x2a, 0x2b, 0x28, 0x58, 0x51, 0x6a, 0x68, 0x76, 0x76, 0x68, 0x6a, 0x51, - 0x58, 0x28, 0x2b, 0x2a, 0x2c, 0x54, 0x56, 0x64, 0x6a, 0x02, 0x2d, 0x1c, - 0x1c, 0x37, 0x36, 0x44, 0x43, 0x4f, 0x4d, 0x45, 0x40, 0x3a, 0x36, 0x1d, - 0x1c, 0x1d, 0x1d, 0x36, 0x3a, 0x3f, 0x46, 0x4c, 0x4f, 0x43, 0x43, 0x36, - 0x37, 0x1c, 0x1d, 0x2d, 0x2a, 0x55, 0x53, 0x68, 0x67, 0x79, 0x76, 0x6a, - 0x62, 0x59, 0x53, 0x2c, 0x2d, 0x2c, 0x2d, 0x52, 0x5a, 0x62, 0x6a, 0x76, - 0x79, 0x67, 0x68, 0x54, 0x55, 0x2a, 0x2c, 0x00, 0x00, 0x02, 0x00, 0x28, - 0xff, 0xf0, 0x04, 0xa9, 0x04, 0x38, 0x00, 0x09, 0x00, 0x13, 0x00, 0x00, - 0x13, 0x25, 0x1b, 0x01, 0x05, 0x03, 0x13, 0x25, 0x05, 0x13, 0x01, 0x03, - 0x21, 0x01, 0x03, 0x09, 0x01, 0x03, 0x01, 0x21, 0x29, 0x01, 0x74, 0xcb, - 0xcc, 0x01, 0x74, 0xf5, 0x1a, 0xfe, 0x9b, 0xfe, 0x9c, 0x1a, 0x01, 0x4a, - 0x87, 0xfe, 0x48, 0x01, 0x63, 0x88, 0x01, 0x64, 0x01, 0x65, 0x88, 0x01, - 0x63, 0xfe, 0x48, 0x02, 0x95, 0x5d, 0x01, 0x46, 0xfe, 0xba, 0x5d, 0xfe, - 0xd9, 0xfe, 0x82, 0x8f, 0x8f, 0x01, 0x7e, 0x02, 0xca, 0xfe, 0x5d, 0xfe, - 0xfd, 0xfe, 0x5e, 0x01, 0x03, 0xfe, 0xfd, 0x01, 0xa2, 0x01, 0x03, 0x00, - 0x00, 0x02, 0x00, 0x43, 0xff, 0xe6, 0x04, 0x8e, 0x04, 0x35, 0x00, 0x09, - 0x00, 0x29, 0x00, 0x00, 0x01, 0x03, 0x21, 0x05, 0x03, 0x25, 0x05, 0x03, - 0x25, 0x21, 0x03, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, - 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x02, 0x68, - 0x7a, 0xfe, 0x74, 0x01, 0x40, 0x7a, 0x01, 0x40, 0x01, 0x41, 0x7a, 0x01, - 0x40, 0xfe, 0x74, 0x7b, 0x6e, 0x65, 0x5f, 0x52, 0x50, 0x29, 0x28, 0x28, - 0x26, 0x53, 0x4e, 0x63, 0x64, 0x6f, 0x6d, 0x65, 0x5f, 0x52, 0x50, 0x29, - 0x28, 0x28, 0x26, 0x53, 0x4d, 0x64, 0x64, 0x04, 0x30, 0xfe, 0x87, 0xe9, - 0xfe, 0x88, 0xe9, 0xe9, 0x01, 0x78, 0xe9, 0x01, 0x7d, 0x2a, 0x28, 0x51, - 0x4f, 0x62, 0x62, 0x72, 0x6c, 0x65, 0x5d, 0x54, 0x50, 0x29, 0x2a, 0x2a, - 0x28, 0x51, 0x4f, 0x62, 0x62, 0x6f, 0x6f, 0x65, 0x5d, 0x54, 0x4e, 0x2b, - 0x2a, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0xff, 0xe6, 0x04, 0xa9, - 0x04, 0x2e, 0x00, 0x1d, 0x00, 0x27, 0x00, 0x00, 0x00, 0x22, 0x07, 0x06, - 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, - 0x32, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, - 0x26, 0x27, 0x03, 0x13, 0x21, 0x01, 0x13, 0x09, 0x01, 0x13, 0x01, 0x21, - 0x02, 0x98, 0x5f, 0x29, 0x28, 0x22, 0x22, 0x11, 0x11, 0x11, 0x11, 0x22, - 0x22, 0x28, 0x29, 0x5f, 0x29, 0x28, 0x22, 0x22, 0x11, 0x11, 0x11, 0x11, - 0x22, 0x22, 0x28, 0x59, 0x88, 0x01, 0xb8, 0xfe, 0x9d, 0x88, 0xfe, 0x9b, - 0xfe, 0x9c, 0x88, 0xfe, 0x9d, 0x01, 0xb8, 0x02, 0xb8, 0x11, 0x13, 0x1f, - 0x24, 0x28, 0x2a, 0x2f, 0x2e, 0x2a, 0x28, 0x23, 0x20, 0x13, 0x11, 0x11, - 0x13, 0x20, 0x23, 0x28, 0x2a, 0x2e, 0x2f, 0x2a, 0x28, 0x24, 0x1f, 0x13, - 0x01, 0x87, 0xfe, 0x5d, 0xfe, 0xfd, 0xfe, 0x5e, 0x01, 0x03, 0xfe, 0xfd, - 0x01, 0xa2, 0x01, 0x03, 0x00, 0x03, 0x00, 0x23, 0xff, 0xe9, 0x04, 0xae, - 0x04, 0x3c, 0x00, 0x09, 0x00, 0x27, 0x00, 0x31, 0x00, 0x00, 0x13, 0x25, - 0x1b, 0x01, 0x05, 0x03, 0x13, 0x25, 0x05, 0x13, 0x00, 0x32, 0x17, 0x16, - 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, - 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, - 0x36, 0x37, 0x13, 0x03, 0x21, 0x01, 0x03, 0x09, 0x01, 0x03, 0x01, 0x21, - 0x23, 0x01, 0x78, 0xcd, 0xce, 0x01, 0x78, 0xf8, 0x1a, 0xfe, 0x98, 0xfe, - 0x99, 0x1a, 0x01, 0x1d, 0x61, 0x29, 0x28, 0x23, 0x22, 0x11, 0x11, 0x11, - 0x11, 0x22, 0x23, 0x28, 0x29, 0x61, 0x29, 0x28, 0x23, 0x22, 0x11, 0x11, - 0x11, 0x11, 0x22, 0x23, 0x28, 0x59, 0x89, 0xfe, 0x44, 0x01, 0x67, 0x89, - 0x01, 0x67, 0x01, 0x68, 0x89, 0x01, 0x67, 0xfe, 0x44, 0x02, 0x95, 0x5e, - 0x01, 0x49, 0xfe, 0xb7, 0x5e, 0xfe, 0xd6, 0xfe, 0x7f, 0x90, 0x90, 0x01, - 0x81, 0x01, 0x57, 0x11, 0x13, 0x20, 0x24, 0x28, 0x2a, 0x30, 0x2e, 0x2b, - 0x28, 0x24, 0x20, 0x13, 0x11, 0x11, 0x13, 0x20, 0x24, 0x28, 0x2b, 0x2e, - 0x30, 0x2a, 0x28, 0x24, 0x20, 0x13, 0x01, 0x8b, 0xfe, 0x59, 0xfe, 0xfb, - 0xfe, 0x5a, 0x01, 0x05, 0xfe, 0xfb, 0x01, 0xa6, 0x01, 0x05, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x28, 0xff, 0xf0, 0x04, 0xa9, 0x04, 0x38, 0x00, 0x09, - 0x00, 0x13, 0x00, 0x1d, 0x00, 0x00, 0x01, 0x17, 0x33, 0x07, 0x17, 0x27, - 0x07, 0x37, 0x27, 0x33, 0x13, 0x03, 0x21, 0x05, 0x03, 0x25, 0x05, 0x03, - 0x25, 0x21, 0x03, 0x13, 0x21, 0x01, 0x13, 0x09, 0x01, 0x13, 0x01, 0x21, - 0x02, 0x68, 0x45, 0xdb, 0xb1, 0x43, 0xb2, 0xb1, 0x43, 0xb1, 0xdb, 0x44, - 0x65, 0xfe, 0xb5, 0x01, 0x0c, 0x67, 0x01, 0x0b, 0x01, 0x0c, 0x67, 0x01, - 0x0c, 0xfe, 0xb5, 0x66, 0x88, 0x01, 0xb8, 0xfe, 0x9d, 0x88, 0xfe, 0x9b, - 0xfe, 0x9c, 0x88, 0xfe, 0x9d, 0x01, 0xb8, 0x03, 0x0a, 0xd2, 0x81, 0xd1, - 0x81, 0x81, 0xd1, 0x81, 0x01, 0x69, 0xfe, 0xc6, 0xc2, 0xfe, 0xc6, 0xc3, - 0xc3, 0x01, 0x3a, 0xc2, 0x01, 0xd1, 0xfe, 0x5d, 0xfe, 0xfd, 0xfe, 0x5e, - 0x01, 0x03, 0xfe, 0xfd, 0x01, 0xa2, 0x01, 0x03, 0x00, 0x03, 0x00, 0x3d, - 0xff, 0xfc, 0x04, 0x94, 0x04, 0x1c, 0x00, 0x09, 0x00, 0x13, 0x00, 0x1d, - 0x00, 0x00, 0x01, 0x17, 0x33, 0x07, 0x17, 0x27, 0x07, 0x37, 0x27, 0x33, - 0x1b, 0x01, 0x21, 0x05, 0x13, 0x25, 0x05, 0x13, 0x25, 0x21, 0x37, 0x07, - 0x21, 0x17, 0x07, 0x37, 0x17, 0x27, 0x37, 0x21, 0x02, 0x68, 0x1b, 0x54, - 0x44, 0x1a, 0x45, 0x44, 0x1a, 0x44, 0x54, 0x1a, 0x83, 0x01, 0xa8, 0xfe, - 0xaa, 0x83, 0xfe, 0xa8, 0xfe, 0xa9, 0x83, 0xfe, 0xaa, 0x01, 0xa8, 0x82, - 0x4e, 0xff, 0x00, 0xcf, 0x50, 0xcf, 0xd0, 0x50, 0xcf, 0xff, 0x00, 0x02, - 0x49, 0x51, 0x32, 0x50, 0x31, 0x31, 0x50, 0x32, 0x02, 0x23, 0xfe, 0x6d, - 0xf9, 0xfe, 0x6d, 0xf9, 0xf9, 0x01, 0x93, 0xf9, 0xac, 0xf3, 0x96, 0xf3, - 0x96, 0x96, 0xf3, 0x96, 0x00, 0x06, 0x00, 0x28, 0xff, 0xf6, 0x04, 0xa9, - 0x04, 0x3f, 0x00, 0x02, 0x00, 0x05, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x0e, - 0x00, 0x18, 0x00, 0x00, 0x2d, 0x01, 0x35, 0x25, 0x05, 0x37, 0x01, 0x03, - 0x27, 0x25, 0x21, 0x07, 0x11, 0x03, 0x17, 0x11, 0x13, 0x21, 0x01, 0x13, - 0x09, 0x01, 0x13, 0x01, 0x21, 0x01, 0x5d, 0x01, 0x0b, 0xfe, 0x50, 0x01, - 0x0c, 0xa4, 0x01, 0x0c, 0x67, 0xa5, 0x01, 0xb1, 0xfe, 0xb5, 0x66, 0x65, - 0x65, 0x88, 0x01, 0xb8, 0xfe, 0x9d, 0x88, 0xfe, 0x9b, 0xfe, 0x9c, 0x88, - 0xfe, 0x9d, 0x01, 0xb8, 0x72, 0xc2, 0xad, 0x8c, 0xc2, 0x36, 0xfe, 0x91, - 0x01, 0x39, 0x36, 0x8c, 0x8c, 0x01, 0xc6, 0xfe, 0xc6, 0x8c, 0x02, 0x5d, - 0xfe, 0x5e, 0xfe, 0xfd, 0xfe, 0x5e, 0x01, 0x03, 0xfe, 0xfd, 0x01, 0xa2, - 0x01, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x2e, 0x00, 0x11, 0x04, 0xa3, - 0x04, 0x05, 0x00, 0x0d, 0x00, 0x17, 0x00, 0x00, 0x01, 0x05, 0x13, 0x2f, - 0x01, 0x05, 0x27, 0x13, 0x25, 0x21, 0x13, 0x17, 0x13, 0x21, 0x25, 0x03, - 0x21, 0x17, 0x03, 0x37, 0x17, 0x03, 0x37, 0x21, 0x04, 0xa2, 0xfe, 0xc4, - 0x79, 0x72, 0xeb, 0xfe, 0xe2, 0x72, 0x79, 0xfe, 0xc4, 0x01, 0x88, 0x79, - 0x71, 0x6d, 0x01, 0x22, 0xfe, 0x00, 0x5f, 0xfe, 0xd0, 0xf6, 0x5e, 0xf7, - 0xf6, 0x5e, 0xf6, 0xfe, 0xd0, 0x02, 0x6c, 0xe7, 0xfe, 0x8c, 0x25, 0xab, - 0xd0, 0x25, 0x01, 0x74, 0xe6, 0x01, 0x75, 0x25, 0xfe, 0xb0, 0xfd, 0xfe, - 0xdf, 0xb4, 0xfe, 0xdf, 0xb3, 0xb3, 0x01, 0x21, 0xb4, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x36, 0xff, 0xfe, 0x04, 0x9b, 0x04, 0x82, 0x00, 0x11, - 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, 0x25, 0x17, 0x0d, 0x01, 0x07, 0x25, - 0x11, 0x23, 0x11, 0x05, 0x27, 0x2d, 0x01, 0x37, 0x01, 0xed, 0xf7, 0x01, - 0x3a, 0x7c, 0xfe, 0xc6, 0x01, 0x3a, 0x7c, 0xfe, 0xc6, 0xf7, 0xfe, 0xc6, - 0x7c, 0x01, 0x39, 0xfe, 0xc7, 0x7c, 0x03, 0x17, 0x01, 0x6b, 0xfe, 0x94, - 0xb6, 0xd6, 0xb5, 0xb6, 0xd6, 0xb5, 0xfe, 0x95, 0x01, 0x6b, 0xb5, 0xd6, - 0xb6, 0xb5, 0xd6, 0x00, 0x00, 0x02, 0x00, 0x57, 0xff, 0xff, 0x04, 0x7a, - 0x04, 0x60, 0x00, 0x05, 0x00, 0x17, 0x00, 0x00, 0x01, 0x07, 0x17, 0x33, - 0x37, 0x27, 0x05, 0x25, 0x37, 0x05, 0x11, 0x17, 0x11, 0x25, 0x17, 0x0d, - 0x01, 0x07, 0x25, 0x11, 0x23, 0x11, 0x05, 0x27, 0x02, 0x0e, 0x5a, 0x5a, - 0xb4, 0x5a, 0x5a, 0xfe, 0xf2, 0xfe, 0xa3, 0x5a, 0x01, 0x5d, 0xb4, 0x01, - 0x5e, 0x5a, 0xfe, 0xa2, 0x01, 0x5e, 0x5a, 0xfe, 0xa2, 0xb4, 0xfe, 0xa3, - 0x5a, 0x02, 0xcb, 0x9b, 0x9d, 0x9d, 0x9b, 0x9b, 0xca, 0x9c, 0xcb, 0x01, - 0x94, 0x01, 0xfe, 0x6d, 0xcb, 0x9c, 0xca, 0xcb, 0x9c, 0xca, 0xfe, 0x6d, - 0x01, 0x93, 0xca, 0x9c, 0x00, 0x01, 0x00, 0x30, 0xff, 0xfd, 0x04, 0xa1, - 0x04, 0x6f, 0x00, 0x17, 0x00, 0x00, 0x09, 0x01, 0x07, 0x01, 0x11, 0x23, - 0x11, 0x01, 0x27, 0x01, 0x21, 0x35, 0x21, 0x01, 0x37, 0x01, 0x11, 0x33, - 0x11, 0x01, 0x17, 0x01, 0x21, 0x15, 0x02, 0xc5, 0x01, 0x50, 0x36, 0xfe, - 0xb0, 0x4d, 0xfe, 0xb0, 0x36, 0x01, 0x50, 0xfe, 0x24, 0x01, 0xdd, 0xfe, - 0xaf, 0x36, 0x01, 0x50, 0x4d, 0x01, 0x50, 0x36, 0xfe, 0xaf, 0x01, 0xdd, - 0x02, 0x10, 0xfe, 0xaf, 0x36, 0x01, 0x52, 0xfe, 0x23, 0x01, 0xdc, 0xfe, - 0xaf, 0x36, 0x01, 0x51, 0x4c, 0x01, 0x52, 0x36, 0xfe, 0xaf, 0x01, 0xdc, - 0xfe, 0x24, 0x01, 0x51, 0x36, 0xfe, 0xae, 0x4c, 0x00, 0x01, 0x00, 0x24, - 0xff, 0xf0, 0x04, 0xad, 0x04, 0x7a, 0x00, 0x0f, 0x00, 0x00, 0x01, 0x13, - 0x09, 0x01, 0x0d, 0x01, 0x09, 0x01, 0x0b, 0x01, 0x09, 0x01, 0x2d, 0x01, - 0x09, 0x01, 0x02, 0x68, 0x3c, 0x01, 0x5f, 0xfe, 0xf5, 0x01, 0xb5, 0xfe, - 0x4b, 0x01, 0x0b, 0xfe, 0xa1, 0x3c, 0x3b, 0xfe, 0xa1, 0x01, 0x0a, 0xfe, - 0x4c, 0x01, 0xb4, 0xfe, 0xf6, 0x01, 0x5f, 0x04, 0x7a, 0xfe, 0x4b, 0x01, - 0x0b, 0xfe, 0xa1, 0x3c, 0x3b, 0xfe, 0xa0, 0x01, 0x0c, 0xfe, 0x4a, 0x01, - 0xb6, 0xfe, 0xf4, 0x01, 0x60, 0x3b, 0x3c, 0x01, 0x5f, 0xfe, 0xf5, 0x00, - 0x00, 0x09, 0x00, 0x1a, 0xff, 0xe9, 0x04, 0xb7, 0x04, 0x86, 0x00, 0x02, - 0x00, 0x05, 0x00, 0x08, 0x00, 0x0b, 0x00, 0x0e, 0x00, 0x11, 0x00, 0x14, - 0x00, 0x17, 0x00, 0x27, 0x00, 0x00, 0x01, 0x0f, 0x01, 0x21, 0x27, 0x07, - 0x01, 0x2f, 0x01, 0x11, 0x37, 0x27, 0x01, 0x3f, 0x01, 0x21, 0x17, 0x37, - 0x01, 0x1f, 0x01, 0x11, 0x07, 0x17, 0x11, 0x13, 0x25, 0x03, 0x0d, 0x01, - 0x13, 0x25, 0x0b, 0x01, 0x05, 0x13, 0x2d, 0x01, 0x03, 0x05, 0x03, 0xa1, - 0xde, 0x5b, 0x01, 0xba, 0xdf, 0xdb, 0x01, 0x39, 0x5e, 0xdb, 0x5b, 0x5b, - 0xfe, 0xc8, 0xde, 0x5a, 0xfe, 0x47, 0xdf, 0xda, 0xfe, 0xc8, 0x5e, 0xda, - 0x5a, 0x5a, 0x7a, 0x01, 0x27, 0x7d, 0x01, 0x2a, 0xfe, 0xd6, 0x7d, 0xfe, - 0xd9, 0x7a, 0x79, 0xfe, 0xd9, 0x7d, 0xfe, 0xd6, 0x01, 0x2a, 0x7d, 0x01, - 0x27, 0x03, 0x71, 0x5e, 0xdc, 0x5c, 0x5c, 0xfe, 0xc8, 0xde, 0x5a, 0xfe, - 0x47, 0xdf, 0xda, 0xfe, 0xc8, 0x5e, 0xda, 0x5a, 0x5a, 0x01, 0x3a, 0xde, - 0x5c, 0x01, 0xbb, 0xdf, 0xdc, 0x02, 0x4f, 0xfe, 0xd6, 0x7d, 0xfe, 0xd8, - 0x7a, 0x79, 0xfe, 0xd9, 0x7d, 0xfe, 0xd6, 0x01, 0x2a, 0x7d, 0x01, 0x27, - 0x79, 0x7a, 0x01, 0x28, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x32, - 0xff, 0xe4, 0x04, 0x9f, 0x05, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x01, 0x13, - 0x25, 0x09, 0x01, 0x25, 0x0b, 0x01, 0x05, 0x09, 0x01, 0x05, 0x02, 0x68, - 0x5f, 0x01, 0xd8, 0xfe, 0x87, 0x01, 0x79, 0xfe, 0x28, 0x5f, 0x5e, 0xfe, - 0x28, 0x01, 0x7a, 0xfe, 0x86, 0x01, 0xd8, 0x04, 0xff, 0xfe, 0x17, 0xa3, - 0xfe, 0xb9, 0xfe, 0xba, 0xa3, 0xfe, 0x15, 0x01, 0xeb, 0xa3, 0x01, 0x46, - 0x01, 0x47, 0xa3, 0x00, 0x00, 0x01, 0x00, 0x1f, 0xff, 0xe0, 0x04, 0xb2, - 0x04, 0x73, 0x00, 0x0f, 0x00, 0x00, 0x01, 0x13, 0x25, 0x03, 0x0d, 0x01, - 0x13, 0x25, 0x0b, 0x01, 0x05, 0x13, 0x2d, 0x01, 0x03, 0x05, 0x02, 0x68, - 0x56, 0x01, 0x48, 0xcf, 0x01, 0x7a, 0xfe, 0x86, 0xcf, 0xfe, 0xb8, 0x56, - 0x55, 0xfe, 0xb8, 0xcf, 0xfe, 0x86, 0x01, 0x7a, 0xcf, 0x01, 0x48, 0x04, - 0x72, 0xfe, 0x86, 0xcf, 0xfe, 0xb8, 0x56, 0x55, 0xfe, 0xb8, 0xcf, 0xfe, - 0x85, 0x01, 0x7b, 0xcf, 0x01, 0x48, 0x55, 0x56, 0x01, 0x48, 0xcf, 0x00, - 0x00, 0x01, 0x00, 0x1a, 0xff, 0xea, 0x04, 0xb7, 0x04, 0x86, 0x00, 0x0f, - 0x00, 0x00, 0x01, 0x13, 0x25, 0x03, 0x0d, 0x01, 0x13, 0x25, 0x0b, 0x01, - 0x05, 0x13, 0x2d, 0x01, 0x03, 0x05, 0x02, 0x68, 0x82, 0x01, 0x1f, 0x68, - 0x01, 0x15, 0xfe, 0xeb, 0x68, 0xfe, 0xe1, 0x82, 0x81, 0xfe, 0xe1, 0x68, - 0xfe, 0xeb, 0x01, 0x15, 0x68, 0x01, 0x1f, 0x04, 0x86, 0xfe, 0xeb, 0x68, - 0xfe, 0xe1, 0x82, 0x82, 0xfe, 0xe1, 0x68, 0xfe, 0xeb, 0x01, 0x15, 0x68, - 0x01, 0x1f, 0x82, 0x82, 0x01, 0x1f, 0x68, 0x00, 0x00, 0x01, 0x00, 0x24, - 0xff, 0xdd, 0x04, 0xad, 0x04, 0x68, 0x00, 0x17, 0x00, 0x00, 0x01, 0x13, - 0x37, 0x03, 0x25, 0x07, 0x0d, 0x01, 0x17, 0x25, 0x13, 0x27, 0x0b, 0x01, - 0x07, 0x13, 0x05, 0x37, 0x2d, 0x01, 0x27, 0x05, 0x03, 0x17, 0x02, 0x68, - 0x58, 0xcb, 0x35, 0x01, 0x0a, 0xb4, 0x01, 0x01, 0xfe, 0xff, 0xb4, 0xfe, - 0xf6, 0x35, 0xcb, 0x58, 0x56, 0xcc, 0x36, 0xfe, 0xf5, 0xb3, 0xff, 0x00, - 0x01, 0x00, 0xb3, 0x01, 0x0b, 0x36, 0xcc, 0x04, 0x67, 0xfe, 0xff, 0xb3, - 0xfe, 0xf6, 0x35, 0xcb, 0x56, 0x57, 0xcc, 0x36, 0xfe, 0xf6, 0xb3, 0xfe, - 0xff, 0x01, 0x01, 0xb3, 0x01, 0x0a, 0x36, 0xcc, 0x57, 0x56, 0xcb, 0x35, - 0x01, 0x0a, 0xb3, 0x00, 0x00, 0x01, 0x00, 0x30, 0x00, 0x02, 0x04, 0xa1, - 0x04, 0x74, 0x00, 0x2f, 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, 0x13, 0x17, - 0x03, 0x37, 0x17, 0x07, 0x25, 0x17, 0x05, 0x21, 0x15, 0x21, 0x05, 0x07, - 0x25, 0x17, 0x07, 0x27, 0x13, 0x07, 0x03, 0x11, 0x23, 0x11, 0x03, 0x27, - 0x13, 0x07, 0x27, 0x37, 0x05, 0x27, 0x25, 0x21, 0x35, 0x21, 0x25, 0x37, - 0x05, 0x27, 0x37, 0x17, 0x03, 0x37, 0x02, 0x3b, 0x5b, 0x82, 0x54, 0x81, - 0xef, 0x41, 0xf0, 0x01, 0x3a, 0x23, 0xfe, 0xc5, 0x01, 0x54, 0xfe, 0xaf, - 0x01, 0x38, 0x23, 0xfe, 0xc6, 0xf0, 0x41, 0xee, 0x80, 0x54, 0x82, 0x5b, - 0x82, 0x54, 0x81, 0xef, 0x41, 0xf0, 0xfe, 0xc6, 0x23, 0x01, 0x39, 0xfe, - 0xae, 0x01, 0x54, 0xfe, 0xc5, 0x23, 0x01, 0x38, 0xee, 0x41, 0xee, 0x80, - 0x54, 0x03, 0x20, 0x01, 0x54, 0xfe, 0xae, 0x01, 0x38, 0x23, 0xfe, 0xc7, - 0xf0, 0x41, 0xf0, 0x82, 0x54, 0x83, 0x5b, 0x81, 0x55, 0x83, 0xf1, 0x40, - 0xee, 0xfe, 0xc8, 0x23, 0x01, 0x37, 0xfe, 0xaf, 0x01, 0x53, 0xfe, 0xc7, - 0x23, 0x01, 0x39, 0xef, 0x40, 0xef, 0x81, 0x55, 0x81, 0x5b, 0x83, 0x54, - 0x81, 0xef, 0x41, 0xef, 0x01, 0x38, 0x23, 0x00, 0x00, 0x01, 0x00, 0x31, - 0xff, 0xf0, 0x04, 0xa0, 0x04, 0xe8, 0x00, 0x9f, 0x00, 0x00, 0x01, 0x35, - 0x34, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x32, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x06, 0x1d, 0x01, 0x17, 0x16, 0x17, 0x37, 0x36, 0x37, 0x36, 0x37, - 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, - 0x06, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, 0x0f, 0x01, 0x16, 0x15, 0x14, - 0x07, 0x17, 0x16, 0x33, 0x32, 0x37, 0x32, 0x33, 0x32, 0x17, 0x16, 0x17, - 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, - 0x26, 0x2f, 0x01, 0x06, 0x0f, 0x01, 0x15, 0x14, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x06, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x3d, 0x01, 0x26, - 0x27, 0x26, 0x27, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, - 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x33, - 0x16, 0x33, 0x32, 0x3f, 0x01, 0x26, 0x35, 0x34, 0x37, 0x27, 0x26, 0x23, - 0x22, 0x23, 0x22, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, - 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x1f, 0x01, 0x36, - 0x37, 0x36, 0x02, 0x3f, 0x3e, 0x24, 0x2c, 0x2e, 0x63, 0x2e, 0x2c, 0x24, - 0x3e, 0x0d, 0x19, 0x14, 0x08, 0x5d, 0x35, 0x20, 0x37, 0x31, 0x2b, 0x12, - 0x11, 0x3a, 0x19, 0x10, 0x04, 0x0b, 0x48, 0x33, 0x3e, 0x05, 0x05, 0x08, - 0x09, 0x6b, 0x52, 0x0a, 0x03, 0x04, 0x0a, 0x53, 0x6b, 0x09, 0x08, 0x05, - 0x05, 0x3e, 0x33, 0x48, 0x0b, 0x04, 0x10, 0x19, 0x3a, 0x11, 0x12, 0x2b, - 0x31, 0x37, 0x20, 0x37, 0x5a, 0x0c, 0x16, 0x14, 0x0d, 0x3e, 0x24, 0x2c, - 0x2e, 0x63, 0x2e, 0x2c, 0x24, 0x3f, 0x07, 0x07, 0x17, 0x13, 0x0c, 0x5a, - 0x37, 0x20, 0x37, 0x31, 0x2b, 0x12, 0x11, 0x3a, 0x19, 0x10, 0x04, 0x0b, - 0x48, 0x33, 0x3e, 0x05, 0x05, 0x08, 0x09, 0x6c, 0x52, 0x0a, 0x04, 0x03, - 0x0a, 0x52, 0x6b, 0x09, 0x08, 0x05, 0x05, 0x3e, 0x33, 0x48, 0x0b, 0x04, - 0x10, 0x19, 0x3a, 0x11, 0x12, 0x2b, 0x31, 0x37, 0x20, 0x39, 0x58, 0x09, - 0x16, 0x17, 0x07, 0x02, 0xf8, 0x0a, 0x69, 0x62, 0x39, 0x40, 0x52, 0x27, - 0x29, 0x29, 0x27, 0x52, 0x40, 0x39, 0x64, 0x67, 0x0a, 0x05, 0x0b, 0x13, - 0x05, 0x38, 0x64, 0x3c, 0x20, 0x1c, 0x05, 0x14, 0x2b, 0x1c, 0x24, 0x12, - 0x14, 0x3b, 0x29, 0x1d, 0x30, 0x05, 0x10, 0x10, 0x12, 0x10, 0x06, 0x31, - 0x01, 0x1e, 0x29, 0x3a, 0x14, 0x12, 0x24, 0x1d, 0x2a, 0x14, 0x05, 0x1c, - 0x20, 0x3c, 0x67, 0x34, 0x07, 0x15, 0x07, 0x05, 0x0d, 0x68, 0x63, 0x39, - 0x40, 0x52, 0x28, 0x28, 0x28, 0x28, 0x52, 0x40, 0x39, 0x63, 0x68, 0x0d, - 0x02, 0x03, 0x0a, 0x12, 0x07, 0x34, 0x67, 0x3c, 0x20, 0x1c, 0x05, 0x14, - 0x2a, 0x1d, 0x24, 0x12, 0x14, 0x3a, 0x29, 0x1e, 0x01, 0x30, 0x06, 0x10, - 0x13, 0x10, 0x10, 0x05, 0x30, 0x1d, 0x29, 0x3b, 0x14, 0x12, 0x24, 0x1c, - 0x2b, 0x14, 0x05, 0x1c, 0x20, 0x3c, 0x6b, 0x30, 0x05, 0x14, 0x09, 0x03, - 0x00, 0x02, 0x00, 0x37, 0xff, 0xee, 0x04, 0x9a, 0x04, 0xd9, 0x00, 0x1d, - 0x00, 0xb9, 0x00, 0x00, 0x00, 0x22, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, - 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x32, 0x37, 0x36, 0x37, - 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x2f, 0x01, 0x35, - 0x34, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x32, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x06, 0x1d, 0x01, 0x17, 0x16, 0x17, 0x37, 0x36, 0x37, 0x36, 0x37, - 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, - 0x06, 0x2b, 0x01, 0x22, 0x23, 0x22, 0x0f, 0x01, 0x16, 0x15, 0x14, 0x07, - 0x17, 0x16, 0x33, 0x32, 0x3b, 0x01, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, - 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x2f, - 0x01, 0x06, 0x0f, 0x01, 0x15, 0x14, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, - 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x3d, 0x01, 0x26, 0x27, 0x26, - 0x27, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, - 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x3b, 0x01, 0x32, 0x33, 0x32, - 0x3f, 0x01, 0x26, 0x35, 0x34, 0x37, 0x27, 0x26, 0x23, 0x22, 0x2b, 0x01, - 0x22, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, - 0x32, 0x17, 0x16, 0x17, 0x16, 0x1f, 0x01, 0x36, 0x37, 0x36, 0x02, 0x7a, - 0x23, 0x0d, 0x0f, 0x0b, 0x0d, 0x05, 0x07, 0x07, 0x05, 0x0d, 0x0b, 0x0f, - 0x0d, 0x23, 0x0d, 0x0f, 0x0b, 0x0d, 0x05, 0x07, 0x07, 0x05, 0x0d, 0x0b, - 0x0f, 0x48, 0x3d, 0x24, 0x2c, 0x2e, 0x61, 0x2e, 0x2c, 0x24, 0x3e, 0x0d, - 0x19, 0x14, 0x08, 0x5c, 0x35, 0x1f, 0x37, 0x30, 0x2b, 0x12, 0x11, 0x39, - 0x19, 0x10, 0x04, 0x0c, 0x46, 0x33, 0x3d, 0x0a, 0x09, 0x08, 0x6b, 0x51, - 0x0a, 0x04, 0x04, 0x09, 0x53, 0x6a, 0x09, 0x08, 0x0a, 0x3d, 0x33, 0x46, - 0x0c, 0x04, 0x10, 0x19, 0x39, 0x11, 0x12, 0x2b, 0x30, 0x37, 0x1f, 0x37, - 0x59, 0x0c, 0x16, 0x14, 0x0d, 0x3e, 0x24, 0x2c, 0x2e, 0x61, 0x2e, 0x2c, - 0x24, 0x3f, 0x08, 0x06, 0x18, 0x12, 0x0c, 0x59, 0x37, 0x1f, 0x37, 0x30, - 0x2b, 0x12, 0x11, 0x39, 0x19, 0x10, 0x04, 0x0b, 0x47, 0x33, 0x3d, 0x0a, - 0x09, 0x08, 0x6b, 0x52, 0x09, 0x04, 0x04, 0x0a, 0x51, 0x6b, 0x08, 0x09, - 0x0a, 0x3d, 0x33, 0x47, 0x0b, 0x04, 0x10, 0x19, 0x39, 0x11, 0x12, 0x2b, - 0x30, 0x37, 0x1f, 0x39, 0x57, 0x09, 0x15, 0x18, 0x06, 0x02, 0xb7, 0x07, - 0x06, 0x0c, 0x0c, 0x0e, 0x0e, 0x11, 0x11, 0x0e, 0x0e, 0x0c, 0x0c, 0x06, - 0x07, 0x07, 0x06, 0x0c, 0x0c, 0x0e, 0x0e, 0x11, 0x11, 0x0e, 0x0e, 0x0c, - 0x0c, 0x06, 0x3e, 0x0a, 0x68, 0x60, 0x39, 0x40, 0x51, 0x27, 0x28, 0x28, - 0x27, 0x51, 0x40, 0x39, 0x62, 0x66, 0x0a, 0x05, 0x0b, 0x13, 0x05, 0x37, - 0x63, 0x3c, 0x1f, 0x1d, 0x06, 0x13, 0x2b, 0x1c, 0x24, 0x12, 0x13, 0x3a, - 0x29, 0x1d, 0x2f, 0x06, 0x0f, 0x10, 0x11, 0x11, 0x05, 0x30, 0x1e, 0x28, - 0x3a, 0x13, 0x12, 0x24, 0x1c, 0x2b, 0x13, 0x06, 0x1d, 0x1f, 0x3c, 0x66, - 0x33, 0x07, 0x15, 0x07, 0x05, 0x0c, 0x67, 0x63, 0x38, 0x40, 0x51, 0x27, - 0x28, 0x28, 0x27, 0x51, 0x40, 0x38, 0x63, 0x67, 0x0c, 0x03, 0x02, 0x0b, - 0x11, 0x07, 0x33, 0x66, 0x3c, 0x1f, 0x1d, 0x06, 0x13, 0x2b, 0x1c, 0x24, - 0x12, 0x13, 0x3a, 0x28, 0x1e, 0x2f, 0x06, 0x10, 0x12, 0x10, 0x0f, 0x06, - 0x2f, 0x1d, 0x29, 0x3a, 0x13, 0x12, 0x24, 0x1c, 0x2b, 0x13, 0x06, 0x1d, - 0x1f, 0x3c, 0x69, 0x30, 0x05, 0x14, 0x09, 0x03, 0x00, 0x01, 0x00, 0x34, - 0xff, 0xeb, 0x04, 0x96, 0x04, 0xdf, 0x00, 0x6a, 0x00, 0x00, 0x01, 0x27, - 0x26, 0x07, 0x06, 0x27, 0x26, 0x27, 0x26, 0x37, 0x36, 0x37, 0x36, 0x17, - 0x16, 0x17, 0x16, 0x1f, 0x01, 0x35, 0x34, 0x27, 0x26, 0x35, 0x34, 0x37, - 0x36, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x1d, 0x01, 0x37, 0x36, - 0x37, 0x36, 0x37, 0x36, 0x17, 0x16, 0x17, 0x16, 0x07, 0x06, 0x07, 0x06, - 0x27, 0x26, 0x0f, 0x01, 0x17, 0x16, 0x37, 0x36, 0x17, 0x16, 0x17, 0x16, - 0x07, 0x06, 0x07, 0x06, 0x27, 0x26, 0x27, 0x26, 0x2f, 0x01, 0x15, 0x14, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x36, 0x3d, 0x01, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x27, 0x26, - 0x27, 0x26, 0x37, 0x36, 0x37, 0x36, 0x17, 0x16, 0x37, 0x02, 0x12, 0x26, - 0x28, 0x97, 0x5a, 0x44, 0x4c, 0x0e, 0x17, 0x22, 0x23, 0x5a, 0x3a, 0x4c, - 0x47, 0x23, 0x3a, 0x2e, 0x27, 0x57, 0x34, 0x2c, 0x43, 0x8a, 0x43, 0x2c, - 0x34, 0x57, 0x27, 0x27, 0x41, 0x28, 0x43, 0x4b, 0x3b, 0x5a, 0x22, 0x22, - 0x17, 0x0e, 0x4c, 0x47, 0x57, 0x90, 0x2f, 0x27, 0x27, 0x27, 0x98, 0x5b, - 0x43, 0x4c, 0x0e, 0x17, 0x22, 0x24, 0x58, 0x3e, 0x48, 0x48, 0x23, 0x3a, - 0x2e, 0x27, 0x57, 0x34, 0x2c, 0x43, 0x45, 0x48, 0x40, 0x2c, 0x34, 0x57, - 0x27, 0x2a, 0x3e, 0x26, 0x44, 0x4c, 0x3a, 0x5a, 0x23, 0x23, 0x18, 0x0f, - 0x4b, 0x47, 0x57, 0x93, 0x2c, 0x02, 0x66, 0x16, 0x17, 0x0d, 0x08, 0x27, - 0x2c, 0x3b, 0x5b, 0x3b, 0x3b, 0x1a, 0x11, 0x2b, 0x2a, 0x51, 0x84, 0x1b, - 0x17, 0x2d, 0x2d, 0x7d, 0x4b, 0x4f, 0x57, 0x2a, 0x41, 0x41, 0x2a, 0x57, - 0x53, 0x47, 0x75, 0x35, 0x2d, 0x17, 0x17, 0x88, 0x55, 0x26, 0x2b, 0x11, - 0x1a, 0x3b, 0x3b, 0x5b, 0x3b, 0x2c, 0x29, 0x0a, 0x10, 0x1a, 0x16, 0x17, - 0x17, 0x0d, 0x07, 0x27, 0x2b, 0x3b, 0x5b, 0x3c, 0x3e, 0x17, 0x10, 0x2a, - 0x2a, 0x51, 0x85, 0x1b, 0x16, 0x2d, 0x2d, 0x7d, 0x4b, 0x4e, 0x57, 0x2b, - 0x40, 0x40, 0x2d, 0x55, 0x53, 0x46, 0x75, 0x35, 0x2d, 0x16, 0x19, 0x87, - 0x53, 0x28, 0x2b, 0x11, 0x1a, 0x3b, 0x3e, 0x59, 0x3b, 0x2b, 0x2a, 0x0a, - 0x10, 0x1a, 0x00, 0x00, 0x00, 0x04, 0x00, 0x21, 0xff, 0xe5, 0x04, 0xb0, - 0x04, 0xbd, 0x00, 0x0e, 0x00, 0x99, 0x00, 0xb1, 0x00, 0xc9, 0x00, 0x00, - 0x01, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x22, 0x07, 0x06, 0x15, - 0x14, 0x17, 0x16, 0x13, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, - 0x27, 0x26, 0x27, 0x26, 0x2f, 0x01, 0x15, 0x14, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x3d, 0x01, - 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, - 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x33, 0x32, - 0x3f, 0x01, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, - 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x17, 0x16, 0x1f, 0x01, 0x35, 0x34, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, - 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x1d, 0x01, 0x37, 0x36, 0x37, - 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, - 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x23, 0x22, 0x07, 0x05, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, - 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x36, 0x25, 0x16, - 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, - 0x27, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x23, 0x22, 0x02, 0x69, - 0x17, 0x2f, 0x1f, 0x19, 0x29, 0x46, 0x29, 0x1a, 0x1f, 0x2f, 0x8d, 0x0f, - 0x2c, 0x55, 0x1b, 0x1f, 0x0f, 0x0e, 0x4b, 0x3a, 0x4d, 0x0f, 0x0a, 0x15, - 0x24, 0x5c, 0x10, 0x12, 0x2f, 0x38, 0x45, 0x28, 0x35, 0x3e, 0x0f, 0x48, - 0x36, 0x2d, 0x45, 0x46, 0x4a, 0x41, 0x2d, 0x35, 0x48, 0x0f, 0x3b, 0x38, - 0x29, 0x44, 0x37, 0x2e, 0x13, 0x11, 0x5c, 0x23, 0x15, 0x09, 0x10, 0x4c, - 0x3b, 0x4b, 0x0e, 0x0f, 0x1e, 0x1b, 0x55, 0x2c, 0x10, 0x10, 0x2a, 0x55, - 0x1c, 0x1f, 0x0f, 0x0e, 0x4b, 0x3b, 0x4b, 0x11, 0x0a, 0x16, 0x23, 0x5c, - 0x11, 0x13, 0x2e, 0x37, 0x46, 0x27, 0x35, 0x3e, 0x0f, 0x48, 0x35, 0x2d, - 0x44, 0x8d, 0x45, 0x2d, 0x36, 0x48, 0x0f, 0x3c, 0x37, 0x2a, 0x43, 0x38, - 0x2f, 0x12, 0x10, 0x5c, 0x24, 0x15, 0x0a, 0x0f, 0x4d, 0x3a, 0x4b, 0x0e, - 0x0f, 0x20, 0x1b, 0x55, 0x2b, 0xfe, 0xd3, 0x3a, 0x36, 0x19, 0x18, 0x08, - 0x08, 0x2d, 0x32, 0x31, 0x06, 0x04, 0x0b, 0x11, 0x34, 0x09, 0x0a, 0x1a, - 0x24, 0x3a, 0x15, 0x1e, 0x01, 0x8f, 0x3c, 0x1e, 0x15, 0x3b, 0x24, 0x1a, - 0x0a, 0x08, 0x34, 0x12, 0x0b, 0x04, 0x06, 0x32, 0x32, 0x2d, 0x08, 0x07, - 0x19, 0x19, 0x36, 0x03, 0x0c, 0x4f, 0x3b, 0x28, 0x41, 0x37, 0x14, 0x23, - 0x23, 0x14, 0x37, 0x41, 0x28, 0x3b, 0xfe, 0xf7, 0x09, 0x1a, 0x03, 0x01, - 0x21, 0x2a, 0x3a, 0x23, 0x1f, 0x2e, 0x23, 0x3b, 0x18, 0x04, 0x1e, 0x26, - 0x52, 0x6d, 0x21, 0x08, 0x10, 0x43, 0x63, 0x4a, 0x4d, 0x55, 0x29, 0x3f, - 0x3f, 0x2c, 0x52, 0x4d, 0x4a, 0x63, 0x43, 0x10, 0x08, 0x1f, 0x6f, 0x53, - 0x25, 0x1f, 0x05, 0x1a, 0x39, 0x23, 0x2e, 0x1f, 0x23, 0x3b, 0x29, 0x21, - 0x01, 0x03, 0x1a, 0x09, 0x08, 0x19, 0x02, 0x01, 0x20, 0x29, 0x3b, 0x23, - 0x1f, 0x2d, 0x24, 0x3a, 0x19, 0x05, 0x1e, 0x27, 0x51, 0x6e, 0x21, 0x08, - 0x10, 0x44, 0x63, 0x49, 0x4d, 0x55, 0x2a, 0x3f, 0x3f, 0x2a, 0x55, 0x4d, - 0x49, 0x63, 0x44, 0x10, 0x08, 0x20, 0x6f, 0x53, 0x25, 0x1e, 0x05, 0x18, - 0x3b, 0x23, 0x2e, 0x1e, 0x24, 0x3a, 0x2a, 0x20, 0x01, 0x02, 0x19, 0x66, - 0x0e, 0x03, 0x01, 0x1c, 0x1b, 0x1f, 0x14, 0x10, 0x1b, 0x12, 0x1d, 0x10, - 0x03, 0x13, 0x20, 0x2f, 0x44, 0x3b, 0x3b, 0x44, 0x2f, 0x20, 0x13, 0x03, - 0x10, 0x1d, 0x12, 0x1b, 0x10, 0x14, 0x1f, 0x1b, 0x1c, 0x01, 0x03, 0x00, - 0x00, 0x02, 0x00, 0x24, 0x00, 0x00, 0x04, 0xad, 0x04, 0x69, 0x00, 0x1d, - 0x00, 0x8d, 0x00, 0x00, 0x00, 0x22, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, - 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x32, 0x37, 0x36, 0x37, - 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x27, 0x37, 0x36, - 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x16, 0x17, 0x16, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, - 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x27, 0x06, 0x07, 0x06, 0x07, 0x06, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x36, 0x37, 0x36, 0x37, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, - 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x17, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, - 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x06, 0x02, 0xa0, 0x6f, 0x30, 0x30, 0x27, 0x29, 0x13, 0x14, 0x14, - 0x13, 0x29, 0x27, 0x30, 0x30, 0x6f, 0x30, 0x30, 0x27, 0x29, 0x13, 0x14, - 0x14, 0x13, 0x29, 0x27, 0x30, 0x5d, 0x30, 0x1d, 0x2b, 0x29, 0x2a, 0x2b, - 0x25, 0x23, 0x20, 0x12, 0x10, 0x10, 0x0f, 0x23, 0x1d, 0x2b, 0x25, 0x30, - 0x16, 0x15, 0x25, 0x1a, 0x23, 0x0e, 0x11, 0x11, 0x12, 0x1f, 0x23, 0x26, - 0x26, 0x2e, 0x30, 0x25, 0x2b, 0x1d, 0x25, 0x0d, 0x0a, 0x04, 0x03, 0x0b, - 0x12, 0x20, 0x23, 0x25, 0x27, 0x2e, 0x30, 0x24, 0x2c, 0x1c, 0x23, 0x0f, - 0x10, 0x10, 0x13, 0x1f, 0x1d, 0x1c, 0x12, 0x13, 0x30, 0x25, 0x2d, 0x1b, - 0x23, 0x0f, 0x10, 0x10, 0x12, 0x20, 0x23, 0x25, 0x27, 0x2e, 0x30, 0x24, - 0x2e, 0x20, 0x06, 0x05, 0x10, 0x10, 0x12, 0x20, 0x23, 0x25, 0x27, 0x2d, - 0x31, 0x24, 0x2c, 0x1c, 0x23, 0x0f, 0x10, 0x10, 0x05, 0x03, 0x24, 0x14, - 0x16, 0x25, 0x2a, 0x2f, 0x30, 0x39, 0x36, 0x31, 0x2f, 0x2a, 0x25, 0x16, - 0x14, 0x14, 0x16, 0x25, 0x2a, 0x2f, 0x31, 0x36, 0x39, 0x30, 0x2f, 0x2a, - 0x25, 0x16, 0x0f, 0x29, 0x0c, 0x12, 0x12, 0x0f, 0x22, 0x1e, 0x2a, 0x26, - 0x30, 0x2d, 0x28, 0x25, 0x24, 0x1d, 0x13, 0x11, 0x04, 0x12, 0x1a, 0x24, - 0x24, 0x29, 0x2d, 0x30, 0x26, 0x2a, 0x1e, 0x21, 0x10, 0x10, 0x10, 0x14, - 0x1d, 0x26, 0x22, 0x1b, 0x1c, 0x1d, 0x1a, 0x2a, 0x1e, 0x21, 0x10, 0x10, - 0x10, 0x14, 0x1d, 0x24, 0x24, 0x29, 0x2d, 0x30, 0x26, 0x2d, 0x1b, 0x1a, - 0x11, 0x04, 0x11, 0x15, 0x1c, 0x23, 0x25, 0x28, 0x2d, 0x30, 0x26, 0x2a, - 0x1e, 0x22, 0x0f, 0x11, 0x11, 0x13, 0x22, 0x0b, 0x0b, 0x28, 0x2d, 0x30, - 0x26, 0x2a, 0x1e, 0x22, 0x0f, 0x10, 0x10, 0x13, 0x1e, 0x24, 0x24, 0x28, - 0x2e, 0x2f, 0x26, 0x0b, 0x00, 0x06, 0x00, 0x16, 0x00, 0x03, 0x04, 0xbb, - 0x04, 0x86, 0x00, 0x6e, 0x00, 0x8a, 0x00, 0xa3, 0x00, 0xbf, 0x00, 0xd8, - 0x00, 0xf4, 0x00, 0x00, 0x25, 0x06, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, - 0x37, 0x36, 0x37, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, - 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x17, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, - 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, - 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, - 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x16, 0x17, - 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, - 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x02, 0x32, 0x17, 0x16, 0x17, - 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x22, 0x07, - 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x1f, 0x01, 0x36, 0x37, 0x13, - 0x26, 0x27, 0x26, 0x27, 0x26, 0x27, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, - 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x32, 0x37, 0x36, 0x37, 0x36, 0x37, - 0x03, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x27, 0x26, 0x27, 0x26, 0x23, - 0x22, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, - 0x16, 0x17, 0x16, 0x17, 0x05, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x32, - 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x2f, 0x01, - 0x06, 0x07, 0x06, 0x07, 0x06, 0x3f, 0x01, 0x36, 0x37, 0x36, 0x37, 0x36, - 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x23, 0x22, - 0x07, 0x06, 0x0f, 0x01, 0x16, 0x17, 0x16, 0x15, 0x14, 0x02, 0x68, 0x03, - 0x0b, 0x0d, 0x26, 0x1d, 0x2c, 0x26, 0x31, 0x2f, 0x28, 0x26, 0x23, 0x21, - 0x12, 0x11, 0x11, 0x0f, 0x24, 0x1a, 0x26, 0x16, 0x17, 0x31, 0x25, 0x2d, - 0x1d, 0x24, 0x0f, 0x11, 0x11, 0x12, 0x21, 0x26, 0x24, 0x2f, 0x27, 0x2e, - 0x29, 0x1d, 0x32, 0x06, 0x05, 0x10, 0x10, 0x0f, 0x24, 0x1d, 0x2d, 0x25, - 0x63, 0x25, 0x2d, 0x1d, 0x24, 0x0f, 0x10, 0x10, 0x05, 0x06, 0x32, 0x1d, - 0x2d, 0x2a, 0x2b, 0x2b, 0x26, 0x24, 0x21, 0x12, 0x11, 0x11, 0x0f, 0x24, - 0x1d, 0x2d, 0x25, 0x31, 0x17, 0x16, 0x26, 0x1a, 0x24, 0x0f, 0x11, 0x11, - 0x12, 0x21, 0x23, 0x26, 0x28, 0x2f, 0x31, 0x26, 0x2c, 0x1d, 0x26, 0x0d, - 0x0b, 0x3d, 0x73, 0x30, 0x06, 0x06, 0x0e, 0x07, 0x0a, 0x09, 0x16, 0x14, - 0x19, 0x18, 0x39, 0x18, 0x19, 0x14, 0x16, 0x09, 0x0a, 0x07, 0x0e, 0x06, - 0x06, 0x35, 0x1c, 0x19, 0x35, 0x25, 0x18, 0x15, 0x52, 0x13, 0x0c, 0x0a, - 0x0a, 0x0a, 0x15, 0x14, 0x19, 0x18, 0x39, 0x18, 0x1a, 0x13, 0x13, 0x0c, - 0xb2, 0x03, 0x15, 0x11, 0x21, 0x5f, 0x07, 0x05, 0x1c, 0x19, 0x1c, 0x18, - 0x19, 0x14, 0x13, 0x0c, 0x0b, 0x0b, 0x09, 0x16, 0x14, 0x19, 0x11, 0x0c, - 0x01, 0xba, 0x2c, 0x0c, 0x13, 0x13, 0x1a, 0x18, 0x39, 0x18, 0x19, 0x14, - 0x15, 0x0a, 0x0a, 0x0a, 0x0c, 0x13, 0x52, 0x15, 0x18, 0x25, 0x35, 0x19, - 0xc2, 0x73, 0x0c, 0x11, 0x19, 0x14, 0x16, 0x09, 0x0b, 0x0b, 0x0c, 0x13, - 0x14, 0x19, 0x18, 0x1c, 0x19, 0x1c, 0x05, 0x07, 0x5f, 0x21, 0x11, 0x15, - 0xc8, 0x1d, 0x1b, 0x23, 0x27, 0x1e, 0x14, 0x11, 0x11, 0x10, 0x22, 0x1f, - 0x2b, 0x27, 0x30, 0x2f, 0x29, 0x26, 0x24, 0x1b, 0x13, 0x04, 0x10, 0x14, - 0x1e, 0x25, 0x25, 0x29, 0x2e, 0x32, 0x27, 0x2b, 0x1f, 0x24, 0x0e, 0x12, - 0x12, 0x0d, 0x2a, 0x0a, 0x0b, 0x27, 0x31, 0x2e, 0x2a, 0x25, 0x25, 0x1e, - 0x14, 0x10, 0x10, 0x14, 0x1e, 0x25, 0x25, 0x2a, 0x2e, 0x31, 0x27, 0x0b, - 0x0a, 0x2a, 0x0d, 0x12, 0x12, 0x10, 0x22, 0x1f, 0x2b, 0x27, 0x32, 0x2e, - 0x29, 0x25, 0x25, 0x1e, 0x14, 0x10, 0x04, 0x13, 0x1b, 0x24, 0x26, 0x29, - 0x2f, 0x30, 0x27, 0x2b, 0x1f, 0x22, 0x10, 0x11, 0x11, 0x14, 0x1e, 0x27, - 0x23, 0x1b, 0x02, 0x8e, 0x14, 0x03, 0x03, 0x4c, 0x25, 0x10, 0x1c, 0x1a, - 0x18, 0x15, 0x13, 0x0b, 0x0b, 0x0b, 0x0b, 0x13, 0x15, 0x18, 0x1a, 0x1c, - 0x10, 0x25, 0x4c, 0x03, 0x03, 0xfd, 0xec, 0x05, 0x0b, 0x18, 0x25, 0x17, - 0x23, 0x4d, 0x13, 0x1b, 0x19, 0x1d, 0x1c, 0x19, 0x18, 0x15, 0x13, 0x0b, - 0x0b, 0x0b, 0x0b, 0x13, 0x13, 0x1a, 0x01, 0x4c, 0x11, 0x13, 0x3a, 0x32, - 0x28, 0x26, 0x36, 0x03, 0x02, 0x0a, 0x0a, 0x0b, 0x13, 0x13, 0x1a, 0x17, - 0x1f, 0x1c, 0x1a, 0x17, 0x16, 0x13, 0x0b, 0x07, 0x02, 0xfb, 0x5f, 0x1a, - 0x13, 0x13, 0x0b, 0x0b, 0x0b, 0x0b, 0x13, 0x15, 0x18, 0x19, 0x1c, 0x1d, - 0x19, 0x1b, 0x13, 0x4d, 0x23, 0x17, 0x25, 0x18, 0x0b, 0xe8, 0x0e, 0x02, - 0x07, 0x0b, 0x13, 0x16, 0x17, 0x1a, 0x1c, 0x1f, 0x17, 0x1a, 0x13, 0x13, - 0x0b, 0x0a, 0x0a, 0x02, 0x03, 0x36, 0x26, 0x28, 0x32, 0x3a, 0x13, 0x00, - 0x00, 0x0a, 0x00, 0x16, 0xff, 0xed, 0x04, 0xbb, 0x04, 0x94, 0x00, 0x2d, - 0x00, 0x5b, 0x00, 0xd5, 0x01, 0x04, 0x01, 0x33, 0x01, 0x62, 0x01, 0x91, - 0x01, 0xaf, 0x01, 0xdd, 0x02, 0x0b, 0x00, 0x00, 0x01, 0x26, 0x27, 0x07, - 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, - 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x1f, 0x01, 0x36, 0x37, 0x27, - 0x26, 0x23, 0x22, 0x06, 0x07, 0x06, 0x07, 0x06, 0x14, 0x17, 0x16, 0x17, - 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x25, 0x06, 0x07, 0x17, 0x16, 0x33, - 0x32, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x34, 0x27, 0x26, 0x27, 0x2e, - 0x01, 0x23, 0x22, 0x0f, 0x01, 0x16, 0x17, 0x37, 0x36, 0x33, 0x32, 0x17, - 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, - 0x06, 0x23, 0x22, 0x27, 0x25, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, - 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x34, 0x36, 0x37, - 0x36, 0x37, 0x36, 0x32, 0x17, 0x16, 0x17, 0x1e, 0x01, 0x15, 0x36, 0x37, - 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, - 0x06, 0x07, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, - 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, - 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x14, 0x06, - 0x07, 0x06, 0x07, 0x06, 0x22, 0x27, 0x26, 0x27, 0x2e, 0x01, 0x35, 0x06, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x36, 0x37, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x01, 0x26, 0x27, 0x07, 0x06, 0x07, - 0x06, 0x07, 0x06, 0x07, 0x26, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x27, - 0x36, 0x37, 0x36, 0x37, 0x36, 0x3f, 0x01, 0x26, 0x27, 0x07, 0x06, 0x07, - 0x06, 0x07, 0x06, 0x15, 0x16, 0x17, 0x16, 0x17, 0x1e, 0x01, 0x33, 0x32, - 0x37, 0x36, 0x37, 0x36, 0x37, 0x01, 0x16, 0x17, 0x37, 0x36, 0x37, 0x36, - 0x37, 0x36, 0x35, 0x26, 0x27, 0x26, 0x27, 0x2e, 0x01, 0x23, 0x22, 0x07, - 0x06, 0x07, 0x06, 0x0f, 0x01, 0x16, 0x17, 0x37, 0x36, 0x37, 0x36, 0x37, - 0x36, 0x37, 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x06, 0x07, - 0x06, 0x07, 0x06, 0x07, 0x03, 0x06, 0x07, 0x17, 0x16, 0x17, 0x16, 0x17, - 0x16, 0x17, 0x06, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x07, 0x26, 0x27, - 0x26, 0x27, 0x26, 0x2f, 0x01, 0x06, 0x07, 0x17, 0x16, 0x17, 0x16, 0x17, - 0x16, 0x33, 0x32, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x34, 0x27, 0x26, - 0x27, 0x26, 0x27, 0x01, 0x36, 0x37, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, - 0x23, 0x22, 0x06, 0x07, 0x06, 0x07, 0x06, 0x07, 0x14, 0x17, 0x16, 0x17, - 0x16, 0x1f, 0x01, 0x36, 0x37, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x27, - 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x16, 0x17, 0x16, 0x17, - 0x16, 0x17, 0x04, 0x22, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, - 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x32, 0x37, 0x36, 0x37, 0x36, 0x37, - 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x27, 0x13, 0x06, 0x07, 0x17, - 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x22, 0x27, 0x26, - 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x3f, 0x01, 0x26, 0x27, 0x07, 0x06, - 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x32, 0x37, 0x36, 0x37, - 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x03, 0x16, 0x17, 0x37, 0x36, 0x35, - 0x34, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x22, 0x07, 0x06, 0x07, 0x06, - 0x07, 0x06, 0x15, 0x14, 0x1f, 0x01, 0x36, 0x37, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, - 0x16, 0x15, 0x14, 0x07, 0x01, 0x8b, 0x04, 0x02, 0xaf, 0x0d, 0x07, 0x07, - 0x0b, 0x09, 0x08, 0x06, 0x05, 0x03, 0x03, 0x05, 0x06, 0x08, 0x09, 0x09, - 0x09, 0x07, 0x0d, 0xaf, 0x02, 0x04, 0x9e, 0x1b, 0x10, 0x15, 0x28, 0x11, - 0x0f, 0x0a, 0x07, 0x07, 0x0a, 0x0f, 0x11, 0x14, 0x14, 0x15, 0x10, 0x1b, - 0x02, 0x62, 0x02, 0x04, 0x9b, 0x1b, 0x0e, 0x17, 0x14, 0x14, 0x11, 0x0f, - 0x0a, 0x07, 0x07, 0x0a, 0x0f, 0x11, 0x28, 0x17, 0x0e, 0x1b, 0x9b, 0x04, - 0x02, 0xac, 0x0d, 0x05, 0x0d, 0x07, 0x09, 0x08, 0x06, 0x05, 0x03, 0x03, - 0x05, 0x06, 0x09, 0x08, 0x0b, 0x09, 0x05, 0x0d, 0xfc, 0xcd, 0x1c, 0x0d, - 0x0d, 0x0d, 0x0c, 0x19, 0x19, 0x1f, 0x1f, 0x23, 0x21, 0x22, 0x1f, 0x1c, - 0x1a, 0x19, 0x19, 0x1e, 0x1f, 0x47, 0x1f, 0x1e, 0x19, 0x19, 0x1a, 0x1e, - 0x1d, 0x22, 0x21, 0x23, 0x1f, 0x1f, 0x19, 0x16, 0x0f, 0x0d, 0x0d, 0x0b, - 0x1e, 0x2a, 0x1e, 0x1d, 0x1a, 0x1b, 0x0b, 0x0d, 0x0d, 0x0d, 0x19, 0x15, - 0x22, 0x20, 0x27, 0x1d, 0x0b, 0x0d, 0x0d, 0x0c, 0x19, 0x19, 0x1f, 0x1f, - 0x23, 0x23, 0x20, 0x1f, 0x1c, 0x1a, 0x19, 0x19, 0x1e, 0x1f, 0x47, 0x1f, - 0x1e, 0x19, 0x19, 0x1a, 0x1f, 0x1c, 0x21, 0x22, 0x22, 0x20, 0x1f, 0x19, - 0x19, 0x0c, 0x0d, 0x0d, 0x0d, 0x1b, 0x27, 0x20, 0x1d, 0x1a, 0x1b, 0x0c, - 0x0c, 0x0c, 0x0e, 0x19, 0x1a, 0x1d, 0x1e, 0x01, 0x59, 0x0f, 0x0d, 0x6d, - 0x08, 0x05, 0x05, 0x0a, 0x09, 0x0b, 0x0a, 0x09, 0x09, 0x07, 0x07, 0x04, - 0x03, 0x01, 0x01, 0x04, 0x03, 0x07, 0x04, 0x0b, 0x8a, 0x0b, 0x08, 0x8d, - 0x1a, 0x0a, 0x11, 0x07, 0x09, 0x01, 0x08, 0x07, 0x11, 0x10, 0x28, 0x16, - 0x18, 0x13, 0x14, 0x10, 0x0b, 0x0e, 0x01, 0x79, 0x0c, 0x07, 0x8b, 0x1a, - 0x0a, 0x11, 0x07, 0x09, 0x01, 0x08, 0x07, 0x11, 0x10, 0x28, 0x16, 0x18, - 0x13, 0x14, 0x11, 0x0a, 0x0e, 0x4f, 0x0f, 0x0d, 0x6b, 0x08, 0x04, 0x08, - 0x08, 0x09, 0x0b, 0x0a, 0x09, 0x09, 0x07, 0x07, 0x04, 0x03, 0x01, 0x01, - 0x04, 0x04, 0x06, 0x04, 0x0b, 0x77, 0x08, 0x0b, 0x8a, 0x0b, 0x04, 0x06, - 0x04, 0x04, 0x01, 0x01, 0x03, 0x04, 0x07, 0x07, 0x09, 0x09, 0x0a, 0x0b, - 0x09, 0x08, 0x07, 0x05, 0x08, 0x6d, 0x0d, 0x0f, 0x51, 0x0e, 0x0b, 0x10, - 0x14, 0x13, 0x18, 0x16, 0x28, 0x10, 0x11, 0x07, 0x08, 0x01, 0x09, 0x07, - 0x11, 0x0a, 0x1a, 0xfe, 0x1c, 0x0e, 0x0e, 0x4f, 0x0e, 0x0a, 0x11, 0x14, - 0x13, 0x18, 0x16, 0x28, 0x10, 0x11, 0x07, 0x08, 0x01, 0x09, 0x07, 0x11, - 0x0a, 0x1a, 0x8b, 0x08, 0x0b, 0x88, 0x0b, 0x04, 0x07, 0x03, 0x04, 0x01, - 0x01, 0x03, 0x04, 0x07, 0x07, 0x09, 0x09, 0x0a, 0x0d, 0x07, 0x0a, 0x06, - 0x04, 0x08, 0x01, 0x1a, 0x3f, 0x1b, 0x1b, 0x17, 0x16, 0x0c, 0x0b, 0x0b, - 0x0c, 0x16, 0x17, 0x1b, 0x1b, 0x3f, 0x1b, 0x1b, 0x17, 0x16, 0x0c, 0x0b, - 0x0b, 0x0c, 0x16, 0x17, 0x1b, 0x02, 0x11, 0x10, 0x15, 0x01, 0x03, 0x04, - 0x07, 0x08, 0x08, 0x0a, 0x13, 0x0a, 0x08, 0x08, 0x07, 0x04, 0x03, 0x01, - 0x15, 0x11, 0x10, 0x2b, 0x08, 0x09, 0x07, 0x11, 0x10, 0x14, 0x13, 0x2f, - 0x13, 0x14, 0x10, 0x11, 0x07, 0x09, 0x08, 0x4c, 0x12, 0x10, 0x2a, 0x08, - 0x09, 0x07, 0x11, 0x10, 0x14, 0x13, 0x2f, 0x13, 0x14, 0x10, 0x11, 0x07, - 0x09, 0x08, 0x2a, 0x11, 0x11, 0x15, 0x01, 0x03, 0x04, 0x07, 0x08, 0x08, - 0x0a, 0x13, 0x0a, 0x08, 0x08, 0x08, 0x03, 0x03, 0x01, 0x02, 0x03, 0x11, - 0x11, 0x15, 0x02, 0x05, 0x03, 0x07, 0x08, 0x08, 0x09, 0x0b, 0x09, 0x09, - 0x09, 0x08, 0x06, 0x05, 0x03, 0x02, 0x14, 0x11, 0x10, 0x2b, 0x07, 0x0f, - 0x11, 0x11, 0x14, 0x12, 0x2e, 0x14, 0x14, 0x10, 0x10, 0x08, 0x09, 0x07, - 0x4d, 0x12, 0x10, 0x2b, 0x07, 0x09, 0x08, 0x10, 0x10, 0x14, 0x14, 0x2e, - 0x12, 0x14, 0x11, 0x11, 0x0f, 0x07, 0x2a, 0x11, 0x11, 0x14, 0x02, 0x03, - 0x05, 0x06, 0x08, 0x09, 0x09, 0x09, 0x0b, 0x09, 0x08, 0x08, 0x09, 0x01, - 0x05, 0x02, 0xdd, 0x1c, 0x20, 0x21, 0x21, 0x21, 0x21, 0x1f, 0x19, 0x19, - 0x0c, 0x0d, 0x0d, 0x0d, 0x1b, 0x27, 0x3f, 0x18, 0x18, 0x0e, 0x0d, 0x0d, - 0x0e, 0x18, 0x18, 0x3f, 0x27, 0x1d, 0x0b, 0x0d, 0x0d, 0x0c, 0x19, 0x16, - 0x22, 0x1f, 0x23, 0x1c, 0x26, 0x1f, 0x1d, 0x0d, 0x0c, 0x1a, 0x1b, 0x1c, - 0x1f, 0x23, 0x27, 0x1b, 0x1f, 0x19, 0x17, 0x0f, 0x0e, 0x1d, 0x1e, 0x22, - 0x21, 0x21, 0x20, 0x1f, 0x19, 0x19, 0x0d, 0x0c, 0x0c, 0x0d, 0x1c, 0x27, - 0x3f, 0x19, 0x17, 0x0e, 0x0d, 0x0d, 0x0e, 0x17, 0x19, 0x3f, 0x27, 0x1e, - 0x0b, 0x0c, 0x0c, 0x0d, 0x19, 0x19, 0x1f, 0x20, 0x21, 0x22, 0x21, 0x20, - 0x1b, 0x0e, 0x0c, 0x1a, 0x1b, 0x1d, 0x1e, 0x24, 0x26, 0x1c, 0x1f, 0x18, - 0x1a, 0x0c, 0x0d, 0xfe, 0x8c, 0x09, 0x0a, 0x8b, 0x0a, 0x04, 0x06, 0x04, - 0x04, 0x01, 0x01, 0x03, 0x04, 0x07, 0x07, 0x09, 0x09, 0x0a, 0x0a, 0x09, - 0x0a, 0x06, 0x05, 0x08, 0x6d, 0x0d, 0x0e, 0x50, 0x0f, 0x0b, 0x0f, 0x14, - 0x13, 0x18, 0x16, 0x15, 0x13, 0x11, 0x10, 0x0f, 0x07, 0x09, 0x0f, 0x0b, - 0x19, 0x01, 0xe5, 0x0d, 0x0f, 0x4f, 0x0f, 0x0a, 0x10, 0x14, 0x13, 0x18, - 0x16, 0x15, 0x13, 0x11, 0x10, 0x0f, 0x07, 0x09, 0x10, 0x0a, 0x19, 0x8b, - 0x09, 0x0b, 0x88, 0x0a, 0x04, 0x09, 0x02, 0x04, 0x01, 0x01, 0x03, 0x04, - 0x07, 0x07, 0x09, 0x09, 0x0a, 0x0d, 0x06, 0x0a, 0x07, 0x04, 0x08, 0xfe, - 0x93, 0x0e, 0x0d, 0x6d, 0x08, 0x05, 0x06, 0x0a, 0x09, 0x0a, 0x0a, 0x09, - 0x09, 0x07, 0x07, 0x04, 0x03, 0x01, 0x01, 0x04, 0x03, 0x07, 0x04, 0x0a, - 0x8b, 0x0b, 0x08, 0x8e, 0x19, 0x0b, 0x0f, 0x09, 0x07, 0x0f, 0x10, 0x11, - 0x13, 0x15, 0x16, 0x18, 0x13, 0x14, 0x0f, 0x0b, 0x0f, 0x01, 0x79, 0x0b, - 0x09, 0x8b, 0x19, 0x0a, 0x10, 0x09, 0x07, 0x0f, 0x10, 0x11, 0x13, 0x15, - 0x16, 0x18, 0x13, 0x14, 0x10, 0x0a, 0x0f, 0x4f, 0x0f, 0x0d, 0x6b, 0x08, - 0x04, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x09, 0x09, 0x07, 0x07, 0x04, 0x03, - 0x01, 0x01, 0x04, 0x04, 0x07, 0x04, 0x0a, 0xa3, 0x0c, 0x0c, 0x15, 0x18, - 0x1a, 0x1c, 0x1f, 0x1f, 0x1c, 0x1b, 0x17, 0x15, 0x0c, 0x0c, 0x0c, 0x0c, - 0x15, 0x17, 0x1b, 0x1c, 0x1f, 0x1f, 0x1c, 0x1a, 0x18, 0x15, 0x0c, 0xfe, - 0x93, 0x05, 0x01, 0xaf, 0x0d, 0x07, 0x08, 0x0a, 0x09, 0x08, 0x07, 0x04, - 0x03, 0x03, 0x04, 0x07, 0x08, 0x09, 0x09, 0x09, 0x07, 0x0d, 0xaf, 0x01, - 0x05, 0x9e, 0x1c, 0x0f, 0x16, 0x14, 0x13, 0x11, 0x0f, 0x09, 0x09, 0x09, - 0x09, 0x0f, 0x11, 0x13, 0x14, 0x16, 0x0f, 0x1c, 0x02, 0x62, 0x01, 0x05, - 0x9a, 0x1d, 0x0e, 0x17, 0x14, 0x13, 0x11, 0x0f, 0x09, 0x09, 0x09, 0x09, - 0x0f, 0x11, 0x13, 0x14, 0x17, 0x0e, 0x1d, 0x9a, 0x05, 0x01, 0xac, 0x0d, - 0x06, 0x0b, 0x08, 0x09, 0x08, 0x07, 0x03, 0x04, 0x04, 0x03, 0x07, 0x0a, - 0x07, 0x0a, 0x09, 0x06, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x25, - 0xff, 0xdf, 0x04, 0xac, 0x04, 0x6a, 0x00, 0x1d, 0x00, 0x3c, 0x00, 0x5c, - 0x00, 0x6c, 0x00, 0x00, 0x00, 0x22, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, - 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x32, 0x37, 0x36, 0x37, - 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x2f, 0x01, 0x32, - 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x34, 0x37, - 0x36, 0x37, 0x36, 0x37, 0x36, 0x13, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, - 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, - 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, - 0x36, 0x17, 0x03, 0x25, 0x13, 0x0d, 0x01, 0x03, 0x25, 0x1b, 0x01, 0x05, - 0x03, 0x2d, 0x01, 0x13, 0x05, 0x02, 0x96, 0x5b, 0x27, 0x27, 0x21, 0x20, - 0x10, 0x10, 0x10, 0x10, 0x20, 0x21, 0x27, 0x27, 0x5b, 0x26, 0x28, 0x20, - 0x21, 0x10, 0x10, 0x10, 0x10, 0x21, 0x20, 0x28, 0x54, 0x42, 0x33, 0x39, - 0x29, 0x2b, 0x18, 0x17, 0x17, 0x17, 0x2c, 0x2b, 0x37, 0x36, 0x3f, 0x41, - 0x33, 0x3a, 0x28, 0x2b, 0x18, 0x17, 0x17, 0x17, 0x2c, 0x2b, 0x37, 0x36, - 0x3e, 0x74, 0x6a, 0x65, 0x56, 0x54, 0x2c, 0x2b, 0x2b, 0x28, 0x58, 0x52, - 0x69, 0x69, 0x75, 0x73, 0x6b, 0x64, 0x56, 0x54, 0x2c, 0x2a, 0x2a, 0x28, - 0x58, 0x51, 0x69, 0x6a, 0x74, 0x75, 0xfe, 0xdf, 0x7a, 0xfe, 0xde, 0x01, - 0x22, 0x7a, 0x01, 0x21, 0x75, 0x76, 0x01, 0x21, 0x7a, 0x01, 0x22, 0xfe, - 0xde, 0x7a, 0xfe, 0xdf, 0x03, 0x04, 0x11, 0x12, 0x1e, 0x23, 0x26, 0x28, - 0x2c, 0x2d, 0x27, 0x27, 0x22, 0x1e, 0x12, 0x11, 0x11, 0x12, 0x1e, 0x22, - 0x27, 0x27, 0x2d, 0x2c, 0x28, 0x26, 0x23, 0x1e, 0x12, 0x65, 0x18, 0x19, - 0x29, 0x2a, 0x3a, 0x36, 0x3f, 0x3b, 0x39, 0x37, 0x2c, 0x2b, 0x17, 0x18, - 0x18, 0x19, 0x29, 0x2a, 0x39, 0x37, 0x7a, 0x38, 0x38, 0x2c, 0x2b, 0x17, - 0x18, 0x01, 0x11, 0x2c, 0x2a, 0x55, 0x54, 0x68, 0x67, 0x79, 0x72, 0x69, - 0x63, 0x59, 0x54, 0x2b, 0x2c, 0x2c, 0x2a, 0x55, 0x53, 0x69, 0x67, 0x74, - 0x76, 0x6a, 0x62, 0x5a, 0x52, 0x2d, 0x2c, 0x06, 0xfe, 0xde, 0x7a, 0xfe, - 0xdf, 0x76, 0x76, 0xfe, 0xe0, 0x7a, 0xfe, 0xde, 0x01, 0x22, 0x7a, 0x01, - 0x20, 0x76, 0x76, 0x01, 0x21, 0x7a, 0x00, 0x00, 0x00, 0x07, 0x00, 0x32, - 0xff, 0xed, 0x04, 0x9f, 0x05, 0x39, 0x00, 0x08, 0x00, 0x93, 0x00, 0x9c, - 0x00, 0xa7, 0x00, 0xb2, 0x00, 0xc1, 0x00, 0xd0, 0x00, 0x00, 0x01, 0x11, - 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x13, 0x17, 0x16, 0x33, 0x32, - 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x2f, 0x01, 0x15, 0x14, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x36, 0x3d, 0x01, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, - 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x33, 0x32, 0x3f, 0x01, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, - 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x1f, 0x01, 0x35, 0x34, 0x27, 0x26, - 0x35, 0x34, 0x37, 0x36, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x1d, - 0x01, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, - 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x23, - 0x22, 0x0f, 0x01, 0x11, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x13, - 0x25, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x06, 0x01, 0x05, - 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x36, 0x13, 0x25, 0x06, - 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x33, 0x32, - 0x0d, 0x01, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, - 0x06, 0x23, 0x22, 0x02, 0x69, 0x22, 0x28, 0x19, 0x1f, 0x2d, 0x89, 0x0e, - 0x2b, 0x53, 0x19, 0x1e, 0x0f, 0x0d, 0x49, 0x39, 0x4b, 0x0e, 0x09, 0x14, - 0x23, 0x59, 0x10, 0x11, 0x2e, 0x36, 0x43, 0x26, 0x34, 0x3c, 0x0e, 0x46, - 0x34, 0x2c, 0x43, 0x44, 0x48, 0x3f, 0x2c, 0x34, 0x46, 0x0f, 0x39, 0x36, - 0x28, 0x42, 0x35, 0x2d, 0x12, 0x11, 0x59, 0x22, 0x15, 0x09, 0x0f, 0x4b, - 0x38, 0x49, 0x0e, 0x0e, 0x1e, 0x1a, 0x53, 0x2a, 0x0f, 0x0f, 0x29, 0x52, - 0x1b, 0x1f, 0x0e, 0x0e, 0x49, 0x38, 0x4a, 0x10, 0x09, 0x15, 0x22, 0x59, - 0x11, 0x12, 0x2d, 0x35, 0x44, 0x26, 0x33, 0x3c, 0x0f, 0x46, 0x34, 0x2c, - 0x43, 0x88, 0x43, 0x2c, 0x34, 0x46, 0x0e, 0x3a, 0x36, 0x28, 0x41, 0x36, - 0x2e, 0x11, 0x10, 0x59, 0x23, 0x14, 0x09, 0x0e, 0x4b, 0x39, 0x49, 0x0d, - 0x0f, 0x1e, 0x1b, 0x52, 0x2a, 0x80, 0x22, 0x28, 0x18, 0x1e, 0x2d, 0x8d, - 0x01, 0x36, 0x11, 0x32, 0x08, 0x0a, 0x19, 0x23, 0x39, 0x14, 0x1e, 0xfe, - 0x7e, 0xfe, 0xc9, 0x11, 0x33, 0x08, 0x0a, 0x19, 0x23, 0x39, 0x14, 0x1d, - 0x3b, 0xfe, 0xc9, 0x0a, 0x04, 0x05, 0x30, 0x31, 0x2b, 0x08, 0x08, 0x17, - 0x18, 0x35, 0x01, 0x80, 0x01, 0x36, 0x0b, 0x04, 0x06, 0x30, 0x30, 0x2c, - 0x08, 0x07, 0x18, 0x18, 0x35, 0x03, 0x60, 0x01, 0x81, 0x25, 0x17, 0x3b, - 0x47, 0x2c, 0x41, 0xfe, 0xde, 0x0a, 0x1c, 0x03, 0x01, 0x24, 0x2e, 0x3f, - 0x27, 0x21, 0x33, 0x26, 0x40, 0x1b, 0x05, 0x21, 0x2a, 0x59, 0x78, 0x24, - 0x09, 0x12, 0x49, 0x6d, 0x50, 0x54, 0x5d, 0x2d, 0x45, 0x45, 0x30, 0x5a, - 0x54, 0x50, 0x6d, 0x49, 0x12, 0x09, 0x22, 0x7a, 0x5a, 0x29, 0x21, 0x05, - 0x1c, 0x3f, 0x26, 0x33, 0x21, 0x27, 0x40, 0x2d, 0x24, 0x01, 0x03, 0x1c, - 0x0a, 0x09, 0x1c, 0x03, 0x01, 0x23, 0x2c, 0x41, 0x27, 0x21, 0x32, 0x27, - 0x3f, 0x1c, 0x05, 0x21, 0x2a, 0x59, 0x78, 0x24, 0x08, 0x11, 0x49, 0x6d, - 0x51, 0x54, 0x5c, 0x2e, 0x45, 0x45, 0x2e, 0x5c, 0x54, 0x51, 0x6d, 0x49, - 0x11, 0x08, 0x23, 0x79, 0x5a, 0x29, 0x21, 0x05, 0x1a, 0x41, 0x26, 0x32, - 0x22, 0x27, 0x3f, 0x2e, 0x23, 0x01, 0x03, 0x1c, 0xd6, 0xfe, 0x7e, 0x26, - 0x16, 0x3c, 0x47, 0x2c, 0x40, 0x01, 0x89, 0xc1, 0x20, 0x12, 0x04, 0x16, - 0x23, 0x33, 0x4a, 0xfe, 0xf3, 0xc1, 0x20, 0x12, 0x03, 0x15, 0x23, 0x33, - 0x4a, 0x01, 0x0d, 0xc1, 0x13, 0x1e, 0x11, 0x16, 0x22, 0x1e, 0x1e, 0x01, - 0x04, 0xdc, 0xc1, 0x14, 0x1d, 0x12, 0x15, 0x22, 0x1e, 0x1e, 0x01, 0x03, - 0x00, 0x01, 0x00, 0x20, 0x00, 0x02, 0x04, 0xb1, 0x05, 0x57, 0x00, 0x41, - 0x00, 0x00, 0x01, 0x27, 0x07, 0x27, 0x37, 0x27, 0x37, 0x17, 0x35, 0x33, - 0x15, 0x17, 0x35, 0x27, 0x37, 0x17, 0x35, 0x33, 0x15, 0x37, 0x17, 0x07, - 0x15, 0x37, 0x35, 0x33, 0x15, 0x37, 0x17, 0x07, 0x17, 0x07, 0x27, 0x07, - 0x17, 0x37, 0x17, 0x07, 0x17, 0x07, 0x27, 0x15, 0x23, 0x35, 0x27, 0x15, - 0x17, 0x07, 0x27, 0x15, 0x23, 0x35, 0x07, 0x27, 0x37, 0x35, 0x07, 0x15, - 0x23, 0x35, 0x07, 0x27, 0x37, 0x27, 0x37, 0x17, 0x02, 0x01, 0xcf, 0xa8, - 0x34, 0x74, 0xa9, 0x34, 0xa9, 0x68, 0xcf, 0xa8, 0x34, 0x74, 0x67, 0x74, - 0x34, 0xa8, 0xcf, 0x68, 0xa9, 0x34, 0xa9, 0x74, 0x34, 0xa8, 0xcf, 0xcf, - 0xa8, 0x34, 0x74, 0xa9, 0x34, 0xa9, 0x68, 0xcf, 0xa8, 0x34, 0x74, 0x67, - 0x74, 0x34, 0xa8, 0xcf, 0x68, 0xa9, 0x34, 0xa9, 0x74, 0x34, 0xa8, 0x02, - 0xad, 0x7e, 0x66, 0x5f, 0x46, 0x68, 0x60, 0x69, 0x8e, 0xcd, 0x7f, 0xfe, - 0x66, 0x5f, 0x47, 0xd0, 0xd0, 0x47, 0x5f, 0x66, 0xfd, 0x7e, 0xcd, 0x8e, - 0x69, 0x60, 0x68, 0x46, 0x5f, 0x66, 0x7e, 0x7f, 0x66, 0x5f, 0x46, 0x68, - 0x5f, 0x68, 0x8e, 0xcd, 0x7f, 0xfe, 0x66, 0x5f, 0x47, 0xd0, 0xd0, 0x47, - 0x5f, 0x66, 0xfe, 0x7f, 0xcd, 0x8e, 0x68, 0x5f, 0x68, 0x46, 0x5f, 0x66, - 0x00, 0x07, 0x00, 0x30, 0xff, 0xfa, 0x04, 0xa1, 0x04, 0xb3, 0x00, 0x1d, - 0x00, 0x21, 0x00, 0x25, 0x00, 0x29, 0x00, 0x2d, 0x00, 0x31, 0x00, 0x35, - 0x00, 0x00, 0x01, 0x33, 0x15, 0x37, 0x11, 0x37, 0x17, 0x07, 0x17, 0x07, - 0x17, 0x07, 0x27, 0x11, 0x27, 0x15, 0x23, 0x35, 0x07, 0x11, 0x07, 0x27, - 0x37, 0x27, 0x37, 0x27, 0x37, 0x17, 0x11, 0x17, 0x07, 0x15, 0x17, 0x35, - 0x37, 0x07, 0x15, 0x37, 0x05, 0x07, 0x17, 0x37, 0x25, 0x07, 0x17, 0x37, - 0x05, 0x07, 0x15, 0x3f, 0x01, 0x15, 0x17, 0x35, 0x02, 0x38, 0x61, 0xec, - 0xd6, 0x31, 0xd8, 0xed, 0xec, 0xd7, 0x31, 0xd6, 0xec, 0x61, 0xec, 0xd6, - 0x31, 0xd7, 0xec, 0xed, 0xd8, 0x31, 0xd6, 0xec, 0x8a, 0x8a, 0xeb, 0x8a, - 0x8a, 0xfe, 0x5b, 0x8b, 0x8a, 0x8a, 0x01, 0x4c, 0x89, 0x8a, 0x8a, 0xfe, - 0x5a, 0x8a, 0x8a, 0x61, 0x8a, 0x04, 0xb3, 0xf9, 0x88, 0xfe, 0xf0, 0x7d, - 0x54, 0x7d, 0x88, 0x88, 0x7b, 0x55, 0x7d, 0xfe, 0xef, 0x89, 0xf8, 0xf8, - 0x89, 0x01, 0x11, 0x7d, 0x55, 0x7b, 0x88, 0x88, 0x7d, 0x54, 0x7d, 0x01, - 0x10, 0x88, 0x20, 0x9f, 0x50, 0x9f, 0x50, 0x50, 0x9f, 0x50, 0x55, 0x50, - 0x4f, 0x4f, 0x50, 0x50, 0x4f, 0x4f, 0x53, 0x50, 0xa0, 0x50, 0xa0, 0xa0, - 0x50, 0xa0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x19, 0x00, 0x05, 0x04, 0xb8, - 0x04, 0xc0, 0x00, 0x41, 0x00, 0x00, 0x01, 0x33, 0x15, 0x37, 0x17, 0x07, - 0x15, 0x37, 0x35, 0x33, 0x15, 0x37, 0x17, 0x07, 0x17, 0x07, 0x27, 0x07, - 0x17, 0x37, 0x17, 0x07, 0x17, 0x07, 0x27, 0x15, 0x23, 0x35, 0x27, 0x15, - 0x17, 0x07, 0x27, 0x15, 0x23, 0x35, 0x07, 0x27, 0x37, 0x35, 0x07, 0x15, - 0x23, 0x35, 0x07, 0x27, 0x37, 0x27, 0x37, 0x17, 0x37, 0x27, 0x07, 0x27, - 0x37, 0x27, 0x37, 0x17, 0x35, 0x33, 0x15, 0x17, 0x35, 0x27, 0x37, 0x17, - 0x02, 0x39, 0x61, 0x72, 0x51, 0xc3, 0xda, 0xa2, 0x48, 0x31, 0x4a, 0x71, - 0x51, 0xc3, 0xd8, 0xd9, 0xc3, 0x51, 0x72, 0x49, 0x31, 0x4b, 0xa2, 0xd6, - 0xc3, 0x51, 0x72, 0x61, 0x72, 0x51, 0xc3, 0xd8, 0xa2, 0x4a, 0x31, 0x48, - 0x72, 0x51, 0xc3, 0xd9, 0xd7, 0xc3, 0x52, 0x72, 0x4b, 0x31, 0x49, 0xa2, - 0xdb, 0xc3, 0x51, 0x72, 0x04, 0xbf, 0x54, 0x42, 0x8d, 0x71, 0xf9, 0x7e, - 0xe2, 0x84, 0x2a, 0x54, 0x2b, 0x42, 0x8d, 0x70, 0x7c, 0x7e, 0x71, 0x8d, - 0x41, 0x2b, 0x54, 0x2b, 0x83, 0xe1, 0x7c, 0xf7, 0x71, 0x8d, 0x42, 0x54, - 0x52, 0x42, 0x8c, 0x71, 0xfb, 0x7c, 0xe1, 0x83, 0x2b, 0x54, 0x2a, 0x41, - 0x8e, 0x71, 0x7d, 0x7c, 0x71, 0x8d, 0x42, 0x2b, 0x54, 0x29, 0x83, 0xe1, - 0x7e, 0xfc, 0x70, 0x8d, 0x42, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x32, - 0xff, 0xee, 0x04, 0x9f, 0x04, 0xd8, 0x00, 0x87, 0x00, 0x00, 0x01, 0x16, - 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x07, - 0x17, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x27, 0x15, 0x16, 0x17, 0x1e, 0x01, 0x14, 0x0e, 0x01, 0x22, 0x2e, - 0x01, 0x34, 0x36, 0x37, 0x36, 0x37, 0x35, 0x07, 0x16, 0x15, 0x14, 0x07, - 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, - 0x36, 0x37, 0x36, 0x32, 0x17, 0x16, 0x17, 0x37, 0x27, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x2e, 0x01, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, - 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x17, 0x35, 0x26, 0x27, 0x2e, 0x01, - 0x34, 0x36, 0x37, 0x36, 0x33, 0x32, 0x1e, 0x01, 0x14, 0x06, 0x07, 0x06, - 0x07, 0x15, 0x37, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x04, 0x89, 0x16, 0x16, 0x16, 0x25, 0x27, 0x2b, 0x2c, 0x25, - 0x0f, 0x0e, 0xc4, 0xc4, 0x0e, 0x0f, 0x25, 0x2c, 0x2b, 0x27, 0x25, 0x16, - 0x16, 0x16, 0x17, 0x24, 0x27, 0x2b, 0x29, 0x28, 0x26, 0x16, 0x15, 0x03, - 0xc4, 0x11, 0x10, 0x25, 0x2c, 0x2c, 0x4b, 0x57, 0x4b, 0x2c, 0x2c, 0x25, - 0x10, 0x11, 0xc4, 0x03, 0x15, 0x16, 0x26, 0x26, 0x2b, 0x2c, 0x26, 0x25, - 0x16, 0x16, 0x16, 0x16, 0x25, 0x27, 0x56, 0x26, 0x0f, 0x0e, 0xc4, 0xc4, - 0x0d, 0x10, 0x28, 0x29, 0x2c, 0x4b, 0x2c, 0x16, 0x16, 0x25, 0x27, 0x2b, - 0x29, 0x28, 0x26, 0x16, 0x15, 0x03, 0xc4, 0x11, 0x10, 0x25, 0x2c, 0x2c, - 0x25, 0x26, 0x2b, 0x2c, 0x4b, 0x2c, 0x2c, 0x25, 0x10, 0x11, 0xc4, 0x03, - 0x15, 0x15, 0x27, 0x25, 0x2c, 0x2b, 0x27, 0x29, 0x03, 0x9d, 0x2c, 0x25, - 0x2b, 0x27, 0x25, 0x16, 0x16, 0x16, 0x09, 0x0c, 0x71, 0x71, 0x0c, 0x09, - 0x16, 0x16, 0x16, 0x26, 0x26, 0x2b, 0x2a, 0x26, 0x26, 0x16, 0x16, 0x16, - 0x15, 0x26, 0x25, 0x2c, 0x12, 0x11, 0x72, 0xe3, 0x06, 0x08, 0x16, 0x4b, - 0x58, 0x4b, 0x2c, 0x2c, 0x4b, 0x58, 0x4b, 0x16, 0x08, 0x06, 0xe3, 0x72, - 0x11, 0x12, 0x2c, 0x25, 0x26, 0x15, 0x16, 0x16, 0x15, 0x26, 0x25, 0x2c, - 0x2b, 0x26, 0x26, 0x16, 0x16, 0x16, 0x09, 0x0c, 0x71, 0x71, 0x0c, 0x09, - 0x16, 0x2c, 0x4b, 0x58, 0x25, 0x26, 0x15, 0x16, 0x16, 0x15, 0x26, 0x25, - 0x2c, 0x12, 0x11, 0x72, 0xe3, 0x05, 0x09, 0x16, 0x4b, 0x58, 0x4b, 0x15, - 0x16, 0x2b, 0x4b, 0x58, 0x4b, 0x16, 0x09, 0x05, 0xe3, 0x72, 0x11, 0x12, - 0x2c, 0x25, 0x24, 0x17, 0x16, 0x16, 0x18, 0x00, 0x00, 0x09, 0x00, 0x29, - 0xff, 0xeb, 0x04, 0xa8, 0x04, 0x6a, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x0f, - 0x00, 0x13, 0x00, 0x17, 0x00, 0x2e, 0x00, 0x45, 0x00, 0x5c, 0x00, 0x73, - 0x00, 0x00, 0x00, 0x14, 0x06, 0x22, 0x26, 0x34, 0x36, 0x32, 0x09, 0x01, - 0x37, 0x09, 0x02, 0x37, 0x01, 0x25, 0x01, 0x27, 0x09, 0x02, 0x27, 0x01, - 0x37, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, - 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x03, - 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x22, - 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x27, 0x06, - 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x34, 0x37, - 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x05, 0x36, 0x37, - 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x14, 0x07, 0x06, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x02, 0xda, 0x43, 0x5d, - 0x43, 0x43, 0x5d, 0x01, 0x40, 0xfe, 0xdc, 0x40, 0x01, 0x24, 0xfd, 0xc6, - 0xfe, 0xdd, 0x40, 0x01, 0x23, 0x01, 0xfa, 0xfe, 0xdc, 0x40, 0x01, 0x24, - 0xfe, 0x46, 0xfe, 0xdd, 0x40, 0x01, 0x23, 0x8b, 0x2b, 0x0b, 0x11, 0x03, - 0x01, 0x01, 0x03, 0x0b, 0x11, 0x57, 0x11, 0x0b, 0x03, 0x01, 0x01, 0x03, - 0x11, 0x0b, 0x2c, 0x2c, 0x0b, 0x11, 0x03, 0x01, 0x01, 0x03, 0x0b, 0x11, - 0x57, 0x11, 0x0b, 0x03, 0x01, 0x01, 0x03, 0x11, 0x0b, 0x78, 0x2d, 0x12, - 0x1c, 0x33, 0x16, 0x3e, 0x34, 0x17, 0x31, 0x18, 0x25, 0x25, 0x18, 0x31, - 0x17, 0x34, 0x3e, 0x16, 0x33, 0x1c, 0x12, 0x01, 0x74, 0x2d, 0x12, 0x1c, - 0x33, 0x16, 0x3e, 0x34, 0x17, 0x31, 0x18, 0x25, 0x25, 0x18, 0x31, 0x17, - 0x34, 0x3e, 0x16, 0x33, 0x1c, 0x12, 0x02, 0x66, 0x5e, 0x43, 0x43, 0x5e, - 0x42, 0xfd, 0xdf, 0x01, 0x25, 0x40, 0xfe, 0xdb, 0x01, 0xba, 0x01, 0x23, - 0x40, 0xfe, 0xdd, 0xe3, 0xfe, 0xdb, 0x40, 0x01, 0x25, 0xfd, 0xc6, 0xfe, - 0xdd, 0x40, 0x01, 0x23, 0xe4, 0x2d, 0x12, 0x1c, 0x34, 0x15, 0x3e, 0x34, - 0x17, 0x31, 0x18, 0x25, 0x25, 0x18, 0x31, 0x17, 0x34, 0x3e, 0x15, 0x34, - 0x1c, 0x12, 0xfe, 0x8c, 0x2d, 0x12, 0x1c, 0x33, 0x16, 0x3e, 0x34, 0x17, - 0x31, 0x18, 0x25, 0x25, 0x18, 0x31, 0x17, 0x34, 0x3e, 0x16, 0x33, 0x1c, - 0x12, 0xd1, 0x2b, 0x0c, 0x11, 0x03, 0x01, 0x02, 0x02, 0x0b, 0x12, 0x56, - 0x11, 0x0b, 0x03, 0x01, 0x01, 0x03, 0x11, 0x0b, 0x2b, 0x2b, 0x0b, 0x11, - 0x03, 0x01, 0x01, 0x03, 0x0b, 0x11, 0x56, 0x12, 0x0b, 0x02, 0x02, 0x01, - 0x03, 0x11, 0x0c, 0x00, 0x00, 0x09, 0x00, 0x21, 0xff, 0xe3, 0x04, 0xb0, - 0x04, 0x72, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x13, 0x00, 0x17, - 0x00, 0x2b, 0x00, 0x3f, 0x00, 0x53, 0x00, 0x67, 0x00, 0x00, 0x00, 0x14, - 0x06, 0x22, 0x26, 0x34, 0x36, 0x32, 0x01, 0x37, 0x17, 0x07, 0x01, 0x37, - 0x17, 0x07, 0x01, 0x17, 0x07, 0x27, 0x01, 0x17, 0x07, 0x27, 0x02, 0x14, - 0x07, 0x06, 0x07, 0x06, 0x22, 0x27, 0x26, 0x27, 0x26, 0x34, 0x37, 0x36, - 0x37, 0x36, 0x32, 0x17, 0x16, 0x17, 0x12, 0x14, 0x07, 0x06, 0x07, 0x06, - 0x22, 0x27, 0x26, 0x27, 0x26, 0x34, 0x37, 0x36, 0x37, 0x36, 0x32, 0x17, - 0x16, 0x17, 0x00, 0x32, 0x17, 0x16, 0x17, 0x16, 0x14, 0x07, 0x06, 0x07, - 0x06, 0x22, 0x27, 0x26, 0x27, 0x26, 0x34, 0x37, 0x36, 0x37, 0x24, 0x32, - 0x17, 0x16, 0x17, 0x16, 0x14, 0x07, 0x06, 0x07, 0x06, 0x22, 0x27, 0x26, - 0x27, 0x26, 0x34, 0x37, 0x36, 0x37, 0x03, 0x15, 0x65, 0x8f, 0x65, 0x65, - 0x8f, 0xfe, 0x04, 0xe3, 0x42, 0xe4, 0x02, 0x03, 0xe4, 0x41, 0xe3, 0xfd, - 0xbb, 0xe4, 0x42, 0xe3, 0x02, 0x86, 0xe3, 0x41, 0xe4, 0x06, 0x0e, 0x10, - 0x1e, 0x23, 0x55, 0x23, 0x1e, 0x10, 0x0e, 0x0e, 0x10, 0x1e, 0x23, 0x55, - 0x23, 0x1e, 0x10, 0x0e, 0x0e, 0x10, 0x1e, 0x23, 0x55, 0x23, 0x1e, 0x10, - 0x0e, 0x0e, 0x10, 0x1e, 0x23, 0x55, 0x23, 0x1e, 0x10, 0xfd, 0xc7, 0x56, - 0x25, 0x2a, 0x1b, 0x1f, 0x1f, 0x1b, 0x2a, 0x25, 0x56, 0x26, 0x2a, 0x1b, - 0x1e, 0x1e, 0x1b, 0x2a, 0x03, 0x4b, 0x56, 0x26, 0x2a, 0x1b, 0x1e, 0x1e, - 0x1b, 0x2a, 0x26, 0x56, 0x25, 0x2a, 0x1b, 0x1f, 0x1f, 0x1b, 0x2a, 0x02, - 0x7e, 0x8e, 0x66, 0x66, 0x8e, 0x65, 0xfd, 0xdf, 0xe3, 0x41, 0xe3, 0x02, - 0x86, 0xe3, 0x41, 0xe3, 0x01, 0x24, 0xe3, 0x41, 0xe3, 0xfd, 0xfc, 0xe3, - 0x41, 0xe3, 0x02, 0x84, 0x56, 0x25, 0x2a, 0x1b, 0x1f, 0x1f, 0x1b, 0x2a, - 0x25, 0x56, 0x26, 0x2a, 0x1b, 0x1e, 0x1e, 0x1b, 0x2a, 0xfc, 0xb5, 0x56, - 0x26, 0x2a, 0x1b, 0x1e, 0x1e, 0x1b, 0x2a, 0x26, 0x56, 0x25, 0x2a, 0x1b, - 0x1f, 0x1f, 0x1b, 0x2a, 0x01, 0xcc, 0x0e, 0x10, 0x1e, 0x23, 0x55, 0x23, - 0x1e, 0x10, 0x0e, 0x0e, 0x10, 0x1e, 0x23, 0x55, 0x23, 0x1e, 0x10, 0x0e, - 0x0e, 0x10, 0x1e, 0x23, 0x55, 0x23, 0x1e, 0x10, 0x0e, 0x0e, 0x10, 0x1e, - 0x23, 0x55, 0x23, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x17, - 0xff, 0xea, 0x04, 0xba, 0x04, 0x8d, 0x00, 0x0c, 0x00, 0x19, 0x00, 0x26, - 0x00, 0x33, 0x00, 0x40, 0x00, 0x4d, 0x00, 0x59, 0x00, 0x61, 0x00, 0x6d, - 0x00, 0x00, 0x01, 0x14, 0x07, 0x06, 0x2b, 0x01, 0x25, 0x35, 0x25, 0x33, - 0x32, 0x17, 0x16, 0x05, 0x34, 0x37, 0x36, 0x3b, 0x01, 0x05, 0x15, 0x05, - 0x23, 0x22, 0x27, 0x26, 0x01, 0x16, 0x15, 0x14, 0x0f, 0x02, 0x27, 0x3f, - 0x01, 0x36, 0x33, 0x32, 0x01, 0x26, 0x35, 0x34, 0x3f, 0x02, 0x17, 0x0f, - 0x01, 0x06, 0x23, 0x22, 0x03, 0x36, 0x33, 0x32, 0x1f, 0x02, 0x07, 0x2f, - 0x01, 0x26, 0x35, 0x34, 0x01, 0x06, 0x23, 0x22, 0x2f, 0x02, 0x37, 0x1f, - 0x01, 0x16, 0x15, 0x14, 0x00, 0x32, 0x17, 0x16, 0x1d, 0x01, 0x03, 0x23, - 0x03, 0x35, 0x34, 0x37, 0x12, 0x14, 0x06, 0x22, 0x26, 0x34, 0x36, 0x32, - 0x02, 0x22, 0x27, 0x26, 0x3d, 0x01, 0x13, 0x33, 0x13, 0x15, 0x14, 0x07, - 0x04, 0xb9, 0x15, 0x16, 0x1e, 0x08, 0xfe, 0xc1, 0x01, 0x3f, 0x08, 0x1d, - 0x17, 0x15, 0xfb, 0x5f, 0x15, 0x16, 0x1e, 0x08, 0x01, 0x3f, 0xfe, 0xc1, - 0x08, 0x1d, 0x17, 0x15, 0x03, 0xf4, 0x16, 0x14, 0x06, 0xfc, 0x36, 0xc6, - 0x05, 0x15, 0x20, 0x20, 0xfc, 0xcf, 0x16, 0x14, 0x06, 0xfc, 0x36, 0xc6, - 0x05, 0x15, 0x20, 0x1e, 0x18, 0x16, 0x20, 0x1f, 0x16, 0x05, 0xc6, 0x36, - 0xfc, 0x06, 0x14, 0x03, 0x5d, 0x17, 0x1f, 0x20, 0x15, 0x05, 0xc6, 0x36, - 0xfc, 0x06, 0x14, 0xfe, 0x27, 0x3f, 0x17, 0x16, 0x26, 0x4d, 0x26, 0x16, - 0xa9, 0x43, 0x5f, 0x43, 0x43, 0x5f, 0x10, 0x3f, 0x17, 0x16, 0x26, 0x4d, - 0x26, 0x16, 0x02, 0x3c, 0x20, 0x17, 0x16, 0x27, 0x4c, 0x26, 0x16, 0x17, - 0x1f, 0x1f, 0x17, 0x16, 0x26, 0x4c, 0x27, 0x16, 0x17, 0x01, 0xc3, 0x16, - 0x21, 0x1e, 0x16, 0x05, 0xc6, 0x36, 0xfc, 0x05, 0x16, 0xfc, 0xa2, 0x17, - 0x20, 0x1e, 0x16, 0x05, 0xc6, 0x36, 0xfc, 0x05, 0x16, 0x03, 0x5e, 0x17, - 0x16, 0x05, 0xfc, 0x36, 0xc6, 0x05, 0x15, 0x1f, 0x21, 0xfc, 0xcf, 0x17, - 0x16, 0x05, 0xfc, 0x36, 0xc6, 0x05, 0x15, 0x1f, 0x20, 0x03, 0xde, 0x17, - 0x15, 0x1f, 0x07, 0xfe, 0xc2, 0x01, 0x3e, 0x07, 0x1e, 0x16, 0xfd, 0xf5, - 0x5f, 0x43, 0x43, 0x5f, 0x44, 0xfd, 0x3c, 0x16, 0x15, 0x1f, 0x07, 0x01, - 0x3e, 0xfe, 0xc2, 0x07, 0x1e, 0x16, 0x00, 0x00, 0x00, 0x01, 0x00, 0x22, - 0xff, 0xe9, 0x04, 0xaf, 0x04, 0x1b, 0x00, 0x6c, 0x00, 0x00, 0x01, 0x32, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x03, 0x13, 0x36, 0x37, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x05, 0x25, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x25, 0x05, 0x16, 0x33, - 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x03, 0x13, - 0x16, 0x15, 0x14, 0x07, 0x06, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x13, - 0x03, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x32, - 0x37, 0x25, 0x05, 0x06, 0x23, 0x22, 0x27, 0x26, 0x34, 0x37, 0x36, 0x33, - 0x32, 0x17, 0x05, 0x25, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x33, - 0x16, 0x17, 0x16, 0x17, 0x13, 0x03, 0x26, 0x35, 0x34, 0x37, 0x36, 0x02, - 0x68, 0x21, 0x23, 0x1b, 0x04, 0x3b, 0xd6, 0x0f, 0x02, 0x27, 0x26, 0x31, - 0x18, 0x16, 0x27, 0x08, 0x12, 0xfe, 0xdb, 0x01, 0x68, 0x13, 0x09, 0x39, - 0x1a, 0x23, 0x23, 0x1b, 0x38, 0x05, 0x1c, 0xfe, 0x9d, 0x01, 0x29, 0x15, - 0x01, 0x27, 0x16, 0x18, 0x31, 0x21, 0x2c, 0x08, 0x0d, 0xd2, 0x3b, 0x04, - 0x1b, 0x23, 0x41, 0x23, 0x1b, 0x04, 0x3b, 0xd2, 0x0d, 0x08, 0x27, 0x26, - 0x31, 0x18, 0x16, 0x27, 0x01, 0x15, 0x01, 0x29, 0xfe, 0x9d, 0x1c, 0x05, - 0x38, 0x1b, 0x23, 0x23, 0x1a, 0x39, 0x09, 0x13, 0x01, 0x68, 0xfe, 0xdb, - 0x12, 0x08, 0x27, 0x16, 0x18, 0x31, 0x1b, 0x32, 0x02, 0x0f, 0xd6, 0x3b, - 0x04, 0x1b, 0x23, 0x04, 0x1a, 0x20, 0x18, 0x34, 0x05, 0x15, 0xfe, 0xb5, - 0x01, 0x10, 0x14, 0x01, 0x25, 0x16, 0x15, 0x2e, 0x26, 0x21, 0x06, 0x0c, - 0xc2, 0x36, 0x03, 0x17, 0x20, 0x3d, 0x20, 0x19, 0x04, 0x36, 0xc4, 0x10, - 0x25, 0x22, 0x2e, 0x15, 0x16, 0x25, 0x07, 0x11, 0x01, 0x0d, 0xfe, 0xb5, - 0x15, 0x05, 0x33, 0x19, 0x20, 0x20, 0x19, 0x33, 0x09, 0x15, 0x01, 0x47, - 0xfe, 0xf3, 0x11, 0x07, 0x25, 0x16, 0x15, 0x2e, 0x35, 0x12, 0x10, 0xc4, - 0x36, 0x04, 0x19, 0x20, 0x3d, 0x20, 0x17, 0x03, 0x36, 0xc2, 0x0c, 0x06, - 0x25, 0x22, 0x2e, 0x15, 0x16, 0x0e, 0x17, 0x01, 0x14, 0xfe, 0xf0, 0x01, - 0x47, 0x15, 0x09, 0x34, 0x18, 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x24, - 0xff, 0xf5, 0x04, 0xad, 0x04, 0x38, 0x00, 0x0b, 0x00, 0x21, 0x00, 0x00, - 0x13, 0x14, 0x00, 0x20, 0x00, 0x35, 0x34, 0x2e, 0x01, 0x22, 0x0e, 0x01, - 0x01, 0x06, 0x23, 0x22, 0x00, 0x35, 0x34, 0x12, 0x24, 0x33, 0x32, 0x17, - 0x36, 0x33, 0x32, 0x04, 0x12, 0x15, 0x14, 0x00, 0x23, 0x22, 0x5f, 0x01, - 0x1c, 0x01, 0x94, 0x01, 0x1c, 0x82, 0xe9, 0xf6, 0xe9, 0x82, 0x02, 0x09, - 0x12, 0x12, 0xe0, 0xfe, 0xc0, 0x93, 0x01, 0x06, 0x87, 0x12, 0x12, 0x12, - 0x11, 0x8a, 0x01, 0x06, 0x92, 0xfe, 0xc0, 0xe2, 0x11, 0x02, 0x16, 0xc9, - 0xfe, 0xe3, 0x01, 0x1d, 0xc9, 0x80, 0xe8, 0x7e, 0x7e, 0xe8, 0xfd, 0x61, - 0x01, 0x01, 0x3e, 0xe2, 0x8d, 0x01, 0x07, 0x8d, 0x01, 0x01, 0x8d, 0xfe, - 0xfb, 0x8f, 0xe2, 0xfe, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x45, - 0xff, 0xc1, 0x04, 0x8c, 0x04, 0x09, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x00, - 0x25, 0x11, 0x21, 0x11, 0x17, 0x23, 0x11, 0x21, 0x15, 0x33, 0x11, 0x21, - 0x04, 0x0e, 0xfc, 0x70, 0x0c, 0x45, 0x04, 0x02, 0x45, 0xfb, 0xfe, 0x3f, - 0x03, 0x90, 0xfc, 0x70, 0x39, 0x04, 0x02, 0x45, 0xfb, 0xff, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x3d, 0x00, 0x00, 0x04, 0x94, 0x04, 0x56, 0x00, 0x03, - 0x00, 0x0b, 0x00, 0x00, 0x25, 0x11, 0x21, 0x11, 0x25, 0x15, 0x21, 0x11, - 0x33, 0x35, 0x21, 0x11, 0x04, 0x14, 0xfc, 0x63, 0x03, 0xd7, 0xfb, 0xf0, - 0x45, 0x04, 0x10, 0x3a, 0x03, 0x9c, 0xfc, 0x64, 0x0c, 0x46, 0x04, 0x10, - 0x46, 0xfb, 0xf0, 0x00, 0x00, 0x02, 0x00, 0x38, 0xff, 0xb8, 0x04, 0x99, - 0x04, 0x19, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x25, 0x11, 0x21, 0x11, - 0x07, 0x11, 0x21, 0x17, 0x11, 0x21, 0x04, 0x18, 0xfc, 0x5b, 0x3a, 0x04, - 0x19, 0x46, 0xfb, 0xfc, 0x3a, 0x03, 0xa4, 0xfc, 0x5c, 0x3b, 0x04, 0x19, - 0x5b, 0xfb, 0xfc, 0x00, 0x00, 0x02, 0x00, 0x30, 0x00, 0x00, 0x04, 0xa1, - 0x04, 0x71, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x25, 0x11, 0x21, 0x11, - 0x05, 0x21, 0x11, 0x37, 0x21, 0x11, 0x04, 0x1e, 0xfc, 0x4e, 0x03, 0xed, - 0xfb, 0xd7, 0x5d, 0x04, 0x14, 0x3c, 0x03, 0xb2, 0xfc, 0x4e, 0x3b, 0x04, - 0x29, 0x47, 0xfb, 0xed, 0x00, 0x04, 0x00, 0x2b, 0xff, 0xfa, 0x04, 0xa6, - 0x04, 0x74, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x00, - 0x13, 0x09, 0x0e, 0x2c, 0x01, 0x03, 0x01, 0x04, 0xfe, 0xfc, 0x01, 0x6f, - 0x01, 0x04, 0x01, 0x03, 0xfe, 0xfd, 0xfd, 0xc4, 0x01, 0x04, 0x01, 0x04, - 0xfe, 0xfc, 0xfe, 0xfc, 0x01, 0x04, 0x01, 0x04, 0xfe, 0xfc, 0x02, 0x39, - 0x01, 0x03, 0xfe, 0xfd, 0xfe, 0xfc, 0x01, 0x04, 0x01, 0x02, 0xfe, 0xfe, - 0xfe, 0xfb, 0x02, 0x3b, 0x01, 0x05, 0xfe, 0xfb, 0xfe, 0xfd, 0xfe, 0x92, - 0x01, 0x04, 0xfe, 0xfc, 0xfe, 0xfc, 0x00, 0x00, 0x00, 0x01, 0x02, 0x1b, - 0xff, 0x0c, 0x02, 0xb6, 0x05, 0x9c, 0x00, 0x03, 0x00, 0x00, 0x01, 0x11, - 0x23, 0x11, 0x02, 0xb6, 0x9b, 0x05, 0x9c, 0xf9, 0x71, 0x06, 0x8f, 0x00, - 0x00, 0x01, 0x01, 0xcd, 0xff, 0x0a, 0x03, 0x04, 0x05, 0x99, 0x00, 0x03, - 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x03, 0x03, 0xfe, 0xcb, 0x05, 0x99, - 0xf9, 0x72, 0x06, 0x8e, 0x00, 0x01, 0x01, 0x51, 0xfe, 0xcb, 0x03, 0x80, - 0x05, 0x6b, 0x00, 0x03, 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x03, 0x7f, - 0xfd, 0xd3, 0x05, 0x6b, 0xf9, 0x60, 0x06, 0xa0, 0x00, 0x01, 0x01, 0xdd, - 0x03, 0xcf, 0x02, 0xf4, 0x05, 0xd9, 0x00, 0x06, 0x00, 0x00, 0x01, 0x21, - 0x11, 0x37, 0x33, 0x07, 0x33, 0x02, 0xf4, 0xfe, 0xe9, 0x7d, 0x62, 0x3e, - 0x76, 0x03, 0xcf, 0x01, 0x17, 0xf3, 0xf3, 0x00, 0x00, 0x01, 0x01, 0xd3, - 0x03, 0xc4, 0x02, 0xfe, 0x05, 0xc7, 0x00, 0x06, 0x00, 0x00, 0x01, 0x21, - 0x11, 0x07, 0x23, 0x37, 0x23, 0x01, 0xd4, 0x01, 0x29, 0x85, 0x69, 0x43, - 0x7e, 0x05, 0xc6, 0xfe, 0xee, 0xef, 0xef, 0x00, 0xff, 0xff, 0x01, 0x00, - 0x03, 0xcf, 0x03, 0xd1, 0x05, 0xd9, 0x10, 0x27, 0x0b, 0x09, 0x00, 0xdd, - 0x00, 0x00, 0x10, 0x07, 0x0b, 0x09, 0xff, 0x23, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xf6, 0x03, 0xc4, 0x03, 0xdb, 0x05, 0xc7, 0x10, 0x27, - 0x0b, 0x0a, 0x00, 0xdd, 0x00, 0x00, 0x10, 0x07, 0x0b, 0x0a, 0xff, 0x23, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x67, 0xff, 0x5d, 0x04, 0x6a, - 0x05, 0x81, 0x00, 0x4f, 0x00, 0x53, 0x00, 0x00, 0x01, 0x32, 0x17, 0x16, - 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x14, 0x17, 0x16, 0x17, - 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x35, - 0x11, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x36, 0x3b, 0x01, 0x35, 0x37, - 0x15, 0x21, 0x07, 0x23, 0x11, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, - 0x37, 0x36, 0x37, 0x36, 0x25, 0x11, 0x23, 0x11, 0x01, 0xb9, 0x19, 0x15, - 0x16, 0x12, 0x11, 0x0a, 0x08, 0x08, 0x0a, 0x11, 0x12, 0x16, 0x15, 0x15, - 0x17, 0x10, 0x0f, 0x0d, 0x0e, 0x06, 0x07, 0x08, 0x08, 0x0d, 0x10, 0x0d, - 0x13, 0x1a, 0x34, 0x32, 0x3b, 0x25, 0x2d, 0x14, 0x16, 0xfa, 0xb4, 0x6e, - 0x60, 0xd4, 0xae, 0xfa, 0x72, 0x01, 0x15, 0x72, 0xa3, 0x1e, 0x23, 0x32, - 0x36, 0x41, 0x40, 0x3a, 0x56, 0x37, 0x3a, 0x24, 0x29, 0x12, 0x13, 0x13, - 0x15, 0x26, 0x1f, 0x37, 0x2e, 0x01, 0x59, 0x9b, 0x01, 0x71, 0x09, 0x0a, - 0x11, 0x10, 0x18, 0x16, 0x19, 0x18, 0x16, 0x18, 0x10, 0x11, 0x0a, 0x09, - 0x07, 0x06, 0x0d, 0x0d, 0x10, 0x10, 0x25, 0x11, 0x12, 0x0b, 0x0f, 0x05, - 0x07, 0x16, 0x1b, 0x24, 0x2e, 0x32, 0x37, 0x37, 0x01, 0x1d, 0x67, 0x5b, - 0x95, 0x9a, 0xbd, 0xa3, 0x28, 0xcb, 0x64, 0xfc, 0xa2, 0x56, 0x44, 0x51, - 0x34, 0x39, 0x1f, 0x1e, 0x14, 0x15, 0x25, 0x2a, 0x2c, 0x30, 0x34, 0x3f, - 0x28, 0x29, 0x2d, 0x23, 0x17, 0x14, 0xfa, 0x01, 0xe6, 0xfe, 0x1a, 0x00, - 0x00, 0x02, 0x00, 0xff, 0xff, 0xd9, 0x03, 0xd2, 0x04, 0xc9, 0x00, 0x17, - 0x00, 0x35, 0x00, 0x00, 0x01, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x06, 0x07, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, - 0x37, 0x36, 0x37, 0x36, 0x12, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x22, 0x27, 0x26, 0x27, - 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x02, 0x68, - 0x82, 0x63, 0x22, 0x24, 0x1f, 0x0f, 0x10, 0x6e, 0x91, 0x6a, 0x6c, 0x8e, - 0x6e, 0x10, 0x0f, 0x1f, 0x1e, 0x28, 0x4c, 0x66, 0x65, 0x2a, 0x2b, 0x24, - 0x24, 0x12, 0x11, 0x11, 0x12, 0x24, 0x24, 0x2b, 0x2a, 0x65, 0x2a, 0x2b, - 0x24, 0x25, 0x11, 0x11, 0x11, 0x11, 0x25, 0x24, 0x2b, 0x04, 0xc9, 0x21, - 0x0b, 0x23, 0x1f, 0x27, 0x28, 0x2a, 0x64, 0x52, 0x6a, 0xa8, 0xa8, 0x6a, - 0x53, 0x63, 0x2a, 0x28, 0x27, 0x1f, 0x1d, 0x11, 0x21, 0xfc, 0xf9, 0x12, - 0x14, 0x22, 0x25, 0x2a, 0x2c, 0x32, 0x30, 0x2c, 0x2b, 0x25, 0x22, 0x14, - 0x11, 0x11, 0x14, 0x22, 0x25, 0x2b, 0x2c, 0x30, 0x32, 0x2c, 0x2a, 0x25, - 0x22, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0xbe, 0xff, 0xe3, 0x04, 0x13, - 0x04, 0xd3, 0x00, 0x25, 0x00, 0x43, 0x00, 0x00, 0x01, 0x26, 0x27, 0x26, - 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x32, 0x17, 0x16, 0x17, - 0x16, 0x17, 0x16, 0x15, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x32, - 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x02, 0x32, - 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, - 0x07, 0x06, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, - 0x36, 0x37, 0x36, 0x37, 0x02, 0x68, 0x63, 0xd8, 0x6e, 0x10, 0x0f, 0x1f, - 0x1e, 0x28, 0x25, 0x58, 0x25, 0x26, 0x1f, 0x1e, 0x10, 0x10, 0x11, 0x10, - 0x1e, 0x1f, 0x26, 0x26, 0x57, 0x25, 0x28, 0x1e, 0x1f, 0x0f, 0x10, 0x6e, - 0xd8, 0x96, 0x65, 0x2a, 0x2b, 0x24, 0x24, 0x12, 0x11, 0x11, 0x12, 0x24, - 0x24, 0x2b, 0x2a, 0x65, 0x2a, 0x2b, 0x24, 0x25, 0x11, 0x11, 0x11, 0x11, - 0x25, 0x24, 0x2b, 0x02, 0x2c, 0x9f, 0x83, 0x44, 0x6a, 0x2a, 0x28, 0x27, - 0x1f, 0x1d, 0x11, 0x10, 0x10, 0x10, 0x1e, 0x1e, 0x28, 0x26, 0x2c, 0x2c, - 0x26, 0x28, 0x1e, 0x1e, 0x10, 0x10, 0x10, 0x11, 0x1d, 0x1f, 0x27, 0x28, - 0x2a, 0x6b, 0x43, 0x83, 0xff, 0x00, 0x11, 0x14, 0x22, 0x26, 0x2a, 0x2c, - 0x31, 0x31, 0x2c, 0x2a, 0x25, 0x23, 0x13, 0x12, 0x12, 0x13, 0x23, 0x25, - 0x2a, 0x2c, 0x31, 0x31, 0x2c, 0x2a, 0x26, 0x22, 0x14, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x2e, 0x00, 0x69, 0x04, 0xa3, 0x04, 0x0f, 0x00, 0x25, - 0x00, 0x00, 0x25, 0x26, 0x25, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, - 0x37, 0x36, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x34, 0x37, - 0x36, 0x37, 0x36, 0x37, 0x36, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x04, 0x02, 0x68, 0x68, 0xfe, 0xc3, 0x94, 0x15, 0x15, - 0x2a, 0x28, 0x34, 0x32, 0x75, 0x32, 0x34, 0x29, 0x28, 0x16, 0x15, 0x16, - 0x16, 0x28, 0x29, 0x34, 0x32, 0x75, 0x32, 0x34, 0x28, 0x2a, 0x15, 0x15, - 0x94, 0xfe, 0xc3, 0x69, 0xc2, 0xc5, 0x5c, 0x90, 0x3d, 0x39, 0x37, 0x2c, - 0x2a, 0x19, 0x17, 0x17, 0x18, 0x2b, 0x2a, 0x39, 0x36, 0x40, 0x40, 0x36, - 0x39, 0x2a, 0x2b, 0x18, 0x17, 0x17, 0x19, 0x2a, 0x2c, 0x37, 0x39, 0x3d, - 0x92, 0x5a, 0xc5, 0x00, 0x00, 0x01, 0x00, 0x72, 0xff, 0xfb, 0x04, 0x5f, - 0x05, 0x19, 0x00, 0x27, 0x00, 0x00, 0x01, 0x06, 0x03, 0x06, 0x23, 0x22, - 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, - 0x37, 0x36, 0x33, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x12, 0x04, 0x5f, - 0xd1, 0xd3, 0x64, 0x9c, 0x41, 0x3d, 0x3b, 0x30, 0x2d, 0x1a, 0x19, 0x19, - 0x18, 0x2f, 0x2e, 0x3d, 0x3a, 0x44, 0x44, 0x3a, 0x3d, 0x2e, 0x2f, 0x18, - 0x19, 0x19, 0x1a, 0x2d, 0x30, 0x3b, 0x3d, 0x41, 0x9e, 0x62, 0xd3, 0x02, - 0x8a, 0x78, 0xfe, 0x94, 0xaa, 0x18, 0x17, 0x31, 0x2e, 0x3d, 0x38, 0x44, - 0x43, 0x39, 0x3c, 0x2f, 0x2e, 0x1a, 0x18, 0x19, 0x18, 0x2f, 0x30, 0x3b, - 0x38, 0x45, 0x42, 0x3a, 0x3b, 0x2f, 0x30, 0x18, 0x19, 0xaa, 0xfe, 0x92, - 0x00, 0x02, 0x00, 0x41, 0x00, 0x19, 0x04, 0x90, 0x04, 0x89, 0x00, 0x0d, - 0x00, 0x69, 0x00, 0x00, 0x01, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, - 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x06, 0x07, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x15, 0x14, 0x33, 0x32, 0x37, 0x36, - 0x33, 0x32, 0x15, 0x14, 0x21, 0x22, 0x27, 0x26, 0x35, 0x10, 0x33, 0x32, - 0x17, 0x36, 0x37, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, - 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, - 0x36, 0x33, 0x32, 0x1f, 0x01, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, - 0x35, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, - 0x23, 0x22, 0x02, 0xc6, 0x08, 0x18, 0x13, 0x2c, 0x18, 0x13, 0x0f, 0x23, - 0x3c, 0x5a, 0x11, 0x25, 0x4c, 0x46, 0x65, 0x30, 0x24, 0xfb, 0x7c, 0x55, - 0x5e, 0x0e, 0x29, 0x2c, 0x33, 0xff, 0x00, 0xa6, 0x97, 0xa1, 0xd4, 0x53, - 0x42, 0x3f, 0x0d, 0x52, 0xbb, 0x38, 0x3c, 0x44, 0x33, 0x21, 0x23, 0x16, - 0x1d, 0x10, 0x1a, 0x14, 0x0c, 0x5e, 0x4c, 0x5f, 0x55, 0x28, 0x3d, 0x21, - 0x23, 0x3f, 0x3e, 0x28, 0x29, 0x0d, 0x31, 0x46, 0x3d, 0x22, 0x25, 0x11, - 0x22, 0x11, 0x19, 0x2e, 0x34, 0x22, 0x11, 0x74, 0x4e, 0x61, 0x35, 0x03, - 0x8c, 0x26, 0x24, 0x34, 0x21, 0x1b, 0x0f, 0x0c, 0x16, 0x2f, 0x1c, 0x2e, - 0x72, 0x3c, 0x40, 0x36, 0x42, 0x32, 0x4c, 0xb2, 0x5f, 0x30, 0x3e, 0x51, - 0x23, 0x6b, 0x49, 0x7f, 0x7c, 0x85, 0xce, 0x01, 0x22, 0x72, 0x7a, 0x37, - 0x26, 0x8b, 0x29, 0x3f, 0x29, 0x2c, 0x1e, 0x1f, 0x17, 0x13, 0x10, 0x17, - 0x25, 0x14, 0x3d, 0x5e, 0x4b, 0x3d, 0x1e, 0x2e, 0x43, 0x19, 0x1a, 0x32, - 0x36, 0x46, 0x40, 0x31, 0x0e, 0x1b, 0x1d, 0x19, 0x33, 0x0f, 0x1d, 0x11, - 0x2e, 0x16, 0x21, 0x39, 0x1b, 0x2b, 0x63, 0x4d, 0x33, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x31, 0x01, 0x33, 0x04, 0xa0, 0x03, 0xc6, 0x00, 0x07, - 0x00, 0x4e, 0x00, 0x00, 0x01, 0x06, 0x07, 0x06, 0x07, 0x36, 0x37, 0x36, - 0x01, 0x20, 0x35, 0x34, 0x37, 0x26, 0x27, 0x26, 0x07, 0x16, 0x07, 0x06, - 0x07, 0x16, 0x33, 0x32, 0x37, 0x16, 0x15, 0x14, 0x23, 0x22, 0x27, 0x23, - 0x35, 0x33, 0x36, 0x37, 0x36, 0x37, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, - 0x34, 0x33, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x32, 0x17, 0x16, 0x17, - 0x26, 0x35, 0x34, 0x37, 0x36, 0x33, 0x32, 0x13, 0x16, 0x33, 0x32, 0x35, - 0x34, 0x27, 0x26, 0x35, 0x34, 0x33, 0x32, 0x15, 0x14, 0x07, 0x06, 0x01, - 0x35, 0x33, 0x25, 0x35, 0x16, 0x40, 0x32, 0x36, 0x01, 0x9a, 0xfe, 0xd1, - 0x60, 0x27, 0x2c, 0x20, 0x20, 0x02, 0x3d, 0x4e, 0x52, 0x15, 0x36, 0x23, - 0x21, 0x06, 0x76, 0x57, 0x10, 0x1d, 0x1f, 0x19, 0x52, 0x3e, 0x34, 0x0d, - 0x1d, 0x1c, 0x32, 0x3a, 0x4f, 0x09, 0x74, 0x35, 0x04, 0x31, 0x22, 0x22, - 0x2e, 0x19, 0x31, 0x26, 0x58, 0xb0, 0x2e, 0x14, 0x52, 0x4f, 0x09, 0x09, - 0x41, 0x35, 0xc8, 0x8f, 0x02, 0xbd, 0x0b, 0x1e, 0x29, 0x54, 0x18, 0x2f, - 0x31, 0xfe, 0xa5, 0xce, 0x38, 0x36, 0x2c, 0x17, 0x11, 0x01, 0x46, 0x41, - 0x53, 0x0c, 0x3a, 0x23, 0x18, 0x28, 0x3d, 0x8b, 0x3a, 0x74, 0x41, 0x30, - 0x02, 0x0f, 0x0e, 0x0f, 0x0b, 0x0e, 0x39, 0x53, 0x18, 0x1c, 0x1f, 0x44, - 0x20, 0x14, 0x10, 0x10, 0x27, 0x41, 0x23, 0x35, 0x1f, 0x18, 0xfe, 0xd7, - 0x7d, 0x31, 0x18, 0x0f, 0x0e, 0x16, 0x31, 0x42, 0x8d, 0x4f, 0x39, 0x00, - 0x00, 0x01, 0x00, 0xf0, 0xff, 0x9b, 0x03, 0xe1, 0x05, 0x82, 0x00, 0x20, - 0x00, 0x00, 0x05, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x15, 0x22, 0x07, 0x0e, 0x01, - 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x33, 0x03, - 0xe1, 0x97, 0x8a, 0x83, 0x70, 0x6d, 0x38, 0x38, 0x38, 0x34, 0x71, 0x6c, - 0x87, 0x8a, 0x97, 0x59, 0x54, 0x4e, 0x87, 0x21, 0x20, 0x20, 0x21, 0x43, - 0x40, 0x52, 0x50, 0x5d, 0x65, 0x3a, 0x36, 0x70, 0x6c, 0x87, 0x86, 0x98, - 0x99, 0x89, 0x80, 0x74, 0x6d, 0x39, 0x3a, 0x27, 0x36, 0x32, 0xd5, 0x7e, - 0x7f, 0x95, 0x90, 0x7f, 0x7e, 0x6a, 0x66, 0x37, 0x37, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xf0, 0xff, 0x9b, 0x03, 0xe1, 0x05, 0x82, 0x00, 0x22, - 0x00, 0x00, 0x17, 0x30, 0x35, 0x32, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, - 0x35, 0x34, 0x27, 0x2e, 0x01, 0x27, 0x26, 0x23, 0x30, 0x35, 0x32, 0x17, - 0x16, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, - 0x06, 0xf0, 0x5d, 0x50, 0x52, 0x40, 0x43, 0x21, 0x20, 0x20, 0x21, 0x87, - 0x4e, 0x54, 0x59, 0x97, 0x8a, 0x87, 0x6c, 0x71, 0x34, 0x38, 0x38, 0x38, - 0x6d, 0x70, 0x83, 0x8a, 0x65, 0x27, 0x36, 0x37, 0x66, 0x6a, 0x7e, 0x7f, - 0x90, 0x95, 0x7f, 0x7e, 0xd5, 0x32, 0x37, 0x26, 0x3a, 0x39, 0x6d, 0x74, - 0x7f, 0x8a, 0x99, 0x98, 0x85, 0x88, 0x6c, 0x6f, 0x37, 0x3a, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x66, 0xff, 0x87, 0x03, 0x6b, 0x05, 0x52, 0x00, 0x0c, - 0x00, 0x00, 0x01, 0x06, 0x02, 0x10, 0x12, 0x17, 0x21, 0x26, 0x02, 0x35, - 0x34, 0x12, 0x37, 0x03, 0x6a, 0x6c, 0x6a, 0x6a, 0x6c, 0xfe, 0xef, 0x79, - 0x79, 0x78, 0x7a, 0x05, 0x51, 0xbb, 0xfe, 0x93, 0xfe, 0x89, 0xfe, 0x8f, - 0xba, 0xbf, 0x01, 0x71, 0xb6, 0xb5, 0x01, 0x70, 0xbf, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x6e, 0xff, 0x87, 0x03, 0x63, 0x05, 0x24, 0x00, 0x0f, - 0x00, 0x00, 0x01, 0x30, 0x21, 0x16, 0x12, 0x15, 0x14, 0x07, 0x06, 0x07, - 0x21, 0x36, 0x37, 0x36, 0x10, 0x02, 0x01, 0x6e, 0x01, 0x09, 0x77, 0x75, - 0x3b, 0x3b, 0x76, 0xfe, 0xf7, 0x69, 0x34, 0x33, 0x66, 0x05, 0x24, 0xba, - 0xfe, 0x9c, 0xb0, 0xb0, 0xb3, 0xb3, 0xb9, 0xb5, 0xb2, 0xb2, 0x01, 0x6c, - 0x01, 0x63, 0x00, 0x00, 0x00, 0x01, 0x01, 0x43, 0xff, 0x7d, 0x03, 0x8e, - 0x05, 0x55, 0x00, 0x05, 0x00, 0x00, 0x05, 0x23, 0x09, 0x01, 0x33, 0x01, - 0x03, 0x8d, 0xd5, 0xfe, 0x8c, 0x01, 0x74, 0xd5, 0xfe, 0x8a, 0x82, 0x02, - 0xeb, 0x02, 0xec, 0xfd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x44, - 0xff, 0x7d, 0x03, 0x8d, 0x05, 0x55, 0x00, 0x05, 0x00, 0x00, 0x05, 0x09, - 0x01, 0x33, 0x09, 0x01, 0x01, 0x44, 0x01, 0x75, 0xfe, 0x8c, 0xd4, 0x01, - 0x74, 0xfe, 0x8c, 0x82, 0x02, 0xeb, 0x02, 0xec, 0xfd, 0x14, 0xfd, 0x15, - 0x00, 0x01, 0x00, 0xd2, 0xff, 0x56, 0x03, 0xff, 0x05, 0x2e, 0x00, 0x05, - 0x00, 0x00, 0x05, 0x21, 0x09, 0x01, 0x21, 0x01, 0x03, 0xfe, 0xfe, 0xb6, - 0xfe, 0x1f, 0x01, 0xe1, 0x01, 0x4a, 0xfe, 0x16, 0xa9, 0x02, 0xeb, 0x02, - 0xec, 0xfd, 0x14, 0x00, 0x00, 0x01, 0x00, 0xd2, 0xff, 0x56, 0x03, 0xff, - 0x05, 0x2e, 0x00, 0x05, 0x00, 0x00, 0x17, 0x09, 0x01, 0x21, 0x09, 0x01, - 0xd3, 0x01, 0xea, 0xfe, 0x16, 0x01, 0x4a, 0x01, 0xe1, 0xfe, 0x1f, 0xa9, - 0x02, 0xeb, 0x02, 0xec, 0xfd, 0x14, 0xfd, 0x15, 0x00, 0x01, 0x00, 0xcd, - 0xff, 0x41, 0x04, 0x04, 0x05, 0xd1, 0x00, 0x05, 0x00, 0x00, 0x05, 0x21, - 0x09, 0x01, 0x21, 0x01, 0x04, 0x03, 0xfe, 0x6d, 0xfe, 0x5e, 0x01, 0xa2, - 0x01, 0x93, 0xfe, 0x5c, 0xbe, 0x03, 0x47, 0x03, 0x48, 0xfc, 0xb8, 0x00, - 0x00, 0x01, 0x00, 0xce, 0xff, 0x42, 0x04, 0x03, 0x05, 0xd2, 0x00, 0x05, - 0x00, 0x00, 0x17, 0x09, 0x01, 0x21, 0x09, 0x01, 0xce, 0x01, 0xa3, 0xfe, - 0x5e, 0x01, 0x92, 0x01, 0xa2, 0xfe, 0x5e, 0xbe, 0x03, 0x48, 0x03, 0x48, - 0xfc, 0xb8, 0xfc, 0xb8, 0x00, 0x01, 0x01, 0xc9, 0xfe, 0xe5, 0x03, 0x08, - 0x05, 0x76, 0x00, 0x07, 0x00, 0x00, 0x21, 0x17, 0x07, 0x27, 0x11, 0x37, - 0x17, 0x07, 0x02, 0x44, 0xc4, 0x57, 0xe8, 0xe8, 0x57, 0xc4, 0xc3, 0x57, - 0xe7, 0x04, 0xc2, 0xe7, 0x57, 0xc3, 0x00, 0x00, 0x00, 0x01, 0x01, 0xc9, - 0xfe, 0xeb, 0x03, 0x08, 0x05, 0x7c, 0x00, 0x07, 0x00, 0x00, 0x01, 0x27, - 0x37, 0x17, 0x11, 0x07, 0x27, 0x37, 0x02, 0x8d, 0xc4, 0x57, 0xe8, 0xe8, - 0x57, 0xc4, 0x04, 0x62, 0xc3, 0x57, 0xe7, 0xfb, 0x3e, 0xe7, 0x57, 0xc3, - 0x00, 0x01, 0x01, 0x19, 0xfe, 0xb8, 0x03, 0xb8, 0x05, 0x5e, 0x00, 0x24, - 0x00, 0x00, 0x05, 0x15, 0x23, 0x22, 0x26, 0x3d, 0x01, 0x34, 0x26, 0x2b, - 0x01, 0x35, 0x33, 0x32, 0x36, 0x3d, 0x01, 0x34, 0x36, 0x3b, 0x01, 0x15, - 0x23, 0x22, 0x06, 0x1d, 0x01, 0x14, 0x06, 0x07, 0x1e, 0x01, 0x1d, 0x01, - 0x14, 0x16, 0x33, 0x03, 0xb8, 0x97, 0xb2, 0x78, 0x4d, 0x65, 0x2c, 0x2c, - 0x66, 0x4c, 0x78, 0xb2, 0x97, 0x31, 0x64, 0x3d, 0x41, 0x4f, 0x4f, 0x41, - 0x3d, 0x64, 0xc6, 0x82, 0x85, 0xc7, 0xd7, 0x88, 0x69, 0x80, 0x68, 0x86, - 0xd8, 0xc7, 0x84, 0x81, 0x4f, 0x7f, 0xdf, 0x8d, 0x80, 0x17, 0x18, 0x80, - 0x8c, 0xdf, 0x7f, 0x4f, 0x00, 0x01, 0x00, 0xf9, 0xfe, 0xb0, 0x03, 0xd8, - 0x05, 0x69, 0x00, 0x28, 0x00, 0x00, 0x17, 0x33, 0x32, 0x36, 0x3d, 0x01, - 0x34, 0x36, 0x37, 0x26, 0x27, 0x26, 0x3d, 0x01, 0x34, 0x26, 0x2b, 0x01, - 0x35, 0x33, 0x32, 0x17, 0x16, 0x1d, 0x01, 0x14, 0x17, 0x16, 0x3b, 0x01, - 0x15, 0x23, 0x22, 0x06, 0x1d, 0x01, 0x14, 0x07, 0x06, 0x2b, 0x01, 0xfa, - 0x35, 0x6e, 0x43, 0x46, 0x56, 0x55, 0x24, 0x23, 0x43, 0x6e, 0x35, 0xa5, - 0xc2, 0x42, 0x42, 0x2a, 0x29, 0x70, 0x2f, 0x2f, 0x6f, 0x54, 0x42, 0x42, - 0xc2, 0xa5, 0xcc, 0x50, 0x80, 0xe2, 0x8e, 0x81, 0x19, 0x16, 0x41, 0x41, - 0x8f, 0xe1, 0x81, 0x50, 0x82, 0x44, 0x42, 0xc9, 0xdb, 0x87, 0x34, 0x35, - 0x82, 0x69, 0x8a, 0xd9, 0xc9, 0x44, 0x43, 0x00, 0x00, 0x01, 0x00, 0x53, - 0x01, 0x2f, 0x04, 0x7e, 0x03, 0xe5, 0x00, 0x08, 0x00, 0x00, 0x09, 0x01, - 0x23, 0x01, 0x21, 0x35, 0x21, 0x01, 0x33, 0x04, 0x7d, 0xfe, 0xa5, 0xe3, - 0x01, 0x06, 0xfd, 0x0f, 0x02, 0xf1, 0xfe, 0xfa, 0xe3, 0x02, 0x8a, 0xfe, - 0xa5, 0x01, 0x06, 0xaa, 0x01, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x74, - 0x00, 0x92, 0x04, 0x5d, 0x04, 0x7d, 0x00, 0x06, 0x00, 0x00, 0x09, 0x01, - 0x37, 0x01, 0x1b, 0x01, 0x25, 0x03, 0x10, 0xfd, 0x64, 0x94, 0x02, 0x5e, - 0xba, 0x3d, 0xfd, 0xa4, 0x01, 0x8a, 0x02, 0x5d, 0x95, 0xfd, 0x64, 0x01, - 0x0e, 0xfd, 0xa4, 0x3e, 0x00, 0x01, 0x00, 0x53, 0x01, 0xa2, 0x04, 0x7e, - 0x04, 0x12, 0x00, 0x06, 0x00, 0x00, 0x01, 0x05, 0x35, 0x05, 0x03, 0x09, - 0x01, 0x03, 0x2f, 0xfd, 0x25, 0x02, 0xdb, 0x30, 0x01, 0x7e, 0xfe, 0x82, - 0x02, 0xa8, 0x23, 0xaa, 0x23, 0x01, 0x05, 0xfe, 0xc9, 0xfe, 0xc9, 0x00, - 0x00, 0x01, 0x00, 0x74, 0x00, 0xc1, 0x04, 0x5d, 0x04, 0xab, 0x00, 0x06, - 0x00, 0x00, 0x09, 0x01, 0x27, 0x01, 0x2d, 0x01, 0x03, 0x03, 0x66, 0xfd, - 0xa2, 0x94, 0x02, 0x9c, 0xfe, 0xf1, 0x02, 0x5c, 0x3d, 0x03, 0x5d, 0xfd, - 0x64, 0x95, 0x02, 0x5d, 0xba, 0x3e, 0xfd, 0xa4, 0x00, 0x01, 0x00, 0x2d, - 0x01, 0xa1, 0x04, 0xa4, 0x03, 0xe1, 0x00, 0x08, 0x00, 0x00, 0x13, 0x21, - 0x27, 0x04, 0x05, 0x04, 0x05, 0x37, 0x21, 0x2e, 0x02, 0x14, 0x80, 0x01, - 0x09, 0x01, 0xd8, 0xfe, 0x28, 0xfe, 0xf7, 0x80, 0xfd, 0xec, 0x02, 0xef, - 0xf2, 0xc0, 0x60, 0x60, 0xc0, 0xf2, 0x00, 0x00, 0x00, 0x01, 0x00, 0x49, - 0x01, 0x29, 0x04, 0x88, 0x04, 0x3d, 0x00, 0x32, 0x00, 0x00, 0x00, 0x14, - 0x07, 0x06, 0x07, 0x01, 0x06, 0x07, 0x06, 0x22, 0x26, 0x27, 0x26, 0x27, - 0x26, 0x35, 0x34, 0x37, 0x36, 0x3f, 0x01, 0x21, 0x22, 0x2e, 0x01, 0x27, - 0x26, 0x34, 0x37, 0x3e, 0x02, 0x33, 0x21, 0x27, 0x26, 0x27, 0x26, 0x35, - 0x34, 0x37, 0x36, 0x37, 0x3e, 0x01, 0x32, 0x17, 0x16, 0x17, 0x01, 0x16, - 0x04, 0x88, 0x07, 0x09, 0x0c, 0xfe, 0xd4, 0x0c, 0x12, 0x11, 0x27, 0x21, - 0x0d, 0x0e, 0x07, 0x07, 0x07, 0x08, 0x0d, 0x8b, 0xfd, 0x60, 0x13, 0x21, - 0x1b, 0x08, 0x06, 0x06, 0x08, 0x1b, 0x21, 0x13, 0x02, 0xa0, 0x8b, 0x0d, - 0x08, 0x07, 0x07, 0x07, 0x0e, 0x0d, 0x21, 0x27, 0x11, 0x12, 0x0c, 0x01, - 0x2c, 0x0e, 0x02, 0xc6, 0x26, 0x10, 0x12, 0x0d, 0xfe, 0xd4, 0x0c, 0x08, - 0x07, 0x0e, 0x0d, 0x0f, 0x10, 0x10, 0x13, 0x14, 0x10, 0x12, 0x0d, 0x8c, - 0x0e, 0x1a, 0x12, 0x10, 0x26, 0x10, 0x12, 0x1a, 0x0f, 0x8b, 0x0d, 0x12, - 0x11, 0x13, 0x13, 0x10, 0x11, 0x0e, 0x0d, 0x0f, 0x07, 0x09, 0x0c, 0xfe, - 0xd4, 0x0e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x53, 0x01, 0xb6, 0x04, 0x7e, - 0x04, 0x26, 0x00, 0x06, 0x00, 0x00, 0x01, 0x21, 0x35, 0x21, 0x11, 0x09, - 0x01, 0x03, 0x46, 0xfd, 0x0e, 0x02, 0xf2, 0x01, 0x37, 0xfe, 0xc9, 0x02, - 0xd2, 0x38, 0x01, 0x1b, 0xfe, 0xc9, 0xfe, 0xc9, 0x00, 0x01, 0x00, 0x2d, - 0x01, 0x78, 0x04, 0xa4, 0x04, 0x14, 0x00, 0x06, 0x00, 0x00, 0x01, 0x21, - 0x35, 0x21, 0x35, 0x09, 0x01, 0x03, 0x56, 0xfc, 0xd8, 0x03, 0x28, 0x01, - 0x4d, 0xfe, 0xb3, 0x02, 0x72, 0xa8, 0xfa, 0xfe, 0xb2, 0xfe, 0xb2, 0x00, - 0x00, 0x04, 0x00, 0x36, 0x01, 0x75, 0x04, 0x9b, 0x04, 0x06, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x0b, 0x00, 0x12, 0x00, 0x00, 0x01, 0x23, 0x11, 0x33, - 0x03, 0x23, 0x11, 0x33, 0x03, 0x23, 0x11, 0x33, 0x01, 0x21, 0x11, 0x21, - 0x35, 0x09, 0x01, 0x01, 0xe9, 0xb4, 0xb4, 0xf0, 0x5a, 0x5a, 0x96, 0x2d, - 0x2d, 0x02, 0xef, 0xfe, 0xd3, 0x01, 0x2d, 0x01, 0x49, 0xfe, 0xb7, 0x02, - 0x28, 0x01, 0x2c, 0xfe, 0xd4, 0x01, 0x2c, 0xfe, 0xd4, 0x01, 0x2c, 0xfe, - 0xd4, 0x01, 0x2c, 0xb2, 0xfe, 0xb8, 0xfe, 0xb7, 0x00, 0x04, 0x00, 0x53, - 0x01, 0x9c, 0x04, 0x7e, 0x04, 0x0b, 0x00, 0x08, 0x00, 0x0c, 0x00, 0x10, - 0x00, 0x14, 0x00, 0x00, 0x01, 0x35, 0x16, 0x17, 0x06, 0x07, 0x35, 0x21, - 0x11, 0x03, 0x23, 0x11, 0x33, 0x03, 0x23, 0x11, 0x33, 0x03, 0x23, 0x11, - 0x33, 0x03, 0x46, 0x83, 0xb4, 0xb4, 0x83, 0xfe, 0xe3, 0x39, 0xab, 0xab, - 0xe4, 0x55, 0x55, 0x8e, 0x2a, 0x2a, 0x03, 0xa9, 0x62, 0xda, 0x5d, 0x5e, - 0xda, 0x62, 0x01, 0xab, 0xfe, 0x55, 0x01, 0xab, 0xfe, 0x55, 0x01, 0xab, - 0xfe, 0x55, 0x01, 0xab, 0x00, 0x01, 0x00, 0x53, 0x01, 0x84, 0x04, 0x7e, - 0x03, 0xf4, 0x00, 0x06, 0x00, 0x00, 0x01, 0x21, 0x11, 0x21, 0x35, 0x09, - 0x01, 0x03, 0x46, 0xfd, 0x0e, 0x02, 0xf2, 0x01, 0x37, 0xfe, 0xc9, 0x02, - 0x2e, 0x01, 0x1c, 0xa9, 0xfe, 0xc9, 0xfe, 0xc9, 0x00, 0x02, 0x00, 0x60, - 0x01, 0x74, 0x04, 0x71, 0x04, 0x18, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, - 0x01, 0x21, 0x25, 0x17, 0x09, 0x02, 0x02, 0x0c, 0x01, 0xa8, 0xfd, 0x8d, - 0x71, 0xfe, 0xae, 0x04, 0x11, 0xfb, 0xef, 0x02, 0xc6, 0xcb, 0xcb, 0x01, - 0x52, 0xfe, 0xae, 0xfe, 0xae, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x7b, - 0x01, 0xa4, 0x04, 0x56, 0x04, 0x24, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, - 0x01, 0x07, 0x25, 0x21, 0x09, 0x02, 0x02, 0x10, 0xc0, 0x02, 0x53, 0xfe, - 0x18, 0xfe, 0xc0, 0x03, 0xdb, 0xfc, 0x25, 0x02, 0xe4, 0xc1, 0xc1, 0x01, - 0x40, 0xfe, 0xc0, 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x7b, - 0x01, 0x1f, 0x04, 0x56, 0x04, 0xbd, 0x00, 0x03, 0x00, 0x00, 0x01, 0x03, - 0x09, 0x01, 0x01, 0x74, 0xf9, 0x03, 0xdb, 0xfc, 0x25, 0x02, 0xee, 0x01, - 0xce, 0xfe, 0x32, 0xfe, 0x32, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x36, - 0x01, 0x8c, 0x04, 0x9b, 0x04, 0x3d, 0x00, 0x16, 0x00, 0x00, 0x13, 0x11, - 0x14, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x33, 0x21, 0x35, 0x09, 0x01, - 0x35, 0x21, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x36, 0x0e, 0x0d, - 0x1b, 0x1a, 0x20, 0x20, 0x24, 0x02, 0x68, 0x01, 0x49, 0xfe, 0xb7, 0xfd, - 0x98, 0x24, 0x20, 0x20, 0x1a, 0x1b, 0x0d, 0x0e, 0x02, 0xd5, 0x01, 0x68, - 0x24, 0x20, 0x20, 0x1b, 0x19, 0x0f, 0x0d, 0x95, 0xfe, 0xb7, 0xfe, 0xb7, - 0x95, 0x0d, 0x0f, 0x19, 0x1b, 0x20, 0x20, 0x00, 0x00, 0x01, 0x00, 0x36, - 0x01, 0x8b, 0x04, 0x9b, 0x04, 0x3c, 0x00, 0x16, 0x00, 0x00, 0x13, 0x34, - 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x21, 0x35, 0x09, 0x01, 0x35, - 0x21, 0x22, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x36, 0x0e, 0x0d, - 0x1b, 0x1a, 0x20, 0x20, 0x24, 0x02, 0x68, 0x01, 0x49, 0xfe, 0xb7, 0xfd, - 0x98, 0x24, 0x20, 0x20, 0x1a, 0x1b, 0x0d, 0x0e, 0x02, 0xf3, 0x24, 0x20, - 0x20, 0x1b, 0x19, 0x0f, 0x0d, 0x95, 0xfe, 0xb7, 0xfe, 0xb7, 0x95, 0x0d, - 0x0f, 0x19, 0x1b, 0x20, 0x20, 0x24, 0x00, 0x00, 0x00, 0x01, 0x01, 0x4f, - 0x01, 0x06, 0x03, 0x82, 0x04, 0xe0, 0x00, 0x06, 0x00, 0x00, 0x01, 0x21, - 0x11, 0x21, 0x11, 0x09, 0x01, 0x02, 0x65, 0xfe, 0xeb, 0x01, 0x15, 0x01, - 0x1c, 0xfe, 0xe4, 0x02, 0x12, 0x01, 0xc2, 0x01, 0x0c, 0xfe, 0x13, 0xfe, - 0x13, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x36, 0x01, 0x6e, 0x04, 0x9b, - 0x04, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, 0x35, 0x16, 0x05, 0x04, 0x07, - 0x35, 0x21, 0x11, 0x02, 0xe2, 0x6c, 0x01, 0x4d, 0xfe, 0xb3, 0x6c, 0xfd, - 0x54, 0x03, 0x89, 0x77, 0xe6, 0x63, 0x63, 0xe6, 0x77, 0x01, 0xa4, 0x00, - 0x00, 0x02, 0x00, 0x65, 0x01, 0x6b, 0x04, 0x6c, 0x04, 0x21, 0x00, 0x08, - 0x00, 0x0f, 0x00, 0x00, 0x01, 0x35, 0x21, 0x11, 0x21, 0x35, 0x33, 0x09, - 0x01, 0x27, 0x15, 0x09, 0x01, 0x15, 0x21, 0x15, 0x02, 0x5f, 0xfe, 0x06, - 0x01, 0xfa, 0xb2, 0x01, 0x5b, 0xfe, 0xa5, 0x79, 0x01, 0x22, 0xfe, 0xde, - 0xfe, 0x06, 0x01, 0x6b, 0xa9, 0x01, 0x64, 0xa9, 0xfe, 0xa5, 0xfe, 0xa5, - 0xe2, 0xa9, 0x01, 0x22, 0x01, 0x22, 0xa9, 0xf2, 0x00, 0x02, 0x00, 0x65, - 0x01, 0x2f, 0x04, 0x6c, 0x03, 0xe5, 0x00, 0x08, 0x00, 0x0f, 0x00, 0x00, - 0x01, 0x35, 0x21, 0x11, 0x21, 0x35, 0x33, 0x09, 0x01, 0x27, 0x15, 0x09, - 0x01, 0x15, 0x21, 0x15, 0x02, 0x5f, 0xfe, 0x06, 0x01, 0xfa, 0xb2, 0x01, - 0x5b, 0xfe, 0xa5, 0x0f, 0x01, 0x22, 0xfe, 0xde, 0xfe, 0x07, 0x01, 0x2f, - 0xa9, 0x01, 0x64, 0xa9, 0xfe, 0xa5, 0xfe, 0xa5, 0xe2, 0xa9, 0x01, 0x22, - 0x01, 0x22, 0xa9, 0xf2, 0x00, 0x02, 0x00, 0x35, 0x00, 0xb7, 0x04, 0x9c, - 0x03, 0xfc, 0x00, 0x0b, 0x00, 0x12, 0x00, 0x00, 0x1b, 0x01, 0x21, 0x37, - 0x33, 0x13, 0x15, 0x01, 0x23, 0x35, 0x37, 0x21, 0x25, 0x07, 0x01, 0x03, - 0x07, 0x21, 0x07, 0x36, 0xcd, 0x02, 0x55, 0x63, 0x47, 0x99, 0xfd, 0xf9, - 0x6a, 0x0f, 0xfd, 0xfd, 0x02, 0xb6, 0x62, 0x01, 0xca, 0x7a, 0x62, 0xfd, - 0xaa, 0x8c, 0x01, 0xef, 0x01, 0x64, 0xa9, 0xfe, 0x93, 0x8f, 0xfe, 0xb8, - 0x8e, 0x1b, 0xc7, 0xa9, 0x01, 0x22, 0x01, 0x22, 0xa9, 0xf2, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x61, 0x00, 0xd6, 0x04, 0x70, 0x03, 0xab, 0x00, 0x0b, - 0x00, 0x12, 0x00, 0x00, 0x13, 0x35, 0x21, 0x27, 0x35, 0x33, 0x01, 0x15, - 0x03, 0x23, 0x27, 0x21, 0x01, 0x21, 0x17, 0x21, 0x17, 0x37, 0x25, 0x61, - 0x01, 0xdc, 0x0f, 0x63, 0x01, 0xdf, 0x8e, 0x41, 0x5b, 0xfd, 0xd8, 0x01, - 0xc4, 0xfd, 0xd8, 0x81, 0x02, 0x28, 0x5a, 0x71, 0xfe, 0x5a, 0x02, 0x9d, - 0x7b, 0x17, 0x7b, 0xfe, 0xe4, 0x7b, 0xfe, 0xc4, 0x92, 0x01, 0x03, 0xd2, - 0x92, 0xfb, 0xfb, 0x00, 0x00, 0x02, 0x00, 0x7d, 0x00, 0xdb, 0x04, 0x54, - 0x04, 0x4d, 0x00, 0x0a, 0x00, 0x11, 0x00, 0x00, 0x25, 0x27, 0x21, 0x27, - 0x11, 0x21, 0x35, 0x33, 0x01, 0x17, 0x01, 0x03, 0x15, 0x09, 0x01, 0x15, - 0x21, 0x11, 0x02, 0x93, 0x3b, 0xfe, 0x71, 0x4b, 0x01, 0xca, 0x52, 0x01, - 0x6e, 0x4b, 0xfe, 0x92, 0x61, 0x01, 0x32, 0xfe, 0xce, 0xfe, 0x36, 0xdb, - 0x77, 0x96, 0x01, 0xee, 0x77, 0xfe, 0x92, 0x96, 0xfe, 0x92, 0x01, 0x49, - 0x77, 0x01, 0x32, 0x01, 0x32, 0x77, 0xfe, 0x8a, 0x00, 0x02, 0x00, 0x54, - 0x00, 0x82, 0x04, 0x7d, 0x04, 0x3e, 0x00, 0x0a, 0x00, 0x11, 0x00, 0x00, - 0x01, 0x33, 0x01, 0x07, 0x01, 0x23, 0x35, 0x21, 0x11, 0x37, 0x21, 0x17, - 0x21, 0x11, 0x21, 0x15, 0x09, 0x01, 0x02, 0x96, 0x5a, 0x01, 0x8c, 0x51, - 0xfe, 0x74, 0x5a, 0xfe, 0x10, 0x51, 0x01, 0xb0, 0x30, 0xfe, 0x10, 0x01, - 0xf0, 0x01, 0x4c, 0xfe, 0xb4, 0x04, 0x3e, 0xfe, 0x73, 0xa2, 0xfe, 0x73, - 0x81, 0x02, 0x18, 0xa3, 0xe4, 0xfe, 0x6a, 0x81, 0x01, 0x4c, 0x01, 0x4b, - 0x00, 0x02, 0x00, 0x32, 0x01, 0x4e, 0x04, 0x9f, 0x04, 0x75, 0x00, 0x0c, - 0x00, 0x14, 0x00, 0x00, 0x13, 0x27, 0x21, 0x35, 0x33, 0x01, 0x17, 0x01, - 0x23, 0x27, 0x35, 0x21, 0x27, 0x37, 0x07, 0x21, 0x15, 0x09, 0x01, 0x15, - 0x21, 0xa3, 0x70, 0x02, 0x85, 0x53, 0x01, 0x6e, 0x25, 0xfe, 0x92, 0x52, - 0x26, 0xfd, 0xa0, 0x25, 0xb5, 0x55, 0x02, 0x61, 0x01, 0x32, 0xfe, 0xce, - 0xfd, 0x9f, 0x03, 0x07, 0xf7, 0x77, 0xfe, 0x92, 0x4b, 0xfe, 0x92, 0x4a, - 0x2c, 0x4c, 0xf7, 0xbb, 0x77, 0x01, 0x32, 0x01, 0x32, 0x77, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x29, 0x00, 0xfd, 0x04, 0xa8, 0x04, 0x31, 0x00, 0x0c, - 0x00, 0x14, 0x00, 0x00, 0x13, 0x27, 0x37, 0x21, 0x35, 0x37, 0x33, 0x01, - 0x07, 0x01, 0x23, 0x35, 0x21, 0x37, 0x07, 0x21, 0x15, 0x09, 0x01, 0x15, - 0x21, 0x9c, 0x72, 0x26, 0x02, 0x6a, 0x26, 0x53, 0x01, 0x74, 0x26, 0xfe, - 0x8c, 0x53, 0xfd, 0x70, 0xb8, 0x57, 0x02, 0x6c, 0x01, 0x36, 0xfe, 0xca, - 0xfd, 0x94, 0x02, 0x71, 0xfb, 0x4d, 0x2c, 0x4c, 0xfe, 0x8c, 0x4c, 0xfe, - 0x8c, 0x79, 0xfb, 0xbe, 0x79, 0x01, 0x37, 0x01, 0x37, 0x79, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x91, 0x00, 0xbd, 0x04, 0x40, 0x04, 0xac, 0x00, 0x21, - 0x00, 0x00, 0x13, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x21, 0x15, 0x09, 0x01, 0x15, - 0x91, 0x20, 0x36, 0x49, 0x59, 0x5a, 0x67, 0x62, 0x5e, 0x55, 0x4d, 0x49, - 0x25, 0x26, 0x26, 0x22, 0x4c, 0x46, 0x5c, 0x5a, 0x66, 0x63, 0x5e, 0x55, - 0x4d, 0x33, 0x21, 0x01, 0xe7, 0x01, 0x74, 0xfe, 0x8c, 0x03, 0xa7, 0x3a, - 0x36, 0x49, 0x26, 0x26, 0x26, 0x23, 0x4c, 0x48, 0x5a, 0x5a, 0x68, 0x63, - 0x5c, 0x55, 0x4d, 0x48, 0x27, 0x26, 0x26, 0x23, 0x4c, 0x32, 0x3c, 0x81, - 0x01, 0x74, 0x01, 0x74, 0x80, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x58, - 0x01, 0x4e, 0x04, 0x79, 0x03, 0x16, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, - 0x00, 0x0f, 0x00, 0x1e, 0x00, 0x22, 0x00, 0x26, 0x00, 0x2a, 0x00, 0x2e, - 0x00, 0x00, 0x01, 0x07, 0x33, 0x37, 0x23, 0x07, 0x33, 0x37, 0x23, 0x07, - 0x33, 0x37, 0x23, 0x07, 0x33, 0x37, 0x23, 0x35, 0x27, 0x21, 0x17, 0x21, - 0x35, 0x16, 0x17, 0x06, 0x07, 0x35, 0x21, 0x07, 0x21, 0x01, 0x33, 0x27, - 0x23, 0x17, 0x33, 0x27, 0x23, 0x17, 0x33, 0x27, 0x23, 0x17, 0x33, 0x27, - 0x23, 0x02, 0x08, 0x72, 0x2b, 0x71, 0x7f, 0x72, 0x2a, 0x72, 0x80, 0x72, - 0x2b, 0x72, 0x80, 0x72, 0x2b, 0x72, 0x56, 0x85, 0x01, 0x80, 0x85, 0x01, - 0x16, 0x7b, 0x8b, 0x8b, 0x7b, 0xfe, 0xea, 0x85, 0xfe, 0x80, 0x01, 0xb0, - 0x2a, 0x71, 0x2b, 0x1d, 0x2a, 0x72, 0x2a, 0x1c, 0x2b, 0x72, 0x2b, 0x1d, - 0x2b, 0x72, 0x2b, 0x02, 0x15, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, - 0xab, 0x39, 0xc7, 0xc7, 0xc6, 0x86, 0x5c, 0x5d, 0x86, 0xc6, 0xc7, 0x01, - 0x00, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0x00, 0x03, 0x00, 0x74, - 0x00, 0xb9, 0x04, 0x5d, 0x04, 0xa2, 0x00, 0x0c, 0x00, 0x10, 0x00, 0x14, - 0x00, 0x00, 0x01, 0x37, 0x06, 0x15, 0x14, 0x17, 0x26, 0x23, 0x22, 0x07, - 0x37, 0x27, 0x37, 0x09, 0x01, 0x23, 0x01, 0x25, 0x35, 0x01, 0x15, 0x03, - 0xb2, 0x8e, 0x06, 0x23, 0x74, 0x85, 0x36, 0x39, 0x8f, 0xcf, 0x2e, 0xfe, - 0x77, 0x01, 0x5a, 0xe6, 0xfe, 0xa6, 0x01, 0x15, 0x01, 0x59, 0x01, 0x93, - 0x8f, 0x39, 0x36, 0x85, 0x74, 0x22, 0x06, 0x8f, 0xcf, 0x2e, 0x01, 0x2a, - 0xfe, 0xa8, 0x01, 0x58, 0x2f, 0xe6, 0xfe, 0xa7, 0xe5, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x53, 0x01, 0xd1, 0x04, 0x7e, 0x03, 0x6b, 0x00, 0x08, - 0x00, 0x0c, 0x00, 0x10, 0x00, 0x00, 0x01, 0x35, 0x16, 0x17, 0x06, 0x07, - 0x35, 0x21, 0x35, 0x05, 0x21, 0x07, 0x21, 0x37, 0x27, 0x21, 0x17, 0x03, - 0x8d, 0x6e, 0x82, 0x82, 0x6e, 0xff, 0x00, 0xfe, 0x55, 0x01, 0xaa, 0x8e, - 0xfe, 0x56, 0x8e, 0x8e, 0x01, 0xaa, 0x8e, 0x02, 0xba, 0xb1, 0x86, 0x47, - 0x47, 0x86, 0xb1, 0x38, 0x3a, 0x8e, 0xc8, 0x8f, 0x8f, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x75, 0x00, 0x81, 0x04, 0x5c, 0x04, 0x6a, 0x00, 0x0c, - 0x00, 0x10, 0x00, 0x14, 0x00, 0x00, 0x01, 0x27, 0x16, 0x33, 0x32, 0x37, - 0x06, 0x15, 0x14, 0x17, 0x27, 0x07, 0x27, 0x09, 0x01, 0x15, 0x01, 0x03, - 0x23, 0x01, 0x33, 0x03, 0x83, 0x8e, 0x39, 0x35, 0x85, 0x74, 0x22, 0x05, - 0x8e, 0xcf, 0x2e, 0xfe, 0xd6, 0x01, 0x59, 0xfe, 0xa7, 0x2f, 0xe6, 0x01, - 0x59, 0xe6, 0x03, 0xbf, 0x8f, 0x06, 0x22, 0x75, 0x84, 0x36, 0x39, 0x8f, - 0xcf, 0x2e, 0xfe, 0x78, 0x01, 0x58, 0xe6, 0xfe, 0xa8, 0x01, 0x15, 0x01, - 0x58, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x4e, 0x00, 0xb9, 0x04, 0x83, - 0x04, 0xee, 0x00, 0x32, 0x00, 0x00, 0x25, 0x26, 0x23, 0x22, 0x07, 0x36, - 0x37, 0x36, 0x37, 0x01, 0x26, 0x27, 0x26, 0x22, 0x07, 0x06, 0x07, 0x01, - 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x26, 0x27, 0x26, 0x35, - 0x34, 0x37, 0x36, 0x37, 0x01, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, - 0x17, 0x01, 0x36, 0x37, 0x36, 0x37, 0x06, 0x15, 0x14, 0x04, 0x82, 0x7d, - 0x90, 0x3a, 0x3c, 0x3f, 0x4d, 0x23, 0x15, 0xfe, 0xf6, 0x19, 0x1f, 0x21, - 0x44, 0x22, 0x20, 0x18, 0xfe, 0x8d, 0x1f, 0x24, 0x28, 0x2a, 0x26, 0x2a, - 0x26, 0x1d, 0x1d, 0x0f, 0x11, 0x11, 0x0f, 0x1d, 0x01, 0x73, 0x1c, 0x09, - 0x0c, 0x0c, 0x0d, 0x18, 0x01, 0x0a, 0x03, 0x0e, 0x20, 0x3f, 0x06, 0xba, - 0x24, 0x06, 0x3e, 0x22, 0x0e, 0x02, 0x01, 0x09, 0x1a, 0x0c, 0x0d, 0x0d, - 0x0d, 0x19, 0x01, 0x73, 0x20, 0x0e, 0x10, 0x10, 0x0f, 0x1f, 0x1f, 0x25, - 0x2a, 0x26, 0x2a, 0x28, 0x26, 0x1e, 0xfe, 0x8c, 0x1d, 0x1b, 0x22, 0x21, - 0x23, 0x21, 0x1e, 0x1a, 0xfe, 0xf7, 0x14, 0x22, 0x4f, 0x3e, 0x3e, 0x3b, - 0x8e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x2a, 0x01, 0x89, 0x04, 0xa7, - 0x03, 0x45, 0x00, 0x2f, 0x00, 0x00, 0x01, 0x06, 0x07, 0x34, 0x37, 0x36, - 0x37, 0x21, 0x22, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, 0x15, 0x21, 0x34, - 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x22, 0x27, 0x26, 0x27, 0x26, - 0x27, 0x26, 0x35, 0x21, 0x14, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x33, - 0x21, 0x26, 0x27, 0x26, 0x35, 0x16, 0x04, 0xa6, 0x8c, 0x76, 0x1c, 0x0c, - 0x0b, 0xfe, 0xb8, 0x1f, 0x1b, 0x1c, 0x16, 0x15, 0x0c, 0x0c, 0xfe, 0x35, - 0x0d, 0x0f, 0x1a, 0x18, 0x24, 0x20, 0x25, 0x25, 0x20, 0x24, 0x18, 0x1a, - 0x0f, 0x0d, 0x01, 0xcb, 0x0c, 0x0c, 0x15, 0x16, 0x1c, 0x1b, 0x1f, 0x01, - 0x48, 0x0b, 0x0c, 0x1c, 0x76, 0x02, 0x67, 0x4d, 0x90, 0x4d, 0x45, 0x1e, - 0x0e, 0x0b, 0x0c, 0x16, 0x14, 0x1e, 0x1b, 0x1f, 0x25, 0x21, 0x23, 0x19, - 0x18, 0x10, 0x0e, 0x0e, 0x10, 0x18, 0x1a, 0x22, 0x21, 0x25, 0x1f, 0x1b, - 0x1e, 0x14, 0x16, 0x0c, 0x0b, 0x0e, 0x1e, 0x45, 0x4d, 0x90, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x75, 0x00, 0xaf, 0x04, 0x5c, 0x04, 0x97, 0x00, 0x32, - 0x00, 0x00, 0x01, 0x06, 0x15, 0x14, 0x17, 0x26, 0x27, 0x26, 0x27, 0x07, - 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x01, 0x26, 0x27, 0x26, - 0x35, 0x34, 0x37, 0x36, 0x37, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, - 0x27, 0x01, 0x16, 0x17, 0x16, 0x32, 0x37, 0x36, 0x3f, 0x01, 0x26, 0x27, - 0x26, 0x27, 0x16, 0x33, 0x32, 0x04, 0x5c, 0x22, 0x06, 0x3a, 0x1e, 0x0d, - 0x04, 0xf6, 0x19, 0x0a, 0x0b, 0x0b, 0x0c, 0x17, 0xfe, 0xa8, 0x1c, 0x0e, - 0x0f, 0x0f, 0x0e, 0x1c, 0x1c, 0x23, 0x27, 0x24, 0x27, 0x24, 0x23, 0x1c, - 0x01, 0x59, 0x16, 0x1e, 0x1f, 0x40, 0x1f, 0x1c, 0x18, 0xf6, 0x14, 0x1f, - 0x49, 0x3a, 0x38, 0x36, 0x86, 0x04, 0x97, 0x73, 0x85, 0x36, 0x3a, 0x3a, - 0x49, 0x20, 0x12, 0xf6, 0x1b, 0x19, 0x1f, 0x1f, 0x1f, 0x20, 0x1d, 0x17, - 0xfe, 0xa7, 0x1b, 0x23, 0x26, 0x27, 0x23, 0x27, 0x22, 0x1d, 0x1d, 0x0d, - 0x0f, 0x0f, 0x0e, 0x1c, 0x01, 0x58, 0x16, 0x0d, 0x0c, 0x0c, 0x0c, 0x17, - 0xf7, 0x02, 0x0d, 0x1f, 0x3a, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x35, - 0x01, 0x2a, 0x04, 0x9c, 0x03, 0xec, 0x00, 0x16, 0x00, 0x2b, 0x00, 0x42, - 0x00, 0x00, 0x01, 0x36, 0x37, 0x06, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, - 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, - 0x36, 0x24, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, 0x32, 0x17, 0x04, - 0x05, 0x04, 0x07, 0x06, 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x25, 0x26, - 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, - 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x17, 0x24, 0x03, 0x03, 0xb8, - 0xe0, 0xaa, 0x5b, 0x09, 0x10, 0x11, 0x14, 0x13, 0x2f, 0x13, 0x15, 0x10, - 0x10, 0x09, 0x08, 0x08, 0x09, 0x10, 0x10, 0xfd, 0x48, 0x0b, 0x0d, 0x14, - 0x16, 0x1b, 0x1a, 0x3d, 0x1b, 0x01, 0x08, 0x02, 0x8d, 0xfd, 0x61, 0xf6, - 0x1b, 0x3d, 0x1a, 0x1f, 0x12, 0x16, 0x0b, 0x02, 0xc2, 0x15, 0x10, 0x10, - 0x09, 0x08, 0x08, 0x09, 0x10, 0x10, 0x15, 0x13, 0x2f, 0x13, 0x14, 0x11, - 0x0d, 0x0c, 0x5a, 0xab, 0xfe, 0xef, 0x02, 0x04, 0x49, 0x3d, 0x58, 0xc2, - 0x16, 0x0f, 0x0f, 0x0a, 0x08, 0x08, 0x0a, 0x0f, 0x0f, 0x16, 0x14, 0x18, - 0x16, 0x14, 0x16, 0x0f, 0x10, 0x71, 0x3e, 0x1a, 0x1e, 0x13, 0x15, 0x0c, - 0x0c, 0x0b, 0x64, 0x28, 0x2a, 0x63, 0x0a, 0x0b, 0x0e, 0x13, 0x18, 0x19, - 0xc1, 0x09, 0x0f, 0x10, 0x15, 0x15, 0x16, 0x17, 0x15, 0x15, 0x0f, 0x10, - 0x09, 0x08, 0x08, 0x09, 0x10, 0x0c, 0x18, 0xc2, 0x58, 0x4a, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x1d, 0x01, 0x6e, 0x04, 0xb4, 0x03, 0xb0, 0x00, 0x1a, - 0x00, 0x2e, 0x00, 0x00, 0x13, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x36, - 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x05, 0x04, 0x07, 0x0e, 0x01, 0x23, - 0x22, 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x25, 0x26, 0x27, 0x26, 0x35, - 0x34, 0x37, 0x36, 0x37, 0x16, 0x17, 0x06, 0x07, 0x26, 0x27, 0x26, 0x35, - 0x34, 0x37, 0x36, 0x1d, 0x35, 0x18, 0x1a, 0x10, 0x20, 0x20, 0x23, 0x26, - 0x2b, 0x2a, 0x31, 0x29, 0x84, 0x01, 0x46, 0xfe, 0xba, 0x84, 0x2d, 0x59, - 0x29, 0x29, 0x20, 0x2e, 0x12, 0x17, 0x13, 0x17, 0x03, 0x45, 0x1e, 0x0f, - 0x10, 0x10, 0x0f, 0x1e, 0x4f, 0xcd, 0xcd, 0x4f, 0x1e, 0x0f, 0x10, 0x10, - 0x0f, 0x02, 0x8f, 0x1f, 0x2f, 0x33, 0x10, 0x1d, 0x0f, 0x0f, 0x0f, 0x12, - 0x1a, 0x53, 0x3e, 0x3e, 0x53, 0x1c, 0x1f, 0x0f, 0x18, 0x14, 0x1d, 0x26, - 0x2f, 0x1f, 0x20, 0x23, 0x24, 0x29, 0x29, 0x25, 0x23, 0x1f, 0xc3, 0x5d, - 0x5d, 0xc3, 0x1f, 0x23, 0x25, 0x29, 0x29, 0x24, 0x23, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x26, 0x01, 0xbe, 0x04, 0xab, 0x03, 0xa6, 0x00, 0x65, - 0x00, 0x00, 0x00, 0x14, 0x06, 0x0f, 0x01, 0x06, 0x07, 0x06, 0x22, 0x27, - 0x26, 0x27, 0x2e, 0x01, 0x35, 0x34, 0x3f, 0x01, 0x36, 0x35, 0x34, 0x27, - 0x26, 0x27, 0x26, 0x27, 0x26, 0x2b, 0x01, 0x22, 0x07, 0x06, 0x07, 0x06, - 0x0f, 0x01, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x21, 0x22, 0x2e, 0x02, - 0x34, 0x3f, 0x01, 0x36, 0x34, 0x2f, 0x01, 0x26, 0x34, 0x36, 0x37, 0x36, - 0x37, 0x36, 0x33, 0x21, 0x32, 0x17, 0x16, 0x17, 0x16, 0x1f, 0x01, 0x16, - 0x17, 0x16, 0x17, 0x16, 0x3b, 0x01, 0x32, 0x37, 0x36, 0x37, 0x36, 0x37, - 0x36, 0x35, 0x34, 0x2f, 0x01, 0x26, 0x35, 0x34, 0x36, 0x37, 0x36, 0x37, - 0x36, 0x32, 0x17, 0x16, 0x1f, 0x01, 0x16, 0x04, 0xab, 0x05, 0x05, 0xc3, - 0x03, 0x07, 0x06, 0x0d, 0x06, 0x05, 0x05, 0x05, 0x05, 0x02, 0x16, 0x03, - 0x03, 0x02, 0x05, 0x04, 0x06, 0x07, 0x06, 0xe5, 0x06, 0x06, 0x06, 0x05, - 0x04, 0x03, 0x49, 0x04, 0x03, 0x04, 0x07, 0x05, 0x06, 0xfe, 0x0e, 0x06, - 0x0b, 0x0a, 0x05, 0x02, 0x5d, 0x03, 0x03, 0x5d, 0x02, 0x05, 0x05, 0x05, - 0x05, 0x06, 0x06, 0x01, 0xf2, 0x06, 0x05, 0x07, 0x04, 0x03, 0x04, 0x49, - 0x03, 0x04, 0x05, 0x06, 0x06, 0x06, 0xe5, 0x06, 0x07, 0x06, 0x04, 0x05, - 0x02, 0x03, 0x03, 0x16, 0x02, 0x05, 0x05, 0x05, 0x05, 0x06, 0x0d, 0x06, - 0x07, 0x03, 0xc3, 0x05, 0x02, 0xb9, 0x0e, 0x0c, 0x05, 0xc3, 0x03, 0x04, - 0x02, 0x02, 0x03, 0x04, 0x05, 0x0c, 0x07, 0x03, 0x09, 0x51, 0x09, 0x04, - 0x05, 0x06, 0x06, 0x05, 0x04, 0x03, 0x03, 0x02, 0x04, 0x04, 0x04, 0x06, - 0x92, 0x09, 0x02, 0x04, 0x03, 0x03, 0x05, 0x0a, 0x0b, 0x0f, 0x05, 0xb9, - 0x05, 0x10, 0x05, 0xb9, 0x05, 0x0f, 0x0b, 0x05, 0x04, 0x03, 0x03, 0x03, - 0x02, 0x05, 0x02, 0x09, 0x92, 0x06, 0x04, 0x04, 0x04, 0x02, 0x03, 0x03, - 0x04, 0x05, 0x06, 0x06, 0x05, 0x04, 0x09, 0x51, 0x09, 0x03, 0x07, 0x0c, - 0x05, 0x04, 0x03, 0x02, 0x02, 0x04, 0x03, 0xc3, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x25, 0x01, 0x65, 0x04, 0xab, 0x03, 0xf1, 0x00, 0x67, - 0x00, 0x00, 0x00, 0x14, 0x07, 0x06, 0x07, 0x01, 0x06, 0x07, 0x06, 0x22, - 0x27, 0x26, 0x27, 0x2e, 0x01, 0x35, 0x34, 0x3f, 0x01, 0x36, 0x35, 0x34, - 0x27, 0x26, 0x27, 0x26, 0x27, 0x26, 0x2b, 0x01, 0x22, 0x07, 0x06, 0x07, - 0x06, 0x0f, 0x01, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x21, 0x22, 0x2e, - 0x02, 0x34, 0x3f, 0x01, 0x36, 0x34, 0x2f, 0x01, 0x26, 0x34, 0x36, 0x37, - 0x36, 0x37, 0x36, 0x33, 0x21, 0x32, 0x17, 0x16, 0x17, 0x16, 0x1f, 0x01, - 0x16, 0x17, 0x16, 0x17, 0x16, 0x3b, 0x01, 0x32, 0x37, 0x36, 0x37, 0x36, - 0x37, 0x36, 0x35, 0x34, 0x2f, 0x01, 0x26, 0x35, 0x34, 0x36, 0x37, 0x36, - 0x37, 0x36, 0x32, 0x17, 0x16, 0x17, 0x01, 0x16, 0x17, 0x04, 0xab, 0x02, - 0x03, 0x05, 0xfe, 0xbb, 0x04, 0x06, 0x06, 0x0d, 0x06, 0x05, 0x05, 0x05, - 0x05, 0x02, 0x47, 0x03, 0x03, 0x02, 0x05, 0x04, 0x07, 0x06, 0x06, 0x4b, - 0x06, 0x06, 0x06, 0x04, 0x05, 0x03, 0x61, 0x04, 0x03, 0x05, 0x06, 0x05, - 0x07, 0xfd, 0xe7, 0x07, 0x0b, 0x0a, 0x05, 0x03, 0x75, 0x02, 0x02, 0x7e, - 0x02, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x02, 0x1a, 0x07, 0x05, 0x07, - 0x04, 0x03, 0x04, 0x69, 0x03, 0x05, 0x04, 0x06, 0x06, 0x06, 0x4b, 0x06, - 0x06, 0x07, 0x04, 0x05, 0x02, 0x03, 0x03, 0x47, 0x02, 0x05, 0x05, 0x05, - 0x05, 0x06, 0x0d, 0x06, 0x06, 0x04, 0x01, 0x45, 0x05, 0x03, 0x02, 0xb2, - 0x0e, 0x06, 0x06, 0x05, 0xfe, 0xdc, 0x04, 0x03, 0x03, 0x03, 0x03, 0x04, - 0x05, 0x0b, 0x07, 0x06, 0x07, 0xb2, 0x06, 0x07, 0x05, 0x06, 0x07, 0x04, - 0x04, 0x03, 0x03, 0x02, 0x04, 0x04, 0x04, 0x06, 0xc3, 0x08, 0x03, 0x04, - 0x03, 0x03, 0x05, 0x0a, 0x0b, 0x0f, 0x05, 0xea, 0x05, 0x10, 0x05, 0xfa, - 0x05, 0x0f, 0x0b, 0x05, 0x04, 0x03, 0x03, 0x03, 0x02, 0x05, 0x02, 0x09, - 0xd3, 0x06, 0x04, 0x04, 0x04, 0x02, 0x03, 0x03, 0x04, 0x04, 0x07, 0x06, - 0x05, 0x07, 0x06, 0xb2, 0x07, 0x06, 0x07, 0x0b, 0x05, 0x04, 0x03, 0x03, - 0x03, 0x03, 0x04, 0xfe, 0xdc, 0x05, 0x06, 0x00, 0x00, 0x03, 0x00, 0x32, - 0x01, 0x0c, 0x04, 0x9f, 0x03, 0xb2, 0x00, 0x13, 0x00, 0x1f, 0x00, 0x2b, - 0x00, 0x00, 0x01, 0x06, 0x07, 0x06, 0x07, 0x23, 0x37, 0x36, 0x37, 0x36, - 0x37, 0x26, 0x27, 0x26, 0x2f, 0x01, 0x33, 0x16, 0x17, 0x16, 0x01, 0x23, - 0x36, 0x37, 0x36, 0x37, 0x21, 0x35, 0x21, 0x06, 0x07, 0x06, 0x03, 0x16, - 0x17, 0x16, 0x17, 0x21, 0x35, 0x21, 0x26, 0x27, 0x26, 0x27, 0x04, 0x9f, - 0x67, 0x3f, 0x6a, 0x37, 0x52, 0x08, 0x3d, 0x79, 0x1d, 0x36, 0x36, 0x1d, - 0x79, 0x3d, 0x08, 0x52, 0x36, 0x6b, 0x3f, 0xfe, 0x56, 0x4f, 0x0e, 0x12, - 0x17, 0x20, 0xfd, 0x9c, 0x02, 0xf1, 0x53, 0x2b, 0x0d, 0x0a, 0x0a, 0x0d, - 0x2b, 0x53, 0xfd, 0x0f, 0x02, 0x64, 0x20, 0x17, 0x12, 0x0e, 0x02, 0x5f, - 0x38, 0x3d, 0x65, 0x79, 0x11, 0x8b, 0x75, 0x1b, 0x27, 0x26, 0x1c, 0x75, - 0x8a, 0x11, 0x74, 0x6a, 0x3c, 0xfe, 0x75, 0x2c, 0x2a, 0x34, 0x34, 0x47, - 0x65, 0x65, 0x1d, 0x02, 0x87, 0x1d, 0x1d, 0x65, 0x65, 0x47, 0x33, 0x35, - 0x2a, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x00, 0x58, 0x00, 0x00, 0x04, 0x79, - 0x05, 0x04, 0x10, 0x06, 0x08, 0x99, 0x00, 0x00, 0x00, 0x01, 0x01, 0x38, - 0xfe, 0xb2, 0x03, 0x9a, 0x06, 0x26, 0x00, 0x19, 0x00, 0x00, 0x01, 0x2a, - 0x01, 0x27, 0x24, 0x03, 0x26, 0x00, 0x27, 0x26, 0x23, 0x22, 0x07, 0x27, - 0x36, 0x37, 0x36, 0x15, 0x14, 0x00, 0x07, 0x06, 0x05, 0x16, 0x36, 0x37, - 0x03, 0x9a, 0x09, 0x68, 0x37, 0xfe, 0x48, 0x02, 0x01, 0x01, 0x6d, 0x04, - 0x03, 0x5e, 0x3a, 0x2d, 0x88, 0x33, 0xd5, 0xde, 0xfe, 0xb0, 0x07, 0x0c, - 0x01, 0x1c, 0x52, 0x45, 0x14, 0xfe, 0xb2, 0x0b, 0x53, 0x01, 0x52, 0xae, - 0x03, 0xf5, 0x51, 0x4f, 0x89, 0x31, 0xd8, 0x01, 0x01, 0xcc, 0xa1, 0xfc, - 0x4c, 0x8f, 0xdc, 0x48, 0x15, 0x01, 0x02, 0x00, 0x00, 0x01, 0x01, 0x37, - 0xfe, 0xb2, 0x03, 0x99, 0x06, 0x26, 0x00, 0x19, 0x00, 0x00, 0x01, 0x35, - 0x1e, 0x01, 0x37, 0x24, 0x27, 0x26, 0x00, 0x35, 0x34, 0x17, 0x16, 0x17, - 0x07, 0x26, 0x23, 0x22, 0x07, 0x06, 0x00, 0x07, 0x02, 0x05, 0x06, 0x22, - 0x01, 0x37, 0x14, 0x45, 0x52, 0x01, 0x1c, 0x0c, 0x07, 0xfe, 0xb0, 0xde, - 0xd5, 0x33, 0x88, 0x2d, 0x3a, 0x5e, 0x03, 0x04, 0x01, 0x6d, 0x01, 0x02, - 0xfe, 0x48, 0x37, 0x68, 0xfe, 0xb2, 0x8f, 0x02, 0x01, 0x15, 0x48, 0xdc, - 0x8f, 0x03, 0xb4, 0xa1, 0xcc, 0x01, 0x01, 0xd8, 0x31, 0x89, 0x4f, 0x51, - 0xfc, 0x0b, 0xae, 0xfe, 0xae, 0x53, 0x0b, 0x00, 0x00, 0x03, 0x00, 0x75, - 0xfe, 0x23, 0x04, 0x5c, 0x06, 0x75, 0x00, 0x03, 0x00, 0x06, 0x00, 0x09, - 0x00, 0x00, 0x09, 0x05, 0x21, 0x09, 0x01, 0x21, 0x02, 0x68, 0x01, 0xf4, - 0xfe, 0x0c, 0xfe, 0x0d, 0x01, 0xf3, 0xfe, 0x98, 0x02, 0xd1, 0xfe, 0x97, - 0x01, 0x69, 0xfd, 0x2f, 0x06, 0x75, 0xfb, 0xdb, 0xfb, 0xd3, 0x04, 0x2d, - 0x03, 0x31, 0xfd, 0x08, 0xfc, 0x8e, 0x03, 0x00, 0x00, 0x02, 0x01, 0x29, - 0xfe, 0xf2, 0x03, 0xa9, 0x06, 0x14, 0x00, 0x03, 0x00, 0x0b, 0x00, 0x00, - 0x01, 0x11, 0x33, 0x11, 0x25, 0x21, 0x15, 0x23, 0x11, 0x33, 0x15, 0x21, - 0x01, 0x8d, 0xc8, 0xfe, 0xd4, 0x02, 0x80, 0xf0, 0xf0, 0xfd, 0x80, 0x05, - 0xb0, 0xf9, 0xa6, 0x06, 0x5a, 0x64, 0x64, 0xf9, 0xa6, 0x64, 0x00, 0x00, - 0x00, 0x02, 0x01, 0x28, 0xfe, 0xf2, 0x03, 0xa8, 0x06, 0x14, 0x00, 0x03, - 0x00, 0x0b, 0x00, 0x00, 0x01, 0x23, 0x11, 0x33, 0x13, 0x11, 0x21, 0x35, - 0x33, 0x11, 0x23, 0x35, 0x03, 0x44, 0xc8, 0xc8, 0x64, 0xfd, 0x80, 0xf0, - 0xf0, 0x05, 0xb0, 0xf9, 0xa6, 0x06, 0xbe, 0xf8, 0xde, 0x64, 0x06, 0x5a, - 0x64, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x86, 0xfe, 0xf2, 0x03, 0x4b, - 0x06, 0x12, 0x00, 0x05, 0x00, 0x00, 0x09, 0x01, 0x33, 0x09, 0x01, 0x23, - 0x01, 0x87, 0x01, 0x19, 0xaa, 0xfe, 0xe7, 0x01, 0x19, 0xaa, 0x02, 0x82, - 0x03, 0x90, 0xfc, 0x70, 0xfc, 0x70, 0x00, 0x00, 0x00, 0x01, 0x01, 0x86, - 0xfe, 0xf2, 0x03, 0x4b, 0x06, 0x12, 0x00, 0x05, 0x00, 0x00, 0x09, 0x01, - 0x23, 0x09, 0x01, 0x33, 0x03, 0x4a, 0xfe, 0xe7, 0xaa, 0x01, 0x19, 0xfe, - 0xe7, 0xaa, 0x02, 0x82, 0xfc, 0x70, 0x03, 0x90, 0x03, 0x90, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x75, 0xfe, 0x23, 0x04, 0x5c, 0x06, 0x75, 0x00, 0x03, - 0x00, 0x00, 0x09, 0x03, 0x02, 0x68, 0x01, 0xf4, 0xfe, 0x0c, 0xfe, 0x0d, - 0x06, 0x75, 0xfb, 0xdb, 0xfb, 0xd3, 0x04, 0x2d, 0x00, 0x01, 0x00, 0x58, - 0x00, 0x71, 0x04, 0x79, 0x04, 0x93, 0x00, 0x13, 0x00, 0x00, 0x01, 0x11, - 0x33, 0x11, 0x33, 0x15, 0x23, 0x11, 0x23, 0x11, 0x23, 0x11, 0x23, 0x11, - 0x23, 0x35, 0x33, 0x11, 0x33, 0x11, 0x02, 0xdc, 0xa8, 0xf5, 0xf5, 0xa8, - 0xe8, 0xa8, 0xf4, 0xf4, 0xa8, 0x02, 0xd7, 0x01, 0xbc, 0xfe, 0x44, 0xaa, - 0xfe, 0x44, 0x01, 0xbc, 0xfe, 0x44, 0x01, 0xbc, 0xaa, 0x01, 0xbc, 0xfe, - 0x44, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x58, 0x00, 0x71, 0x04, 0x79, - 0x04, 0x93, 0x00, 0x1b, 0x00, 0x00, 0x13, 0x11, 0x33, 0x11, 0x33, 0x11, - 0x33, 0x11, 0x33, 0x11, 0x33, 0x11, 0x33, 0x15, 0x23, 0x11, 0x23, 0x11, - 0x23, 0x11, 0x23, 0x11, 0x23, 0x11, 0x23, 0x11, 0x23, 0x35, 0xca, 0xa8, - 0xa2, 0xa8, 0xa2, 0xa8, 0x73, 0x73, 0xa8, 0xa2, 0xa8, 0xa2, 0xa8, 0x72, - 0x02, 0xd7, 0x01, 0xbc, 0xfe, 0x44, 0x01, 0xbc, 0xfe, 0x44, 0x01, 0xbc, - 0xfe, 0x44, 0xaa, 0xfe, 0x44, 0x01, 0xbc, 0xfe, 0x44, 0x01, 0xbc, 0xfe, - 0x44, 0x01, 0xbc, 0xaa, 0xff, 0xff, 0x00, 0x96, 0x00, 0xae, 0x04, 0x3b, - 0x04, 0x54, 0x10, 0x06, 0x00, 0x99, 0x00, 0x00, 0xff, 0xff, 0x00, 0x58, - 0x01, 0xf1, 0x04, 0x79, 0x04, 0x84, 0x10, 0x26, 0x08, 0x3b, 0x00, 0x00, - 0x10, 0x07, 0x08, 0x9a, 0x00, 0x02, 0x01, 0x24, 0xff, 0xff, 0x00, 0x58, - 0x00, 0x86, 0x04, 0x79, 0x04, 0x84, 0x10, 0x26, 0x08, 0x3b, 0x00, 0x00, - 0x10, 0x27, 0x08, 0x9a, 0x00, 0xf2, 0x01, 0x24, 0x10, 0x07, 0x08, 0x9a, - 0xff, 0x11, 0xfe, 0x57, 0x00, 0x01, 0x00, 0x54, 0x01, 0x85, 0x04, 0x7d, - 0x03, 0xf3, 0x00, 0x06, 0x00, 0x00, 0x01, 0x21, 0x11, 0x21, 0x15, 0x09, - 0x01, 0x01, 0x8b, 0x02, 0xf2, 0xfd, 0x0e, 0xfe, 0xc9, 0x01, 0x37, 0x03, - 0x4a, 0xfe, 0xe4, 0xa9, 0x01, 0x37, 0x01, 0x37, 0x00, 0x01, 0x01, 0x31, - 0x00, 0xa7, 0x03, 0xa0, 0x04, 0xd1, 0x00, 0x06, 0x00, 0x00, 0x01, 0x11, - 0x21, 0x11, 0x23, 0x09, 0x01, 0x02, 0xf7, 0xfe, 0xe3, 0xa9, 0x01, 0x37, - 0x01, 0x38, 0x03, 0x99, 0xfd, 0x0e, 0x02, 0xf2, 0x01, 0x38, 0xfe, 0xc8, - 0x00, 0x01, 0x01, 0x31, 0x00, 0xa7, 0x03, 0xa0, 0x04, 0xd1, 0x00, 0x06, - 0x00, 0x00, 0x01, 0x11, 0x21, 0x11, 0x33, 0x09, 0x01, 0x01, 0xda, 0x01, - 0x1d, 0xa9, 0xfe, 0xc9, 0xfe, 0xc8, 0x01, 0xdf, 0x02, 0xf2, 0xfd, 0x0e, - 0xfe, 0xc8, 0x01, 0x38, 0x00, 0x01, 0x00, 0x8b, 0x00, 0xdf, 0x03, 0xe1, - 0x04, 0x35, 0x00, 0x06, 0x00, 0x00, 0x09, 0x01, 0x27, 0x01, 0x27, 0x21, - 0x11, 0x03, 0x6a, 0xfd, 0xea, 0xc9, 0x02, 0x16, 0x78, 0x01, 0xb8, 0x02, - 0xf4, 0xfd, 0xeb, 0xc9, 0x02, 0x15, 0x78, 0xfe, 0x47, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xf0, 0x00, 0xdf, 0x04, 0x46, 0x04, 0x35, 0x00, 0x06, - 0x00, 0x00, 0x09, 0x01, 0x07, 0x01, 0x07, 0x11, 0x21, 0x02, 0x30, 0x02, - 0x16, 0xc9, 0xfd, 0xea, 0x77, 0x01, 0xb8, 0x03, 0xbd, 0xfd, 0xeb, 0xc9, - 0x02, 0x15, 0x78, 0x01, 0xb9, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf0, - 0x00, 0xdf, 0x04, 0x46, 0x04, 0x35, 0x00, 0x06, 0x00, 0x00, 0x09, 0x01, - 0x37, 0x01, 0x37, 0x11, 0x21, 0x03, 0x05, 0xfd, 0xeb, 0xc9, 0x02, 0x15, - 0x78, 0xfe, 0x47, 0x01, 0x56, 0x02, 0x16, 0xc9, 0xfd, 0xea, 0x78, 0xfe, - 0x48, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x8b, 0x00, 0xdf, 0x03, 0xe1, - 0x04, 0x35, 0x00, 0x06, 0x00, 0x00, 0x09, 0x01, 0x17, 0x01, 0x17, 0x21, - 0x11, 0x01, 0x03, 0x02, 0x15, 0xc9, 0xfd, 0xeb, 0x78, 0xfe, 0x47, 0x02, - 0x1f, 0x02, 0x16, 0xc9, 0xfd, 0xea, 0x77, 0x01, 0xb8, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x54, 0x01, 0x85, 0x04, 0x7d, 0x03, 0xf3, 0x00, 0x09, - 0x00, 0x00, 0x01, 0x21, 0x35, 0x09, 0x01, 0x35, 0x21, 0x15, 0x09, 0x01, - 0x01, 0x8b, 0x01, 0xbb, 0x01, 0x37, 0xfe, 0xc9, 0xfe, 0x45, 0xfe, 0xc9, - 0x01, 0x37, 0x03, 0x4a, 0xa9, 0xfe, 0xc9, 0xfe, 0xc9, 0xa9, 0xa9, 0x01, - 0x37, 0x01, 0x37, 0x00, 0x00, 0x01, 0x01, 0x31, 0x00, 0xa7, 0x03, 0xa0, - 0x04, 0xd1, 0x00, 0x09, 0x00, 0x00, 0x01, 0x11, 0x23, 0x09, 0x01, 0x23, - 0x11, 0x33, 0x09, 0x01, 0x01, 0xda, 0xa9, 0x01, 0x38, 0x01, 0x37, 0xa9, - 0xa9, 0xfe, 0xc9, 0xfe, 0xc8, 0x01, 0xdf, 0x01, 0xba, 0x01, 0x38, 0xfe, - 0xc8, 0xfe, 0x46, 0xfe, 0xc8, 0x01, 0x38, 0x00, 0x00, 0x02, 0x00, 0x06, - 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, - 0x37, 0x21, 0x11, 0x21, 0x03, 0x11, 0x21, 0x11, 0x78, 0x03, 0xe1, 0xfc, - 0x1f, 0x72, 0x04, 0xc5, 0x24, 0x01, 0xf0, 0xfd, 0x9e, 0x04, 0xc4, 0xfb, - 0x3c, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, - 0x04, 0x77, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x13, 0x21, 0x11, 0x21, - 0x03, 0x11, 0x21, 0x11, 0x78, 0x03, 0xe1, 0xfc, 0x1f, 0x72, 0x04, 0xc5, - 0x02, 0x14, 0x01, 0xf0, 0xfb, 0xae, 0x04, 0xc4, 0xfb, 0x3c, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x02, - 0x00, 0x06, 0x00, 0x00, 0x37, 0x21, 0x01, 0x03, 0x11, 0x21, 0x11, 0x78, - 0x03, 0xe1, 0xfc, 0x1f, 0x72, 0x04, 0xc5, 0x24, 0x03, 0xe0, 0xfb, 0xae, - 0x04, 0xc4, 0xfb, 0x3c, 0x00, 0x02, 0x00, 0x06, 0xff, 0xb1, 0x04, 0xcb, - 0x04, 0x77, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, 0x25, 0x11, 0x21, 0x03, - 0x11, 0x21, 0x11, 0x04, 0x59, 0xfc, 0x1f, 0x72, 0x04, 0xc5, 0x24, 0x03, - 0xe0, 0xfb, 0xae, 0x04, 0xc4, 0xfb, 0x3c, 0x00, 0x00, 0x02, 0x00, 0x06, - 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, - 0x25, 0x09, 0x05, 0x02, 0x68, 0x01, 0xcb, 0xfe, 0x35, 0xfd, 0x9e, 0x02, - 0x62, 0x02, 0x63, 0xfd, 0x9d, 0x4a, 0x01, 0xca, 0x01, 0xca, 0xfe, 0x36, - 0x02, 0x62, 0xfd, 0x9e, 0xfd, 0x9e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, - 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, - 0x13, 0x01, 0x11, 0x09, 0x03, 0x9e, 0x01, 0xca, 0xfd, 0x9e, 0x02, 0x62, - 0x02, 0x63, 0xfd, 0x9d, 0x02, 0x14, 0xfe, 0x36, 0x03, 0x94, 0xfe, 0x36, - 0x02, 0x62, 0xfd, 0x9e, 0xfd, 0x9e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, - 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, - 0x13, 0x09, 0x01, 0x21, 0x09, 0x02, 0x9e, 0x01, 0xca, 0x01, 0xcb, 0xfb, - 0xd3, 0x02, 0x62, 0x02, 0x63, 0xfd, 0x9d, 0x02, 0x14, 0xfe, 0x36, 0x01, - 0xca, 0x02, 0x62, 0xfd, 0x9e, 0xfd, 0x9e, 0x00, 0x00, 0x02, 0x00, 0x06, - 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x02, 0x00, 0x06, 0x00, 0x00, - 0x13, 0x21, 0x09, 0x04, 0x9e, 0x03, 0x95, 0xfe, 0x35, 0xfd, 0x9e, 0x02, - 0x62, 0x02, 0x63, 0xfd, 0x9d, 0x02, 0x14, 0x01, 0xca, 0xfe, 0x36, 0x02, - 0x62, 0xfd, 0x9e, 0xfd, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, - 0xff, 0xb1, 0x04, 0xcb, 0x04, 0x77, 0x00, 0x05, 0x00, 0x09, 0x00, 0x0d, - 0x00, 0x11, 0x00, 0x15, 0x00, 0x1b, 0x00, 0x1f, 0x00, 0x23, 0x00, 0x29, - 0x00, 0x2d, 0x00, 0x31, 0x00, 0x37, 0x00, 0x00, 0x25, 0x15, 0x23, 0x35, - 0x33, 0x35, 0x13, 0x15, 0x23, 0x35, 0x13, 0x15, 0x23, 0x35, 0x03, 0x15, - 0x23, 0x35, 0x23, 0x15, 0x23, 0x35, 0x27, 0x15, 0x33, 0x15, 0x23, 0x35, - 0x13, 0x15, 0x23, 0x35, 0x13, 0x15, 0x23, 0x35, 0x01, 0x15, 0x23, 0x35, - 0x23, 0x35, 0x23, 0x15, 0x23, 0x35, 0x23, 0x15, 0x23, 0x35, 0x23, 0x15, - 0x23, 0x15, 0x23, 0x35, 0x04, 0xcb, 0xcd, 0x5a, 0x73, 0x73, 0x73, 0x73, - 0xf4, 0xae, 0x9a, 0xb4, 0xf0, 0x56, 0xc8, 0x72, 0x72, 0x72, 0x72, 0x04, - 0xc5, 0x73, 0x5a, 0x9a, 0xae, 0x9a, 0xb4, 0x9a, 0x56, 0x72, 0x7e, 0xcc, - 0x72, 0x5a, 0x01, 0x48, 0xae, 0xae, 0x01, 0x4e, 0xb3, 0xb3, 0xfd, 0x10, - 0x72, 0x72, 0x72, 0x72, 0x5a, 0x5a, 0x72, 0xcc, 0x01, 0x48, 0xae, 0xae, - 0x01, 0x4e, 0xb3, 0xb3, 0x01, 0x62, 0xc8, 0x56, 0x72, 0x72, 0x72, 0x72, - 0x72, 0x72, 0x56, 0xc8, 0x00, 0x02, 0x00, 0x8f, 0xfe, 0x4c, 0x04, 0xd1, - 0x05, 0xd5, 0x00, 0x1e, 0x00, 0x27, 0x00, 0x00, 0x17, 0x11, 0x21, 0x32, - 0x04, 0x15, 0x14, 0x06, 0x07, 0x16, 0x17, 0x16, 0x17, 0x13, 0x23, 0x03, - 0x2e, 0x01, 0x2b, 0x01, 0x11, 0x14, 0x17, 0x16, 0x3b, 0x01, 0x15, 0x23, - 0x22, 0x27, 0x26, 0x13, 0x11, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x23, - 0x8f, 0x01, 0xa0, 0xf6, 0x01, 0x06, 0xa1, 0x92, 0x4e, 0x37, 0x36, 0x53, - 0xcb, 0xd9, 0xb2, 0x4d, 0x7b, 0x63, 0xc1, 0x2c, 0x2d, 0x5a, 0xb9, 0xdf, - 0xa5, 0x5a, 0x59, 0xcb, 0xdd, 0x91, 0x8e, 0x97, 0x90, 0x1e, 0x05, 0xf3, - 0xde, 0xd2, 0x94, 0xbb, 0x15, 0x14, 0x37, 0x37, 0xa7, 0xfe, 0x68, 0x01, - 0x79, 0xa1, 0x5d, 0xfd, 0x6b, 0x7e, 0x3e, 0x3e, 0x9c, 0x6a, 0x69, 0x06, - 0x10, 0xfd, 0xee, 0x82, 0x86, 0x81, 0x89, 0x00, 0x00, 0x02, 0x00, 0x6a, - 0xff, 0xe3, 0x04, 0x52, 0x05, 0xf0, 0x00, 0x13, 0x00, 0x22, 0x00, 0x00, - 0x01, 0x35, 0x33, 0x11, 0x23, 0x35, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, - 0x26, 0x11, 0x10, 0x00, 0x33, 0x32, 0x17, 0x16, 0x00, 0x10, 0x17, 0x16, - 0x33, 0x32, 0x37, 0x36, 0x11, 0x10, 0x27, 0x26, 0x23, 0x22, 0x07, 0x03, - 0x9a, 0xb8, 0xb8, 0x33, 0x55, 0x56, 0x6e, 0xe1, 0x81, 0x82, 0x01, 0x04, - 0xe0, 0x70, 0x56, 0x54, 0xfd, 0xd5, 0x4d, 0x4c, 0x95, 0x94, 0x4e, 0x4d, - 0x4d, 0x4e, 0x94, 0x95, 0x4c, 0x05, 0x41, 0x94, 0xfa, 0x2b, 0xc1, 0x6c, - 0x39, 0x39, 0xcf, 0xd1, 0x01, 0x6c, 0x01, 0x67, 0x01, 0x9a, 0x2d, 0x2c, - 0xfe, 0x80, 0xfd, 0xa5, 0x9b, 0x9a, 0x9c, 0x99, 0x01, 0x2e, 0x01, 0x2e, - 0x99, 0x9b, 0x9a, 0x00, 0x00, 0x01, 0x00, 0x56, 0xfe, 0x56, 0x04, 0x79, - 0x05, 0xd5, 0x00, 0x16, 0x00, 0x00, 0x09, 0x01, 0x23, 0x01, 0x11, 0x23, - 0x11, 0x21, 0x09, 0x01, 0x21, 0x11, 0x14, 0x07, 0x06, 0x2b, 0x01, 0x35, - 0x33, 0x32, 0x37, 0x36, 0x35, 0x03, 0xbe, 0xfe, 0xf6, 0x99, 0xfe, 0xf5, - 0xba, 0x01, 0x0e, 0x01, 0x02, 0x01, 0x04, 0x01, 0x0f, 0x59, 0x5a, 0xa5, - 0xcd, 0xb7, 0x5a, 0x2d, 0x2c, 0x05, 0x27, 0xfc, 0xed, 0x03, 0x13, 0xfa, - 0xd9, 0x05, 0xd5, 0xfd, 0x08, 0x02, 0xf8, 0xfa, 0x17, 0xc3, 0x69, 0x6a, - 0x9c, 0x3e, 0x3e, 0x92, 0x00, 0x02, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, - 0x05, 0xd5, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x00, 0x25, 0x13, 0x21, 0x01, - 0x23, 0x01, 0x33, 0x13, 0x21, 0x13, 0x33, 0x02, 0x69, 0xd5, 0xfe, 0x56, - 0x01, 0x4f, 0xf5, 0xfe, 0x37, 0xd1, 0x6e, 0x02, 0x0b, 0x6c, 0xd1, 0xb2, - 0x02, 0xfc, 0xfc, 0x52, 0x05, 0xd5, 0xfe, 0x7b, 0x01, 0x85, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x6a, 0xff, 0xe3, 0x04, 0x52, 0x05, 0xf0, 0x00, 0x13, - 0x00, 0x22, 0x00, 0x00, 0x25, 0x15, 0x23, 0x11, 0x33, 0x15, 0x36, 0x37, - 0x36, 0x33, 0x32, 0x17, 0x16, 0x11, 0x10, 0x00, 0x23, 0x22, 0x27, 0x26, - 0x00, 0x10, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x11, 0x10, 0x17, 0x16, - 0x33, 0x32, 0x37, 0x01, 0x22, 0xb8, 0xb8, 0x33, 0x55, 0x56, 0x6e, 0xe1, - 0x81, 0x82, 0xfe, 0xfc, 0xe0, 0x70, 0x56, 0x54, 0x02, 0x2b, 0x4d, 0x4c, - 0x95, 0x94, 0x4e, 0x4d, 0x4d, 0x4e, 0x94, 0x95, 0x4c, 0x92, 0x94, 0x05, - 0xd5, 0xc1, 0x6c, 0x39, 0x39, 0xcf, 0xd1, 0xfe, 0x94, 0xfe, 0x99, 0xfe, - 0x66, 0x2d, 0x2c, 0x01, 0x80, 0x02, 0x5b, 0x9b, 0x9a, 0x9c, 0x99, 0xfe, - 0xd3, 0xfe, 0xd1, 0x99, 0x9b, 0x9a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x89, - 0x00, 0x00, 0x04, 0x48, 0x05, 0xd5, 0x00, 0x07, 0x00, 0x00, 0x13, 0x33, - 0x11, 0x21, 0x15, 0x21, 0x11, 0x23, 0x89, 0xcb, 0x02, 0xf4, 0xfd, 0x0c, - 0xcb, 0x05, 0xd5, 0xfd, 0x9c, 0xaa, 0xfd, 0x39, 0x00, 0x01, 0x00, 0xc3, - 0x00, 0x00, 0x04, 0x1a, 0x04, 0x60, 0x00, 0x07, 0x00, 0x00, 0x01, 0x11, - 0x23, 0x11, 0x33, 0x11, 0x21, 0x15, 0x01, 0x7b, 0xb8, 0xb8, 0x02, 0x9f, - 0x02, 0x03, 0xfd, 0xfd, 0x04, 0x60, 0xfe, 0x39, 0x96, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x4c, 0xff, 0xe7, 0x04, 0x85, 0x04, 0x68, 0x00, 0x0a, - 0x00, 0x27, 0x00, 0x00, 0x01, 0x22, 0x15, 0x11, 0x32, 0x37, 0x36, 0x35, - 0x34, 0x27, 0x26, 0x27, 0x32, 0x17, 0x16, 0x11, 0x10, 0x07, 0x06, 0x23, - 0x07, 0x22, 0x27, 0x26, 0x11, 0x10, 0x37, 0x36, 0x37, 0x15, 0x06, 0x07, - 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x11, 0x10, 0x03, 0x05, 0x41, 0x5c, - 0x56, 0x4d, 0x4d, 0x47, 0x2a, 0x8a, 0x77, 0x7f, 0x7f, 0x81, 0xc1, 0xb7, - 0xc7, 0x7c, 0x7e, 0x7e, 0x68, 0x9a, 0x41, 0x31, 0x4c, 0x4c, 0x4e, 0x65, - 0x03, 0xcb, 0x91, 0xfd, 0x52, 0x68, 0x5d, 0xdf, 0xdd, 0x63, 0x5b, 0x9d, - 0x84, 0x8d, 0xfe, 0xd9, 0xfe, 0xe6, 0x96, 0x98, 0x01, 0x99, 0x9b, 0x01, - 0x14, 0x01, 0x2c, 0x84, 0x6d, 0x1c, 0xa3, 0x1a, 0x4b, 0x73, 0xbe, 0xd8, - 0x65, 0x67, 0x02, 0xaf, 0x01, 0x2e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x98, - 0xff, 0xe5, 0x03, 0xb1, 0x06, 0x14, 0x00, 0x19, 0x00, 0x00, 0x21, 0x23, - 0x35, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x27, 0x35, 0x1e, 0x01, 0x33, 0x32, - 0x36, 0x35, 0x11, 0x34, 0x26, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x16, 0x15, - 0x03, 0xb1, 0xb9, 0x2e, 0xbf, 0x83, 0x44, 0x76, 0x36, 0x3b, 0x7a, 0x49, - 0xac, 0xb6, 0x4d, 0x63, 0xd1, 0xdd, 0xb3, 0xaa, 0xdb, 0x77, 0x7f, 0x22, - 0x24, 0xbc, 0x2e, 0x2a, 0xd8, 0xcc, 0x02, 0x90, 0x67, 0x51, 0x99, 0xae, - 0xb8, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, - 0x04, 0x7b, 0x00, 0x07, 0x00, 0x0f, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x22, - 0x06, 0x14, 0x16, 0x32, 0x36, 0x34, 0x00, 0x20, 0x12, 0x10, 0x02, 0x20, - 0x02, 0x10, 0x01, 0x10, 0x20, 0x11, 0x14, 0x17, 0x36, 0x37, 0x36, 0x33, - 0x32, 0x17, 0x16, 0x17, 0x36, 0x02, 0xad, 0x86, 0x5e, 0x5c, 0x87, 0x60, - 0xfe, 0x73, 0x01, 0xd2, 0xf7, 0xf6, 0xfe, 0x2d, 0xf6, 0x02, 0xfc, 0xfd, - 0xc7, 0x06, 0x16, 0x21, 0x5c, 0x85, 0x87, 0x5b, 0x1e, 0x15, 0x06, 0x01, - 0xc0, 0x5e, 0x88, 0x5b, 0x5d, 0x85, 0x03, 0x1a, 0xfe, 0xd2, 0xfd, 0xc3, - 0xfe, 0xd3, 0x01, 0x2d, 0x02, 0x3d, 0xfe, 0xe2, 0x01, 0xb0, 0xfe, 0x50, - 0x40, 0x37, 0x27, 0x22, 0x5d, 0x5f, 0x1e, 0x24, 0x35, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x01, 0xe6, 0xff, 0x11, 0x02, 0xeb, 0x03, 0x68, 0x12, 0x07, - 0x02, 0x58, 0x00, 0x00, 0xfd, 0x64, 0x00, 0x00, 0x00, 0x01, 0x01, 0x08, - 0x02, 0x9c, 0x03, 0xc9, 0x05, 0xe0, 0x00, 0x06, 0x00, 0x00, 0x01, 0x13, - 0x33, 0x01, 0x23, 0x01, 0x33, 0x02, 0x68, 0xdd, 0x84, 0xfe, 0xed, 0x9b, - 0xfe, 0xed, 0x84, 0x02, 0xfb, 0x02, 0xe5, 0xfc, 0xbc, 0x03, 0x44, 0x00, - 0x00, 0x01, 0x00, 0x8b, 0xfe, 0x10, 0x04, 0x8f, 0x05, 0xf0, 0x00, 0x38, - 0x00, 0x00, 0x01, 0x15, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x15, 0x14, 0x16, - 0x1f, 0x01, 0x1e, 0x01, 0x15, 0x14, 0x07, 0x06, 0x07, 0x17, 0x16, 0x3b, - 0x01, 0x15, 0x23, 0x22, 0x2e, 0x03, 0x2f, 0x01, 0x2e, 0x01, 0x27, 0x26, - 0x27, 0x35, 0x1e, 0x01, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x2f, 0x01, - 0x26, 0x27, 0x26, 0x35, 0x34, 0x24, 0x33, 0x32, 0x16, 0x03, 0xf4, 0x5c, - 0xb9, 0x5e, 0x8f, 0xa6, 0x6d, 0x95, 0x6a, 0xd2, 0xc0, 0x84, 0x6a, 0xb7, - 0x82, 0xba, 0x96, 0x18, 0x33, 0x21, 0x32, 0x5f, 0x50, 0x66, 0x2d, 0xde, - 0x14, 0x45, 0x1d, 0x66, 0x6f, 0x73, 0xcd, 0x68, 0x99, 0xaa, 0x75, 0x91, - 0x6c, 0xd1, 0x5d, 0x5e, 0x01, 0x0d, 0xdf, 0x56, 0xbe, 0x05, 0xa2, 0xcd, - 0x3b, 0x3c, 0x85, 0x71, 0x63, 0x68, 0x23, 0x18, 0x31, 0xd2, 0xb5, 0xd5, - 0x70, 0x5a, 0x12, 0x89, 0xa4, 0xaa, 0x03, 0x12, 0x22, 0x44, 0x30, 0xec, - 0x16, 0x37, 0x06, 0x14, 0x2f, 0xd7, 0x49, 0x44, 0x89, 0x7b, 0x70, 0x76, - 0x20, 0x19, 0x30, 0x5e, 0x5f, 0xa0, 0xc8, 0xf1, 0x27, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x9c, 0xfe, 0x10, 0x04, 0x92, 0x05, 0xd5, 0x00, 0x1a, - 0x00, 0x00, 0x33, 0x35, 0x01, 0x21, 0x35, 0x21, 0x15, 0x01, 0x16, 0x1f, - 0x01, 0x1e, 0x03, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x2e, 0x02, 0x2f, 0x01, - 0x26, 0x23, 0x9c, 0x02, 0xf7, 0xfd, 0x1f, 0x03, 0xc9, 0xfc, 0xf4, 0x66, - 0x61, 0xd4, 0x2d, 0x42, 0x51, 0x4f, 0x28, 0x51, 0x72, 0x20, 0x4c, 0x63, - 0x75, 0x39, 0xfd, 0x42, 0x5f, 0x9a, 0x04, 0x91, 0xaa, 0x9a, 0xfb, 0x6f, - 0x0e, 0x5e, 0xcd, 0x2c, 0x39, 0x37, 0x1b, 0xaa, 0x11, 0x26, 0x50, 0x37, - 0xf3, 0x3f, 0x00, 0x00, 0x00, 0x03, 0x00, 0xc1, 0xff, 0xe5, 0x03, 0xdd, - 0x05, 0xd5, 0x00, 0x17, 0x00, 0x1b, 0x00, 0x25, 0x00, 0x00, 0x01, 0x33, - 0x11, 0x36, 0x37, 0x36, 0x37, 0x15, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, - 0x26, 0x35, 0x34, 0x37, 0x36, 0x3f, 0x01, 0x3e, 0x01, 0x35, 0x13, 0x15, - 0x23, 0x35, 0x13, 0x11, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, - 0x02, 0x25, 0xbe, 0x1f, 0x20, 0x59, 0x62, 0x5e, 0x60, 0x5f, 0x68, 0xba, - 0x6f, 0x6e, 0x22, 0x21, 0x5e, 0x58, 0x45, 0x26, 0xc5, 0xcb, 0x06, 0x2d, - 0x3e, 0x17, 0x18, 0x42, 0x25, 0x04, 0x44, 0xfc, 0x53, 0x08, 0x0c, 0x23, - 0x44, 0xbc, 0x39, 0x1c, 0x1c, 0x60, 0x60, 0xa1, 0x4c, 0x41, 0x42, 0x5c, - 0x56, 0x42, 0x54, 0x3d, 0x02, 0x3b, 0xfe, 0xfe, 0xfa, 0xbe, 0x01, 0xae, - 0x2d, 0x3b, 0x2c, 0x2c, 0x31, 0x59, 0x37, 0x1f, 0xff, 0xff, 0x00, 0x58, - 0x00, 0x86, 0x04, 0x79, 0x03, 0x12, 0x10, 0x26, 0x08, 0x3b, 0x00, 0x00, - 0x10, 0x07, 0x08, 0x9a, 0x00, 0x01, 0xfe, 0x57, 0x00, 0x01, 0x01, 0xcf, - 0x03, 0x3a, 0x03, 0x77, 0x06, 0x14, 0x00, 0x05, 0x00, 0x00, 0x01, 0x21, - 0x15, 0x23, 0x11, 0x23, 0x01, 0xcf, 0x01, 0xa8, 0xf0, 0xb8, 0x06, 0x14, - 0x8f, 0xfd, 0xb5, 0x00, 0x00, 0x01, 0x01, 0x5a, 0x03, 0x3a, 0x03, 0x02, - 0x06, 0x14, 0x00, 0x05, 0x00, 0x00, 0x01, 0x23, 0x35, 0x21, 0x11, 0x23, - 0x02, 0x4a, 0xf0, 0x01, 0xa8, 0xb8, 0x05, 0x85, 0x8f, 0xfd, 0x26, 0x00, - 0x00, 0x01, 0x01, 0xcf, 0xfe, 0xf2, 0x03, 0x77, 0x01, 0xcc, 0x00, 0x05, - 0x00, 0x00, 0x05, 0x33, 0x15, 0x21, 0x11, 0x33, 0x02, 0x87, 0xf0, 0xfe, - 0x58, 0xb8, 0x7f, 0x8f, 0x02, 0xda, 0x00, 0x00, 0x00, 0x01, 0x01, 0x5a, - 0xfe, 0xf2, 0x03, 0x02, 0x01, 0xcc, 0x00, 0x05, 0x00, 0x00, 0x01, 0x21, - 0x35, 0x33, 0x11, 0x33, 0x03, 0x02, 0xfe, 0x58, 0xf0, 0xb8, 0xfe, 0xf2, - 0x8f, 0x02, 0x4b, 0x00, 0xff, 0xff, 0x00, 0xda, 0x00, 0x00, 0x03, 0xf7, - 0x05, 0xf0, 0x10, 0x06, 0x04, 0x50, 0x00, 0x00, 0x00, 0x02, 0x01, 0x2c, - 0x00, 0x00, 0x03, 0xa5, 0x05, 0x58, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, - 0x01, 0x33, 0x15, 0x23, 0x01, 0x11, 0x33, 0x11, 0x01, 0x2c, 0xaa, 0xaa, - 0x01, 0xf1, 0x88, 0x05, 0x58, 0x88, 0xfb, 0x30, 0x05, 0x58, 0xfa, 0xa8, - 0x00, 0x02, 0x01, 0x2c, 0x00, 0x00, 0x03, 0xa5, 0x05, 0x58, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x00, 0x01, 0x33, 0x15, 0x23, 0x01, 0x11, 0x33, 0x11, - 0x01, 0x2c, 0xaa, 0xaa, 0x01, 0xf1, 0x88, 0x04, 0x24, 0x88, 0xfc, 0x64, - 0x05, 0x58, 0xfa, 0xa8, 0x00, 0x02, 0x01, 0x2c, 0x00, 0x00, 0x03, 0xa5, - 0x05, 0x58, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x01, 0x33, 0x15, 0x23, - 0x01, 0x11, 0x33, 0x11, 0x01, 0x2c, 0xaa, 0xaa, 0x01, 0xf1, 0x88, 0x02, - 0xf0, 0x88, 0xfd, 0x98, 0x05, 0x58, 0xfa, 0xa8, 0x00, 0x02, 0x01, 0x2c, - 0x00, 0x00, 0x03, 0xa5, 0x05, 0x58, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, - 0x01, 0x33, 0x15, 0x23, 0x01, 0x11, 0x33, 0x11, 0x01, 0x2c, 0xaa, 0xaa, - 0x01, 0xf1, 0x88, 0x01, 0xbc, 0x88, 0xfe, 0xcc, 0x05, 0x58, 0xfa, 0xa8, - 0x00, 0x02, 0x01, 0x2c, 0x00, 0x00, 0x03, 0xa5, 0x05, 0x58, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x00, 0x25, 0x33, 0x15, 0x23, 0x01, 0x33, 0x11, 0x23, - 0x01, 0x2c, 0xaa, 0xaa, 0x01, 0xf1, 0x88, 0x88, 0x88, 0x88, 0x05, 0x58, - 0xfa, 0xa8, 0x00, 0x00, 0x00, 0x02, 0x01, 0x2c, 0x00, 0x00, 0x03, 0xa5, - 0x05, 0x58, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x01, 0x33, 0x15, 0x23, - 0x01, 0x23, 0x11, 0x33, 0x02, 0xfb, 0xaa, 0xaa, 0xfe, 0xb9, 0x88, 0x88, - 0x05, 0x58, 0x88, 0xfb, 0x30, 0x05, 0x58, 0x00, 0x00, 0x02, 0x01, 0x2c, - 0x00, 0x00, 0x03, 0xa5, 0x05, 0x58, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, - 0x01, 0x33, 0x15, 0x23, 0x01, 0x23, 0x11, 0x33, 0x02, 0xfb, 0xaa, 0xaa, - 0xfe, 0xb9, 0x88, 0x88, 0x04, 0x24, 0x88, 0xfc, 0x64, 0x05, 0x58, 0x00, - 0x00, 0x02, 0x01, 0x2c, 0x00, 0x00, 0x03, 0xa5, 0x05, 0x58, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x00, 0x01, 0x33, 0x15, 0x23, 0x01, 0x23, 0x11, 0x33, - 0x02, 0xfb, 0xaa, 0xaa, 0xfe, 0xb9, 0x88, 0x88, 0x02, 0xf0, 0x88, 0xfd, - 0x98, 0x05, 0x58, 0x00, 0x00, 0x02, 0x01, 0x2c, 0x00, 0x00, 0x03, 0xa5, - 0x05, 0x58, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x01, 0x33, 0x15, 0x23, - 0x01, 0x23, 0x11, 0x33, 0x02, 0xfb, 0xaa, 0xaa, 0xfe, 0xb9, 0x88, 0x88, - 0x01, 0xbc, 0x88, 0xfe, 0xcc, 0x05, 0x58, 0x00, 0x00, 0x02, 0x01, 0x2c, - 0x00, 0x00, 0x03, 0xa5, 0x05, 0x58, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, - 0x25, 0x33, 0x15, 0x23, 0x21, 0x23, 0x11, 0x33, 0x02, 0xfb, 0xaa, 0xaa, - 0xfe, 0xb9, 0x88, 0x88, 0x88, 0x88, 0x05, 0x58, 0x00, 0x01, 0x01, 0x2c, - 0x00, 0x00, 0x03, 0xa5, 0x05, 0x58, 0x00, 0x05, 0x00, 0x00, 0x21, 0x23, - 0x11, 0x21, 0x15, 0x21, 0x01, 0xb4, 0x88, 0x02, 0x79, 0xfe, 0x0f, 0x05, - 0x58, 0x88, 0x00, 0x00, 0x00, 0x01, 0x01, 0x2c, 0x00, 0x00, 0x03, 0xa5, - 0x05, 0x58, 0x00, 0x07, 0x00, 0x00, 0x21, 0x23, 0x11, 0x33, 0x11, 0x21, - 0x15, 0x21, 0x01, 0xb4, 0x88, 0x88, 0x01, 0xf1, 0xfe, 0x0f, 0x05, 0x58, - 0xfe, 0xcc, 0x88, 0x00, 0x00, 0x01, 0x01, 0x2c, 0x00, 0x00, 0x03, 0xa5, - 0x05, 0x58, 0x00, 0x07, 0x00, 0x00, 0x21, 0x23, 0x11, 0x33, 0x11, 0x21, - 0x15, 0x21, 0x01, 0xb4, 0x88, 0x88, 0x01, 0xf1, 0xfe, 0x0f, 0x05, 0x58, - 0xfd, 0x98, 0x88, 0x00, 0x00, 0x01, 0x01, 0x2c, 0x00, 0x00, 0x03, 0xa5, - 0x05, 0x58, 0x00, 0x07, 0x00, 0x00, 0x21, 0x23, 0x11, 0x33, 0x11, 0x21, - 0x15, 0x21, 0x01, 0xb4, 0x88, 0x88, 0x01, 0xf1, 0xfe, 0x0f, 0x05, 0x58, - 0xfc, 0x64, 0x88, 0x00, 0x00, 0x01, 0x01, 0x2c, 0x00, 0x00, 0x03, 0xa5, - 0x05, 0x58, 0x00, 0x05, 0x00, 0x00, 0x25, 0x21, 0x15, 0x21, 0x11, 0x33, - 0x01, 0xb4, 0x01, 0xf1, 0xfd, 0x87, 0x88, 0x88, 0x88, 0x05, 0x58, 0x00, - 0x00, 0x01, 0x01, 0x54, 0x02, 0x9c, 0x03, 0x7c, 0x05, 0xe4, 0x00, 0x09, - 0x00, 0x00, 0x01, 0x33, 0x17, 0x07, 0x27, 0x11, 0x23, 0x11, 0x07, 0x27, - 0x02, 0x4c, 0x3a, 0xf6, 0x4c, 0x92, 0x6a, 0x94, 0x4c, 0x05, 0xe4, 0xdd, - 0x43, 0x83, 0xfd, 0x55, 0x02, 0xab, 0x83, 0x43, 0x00, 0x01, 0x01, 0x54, - 0x02, 0x98, 0x03, 0x7c, 0x05, 0xe0, 0x00, 0x09, 0x00, 0x00, 0x01, 0x23, - 0x27, 0x37, 0x17, 0x11, 0x33, 0x11, 0x37, 0x17, 0x02, 0x86, 0x3a, 0xf8, - 0x4c, 0x94, 0x6a, 0x92, 0x4c, 0x02, 0x98, 0xdd, 0x43, 0x83, 0x02, 0xab, - 0xfd, 0x55, 0x83, 0x43, 0x00, 0x02, 0x02, 0x28, 0x02, 0x9c, 0x02, 0xa8, - 0x05, 0xe0, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x01, 0x33, 0x15, 0x23, - 0x11, 0x33, 0x11, 0x07, 0x23, 0x27, 0x02, 0x28, 0x80, 0x80, 0x80, 0x0c, - 0x66, 0x0e, 0x03, 0x2a, 0x8e, 0x03, 0x44, 0xfe, 0x91, 0xc8, 0xc8, 0x00, - 0x00, 0x02, 0x02, 0x28, 0x02, 0x9c, 0x02, 0xa8, 0x05, 0xe0, 0x00, 0x03, - 0x00, 0x09, 0x00, 0x00, 0x01, 0x23, 0x35, 0x33, 0x11, 0x23, 0x11, 0x37, - 0x33, 0x17, 0x02, 0xa8, 0x80, 0x80, 0x80, 0x0c, 0x66, 0x0e, 0x05, 0x52, - 0x8e, 0xfc, 0xbc, 0x01, 0x6f, 0xc8, 0xc8, 0x00, 0xff, 0xff, 0x02, 0x28, - 0x00, 0x00, 0x02, 0xa8, 0x03, 0x44, 0x10, 0x07, 0x0b, 0x90, 0x00, 0x00, - 0xfd, 0x64, 0x00, 0x00, 0x00, 0x01, 0x01, 0x41, 0x00, 0x00, 0x03, 0xb7, - 0x05, 0xd4, 0x00, 0x10, 0x00, 0x00, 0x21, 0x35, 0x20, 0x02, 0x21, 0x35, - 0x20, 0x02, 0x21, 0x35, 0x20, 0x13, 0x16, 0x07, 0x16, 0x13, 0x12, 0x01, - 0x87, 0x01, 0x7c, 0x14, 0xfe, 0x84, 0x01, 0x7c, 0x1e, 0xfe, 0x70, 0x02, - 0x4f, 0x0e, 0x09, 0xae, 0xb8, 0x06, 0x0a, 0xa3, 0x02, 0x27, 0xa3, 0x01, - 0xc5, 0xa2, 0xfe, 0x8c, 0xe5, 0x63, 0x6d, 0xfe, 0xfb, 0xfe, 0x5a, 0x00, - 0x00, 0x01, 0x01, 0x6e, 0x00, 0x00, 0x03, 0x9e, 0x04, 0x60, 0x00, 0x10, - 0x00, 0x00, 0x21, 0x35, 0x20, 0x02, 0x21, 0x35, 0x20, 0x02, 0x21, 0x35, - 0x20, 0x13, 0x16, 0x07, 0x16, 0x17, 0x12, 0x01, 0xa0, 0x01, 0x54, 0x14, - 0xfe, 0xac, 0x01, 0x54, 0x1e, 0xfe, 0xac, 0x02, 0x09, 0x0e, 0x08, 0x84, - 0x8f, 0x06, 0x0a, 0x99, 0x01, 0x7c, 0x99, 0x01, 0x1a, 0x98, 0xfe, 0xe8, - 0x9e, 0x4d, 0x59, 0xbc, 0xfe, 0xb8, 0x00, 0x00, 0x00, 0x01, 0x00, 0xeb, - 0x01, 0xcb, 0x03, 0xf4, 0x05, 0xf0, 0x00, 0x09, 0x00, 0x00, 0x01, 0x10, - 0x17, 0x07, 0x02, 0x35, 0x10, 0x21, 0x15, 0x20, 0x01, 0xa5, 0x75, 0xa4, - 0x8b, 0x03, 0x09, 0xfd, 0xb1, 0x03, 0xcd, 0xfe, 0xfe, 0xd2, 0x2e, 0x01, - 0x31, 0xd4, 0x02, 0x20, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xeb, - 0x00, 0x56, 0x03, 0xf4, 0x04, 0x7b, 0x00, 0x09, 0x00, 0x00, 0x01, 0x10, - 0x17, 0x07, 0x02, 0x35, 0x10, 0x21, 0x15, 0x20, 0x01, 0xa5, 0x75, 0xa4, - 0x8b, 0x03, 0x09, 0xfd, 0xb1, 0x02, 0x58, 0xfe, 0xfe, 0xd2, 0x2e, 0x01, - 0x31, 0xd4, 0x02, 0x20, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x89, - 0xfe, 0x56, 0x04, 0x48, 0x05, 0xd5, 0x00, 0x15, 0x00, 0x00, 0x01, 0x11, - 0x14, 0x07, 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x37, 0x36, 0x35, 0x11, - 0x21, 0x11, 0x23, 0x11, 0x33, 0x11, 0x21, 0x11, 0x04, 0x48, 0x59, 0x5a, - 0xa5, 0xcd, 0xa7, 0x5a, 0x2d, 0x2c, 0xfd, 0xd7, 0xcb, 0xcb, 0x02, 0x29, - 0x05, 0xd5, 0xfa, 0x17, 0xc3, 0x69, 0x6a, 0x9c, 0x3e, 0x3e, 0x92, 0x02, - 0xc7, 0xfd, 0x39, 0x05, 0xd5, 0xfd, 0x9c, 0x02, 0x64, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xc3, 0xfe, 0x56, 0x04, 0x1b, 0x06, 0x14, 0x00, 0x1d, - 0x00, 0x00, 0x01, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, 0x11, - 0x33, 0x11, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x15, 0x11, 0x14, 0x07, 0x06, - 0x2b, 0x01, 0x35, 0x33, 0x32, 0x37, 0x36, 0x35, 0x03, 0x62, 0x6a, 0x71, - 0x81, 0x8b, 0xb8, 0xb8, 0x31, 0xa8, 0x73, 0xab, 0xa9, 0x59, 0x5a, 0xa5, - 0xcd, 0xb9, 0x5a, 0x2d, 0x2c, 0x02, 0xb6, 0x97, 0x8e, 0xb7, 0xab, 0xfd, - 0x87, 0x06, 0x14, 0xfd, 0xa4, 0x60, 0x63, 0xe1, 0xe4, 0xfd, 0x36, 0xc3, - 0x69, 0x6a, 0x9c, 0x3e, 0x3e, 0x7e, 0x00, 0x00, 0xff, 0xff, 0x01, 0xe9, - 0x00, 0x00, 0x02, 0xe5, 0x04, 0x27, 0x12, 0x06, 0x00, 0x1d, 0x00, 0x00, - 0x00, 0x02, 0x01, 0x88, 0x01, 0x49, 0x03, 0x4a, 0x03, 0x0b, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x00, 0x01, 0x21, 0x35, 0x21, 0x35, 0x21, 0x35, 0x21, - 0x03, 0x4a, 0xfe, 0x3e, 0x01, 0xc2, 0xfe, 0x3e, 0x01, 0xc2, 0x01, 0x49, - 0x96, 0x96, 0x96, 0x00, 0x00, 0x01, 0x02, 0x04, 0x01, 0xe1, 0x02, 0xcf, - 0x05, 0xd5, 0x00, 0x05, 0x00, 0x00, 0x01, 0x33, 0x11, 0x03, 0x23, 0x03, - 0x02, 0x04, 0xcb, 0x15, 0xa1, 0x15, 0x05, 0xd5, 0xfd, 0x71, 0xfe, 0x9b, - 0x01, 0x65, 0x00, 0x00, 0x00, 0x01, 0x02, 0x10, 0x03, 0xaa, 0x02, 0xbe, - 0x05, 0xd5, 0x00, 0x03, 0x00, 0x12, 0xb7, 0x01, 0x00, 0x88, 0x04, 0x00, - 0x04, 0x02, 0x04, 0x10, 0xd4, 0xec, 0x31, 0x00, 0x10, 0xf4, 0xc4, 0x30, - 0x01, 0x11, 0x23, 0x11, 0x02, 0xbe, 0xae, 0x05, 0xd5, 0xfd, 0xd5, 0x02, - 0x2b, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0x00, 0x00, 0x04, 0x44, - 0x05, 0xd5, 0x12, 0x06, 0x03, 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x9d, - 0xfe, 0x56, 0x04, 0x34, 0x06, 0x1f, 0x00, 0x19, 0x00, 0x20, 0x00, 0x00, - 0x05, 0x14, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x26, 0x35, 0x11, 0x23, - 0x20, 0x35, 0x34, 0x33, 0x32, 0x17, 0x11, 0x21, 0x35, 0x21, 0x11, 0x33, - 0x15, 0x23, 0x27, 0x26, 0x23, 0x22, 0x15, 0x14, 0x33, 0x02, 0xaa, 0x5b, - 0x59, 0xd6, 0xe8, 0xa5, 0xb5, 0x3e, 0xfe, 0xe9, 0xf6, 0x35, 0x2a, 0xfe, - 0xd9, 0x01, 0xdf, 0xfa, 0xfa, 0xb8, 0x17, 0x47, 0x4e, 0x5c, 0x14, 0x7c, - 0x7e, 0x9c, 0xd4, 0xc2, 0x02, 0x86, 0xbd, 0xf6, 0x19, 0x01, 0x83, 0x90, - 0xfc, 0xf3, 0xa0, 0xa0, 0x84, 0x4b, 0x39, 0x00, 0x00, 0x01, 0x00, 0x54, - 0xfe, 0xbe, 0x04, 0x95, 0x05, 0xd5, 0x00, 0x0d, 0x00, 0x00, 0x13, 0x21, - 0x01, 0x11, 0x33, 0x11, 0x33, 0x11, 0x23, 0x11, 0x23, 0x01, 0x11, 0x23, - 0x54, 0x01, 0x00, 0x01, 0xf8, 0xc3, 0x86, 0xaa, 0xdc, 0xfe, 0x08, 0xc3, - 0x05, 0xd5, 0xfb, 0x33, 0x04, 0xcd, 0xfa, 0xd5, 0xfe, 0x14, 0x01, 0x42, - 0x04, 0xcd, 0xfb, 0x33, 0x00, 0x01, 0x00, 0x7a, 0xfe, 0xe2, 0x04, 0x5e, - 0x04, 0x7b, 0x00, 0x17, 0x00, 0x00, 0x01, 0x11, 0x33, 0x11, 0x23, 0x11, - 0x23, 0x11, 0x34, 0x26, 0x23, 0x22, 0x06, 0x15, 0x11, 0x23, 0x11, 0x33, - 0x15, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x03, 0xd2, 0x8c, 0x96, 0xaf, 0x6a, - 0x71, 0x81, 0x8b, 0xb8, 0xb8, 0x31, 0xa8, 0x73, 0xab, 0xa9, 0x02, 0xb6, - 0xfd, 0xe0, 0xfe, 0x4c, 0x01, 0x1e, 0x02, 0xb6, 0x97, 0x8e, 0xb7, 0xab, - 0xfd, 0x87, 0x04, 0x60, 0xa8, 0x60, 0x63, 0xe1, 0x00, 0x01, 0x00, 0x14, - 0x00, 0x00, 0x04, 0xaf, 0x05, 0xd5, 0x00, 0x14, 0x00, 0x00, 0x01, 0x22, - 0x06, 0x1d, 0x01, 0x23, 0x35, 0x34, 0x36, 0x3b, 0x01, 0x11, 0x21, 0x11, - 0x33, 0x11, 0x23, 0x11, 0x21, 0x11, 0x23, 0x01, 0x52, 0x3e, 0x64, 0x9c, - 0xa9, 0x95, 0xcb, 0x01, 0xc7, 0xcb, 0xcb, 0xfe, 0x39, 0xcb, 0x05, 0x2f, - 0x57, 0x70, 0x31, 0x46, 0x9f, 0xb9, 0xfd, 0x9c, 0x02, 0x64, 0xfa, 0x2b, - 0x02, 0xc7, 0xfd, 0x39, 0x00, 0x02, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, - 0x06, 0x15, 0x00, 0x0b, 0x00, 0x25, 0x00, 0x00, 0x01, 0x22, 0x06, 0x15, - 0x14, 0x16, 0x33, 0x32, 0x36, 0x35, 0x34, 0x26, 0x27, 0x36, 0x12, 0x11, - 0x10, 0x02, 0x23, 0x22, 0x02, 0x11, 0x34, 0x36, 0x37, 0x2e, 0x01, 0x35, - 0x34, 0x36, 0x33, 0x25, 0x15, 0x21, 0x22, 0x15, 0x14, 0x16, 0x02, 0x68, - 0x8c, 0x90, 0x90, 0x8c, 0x8d, 0x90, 0x90, 0x8d, 0xe8, 0xf8, 0xf6, 0xea, - 0xe9, 0xf6, 0x7b, 0x31, 0x50, 0x41, 0xc2, 0x9e, 0x01, 0xfc, 0xfe, 0x28, - 0xbc, 0x72, 0x03, 0xdf, 0xda, 0xd6, 0xd5, 0xdb, 0xdb, 0xd5, 0xd6, 0xda, - 0x9c, 0x01, 0xfe, 0xd1, 0xfe, 0xe2, 0xfe, 0xe1, 0xfe, 0xd3, 0x01, 0x2d, - 0x01, 0x1f, 0xe5, 0xd8, 0x2a, 0x2f, 0x8e, 0x31, 0x7c, 0x94, 0x01, 0x96, - 0x87, 0x49, 0x35, 0x00, 0x00, 0x02, 0x00, 0x23, 0x00, 0x00, 0x04, 0x37, - 0x06, 0x14, 0x00, 0x03, 0x00, 0x19, 0x00, 0x4e, 0x40, 0x2a, 0x14, 0x09, - 0x16, 0x02, 0x12, 0x0e, 0xb6, 0x0a, 0x05, 0x8c, 0x04, 0x02, 0xc4, 0x00, - 0x9b, 0x04, 0x9b, 0x0a, 0xc2, 0x10, 0x0c, 0x06, 0x19, 0x09, 0x04, 0x0d, - 0x00, 0x06, 0x01, 0x04, 0x0f, 0x09, 0x06, 0x0b, 0x01, 0x4a, 0x13, 0x45, - 0x15, 0x11, 0x45, 0x1a, 0x10, 0xf4, 0x3c, 0xe4, 0xec, 0x32, 0xfc, 0x3c, - 0xc4, 0x10, 0xee, 0x32, 0x11, 0x12, 0x39, 0x39, 0x31, 0x00, 0x2f, 0x3c, - 0xe6, 0xec, 0xfe, 0xee, 0x10, 0xee, 0x10, 0xee, 0x32, 0x12, 0x39, 0x39, - 0x39, 0x30, 0x01, 0x33, 0x15, 0x23, 0x27, 0x15, 0x23, 0x22, 0x06, 0x1d, - 0x01, 0x21, 0x11, 0x23, 0x11, 0x21, 0x11, 0x23, 0x11, 0x23, 0x35, 0x33, - 0x35, 0x34, 0x36, 0x33, 0x03, 0x7f, 0xb8, 0xb8, 0x77, 0xb4, 0x63, 0x4d, - 0x02, 0x93, 0xb8, 0xfe, 0x25, 0xb8, 0xc9, 0xc9, 0xa9, 0xb3, 0x06, 0x12, - 0xe9, 0xeb, 0x99, 0x51, 0x67, 0x65, 0xfb, 0xa2, 0x03, 0xd1, 0xfc, 0x2f, - 0x03, 0xd1, 0x8f, 0x4e, 0xb8, 0xae, 0x00, 0x00, 0x00, 0x01, 0x00, 0x23, - 0x00, 0x00, 0x04, 0x37, 0x06, 0x14, 0x00, 0x15, 0x00, 0x42, 0x40, 0x23, - 0x10, 0x07, 0x12, 0x03, 0x0e, 0x0a, 0xb6, 0x08, 0x03, 0x8c, 0x00, 0x9b, - 0x08, 0xc2, 0x0c, 0x01, 0x04, 0x15, 0x09, 0x07, 0x02, 0x06, 0x00, 0x09, - 0x0b, 0x07, 0x06, 0x00, 0x4a, 0x0f, 0x45, 0x11, 0x0d, 0x45, 0x16, 0x10, - 0xf4, 0x3c, 0xe4, 0xec, 0xfc, 0x3c, 0xc4, 0x10, 0xee, 0x11, 0x12, 0x39, - 0x39, 0x31, 0x00, 0x2f, 0x3c, 0xe6, 0xfe, 0xee, 0x10, 0xee, 0x32, 0x12, - 0x39, 0x39, 0x39, 0x30, 0x01, 0x11, 0x23, 0x11, 0x21, 0x22, 0x06, 0x1d, - 0x01, 0x21, 0x15, 0x21, 0x11, 0x23, 0x11, 0x23, 0x35, 0x33, 0x35, 0x34, - 0x36, 0x33, 0x04, 0x37, 0xb8, 0xfe, 0xd5, 0x63, 0x4d, 0x01, 0x25, 0xfe, - 0xdb, 0xb8, 0xc9, 0xc9, 0xa9, 0xb3, 0x06, 0x14, 0xf9, 0xec, 0x05, 0x7b, - 0x51, 0x67, 0x65, 0x8d, 0xfc, 0x2f, 0x03, 0xd1, 0x8f, 0x4e, 0xb8, 0xae, - 0xff, 0xff, 0x00, 0x45, 0xfe, 0x0c, 0x04, 0xb0, 0x02, 0x1b, 0x10, 0x26, - 0x0c, 0xe0, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xda, 0x02, 0x1e, 0xff, 0x06, - 0xff, 0xff, 0x00, 0x45, 0xfe, 0x0c, 0x04, 0xe5, 0x02, 0x1c, 0x10, 0x26, - 0x0c, 0xd4, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xda, 0x01, 0xfc, 0xff, 0x06, - 0xff, 0xff, 0xff, 0xec, 0xfe, 0x0c, 0x02, 0xbc, 0x02, 0x58, 0x10, 0x26, - 0x0b, 0xe6, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xda, 0x02, 0x0c, 0xff, 0x06, - 0xff, 0xff, 0xff, 0xec, 0xfe, 0x0c, 0x04, 0xe5, 0x02, 0x58, 0x10, 0x26, - 0x0b, 0xe7, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xda, 0x02, 0x0c, 0xff, 0x06, - 0xff, 0xff, 0x00, 0x45, 0xfe, 0x0c, 0x04, 0xb0, 0x02, 0x1b, 0x10, 0x26, - 0x0c, 0xe0, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd9, 0x01, 0xbd, 0xff, 0x06, - 0xff, 0xff, 0x00, 0x45, 0xfe, 0x0c, 0x04, 0xe5, 0x02, 0x1c, 0x10, 0x26, - 0x0c, 0xd4, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd9, 0x01, 0x78, 0xff, 0x06, - 0xff, 0xff, 0xff, 0xec, 0xfe, 0x0c, 0x03, 0x1c, 0x02, 0x58, 0x10, 0x26, - 0x0b, 0xe6, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd9, 0x01, 0x8c, 0xff, 0x06, - 0xff, 0xff, 0xff, 0xec, 0xfe, 0x0c, 0x04, 0xe5, 0x02, 0x58, 0x10, 0x26, - 0x0b, 0xe7, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd9, 0x01, 0x8c, 0xff, 0x06, - 0xff, 0xff, 0x00, 0x45, 0xfe, 0x0c, 0x04, 0xb0, 0x02, 0x1b, 0x10, 0x26, - 0x0c, 0xe0, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xdb, 0x01, 0x93, 0xff, 0x06, - 0xff, 0xff, 0x00, 0x45, 0xfe, 0x0c, 0x04, 0xe5, 0x02, 0x1c, 0x10, 0x26, - 0x0c, 0xd4, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xdb, 0x01, 0x72, 0xff, 0x06, - 0xff, 0xff, 0xff, 0xec, 0xfe, 0x0c, 0x03, 0x0a, 0x02, 0x58, 0x10, 0x26, - 0x0b, 0xe6, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xdb, 0x01, 0x7a, 0xff, 0x06, - 0xff, 0xff, 0xff, 0xec, 0xfe, 0x0c, 0x04, 0xe5, 0x02, 0x58, 0x10, 0x26, - 0x0b, 0xe7, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xdb, 0x01, 0x98, 0xff, 0x06, - 0xff, 0xff, 0x00, 0x45, 0xff, 0xec, 0x04, 0xb0, 0x03, 0xbd, 0x10, 0x26, - 0x0c, 0xe0, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xda, 0x02, 0x37, 0x03, 0x27, - 0xff, 0xff, 0x00, 0x45, 0xff, 0xec, 0x04, 0xe5, 0x03, 0xc3, 0x10, 0x26, - 0x0c, 0xd4, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xda, 0x02, 0x01, 0x03, 0x2d, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x02, 0xbc, 0x04, 0x78, 0x10, 0x26, - 0x0b, 0xe6, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xda, 0x02, 0x10, 0x03, 0xe2, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x04, 0xe5, 0x04, 0x6d, 0x10, 0x26, - 0x0b, 0xe7, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xda, 0x02, 0x0f, 0x03, 0xd7, - 0xff, 0xff, 0x00, 0x45, 0xff, 0xec, 0x04, 0xb0, 0x04, 0x1a, 0x10, 0x26, - 0x0c, 0xe0, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xdb, 0x01, 0x93, 0x03, 0x84, - 0xff, 0xff, 0x00, 0x45, 0xff, 0xec, 0x04, 0xe5, 0x04, 0x1a, 0x10, 0x27, - 0x0c, 0xdb, 0x01, 0x81, 0x03, 0x84, 0x10, 0x06, 0x0c, 0xd4, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x03, 0x1f, 0x04, 0x79, 0x10, 0x26, - 0x0b, 0xe6, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xdb, 0x01, 0x8f, 0x03, 0xe3, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x04, 0xe5, 0x04, 0x7c, 0x10, 0x26, - 0x0b, 0xe7, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xdb, 0x01, 0x8c, 0x03, 0xe6, - 0xff, 0xff, 0x00, 0x45, 0xff, 0xec, 0x04, 0xb0, 0x04, 0x57, 0x10, 0x26, - 0x0c, 0xe0, 0x00, 0x00, 0x10, 0x07, 0x04, 0x4e, 0x00, 0x4c, 0xfd, 0x66, - 0xff, 0xff, 0x00, 0x45, 0xff, 0xec, 0x04, 0xe5, 0x04, 0x48, 0x10, 0x27, - 0x04, 0x4e, 0x00, 0x34, 0xfd, 0x57, 0x10, 0x06, 0x0c, 0xd4, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x03, 0xb8, 0x04, 0xf5, 0x10, 0x26, - 0x0b, 0xe6, 0x00, 0x00, 0x10, 0x07, 0x04, 0x4e, 0x00, 0x4b, 0xfe, 0x04, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x04, 0xe5, 0x05, 0x04, 0x10, 0x26, - 0x0b, 0xe7, 0x00, 0x00, 0x10, 0x07, 0x04, 0x4e, 0x00, 0x5d, 0xfe, 0x13, - 0xff, 0xff, 0xff, 0xb6, 0xff, 0xa4, 0x04, 0x8c, 0x05, 0x72, 0x10, 0x26, - 0x0c, 0xe8, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd3, 0x02, 0x74, 0x03, 0xe2, - 0xff, 0xff, 0xff, 0x6a, 0xff, 0xa5, 0x04, 0xe5, 0x05, 0x06, 0x10, 0x27, - 0x0c, 0xd3, 0x02, 0x84, 0x03, 0x76, 0x10, 0x06, 0x0c, 0xd8, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x03, 0x3f, 0x06, 0x0e, 0x10, 0x27, - 0x0c, 0xd3, 0x01, 0x2c, 0x04, 0x7e, 0x10, 0x06, 0x0c, 0xd5, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x04, 0xe5, 0x05, 0x10, 0x10, 0x27, - 0x0c, 0xd3, 0x01, 0x96, 0x03, 0x80, 0x10, 0x06, 0x0c, 0xd6, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xb6, 0xff, 0xa4, 0x04, 0x8c, 0x05, 0x7e, 0x10, 0x26, - 0x0c, 0xe8, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xdb, 0x02, 0x88, 0x04, 0xe8, - 0xff, 0xff, 0xff, 0x6a, 0xff, 0xa5, 0x04, 0xe5, 0x05, 0x0a, 0x10, 0x27, - 0x0c, 0xdb, 0x02, 0x8c, 0x04, 0x74, 0x10, 0x06, 0x0c, 0xd8, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x03, 0x3f, 0x06, 0x0e, 0x10, 0x27, - 0x0c, 0xdb, 0x01, 0x2c, 0x05, 0x78, 0x10, 0x06, 0x0c, 0xd5, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x04, 0xe5, 0x05, 0x20, 0x10, 0x27, - 0x0c, 0xdb, 0x01, 0x9a, 0x04, 0x8a, 0x10, 0x06, 0x0c, 0xd6, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x58, 0xfe, 0x0c, 0x04, 0xad, 0x03, 0x66, 0x10, 0x26, - 0x04, 0x5d, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xda, 0x02, 0x7b, 0x00, 0xaf, - 0xff, 0xff, 0x00, 0x58, 0xfe, 0x0c, 0x04, 0xf9, 0x03, 0x66, 0x10, 0x26, - 0x0c, 0x1d, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xda, 0x02, 0x2f, 0x00, 0x7d, - 0xff, 0xff, 0xff, 0xec, 0xfe, 0x3e, 0x04, 0x5c, 0x03, 0x2f, 0x10, 0x27, - 0x0c, 0xda, 0x01, 0x61, 0xff, 0x38, 0x10, 0x06, 0x0c, 0x1e, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0xfe, 0x3e, 0x04, 0xfc, 0x03, 0x2f, 0x10, 0x27, - 0x0c, 0xda, 0x02, 0x0d, 0xff, 0x38, 0x10, 0x06, 0x0c, 0x1f, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x58, 0xfe, 0x0c, 0x04, 0xad, 0x03, 0x66, 0x10, 0x26, - 0x04, 0x5d, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd2, 0x02, 0x8a, 0x00, 0x19, - 0xff, 0xff, 0x00, 0x58, 0xfe, 0x0c, 0x04, 0xf9, 0x03, 0x66, 0x10, 0x26, - 0x0c, 0x1d, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd2, 0x02, 0x26, 0xff, 0xe7, - 0xff, 0xff, 0xff, 0xec, 0xff, 0x38, 0x04, 0x5c, 0x03, 0x2f, 0x10, 0x27, - 0x0c, 0xd2, 0x00, 0xbc, 0xff, 0x38, 0x10, 0x06, 0x0c, 0x1e, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0xff, 0x38, 0x04, 0xfc, 0x03, 0x2f, 0x10, 0x27, - 0x0c, 0xd2, 0x01, 0x90, 0xff, 0x38, 0x10, 0x06, 0x0c, 0x1f, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x58, 0xfe, 0x0c, 0x04, 0xad, 0x03, 0x66, 0x10, 0x26, - 0x04, 0x5d, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd9, 0x02, 0x2a, 0x00, 0x96, - 0xff, 0xff, 0x00, 0x58, 0xfe, 0x0c, 0x04, 0xf9, 0x03, 0x66, 0x10, 0x26, - 0x0c, 0x1d, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd9, 0x01, 0xc5, 0x00, 0x42, - 0xff, 0xff, 0xff, 0xec, 0xfe, 0x16, 0x04, 0x5c, 0x03, 0x2f, 0x10, 0x27, - 0x0c, 0xd9, 0x00, 0xf0, 0xff, 0x10, 0x10, 0x06, 0x0c, 0x1e, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0xfe, 0x3e, 0x04, 0xfc, 0x03, 0x2f, 0x10, 0x27, - 0x0c, 0xd9, 0x01, 0x90, 0xff, 0x38, 0x10, 0x06, 0x0c, 0x1f, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x58, 0xfe, 0x0c, 0x04, 0xad, 0x03, 0x66, 0x10, 0x26, - 0x04, 0x5d, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xdb, 0x02, 0x32, 0x00, 0xaf, - 0xff, 0xff, 0x00, 0x58, 0xfe, 0x0c, 0x04, 0xf9, 0x03, 0x66, 0x10, 0x26, - 0x0c, 0x1d, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xdb, 0x01, 0xc5, 0x00, 0x5e, - 0xff, 0xff, 0xff, 0xec, 0xfe, 0x16, 0x04, 0x5c, 0x03, 0x2f, 0x10, 0x27, - 0x0c, 0xdb, 0x00, 0xfc, 0xff, 0x10, 0x10, 0x06, 0x0c, 0x1e, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0xfe, 0x3e, 0x04, 0xfc, 0x03, 0x2f, 0x10, 0x27, - 0x0c, 0xdb, 0x01, 0x90, 0xff, 0x38, 0x10, 0x06, 0x0c, 0x1f, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xcc, 0xfe, 0x08, 0x04, 0x61, 0x04, 0x37, 0x10, 0x26, - 0x04, 0x61, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd3, 0x02, 0xd0, 0x02, 0xa6, - 0xff, 0xff, 0xff, 0x60, 0xfe, 0x0c, 0x04, 0xe5, 0x04, 0x44, 0x10, 0x27, - 0x0c, 0xd3, 0x02, 0x5c, 0x02, 0xb4, 0x10, 0x06, 0x0c, 0x29, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xcc, 0xfe, 0x08, 0x04, 0xc2, 0x04, 0x9b, 0x10, 0x27, - 0x04, 0x4e, 0x01, 0x55, 0xfd, 0xaa, 0x10, 0x06, 0x04, 0x61, 0x00, 0x00, - 0xff, 0xff, 0xff, 0x60, 0xfe, 0x0c, 0x04, 0xe5, 0x04, 0x84, 0x10, 0x27, - 0x04, 0x4e, 0x00, 0xe9, 0xfd, 0x93, 0x10, 0x06, 0x0c, 0x29, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x0a, 0xff, 0xa7, 0x05, 0x5d, 0x06, 0x14, 0x10, 0x06, - 0x04, 0x9e, 0x00, 0x00, 0x00, 0x01, 0xff, 0x83, 0xff, 0xa7, 0x05, 0x1a, - 0x06, 0x14, 0x00, 0x32, 0x00, 0x00, 0x25, 0x06, 0x07, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x24, 0x11, 0x34, 0x37, 0x33, 0x06, 0x15, 0x14, 0x17, - 0x16, 0x33, 0x32, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x03, 0x26, 0x35, - 0x34, 0x37, 0x36, 0x37, 0x01, 0x15, 0x01, 0x06, 0x15, 0x14, 0x17, 0x01, - 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, 0x26, 0x27, 0x03, 0xf5, 0x19, - 0x30, 0x51, 0x80, 0x63, 0xcf, 0x70, 0x6c, 0xfe, 0xb6, 0x3f, 0xb8, 0x41, - 0xcb, 0x4f, 0x4c, 0xa2, 0xda, 0x36, 0x34, 0x29, 0xb6, 0x3e, 0x12, 0x2e, - 0x56, 0x02, 0x0e, 0xfe, 0x68, 0x46, 0x12, 0x01, 0x64, 0x28, 0x28, 0x26, - 0x2a, 0x3d, 0x23, 0x3e, 0x14, 0xb6, 0x32, 0x28, 0x49, 0x3d, 0x2f, 0x20, - 0x62, 0x01, 0x0b, 0x8a, 0x5c, 0x5e, 0x88, 0x78, 0x48, 0x1c, 0x6a, 0x3c, - 0x39, 0x22, 0x31, 0x42, 0x01, 0x2c, 0x66, 0x25, 0x54, 0x1f, 0x4f, 0x41, - 0x01, 0x8e, 0xd1, 0xfe, 0xc2, 0x37, 0x2e, 0x4e, 0x1d, 0xfd, 0xc2, 0x3f, - 0xb8, 0x12, 0x1e, 0x1e, 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x04, 0x2b, - 0x06, 0x14, 0x10, 0x06, 0x0c, 0x56, 0x00, 0x00, 0xff, 0xff, 0xff, 0xec, - 0x00, 0x00, 0x04, 0xe6, 0x06, 0x14, 0x10, 0x06, 0x0c, 0x57, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x0a, 0xff, 0xa7, 0x05, 0x63, 0x07, 0x47, 0x10, 0x26, - 0x04, 0x9e, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xdc, 0x02, 0xac, 0x00, 0x0e, - 0xff, 0xff, 0xff, 0x83, 0xff, 0xa7, 0x05, 0x1a, 0x07, 0x4a, 0x10, 0x27, - 0x0c, 0xdc, 0x02, 0x54, 0x00, 0x12, 0x10, 0x06, 0x0b, 0xd9, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x04, 0x2b, 0x07, 0x39, 0x10, 0x27, - 0x0c, 0xdd, 0x00, 0x8f, 0x00, 0x00, 0x10, 0x06, 0x0b, 0xda, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x04, 0xe6, 0x07, 0x39, 0x10, 0x27, - 0x0c, 0xdd, 0x00, 0x9c, 0x00, 0x00, 0x10, 0x06, 0x0b, 0xdb, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x36, 0xfe, 0xb5, 0x04, 0x8d, 0x02, 0xb0, 0x10, 0x06, - 0x0c, 0xea, 0x00, 0x00, 0x00, 0x01, 0xff, 0xd5, 0xfe, 0x0c, 0x04, 0xe6, - 0x02, 0x0c, 0x00, 0x26, 0x00, 0x00, 0x01, 0x06, 0x07, 0x06, 0x23, 0x22, - 0x27, 0x26, 0x11, 0x34, 0x37, 0x33, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, - 0x32, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x33, 0x16, 0x17, 0x16, - 0x17, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, 0x06, 0x03, 0xc8, 0x47, - 0x8e, 0x8c, 0x81, 0xac, 0x7b, 0xea, 0x35, 0xb8, 0x37, 0xa1, 0x39, 0x81, - 0x54, 0x3f, 0x9d, 0x3a, 0x21, 0x65, 0xb8, 0x11, 0x23, 0x22, 0x1f, 0x23, - 0x56, 0x34, 0x5e, 0x57, 0x0e, 0x06, 0xfe, 0xf7, 0x74, 0x3c, 0x3b, 0x3f, - 0x78, 0x01, 0x12, 0xae, 0x8e, 0xae, 0x8e, 0xb4, 0x43, 0x18, 0x14, 0x33, - 0xa7, 0x5e, 0x77, 0xb8, 0xcb, 0x33, 0x55, 0x54, 0x38, 0x40, 0xb8, 0x30, - 0xad, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xbd, 0x04, 0x93, - 0x03, 0xe5, 0x10, 0x06, 0x04, 0xa0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x04, 0xf2, 0x03, 0xe5, 0x00, 0x26, 0x00, 0x36, 0x00, 0x44, - 0x00, 0x00, 0x25, 0x33, 0x15, 0x21, 0x22, 0x27, 0x06, 0x07, 0x06, 0x27, - 0x26, 0x35, 0x34, 0x37, 0x33, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, - 0x37, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x17, 0x26, 0x27, 0x35, - 0x16, 0x17, 0x16, 0x17, 0x16, 0x25, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, - 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x25, 0x16, 0x07, - 0x06, 0x07, 0x16, 0x33, 0x32, 0x37, 0x36, 0x27, 0x26, 0x27, 0x26, 0x04, - 0x90, 0x62, 0xfe, 0x88, 0xbe, 0x4a, 0x83, 0xa4, 0x91, 0x44, 0x76, 0x10, - 0xb8, 0x0e, 0x1e, 0x2d, 0x28, 0x30, 0x67, 0x3a, 0x17, 0x12, 0x2d, 0x30, - 0x4d, 0x2c, 0x51, 0xd4, 0xe3, 0xf9, 0x47, 0x18, 0xfd, 0xcd, 0x24, 0x22, - 0x27, 0x0f, 0x16, 0x3a, 0x41, 0x17, 0x16, 0x07, 0x15, 0x01, 0x47, 0x0d, - 0x16, 0x19, 0x35, 0x1c, 0x27, 0x81, 0x0d, 0x05, 0x05, 0x06, 0x14, 0x33, - 0xb8, 0xb8, 0x34, 0x33, 0x01, 0x01, 0x25, 0x40, 0x80, 0x4b, 0x35, 0x3a, - 0x2c, 0x2b, 0x0b, 0x10, 0x10, 0x43, 0x66, 0x4e, 0x40, 0x54, 0x53, 0x5a, - 0x09, 0x27, 0x0e, 0xb9, 0x41, 0xb6, 0xc8, 0xe7, 0x4f, 0x1d, 0x1b, 0x40, - 0x48, 0x3d, 0x2e, 0x25, 0x34, 0x2d, 0x2b, 0x23, 0x1e, 0x25, 0x76, 0xbc, - 0x5f, 0x55, 0x5b, 0x31, 0x15, 0x43, 0x1f, 0x20, 0x22, 0x26, 0x5f, 0x00, - 0xff, 0xff, 0xff, 0xec, 0xff, 0xbd, 0x03, 0xe3, 0x03, 0xe5, 0x10, 0x06, - 0x0c, 0x66, 0x00, 0x00, 0x00, 0x03, 0xff, 0xec, 0x00, 0x00, 0x04, 0xf2, - 0x03, 0xe5, 0x00, 0x1c, 0x00, 0x2c, 0x00, 0x3a, 0x00, 0x00, 0x25, 0x26, - 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x17, 0x26, 0x27, 0x35, 0x16, 0x17, - 0x16, 0x17, 0x16, 0x07, 0x33, 0x15, 0x21, 0x22, 0x27, 0x06, 0x2b, 0x01, - 0x35, 0x33, 0x32, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, - 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x25, 0x16, 0x07, 0x06, 0x07, - 0x16, 0x33, 0x32, 0x37, 0x36, 0x27, 0x26, 0x27, 0x26, 0x01, 0x5c, 0x3a, - 0x17, 0x12, 0x2d, 0x30, 0x4d, 0x2c, 0x51, 0xd4, 0xe3, 0xf9, 0x47, 0x18, - 0x0d, 0xca, 0xfe, 0x20, 0xbe, 0x4a, 0x86, 0xa1, 0xf7, 0xee, 0x46, 0xe2, - 0x24, 0x22, 0x27, 0x0f, 0x16, 0x3a, 0x41, 0x17, 0x16, 0x07, 0x15, 0x01, - 0x47, 0x0d, 0x16, 0x19, 0x35, 0x1c, 0x27, 0x81, 0x0d, 0x05, 0x05, 0x06, - 0x14, 0x33, 0xc8, 0x43, 0x66, 0x4e, 0x40, 0x54, 0x53, 0x5a, 0x09, 0x27, - 0x0e, 0xb9, 0x41, 0xb6, 0xc8, 0xe7, 0x4f, 0x38, 0xb8, 0x34, 0x34, 0xb8, - 0x55, 0x1b, 0x40, 0x48, 0x3d, 0x2e, 0x25, 0x34, 0x2d, 0x2b, 0x23, 0x1e, - 0x25, 0x76, 0xbc, 0x5f, 0x55, 0x5b, 0x31, 0x15, 0x43, 0x1f, 0x20, 0x22, - 0x26, 0x5f, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, 0x00, 0x00, 0x02, 0xbc, - 0x02, 0x58, 0x00, 0x0d, 0x00, 0x00, 0x25, 0x06, 0x21, 0x23, 0x35, 0x33, - 0x20, 0x37, 0x36, 0x3d, 0x01, 0x33, 0x15, 0x14, 0x02, 0x60, 0x48, 0xfe, - 0xa9, 0xd5, 0x9e, 0x01, 0x1d, 0x2c, 0x31, 0xb8, 0x56, 0x56, 0xb8, 0x2c, - 0x31, 0x6a, 0xd9, 0xd9, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, - 0x00, 0x00, 0x04, 0xe5, 0x02, 0x58, 0x00, 0x14, 0x00, 0x00, 0x25, 0x06, - 0x23, 0x21, 0x35, 0x21, 0x32, 0x37, 0x36, 0x3d, 0x01, 0x33, 0x15, 0x14, - 0x17, 0x16, 0x33, 0x21, 0x15, 0x21, 0x22, 0x02, 0x5e, 0x4c, 0xd7, 0xfe, - 0xb1, 0x01, 0x18, 0xa2, 0x2c, 0x30, 0xb8, 0x32, 0x2c, 0xa3, 0x01, 0x2a, - 0xfe, 0x9f, 0xd6, 0x56, 0x56, 0xb8, 0x2c, 0x31, 0x6a, 0xd9, 0xd9, 0x6a, - 0x31, 0x2c, 0xb8, 0x00, 0xff, 0xff, 0x00, 0x19, 0xfe, 0xf3, 0x04, 0xd1, - 0x03, 0x1c, 0x10, 0x06, 0x04, 0x74, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7c, - 0xfe, 0xf0, 0x04, 0xe5, 0x02, 0x02, 0x10, 0x06, 0x0c, 0x6b, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0xfe, 0xd4, 0x03, 0x17, 0x02, 0x58, 0x10, 0x27, - 0x0c, 0xd2, 0x01, 0x87, 0xfe, 0xd4, 0x10, 0x06, 0x0b, 0xe6, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0xfe, 0xd4, 0x04, 0xe5, 0x02, 0x58, 0x10, 0x27, - 0x0c, 0xd2, 0x01, 0x93, 0xfe, 0xd4, 0x10, 0x06, 0x0b, 0xe7, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x44, 0x04, 0xba, 0x03, 0x8c, 0x06, 0x9a, 0x10, 0x06, - 0x04, 0x76, 0x00, 0x00, 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x04, 0xe5, - 0x06, 0x9a, 0x10, 0x26, 0x04, 0x76, 0x00, 0x00, 0x10, 0x06, 0x04, 0x6b, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x44, 0x04, 0xba, 0x03, 0x8c, - 0x06, 0xfd, 0x10, 0x06, 0x04, 0x77, 0x00, 0x00, 0x00, 0x01, 0x03, 0x22, - 0x00, 0x00, 0x04, 0xe5, 0x01, 0x6b, 0x00, 0x0d, 0x00, 0x00, 0x01, 0x14, - 0x17, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, 0x26, 0x3d, 0x01, 0x33, - 0x03, 0xda, 0x31, 0x2c, 0x63, 0x4b, 0x82, 0x8e, 0x5c, 0x57, 0xb8, 0x01, - 0x4c, 0x37, 0x31, 0x2c, 0xb8, 0x5c, 0x57, 0x8d, 0x2b, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x44, 0xfe, 0x16, 0x03, 0x8c, 0xff, 0xf6, 0x10, 0x06, - 0x04, 0x78, 0x00, 0x00, 0xff, 0xff, 0x01, 0x44, 0x04, 0xba, 0x03, 0x8c, - 0x05, 0xaa, 0x10, 0x06, 0x04, 0x79, 0x00, 0x00, 0xff, 0xff, 0xff, 0xec, - 0x00, 0x00, 0x04, 0xe5, 0x05, 0xaa, 0x10, 0x26, 0x04, 0x6b, 0x00, 0x00, - 0x10, 0x06, 0x04, 0x79, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x44, - 0x04, 0xb9, 0x03, 0x8c, 0x06, 0xfd, 0x10, 0x06, 0x04, 0x7a, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x04, 0xe5, 0x06, 0xfd, 0x10, 0x26, - 0x04, 0x6b, 0x00, 0x00, 0x10, 0x06, 0x04, 0x7a, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x01, 0x44, 0xfe, 0xe8, 0x03, 0x8c, 0xff, 0xd8, 0x10, 0x06, - 0x04, 0x7b, 0x00, 0x00, 0xff, 0xff, 0xff, 0xec, 0xfe, 0xe8, 0x04, 0xe5, - 0x00, 0xb8, 0x10, 0x26, 0x04, 0x6b, 0x00, 0x00, 0x10, 0x06, 0x04, 0x7b, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x30, 0x04, 0xcb, 0x03, 0xa0, - 0x06, 0xf4, 0x10, 0x06, 0x04, 0x7c, 0x00, 0x00, 0xff, 0xff, 0xff, 0xec, - 0x00, 0x00, 0x04, 0xe5, 0x06, 0xf4, 0x10, 0x26, 0x04, 0x6b, 0x00, 0x00, - 0x10, 0x06, 0x04, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x56, - 0x04, 0xe1, 0x03, 0x7a, 0x07, 0x06, 0x10, 0x06, 0x04, 0x7d, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x04, 0xe5, 0x07, 0x06, 0x10, 0x26, - 0x04, 0x7d, 0x00, 0x00, 0x10, 0x06, 0x04, 0x6b, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x01, 0xb2, 0x00, 0x55, 0x04, 0x2d, 0x03, 0xde, 0x10, 0x06, - 0x04, 0x51, 0x00, 0x00, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x03, 0xd0, - 0x07, 0x83, 0x10, 0x26, 0x04, 0x57, 0x00, 0x00, 0x10, 0x07, 0x04, 0x7e, - 0x00, 0x00, 0x01, 0xc2, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x04, 0xe6, - 0x07, 0x83, 0x10, 0x27, 0x04, 0x7e, 0x00, 0x00, 0x01, 0xc2, 0x10, 0x06, - 0x0c, 0x09, 0x00, 0x00, 0xff, 0xff, 0x01, 0xb3, 0x00, 0x00, 0x03, 0x0a, - 0x08, 0x39, 0x10, 0x26, 0x04, 0x57, 0x00, 0x00, 0x10, 0x07, 0x04, 0x7f, - 0xff, 0xf6, 0x01, 0xc2, 0xff, 0xff, 0x01, 0xe4, 0x00, 0x00, 0x04, 0xe6, - 0x08, 0x39, 0x10, 0x27, 0x04, 0x7f, 0x00, 0x27, 0x01, 0xc2, 0x10, 0x06, - 0x0c, 0x09, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4c, 0xfe, 0x0c, 0x04, 0x33, - 0x04, 0xb5, 0x10, 0x26, 0x04, 0x73, 0x00, 0x00, 0x10, 0x07, 0x04, 0x7f, - 0x00, 0x60, 0xfe, 0x3e, 0xff, 0xff, 0x00, 0x5a, 0xfe, 0x0c, 0x04, 0xe5, - 0x04, 0xb5, 0x10, 0x27, 0x04, 0x7f, 0x00, 0x32, 0xfe, 0x3e, 0x10, 0x06, - 0x0c, 0x69, 0x00, 0x00, 0xff, 0xff, 0x01, 0xb6, 0xfe, 0x0c, 0x03, 0x0d, - 0x06, 0x14, 0x10, 0x26, 0x04, 0x57, 0x00, 0x00, 0x10, 0x06, 0x04, 0x80, - 0xf9, 0x00, 0x00, 0x00, 0xff, 0xff, 0x02, 0x13, 0xfe, 0x0c, 0x04, 0xe6, - 0x06, 0x14, 0x10, 0x26, 0x04, 0x80, 0x56, 0x00, 0x10, 0x06, 0x0c, 0x09, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x19, 0xfe, 0xf3, 0x04, 0xd1, - 0x04, 0x56, 0x10, 0x26, 0x04, 0x74, 0x00, 0x00, 0x10, 0x07, 0x04, 0x7f, - 0xff, 0x59, 0xfd, 0xdf, 0xff, 0xff, 0xff, 0x7c, 0xfe, 0xf0, 0x04, 0xe5, - 0x03, 0x5f, 0x10, 0x27, 0x04, 0x7f, 0xfe, 0xe4, 0xfc, 0xe8, 0x10, 0x06, - 0x0c, 0x6b, 0x00, 0x00, 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x02, 0xfe, - 0x04, 0xe7, 0x10, 0x27, 0x04, 0x7f, 0xff, 0xea, 0xfe, 0x70, 0x10, 0x06, - 0x0b, 0xe6, 0x00, 0x00, 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x04, 0xe5, - 0x04, 0xe7, 0x10, 0x27, 0x04, 0x7f, 0x00, 0x00, 0xfe, 0x70, 0x10, 0x06, - 0x0b, 0xe7, 0x00, 0x00, 0xff, 0xff, 0x02, 0x0c, 0x00, 0x00, 0x02, 0xc4, - 0x06, 0x14, 0x10, 0x06, 0x04, 0x57, 0x00, 0x00, 0x00, 0x01, 0x02, 0x4c, - 0x00, 0x00, 0x04, 0xe6, 0x06, 0x14, 0x00, 0x0d, 0x00, 0x00, 0x01, 0x11, - 0x33, 0x11, 0x14, 0x17, 0x16, 0x3b, 0x01, 0x15, 0x21, 0x22, 0x27, 0x26, - 0x02, 0x4c, 0xb8, 0x32, 0x2c, 0xb4, 0xd0, 0xfe, 0xf8, 0xea, 0x50, 0x58, - 0x01, 0x73, 0x04, 0xa1, 0xfb, 0x6b, 0x6a, 0x31, 0x2c, 0xb8, 0x5c, 0x65, - 0xff, 0xff, 0x00, 0x45, 0xfe, 0xa2, 0x04, 0xb0, 0x02, 0x1b, 0x10, 0x26, - 0x0c, 0xe0, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd1, 0x02, 0x1b, 0xfe, 0xa2, - 0xff, 0xff, 0x00, 0x45, 0xfe, 0xa2, 0x04, 0xe5, 0x02, 0x1c, 0x10, 0x27, - 0x0c, 0xd1, 0x01, 0xd1, 0xfe, 0xa2, 0x10, 0x06, 0x0c, 0xd4, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0xfe, 0xd4, 0x02, 0xbc, 0x02, 0x58, 0x10, 0x26, - 0x0b, 0xe6, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd1, 0x01, 0xf8, 0xfe, 0xd4, - 0xff, 0xff, 0xff, 0xec, 0xfe, 0xd4, 0x04, 0xe5, 0x02, 0x58, 0x10, 0x26, - 0x0b, 0xe7, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd1, 0x02, 0x14, 0xfe, 0xd4, - 0xff, 0xff, 0x00, 0xde, 0xff, 0xc6, 0x03, 0xf3, 0x04, 0x1a, 0x10, 0x26, - 0x04, 0x72, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd2, 0x01, 0x6a, 0x03, 0x84, - 0xff, 0xff, 0x00, 0xf2, 0x00, 0x00, 0x04, 0xe5, 0x04, 0x1a, 0x10, 0x27, - 0x0c, 0xd2, 0x01, 0xc6, 0x03, 0x84, 0x10, 0x06, 0x0c, 0x65, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x45, 0xff, 0xec, 0x04, 0xb0, 0x03, 0x20, 0x10, 0x26, - 0x0c, 0xe0, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd2, 0x01, 0xbf, 0x02, 0x8a, - 0xff, 0xff, 0x00, 0x45, 0xff, 0xec, 0x04, 0xe5, 0x03, 0x20, 0x10, 0x27, - 0x0c, 0xd2, 0x01, 0x9c, 0x02, 0x8a, 0x10, 0x06, 0x0c, 0xd4, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x03, 0x23, 0x03, 0xe8, 0x10, 0x27, - 0x0c, 0xd2, 0x01, 0x93, 0x03, 0x52, 0x10, 0x06, 0x0b, 0xe6, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x04, 0xe5, 0x03, 0xe8, 0x10, 0x27, - 0x0c, 0xd2, 0x01, 0x93, 0x03, 0x52, 0x10, 0x06, 0x0b, 0xe7, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x45, 0xff, 0xec, 0x04, 0xb0, 0x04, 0x1a, 0x10, 0x26, - 0x0c, 0xe0, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd3, 0x01, 0xba, 0x02, 0x8a, - 0xff, 0xff, 0x00, 0x45, 0xff, 0xec, 0x04, 0xe5, 0x04, 0x1a, 0x10, 0x27, - 0x0c, 0xd3, 0x01, 0xa8, 0x02, 0x8a, 0x10, 0x06, 0x0c, 0xd4, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x03, 0x2c, 0x04, 0xe2, 0x10, 0x26, - 0x0b, 0xe6, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd3, 0x01, 0x9c, 0x03, 0x52, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x04, 0xe5, 0x04, 0xbc, 0x10, 0x26, - 0x0b, 0xe7, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd3, 0x01, 0x9b, 0x03, 0x2c, - 0xff, 0xff, 0x00, 0x58, 0xfe, 0x0c, 0x04, 0xad, 0x03, 0x66, 0x10, 0x26, - 0x04, 0x5d, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd1, 0x02, 0x9f, 0x00, 0x19, - 0xff, 0xff, 0x00, 0x58, 0xfe, 0x0c, 0x04, 0xf9, 0x03, 0x66, 0x10, 0x27, - 0x0c, 0xd1, 0x02, 0x70, 0xff, 0xce, 0x10, 0x06, 0x0c, 0x1d, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0xfe, 0xd4, 0x04, 0x5c, 0x03, 0x2f, 0x10, 0x27, - 0x0c, 0xd1, 0x02, 0x0d, 0xfe, 0xd4, 0x10, 0x06, 0x0c, 0x1e, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0xfe, 0xd4, 0x04, 0xfc, 0x03, 0x2f, 0x10, 0x27, - 0x0c, 0xd1, 0x02, 0x0d, 0xfe, 0xd4, 0x10, 0x06, 0x0c, 0x1f, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x58, 0xfe, 0x0c, 0x04, 0xad, 0x03, 0x66, 0x10, 0x06, - 0x04, 0x5d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x58, 0xfe, 0x0c, 0x04, 0xf9, - 0x03, 0x66, 0x00, 0x2e, 0x00, 0x00, 0x25, 0x33, 0x15, 0x23, 0x22, 0x27, - 0x26, 0x27, 0x26, 0x27, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x05, - 0x32, 0x37, 0x15, 0x06, 0x07, 0x04, 0x27, 0x26, 0x35, 0x10, 0x37, 0x36, - 0x37, 0x26, 0x07, 0x06, 0x07, 0x35, 0x24, 0x17, 0x04, 0x17, 0x15, 0x06, - 0x07, 0x17, 0x16, 0x17, 0x16, 0x04, 0xd1, 0x28, 0x31, 0x81, 0x7b, 0x52, - 0x3d, 0x06, 0x49, 0x72, 0x62, 0xe0, 0x4a, 0x81, 0x01, 0x13, 0xc1, 0xd4, - 0x96, 0xfa, 0xfe, 0x94, 0xa9, 0x83, 0xd4, 0x60, 0x89, 0x65, 0x9f, 0x87, - 0x5f, 0x01, 0x14, 0xc3, 0x01, 0x24, 0xc4, 0x6d, 0x1f, 0x1d, 0x33, 0x48, - 0x5a, 0xb8, 0xb8, 0x96, 0x64, 0x9c, 0x0f, 0xb2, 0x18, 0x50, 0xb7, 0xfc, - 0x8a, 0x5d, 0xa3, 0x01, 0x76, 0xb8, 0x62, 0x01, 0x02, 0xc4, 0x98, 0xde, - 0x01, 0x02, 0xdf, 0x65, 0x34, 0x03, 0x16, 0x13, 0x29, 0xb8, 0x40, 0x01, - 0x01, 0x35, 0x9a, 0x03, 0x0a, 0x5b, 0xa0, 0x5f, 0x77, 0x00, 0x00, 0x00, - 0x00, 0x01, 0xff, 0xec, 0x00, 0x00, 0x04, 0x5c, 0x03, 0x2f, 0x00, 0x1e, - 0x00, 0x00, 0x01, 0x26, 0x27, 0x26, 0x27, 0x26, 0x07, 0x35, 0x36, 0x37, - 0x32, 0x17, 0x04, 0x17, 0x15, 0x06, 0x07, 0x06, 0x07, 0x06, 0x07, 0x06, - 0x2b, 0x01, 0x35, 0x33, 0x32, 0x37, 0x36, 0x37, 0x36, 0x03, 0x53, 0x53, - 0x67, 0x55, 0xb4, 0x52, 0xa1, 0x48, 0x4b, 0xa2, 0xac, 0x01, 0x02, 0xdc, - 0x4c, 0x58, 0xa6, 0x4a, 0x91, 0x4b, 0xdd, 0xa3, 0x80, 0x64, 0xe3, 0x81, - 0x68, 0x74, 0x5e, 0x02, 0x1d, 0x17, 0x17, 0x13, 0x10, 0x07, 0x06, 0xb8, - 0x07, 0x01, 0x23, 0x34, 0x62, 0x9a, 0x18, 0x34, 0x62, 0x42, 0x81, 0x1b, - 0x50, 0xb8, 0x48, 0x3a, 0x6a, 0x56, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, - 0x00, 0x00, 0x04, 0xfc, 0x03, 0x2f, 0x00, 0x29, 0x00, 0x00, 0x01, 0x04, - 0x17, 0x15, 0x06, 0x07, 0x16, 0x17, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, - 0x27, 0x26, 0x27, 0x06, 0x07, 0x06, 0x07, 0x06, 0x2b, 0x01, 0x35, 0x33, - 0x32, 0x37, 0x36, 0x37, 0x36, 0x37, 0x26, 0x27, 0x26, 0x27, 0x26, 0x07, - 0x35, 0x36, 0x37, 0x32, 0x02, 0x7e, 0x01, 0x02, 0xdc, 0x41, 0x49, 0x32, - 0x1e, 0x68, 0x36, 0x3c, 0x50, 0x97, 0x7c, 0x28, 0x3b, 0x45, 0x29, 0x91, - 0x4b, 0xdd, 0xa3, 0x80, 0x64, 0xe3, 0x81, 0x68, 0x74, 0x5e, 0x65, 0x53, - 0x67, 0x55, 0xb4, 0x52, 0xa1, 0x48, 0x4b, 0xa2, 0x03, 0x0c, 0x34, 0x62, - 0x9a, 0x14, 0x29, 0x4e, 0x22, 0x77, 0xb8, 0xa8, 0x36, 0x61, 0x2e, 0x25, - 0x81, 0x1b, 0x50, 0xb8, 0x48, 0x3a, 0x6a, 0x56, 0x23, 0x17, 0x17, 0x13, - 0x10, 0x07, 0x06, 0xb8, 0x07, 0x01, 0x00, 0x00, 0xff, 0xff, 0x00, 0x58, - 0xfe, 0x0c, 0x04, 0xad, 0x04, 0xb0, 0x10, 0x26, 0x04, 0x5d, 0x00, 0x00, - 0x10, 0x07, 0x0c, 0xd1, 0x01, 0xdc, 0x04, 0x1a, 0xff, 0xff, 0x00, 0x58, - 0xfe, 0x0c, 0x04, 0xf9, 0x04, 0xb0, 0x10, 0x27, 0x0c, 0xd1, 0x01, 0xd8, - 0x04, 0x1a, 0x10, 0x06, 0x0c, 0x1d, 0x00, 0x00, 0xff, 0xff, 0xff, 0xec, - 0x00, 0x00, 0x04, 0x5c, 0x04, 0x4c, 0x10, 0x27, 0x0c, 0xd1, 0x02, 0x0d, - 0x03, 0xb6, 0x10, 0x06, 0x0c, 0x1e, 0x00, 0x00, 0xff, 0xff, 0xff, 0xec, - 0x00, 0x00, 0x04, 0xfc, 0x04, 0x4c, 0x10, 0x27, 0x0c, 0xd1, 0x02, 0x0d, - 0x03, 0xb6, 0x10, 0x06, 0x0c, 0x1f, 0x00, 0x00, 0xff, 0xff, 0x00, 0xe8, - 0xff, 0xda, 0x03, 0xe8, 0x03, 0x6a, 0x10, 0x06, 0x04, 0x5f, 0x00, 0x00, - 0x00, 0x01, 0x00, 0xe8, 0xff, 0xda, 0x04, 0xe5, 0x03, 0x6a, 0x00, 0x20, - 0x00, 0x00, 0x01, 0x14, 0x17, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, - 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x35, 0x16, 0x33, 0x32, 0x37, 0x36, - 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x33, 0x16, 0x17, 0x16, 0x03, - 0xe8, 0x52, 0x2c, 0x63, 0x1c, 0x53, 0x93, 0x61, 0x5e, 0xce, 0x2e, 0x5e, - 0x97, 0x67, 0x73, 0x85, 0x52, 0x22, 0xad, 0x22, 0x08, 0x3c, 0x45, 0xaa, - 0xe3, 0x6b, 0x48, 0x52, 0x01, 0x7a, 0x44, 0x52, 0x2c, 0xb8, 0x82, 0x82, - 0x1f, 0x07, 0x26, 0xb8, 0x2a, 0x09, 0x2e, 0x73, 0x1b, 0x2a, 0x5d, 0x65, - 0x73, 0xb8, 0x6c, 0x83, 0x95, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xe8, - 0xff, 0xda, 0x03, 0xe8, 0x04, 0xb0, 0x10, 0x26, 0x04, 0x5f, 0x00, 0x00, - 0x10, 0x07, 0x0c, 0xd1, 0x02, 0x0c, 0x04, 0x1a, 0xff, 0xff, 0x00, 0xe8, - 0xff, 0xda, 0x04, 0xe5, 0x04, 0xb0, 0x10, 0x27, 0x0c, 0xd1, 0x02, 0x15, - 0x04, 0x1a, 0x10, 0x06, 0x0c, 0x25, 0x00, 0x00, 0xff, 0xff, 0xff, 0xcc, - 0xfe, 0x08, 0x04, 0x44, 0x02, 0x22, 0x10, 0x06, 0x04, 0x61, 0x00, 0x00, - 0x00, 0x01, 0xff, 0x60, 0xfe, 0x0c, 0x04, 0xe5, 0x02, 0x26, 0x00, 0x18, - 0x00, 0x00, 0x01, 0x33, 0x16, 0x17, 0x16, 0x17, 0x16, 0x3b, 0x01, 0x15, - 0x23, 0x22, 0x27, 0x06, 0x05, 0x04, 0x21, 0x35, 0x20, 0x37, 0x24, 0x37, - 0x36, 0x35, 0x34, 0x02, 0xee, 0xb8, 0x1e, 0x03, 0x0a, 0x49, 0x2a, 0x65, - 0x3c, 0x73, 0x82, 0x32, 0x39, 0xfe, 0xd7, 0xfe, 0xe4, 0xfe, 0x20, 0x01, - 0xbd, 0xdb, 0x00, 0xff, 0x22, 0x0a, 0x02, 0x26, 0x70, 0x1e, 0x67, 0x4d, - 0x2c, 0xb8, 0x3e, 0xfd, 0x9e, 0x97, 0xb8, 0x80, 0x95, 0xc5, 0x3a, 0x48, - 0x7e, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xcc, 0xfe, 0x08, 0x04, 0x44, - 0x03, 0xb6, 0x10, 0x26, 0x04, 0x61, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd1, - 0x03, 0x5d, 0x03, 0x20, 0xff, 0xff, 0xff, 0x60, 0xfe, 0x0c, 0x04, 0xe5, - 0x03, 0xb6, 0x10, 0x27, 0x0c, 0xd1, 0x02, 0xef, 0x03, 0x20, 0x10, 0x06, - 0x0c, 0x29, 0x00, 0x00, 0xff, 0xff, 0xff, 0x24, 0xfe, 0x14, 0x04, 0x98, - 0x02, 0xee, 0x10, 0x06, 0x04, 0x63, 0x00, 0x00, 0x00, 0x01, 0xfe, 0xd8, - 0xfe, 0x14, 0x04, 0xe5, 0x02, 0xee, 0x00, 0x46, 0x00, 0x00, 0x05, 0x22, - 0x27, 0x26, 0x27, 0x06, 0x07, 0x06, 0x07, 0x06, 0x27, 0x06, 0x07, 0x06, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x37, 0x36, 0x37, 0x33, 0x06, 0x17, - 0x16, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x36, 0x27, 0x26, 0x2f, - 0x01, 0x33, 0x17, 0x16, 0x17, 0x16, 0x17, 0x16, 0x37, 0x36, 0x35, 0x33, - 0x06, 0x17, 0x16, 0x33, 0x32, 0x19, 0x01, 0x33, 0x11, 0x14, 0x17, 0x16, - 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, 0x06, 0x07, 0x06, 0x03, 0x34, 0x41, - 0x19, 0x40, 0x1a, 0x1f, 0x45, 0x32, 0x4a, 0x2f, 0x31, 0x08, 0x1e, 0x25, - 0x3d, 0x47, 0x71, 0x5f, 0x65, 0x76, 0x12, 0x14, 0x3c, 0xa4, 0x57, 0x05, - 0x08, 0x21, 0x2e, 0x30, 0x35, 0x32, 0x23, 0x1a, 0x18, 0x02, 0x01, 0x10, - 0x29, 0x9f, 0x12, 0x11, 0x15, 0x31, 0x27, 0x2f, 0x2d, 0x25, 0xa4, 0x04, - 0x25, 0x20, 0x2a, 0x69, 0xa4, 0x29, 0x2c, 0x3b, 0x08, 0x3f, 0x64, 0x3c, - 0x1f, 0x47, 0x21, 0x1d, 0x19, 0x43, 0x7e, 0x6d, 0x38, 0x28, 0x02, 0x02, - 0x50, 0xa8, 0x5e, 0x79, 0x4d, 0x5c, 0x64, 0x73, 0xd5, 0xe8, 0x82, 0xe1, - 0x89, 0xac, 0x2b, 0x3b, 0x48, 0x32, 0x7a, 0x6d, 0xa5, 0x5e, 0x5c, 0xea, - 0x9c, 0x91, 0x23, 0x50, 0x03, 0x03, 0x7d, 0x67, 0xc2, 0xa3, 0x8d, 0x78, - 0x01, 0x18, 0x01, 0x26, 0xfe, 0xaa, 0x8b, 0x29, 0x2c, 0xb8, 0x60, 0x61, - 0x13, 0x09, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, 0xff, 0xdd, 0x04, 0x94, - 0x02, 0xe8, 0x00, 0x31, 0x00, 0x00, 0x25, 0x32, 0x37, 0x36, 0x35, 0x33, - 0x06, 0x17, 0x16, 0x33, 0x32, 0x19, 0x01, 0x33, 0x11, 0x14, 0x07, 0x06, - 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x06, 0x07, 0x06, 0x23, 0x22, - 0x27, 0x26, 0x27, 0x06, 0x07, 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x37, - 0x36, 0x3d, 0x01, 0x33, 0x15, 0x14, 0x17, 0x16, 0x01, 0xe6, 0x43, 0x2a, - 0x25, 0xa5, 0x05, 0x26, 0x1f, 0x2b, 0x68, 0xa4, 0x3e, 0x21, 0x55, 0x16, - 0x4e, 0x42, 0x18, 0x41, 0x19, 0x1f, 0x46, 0x33, 0x49, 0x32, 0x51, 0x2c, - 0x0c, 0x15, 0x45, 0x3b, 0x65, 0x46, 0x2a, 0x4c, 0x24, 0x46, 0xa4, 0x1a, - 0x15, 0xb5, 0x74, 0x67, 0xc2, 0xa3, 0x8d, 0x78, 0x01, 0x18, 0x01, 0x26, - 0xfe, 0xaa, 0x9f, 0x99, 0x52, 0x22, 0x09, 0x19, 0x43, 0x7e, 0x6d, 0x38, - 0x2a, 0x40, 0x23, 0x3f, 0x39, 0x2c, 0x25, 0xb8, 0x23, 0x47, 0x76, 0xc0, - 0x9c, 0x4f, 0x64, 0x54, 0x00, 0x01, 0xff, 0xec, 0xff, 0xdd, 0x04, 0xe6, - 0x02, 0xe8, 0x00, 0x37, 0x00, 0x00, 0x01, 0x14, 0x17, 0x16, 0x33, 0x32, - 0x19, 0x01, 0x33, 0x11, 0x14, 0x17, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, - 0x27, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x27, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x27, 0x06, 0x07, 0x06, 0x2b, 0x01, 0x35, 0x33, - 0x32, 0x37, 0x36, 0x3d, 0x01, 0x33, 0x15, 0x14, 0x17, 0x16, 0x32, 0x37, - 0x36, 0x35, 0x02, 0xd1, 0x21, 0x1d, 0x35, 0x64, 0xa4, 0x2a, 0x2c, 0x22, - 0x22, 0x40, 0x65, 0x3b, 0x36, 0x3a, 0x16, 0x48, 0x4f, 0x37, 0x2a, 0x0c, - 0x1e, 0x46, 0x33, 0x35, 0x43, 0x25, 0x26, 0x18, 0x14, 0x46, 0x3a, 0x44, - 0x46, 0x2a, 0x37, 0x1f, 0x40, 0xa2, 0x1a, 0x16, 0x60, 0x2a, 0x25, 0x02, - 0x52, 0xa6, 0x8a, 0x78, 0x01, 0x18, 0x01, 0x26, 0xfe, 0xaa, 0x8b, 0x29, - 0x2c, 0xb8, 0x60, 0x58, 0x1b, 0x0a, 0x49, 0x36, 0x5b, 0x6d, 0x38, 0x2a, - 0x36, 0x37, 0x35, 0x39, 0x2c, 0x25, 0xb8, 0x23, 0x47, 0x76, 0xc0, 0x9c, - 0x4f, 0x64, 0x54, 0x74, 0x67, 0xc2, 0x00, 0x00, 0xff, 0xff, 0xff, 0x24, - 0xfe, 0x14, 0x04, 0x98, 0x04, 0xb0, 0x10, 0x26, 0x04, 0x63, 0x00, 0x00, - 0x10, 0x07, 0x0c, 0xd3, 0x01, 0x36, 0x03, 0x20, 0xff, 0xff, 0xfe, 0xd8, - 0xfe, 0x14, 0x04, 0xe5, 0x04, 0xb0, 0x10, 0x27, 0x0c, 0xd3, 0x00, 0xec, - 0x03, 0x20, 0x10, 0x06, 0x0c, 0x2d, 0x00, 0x00, 0xff, 0xff, 0xff, 0xec, - 0xff, 0xdd, 0x04, 0x94, 0x04, 0xb0, 0x10, 0x27, 0x0c, 0xd3, 0x01, 0x96, - 0x03, 0x20, 0x10, 0x06, 0x0c, 0x2e, 0x00, 0x00, 0xff, 0xff, 0xff, 0xec, - 0xff, 0xdd, 0x04, 0xe6, 0x04, 0xb0, 0x10, 0x27, 0x0c, 0xd3, 0x01, 0x52, - 0x03, 0x20, 0x10, 0x06, 0x0c, 0x2f, 0x00, 0x00, 0xff, 0xff, 0xff, 0x10, - 0xfe, 0x14, 0x04, 0xc0, 0x02, 0x8f, 0x10, 0x06, 0x04, 0x65, 0x00, 0x00, - 0x00, 0x02, 0xfe, 0xc5, 0xfe, 0x14, 0x04, 0xe5, 0x02, 0x8f, 0x00, 0x0c, - 0x00, 0x47, 0x00, 0x00, 0x25, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, - 0x26, 0x23, 0x22, 0x07, 0x06, 0x25, 0x14, 0x07, 0x16, 0x17, 0x16, 0x3b, - 0x01, 0x15, 0x23, 0x22, 0x2f, 0x01, 0x06, 0x2b, 0x01, 0x22, 0x27, 0x26, - 0x35, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x33, 0x06, 0x15, 0x14, 0x17, 0x16, 0x37, 0x36, 0x37, 0x36, 0x35, - 0x34, 0x27, 0x26, 0x27, 0x33, 0x06, 0x17, 0x16, 0x17, 0x36, 0x37, 0x36, - 0x33, 0x32, 0x17, 0x16, 0x01, 0xfd, 0x81, 0x8c, 0x49, 0x6a, 0x28, 0x24, - 0x3f, 0x47, 0x68, 0x4b, 0x02, 0x3d, 0x1f, 0x10, 0x0e, 0x2e, 0x1c, 0x27, - 0x3b, 0x34, 0x66, 0x1c, 0xac, 0x88, 0xda, 0x26, 0x34, 0x2d, 0x2f, 0x2f, - 0x33, 0x66, 0x4a, 0x82, 0x5a, 0x7d, 0x65, 0xac, 0x68, 0x3c, 0x32, 0x3c, - 0x43, 0x25, 0x40, 0x09, 0x21, 0x0d, 0xab, 0x01, 0x0e, 0x0a, 0x28, 0x4c, - 0x31, 0x92, 0x96, 0xab, 0x5b, 0x57, 0xb8, 0x2e, 0x44, 0x46, 0x2d, 0x25, - 0x21, 0x6d, 0x4e, 0x4e, 0x34, 0x47, 0x0a, 0x0d, 0x2c, 0xb8, 0x5e, 0x1a, - 0x78, 0x1e, 0x1a, 0x10, 0xaf, 0x83, 0x81, 0x2b, 0x56, 0x5a, 0x7d, 0xcd, - 0xbc, 0xac, 0xcc, 0x9c, 0x91, 0x32, 0x29, 0x03, 0x04, 0x3b, 0x67, 0x8b, - 0x68, 0x3e, 0xd4, 0x48, 0x0f, 0x37, 0x28, 0x32, 0x80, 0x3c, 0xb1, 0x52, - 0x4e, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x00, 0x00, 0x04, 0xc1, - 0x02, 0x8f, 0x00, 0x0c, 0x00, 0x2c, 0x00, 0x00, 0x25, 0x33, 0x32, 0x37, - 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x03, 0x22, 0x27, - 0x26, 0x27, 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x37, 0x36, 0x3d, 0x01, - 0x33, 0x15, 0x14, 0x16, 0x17, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x06, 0x23, 0x02, 0x49, 0x81, 0x8c, 0x49, 0x6a, 0x28, - 0x24, 0x3f, 0x47, 0x68, 0x4b, 0x52, 0x4a, 0x4e, 0x41, 0x27, 0x66, 0x5e, - 0x82, 0x4b, 0x2b, 0x25, 0x41, 0xb8, 0x12, 0x2d, 0x4c, 0x31, 0x92, 0x96, - 0xab, 0x5b, 0x57, 0xb8, 0x7e, 0x7f, 0xb8, 0x2e, 0x44, 0x46, 0x2d, 0x25, - 0x21, 0x6d, 0x4e, 0xfe, 0xd8, 0x2a, 0x23, 0x3d, 0x8a, 0xb8, 0x2c, 0x50, - 0x64, 0x72, 0x4e, 0x18, 0x50, 0x32, 0x80, 0x3c, 0xb1, 0x52, 0x4e, 0x79, - 0xbe, 0x6d, 0x4b, 0x00, 0x00, 0x02, 0xff, 0xec, 0x00, 0x00, 0x04, 0xe5, - 0x02, 0x8f, 0x00, 0x0c, 0x00, 0x36, 0x00, 0x00, 0x25, 0x33, 0x32, 0x37, - 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x03, 0x22, 0x27, - 0x26, 0x27, 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x37, 0x36, 0x3d, 0x01, - 0x33, 0x15, 0x14, 0x16, 0x17, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x16, 0x17, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x2f, - 0x01, 0x06, 0x23, 0x01, 0xfd, 0x81, 0x8c, 0x49, 0x6a, 0x28, 0x24, 0x3f, - 0x47, 0x68, 0x4b, 0x52, 0x4a, 0x4e, 0x41, 0x27, 0x66, 0x44, 0x50, 0x1a, - 0x1f, 0x2a, 0x2d, 0xb8, 0x12, 0x2d, 0x4c, 0x31, 0x92, 0x96, 0xab, 0x5b, - 0x57, 0x1f, 0x10, 0x0e, 0x2e, 0x1c, 0x27, 0x3b, 0x34, 0x66, 0x1c, 0xac, - 0x88, 0xb8, 0x2e, 0x44, 0x46, 0x2d, 0x25, 0x21, 0x6d, 0x4e, 0xfe, 0xd8, - 0x2a, 0x23, 0x3d, 0x8a, 0xb8, 0x2e, 0x32, 0x80, 0x72, 0x4e, 0x18, 0x50, - 0x32, 0x80, 0x3c, 0xb1, 0x52, 0x4e, 0x79, 0x34, 0x47, 0x0a, 0x0d, 0x2c, - 0xb8, 0x5e, 0x1a, 0x78, 0xff, 0xff, 0xff, 0x10, 0xfe, 0x14, 0x04, 0xc0, - 0x03, 0x34, 0x10, 0x26, 0x04, 0x65, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd1, - 0x01, 0x4f, 0x02, 0x9e, 0xff, 0xff, 0xfe, 0xc5, 0xfe, 0x14, 0x04, 0xe5, - 0x03, 0x34, 0x10, 0x27, 0x0c, 0xd1, 0x01, 0x04, 0x02, 0x9e, 0x10, 0x06, - 0x0c, 0x35, 0x00, 0x00, 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x04, 0xc1, - 0x03, 0x76, 0x10, 0x27, 0x0c, 0xd1, 0x01, 0x57, 0x02, 0xe0, 0x10, 0x06, - 0x0c, 0x36, 0x00, 0x00, 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x04, 0xe5, - 0x03, 0x68, 0x10, 0x27, 0x0c, 0xd1, 0x01, 0x34, 0x02, 0xd2, 0x10, 0x06, - 0x0c, 0x37, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0a, 0x00, 0x00, 0x04, 0xa4, - 0x06, 0x14, 0x10, 0x06, 0x04, 0x67, 0x00, 0x00, 0x00, 0x02, 0x00, 0x14, - 0x00, 0x00, 0x04, 0xe5, 0x06, 0x14, 0x00, 0x0c, 0x00, 0x27, 0x00, 0x00, - 0x25, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, - 0x06, 0x25, 0x14, 0x07, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x2f, 0x01, - 0x06, 0x23, 0x21, 0x23, 0x35, 0x33, 0x11, 0x33, 0x11, 0x36, 0x37, 0x36, - 0x33, 0x32, 0x17, 0x16, 0x02, 0x08, 0x81, 0x8c, 0x49, 0x6a, 0x28, 0x24, - 0x3f, 0x47, 0x68, 0x4b, 0x02, 0x3d, 0x2a, 0x3d, 0x25, 0x2d, 0x3a, 0x5d, - 0x55, 0x1c, 0x7d, 0x95, 0xfd, 0xfb, 0xb2, 0xb2, 0xb8, 0x4c, 0x31, 0x92, - 0x96, 0xab, 0x5b, 0x57, 0xb8, 0x2e, 0x44, 0x46, 0x2d, 0x25, 0x21, 0x6d, - 0x4e, 0x4e, 0x35, 0x46, 0x43, 0xb8, 0x4f, 0x1a, 0x69, 0xb8, 0x05, 0x5c, - 0xfb, 0x0e, 0x80, 0x3c, 0xb1, 0x52, 0x4e, 0x00, 0x00, 0x02, 0xff, 0xec, - 0x00, 0x00, 0x04, 0xa4, 0x06, 0x14, 0x00, 0x0c, 0x00, 0x1f, 0x00, 0x00, - 0x25, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x23, 0x22, 0x07, - 0x06, 0x13, 0x21, 0x23, 0x35, 0x33, 0x11, 0x33, 0x11, 0x36, 0x37, 0x36, - 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x02, 0x2c, 0x81, 0x8c, - 0x49, 0x6a, 0x28, 0x24, 0x3f, 0x47, 0x68, 0x4b, 0x88, 0xfd, 0xfb, 0xfe, - 0xfe, 0xb8, 0x4c, 0x31, 0x8e, 0x9a, 0xab, 0x5b, 0x57, 0xb8, 0x7e, 0xb8, - 0x2e, 0x44, 0x46, 0x2d, 0x25, 0x21, 0x6d, 0x4e, 0xfe, 0xd8, 0xb8, 0x05, - 0x5c, 0xfb, 0x0e, 0x80, 0x3c, 0xb1, 0x52, 0x4e, 0x79, 0xbe, 0x6d, 0x4b, - 0x00, 0x02, 0xff, 0xec, 0x00, 0x00, 0x04, 0xe5, 0x06, 0x14, 0x00, 0x0c, - 0x00, 0x27, 0x00, 0x00, 0x25, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, - 0x26, 0x23, 0x22, 0x07, 0x06, 0x25, 0x14, 0x07, 0x16, 0x3b, 0x01, 0x15, - 0x23, 0x22, 0x2f, 0x01, 0x06, 0x23, 0x21, 0x23, 0x35, 0x33, 0x11, 0x33, - 0x11, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x02, 0x08, 0x81, 0x8c, - 0x49, 0x6a, 0x28, 0x24, 0x3f, 0x47, 0x68, 0x4b, 0x02, 0x3d, 0x2a, 0x3d, - 0x25, 0x2d, 0x3a, 0x5d, 0x55, 0x1c, 0x7d, 0x95, 0xfd, 0xfb, 0xda, 0xda, - 0xb8, 0x4c, 0x31, 0x92, 0x96, 0xab, 0x5b, 0x57, 0xb8, 0x2e, 0x44, 0x46, - 0x2d, 0x25, 0x21, 0x6d, 0x4e, 0x4e, 0x35, 0x46, 0x43, 0xb8, 0x4f, 0x1a, - 0x69, 0xb8, 0x05, 0x5c, 0xfb, 0x0e, 0x80, 0x3c, 0xb1, 0x52, 0x4e, 0x00, - 0xff, 0xff, 0x00, 0x0a, 0x00, 0x00, 0x04, 0xa4, 0x06, 0x14, 0x10, 0x26, - 0x04, 0x67, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd1, 0x02, 0x43, 0x03, 0x00, - 0xff, 0xff, 0x00, 0x14, 0x00, 0x00, 0x04, 0xe5, 0x06, 0x14, 0x10, 0x27, - 0x0c, 0xd1, 0x02, 0x43, 0x03, 0x00, 0x10, 0x06, 0x0c, 0x3d, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x04, 0xa4, 0x06, 0x14, 0x10, 0x27, - 0x0c, 0xd1, 0x02, 0x43, 0x03, 0x00, 0x10, 0x06, 0x0c, 0x3e, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x04, 0xe5, 0x06, 0x14, 0x10, 0x27, - 0x0c, 0xd1, 0x02, 0x43, 0x03, 0x00, 0x10, 0x06, 0x0c, 0x3f, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x7a, 0xfe, 0x0c, 0x04, 0xb7, 0x04, 0x2a, 0x10, 0x06, - 0x04, 0x69, 0x00, 0x00, 0x00, 0x02, 0x00, 0x94, 0xfe, 0x0c, 0x04, 0xf4, - 0x03, 0x0e, 0x00, 0x2c, 0x00, 0x37, 0x00, 0x00, 0x33, 0x34, 0x37, 0x26, - 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x32, 0x17, 0x16, 0x17, - 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x16, 0x17, 0x16, 0x3b, 0x01, 0x15, - 0x23, 0x20, 0x27, 0x06, 0x15, 0x14, 0x17, 0x16, 0x21, 0x32, 0x37, 0x15, - 0x06, 0x07, 0x04, 0x27, 0x26, 0x00, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, - 0x36, 0x37, 0x36, 0x27, 0x94, 0xbb, 0x3d, 0x26, 0x1e, 0x0d, 0x10, 0x68, - 0x59, 0xee, 0x59, 0x65, 0x13, 0x0d, 0x45, 0x76, 0x37, 0x44, 0x57, 0x5f, - 0x94, 0xe0, 0xd0, 0xfe, 0xb7, 0xf8, 0x9a, 0x29, 0x6b, 0x01, 0x5f, 0xc1, - 0xd4, 0x96, 0xfa, 0xfe, 0x52, 0x9d, 0x62, 0x01, 0xa9, 0x34, 0x1e, 0x2f, - 0x46, 0x86, 0x02, 0x01, 0x30, 0xd4, 0x8c, 0x32, 0x48, 0x39, 0x1b, 0x1f, - 0x29, 0x37, 0x34, 0x2d, 0x2d, 0x33, 0x38, 0x26, 0x22, 0x3e, 0x38, 0x60, - 0x13, 0x40, 0x25, 0x28, 0xb8, 0xe4, 0x81, 0x6a, 0x6d, 0x3d, 0x9e, 0x76, - 0xb8, 0x62, 0x01, 0x02, 0xbe, 0x77, 0x03, 0x16, 0x07, 0x0c, 0x20, 0x24, - 0x41, 0x37, 0x2e, 0x20, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, - 0x00, 0x00, 0x03, 0xf9, 0x04, 0x2a, 0x00, 0x1a, 0x00, 0x00, 0x37, 0x32, - 0x37, 0x26, 0x27, 0x26, 0x35, 0x10, 0x37, 0x36, 0x33, 0x15, 0x22, 0x06, - 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x25, 0x15, 0x05, 0x04, 0x2b, 0x01, - 0x35, 0x3d, 0xa1, 0xca, 0x4b, 0x34, 0x58, 0xcc, 0x7d, 0xfb, 0xda, 0xba, - 0x3e, 0x53, 0x46, 0x38, 0x49, 0x01, 0x20, 0xfe, 0x5c, 0xfe, 0xa2, 0xb2, - 0x59, 0xb8, 0x5d, 0x18, 0x3b, 0x64, 0x8c, 0x01, 0x08, 0x7d, 0x4d, 0xa9, - 0x89, 0xff, 0x34, 0x46, 0x21, 0x81, 0xb8, 0xc5, 0xa4, 0xb8, 0x00, 0x00, - 0x00, 0x02, 0xff, 0xec, 0x00, 0x00, 0x04, 0xe5, 0x03, 0x0e, 0x00, 0x24, - 0x00, 0x2f, 0x00, 0x00, 0x25, 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x37, - 0x36, 0x37, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x32, - 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x16, 0x17, 0x16, - 0x3b, 0x01, 0x15, 0x23, 0x22, 0x02, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, - 0x36, 0x35, 0x34, 0x27, 0x02, 0x68, 0xc2, 0xca, 0xf0, 0xda, 0x6b, 0x42, - 0x3b, 0x28, 0x61, 0x44, 0x1e, 0x0d, 0x10, 0x68, 0x59, 0xee, 0x59, 0x66, - 0x12, 0x0d, 0x1e, 0x4d, 0x58, 0x1f, 0x44, 0x3d, 0x70, 0xdb, 0xf1, 0xca, - 0xa8, 0x34, 0x1e, 0x2f, 0x67, 0x67, 0x2f, 0xb9, 0xb9, 0xb8, 0x28, 0x24, - 0x27, 0x55, 0x5a, 0x27, 0x2d, 0x1f, 0x29, 0x37, 0x34, 0x2d, 0x2d, 0x33, - 0x38, 0x29, 0x1f, 0x2d, 0x27, 0x62, 0x4d, 0x1f, 0x2c, 0x28, 0xb8, 0x02, - 0x55, 0x07, 0x0c, 0x20, 0x1d, 0x5f, 0x5f, 0x1d, 0x20, 0x0c, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x7a, 0xfe, 0x0c, 0x04, 0xb7, 0x05, 0x46, 0x10, 0x26, - 0x04, 0x69, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd1, 0x01, 0x77, 0x04, 0xb0, - 0xff, 0xff, 0x00, 0x94, 0xfe, 0x0c, 0x04, 0xf4, 0x04, 0x4c, 0x10, 0x27, - 0x0c, 0xd1, 0x01, 0xd6, 0x03, 0xb6, 0x10, 0x06, 0x0c, 0x45, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x03, 0xf9, 0x05, 0x46, 0x10, 0x27, - 0x0c, 0xd1, 0x01, 0x77, 0x04, 0xb0, 0x10, 0x06, 0x0c, 0x46, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x04, 0xe5, 0x04, 0x4c, 0x10, 0x27, - 0x0c, 0xd1, 0x02, 0x1b, 0x03, 0xb6, 0x10, 0x06, 0x0c, 0x47, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xb6, 0xff, 0xa4, 0x04, 0x8c, 0x04, 0xc0, 0x10, 0x26, - 0x0c, 0xe8, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd1, 0x02, 0xf0, 0x04, 0x2a, - 0xff, 0xff, 0xff, 0x6a, 0xff, 0xa5, 0x04, 0xe5, 0x04, 0x4c, 0x10, 0x27, - 0x0c, 0xd1, 0x02, 0xf6, 0x03, 0xb6, 0x10, 0x06, 0x0c, 0xd8, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x03, 0x3f, 0x05, 0x14, 0x10, 0x27, - 0x0c, 0xd1, 0x01, 0xa9, 0x04, 0x7e, 0x10, 0x06, 0x0c, 0xd5, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x04, 0xe5, 0x04, 0x7e, 0x10, 0x27, - 0x0c, 0xd1, 0x02, 0x22, 0x03, 0xe8, 0x10, 0x06, 0x0c, 0xd6, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x1f, 0xfe, 0x7d, 0x04, 0x74, 0x05, 0x14, 0x10, 0x26, - 0x0c, 0xe1, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd2, 0x02, 0x5d, 0x04, 0x7e, - 0xff, 0xff, 0xff, 0xed, 0xfe, 0x14, 0x04, 0xe5, 0x04, 0x01, 0x10, 0x27, - 0x0c, 0xd2, 0x02, 0x4e, 0x03, 0x6b, 0x10, 0x06, 0x0c, 0xd7, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x03, 0x3f, 0x05, 0x14, 0x10, 0x26, - 0x0c, 0xd5, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd2, 0x01, 0x2c, 0x04, 0x7e, - 0xff, 0xff, 0xff, 0xec, 0x00, 0x00, 0x04, 0xe5, 0x04, 0x7e, 0x10, 0x26, - 0x0c, 0xd6, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd2, 0x01, 0x96, 0x03, 0xe8, - 0xff, 0xff, 0x00, 0x08, 0xff, 0xc9, 0x04, 0x9f, 0x06, 0x14, 0x10, 0x06, - 0x04, 0x6e, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa1, 0xff, 0xc9, 0x04, 0xe5, - 0x06, 0x14, 0x00, 0x21, 0x00, 0x44, 0x00, 0x00, 0x01, 0x15, 0x06, 0x07, - 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, - 0x22, 0x27, 0x35, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, - 0x27, 0x26, 0x37, 0x36, 0x37, 0x36, 0x01, 0x11, 0x14, 0x17, 0x16, 0x3b, - 0x01, 0x15, 0x23, 0x22, 0x27, 0x06, 0x07, 0x06, 0x07, 0x06, 0x27, 0x26, - 0x35, 0x34, 0x37, 0x33, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, - 0x36, 0x37, 0x36, 0x19, 0x01, 0x02, 0x14, 0x4a, 0x26, 0x50, 0x0e, 0x0c, - 0x44, 0x66, 0x58, 0x52, 0x4e, 0x42, 0x38, 0x44, 0x2d, 0x3c, 0x39, 0x3c, - 0x4e, 0x4a, 0x12, 0x20, 0x01, 0x02, 0x4b, 0x55, 0x02, 0x82, 0x31, 0x2c, - 0x1a, 0x4b, 0x82, 0x50, 0x71, 0x5b, 0x4f, 0x67, 0xc7, 0xad, 0xa3, 0xd9, - 0x10, 0xb8, 0x0e, 0x9a, 0x79, 0x57, 0x75, 0x62, 0x51, 0x4a, 0x34, 0x04, - 0x4c, 0x52, 0x04, 0x0e, 0x1e, 0x21, 0x1c, 0x12, 0x10, 0x0a, 0x0f, 0x58, - 0x6e, 0x2a, 0x27, 0x0b, 0x58, 0x0a, 0x1a, 0x1a, 0x1e, 0x26, 0x11, 0x10, - 0x1c, 0x2f, 0x2e, 0x51, 0x26, 0x2b, 0x01, 0xcc, 0xfb, 0x6b, 0x6a, 0x31, - 0x2c, 0xb8, 0x7b, 0x4e, 0x2d, 0x35, 0x02, 0x02, 0x39, 0x4c, 0xb8, 0x4b, - 0x35, 0x3a, 0x2c, 0x5d, 0x2d, 0x23, 0x26, 0x23, 0x5f, 0x43, 0x01, 0x07, - 0x03, 0xb1, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, 0x00, 0x00, 0x04, 0x2b, - 0x06, 0x14, 0x00, 0x1f, 0x00, 0x00, 0x29, 0x01, 0x35, 0x21, 0x32, 0x37, - 0x36, 0x35, 0x34, 0x27, 0x01, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x01, - 0x15, 0x05, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x01, 0x16, 0x15, 0x14, - 0x07, 0x06, 0x01, 0x92, 0xfe, 0x5a, 0x01, 0x92, 0x93, 0x2e, 0x10, 0x36, - 0xfe, 0xca, 0x32, 0x0a, 0x1f, 0x68, 0x02, 0xe9, 0xfd, 0xad, 0x47, 0x15, - 0x06, 0x1f, 0x01, 0x13, 0x66, 0x3e, 0x5f, 0xb8, 0x68, 0x24, 0x24, 0x45, - 0x42, 0x01, 0x7c, 0x3d, 0x51, 0x1e, 0x26, 0x76, 0x2b, 0x01, 0x36, 0xba, - 0xfa, 0x1e, 0x28, 0x0b, 0x19, 0x20, 0x25, 0xfe, 0xb6, 0x7a, 0x7c, 0x71, - 0x65, 0x9b, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, 0x00, 0x00, 0x04, 0xe6, - 0x06, 0x14, 0x00, 0x29, 0x00, 0x00, 0x29, 0x01, 0x35, 0x21, 0x32, 0x37, - 0x36, 0x35, 0x34, 0x27, 0x01, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x01, - 0x15, 0x05, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x01, 0x16, 0x17, 0x16, - 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, 0x26, 0x2f, 0x01, 0x06, 0x07, 0x06, - 0x01, 0x9c, 0xfe, 0x50, 0x01, 0x9c, 0x93, 0x2f, 0x10, 0x36, 0xfe, 0xca, - 0x32, 0x0a, 0x1e, 0x68, 0x02, 0xea, 0xfd, 0xac, 0x46, 0x16, 0x06, 0x20, - 0x02, 0x46, 0x16, 0x26, 0x2c, 0x40, 0x58, 0x84, 0x42, 0x3a, 0x66, 0x22, - 0x60, 0x16, 0x10, 0x60, 0xb8, 0x68, 0x24, 0x24, 0x45, 0x42, 0x01, 0x7c, - 0x3d, 0x51, 0x1e, 0x26, 0x76, 0x2b, 0x01, 0x36, 0xba, 0xfa, 0x1e, 0x28, - 0x0b, 0x19, 0x20, 0x25, 0xfd, 0x3f, 0x1a, 0x0e, 0x10, 0xb8, 0x18, 0x2b, - 0x29, 0x78, 0x2e, 0x1b, 0x9b, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x43, - 0xfe, 0xc8, 0x04, 0x4b, 0x06, 0x14, 0x10, 0x06, 0x04, 0x6f, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x0a, 0xfe, 0xc8, 0x04, 0xe5, 0x06, 0x14, 0x00, 0x24, - 0x00, 0x00, 0x01, 0x11, 0x14, 0x17, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, - 0x27, 0x06, 0x07, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x03, 0x26, - 0x37, 0x33, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, - 0x36, 0x19, 0x01, 0x04, 0x12, 0x31, 0x2c, 0x2b, 0x4b, 0x82, 0x38, 0x4e, - 0x0f, 0x33, 0x68, 0x81, 0x5e, 0x7d, 0x63, 0x77, 0xf2, 0x01, 0x01, 0x40, - 0xb8, 0x41, 0xa6, 0x28, 0x49, 0x69, 0x54, 0x63, 0x45, 0x1e, 0x06, 0x14, - 0xfb, 0x6b, 0x6a, 0x31, 0x2c, 0xb8, 0x33, 0x5d, 0x3f, 0x7e, 0x2f, 0x22, - 0x2a, 0x56, 0x01, 0x03, 0x8a, 0x5c, 0x73, 0x73, 0x7e, 0x42, 0x10, 0x22, - 0x29, 0x83, 0x39, 0x01, 0x28, 0x04, 0x6a, 0x00, 0x00, 0x01, 0xff, 0xec, - 0x00, 0x00, 0x03, 0xe9, 0x06, 0x14, 0x00, 0x0d, 0x00, 0x00, 0x01, 0x14, - 0x07, 0x06, 0x29, 0x01, 0x35, 0x21, 0x32, 0x37, 0x36, 0x35, 0x11, 0x33, - 0x03, 0xe9, 0x57, 0x50, 0xfe, 0xf0, 0xfd, 0xba, 0x02, 0x0e, 0xda, 0x2c, - 0x31, 0xb8, 0x01, 0x73, 0xb2, 0x65, 0x5c, 0xb8, 0x2c, 0x31, 0x6a, 0x04, - 0x95, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xec, 0x00, 0x00, 0x04, 0xe5, - 0x06, 0x14, 0x00, 0x14, 0x00, 0x00, 0x25, 0x06, 0x29, 0x01, 0x35, 0x33, - 0x32, 0x37, 0x36, 0x35, 0x11, 0x33, 0x11, 0x14, 0x17, 0x16, 0x3b, 0x01, - 0x15, 0x21, 0x20, 0x02, 0x68, 0x4c, 0xfe, 0xf0, 0xfe, 0xe0, 0xea, 0xda, - 0x2c, 0x30, 0xb8, 0x32, 0x2c, 0xda, 0xe9, 0xfe, 0xdf, 0xfe, 0xf4, 0x56, - 0x56, 0xb8, 0x2c, 0x31, 0x6a, 0x04, 0x95, 0xfb, 0x6b, 0x6a, 0x31, 0x2c, - 0xb8, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x82, 0xfe, 0x14, 0x04, 0x54, - 0x02, 0xf3, 0x10, 0x06, 0x04, 0x70, 0x00, 0x00, 0x00, 0x02, 0x00, 0x47, - 0xfe, 0x14, 0x04, 0xe5, 0x02, 0x74, 0x00, 0x11, 0x00, 0x34, 0x00, 0x00, - 0x25, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, - 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, 0x05, 0x06, 0x07, 0x06, 0x23, 0x22, - 0x27, 0x26, 0x07, 0x06, 0x15, 0x11, 0x23, 0x11, 0x34, 0x37, 0x36, 0x33, - 0x26, 0x35, 0x34, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x1e, 0x01, - 0x3b, 0x01, 0x15, 0x23, 0x22, 0x02, 0x0c, 0x7a, 0x4c, 0x2c, 0x15, 0x35, - 0x06, 0x15, 0x3b, 0x28, 0x2e, 0x3b, 0x1b, 0x44, 0x01, 0xc0, 0x0f, 0x0d, - 0x85, 0x4b, 0xd2, 0x70, 0x23, 0x49, 0x19, 0xc8, 0x78, 0x41, 0x49, 0x02, - 0xa2, 0x4d, 0x5c, 0x48, 0x54, 0xaa, 0x28, 0x0e, 0x52, 0x66, 0x1f, 0x56, - 0xad, 0xa8, 0x2a, 0x16, 0x39, 0x3a, 0x18, 0x14, 0x58, 0x11, 0x0c, 0x1b, - 0x44, 0x44, 0x28, 0xa9, 0x0e, 0x08, 0x50, 0x4e, 0x19, 0x4b, 0x1a, 0x4f, - 0xfe, 0x93, 0x01, 0x6d, 0xad, 0x66, 0x37, 0x2a, 0x28, 0x94, 0x84, 0x3f, - 0x24, 0x47, 0xb3, 0x40, 0x5e, 0xb8, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, - 0xff, 0xce, 0x03, 0xa6, 0x02, 0x6d, 0x00, 0x18, 0x00, 0x2a, 0x00, 0x00, - 0x25, 0x06, 0x07, 0x06, 0x27, 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x37, - 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, - 0x14, 0x25, 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, - 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x06, 0x03, 0x64, 0x60, 0x8c, 0xd4, - 0x70, 0x40, 0x68, 0xa0, 0x74, 0x34, 0x2c, 0x2b, 0x05, 0x14, 0x87, 0x5e, - 0x5d, 0x45, 0x45, 0xbd, 0x15, 0x04, 0xfd, 0xf0, 0x3e, 0x9f, 0x2f, 0x13, - 0x34, 0x05, 0x16, 0x3a, 0x27, 0x27, 0x35, 0x29, 0x32, 0x0f, 0x07, 0x34, - 0x65, 0x01, 0x02, 0x64, 0x30, 0xb8, 0x24, 0x23, 0x31, 0xb5, 0x50, 0x38, - 0x1d, 0x4f, 0xab, 0x24, 0x2a, 0x8e, 0x4d, 0x45, 0x12, 0x35, 0x45, 0x13, - 0x12, 0x58, 0x11, 0x0c, 0x1b, 0x21, 0x61, 0x25, 0x00, 0x02, 0xff, 0xec, - 0xff, 0xce, 0x04, 0xe5, 0x02, 0x6d, 0x00, 0x1d, 0x00, 0x2f, 0x00, 0x00, - 0x25, 0x06, 0x23, 0x22, 0x27, 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x37, - 0x36, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x17, - 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x25, 0x16, 0x33, 0x32, 0x37, 0x36, - 0x35, 0x34, 0x27, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x06, - 0x03, 0x7c, 0x61, 0x8b, 0xd6, 0x6e, 0x40, 0x68, 0xb8, 0x8c, 0x34, 0x2c, - 0x2b, 0x05, 0x14, 0x87, 0x5e, 0x5d, 0x48, 0x42, 0xc1, 0x11, 0x05, 0x33, - 0x26, 0x69, 0x64, 0x9b, 0xae, 0xfe, 0x12, 0x3e, 0x9f, 0x2f, 0x13, 0x34, - 0x05, 0x16, 0x3a, 0x27, 0x27, 0x35, 0x29, 0x2e, 0x13, 0x07, 0x34, 0x66, - 0x62, 0x30, 0xb8, 0x24, 0x23, 0x31, 0xb5, 0x50, 0x38, 0x1d, 0x53, 0xa7, - 0x31, 0x3e, 0x2f, 0xb8, 0xc7, 0x45, 0x12, 0x35, 0x45, 0x13, 0x12, 0x58, - 0x11, 0x0c, 0x1b, 0x1e, 0x64, 0x25, 0x00, 0x00, 0xff, 0xff, 0x00, 0x36, - 0xfe, 0xb5, 0x04, 0x8d, 0x03, 0x84, 0x10, 0x26, 0x0c, 0xea, 0x00, 0x00, - 0x10, 0x07, 0x0c, 0xd1, 0x01, 0xd3, 0x02, 0xee, 0xff, 0xff, 0xff, 0xd5, - 0xfe, 0x0c, 0x04, 0xe6, 0x02, 0xaf, 0x10, 0x27, 0x0c, 0xd1, 0x01, 0x77, - 0x02, 0x19, 0x10, 0x06, 0x0b, 0xe1, 0x00, 0x00, 0xff, 0xff, 0xff, 0xec, - 0x00, 0x00, 0x02, 0xbc, 0x03, 0xe8, 0x10, 0x26, 0x0b, 0xe6, 0x00, 0x00, - 0x10, 0x07, 0x0c, 0xd1, 0x02, 0x10, 0x03, 0x52, 0xff, 0xff, 0xff, 0xec, - 0x00, 0x00, 0x04, 0xe5, 0x03, 0xe8, 0x10, 0x26, 0x0b, 0xe7, 0x00, 0x00, - 0x10, 0x07, 0x0c, 0xd1, 0x02, 0x15, 0x03, 0x52, 0xff, 0xff, 0x00, 0xde, - 0xff, 0xc6, 0x03, 0xf3, 0x02, 0xde, 0x10, 0x06, 0x04, 0x72, 0x00, 0x00, - 0x00, 0x02, 0x00, 0xf2, 0x00, 0x00, 0x04, 0xe5, 0x02, 0xee, 0x00, 0x0a, - 0x00, 0x24, 0x00, 0x00, 0x01, 0x26, 0x27, 0x26, 0x27, 0x06, 0x07, 0x06, - 0x17, 0x1e, 0x01, 0x13, 0x26, 0x27, 0x33, 0x16, 0x17, 0x16, 0x17, 0x16, - 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, 0x26, 0x27, 0x06, 0x23, 0x22, 0x27, - 0x26, 0x35, 0x34, 0x37, 0x36, 0x03, 0x05, 0x0f, 0x0d, 0x0d, 0x0c, 0x78, - 0x52, 0x6f, 0x02, 0x01, 0xb4, 0x74, 0x04, 0x03, 0xb8, 0x01, 0x24, 0x15, - 0x38, 0x1f, 0x70, 0x71, 0xa8, 0x5a, 0x49, 0x2d, 0x26, 0x8a, 0x9c, 0x38, - 0x3a, 0xbd, 0xcc, 0x6d, 0x01, 0x1a, 0x2a, 0x31, 0x32, 0x65, 0x0c, 0x43, - 0x59, 0x3e, 0x29, 0x32, 0x01, 0xd1, 0x27, 0x2b, 0xa8, 0xae, 0x65, 0x4f, - 0x2c, 0xb8, 0x33, 0x1f, 0x3b, 0x49, 0x0f, 0x30, 0x9a, 0xad, 0x7f, 0x44, - 0x00, 0x03, 0xff, 0xec, 0xff, 0xbd, 0x03, 0xe3, 0x03, 0xe5, 0x00, 0x0f, - 0x00, 0x2d, 0x00, 0x3d, 0x00, 0x00, 0x01, 0x36, 0x37, 0x36, 0x35, 0x34, - 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x07, 0x32, - 0x37, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x17, 0x26, 0x27, 0x35, - 0x16, 0x17, 0x04, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, - 0x06, 0x2b, 0x01, 0x35, 0x01, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x16, - 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x01, 0xba, 0x24, 0x22, - 0x27, 0x0f, 0x16, 0x3a, 0x41, 0x17, 0x16, 0x07, 0x15, 0xf9, 0x34, 0x4e, - 0x2d, 0x0f, 0x12, 0x2d, 0x30, 0x4d, 0x2c, 0x51, 0xdb, 0xdc, 0x01, 0x05, - 0x3b, 0x0e, 0x28, 0x4a, 0xaf, 0x83, 0x9a, 0x78, 0x92, 0xaf, 0x02, 0xd1, - 0x06, 0x62, 0x0c, 0x11, 0x34, 0x31, 0x7e, 0x10, 0x07, 0x21, 0x1d, 0x01, - 0x0d, 0x1b, 0x40, 0x48, 0x3d, 0x2e, 0x25, 0x34, 0x2d, 0x2b, 0x23, 0x1e, - 0x25, 0x76, 0x88, 0x0b, 0x69, 0x45, 0x4e, 0x40, 0x54, 0x53, 0x5a, 0x09, - 0x27, 0x0e, 0xb9, 0x43, 0xb4, 0xd6, 0xd9, 0x34, 0x39, 0x67, 0x3d, 0x71, - 0x6c, 0x29, 0xb8, 0x01, 0x44, 0x25, 0x27, 0x8a, 0x72, 0x0e, 0x13, 0x2e, - 0x43, 0x1e, 0x21, 0x3c, 0x4e, 0x45, 0x00, 0x00, 0x00, 0x03, 0xff, 0xec, - 0xfe, 0x0d, 0x04, 0xe5, 0x02, 0xab, 0x00, 0x0a, 0x00, 0x24, 0x00, 0x2f, - 0x00, 0x00, 0x25, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x23, 0x22, 0x07, - 0x06, 0x07, 0x12, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x15, 0x14, 0x07, - 0x21, 0x15, 0x21, 0x16, 0x15, 0x14, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, - 0x03, 0x21, 0x35, 0x05, 0x14, 0x17, 0x16, 0x33, 0x32, 0x35, 0x34, 0x27, - 0x26, 0x23, 0x01, 0xe4, 0x13, 0x2a, 0x60, 0x72, 0x54, 0x4b, 0x4a, 0x26, - 0xb8, 0x09, 0x81, 0x6c, 0x81, 0x8a, 0x45, 0x2e, 0xa3, 0x01, 0xe8, 0xfe, - 0x18, 0xa3, 0x2e, 0x45, 0x8a, 0x81, 0x6c, 0x81, 0x09, 0xfe, 0xc0, 0x01, - 0xf8, 0x26, 0x4a, 0x4b, 0x54, 0x72, 0x60, 0x2a, 0xb8, 0x4c, 0x5a, 0x34, - 0x70, 0x8d, 0x48, 0x75, 0x01, 0x0a, 0x7e, 0x6b, 0x63, 0x43, 0x72, 0x6f, - 0x6c, 0xb8, 0x6c, 0x6f, 0x72, 0x43, 0x63, 0x6b, 0x80, 0x01, 0x08, 0xb8, - 0xb8, 0x75, 0x48, 0x8d, 0x70, 0x34, 0x5a, 0x4c, 0xff, 0xff, 0x00, 0x4c, - 0xfe, 0x0c, 0x04, 0x33, 0x02, 0x86, 0x10, 0x06, 0x04, 0x73, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x5a, 0xfe, 0x0c, 0x04, 0xe5, 0x02, 0x86, 0x00, 0x0b, - 0x00, 0x2c, 0x00, 0x00, 0x25, 0x34, 0x27, 0x26, 0x27, 0x26, 0x07, 0x06, - 0x07, 0x06, 0x17, 0x16, 0x05, 0x33, 0x15, 0x23, 0x27, 0x06, 0x07, 0x06, - 0x07, 0x06, 0x21, 0x35, 0x20, 0x37, 0x36, 0x37, 0x26, 0x27, 0x26, 0x27, - 0x26, 0x27, 0x26, 0x37, 0x36, 0x37, 0x36, 0x17, 0x16, 0x17, 0x16, 0x17, - 0x16, 0x03, 0x3c, 0x10, 0x18, 0x2e, 0x3c, 0x3c, 0x43, 0x0d, 0x11, 0x40, - 0x2f, 0x01, 0x73, 0xf6, 0xc2, 0x46, 0x19, 0x81, 0x53, 0x69, 0xc0, 0xfe, - 0x93, 0x01, 0x69, 0x84, 0xa8, 0x3e, 0x76, 0x2d, 0x8b, 0x33, 0x6a, 0x0a, - 0x02, 0x0a, 0x1b, 0xb0, 0x3b, 0x41, 0x57, 0x45, 0x85, 0x16, 0x0d, 0xb8, - 0x4c, 0x39, 0x50, 0x1e, 0x29, 0x1a, 0x1d, 0x38, 0x4b, 0x36, 0x28, 0x04, - 0xb8, 0x01, 0x9c, 0x81, 0x53, 0x2f, 0x56, 0xb8, 0x4c, 0x5f, 0x94, 0x03, - 0x07, 0x18, 0x2b, 0x59, 0x87, 0x1f, 0x39, 0x9b, 0x4b, 0x19, 0x01, 0x02, - 0x31, 0x5c, 0x8d, 0x53, 0xff, 0xff, 0x00, 0x19, 0xfe, 0xf3, 0x04, 0xd1, - 0x03, 0x1c, 0x10, 0x06, 0x04, 0x74, 0x00, 0x00, 0x00, 0x01, 0xff, 0x7c, - 0xfe, 0xf0, 0x04, 0xe5, 0x02, 0x02, 0x00, 0x37, 0x00, 0x00, 0x25, 0x26, - 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, - 0x17, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, 0x26, 0x23, 0x06, 0x07, - 0x06, 0x15, 0x14, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, - 0x22, 0x27, 0x26, 0x27, 0x26, 0x37, 0x33, 0x06, 0x15, 0x16, 0x17, 0x16, - 0x33, 0x32, 0x37, 0x36, 0x37, 0x36, 0x03, 0x01, 0x02, 0x09, 0x18, 0x18, - 0x2c, 0x29, 0x4d, 0x57, 0x1d, 0x2c, 0x82, 0x2e, 0x40, 0x22, 0x23, 0x23, - 0x7f, 0x43, 0x40, 0x1e, 0x22, 0x10, 0x14, 0x2a, 0x35, 0x4e, 0x68, 0xb5, - 0x8c, 0x4c, 0x79, 0x93, 0xe4, 0x0c, 0x06, 0x24, 0xb2, 0x1a, 0x01, 0x8d, - 0x45, 0x71, 0x82, 0x3a, 0x80, 0x14, 0x3c, 0x33, 0x2c, 0x0c, 0x24, 0x19, - 0x2e, 0x3d, 0x4e, 0x2f, 0x5b, 0x11, 0x06, 0x8a, 0xc0, 0xb8, 0xac, 0xa5, - 0x01, 0x10, 0x12, 0x20, 0x03, 0x45, 0x57, 0x3c, 0x53, 0x53, 0x6f, 0x1a, - 0x14, 0x24, 0x38, 0xc6, 0x5c, 0x8a, 0x50, 0x74, 0x6a, 0x1a, 0x0d, 0x11, - 0x25, 0x0f, 0x2e, 0x00, 0xff, 0xff, 0x00, 0x19, 0xfe, 0x0c, 0x04, 0xd1, - 0x03, 0x1c, 0x10, 0x26, 0x04, 0x74, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd2, - 0x01, 0x59, 0xfe, 0x0c, 0xff, 0xff, 0xff, 0x7c, 0xfe, 0x0c, 0x04, 0xe5, - 0x02, 0x02, 0x10, 0x26, 0x0c, 0x6b, 0x00, 0x00, 0x10, 0x07, 0x0c, 0xd2, - 0x00, 0xc0, 0xfe, 0x0c, 0xff, 0xff, 0xff, 0xec, 0xfe, 0xd4, 0x03, 0x12, - 0x02, 0x58, 0x10, 0x27, 0x0c, 0xd2, 0x01, 0x82, 0xfe, 0xd4, 0x10, 0x06, - 0x0b, 0xe6, 0x00, 0x00, 0xff, 0xff, 0xff, 0xec, 0xfe, 0xd4, 0x04, 0xe5, - 0x02, 0x58, 0x10, 0x27, 0x0c, 0xd2, 0x01, 0x93, 0xfe, 0xd4, 0x10, 0x06, - 0x0b, 0xe7, 0x00, 0x00, 0xff, 0xff, 0xff, 0x96, 0xff, 0xec, 0x04, 0x1e, - 0x06, 0xed, 0x10, 0x27, 0x04, 0x7e, 0xfe, 0x96, 0x01, 0x2c, 0x10, 0x06, - 0x0c, 0x76, 0x00, 0x00, 0xff, 0xff, 0xff, 0x40, 0xff, 0xec, 0x04, 0xe5, - 0x06, 0xed, 0x10, 0x27, 0x04, 0x7e, 0xfe, 0x40, 0x01, 0x2c, 0x10, 0x06, - 0x0c, 0x77, 0x00, 0x00, 0xff, 0xff, 0x00, 0x53, 0xff, 0xec, 0x04, 0x1e, - 0x07, 0xa3, 0x10, 0x27, 0x04, 0x7f, 0xfe, 0x96, 0x01, 0x2c, 0x10, 0x06, - 0x0c, 0x76, 0x00, 0x00, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xec, 0x04, 0xe5, - 0x07, 0xa3, 0x10, 0x27, 0x04, 0x7f, 0xfe, 0x23, 0x01, 0x2c, 0x10, 0x06, - 0x0c, 0x77, 0x00, 0x00, 0xff, 0xff, 0x00, 0x85, 0xfe, 0x0c, 0x04, 0x1e, - 0x06, 0x14, 0x10, 0x27, 0x04, 0x80, 0xfe, 0xc8, 0x00, 0x00, 0x10, 0x06, - 0x0c, 0x76, 0x00, 0x00, 0xff, 0xff, 0x00, 0x5f, 0xfe, 0x0c, 0x04, 0xe5, - 0x06, 0x14, 0x10, 0x27, 0x04, 0x80, 0xfe, 0xc8, 0x00, 0x00, 0x10, 0x06, - 0x0c, 0x77, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb3, 0xff, 0xec, 0x04, 0x1e, - 0x06, 0x14, 0x00, 0x16, 0x00, 0x00, 0x01, 0x10, 0x07, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x35, 0x16, 0x33, 0x32, 0x37, 0x01, 0x33, 0x01, 0x36, - 0x37, 0x36, 0x35, 0x11, 0x33, 0x04, 0x1e, 0x8b, 0x37, 0x4d, 0xcd, 0x9e, - 0x6a, 0x4b, 0x60, 0x55, 0x71, 0x88, 0xfe, 0x16, 0xb3, 0x01, 0xaa, 0x1d, - 0x14, 0x25, 0xb8, 0x03, 0x42, 0xfe, 0xd4, 0xda, 0x55, 0x47, 0xb4, 0x20, - 0xb8, 0x20, 0x98, 0x04, 0x46, 0xfc, 0x41, 0x2b, 0x37, 0x89, 0xb8, 0x02, - 0xae, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x5f, 0xff, 0xec, 0x04, 0xe5, - 0x06, 0x14, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x06, 0x07, 0x06, 0x23, 0x22, - 0x27, 0x35, 0x16, 0x33, 0x32, 0x37, 0x01, 0x33, 0x01, 0x36, 0x37, 0x36, - 0x35, 0x11, 0x33, 0x11, 0x14, 0x17, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, - 0x27, 0x26, 0x03, 0x3f, 0x3b, 0x49, 0xca, 0xa1, 0x6a, 0x4b, 0x60, 0x55, - 0x71, 0x88, 0xfe, 0x16, 0xb3, 0x01, 0xaa, 0x1d, 0x14, 0x25, 0xb8, 0x22, - 0x40, 0x50, 0x69, 0x81, 0xaf, 0x66, 0x11, 0x01, 0x3c, 0x5b, 0x41, 0xb4, - 0x20, 0xb8, 0x20, 0x98, 0x04, 0x46, 0xfc, 0x41, 0x2b, 0x37, 0x89, 0xb8, - 0x02, 0xae, 0xfc, 0x44, 0xae, 0x54, 0x9e, 0xb8, 0xf3, 0x29, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x52, 0xff, 0x54, 0x04, 0x7e, 0x07, 0x18, 0x00, 0x05, - 0x00, 0x26, 0x00, 0x2a, 0x00, 0x00, 0x09, 0x01, 0x11, 0x09, 0x01, 0x11, - 0x01, 0x35, 0x34, 0x37, 0x36, 0x3f, 0x01, 0x36, 0x37, 0x36, 0x35, 0x34, - 0x26, 0x23, 0x22, 0x06, 0x07, 0x15, 0x3e, 0x01, 0x33, 0x32, 0x16, 0x15, - 0x14, 0x06, 0x0f, 0x01, 0x06, 0x07, 0x06, 0x1d, 0x01, 0x07, 0x15, 0x33, - 0x35, 0x02, 0x68, 0x02, 0x16, 0xfd, 0xea, 0xfd, 0xea, 0x02, 0x75, 0x13, - 0x12, 0x46, 0x58, 0x5e, 0x22, 0x21, 0xdd, 0xba, 0x68, 0xbf, 0x5e, 0x62, - 0xb2, 0x4e, 0x6d, 0x83, 0x2f, 0x3e, 0x5a, 0x55, 0x1d, 0x1f, 0x07, 0xcb, - 0x07, 0x18, 0xfe, 0x17, 0xfc, 0x0e, 0xfe, 0x17, 0x01, 0xe9, 0x03, 0xf2, - 0xfc, 0x62, 0xaa, 0x3d, 0x2a, 0x28, 0x44, 0x56, 0x5c, 0x42, 0x41, 0x4c, - 0xa1, 0xc0, 0x38, 0x39, 0xbc, 0x44, 0x45, 0x6e, 0x59, 0x31, 0x58, 0x3b, - 0x59, 0x54, 0x42, 0x45, 0x62, 0x9a, 0x93, 0xfe, 0xfe, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0xb2, 0x00, 0x00, 0x04, 0x44, 0x06, 0x14, 0x00, 0x09, - 0x00, 0x0d, 0x00, 0x11, 0x00, 0x00, 0x01, 0x21, 0x11, 0x21, 0x15, 0x21, - 0x35, 0x21, 0x11, 0x23, 0x01, 0x33, 0x11, 0x23, 0x03, 0x33, 0x15, 0x23, - 0x01, 0x00, 0x02, 0x21, 0x01, 0x23, 0xfc, 0x6e, 0x01, 0x21, 0xd3, 0x01, - 0x37, 0x86, 0x86, 0x19, 0xb8, 0xb8, 0x04, 0x60, 0xfc, 0x04, 0x64, 0x64, - 0x03, 0x98, 0xfc, 0x68, 0x03, 0x98, 0x02, 0x18, 0xe9, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, 0x05, 0xd5, 0x10, 0x06, - 0x00, 0x24, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa6, 0x00, 0x00, 0x04, 0x71, - 0x05, 0xd5, 0x10, 0x06, 0x00, 0x25, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8b, - 0xff, 0xe3, 0x04, 0x31, 0x05, 0xf0, 0x10, 0x06, 0x00, 0x26, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x89, 0x00, 0x00, 0x04, 0x52, 0x05, 0xd5, 0x10, 0x06, - 0x00, 0x27, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc5, 0x00, 0x00, 0x04, 0x4e, - 0x05, 0xd5, 0x10, 0x06, 0x00, 0x28, 0x00, 0x00, 0xff, 0xff, 0x00, 0xe9, - 0x00, 0x00, 0x04, 0x58, 0x05, 0xd5, 0x10, 0x06, 0x00, 0x29, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x66, 0xff, 0xe3, 0x04, 0x50, 0x05, 0xf0, 0x10, 0x06, - 0x00, 0x2a, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0x00, 0x00, 0x04, 0x48, - 0x05, 0xd5, 0x10, 0x06, 0x00, 0x2b, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc9, - 0x00, 0x00, 0x04, 0x06, 0x05, 0xd5, 0x10, 0x06, 0x00, 0x2c, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x6d, 0xff, 0xe3, 0x03, 0xbc, 0x05, 0xd5, 0x10, 0x06, - 0x00, 0x2d, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0x00, 0x00, 0x04, 0xc9, - 0x05, 0xd5, 0x10, 0x06, 0x00, 0x2e, 0x00, 0x00, 0xff, 0xff, 0x00, 0xd7, - 0x00, 0x00, 0x04, 0x73, 0x05, 0xd5, 0x10, 0x06, 0x00, 0x2f, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x56, 0x00, 0x00, 0x04, 0x79, 0x05, 0xd5, 0x10, 0x06, - 0x00, 0x30, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8b, 0x00, 0x00, 0x04, 0x46, - 0x05, 0xd5, 0x10, 0x06, 0x00, 0x31, 0x00, 0x00, 0xff, 0xff, 0x00, 0x75, - 0xff, 0xe3, 0x04, 0x5c, 0x05, 0xf0, 0x10, 0x06, 0x00, 0x32, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc5, 0x00, 0x00, 0x04, 0x75, 0x05, 0xd5, 0x10, 0x06, - 0x00, 0x33, 0x00, 0x00, 0xff, 0xff, 0x00, 0x75, 0xfe, 0xf2, 0x04, 0x5c, - 0x05, 0xf0, 0x10, 0x06, 0x00, 0x34, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8f, - 0x00, 0x00, 0x04, 0xd1, 0x05, 0xd5, 0x10, 0x06, 0x00, 0x35, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x8b, 0xff, 0xe3, 0x04, 0x4a, 0x05, 0xf0, 0x10, 0x06, - 0x00, 0x36, 0x00, 0x00, 0xff, 0xff, 0x00, 0x2f, 0x00, 0x00, 0x04, 0xa2, - 0x05, 0xd5, 0x10, 0x06, 0x00, 0x37, 0x00, 0x00, 0xff, 0xff, 0x00, 0x93, - 0xff, 0xe3, 0x04, 0x3d, 0x05, 0xd5, 0x10, 0x06, 0x00, 0x38, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x39, 0x00, 0x00, 0x04, 0x98, 0x05, 0xd5, 0x10, 0x06, - 0x00, 0x39, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd1, - 0x05, 0xd5, 0x10, 0x06, 0x00, 0x3a, 0x00, 0x00, 0xff, 0xff, 0x00, 0x12, - 0x00, 0x00, 0x04, 0xbe, 0x05, 0xd5, 0x10, 0x06, 0x00, 0x3b, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x25, 0x00, 0x00, 0x04, 0xac, 0x05, 0xd5, 0x10, 0x06, - 0x00, 0x3c, 0x00, 0x00, 0xff, 0xff, 0x00, 0x9c, 0x00, 0x00, 0x04, 0x91, - 0x05, 0xd5, 0x10, 0x06, 0x00, 0x3d, 0x00, 0x00, 0xff, 0xff, 0x00, 0x85, - 0xff, 0xe3, 0x04, 0x23, 0x04, 0x7b, 0x10, 0x06, 0x00, 0x44, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc1, 0xff, 0xe3, 0x04, 0x58, 0x06, 0x14, 0x10, 0x06, - 0x00, 0x45, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, 0xff, 0xe3, 0x04, 0x25, - 0x04, 0x7b, 0x10, 0x06, 0x00, 0x46, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, - 0xff, 0xe3, 0x04, 0x12, 0x06, 0x14, 0x10, 0x06, 0x00, 0x47, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x7b, 0xff, 0xe3, 0x04, 0x58, 0x04, 0x7b, 0x10, 0x06, - 0x00, 0x48, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, 0x00, 0x00, 0x04, 0x27, - 0x06, 0x14, 0x10, 0x06, 0x00, 0x49, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7b, - 0xfe, 0x48, 0x04, 0x12, 0x04, 0x7b, 0x10, 0x06, 0x00, 0x4a, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0x00, 0x00, 0x04, 0x1b, 0x06, 0x14, 0x10, 0x06, - 0x00, 0x4b, 0x00, 0x00, 0xff, 0xff, 0x00, 0xb2, 0x00, 0x00, 0x04, 0x44, - 0x06, 0x14, 0x10, 0x06, 0x00, 0x4c, 0x00, 0x00, 0xff, 0xff, 0x00, 0xba, - 0xfe, 0x56, 0x03, 0x10, 0x06, 0x14, 0x10, 0x06, 0x00, 0x4d, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xec, 0x00, 0x00, 0x04, 0xb2, 0x06, 0x14, 0x10, 0x06, - 0x00, 0x4e, 0x00, 0x00, 0xff, 0xff, 0x00, 0xa0, 0x00, 0x00, 0x04, 0x0a, - 0x06, 0x1f, 0x10, 0x06, 0x00, 0x4f, 0x00, 0x00, 0xff, 0xff, 0x00, 0x6d, - 0x00, 0x00, 0x04, 0x6f, 0x04, 0x7b, 0x10, 0x06, 0x00, 0x50, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xc3, 0x00, 0x00, 0x04, 0x1b, 0x04, 0x7b, 0x10, 0x06, - 0x00, 0x51, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x48, - 0x04, 0x7b, 0x10, 0x06, 0x00, 0x52, 0x00, 0x00, 0xff, 0xff, 0x00, 0xbe, - 0xfe, 0x56, 0x04, 0x54, 0x04, 0x7b, 0x10, 0x06, 0x00, 0x53, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x89, 0xfe, 0x52, 0x04, 0x1f, 0x04, 0x77, 0x10, 0x06, - 0x00, 0x54, 0x00, 0x00, 0xff, 0xff, 0x01, 0x6a, 0x00, 0x00, 0x04, 0x83, - 0x04, 0x7b, 0x10, 0x06, 0x00, 0x55, 0x00, 0x00, 0xff, 0xff, 0x00, 0xd5, - 0xff, 0xe3, 0x04, 0x06, 0x04, 0x7b, 0x10, 0x06, 0x00, 0x56, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x83, 0x00, 0x00, 0x04, 0x08, 0x05, 0x9e, 0x10, 0x06, - 0x00, 0x57, 0x00, 0x00, 0xff, 0xff, 0x00, 0xc3, 0xff, 0xe3, 0x04, 0x1b, - 0x04, 0x5e, 0x10, 0x06, 0x00, 0x58, 0x00, 0x00, 0xff, 0xff, 0x00, 0x64, - 0x00, 0x00, 0x04, 0x6d, 0x04, 0x60, 0x10, 0x06, 0x00, 0x59, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd1, 0x04, 0x60, 0x10, 0x06, - 0x00, 0x5a, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4c, 0x00, 0x00, 0x04, 0x85, - 0x04, 0x60, 0x10, 0x06, 0x00, 0x5b, 0x00, 0x00, 0xff, 0xff, 0x00, 0x68, - 0xfe, 0x56, 0x04, 0x81, 0x04, 0x60, 0x10, 0x06, 0x00, 0x5c, 0x00, 0x00, - 0xff, 0xff, 0x00, 0xcb, 0x00, 0x00, 0x04, 0x10, 0x04, 0x62, 0x10, 0x06, - 0x00, 0x5d, 0x00, 0x00, 0xff, 0xff, 0x00, 0x85, 0xff, 0xe3, 0x04, 0x4c, - 0x05, 0xf0, 0x10, 0x06, 0x00, 0x13, 0x00, 0x00, 0xff, 0xff, 0x00, 0xf6, - 0x00, 0x00, 0x04, 0x46, 0x05, 0xd5, 0x10, 0x06, 0x00, 0x14, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x98, 0x00, 0x00, 0x04, 0x23, 0x05, 0xf0, 0x10, 0x06, - 0x00, 0x15, 0x00, 0x00, 0xff, 0xff, 0x00, 0x89, 0xff, 0xe3, 0x04, 0x37, - 0x05, 0xf0, 0x10, 0x06, 0x00, 0x16, 0x00, 0x00, 0xff, 0xff, 0x00, 0x66, - 0x00, 0x00, 0x04, 0x6f, 0x05, 0xd5, 0x10, 0x06, 0x00, 0x17, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x8f, 0xff, 0xe3, 0x04, 0x2d, 0x05, 0xd5, 0x10, 0x06, - 0x00, 0x18, 0x00, 0x00, 0xff, 0xff, 0x00, 0x85, 0xff, 0xe3, 0x04, 0x4c, - 0x05, 0xf0, 0x10, 0x06, 0x00, 0x19, 0x00, 0x00, 0xff, 0xff, 0x00, 0x8b, - 0x00, 0x00, 0x04, 0x37, 0x05, 0xd5, 0x10, 0x06, 0x00, 0x1a, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x83, 0xff, 0xe3, 0x04, 0x4e, 0x05, 0xf0, 0x10, 0x06, - 0x00, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x00, 0x7f, 0xff, 0xe3, 0x04, 0x46, - 0x05, 0xf0, 0x10, 0x06, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x01, 0x01, 0xdb, - 0x04, 0xee, 0x02, 0xe6, 0x06, 0x66, 0x00, 0x03, 0x00, 0x11, 0x40, 0x06, - 0x00, 0x03, 0x04, 0x01, 0x03, 0x04, 0x10, 0xd4, 0xcc, 0x31, 0x00, 0x10, - 0xd4, 0xcc, 0x30, 0x01, 0x33, 0x03, 0x23, 0x02, 0x20, 0xc6, 0x71, 0x9a, - 0x06, 0x66, 0xfe, 0x88, 0x00, 0x02, 0x01, 0x3f, 0x05, 0x0e, 0x03, 0x91, - 0x05, 0xd9, 0x00, 0x03, 0x00, 0x07, 0x00, 0x51, 0x40, 0x0d, 0x04, 0x00, - 0xde, 0x06, 0x02, 0x08, 0x05, 0x61, 0x04, 0x01, 0x61, 0x00, 0x08, 0x10, - 0xd4, 0xfc, 0xd4, 0xec, 0x31, 0x00, 0x10, 0xd4, 0x3c, 0xec, 0x32, 0x30, - 0x00, 0x4b, 0xb0, 0x0e, 0x54, 0x58, 0xbd, 0x00, 0x08, 0x00, 0x40, 0x00, - 0x01, 0x00, 0x08, 0x00, 0x08, 0xff, 0xc0, 0x38, 0x11, 0x37, 0x38, 0x59, - 0x01, 0x4b, 0xb0, 0x0e, 0x54, 0x4b, 0xb0, 0x0d, 0x54, 0x5b, 0x58, 0xbd, - 0x00, 0x08, 0xff, 0xc0, 0x00, 0x01, 0x00, 0x08, 0x00, 0x08, 0x00, 0x40, - 0x38, 0x11, 0x37, 0x38, 0x59, 0x01, 0x33, 0x15, 0x23, 0x25, 0x33, 0x15, - 0x23, 0x01, 0x3f, 0xcb, 0xcb, 0x01, 0x88, 0xca, 0xca, 0x05, 0xd9, 0xcb, - 0xcb, 0xcb, 0x00, 0x00, 0x00, 0x01, 0x01, 0xdb, 0x04, 0xee, 0x03, 0x5a, - 0x05, 0xf6, 0x00, 0x03, 0x00, 0x6b, 0xb5, 0x00, 0x02, 0x04, 0x01, 0x03, - 0x04, 0x10, 0xd4, 0xc4, 0x31, 0x00, 0x10, 0xd4, 0xc4, 0x30, 0x00, 0x4b, - 0xb0, 0x0c, 0x54, 0x58, 0xbd, 0x00, 0x04, 0xff, 0xc0, 0x00, 0x01, 0x00, - 0x04, 0x00, 0x04, 0x00, 0x40, 0x38, 0x11, 0x37, 0x38, 0x59, 0x00, 0x4b, - 0xb0, 0x0e, 0x54, 0x58, 0xbd, 0x00, 0x04, 0x00, 0x40, 0x00, 0x01, 0x00, - 0x04, 0x00, 0x04, 0xff, 0xc0, 0x38, 0x11, 0x37, 0x38, 0x59, 0x40, 0x26, - 0x0f, 0x00, 0x0f, 0x01, 0x0a, 0x02, 0x0a, 0x03, 0x1f, 0x00, 0x1f, 0x01, - 0x1f, 0x02, 0x1f, 0x03, 0x2f, 0x00, 0x2f, 0x01, 0x2f, 0x02, 0x2f, 0x03, - 0x0c, 0x0f, 0x00, 0x0f, 0x01, 0x1f, 0x00, 0x1f, 0x01, 0x2f, 0x00, 0x2f, - 0x01, 0x06, 0x5d, 0x01, 0x5d, 0x01, 0x33, 0x03, 0x23, 0x02, 0xa0, 0xba, - 0xe5, 0x9a, 0x05, 0xf6, 0xfe, 0xf8, 0x00, 0x00, 0x00, 0x01, 0x01, 0x1f, - 0x05, 0x0e, 0x03, 0xb2, 0x05, 0xe9, 0x00, 0x1d, 0x00, 0xd1, 0x40, 0x1e, - 0x16, 0x10, 0x0f, 0x03, 0x13, 0x0c, 0x07, 0x01, 0x00, 0x03, 0x08, 0x04, - 0xcc, 0x17, 0x0c, 0x13, 0xcc, 0x1b, 0x08, 0x1e, 0x10, 0x01, 0x0f, 0x00, - 0x07, 0x16, 0x18, 0x07, 0x09, 0x1e, 0x10, 0xd4, 0xc4, 0xd4, 0xc4, 0x11, - 0x39, 0x39, 0x39, 0x39, 0x31, 0x00, 0x10, 0xd4, 0x3c, 0xfc, 0xd4, 0x3c, - 0xec, 0x11, 0x17, 0x39, 0x11, 0x12, 0x17, 0x39, 0x30, 0x00, 0x4b, 0xb0, - 0x0e, 0x54, 0x4b, 0xb0, 0x11, 0x54, 0x5b, 0x58, 0xbd, 0x00, 0x1e, 0x00, - 0x40, 0x00, 0x01, 0x00, 0x1e, 0x00, 0x1e, 0xff, 0xc0, 0x38, 0x11, 0x37, - 0x38, 0x59, 0x40, 0x74, 0x09, 0x00, 0x09, 0x01, 0x0f, 0x0b, 0x0f, 0x0c, - 0x0f, 0x0d, 0x0d, 0x0e, 0x0f, 0x0f, 0x0f, 0x10, 0x0f, 0x11, 0x0f, 0x12, - 0x0f, 0x13, 0x0f, 0x14, 0x0f, 0x15, 0x0f, 0x16, 0x0f, 0x17, 0x0f, 0x18, - 0x0b, 0x19, 0x1a, 0x00, 0x1a, 0x01, 0x1d, 0x0b, 0x1d, 0x0c, 0x1d, 0x0d, - 0x1e, 0x0e, 0x1f, 0x0f, 0x1f, 0x10, 0x1f, 0x11, 0x1f, 0x12, 0x1f, 0x13, - 0x1f, 0x14, 0x1f, 0x15, 0x1f, 0x16, 0x1f, 0x17, 0x1f, 0x18, 0x21, 0x0f, - 0x01, 0x0f, 0x02, 0x0f, 0x03, 0x0f, 0x04, 0x0f, 0x05, 0x0f, 0x0b, 0x0f, - 0x0c, 0x0f, 0x0d, 0x0f, 0x15, 0x0f, 0x16, 0x0f, 0x17, 0x0f, 0x18, 0x1f, - 0x01, 0x1f, 0x02, 0x1f, 0x03, 0x1f, 0x04, 0x1f, 0x05, 0x1f, 0x0b, 0x1f, - 0x0c, 0x1f, 0x0d, 0x1f, 0x15, 0x1f, 0x16, 0x1f, 0x17, 0x1f, 0x18, 0x18, - 0x5d, 0x01, 0x5d, 0x01, 0x27, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x1d, 0x01, - 0x23, 0x34, 0x36, 0x33, 0x32, 0x16, 0x1f, 0x01, 0x1e, 0x01, 0x33, 0x32, - 0x36, 0x3d, 0x01, 0x33, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x02, 0x64, 0x39, - 0x19, 0x1f, 0x0c, 0x23, 0x28, 0x7d, 0x67, 0x55, 0x24, 0x3d, 0x31, 0x39, - 0x16, 0x23, 0x0f, 0x1f, 0x28, 0x7d, 0x02, 0x66, 0x54, 0x22, 0x3c, 0x05, - 0x39, 0x21, 0x0e, 0x0b, 0x32, 0x2d, 0x06, 0x65, 0x76, 0x10, 0x1b, 0x1e, - 0x0d, 0x0c, 0x33, 0x29, 0x06, 0x64, 0x77, 0x10, 0x00, 0x01, 0x01, 0x79, - 0x04, 0xee, 0x02, 0xf6, 0x05, 0xf6, 0x00, 0x03, 0x00, 0x69, 0xb5, 0x00, - 0x01, 0x04, 0x01, 0x03, 0x04, 0x10, 0xd4, 0xc4, 0x31, 0x00, 0x10, 0xd4, - 0xc4, 0x30, 0x00, 0x4b, 0xb0, 0x0c, 0x54, 0x58, 0xbd, 0x00, 0x04, 0xff, - 0xc0, 0x00, 0x01, 0x00, 0x04, 0x00, 0x04, 0x00, 0x40, 0x38, 0x11, 0x37, - 0x38, 0x59, 0x00, 0x4b, 0xb0, 0x0e, 0x54, 0x58, 0xbd, 0x00, 0x04, 0x00, - 0x40, 0x00, 0x01, 0x00, 0x04, 0x00, 0x04, 0xff, 0xc0, 0x38, 0x11, 0x37, - 0x38, 0x59, 0x01, 0x4b, 0xb0, 0x0e, 0x54, 0x58, 0xbd, 0x00, 0x04, 0x00, - 0x40, 0x00, 0x01, 0x00, 0x04, 0x00, 0x04, 0xff, 0xc0, 0x38, 0x11, 0x37, - 0x38, 0x59, 0x40, 0x0d, 0x0f, 0x00, 0x0f, 0x03, 0x1f, 0x00, 0x1f, 0x03, - 0x2f, 0x00, 0x2f, 0x03, 0x06, 0x00, 0x5d, 0x01, 0x13, 0x23, 0x03, 0x02, - 0x31, 0xc5, 0x9a, 0xe3, 0x05, 0xf6, 0xfe, 0xf8, 0x01, 0x08, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x37, 0x04, 0xee, 0x03, 0x9a, 0x05, 0xf8, 0x00, 0x06, - 0x00, 0x5d, 0x40, 0x09, 0x04, 0x00, 0x05, 0x02, 0x07, 0x04, 0x02, 0x06, - 0x07, 0x10, 0xd4, 0xc4, 0x39, 0x31, 0x00, 0x10, 0xd4, 0x3c, 0xc4, 0x39, - 0x30, 0x00, 0x4b, 0xb0, 0x0c, 0x54, 0x58, 0xbd, 0x00, 0x07, 0xff, 0xc0, - 0x00, 0x01, 0x00, 0x07, 0x00, 0x07, 0x00, 0x40, 0x38, 0x11, 0x37, 0x38, - 0x59, 0x00, 0x4b, 0xb0, 0x0e, 0x54, 0x58, 0xbd, 0x00, 0x07, 0x00, 0x40, - 0x00, 0x01, 0x00, 0x07, 0x00, 0x07, 0xff, 0xc0, 0x38, 0x11, 0x37, 0x38, - 0x59, 0x40, 0x13, 0x0f, 0x00, 0x0f, 0x01, 0x0c, 0x04, 0x1f, 0x00, 0x1f, - 0x01, 0x1c, 0x04, 0x2f, 0x00, 0x2f, 0x01, 0x2c, 0x04, 0x09, 0x5d, 0x01, - 0x33, 0x13, 0x23, 0x27, 0x07, 0x23, 0x02, 0x0a, 0xbd, 0xd3, 0x8c, 0xa6, - 0xa5, 0x8c, 0x05, 0xf8, 0xfe, 0xf6, 0xb2, 0xb2, 0x00, 0x01, 0x01, 0x37, - 0x04, 0xee, 0x03, 0x9a, 0x05, 0xf8, 0x00, 0x06, 0x00, 0x69, 0x40, 0x09, - 0x03, 0x04, 0x01, 0x00, 0x07, 0x03, 0x05, 0x01, 0x07, 0x10, 0xd4, 0xc4, - 0x39, 0x31, 0x00, 0x10, 0xd4, 0xc4, 0x32, 0x39, 0x30, 0x00, 0x4b, 0xb0, - 0x0e, 0x54, 0x58, 0xbd, 0x00, 0x07, 0x00, 0x40, 0x00, 0x01, 0x00, 0x07, - 0x00, 0x07, 0xff, 0xc0, 0x38, 0x11, 0x37, 0x38, 0x59, 0x00, 0x4b, 0xb0, - 0x0c, 0x54, 0x58, 0xbd, 0x00, 0x07, 0xff, 0xc0, 0x00, 0x01, 0x00, 0x07, - 0x00, 0x07, 0x00, 0x40, 0x38, 0x11, 0x37, 0x38, 0x59, 0x40, 0x1f, 0x0f, - 0x01, 0x0f, 0x02, 0x0a, 0x03, 0x0f, 0x04, 0x0f, 0x05, 0x1f, 0x01, 0x1f, - 0x02, 0x1a, 0x03, 0x1f, 0x04, 0x1f, 0x05, 0x2f, 0x01, 0x2f, 0x02, 0x2a, - 0x03, 0x2f, 0x04, 0x2f, 0x05, 0x0f, 0x5d, 0x01, 0x03, 0x33, 0x17, 0x37, - 0x33, 0x03, 0x02, 0x0a, 0xd3, 0x8c, 0xa5, 0xa6, 0x8c, 0xd3, 0x04, 0xee, - 0x01, 0x0a, 0xb2, 0xb2, 0xfe, 0xf6, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1b, - 0x01, 0xf8, 0x04, 0x5a, 0x03, 0x6a, 0x00, 0x03, 0x00, 0x19, 0x40, 0x0a, - 0x01, 0x00, 0x03, 0x02, 0x04, 0x02, 0x00, 0x03, 0x01, 0x04, 0x10, 0xd4, - 0xc4, 0x39, 0x39, 0x31, 0x00, 0x10, 0xd4, 0xdc, 0xd4, 0xcc, 0x30, 0x13, - 0x27, 0x01, 0x17, 0x33, 0x18, 0x04, 0x24, 0x1b, 0x01, 0xf8, 0x6c, 0x01, - 0x06, 0x6c, 0x00, 0x00, 0x00, 0x01, 0x01, 0x2f, 0x06, 0x7b, 0x03, 0xa2, - 0x07, 0x6d, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x3e, 0x01, 0x20, 0x16, 0x17, - 0x23, 0x2e, 0x01, 0x23, 0x22, 0x06, 0x07, 0x01, 0x2f, 0x0b, 0x9e, 0x01, - 0x20, 0x9f, 0x0b, 0x77, 0x0f, 0x61, 0x53, 0x52, 0x64, 0x0c, 0x06, 0x7b, - 0x78, 0x7a, 0x7b, 0x77, 0x38, 0x37, 0x39, 0x36, 0x00, 0x01, 0x01, 0x2f, - 0x06, 0x7b, 0x03, 0xa2, 0x07, 0x6d, 0x00, 0x0d, 0x00, 0x1f, 0xb2, 0x07, - 0x00, 0x04, 0xb8, 0x01, 0x03, 0x40, 0x09, 0x0b, 0x0e, 0x07, 0x50, 0x08, - 0x01, 0x50, 0x00, 0x0e, 0x10, 0xd4, 0xec, 0xd4, 0xec, 0x31, 0x00, 0x10, - 0xd4, 0xfc, 0xc4, 0x32, 0x30, 0x01, 0x33, 0x1e, 0x01, 0x33, 0x32, 0x36, - 0x37, 0x33, 0x0e, 0x01, 0x23, 0x22, 0x26, 0x01, 0x2f, 0x77, 0x0c, 0x64, - 0x52, 0x53, 0x61, 0x0f, 0x77, 0x0b, 0x9f, 0x90, 0x90, 0x9e, 0x07, 0x6d, - 0x36, 0x39, 0x37, 0x38, 0x77, 0x7b, 0x7a, 0x00, 0x00, 0x01, 0x02, 0x01, - 0x06, 0x83, 0x02, 0xce, 0x07, 0x50, 0x00, 0x03, 0x00, 0x12, 0xb7, 0x00, - 0xde, 0x02, 0x04, 0x01, 0x61, 0x00, 0x04, 0x10, 0xd4, 0xec, 0x31, 0x00, - 0x10, 0xd4, 0xec, 0x30, 0x01, 0x33, 0x15, 0x23, 0x02, 0x01, 0xcd, 0xcd, - 0x07, 0x50, 0xcd, 0x00, 0x00, 0x02, 0x01, 0x58, 0x06, 0x63, 0x04, 0x16, - 0x07, 0x6b, 0x00, 0x03, 0x00, 0x07, 0x00, 0x19, 0x40, 0x0a, 0x00, 0x04, - 0x03, 0x07, 0x08, 0x01, 0x03, 0x05, 0x07, 0x08, 0x10, 0xd4, 0xcc, 0xd4, - 0xcc, 0x31, 0x00, 0x10, 0xd4, 0x3c, 0xcc, 0x32, 0x30, 0x01, 0x33, 0x03, - 0x23, 0x03, 0x33, 0x03, 0x23, 0x03, 0x5c, 0xba, 0xe5, 0x9a, 0x7a, 0xba, - 0xe5, 0x9a, 0x07, 0x6b, 0xfe, 0xf8, 0x01, 0x08, 0xfe, 0xf8, 0x00, 0x00, - 0x00, 0x02, 0x00, 0xbb, 0x06, 0x63, 0x03, 0x79, 0x07, 0x6b, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x00, 0x01, 0x13, 0x23, 0x03, 0x21, 0x13, 0x23, 0x03, - 0x01, 0x75, 0xc5, 0x9a, 0xe5, 0x01, 0xf9, 0xc5, 0x9a, 0xe5, 0x07, 0x6b, - 0xfe, 0xf8, 0x01, 0x08, 0xfe, 0xf8, 0x01, 0x08, 0x00, 0x02, 0x01, 0x66, - 0x00, 0x00, 0x03, 0x95, 0x05, 0xf0, 0x00, 0x24, 0x00, 0x28, 0x00, 0x00, - 0x01, 0x23, 0x35, 0x34, 0x37, 0x36, 0x3f, 0x01, 0x3e, 0x01, 0x35, 0x34, - 0x27, 0x26, 0x27, 0x26, 0x07, 0x06, 0x07, 0x35, 0x36, 0x37, 0x36, 0x17, - 0x16, 0x17, 0x16, 0x15, 0x14, 0x07, 0x06, 0x0f, 0x01, 0x06, 0x07, 0x06, - 0x15, 0x03, 0x33, 0x15, 0x23, 0x02, 0xae, 0xc2, 0x13, 0x14, 0x37, 0x3a, - 0x29, 0x1e, 0x2a, 0x25, 0x3e, 0x38, 0x27, 0x39, 0x40, 0x42, 0x39, 0x51, - 0x5b, 0x7e, 0x43, 0x47, 0x15, 0x16, 0x3d, 0x39, 0x2e, 0x0c, 0x0c, 0xc7, - 0xcb, 0xcb, 0x01, 0x91, 0x9a, 0x62, 0x45, 0x42, 0x54, 0x59, 0x3b, 0x58, - 0x31, 0x49, 0x2a, 0x25, 0x04, 0x02, 0x16, 0x23, 0x44, 0xd9, 0x3e, 0x17, - 0x22, 0x06, 0x07, 0x59, 0x60, 0xa1, 0x4c, 0x41, 0x42, 0x5c, 0x56, 0x45, - 0x27, 0x2a, 0x3d, 0xfe, 0xc3, 0xfe, 0x00, 0x00, 0x00, 0x01, 0x01, 0x3d, - 0x06, 0x9c, 0x03, 0x93, 0x07, 0x30, 0x00, 0x03, 0x00, 0x11, 0xb6, 0x02, - 0xb6, 0x00, 0x04, 0x01, 0x00, 0x04, 0x10, 0xd4, 0xcc, 0x31, 0x00, 0x10, - 0xd4, 0xec, 0x30, 0x01, 0x21, 0x15, 0x21, 0x01, 0x3d, 0x02, 0x56, 0xfd, - 0xaa, 0x07, 0x30, 0x94, 0x00, 0x01, 0x00, 0x9c, 0xff, 0x34, 0x04, 0x35, - 0xff, 0xa6, 0x00, 0x03, 0x00, 0x00, 0x05, 0x21, 0x35, 0x21, 0x04, 0x35, - 0xfc, 0x67, 0x03, 0x99, 0xcc, 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, - 0xff, 0x34, 0x04, 0xcb, 0xff, 0xa6, 0x00, 0x03, 0x00, 0x00, 0x05, 0x21, - 0x35, 0x21, 0x04, 0xcb, 0xfb, 0x3b, 0x04, 0xc5, 0xcc, 0x72, 0x00, 0x00, - 0x00, 0x01, 0x01, 0x00, 0xff, 0x34, 0x03, 0xd1, 0xff, 0xa6, 0x00, 0x03, - 0x00, 0x00, 0x05, 0x21, 0x35, 0x21, 0x03, 0xd1, 0xfd, 0x2f, 0x02, 0xd1, - 0xcc, 0x72, 0x00, 0x00, 0x00, 0x02, 0x01, 0x5e, 0x01, 0xd4, 0x03, 0x73, - 0x03, 0xe9, 0x00, 0x0b, 0x00, 0x13, 0x00, 0x00, 0x01, 0x32, 0x17, 0x1e, - 0x01, 0x15, 0x14, 0x06, 0x22, 0x26, 0x34, 0x36, 0x16, 0x22, 0x06, 0x14, - 0x16, 0x32, 0x36, 0x34, 0x02, 0x68, 0x72, 0x4c, 0x26, 0x27, 0x9c, 0xe2, - 0x97, 0x9a, 0xab, 0x76, 0x55, 0x52, 0x79, 0x56, 0x03, 0xe9, 0x50, 0x25, - 0x60, 0x38, 0x6e, 0x9a, 0x97, 0xe2, 0x9c, 0x7c, 0x54, 0x79, 0x52, 0x54, - 0x76, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x3f, 0x05, 0x46, 0x03, 0x91, - 0x06, 0x10, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x01, 0x33, 0x15, 0x23, - 0x25, 0x33, 0x15, 0x23, 0x01, 0x3f, 0xcb, 0xcb, 0x01, 0x88, 0xca, 0xca, - 0x06, 0x10, 0xca, 0xca, 0xca, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x96, 0x00, 0x96, 0x00, 0x03, 0x00, 0x00, 0x35, 0x33, - 0x15, 0x23, 0x96, 0x96, 0x96, 0x96, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x90, 0x00, 0x96, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, - 0x37, 0x33, 0x15, 0x23, 0x27, 0x33, 0x15, 0x23, 0xfa, 0x96, 0x96, 0xfa, - 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x90, 0x01, 0x90, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0b, - 0x00, 0x00, 0x13, 0x33, 0x15, 0x23, 0x17, 0x33, 0x15, 0x23, 0x27, 0x33, - 0x15, 0x23, 0x7d, 0x96, 0x96, 0x7d, 0x96, 0x96, 0xfa, 0x96, 0x96, 0x01, - 0x90, 0x96, 0x64, 0x96, 0x96, 0x96, 0x00, 0x00, 0x00, 0x01, 0x00, 0x45, - 0xff, 0xec, 0x04, 0xe5, 0x02, 0x1c, 0x00, 0x26, 0x00, 0x00, 0x05, 0x22, - 0x27, 0x26, 0x35, 0x34, 0x37, 0x33, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, - 0x32, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x33, 0x16, 0x15, 0x14, - 0x17, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, 0x26, 0x27, 0x06, 0x07, - 0x06, 0x02, 0x1f, 0xba, 0x83, 0x9d, 0x29, 0xb8, 0x2b, 0x75, 0x62, 0x7f, - 0x45, 0x82, 0x57, 0x2d, 0x37, 0x1d, 0xb8, 0x13, 0x18, 0x13, 0x18, 0x21, - 0x4b, 0x34, 0x2f, 0x2b, 0x14, 0x58, 0x60, 0x74, 0x14, 0x38, 0x41, 0xdb, - 0x3e, 0x7c, 0x8a, 0x30, 0x6c, 0x1e, 0x19, 0x37, 0x25, 0x35, 0x41, 0x38, - 0x3e, 0x37, 0x4b, 0x5a, 0x64, 0x33, 0x28, 0xb8, 0x2c, 0x2a, 0x4f, 0x51, - 0x2f, 0x39, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x00, 0x00, 0x03, 0x3f, - 0x03, 0xd9, 0x00, 0x0f, 0x00, 0x30, 0x00, 0x00, 0x01, 0x36, 0x35, 0x34, - 0x27, 0x26, 0x07, 0x06, 0x07, 0x06, 0x07, 0x14, 0x17, 0x16, 0x33, 0x32, - 0x01, 0x33, 0x32, 0x37, 0x36, 0x37, 0x36, 0x37, 0x06, 0x07, 0x06, 0x27, - 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, - 0x16, 0x15, 0x14, 0x07, 0x06, 0x07, 0x06, 0x23, 0x21, 0x02, 0x56, 0x29, - 0x42, 0x1f, 0x2c, 0x34, 0x28, 0x28, 0x01, 0x37, 0x28, 0x2a, 0x48, 0xfd, - 0xae, 0xf1, 0x54, 0x97, 0x4f, 0x3c, 0x1f, 0x0f, 0x3f, 0x61, 0x82, 0x4e, - 0x62, 0x08, 0x17, 0x96, 0x4e, 0x4c, 0x5a, 0x42, 0x60, 0x2e, 0x17, 0x4e, - 0x4a, 0x7c, 0x6d, 0x91, 0xfe, 0xbf, 0x02, 0x19, 0x2b, 0x4d, 0x3b, 0x33, - 0x19, 0x01, 0x01, 0x2a, 0x29, 0x33, 0x50, 0x26, 0x19, 0xfe, 0xb7, 0x17, - 0x0c, 0x5d, 0x30, 0x32, 0x37, 0x02, 0x02, 0x45, 0x57, 0x81, 0x34, 0x2c, - 0x94, 0x45, 0x24, 0x32, 0x48, 0x66, 0x33, 0x8c, 0xd0, 0x8f, 0x88, 0x2c, - 0x27, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x00, 0x00, 0x04, 0xe5, - 0x03, 0x08, 0x00, 0x20, 0x00, 0x33, 0x00, 0x00, 0x01, 0x16, 0x17, 0x16, - 0x15, 0x14, 0x07, 0x06, 0x07, 0x16, 0x3b, 0x01, 0x15, 0x21, 0x22, 0x27, - 0x06, 0x23, 0x21, 0x35, 0x33, 0x32, 0x37, 0x26, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x36, 0x37, 0x36, 0x32, 0x06, 0x22, 0x07, 0x06, 0x07, 0x06, 0x15, - 0x14, 0x17, 0x16, 0x17, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x26, 0x27, - 0x02, 0xc8, 0xb7, 0x19, 0x08, 0x16, 0x1c, 0x24, 0x26, 0x94, 0xe1, 0xfe, - 0xc5, 0x88, 0xba, 0xb8, 0x88, 0xfe, 0xc4, 0xe2, 0x92, 0x28, 0x1e, 0x24, - 0x14, 0x08, 0x17, 0xb9, 0x1e, 0x80, 0x32, 0x1c, 0x12, 0x38, 0x18, 0x0a, - 0x18, 0x1e, 0x44, 0x40, 0x24, 0x18, 0x0a, 0x18, 0x38, 0x02, 0xfa, 0x50, - 0x96, 0x32, 0x2a, 0x49, 0x31, 0x43, 0x32, 0x11, 0xb8, 0x39, 0x39, 0xb8, - 0x11, 0x28, 0x4d, 0x2e, 0x4c, 0x2c, 0x30, 0x8f, 0x57, 0x0e, 0xb8, 0x0a, - 0x20, 0x35, 0x15, 0x1d, 0x2b, 0x35, 0x44, 0x16, 0x15, 0x45, 0x32, 0x2e, - 0x18, 0x1a, 0x34, 0x21, 0x00, 0x02, 0xff, 0xed, 0xfe, 0x14, 0x04, 0xe5, - 0x02, 0xe4, 0x00, 0x2e, 0x00, 0x40, 0x00, 0x00, 0x25, 0x26, 0x27, 0x26, - 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, - 0x17, 0x16, 0x17, 0x16, 0x3b, 0x01, 0x15, 0x2b, 0x01, 0x06, 0x07, 0x06, - 0x07, 0x06, 0x27, 0x24, 0x27, 0x26, 0x35, 0x34, 0x37, 0x33, 0x06, 0x15, - 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, 0x13, 0x36, 0x27, 0x26, 0x27, - 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, 0x17, 0x16, 0x17, - 0x16, 0x03, 0x8c, 0x42, 0x2e, 0x79, 0x39, 0x93, 0x06, 0x28, 0x93, 0x29, - 0x57, 0x70, 0x38, 0x63, 0x32, 0x14, 0x06, 0x1a, 0x04, 0x58, 0x5d, 0x30, - 0x1e, 0x4c, 0x68, 0x8e, 0x97, 0xa4, 0xfe, 0xd3, 0x5e, 0x45, 0x3e, 0xb8, - 0x3e, 0x1b, 0x3a, 0xc3, 0x6c, 0x75, 0x9e, 0x7b, 0x04, 0x16, 0x13, 0x2f, - 0x22, 0x27, 0x22, 0x15, 0x35, 0x13, 0x0a, 0x39, 0x4c, 0x64, 0x2f, 0x0a, - 0x05, 0x0d, 0x23, 0x2b, 0x6d, 0xb9, 0x3d, 0x1a, 0xa5, 0x45, 0x13, 0x32, - 0x58, 0x91, 0x3a, 0xd6, 0x01, 0xb8, 0x53, 0x6d, 0x95, 0x4a, 0x4e, 0x01, - 0x02, 0xbe, 0x8a, 0x7d, 0xa6, 0x60, 0x6b, 0x9b, 0x49, 0x3d, 0x82, 0x3c, - 0x51, 0x01, 0x6b, 0x7a, 0x57, 0x4b, 0x23, 0x19, 0x0a, 0x1c, 0x39, 0x1e, - 0x19, 0x3c, 0x2c, 0x3b, 0x14, 0x09, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6a, - 0xff, 0xa5, 0x04, 0xe5, 0x03, 0x04, 0x00, 0x2b, 0x00, 0x3d, 0x00, 0x00, - 0x25, 0x06, 0x07, 0x06, 0x07, 0x06, 0x27, 0x24, 0x03, 0x34, 0x37, 0x33, - 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x26, 0x27, 0x26, 0x35, - 0x34, 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, - 0x14, 0x07, 0x16, 0x3b, 0x01, 0x15, 0x23, 0x22, 0x27, 0x36, 0x35, 0x34, - 0x27, 0x26, 0x27, 0x26, 0x23, 0x22, 0x07, 0x06, 0x07, 0x06, 0x15, 0x14, - 0x17, 0x16, 0x03, 0x73, 0x3d, 0x76, 0xb6, 0x7c, 0x8b, 0x71, 0xfe, 0xda, - 0x02, 0x40, 0xb8, 0x42, 0xaa, 0x47, 0x83, 0x70, 0x97, 0x22, 0x1d, 0x52, - 0x04, 0x16, 0xbc, 0x3a, 0x34, 0x52, 0x51, 0x8b, 0x10, 0x04, 0x50, 0x09, - 0x07, 0x95, 0x9a, 0x69, 0x6f, 0x68, 0x05, 0x0e, 0x34, 0x22, 0x28, 0x18, - 0x16, 0x3d, 0x13, 0x06, 0x29, 0x31, 0x24, 0x21, 0x24, 0x38, 0x02, 0x02, - 0x28, 0x67, 0x01, 0x08, 0x8a, 0x5c, 0x5e, 0x88, 0x7d, 0x45, 0x1d, 0x3a, - 0x1b, 0x2c, 0x7c, 0x6c, 0x27, 0x1c, 0x9b, 0x4b, 0x17, 0x32, 0x54, 0x95, - 0x25, 0x1e, 0x83, 0x6a, 0x01, 0xb8, 0xdf, 0x41, 0x6d, 0x14, 0x1b, 0x47, - 0x27, 0x19, 0x0a, 0x19, 0x3c, 0x13, 0x12, 0x2b, 0x42, 0x4e, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x00, 0xff, 0x06, 0x01, 0x90, 0x00, 0x96, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x0b, 0x00, 0x00, 0x17, 0x35, 0x33, 0x15, 0x27, 0x35, - 0x33, 0x15, 0x21, 0x35, 0x33, 0x15, 0x7d, 0x96, 0x19, 0x96, 0xfe, 0x70, - 0x96, 0xfa, 0x96, 0x96, 0xfa, 0x96, 0x96, 0x96, 0x96, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0xff, 0x06, 0x00, 0x96, 0x00, 0x96, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x00, 0x15, 0x33, 0x15, 0x23, 0x11, 0x33, 0x15, 0x23, - 0x96, 0x96, 0x96, 0x96, 0x64, 0x96, 0x01, 0x90, 0x96, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x00, 0xff, 0x06, 0x01, 0x90, 0x00, 0x96, 0x00, 0x03, - 0x00, 0x07, 0x00, 0x0b, 0x00, 0x0f, 0x00, 0x00, 0x17, 0x33, 0x15, 0x23, - 0x11, 0x33, 0x15, 0x23, 0x07, 0x33, 0x15, 0x23, 0x11, 0x33, 0x15, 0x23, - 0xfa, 0x96, 0x96, 0x96, 0x96, 0xfa, 0x96, 0x96, 0x96, 0x96, 0x64, 0x96, - 0x01, 0x90, 0x96, 0x64, 0x96, 0x01, 0x90, 0x96, 0x00, 0x01, 0x00, 0x00, - 0x04, 0x74, 0x02, 0xb7, 0x07, 0x38, 0x00, 0x03, 0x00, 0x00, 0x09, 0x01, - 0x35, 0x01, 0x02, 0xb7, 0xfd, 0x49, 0x02, 0xb7, 0x06, 0x86, 0xfd, 0xee, - 0xb2, 0x02, 0x12, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0xf3, 0x03, 0x9c, - 0x07, 0x39, 0x00, 0x03, 0x00, 0x00, 0x09, 0x01, 0x35, 0x01, 0x03, 0x9c, - 0xfc, 0x64, 0x03, 0x9c, 0x06, 0x87, 0xfe, 0x6d, 0xb2, 0x01, 0x93, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0xb6, 0x01, 0xb7, 0x00, 0x0b, - 0x00, 0x17, 0x00, 0x00, 0x25, 0x34, 0x27, 0x26, 0x22, 0x06, 0x15, 0x14, - 0x17, 0x16, 0x32, 0x3e, 0x01, 0x14, 0x07, 0x06, 0x22, 0x27, 0x26, 0x34, - 0x37, 0x36, 0x32, 0x17, 0x01, 0x3c, 0x1c, 0x1c, 0x52, 0x38, 0x1c, 0x1c, - 0x52, 0x38, 0x7a, 0x3f, 0x40, 0xb8, 0x3f, 0x40, 0x40, 0x3f, 0xb8, 0x40, - 0xdc, 0x28, 0x1c, 0x1d, 0x38, 0x29, 0x2a, 0x1c, 0x1b, 0x38, 0x85, 0xb8, - 0x40, 0x40, 0x40, 0x40, 0xb8, 0x40, 0x3f, 0x3f, 0x00, 0x01, 0x00, 0x95, - 0xfe, 0x56, 0x04, 0x3c, 0x05, 0xd5, 0x00, 0x13, 0x00, 0x44, 0x40, 0x21, - 0x11, 0x01, 0x02, 0x01, 0x02, 0x10, 0x11, 0x10, 0x42, 0x11, 0x02, 0x03, - 0x00, 0xb4, 0x13, 0x0b, 0x97, 0x0a, 0x10, 0x13, 0x01, 0x11, 0x10, 0x03, - 0x11, 0x0b, 0x04, 0x31, 0x11, 0x11, 0x00, 0x30, 0x14, 0x10, 0xfc, 0xec, - 0xfc, 0xc4, 0xec, 0x32, 0x11, 0x39, 0x31, 0x00, 0x2f, 0x3c, 0xd4, 0xec, - 0x10, 0xec, 0x32, 0x39, 0x39, 0x30, 0x4b, 0x53, 0x58, 0x07, 0x10, 0x04, - 0xc9, 0x07, 0x10, 0x04, 0xc9, 0x59, 0x13, 0x33, 0x01, 0x11, 0x33, 0x11, - 0x14, 0x07, 0x06, 0x2b, 0x01, 0x35, 0x33, 0x32, 0x37, 0x36, 0x35, 0x01, - 0x11, 0x23, 0x95, 0xb9, 0x02, 0x35, 0xb9, 0x59, 0x5a, 0xa5, 0xcd, 0xb9, - 0x5a, 0x2d, 0x2c, 0xfd, 0xcb, 0xb9, 0x05, 0xd5, 0xfb, 0x97, 0x04, 0x69, - 0xfa, 0x17, 0xc3, 0x69, 0x6a, 0x9c, 0x3e, 0x3e, 0x92, 0x04, 0x69, 0xfb, - 0x97, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x45, 0xff, 0xec, 0x04, 0xb0, - 0x02, 0x1b, 0x00, 0x19, 0x00, 0x00, 0x01, 0x16, 0x15, 0x14, 0x07, 0x06, - 0x05, 0x06, 0x27, 0x26, 0x35, 0x34, 0x37, 0x33, 0x06, 0x15, 0x14, 0x17, - 0x16, 0x33, 0x32, 0x37, 0x36, 0x35, 0x34, 0x27, 0x04, 0x96, 0x1a, 0xa6, - 0x98, 0xfe, 0xe9, 0xdf, 0x9a, 0x9d, 0x29, 0xb8, 0x2b, 0x75, 0x62, 0x84, - 0xbc, 0x6a, 0x7b, 0x19, 0x02, 0x1b, 0x47, 0x84, 0x7b, 0x79, 0x6f, 0x01, - 0x01, 0x39, 0x3b, 0xe1, 0x3e, 0x7c, 0x8a, 0x30, 0x6c, 0x1e, 0x19, 0x41, - 0x4c, 0x6a, 0x40, 0x47, 0x00, 0x02, 0x00, 0x1f, 0xfe, 0x7d, 0x04, 0x74, - 0x03, 0xd9, 0x00, 0x0f, 0x00, 0x38, 0x00, 0x00, 0x01, 0x36, 0x35, 0x34, - 0x27, 0x26, 0x07, 0x06, 0x07, 0x06, 0x07, 0x14, 0x17, 0x16, 0x33, 0x32, - 0x01, 0x36, 0x37, 0x36, 0x11, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, - 0x37, 0x36, 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x14, - 0x07, 0x06, 0x07, 0x06, 0x27, 0x26, 0x27, 0x26, 0x35, 0x34, 0x37, 0x33, - 0x06, 0x07, 0x14, 0x17, 0x16, 0x03, 0x81, 0x29, 0x42, 0x1f, 0x2c, 0x34, - 0x28, 0x28, 0x01, 0x37, 0x28, 0x2a, 0x48, 0xfe, 0x5b, 0xd4, 0x62, 0xcb, - 0x3f, 0x7a, 0x85, 0x4b, 0x62, 0x08, 0x17, 0x96, 0x4e, 0x4c, 0x63, 0x39, - 0x67, 0x27, 0x21, 0x2e, 0x39, 0xa5, 0xbb, 0xe9, 0xce, 0x8a, 0x4d, 0x52, - 0xb7, 0x56, 0x02, 0x12, 0x56, 0x02, 0x19, 0x2b, 0x4d, 0x3b, 0x33, 0x19, - 0x01, 0x01, 0x2a, 0x29, 0x33, 0x50, 0x26, 0x19, 0xfd, 0x3b, 0x02, 0x66, - 0xd4, 0x01, 0x34, 0x4b, 0x43, 0x57, 0x81, 0x2d, 0x33, 0x94, 0x45, 0x24, - 0x32, 0x5a, 0x77, 0x66, 0xa0, 0xfc, 0x8e, 0xb3, 0x83, 0x94, 0x01, 0x01, - 0xbf, 0x6a, 0x7d, 0xb4, 0xd8, 0xbb, 0x99, 0x48, 0x28, 0xb0, 0x00, 0x00, - 0xff, 0xff, 0x00, 0x45, 0xfe, 0x0c, 0x04, 0xb0, 0x03, 0x20, 0x10, 0x27, - 0x0c, 0xde, 0x01, 0x98, 0xfe, 0x0c, 0x10, 0x26, 0x0c, 0xe0, 0x00, 0x00, - 0x10, 0x07, 0x0c, 0xd2, 0x01, 0xb8, 0x02, 0x8a, 0xff, 0xff, 0x00, 0x45, - 0xff, 0xec, 0x04, 0xb0, 0x03, 0xb6, 0x10, 0x27, 0x0c, 0xd9, 0x01, 0xa9, - 0x03, 0x20, 0x10, 0x06, 0x0c, 0xe0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x58, - 0xfe, 0x0c, 0x04, 0xad, 0x05, 0xaf, 0x10, 0x27, 0x04, 0x7f, 0xff, 0xae, - 0xff, 0x38, 0x10, 0x06, 0x04, 0x5d, 0x00, 0x00, 0xff, 0xff, 0x00, 0x58, - 0xfe, 0x0c, 0x04, 0xad, 0x05, 0xaa, 0x10, 0x27, 0x0c, 0xda, 0x01, 0xc2, - 0x05, 0x14, 0x10, 0x06, 0x04, 0x5d, 0x00, 0x00, 0xff, 0xff, 0x00, 0x58, - 0xfe, 0x0c, 0x04, 0xad, 0x05, 0xaa, 0x10, 0x27, 0x0c, 0xd3, 0x01, 0x54, - 0x04, 0x1a, 0x10, 0x06, 0x04, 0x5d, 0x00, 0x00, 0xff, 0xff, 0xff, 0xcc, - 0xfe, 0x08, 0x04, 0xb5, 0x04, 0x06, 0x10, 0x26, 0x04, 0x61, 0x00, 0x00, - 0x10, 0x07, 0x04, 0x81, 0x01, 0x3e, 0xfd, 0xd2, 0x00, 0x02, 0xff, 0xb6, - 0xff, 0xa4, 0x04, 0x8c, 0x03, 0x78, 0x00, 0x0e, 0x00, 0x39, 0x00, 0x00, - 0x01, 0x36, 0x35, 0x34, 0x27, 0x26, 0x07, 0x22, 0x06, 0x07, 0x14, 0x17, - 0x16, 0x33, 0x32, 0x13, 0x06, 0x07, 0x06, 0x23, 0x22, 0x27, 0x26, 0x03, - 0x26, 0x37, 0x33, 0x06, 0x15, 0x14, 0x17, 0x16, 0x33, 0x32, 0x37, 0x36, - 0x37, 0x36, 0x37, 0x06, 0x23, 0x22, 0x27, 0x26, 0x35, 0x34, 0x37, 0x36, - 0x37, 0x36, 0x33, 0x32, 0x17, 0x16, 0x17, 0x16, 0x15, 0x10, 0x03, 0xa3, - 0x29, 0x42, 0x1f, 0x2c, 0x34, 0x50, 0x01, 0x37, 0x26, 0x2c, 0x48, 0x9d, - 0x69, 0xa7, 0xb2, 0xa5, 0xa3, 0x72, 0xf4, 0x02, 0x02, 0x24, 0xb8, 0x24, - 0x78, 0x5a, 0x83, 0x7f, 0x54, 0xbc, 0x30, 0x41, 0x26, 0x3f, 0x7a, 0x85, - 0x4b, 0x62, 0x08, 0x17, 0x96, 0x4e, 0x4c, 0x5a, 0x42, 0x60, 0x2e, 0x17, - 0x01, 0xb8, 0x2c, 0x4c, 0x39, 0x35, 0x1a, 0x02, 0x54, 0x32, 0x52, 0x24, - 0x1a, 0xfe, 0xa6, 0x54, 0x26, 0x28, 0x29, 0x58, 0x01, 0x15, 0x8a, 0x5c, - 0x5e, 0x88, 0x93, 0x2d, 0x22, 0x16, 0x32, 0x1c, 0x28, 0x68, 0x4c, 0x44, - 0x56, 0x82, 0x2c, 0x34, 0x94, 0x44, 0x24, 0x32, 0x48, 0x66, 0x33, 0x8b, - 0xfe, 0xbb, 0x00, 0x00, 0xff, 0xff, 0x00, 0x43, 0xfe, 0xc8, 0x04, 0xfa, - 0x07, 0xc4, 0x10, 0x27, 0x04, 0x81, 0x01, 0x84, 0x01, 0x90, 0x10, 0x06, - 0x04, 0x6f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x36, 0xfe, 0xb5, 0x04, 0x8d, - 0x02, 0xb0, 0x00, 0x1d, 0x00, 0x00, 0x01, 0x14, 0x07, 0x06, 0x07, 0x06, - 0x23, 0x22, 0x27, 0x26, 0x11, 0x34, 0x37, 0x33, 0x06, 0x15, 0x14, 0x17, - 0x16, 0x33, 0x32, 0x37, 0x36, 0x37, 0x36, 0x35, 0x34, 0x27, 0x33, 0x16, - 0x04, 0x8d, 0x64, 0x47, 0x8e, 0x8c, 0x81, 0xac, 0x7b, 0xea, 0x35, 0xb8, - 0x37, 0xa1, 0x39, 0x81, 0x54, 0x3f, 0x9d, 0x3a, 0x22, 0x46, 0xb8, 0x48, - 0x00, 0xff, 0xbb, 0xa4, 0x74, 0x3c, 0x3b, 0x3f, 0x78, 0x01, 0x12, 0xae, - 0x8e, 0xae, 0x8e, 0xb4, 0x43, 0x18, 0x14, 0x33, 0xa7, 0x62, 0x60, 0xf9, - 0x98, 0x9f, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4c, 0xfe, 0x0c, 0x04, 0x33, - 0x04, 0x48, 0x10, 0x27, 0x04, 0x81, 0x00, 0x70, 0xfe, 0x14, 0x10, 0x06, - 0x04, 0x73, 0x00, 0x00, 0xff, 0xff, 0x00, 0x19, 0xfe, 0xf3, 0x04, 0xd1, - 0x04, 0x14, 0x10, 0x27, 0x04, 0x81, 0xff, 0x28, 0xfd, 0xe0, 0x10, 0x06, - 0x04, 0x74, 0x00, 0x00, 0xff, 0xff, 0x00, 0xde, 0xff, 0xc6, 0x03, 0xf3, - 0x02, 0xde, 0x10, 0x06, 0x04, 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x02, 0x57, 0x0a, 0x12, 0xce, 0x75, 0xda, 0x5f, 0x0f, 0x3c, 0xf5, - 0x00, 0x1f, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0x3f, 0xd7, 0xaf, - 0x00, 0x00, 0x00, 0x00, 0xce, 0x3f, 0xd7, 0xaf, 0xfb, 0x8a, 0xfd, 0x01, - 0x05, 0xbe, 0x08, 0x55, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07, 0x6d, 0xfe, 0x1d, - 0x00, 0x00, 0x04, 0xd1, 0xfb, 0x8a, 0xff, 0x14, 0x05, 0xbe, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x04, 0x04, 0xd1, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, - 0x04, 0xd1, 0x00, 0x00, 0x04, 0xd1, 0x00, 0x00, 0x02, 0x04, 0x01, 0x52, - 0x00, 0x02, 0x00, 0xbe, 0x00, 0x21, 0x00, 0x39, 0x02, 0x10, 0x01, 0xaa, - 0x01, 0x5c, 0x00, 0xa6, 0x00, 0x58, 0x01, 0x93, 0x01, 0x64, 0x01, 0xe9, - 0x00, 0x66, 0x00, 0x85, 0x00, 0xf6, 0x00, 0x98, 0x00, 0x89, 0x00, 0x66, - 0x00, 0x8f, 0x00, 0x85, 0x00, 0x8b, 0x00, 0x83, 0x00, 0x7f, 0x01, 0xe9, - 0x01, 0x93, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0xf4, 0x00, 0x1b, - 0x00, 0x25, 0x00, 0xa6, 0x00, 0x8b, 0x00, 0x89, 0x00, 0xc5, 0x00, 0xe9, - 0x00, 0x66, 0x00, 0x89, 0x00, 0xc9, 0x00, 0x6d, 0x00, 0x89, 0x00, 0xd7, - 0x00, 0x56, 0x00, 0x8b, 0x00, 0x75, 0x00, 0xc5, 0x00, 0x75, 0x00, 0x8f, - 0x00, 0x8b, 0x00, 0x2f, 0x00, 0x93, 0x00, 0x39, 0x00, 0x00, 0x00, 0x12, - 0x00, 0x25, 0x00, 0x9c, 0x01, 0xcf, 0x00, 0x66, 0x01, 0x5a, 0x00, 0x48, - 0x00, 0x00, 0x01, 0x17, 0x00, 0x85, 0x00, 0xc1, 0x00, 0xc3, 0x00, 0x7b, - 0x00, 0x7b, 0x00, 0xc3, 0x00, 0x7b, 0x00, 0xc3, 0x00, 0xb2, 0x00, 0xba, - 0x00, 0xec, 0x00, 0xa0, 0x00, 0x6d, 0x00, 0xc3, 0x00, 0x89, 0x00, 0xbe, - 0x00, 0x89, 0x01, 0x6a, 0x00, 0xd5, 0x00, 0x83, 0x00, 0xc3, 0x00, 0x64, - 0x00, 0x00, 0x00, 0x4c, 0x00, 0x68, 0x00, 0xcb, 0x00, 0xdd, 0x02, 0x12, - 0x00, 0xdd, 0x00, 0x58, 0x00, 0x00, 0x02, 0x04, 0x00, 0xd5, 0x00, 0x8b, - 0x00, 0xcd, 0x00, 0x25, 0x02, 0x12, 0x00, 0xc7, 0x01, 0x3f, 0x00, 0x00, - 0x01, 0x0e, 0x00, 0x77, 0x00, 0x58, 0x01, 0x64, 0x00, 0x00, 0x01, 0x3d, - 0x01, 0x2b, 0x00, 0x58, 0x01, 0x42, 0x01, 0x46, 0x01, 0xdb, 0x00, 0xc3, - 0x00, 0x6a, 0x01, 0xe9, 0x01, 0x8b, 0x01, 0x58, 0x00, 0xf4, 0x00, 0xc1, - 0x00, 0x1b, 0x00, 0x1b, 0x00, 0x1b, 0x00, 0xc1, 0x00, 0x25, 0x00, 0x25, - 0x00, 0x25, 0x00, 0x25, 0x00, 0x25, 0x00, 0x25, 0x00, 0x00, 0x00, 0x8b, - 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xc5, 0x00, 0xc9, 0x00, 0xc9, - 0x00, 0xc9, 0x00, 0xc9, 0x00, 0x08, 0x00, 0x8b, 0x00, 0x75, 0x00, 0x75, - 0x00, 0x75, 0x00, 0x75, 0x00, 0x75, 0x00, 0x96, 0x00, 0x08, 0x00, 0x93, - 0x00, 0x93, 0x00, 0x93, 0x00, 0x93, 0x00, 0x25, 0x00, 0xc9, 0x00, 0xbc, - 0x00, 0x85, 0x00, 0x85, 0x00, 0x85, 0x00, 0x85, 0x00, 0x85, 0x00, 0x85, - 0x00, 0x29, 0x00, 0xc3, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x7b, - 0x00, 0xb2, 0x00, 0xb2, 0x00, 0xb2, 0x00, 0xb2, 0x00, 0x89, 0x00, 0xc3, - 0x00, 0x89, 0x00, 0x89, 0x00, 0x89, 0x00, 0x89, 0x00, 0x89, 0x00, 0x58, - 0x00, 0x2f, 0x00, 0xc3, 0x00, 0xc3, 0x00, 0xc3, 0x00, 0xc3, 0x00, 0x68, - 0x00, 0xbe, 0x00, 0x68, 0x00, 0x25, 0x00, 0x85, 0x00, 0x25, 0x00, 0x85, - 0x00, 0x25, 0x00, 0x85, 0x00, 0x8b, 0x00, 0xc3, 0x00, 0x8b, 0x00, 0xc3, - 0x00, 0x8b, 0x00, 0xc3, 0x00, 0x8b, 0x00, 0xc3, 0x00, 0x89, 0x00, 0x7b, - 0x00, 0x08, 0x00, 0x7b, 0x00, 0xc5, 0x00, 0x7b, 0x00, 0xc5, 0x00, 0x7b, - 0x00, 0xc5, 0x00, 0x7b, 0x00, 0xc5, 0x00, 0x7b, 0x00, 0xc5, 0x00, 0x7b, - 0x00, 0x66, 0x00, 0x7b, 0x00, 0x66, 0x00, 0x7b, 0x00, 0x66, 0x00, 0x7b, - 0x00, 0x66, 0x00, 0x7b, 0x00, 0x89, 0x00, 0xc3, 0x00, 0x03, 0x00, 0x46, - 0x00, 0xc9, 0x00, 0xb2, 0x00, 0xc9, 0x00, 0xb2, 0x00, 0xc9, 0x00, 0xb2, - 0x00, 0xc9, 0x00, 0xb2, 0x00, 0xc9, 0x00, 0xb2, 0xff, 0xff, 0xff, 0xfc, - 0x00, 0x6d, 0x00, 0xba, 0x00, 0x89, 0x00, 0xec, 0x00, 0xec, 0x00, 0xc8, - 0x00, 0xa0, 0x00, 0xd7, 0x00, 0xa0, 0x00, 0xd7, 0x00, 0xa0, 0x00, 0xd7, - 0x00, 0xa0, 0xff, 0xf6, 0x00, 0x4c, 0x00, 0x8b, 0x00, 0xc3, 0x00, 0x8b, - 0x00, 0xc3, 0x00, 0x8b, 0x00, 0xc3, 0x00, 0x18, 0x00, 0x93, 0x00, 0xc3, - 0x00, 0x75, 0x00, 0x89, 0x00, 0x75, 0x00, 0x89, 0x00, 0x75, 0x00, 0x89, - 0x00, 0x48, 0x00, 0x0e, 0x00, 0x8f, 0x01, 0x6a, 0x00, 0x8f, 0x01, 0x20, - 0x00, 0x8f, 0x01, 0x6a, 0x00, 0x8b, 0x00, 0xd5, 0x00, 0x8b, 0x00, 0xd5, - 0x00, 0x8b, 0x00, 0xd5, 0x00, 0x8b, 0x00, 0xd5, 0x00, 0x2f, 0x00, 0x83, - 0x00, 0x2f, 0x00, 0x83, 0x00, 0x2f, 0x00, 0x83, 0x00, 0x93, 0x00, 0xc3, - 0x00, 0x93, 0x00, 0xc3, 0x00, 0x93, 0x00, 0xc3, 0x00, 0x93, 0x00, 0xc3, - 0x00, 0x93, 0x00, 0xc3, 0x00, 0x93, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x25, 0x00, 0x68, 0x00, 0x25, 0x00, 0x9c, 0x00, 0xcb, 0x00, 0x9c, - 0x00, 0xcb, 0x00, 0x9c, 0x00, 0xcb, 0x00, 0xc3, 0x00, 0x46, 0x00, 0x14, - 0x00, 0xa6, 0x00, 0xc1, 0x00, 0x30, 0x00, 0x3c, 0x00, 0x8b, 0x00, 0x3c, - 0x00, 0x5e, 0x00, 0x08, 0x00, 0x08, 0x00, 0x83, 0x00, 0x9d, 0x00, 0x88, - 0x00, 0xc5, 0x00, 0x75, 0x00, 0x89, 0x00, 0x3f, 0x00, 0xc3, 0x00, 0x34, - 0x00, 0x1c, 0x00, 0x41, 0x00, 0xc9, 0x00, 0xc9, 0x00, 0x6e, 0x00, 0xec, - 0x00, 0xa0, 0x00, 0x31, 0x00, 0x6d, 0x00, 0x1d, 0x00, 0xc3, 0x00, 0x75, - 0x00, 0x06, 0x00, 0x20, 0x00, 0x2d, 0x00, 0x56, 0x00, 0x38, 0x00, 0xbe, - 0x00, 0x8f, 0x00, 0x8b, 0x00, 0xd5, 0x00, 0x78, 0x00, 0x76, 0x00, 0x83, - 0x00, 0x2f, 0x00, 0x83, 0x00, 0x2f, 0x00, 0x09, 0x00, 0x27, 0x00, 0x4a, - 0x00, 0x9a, 0x00, 0x11, 0x00, 0x18, 0x00, 0x9c, 0x00, 0x9c, 0x00, 0x1a, - 0x00, 0x1a, 0x00, 0x7d, 0x00, 0xad, 0x00, 0x98, 0x00, 0x1a, 0x00, 0x7d, - 0x00, 0xc2, 0x00, 0x7d, 0x02, 0x03, 0x01, 0x39, 0x00, 0xa4, 0x02, 0x03, - 0x00, 0x25, 0x00, 0x85, 0x00, 0xc9, 0x00, 0xb2, 0x00, 0x75, 0x00, 0x89, - 0x00, 0x93, 0x00, 0xc3, 0x00, 0x93, 0x00, 0xc3, 0x00, 0x93, 0x00, 0xc3, - 0x00, 0x93, 0x00, 0xc3, 0x00, 0x93, 0x00, 0xc3, 0x00, 0x7a, 0x00, 0x25, - 0x00, 0x85, 0x00, 0x25, 0x00, 0x85, 0x00, 0x00, 0x00, 0x29, 0x00, 0x66, - 0x00, 0x7b, 0x00, 0x89, 0x00, 0xec, 0x00, 0x75, 0x00, 0x89, 0x00, 0x75, - 0x00, 0x89, 0x00, 0x1a, 0x00, 0x7d, 0x00, 0xba, 0x00, 0x66, 0x00, 0x7b, - 0x00, 0x3d, 0x00, 0x8b, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x29, 0x00, 0x08, - 0x00, 0x2f, 0x00, 0x25, 0x00, 0x85, 0x00, 0x25, 0x00, 0x85, 0x00, 0xbb, - 0x00, 0x7b, 0x00, 0xc5, 0x00, 0x7b, 0x00, 0xbb, 0x00, 0xb2, 0x00, 0xc9, - 0x00, 0xb2, 0x00, 0x75, 0x00, 0x89, 0x00, 0x75, 0x00, 0x89, 0x00, 0x89, - 0x01, 0x68, 0x00, 0x8f, 0x01, 0x6a, 0x00, 0x93, 0x00, 0xc3, 0x00, 0x93, - 0x00, 0xc3, 0x00, 0x8b, 0x00, 0xd5, 0x00, 0x2f, 0x00, 0x83, 0x00, 0x7d, - 0x00, 0xae, 0x00, 0x89, 0x00, 0xc3, 0x00, 0x93, 0x00, 0x12, 0x00, 0x9c, - 0x00, 0xcb, 0x00, 0x25, 0x00, 0x85, 0x00, 0xc5, 0x00, 0x7b, 0x00, 0x75, - 0x00, 0x89, 0x00, 0x75, 0x00, 0x89, 0x00, 0x75, 0x00, 0x89, 0x00, 0x75, - 0x00, 0x89, 0x00, 0x25, 0x00, 0x68, 0x00, 0xa0, 0x00, 0x6a, 0x00, 0x83, - 0x00, 0xba, 0x00, 0x78, 0x00, 0x78, 0x00, 0x08, 0x00, 0x08, 0x00, 0x2f, - 0x00, 0x15, 0x00, 0x21, 0x00, 0xd5, 0x00, 0xcb, 0x00, 0x37, 0x00, 0x08, - 0x00, 0x15, 0x00, 0x39, 0x00, 0x15, 0x00, 0x8e, 0x00, 0x9a, 0x00, 0x7b, - 0x00, 0xc0, 0x00, 0xc1, 0x00, 0xb8, 0x00, 0xc3, 0x00, 0x7b, 0x00, 0x7b, - 0x00, 0x7a, 0x00, 0x7a, 0x00, 0x1e, 0x00, 0xa9, 0x00, 0xa9, 0x00, 0x38, - 0x00, 0xb0, 0x00, 0xba, 0x00, 0x7b, 0x00, 0x9d, 0x00, 0x7a, 0x00, 0x66, - 0x00, 0x66, 0x00, 0xbc, 0x00, 0xc3, 0x00, 0xc3, 0x00, 0x8e, 0x00, 0xc6, - 0x00, 0xa0, 0x00, 0x58, 0x00, 0x9d, 0x00, 0xa0, 0x00, 0x28, 0x00, 0x68, - 0x00, 0x68, 0x00, 0x67, 0x00, 0xb2, 0x00, 0x88, 0x00, 0x90, 0x00, 0x89, - 0x00, 0x45, 0x00, 0xaa, 0x00, 0x89, 0x00, 0x98, 0x00, 0x98, 0x00, 0x66, - 0x01, 0x6a, 0x01, 0x6a, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0x7a, 0x00, 0x7a, - 0x00, 0xbc, 0x00, 0x7d, 0x00, 0x7d, 0x00, 0x7d, 0x00, 0x76, 0x00, 0xa6, - 0x00, 0x83, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x41, 0x00, 0x48, 0x00, 0x0f, - 0x00, 0x48, 0x00, 0x66, 0x00, 0xc2, 0x00, 0xa7, 0x00, 0x7d, 0x00, 0x69, - 0x00, 0xc2, 0x00, 0xc2, 0x00, 0xc2, 0x00, 0xc2, 0x00, 0x5f, 0x00, 0xd1, - 0x00, 0xb0, 0x00, 0x36, 0x00, 0x90, 0x00, 0xca, 0x00, 0x77, 0x00, 0xf5, - 0x00, 0x23, 0x00, 0xc2, 0x00, 0xc2, 0x00, 0x1d, 0x00, 0x1b, 0x00, 0x36, - 0x00, 0x99, 0x00, 0x99, 0x00, 0xb5, 0x00, 0x87, 0x00, 0xe6, 0x00, 0xdb, - 0x00, 0x8f, 0x00, 0x8f, 0x00, 0xb2, 0x00, 0xc5, 0x01, 0x41, 0x01, 0x41, - 0x01, 0xe6, 0x01, 0x99, 0x01, 0x99, 0x01, 0x51, 0x01, 0x30, 0x00, 0x8f, - 0x01, 0x11, 0x01, 0xec, 0x01, 0xcf, 0x01, 0xcf, 0x01, 0xf0, 0x01, 0xdf, - 0x01, 0xdf, 0x01, 0x5e, 0x01, 0x5e, 0x01, 0x29, 0x01, 0x29, 0x02, 0x24, - 0x01, 0x3d, 0x02, 0x24, 0x01, 0x3d, 0x01, 0x79, 0x01, 0x79, 0x01, 0xb6, - 0x01, 0xb6, 0x01, 0xdf, 0x01, 0xdf, 0x01, 0x3e, 0x01, 0x88, 0x01, 0x2f, - 0x02, 0x01, 0x01, 0x56, 0x01, 0xa4, 0x01, 0x1f, 0x01, 0x58, 0xfe, 0xa1, - 0x01, 0x25, 0x01, 0x56, 0x01, 0x5b, 0x01, 0x12, 0x01, 0x5e, 0x01, 0x2c, - 0x01, 0x2c, 0x01, 0x2c, 0x01, 0x2c, 0x01, 0x2c, 0x00, 0xd3, 0x01, 0x8d, - 0x01, 0x17, 0x01, 0xdb, 0x01, 0x29, 0x01, 0x1f, 0x01, 0x3d, 0x00, 0x00, - 0x01, 0x2f, 0x02, 0x01, 0x01, 0x3f, 0x01, 0x99, 0x01, 0x56, 0x01, 0x58, - 0x01, 0x29, 0x02, 0x22, 0x01, 0x56, 0x00, 0xd2, 0x01, 0x2f, 0x01, 0x2f, - 0x01, 0xd5, 0x01, 0xef, 0x01, 0xf0, 0x01, 0xdb, 0x01, 0x79, 0x01, 0x79, - 0x01, 0x9c, 0x01, 0xcc, 0x01, 0x73, 0x01, 0xa3, 0x01, 0xfa, 0x01, 0x62, - 0x01, 0x5e, 0x01, 0x5f, 0x01, 0x73, 0x01, 0xf6, 0x00, 0xb6, 0x02, 0x01, - 0x01, 0x3f, 0x01, 0x8d, 0x01, 0x98, 0x01, 0x8b, 0x01, 0xae, 0x02, 0x24, - 0x01, 0x55, 0x00, 0xce, 0x01, 0x29, 0x01, 0x29, 0x01, 0x2f, 0x01, 0x2f, - 0x01, 0x1f, 0x01, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x00, 0x8d, - 0x00, 0x00, 0x00, 0x2f, 0x00, 0x08, 0x01, 0xfa, 0x01, 0x55, 0x01, 0x55, - 0x00, 0xce, 0x01, 0x8b, 0x01, 0xdb, 0x00, 0x00, 0x01, 0xef, 0x04, 0x02, - 0xff, 0x14, 0x01, 0xec, 0x01, 0xe6, 0x02, 0x1e, 0x01, 0x93, 0x01, 0xdb, - 0x01, 0x3f, 0x00, 0x19, 0x01, 0xe9, 0xff, 0x1f, 0xfe, 0xed, 0xff, 0x1f, - 0xff, 0xb5, 0xfe, 0x70, 0xff, 0xce, 0x01, 0x36, 0x00, 0x25, 0x00, 0xa6, - 0x00, 0xd7, 0x00, 0x25, 0x00, 0xc5, 0x00, 0x9c, 0x00, 0x89, 0x00, 0x75, - 0x00, 0xc9, 0x00, 0x89, 0x00, 0x25, 0x00, 0x56, 0x00, 0x8b, 0x00, 0x89, - 0x00, 0x75, 0x00, 0x89, 0x00, 0xc5, 0x00, 0x78, 0x00, 0x2f, 0x00, 0x25, - 0x00, 0x75, 0x00, 0x12, 0x00, 0x75, 0x00, 0x4a, 0x00, 0xc9, 0x00, 0x25, - 0x00, 0x46, 0x00, 0xa9, 0x00, 0xc3, 0x01, 0x36, 0x00, 0x33, 0x00, 0x46, - 0x00, 0x97, 0x00, 0x20, 0x00, 0x89, 0x00, 0xa9, 0x00, 0x99, 0x00, 0xc3, - 0x00, 0x89, 0x01, 0x36, 0x00, 0xec, 0x00, 0x44, 0x00, 0xc3, 0x00, 0x74, - 0x00, 0xa2, 0x00, 0x89, 0x00, 0x50, 0x00, 0xbe, 0x00, 0xc3, 0x00, 0x89, - 0x00, 0x9f, 0x00, 0x33, 0x00, 0x4c, 0x00, 0x59, 0x00, 0x83, 0x00, 0x46, - 0x01, 0x36, 0x00, 0x33, 0x00, 0x89, 0x00, 0x33, 0x00, 0x46, 0x00, 0x96, - 0x00, 0x74, 0x00, 0x22, 0xfe, 0x70, 0x00, 0x22, 0x00, 0x6d, 0x00, 0x39, - 0x00, 0x34, 0x00, 0x75, 0x00, 0x89, 0x00, 0x8b, 0x00, 0x9b, 0x00, 0xe9, - 0x00, 0x00, 0x00, 0x60, 0x00, 0x84, 0x00, 0x21, 0x00, 0x59, 0x00, 0x34, - 0x00, 0xbe, 0x00, 0xc3, 0x00, 0xba, 0x00, 0x75, 0x00, 0xa2, 0x00, 0xa2, - 0x00, 0xc9, 0x00, 0xbe, 0x00, 0x8b, 0x00, 0x56, 0x00, 0x7f, 0x00, 0x55, - 0x00, 0x8b, 0x00, 0x8b, 0x00, 0x8b, 0x00, 0xc5, 0x00, 0xc5, 0xff, 0xbe, - 0x00, 0xd7, 0x00, 0x8b, 0x00, 0x8b, 0x00, 0xc9, 0x00, 0xc9, 0x00, 0x6d, - 0xff, 0xed, 0x00, 0x22, 0xff, 0xbe, 0x00, 0x89, 0x00, 0x8b, 0x00, 0x68, - 0x00, 0x89, 0x00, 0x25, 0x00, 0xa6, 0x00, 0xa6, 0x00, 0xd7, 0x00, 0x21, - 0x00, 0xc5, 0x00, 0x0f, 0x00, 0x89, 0x00, 0x8b, 0x00, 0x8b, 0x00, 0x89, - 0x00, 0x04, 0x00, 0x56, 0x00, 0x89, 0x00, 0x75, 0x00, 0x89, 0x00, 0xc5, - 0x00, 0x8b, 0x00, 0x2f, 0x00, 0x68, 0x00, 0x42, 0x00, 0x12, 0x00, 0x50, - 0x00, 0x89, 0x00, 0x72, 0x00, 0x3c, 0x00, 0x20, 0x00, 0x41, 0x00, 0xc5, - 0x00, 0x8b, 0x00, 0x3c, 0x00, 0x4c, 0x00, 0x85, 0x00, 0x7d, 0x00, 0xd1, - 0x01, 0x01, 0x00, 0x69, 0x00, 0x7b, 0x00, 0x3b, 0x00, 0xa9, 0x00, 0xc3, - 0x00, 0xc3, 0x00, 0xec, 0x00, 0x1e, 0x00, 0x3d, 0x00, 0xc3, 0x00, 0x89, - 0x00, 0xc3, 0x00, 0xbe, 0x00, 0xc3, 0x00, 0xe1, 0x00, 0x68, 0x00, 0x63, - 0x00, 0x4c, 0x00, 0x7c, 0x00, 0xc3, 0x00, 0x7d, 0x00, 0x50, 0x00, 0x1e, - 0x00, 0x68, 0x00, 0xc3, 0x00, 0xc3, 0x00, 0x4e, 0x00, 0xa8, 0x00, 0x7b, - 0x00, 0x7b, 0x00, 0x23, 0x01, 0x01, 0x00, 0xc3, 0x00, 0xd5, 0x00, 0xb2, - 0x00, 0xb2, 0x00, 0xba, 0x00, 0x0a, 0x00, 0x41, 0x00, 0x23, 0x00, 0xec, - 0x00, 0xc3, 0x00, 0x68, 0x00, 0xc3, 0x00, 0x20, 0x00, 0x1e, 0x00, 0x75, - 0x00, 0x89, 0x00, 0xd7, 0x01, 0x01, 0x00, 0x55, 0x00, 0x7f, 0x00, 0xd7, - 0x01, 0x01, 0x00, 0x0f, 0x00, 0x3b, 0x00, 0x89, 0x00, 0xa9, 0x00, 0x89, - 0x00, 0xec, 0x00, 0x1f, 0x00, 0x62, 0x00, 0x71, 0x00, 0x7d, 0x00, 0x8b, - 0x00, 0xc3, 0x00, 0x2f, 0x00, 0xe1, 0x00, 0x25, 0x00, 0x5c, 0x00, 0x25, - 0x00, 0x5c, 0x00, 0x12, 0x00, 0x4c, 0x00, 0x8c, 0x00, 0xc3, 0x00, 0xc9, - 0x00, 0x0f, 0x00, 0x3b, 0x00, 0x89, 0x00, 0xec, 0x00, 0x89, 0x00, 0xc3, - 0x00, 0x8c, 0x00, 0xc3, 0x01, 0xc7, 0x00, 0x25, 0x00, 0x85, 0x00, 0x25, - 0x00, 0x85, 0x00, 0x00, 0x00, 0x29, 0x00, 0xc5, 0x00, 0x7b, 0x00, 0x75, - 0x00, 0x7a, 0x00, 0x75, 0x00, 0x7a, 0x00, 0x0f, 0x00, 0x3b, 0x00, 0x89, - 0x00, 0xa9, 0x00, 0x1a, 0x00, 0x7d, 0x00, 0x8b, 0x00, 0xc3, 0x00, 0x8b, - 0x00, 0xc3, 0x00, 0x75, 0x00, 0x89, 0x00, 0x75, 0x00, 0x89, 0x00, 0x75, - 0x00, 0x89, 0x00, 0x8b, 0x00, 0xc3, 0x00, 0x68, 0x00, 0x68, 0x00, 0x68, - 0x00, 0x68, 0x00, 0x68, 0x00, 0x68, 0x00, 0x89, 0x00, 0xc3, 0x00, 0xd7, - 0x01, 0x01, 0x00, 0x41, 0x00, 0x68, 0x00, 0x89, 0x00, 0xa9, 0x00, 0x75, - 0x00, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x80, 0x00, 0x55, - 0x00, 0x36, 0x00, 0x80, 0x00, 0x60, 0x00, 0x78, 0x00, 0x80, 0x00, 0x2b, - 0x00, 0x55, 0x00, 0x93, 0x00, 0x9a, 0x00, 0x5d, 0x00, 0x36, 0x00, 0x93, - 0x00, 0x5b, 0x00, 0x5f, 0x00, 0x36, 0x00, 0x56, 0x00, 0x36, 0x00, 0x40, - 0x00, 0x36, 0x00, 0x60, 0x00, 0x93, 0x00, 0x60, 0x00, 0x41, 0x00, 0x60, - 0x00, 0x36, 0x00, 0x93, 0x00, 0x21, 0x00, 0x69, 0x00, 0x93, 0x00, 0x40, - 0x00, 0x87, 0x00, 0x46, 0x00, 0x33, 0x00, 0x75, 0x00, 0x47, 0x01, 0xdf, - 0x01, 0xd6, 0x01, 0x7a, 0x00, 0xe1, 0x01, 0x79, 0x00, 0xb2, 0x00, 0xbc, - 0x00, 0x67, 0x00, 0xb7, 0x00, 0x49, 0x00, 0x72, 0x00, 0xa4, 0x00, 0x49, - 0x00, 0xcf, 0x00, 0xb7, 0x00, 0x42, 0x00, 0x49, 0x00, 0xbc, 0x01, 0x47, - 0x00, 0x68, 0x00, 0x89, 0x00, 0xbc, 0x00, 0xbd, 0x00, 0xab, 0x00, 0x72, - 0x00, 0x9f, 0x00, 0x68, 0x01, 0x3d, 0x00, 0x68, 0x00, 0xad, 0x00, 0xbd, - 0x00, 0xf2, 0x00, 0x67, 0x00, 0xa8, 0x00, 0x84, 0x00, 0xbd, 0x00, 0x66, - 0x00, 0x68, 0x00, 0xbc, 0x00, 0x9d, 0x00, 0xf9, 0x00, 0x68, 0x00, 0x57, - 0x00, 0x89, 0x00, 0x28, 0x00, 0x48, 0x01, 0xff, 0x01, 0x64, 0x00, 0x31, - 0x00, 0x31, 0x00, 0x5a, 0x00, 0x00, 0x01, 0xd6, 0x01, 0x64, 0x01, 0xd6, - 0x00, 0xda, 0x01, 0xb2, 0x01, 0x00, 0x01, 0xbd, 0x00, 0x4c, 0x01, 0xbd, - 0x00, 0x19, 0x02, 0x0c, 0x00, 0x45, 0x00, 0xde, 0x00, 0x45, 0x00, 0x45, - 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0xe8, 0x00, 0xe8, 0xff, 0xcc, - 0xff, 0xcc, 0xff, 0x24, 0xff, 0x24, 0xff, 0x10, 0xff, 0x10, 0x00, 0x0a, - 0x00, 0x0a, 0x00, 0x7a, 0x00, 0x7a, 0xff, 0xec, 0xff, 0xb6, 0x00, 0x1f, - 0x00, 0x08, 0x00, 0x43, 0x00, 0x82, 0x00, 0x36, 0x00, 0xde, 0x00, 0x4c, - 0x00, 0x19, 0x00, 0x19, 0x01, 0x44, 0x01, 0x44, 0x01, 0x44, 0x01, 0x44, - 0x01, 0x44, 0x01, 0x44, 0x01, 0x30, 0x01, 0x56, 0x01, 0x00, 0x01, 0xbd, - 0x01, 0xbd, 0x01, 0x5c, 0x01, 0xfa, 0x01, 0x96, 0x00, 0x9a, 0x00, 0x86, - 0x00, 0xec, 0x00, 0xca, 0x00, 0x9a, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0xa2, - 0x00, 0xc8, 0x01, 0x36, 0x01, 0xd6, 0x00, 0x92, 0x01, 0xbd, 0x00, 0x45, - 0x00, 0x45, 0x00, 0x45, 0x00, 0x45, 0x00, 0x45, 0x00, 0x45, 0x00, 0x58, - 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0xff, 0xcc, 0xff, 0xcc, 0xff, 0xb6, - 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x19, 0x01, 0xfa, 0x01, 0x96, - 0x00, 0x9a, 0x00, 0x86, 0x00, 0xaf, 0x00, 0xac, 0x01, 0x08, 0x00, 0x7e, - 0x00, 0x7e, 0x00, 0xa2, 0x00, 0x3e, 0x00, 0x6c, 0x00, 0x79, 0x00, 0xf6, - 0x00, 0x7c, 0x00, 0x61, 0x00, 0x73, 0x00, 0x7b, 0x00, 0x95, 0x00, 0x1a, - 0x00, 0x6a, 0x00, 0x4b, 0x00, 0x7d, 0x00, 0x7d, 0x00, 0x63, 0x00, 0x63, - 0x00, 0x65, 0x00, 0x65, 0x00, 0x10, 0x00, 0x73, 0x00, 0x64, 0x00, 0x61, - 0x00, 0x6f, 0x00, 0x62, 0x00, 0x14, 0x00, 0x77, 0x00, 0x55, 0x00, 0x30, - 0x00, 0x5b, 0xfb, 0x8a, 0x00, 0x9d, 0xfc, 0xc6, 0x00, 0x53, 0x00, 0x53, - 0x00, 0x53, 0x00, 0x53, 0x01, 0xcf, 0x01, 0x78, 0x00, 0x45, 0xff, 0xf0, - 0x02, 0x0e, 0x00, 0x56, 0x00, 0x5f, 0x01, 0x49, 0xff, 0xf0, 0x01, 0x96, - 0x00, 0xa0, 0x00, 0x9e, 0x00, 0x6e, 0x00, 0x37, 0x00, 0xa0, 0x00, 0x9e, - 0x00, 0x9e, 0x00, 0x37, 0x00, 0xa0, 0x00, 0x9e, 0x00, 0xa0, 0x00, 0x9e, - 0x00, 0x9f, 0x00, 0x37, 0x00, 0xa0, 0x00, 0x9f, 0x00, 0x37, 0x00, 0x9f, - 0x00, 0x2d, 0x00, 0x37, 0x00, 0x37, 0x00, 0xa0, 0x00, 0x37, 0x00, 0x9e, - 0x00, 0x37, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e, 0x00, 0xa1, 0x00, 0xa0, - 0x00, 0x9f, 0x00, 0x9f, 0x00, 0x9e, 0x00, 0x76, 0x00, 0xa0, 0x00, 0x9f, - 0x00, 0x9f, 0x00, 0x8b, 0x00, 0x37, 0x00, 0x6b, 0x00, 0xa1, 0x00, 0x6e, - 0x00, 0xa0, 0x01, 0x23, 0x01, 0x95, 0x00, 0x29, 0x00, 0xa9, 0x00, 0xb2, - 0x00, 0x0e, 0x00, 0x89, 0x00, 0x88, 0x00, 0x2b, 0x00, 0x3f, 0x00, 0x2b, - 0x00, 0xfc, 0x00, 0xf5, 0x01, 0x37, 0x01, 0x37, 0x01, 0x4c, 0x01, 0x4c, - 0x01, 0x2c, 0x01, 0x3a, 0x01, 0x64, 0x01, 0x5e, 0x01, 0x12, 0x01, 0x45, - 0x01, 0x1b, 0x01, 0x3c, 0x01, 0x3c, 0x01, 0x2e, 0x01, 0x3f, 0x01, 0x11, - 0x01, 0x02, 0x01, 0x41, 0x00, 0xe4, 0x01, 0x45, 0x01, 0x45, 0x01, 0x47, - 0x00, 0xfb, 0x01, 0x47, 0x01, 0x47, 0x01, 0x31, 0x01, 0x31, 0x01, 0x4f, - 0x01, 0x4f, 0x01, 0x47, 0x01, 0x49, 0x01, 0x38, 0x01, 0x25, 0x01, 0x5b, - 0x01, 0x3a, 0x01, 0x58, 0x01, 0x3a, 0x01, 0x3a, 0x01, 0x47, 0x01, 0x4d, - 0x01, 0x5b, 0x00, 0xff, 0x01, 0x25, 0x01, 0x23, 0x01, 0x48, 0x01, 0x99, - 0x01, 0x5b, 0x01, 0x23, 0x00, 0x7b, 0x01, 0x3a, 0x00, 0x9c, 0x00, 0xa0, - 0x01, 0x47, 0x01, 0x58, 0x01, 0x51, 0x01, 0x3a, 0x01, 0x4f, 0x01, 0x57, - 0x01, 0x62, 0x01, 0x47, 0x01, 0x5b, 0x01, 0x43, 0x01, 0x61, 0x01, 0x49, - 0x01, 0x47, 0x01, 0x64, 0x01, 0x55, 0x01, 0x55, 0x01, 0x7e, 0x01, 0x25, - 0x01, 0x25, 0x01, 0x55, 0x01, 0x55, 0x01, 0x3f, 0x01, 0x3a, 0x01, 0x3a, - 0x01, 0x5b, 0x01, 0x78, 0x01, 0x4d, 0x00, 0xd0, 0x01, 0x20, 0x01, 0x46, - 0x01, 0x11, 0x01, 0x61, 0x01, 0x5e, 0x01, 0x4d, 0x01, 0x33, 0x01, 0x3a, - 0x00, 0x25, 0x00, 0x85, 0x00, 0xa6, 0x00, 0xc1, 0x00, 0xa6, 0x00, 0xc1, - 0x00, 0xa6, 0x00, 0xc1, 0x00, 0x8b, 0x00, 0xc3, 0x00, 0x89, 0x00, 0x7b, - 0x00, 0x89, 0x00, 0x7b, 0x00, 0x89, 0x00, 0x7b, 0x00, 0x7d, 0x00, 0x7b, - 0x00, 0x89, 0x00, 0x7b, 0x00, 0xc5, 0x00, 0x7b, 0x00, 0xc5, 0x00, 0x7b, - 0x00, 0xc5, 0x00, 0x7b, 0x00, 0xe9, 0x00, 0xc3, 0x00, 0x66, 0x00, 0x7b, - 0x00, 0x89, 0x00, 0xc3, 0x00, 0x89, 0x00, 0xc3, 0x00, 0x89, 0x00, 0xc3, - 0x00, 0x14, 0x00, 0x37, 0x00, 0x89, 0x00, 0xc3, 0x00, 0xc9, 0x00, 0xb2, - 0x00, 0x89, 0x00, 0xec, 0x00, 0x89, 0x00, 0xec, 0x00, 0x89, 0x00, 0xec, - 0x00, 0xd7, 0x00, 0xa0, 0x00, 0xd7, 0x00, 0xa0, 0x00, 0xd7, 0x00, 0xa0, - 0x00, 0xd7, 0x00, 0xa0, 0x00, 0x56, 0x00, 0x6d, 0x00, 0x56, 0x00, 0x6d, - 0x00, 0x56, 0x00, 0x6d, 0x00, 0x8b, 0x00, 0xc3, 0x00, 0x8b, 0x00, 0xc3, - 0x00, 0x8b, 0x00, 0xc3, 0x00, 0x8b, 0x00, 0xc3, 0x00, 0x75, 0x00, 0x89, - 0x00, 0xc5, 0x00, 0xbe, 0x00, 0xc5, 0x00, 0xbe, 0x00, 0x8f, 0x01, 0x6a, - 0x00, 0x8f, 0x01, 0x6a, 0x00, 0x8f, 0x01, 0x3d, 0x00, 0x8f, 0x01, 0x3d, - 0x00, 0x8b, 0x00, 0xd5, 0x00, 0x8b, 0x00, 0xd5, 0x00, 0x8b, 0x00, 0xd5, - 0x00, 0x2f, 0x00, 0x83, 0x00, 0x2f, 0x00, 0x83, 0x00, 0x2f, 0x00, 0x83, - 0x00, 0x2f, 0x00, 0x83, 0x00, 0x93, 0x00, 0xc3, 0x00, 0x93, 0x00, 0xc3, - 0x00, 0x93, 0x00, 0xc3, 0x00, 0x93, 0x00, 0xc3, 0x00, 0x39, 0x00, 0x64, - 0x00, 0x39, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x12, 0x00, 0x4c, 0x00, 0x12, 0x00, 0x4c, 0x00, 0x25, 0x00, 0x68, - 0x00, 0x9c, 0x00, 0xcb, 0x00, 0x9c, 0x00, 0xcb, 0x00, 0x9c, 0x00, 0xcb, - 0x00, 0xc3, 0x00, 0x83, 0x00, 0x00, 0x00, 0x68, 0x00, 0xc3, 0x00, 0x89, - 0x00, 0x25, 0x00, 0x85, 0x00, 0x25, 0x00, 0x85, 0x00, 0x25, 0x00, 0x85, - 0x00, 0x25, 0x00, 0x85, 0x00, 0xc5, 0x00, 0x7b, 0x00, 0xc5, 0x00, 0x7b, - 0x00, 0xc5, 0x00, 0x7b, 0x00, 0xc9, 0x00, 0xb2, 0x00, 0x75, 0x00, 0x89, - 0x00, 0x75, 0x00, 0x89, 0x00, 0x06, 0x00, 0x20, 0x00, 0x06, 0x00, 0x20, - 0x00, 0x06, 0x00, 0x20, 0x00, 0x06, 0x00, 0x20, 0x00, 0x93, 0x00, 0xc3, - 0x00, 0x09, 0x00, 0x27, 0x00, 0x09, 0x00, 0x27, 0x00, 0x09, 0x00, 0x27, - 0x00, 0x09, 0x00, 0x27, 0x00, 0x25, 0x00, 0x68, 0x00, 0x25, 0x00, 0x68, - 0x00, 0x25, 0x00, 0x68, 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, - 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, 0x00, 0x25, 0x00, 0x25, - 0xfe, 0x6c, 0xfe, 0x6c, 0xff, 0x1b, 0xff, 0x07, 0xff, 0xc1, 0xff, 0x8f, - 0x00, 0xa9, 0x00, 0xa9, 0x00, 0xa9, 0x00, 0xa9, 0x00, 0xa9, 0x00, 0xa9, - 0xff, 0x7f, 0xff, 0x7f, 0xfd, 0x8b, 0xfd, 0x8b, 0xfe, 0x08, 0xfd, 0xf4, - 0x00, 0xc3, 0x00, 0xc3, 0x00, 0xc3, 0x00, 0xc3, 0x00, 0xc3, 0x00, 0xc3, - 0x00, 0xc3, 0x00, 0xc3, 0xff, 0x4d, 0xff, 0x4d, 0xfd, 0x40, 0xfd, 0x40, - 0xfd, 0xa4, 0xfd, 0x90, 0xfe, 0x63, 0xfe, 0x63, 0x01, 0x36, 0x01, 0x36, - 0x00, 0xf5, 0x00, 0xf5, 0x01, 0x27, 0x01, 0x13, 0x01, 0x1f, 0x01, 0x1f, - 0xff, 0x7f, 0xff, 0x7f, 0xfd, 0xa4, 0xfd, 0xa4, 0xfe, 0x08, 0xfd, 0xf4, - 0xfe, 0xae, 0xfe, 0xae, 0x00, 0x89, 0x00, 0x89, 0x00, 0x89, 0x00, 0x89, - 0x00, 0x89, 0x00, 0x89, 0xff, 0xca, 0xff, 0x7f, 0xfd, 0x8b, 0xfd, 0x8b, - 0xfe, 0x9e, 0xfe, 0x8a, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, - 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0xfe, 0xe9, 0xfd, 0x40, - 0xfd, 0x45, 0xfe, 0x18, 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, - 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, 0xff, 0xca, 0xff, 0x66, - 0xfd, 0x8b, 0xfd, 0x8b, 0xfe, 0xb7, 0xfe, 0xa3, 0xfe, 0xf9, 0xfe, 0xae, - 0x00, 0x46, 0x00, 0x46, 0x00, 0xa9, 0x00, 0xa9, 0x00, 0xc3, 0x00, 0xc3, - 0x01, 0x17, 0x01, 0x36, 0x00, 0x89, 0x00, 0x89, 0x00, 0x33, 0x00, 0x33, - 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, - 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, 0x00, 0x25, 0x00, 0x25, - 0xfe, 0x6c, 0xfe, 0x6c, 0xff, 0x1b, 0xff, 0x07, 0xff, 0xc1, 0xff, 0x8f, - 0x00, 0xc3, 0x00, 0xc3, 0x00, 0xc3, 0x00, 0xc3, 0x00, 0xc3, 0x00, 0xc3, - 0x00, 0xc3, 0x00, 0xc3, 0xff, 0x4d, 0xff, 0x4d, 0xfd, 0x40, 0xfd, 0x40, - 0xfd, 0xa4, 0xfd, 0x90, 0xfe, 0x63, 0xfe, 0x63, 0x00, 0x46, 0x00, 0x46, - 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, - 0xff, 0xca, 0xff, 0x66, 0xfd, 0x8b, 0xfd, 0x8b, 0xfe, 0xb7, 0xfe, 0xa3, - 0xfe, 0xf9, 0xfe, 0xae, 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, - 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, 0x00, 0x25, 0x00, 0x25, 0xff, 0x87, - 0x00, 0x19, 0x00, 0x25, 0x01, 0xef, 0x02, 0x1e, 0x01, 0xef, 0x01, 0x1f, - 0x01, 0x1f, 0x00, 0xc3, 0x00, 0xc3, 0x00, 0xc3, 0x00, 0xc3, 0x00, 0xc3, - 0xfe, 0x8d, 0xff, 0x1f, 0xfe, 0x5b, 0xfe, 0xed, 0x00, 0x89, 0x00, 0xf5, - 0x01, 0x27, 0x01, 0x1f, 0x01, 0x2f, 0x01, 0x36, 0x01, 0x17, 0x01, 0x36, - 0x01, 0x1f, 0x01, 0x1f, 0x00, 0xc9, 0x00, 0xc9, 0xfe, 0xbf, 0xff, 0x1f, - 0x00, 0xf5, 0x01, 0x13, 0x01, 0x1f, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, - 0x00, 0x33, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0x33, 0x00, 0x33, 0x00, 0x25, - 0x00, 0x25, 0xfe, 0x5b, 0xfe, 0x70, 0xff, 0x7f, 0x01, 0x17, 0x01, 0x3f, - 0x01, 0x17, 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, - 0xfe, 0xa6, 0xff, 0xb5, 0xfe, 0xa6, 0xff, 0xce, 0x00, 0x4a, 0x01, 0xdb, - 0x01, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x64, 0x01, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x1d, 0x00, 0x00, 0x01, 0xcf, 0x01, 0xcf, 0x01, 0x93, 0x01, 0xcf, - 0x00, 0xd3, 0x00, 0xd3, 0x00, 0xd3, 0x00, 0xd3, 0x00, 0xa2, 0x00, 0xa2, - 0x01, 0x3f, 0x01, 0x3f, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0xac, 0x01, 0x16, 0x00, 0x80, 0x01, 0xac, 0x01, 0x16, 0x00, 0x80, - 0x01, 0x5a, 0x01, 0xa4, 0x00, 0xd0, 0x00, 0xf4, 0x00, 0x00, 0x01, 0xcf, - 0x01, 0x5a, 0x00, 0x21, 0x00, 0x21, 0x00, 0xd0, 0x00, 0xcb, 0x00, 0x00, - 0x01, 0x3d, 0x01, 0x48, 0x01, 0x0c, 0x01, 0x3f, 0x01, 0x49, 0x01, 0x3d, - 0x01, 0x3b, 0x01, 0x30, 0x01, 0x1c, 0x01, 0x1c, 0x01, 0x1c, 0x01, 0xd8, - 0x01, 0xd8, 0x01, 0x41, 0x01, 0x3d, 0x01, 0x58, 0x01, 0x42, 0x01, 0x46, - 0x01, 0x0c, 0x01, 0x3f, 0x01, 0x49, 0x01, 0x3d, 0x01, 0x3b, 0x01, 0x30, - 0x01, 0x1c, 0x01, 0x1c, 0x01, 0x1c, 0x01, 0xd8, 0x01, 0xd8, 0x01, 0x45, - 0x01, 0x31, 0x01, 0x3a, 0x01, 0x12, 0x01, 0x31, 0x01, 0x41, 0x01, 0x38, - 0x01, 0x56, 0x01, 0x25, 0x01, 0x41, 0x01, 0x47, 0x01, 0x5b, 0x01, 0x4d, - 0x00, 0x0a, 0x00, 0x7b, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x6d, - 0x00, 0x00, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x7b, - 0x00, 0x25, 0x00, 0x2a, 0x00, 0x2f, 0x00, 0x1e, 0x00, 0x2e, 0x00, 0x6a, - 0x00, 0x35, 0x00, 0x27, 0x00, 0x00, 0x00, 0x82, 0x00, 0x2f, 0x00, 0x68, - 0x00, 0x8c, 0x00, 0x06, 0x00, 0x3a, 0x00, 0x54, 0x00, 0x54, 0x00, 0x4a, - 0x00, 0x0a, 0x00, 0x00, 0x00, 0x42, 0x00, 0x11, 0x00, 0x25, 0x00, 0x00, - 0x00, 0x30, 0x00, 0x4a, 0x00, 0x89, 0x00, 0x25, 0x00, 0x0b, 0x00, 0x1b, - 0x00, 0x1b, 0x00, 0x1b, 0x00, 0x1b, 0x00, 0x1b, 0x00, 0x1b, 0x00, 0x0a, - 0x00, 0x1b, 0x00, 0x1b, 0x00, 0x1b, 0x00, 0x1b, 0x00, 0x1b, 0x00, 0x1b, - 0x00, 0x1b, 0x00, 0x42, 0x01, 0x1c, 0x00, 0x42, 0x01, 0x1c, 0x00, 0x42, - 0x01, 0x1c, 0x00, 0xb8, 0x00, 0xb8, 0x00, 0xb8, 0x00, 0xb8, 0x00, 0x42, - 0x00, 0x42, 0x00, 0x59, 0x00, 0x59, 0x00, 0x42, 0x01, 0x1c, 0x00, 0x42, - 0x01, 0x1c, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x01, 0x1c, 0x00, 0x42, - 0x01, 0x1c, 0x01, 0x1c, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, - 0x00, 0x42, 0x00, 0x42, 0x00, 0x71, 0x00, 0xb7, 0x00, 0xb7, 0x00, 0xb7, - 0x00, 0xb7, 0x00, 0xba, 0x00, 0x3f, 0x00, 0x51, 0x00, 0x51, 0x00, 0x32, - 0x00, 0x42, 0x00, 0x58, 0x00, 0x58, 0x00, 0x42, 0x00, 0x42, 0x02, 0x16, - 0x01, 0x1c, 0x00, 0x42, 0x00, 0x42, 0x02, 0x16, 0x01, 0x47, 0x00, 0x42, - 0x00, 0x2a, 0x00, 0x42, 0x00, 0x42, 0x00, 0x2a, 0x00, 0x42, 0x00, 0x2a, - 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, - 0x01, 0x1c, 0x00, 0x42, 0x01, 0x1c, 0x00, 0x42, 0x01, 0x1c, 0x00, 0x9b, - 0x00, 0x9b, 0x00, 0x9b, 0x00, 0x9b, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, - 0x00, 0x42, 0x01, 0x1c, 0x01, 0x1c, 0x00, 0x42, 0x01, 0x1c, 0x00, 0x42, - 0x01, 0x1c, 0x00, 0x42, 0x00, 0x42, 0x00, 0x19, 0x00, 0xf3, 0x00, 0x42, - 0x00, 0xf3, 0x00, 0xf3, 0x00, 0xf3, 0x00, 0xf3, 0x00, 0xf3, 0x00, 0xf3, - 0x00, 0xf3, 0x00, 0x42, 0x00, 0x45, 0x00, 0x45, 0x00, 0xf3, 0x00, 0x42, - 0x00, 0x2a, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, 0x00, 0x42, - 0x00, 0x42, 0x00, 0x42, 0x00, 0x19, 0x00, 0x42, 0x00, 0x19, 0x00, 0x25, - 0x00, 0x75, 0x00, 0xb6, 0x00, 0xb2, 0x00, 0xb2, 0x00, 0x49, 0xff, 0xfa, - 0xff, 0xfa, 0x00, 0x81, 0x00, 0x81, 0x00, 0x82, 0x00, 0x81, 0x00, 0x81, - 0x00, 0x82, 0x00, 0x98, 0x00, 0x8f, 0x00, 0x58, 0x00, 0x58, 0x00, 0x66, - 0x00, 0xa6, 0x01, 0x2b, 0x01, 0x3f, 0x00, 0x3b, 0x00, 0x3b, 0x00, 0x3b, - 0x00, 0xba, 0x00, 0x29, 0x00, 0x7d, 0x00, 0x7d, 0x00, 0xa4, 0x00, 0xa4, - 0x00, 0xa4, 0x00, 0xa4, 0x00, 0x81, 0x00, 0x3f, 0x00, 0x35, 0x00, 0xbb, - 0x00, 0xbc, 0x01, 0xe8, 0x00, 0xbb, 0x00, 0x58, 0x00, 0x4a, 0x00, 0x57, - 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, - 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, - 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x57, 0x00, 0x58, 0x00, 0x58, - 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x57, 0x00, 0x4a, 0x00, 0x4a, - 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, - 0x00, 0x58, 0x00, 0x45, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, - 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x56, 0x00, 0x56, - 0x00, 0x56, 0x00, 0x56, 0x00, 0x57, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, - 0x00, 0x58, 0x00, 0x56, 0x00, 0x56, 0x00, 0x56, 0x00, 0x56, 0x00, 0x56, - 0x00, 0x56, 0x00, 0x56, 0x00, 0x56, 0x00, 0x56, 0x00, 0x58, 0x00, 0x56, - 0x00, 0x56, 0x00, 0x56, 0x00, 0x56, 0x00, 0x56, 0x00, 0x56, 0x00, 0x58, - 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, - 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, - 0x00, 0x58, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x4f, - 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x4f, 0x00, 0x50, 0x00, 0x50, - 0x00, 0x50, 0x00, 0x50, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, - 0x01, 0xe9, 0x01, 0x08, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x56, - 0x00, 0x58, 0x00, 0x56, 0x00, 0x56, 0x00, 0x56, 0x00, 0x56, 0x00, 0x58, - 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x56, 0x00, 0x56, 0x00, 0x56, - 0x00, 0x56, 0x00, 0x50, 0x00, 0x49, 0x00, 0x72, 0x00, 0x92, 0x00, 0x92, - 0x00, 0x92, 0x00, 0x92, 0x00, 0x92, 0x01, 0xcf, 0x01, 0x5a, 0x01, 0xcf, - 0x01, 0x5a, 0x02, 0x25, 0x00, 0x0d, 0x02, 0x25, 0x00, 0x0d, 0x00, 0x58, - 0x00, 0x61, 0x00, 0x06, 0x00, 0x06, 0x00, 0xb8, 0x00, 0xa6, 0x00, 0x47, - 0x00, 0x58, 0x01, 0x2b, 0x01, 0x1c, 0x01, 0x2b, 0x01, 0x1c, 0x02, 0x01, - 0x00, 0x7c, 0x00, 0x68, 0x00, 0x06, 0x00, 0x7d, 0x00, 0x32, 0x00, 0x06, - 0x00, 0x48, 0x01, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, - 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, - 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x25, 0x00, 0x06, - 0x00, 0x06, 0x00, 0x06, 0x00, 0x25, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, - 0x01, 0x00, 0x00, 0x06, 0x00, 0x06, 0x01, 0x00, 0x00, 0x06, 0x00, 0x06, - 0xff, 0xec, 0x00, 0x06, 0x01, 0x08, 0x01, 0x3f, 0x00, 0x06, 0x00, 0x58, - 0x00, 0x58, 0x00, 0x25, 0x00, 0x58, 0x00, 0x58, 0x01, 0x00, 0x00, 0x06, - 0x00, 0x06, 0x01, 0x36, 0x00, 0xbe, 0x00, 0x46, 0x00, 0x06, 0x00, 0x9c, - 0x01, 0x00, 0x00, 0x06, 0x00, 0x46, 0x00, 0x1a, 0x00, 0x48, 0x00, 0x06, - 0x00, 0x06, 0x00, 0x06, 0x00, 0x52, 0x00, 0x46, 0x00, 0x46, 0x00, 0x46, - 0x00, 0x06, 0x01, 0x18, 0x01, 0x18, 0x01, 0x18, 0x01, 0x19, 0x02, 0xf6, - 0x01, 0x19, 0x01, 0x18, 0x01, 0x18, 0x01, 0x18, 0x01, 0x18, 0x02, 0xf5, - 0x01, 0x18, 0x02, 0x0c, 0x00, 0x11, 0x02, 0x0c, 0x02, 0x0c, 0x00, 0x10, - 0x02, 0x0b, 0x00, 0x10, 0x02, 0x01, 0x00, 0x19, 0x00, 0x06, 0x00, 0x96, - 0xff, 0xec, 0xff, 0xec, 0x02, 0x18, 0x01, 0xc8, 0xff, 0xec, 0xff, 0xec, - 0x02, 0x18, 0x01, 0xc8, 0xff, 0xeb, 0xff, 0xec, 0x02, 0x18, 0x01, 0xc8, - 0x02, 0x18, 0x02, 0x18, 0x01, 0xc8, 0x01, 0xc8, 0xff, 0xec, 0xff, 0xec, - 0xff, 0xec, 0xff, 0xec, 0x02, 0x18, 0x02, 0x18, 0x01, 0xc8, 0x01, 0xc8, - 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0x02, 0x18, 0x02, 0x18, - 0x01, 0xc8, 0x01, 0xc8, 0x01, 0xc8, 0x01, 0xc8, 0x01, 0xc8, 0x01, 0xc8, - 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, - 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, - 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, - 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, - 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, - 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, - 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, - 0x02, 0x18, 0x01, 0xc8, 0xff, 0xec, 0x01, 0x78, 0x02, 0x18, 0x01, 0x78, - 0x01, 0x78, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0x02, 0x18, 0x01, 0x78, - 0x01, 0x78, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0x02, 0x18, 0x01, 0x78, - 0x01, 0x78, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, - 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, - 0xff, 0xec, 0x02, 0x18, 0xff, 0xec, 0xff, 0xec, 0x02, 0x18, 0xff, 0x93, - 0xff, 0x93, 0xff, 0x93, 0xff, 0xec, 0x02, 0x18, 0x02, 0x7c, 0x02, 0x18, - 0xff, 0xec, 0x01, 0xc8, 0x02, 0x7c, 0x01, 0xc8, 0xff, 0xec, 0x01, 0xc8, - 0xff, 0xec, 0x01, 0xc8, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, - 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, - 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, - 0x02, 0x69, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0x04, 0x45, - 0xff, 0xec, 0x02, 0x69, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, - 0xff, 0xec, 0x02, 0x69, 0xff, 0xec, 0xff, 0xec, 0x00, 0x06, 0x00, 0x06, - 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, - 0x00, 0x06, 0x00, 0x06, 0x00, 0xdb, 0x00, 0xdb, 0x00, 0x06, 0x00, 0x06, - 0x01, 0x44, 0x01, 0x44, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, - 0x00, 0xdb, 0x00, 0xdb, 0x00, 0x06, 0x00, 0x06, 0x00, 0xdb, 0x00, 0xdb, - 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0xdb, 0x00, 0xdb, - 0x00, 0x06, 0x00, 0x06, 0x00, 0xdb, 0x00, 0xdb, 0x00, 0x06, 0x00, 0x06, - 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x75, 0x00, 0x06, - 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, - 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x01, 0x37, 0x01, 0x37, - 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0x01, 0x37, 0x01, 0x37, - 0x01, 0x37, 0x01, 0x37, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, - 0x00, 0x06, 0x00, 0x06, 0x01, 0x3f, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, - 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0xff, 0xec, - 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, - 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x61, - 0x00, 0x61, 0x00, 0xaf, 0x00, 0xaf, 0x00, 0x06, 0x00, 0x22, 0x00, 0x32, - 0x00, 0x22, 0x00, 0x59, 0x00, 0x1d, 0x00, 0x3a, 0x00, 0x3a, 0x00, 0xc8, - 0x00, 0x3b, 0x00, 0x2b, 0x00, 0x0f, 0x00, 0x12, 0x00, 0x36, 0x00, 0x2e, - 0x00, 0x14, 0x00, 0x08, 0x00, 0x6f, 0x00, 0x63, 0x00, 0x85, 0x00, 0xc9, - 0x00, 0x1c, 0x00, 0x4e, 0x00, 0x38, 0x00, 0x2f, 0x00, 0x26, 0x00, 0x2f, - 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x0e, 0x00, 0x8c, 0x00, 0x0e, 0x00, 0x8c, - 0x00, 0x0c, 0x00, 0x09, 0x00, 0x08, 0x00, 0x22, 0x00, 0x4e, 0x00, 0x60, - 0x00, 0x79, 0x00, 0x61, 0x00, 0xcc, 0x00, 0x37, 0x00, 0x1e, 0x00, 0x08, - 0x00, 0x67, 0x00, 0x0f, 0x00, 0x1b, 0x00, 0x0e, 0x00, 0x1b, 0x00, 0x21, - 0x00, 0x21, 0x00, 0x21, 0x00, 0x21, 0x00, 0x9c, 0x00, 0x95, 0x00, 0xbd, - 0x00, 0x91, 0x00, 0x91, 0x00, 0x15, 0x00, 0x47, 0x00, 0xae, 0x00, 0x43, - 0x00, 0x4c, 0x00, 0xd7, 0x00, 0x18, 0x00, 0x35, 0x00, 0x1b, 0x00, 0x34, - 0x00, 0x3d, 0x00, 0x2f, 0x00, 0x55, 0x00, 0x32, 0x00, 0x38, 0x00, 0x15, - 0x00, 0x59, 0x00, 0x5e, 0x00, 0x43, 0x00, 0x56, 0x00, 0x70, 0x00, 0xde, - 0x00, 0x90, 0x00, 0x9c, 0x00, 0x6a, 0x00, 0x36, 0x00, 0x94, 0x00, 0xe2, - 0x00, 0x67, 0x00, 0x76, 0x00, 0x80, 0x00, 0x0e, 0x00, 0x91, 0x00, 0x32, - 0x00, 0x7f, 0x00, 0x0b, 0x00, 0x91, 0x00, 0x31, 0x00, 0x2e, 0x01, 0x72, - 0x00, 0xa2, 0x00, 0x6a, 0x00, 0x11, 0x01, 0x44, 0x01, 0xb1, 0x01, 0x37, - 0x00, 0x60, 0x00, 0x2e, 0x00, 0x2f, 0x00, 0x3c, 0x00, 0x4b, 0x00, 0x44, - 0x00, 0x24, 0x00, 0x3e, 0x00, 0x4b, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x39, - 0x00, 0x2e, 0x00, 0x37, 0x00, 0x2e, 0x00, 0x50, 0x00, 0x3c, 0x00, 0x3c, - 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x2e, 0x00, 0x2e, - 0x00, 0x2e, 0x00, 0x2e, 0x00, 0x52, 0x00, 0x52, 0x00, 0x96, 0x00, 0x73, - 0x00, 0x27, 0x00, 0x1f, 0x00, 0x81, 0x00, 0xbc, 0x00, 0x13, 0x00, 0x16, - 0x00, 0x4a, 0x00, 0x1e, 0x00, 0x2a, 0x00, 0x52, 0x00, 0x2a, 0x00, 0x22, - 0x00, 0x88, 0x00, 0xf3, 0x00, 0xde, 0x00, 0x2e, 0x00, 0x2e, 0x00, 0x3a, - 0x00, 0x3d, 0x00, 0x34, 0x00, 0x25, 0x00, 0x3d, 0x00, 0x3f, 0x01, 0x44, - 0x00, 0x2d, 0x00, 0x57, 0x00, 0x26, 0x00, 0x57, 0x00, 0x3b, 0x00, 0x25, - 0x00, 0x98, 0x00, 0x4a, 0x00, 0x81, 0x00, 0x40, 0x00, 0x83, 0x00, 0x33, - 0x00, 0x40, 0x00, 0x56, 0x00, 0x39, 0x00, 0x30, 0x00, 0x9b, 0x00, 0x7e, - 0x00, 0x90, 0x00, 0x30, 0x00, 0x47, 0x00, 0x1f, 0x00, 0x1c, 0x00, 0x1a, - 0x00, 0x17, 0x00, 0x2b, 0x00, 0x25, 0x00, 0x28, 0x00, 0x43, 0x00, 0x28, - 0x00, 0x23, 0x00, 0x28, 0x00, 0x3d, 0x00, 0x28, 0x00, 0x2e, 0x00, 0x36, - 0x00, 0x57, 0x00, 0x30, 0x00, 0x24, 0x00, 0x1a, 0x00, 0x32, 0x00, 0x1f, - 0x00, 0x1a, 0x00, 0x24, 0x00, 0x30, 0x00, 0x31, 0x00, 0x37, 0x00, 0x34, - 0x00, 0x21, 0x00, 0x24, 0x00, 0x16, 0x00, 0x16, 0x00, 0x25, 0x00, 0x32, - 0x00, 0x20, 0x00, 0x30, 0x00, 0x19, 0x00, 0x32, 0x00, 0x29, 0x00, 0x21, - 0x00, 0x17, 0x00, 0x22, 0x00, 0x24, 0x00, 0x45, 0x00, 0x3d, 0x00, 0x38, - 0x00, 0x30, 0x00, 0x2b, 0x02, 0x1b, 0x01, 0xcd, 0x01, 0x51, 0x01, 0xdd, - 0x01, 0xd3, 0x01, 0x00, 0x00, 0xf6, 0x00, 0x67, 0x00, 0xff, 0x00, 0xbe, - 0x00, 0x2e, 0x00, 0x72, 0x00, 0x41, 0x00, 0x31, 0x00, 0xf0, 0x00, 0xf0, - 0x01, 0x66, 0x01, 0x6e, 0x01, 0x43, 0x01, 0x44, 0x00, 0xd2, 0x00, 0xd2, - 0x00, 0xcd, 0x00, 0xce, 0x01, 0xc9, 0x01, 0xc9, 0x01, 0x19, 0x00, 0xf9, - 0x00, 0x53, 0x00, 0x74, 0x00, 0x53, 0x00, 0x74, 0x00, 0x2d, 0x00, 0x49, - 0x00, 0x53, 0x00, 0x2d, 0x00, 0x36, 0x00, 0x53, 0x00, 0x53, 0x00, 0x60, - 0x00, 0x7b, 0x00, 0x7b, 0x00, 0x36, 0x00, 0x36, 0x01, 0x4f, 0x00, 0x36, - 0x00, 0x65, 0x00, 0x65, 0x00, 0x35, 0x00, 0x61, 0x00, 0x7d, 0x00, 0x54, - 0x00, 0x32, 0x00, 0x29, 0x00, 0x91, 0x00, 0x58, 0x00, 0x74, 0x00, 0x53, - 0x00, 0x75, 0x00, 0x4e, 0x00, 0x2a, 0x00, 0x75, 0x00, 0x35, 0x00, 0x1d, - 0x00, 0x26, 0x00, 0x25, 0x00, 0x32, 0x00, 0x58, 0x01, 0x38, 0x01, 0x37, - 0x00, 0x75, 0x01, 0x29, 0x01, 0x28, 0x01, 0x86, 0x01, 0x86, 0x00, 0x75, - 0x00, 0x58, 0x00, 0x58, 0x00, 0x96, 0x00, 0x58, 0x00, 0x58, 0x00, 0x54, - 0x01, 0x31, 0x01, 0x31, 0x00, 0x8b, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0x8b, - 0x00, 0x54, 0x01, 0x31, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, - 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x8f, - 0x00, 0x6a, 0x00, 0x56, 0x00, 0x25, 0x00, 0x6a, 0x00, 0x89, 0x00, 0xc3, - 0x00, 0x4c, 0x00, 0x98, 0x00, 0x89, 0x01, 0xe6, 0x01, 0x08, 0x00, 0x8b, - 0x00, 0x9c, 0x00, 0xc1, 0x00, 0x58, 0x01, 0xcf, 0x01, 0x5a, 0x01, 0xcf, - 0x01, 0x5a, 0x00, 0xda, 0x01, 0x2c, 0x01, 0x2c, 0x01, 0x2c, 0x01, 0x2c, - 0x01, 0x2c, 0x01, 0x2c, 0x01, 0x2c, 0x01, 0x2c, 0x01, 0x2c, 0x01, 0x2c, - 0x01, 0x2c, 0x01, 0x2c, 0x01, 0x2c, 0x01, 0x2c, 0x01, 0x2c, 0x01, 0x54, - 0x01, 0x54, 0x02, 0x28, 0x02, 0x28, 0x02, 0x28, 0x01, 0x41, 0x01, 0x6e, - 0x00, 0xeb, 0x00, 0xeb, 0x00, 0x89, 0x00, 0xc3, 0x01, 0xe9, 0x01, 0x88, - 0x02, 0x04, 0x02, 0x10, 0x00, 0x89, 0x00, 0x9d, 0x00, 0x54, 0x00, 0x7a, - 0x00, 0x14, 0x00, 0x89, 0x00, 0x23, 0x00, 0x23, 0x00, 0x45, 0x00, 0x45, - 0xff, 0xec, 0xff, 0xec, 0x00, 0x45, 0x00, 0x45, 0xff, 0xec, 0xff, 0xec, - 0x00, 0x45, 0x00, 0x45, 0xff, 0xec, 0xff, 0xec, 0x00, 0x45, 0x00, 0x45, - 0xff, 0xec, 0xff, 0xec, 0x00, 0x45, 0x00, 0x45, 0xff, 0xec, 0xff, 0xec, - 0x00, 0x45, 0x00, 0x45, 0xff, 0xec, 0xff, 0xec, 0xff, 0xb6, 0xff, 0x6a, - 0xff, 0xec, 0xff, 0xec, 0xff, 0xb6, 0xff, 0x6a, 0xff, 0xec, 0xff, 0xec, - 0x00, 0x58, 0x00, 0x58, 0xff, 0xec, 0xff, 0xec, 0x00, 0x58, 0x00, 0x58, - 0xff, 0xec, 0xff, 0xec, 0x00, 0x58, 0x00, 0x58, 0xff, 0xec, 0xff, 0xec, - 0x00, 0x58, 0x00, 0x58, 0xff, 0xec, 0xff, 0xec, 0xff, 0xcc, 0xff, 0x60, - 0xff, 0xcc, 0xff, 0x60, 0x00, 0x0a, 0xff, 0x83, 0xff, 0xec, 0xff, 0xec, - 0x00, 0x0a, 0xff, 0x83, 0xff, 0xec, 0xff, 0xec, 0x00, 0x36, 0xff, 0xd5, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, 0xff, 0xec, - 0x00, 0x19, 0xff, 0x7c, 0xff, 0xec, 0xff, 0xec, 0x01, 0x44, 0xff, 0xec, - 0x01, 0x44, 0x03, 0x22, 0x01, 0x44, 0x01, 0x44, 0xff, 0xec, 0x01, 0x44, - 0xff, 0xec, 0x01, 0x44, 0xff, 0xec, 0x01, 0x30, 0xff, 0xec, 0x01, 0x56, - 0xff, 0xec, 0x01, 0xb2, 0x01, 0x00, 0x01, 0x00, 0x01, 0xb3, 0x01, 0xe4, - 0x00, 0x4c, 0x00, 0x5a, 0x01, 0xb6, 0x02, 0x13, 0x00, 0x19, 0xff, 0x7c, - 0xff, 0xec, 0xff, 0xec, 0x02, 0x0c, 0x02, 0x4c, 0x00, 0x45, 0x00, 0x45, - 0xff, 0xec, 0xff, 0xec, 0x00, 0xde, 0x00, 0xf2, 0x00, 0x45, 0x00, 0x45, - 0xff, 0xec, 0xff, 0xec, 0x00, 0x45, 0x00, 0x45, 0xff, 0xec, 0xff, 0xec, - 0x00, 0x58, 0x00, 0x58, 0xff, 0xec, 0xff, 0xec, 0x00, 0x58, 0x00, 0x58, - 0xff, 0xec, 0xff, 0xec, 0x00, 0x58, 0x00, 0x58, 0xff, 0xec, 0xff, 0xec, - 0x00, 0xe8, 0x00, 0xe8, 0x00, 0xe8, 0x00, 0xe8, 0xff, 0xcc, 0xff, 0x60, - 0xff, 0xcc, 0xff, 0x60, 0xff, 0x24, 0xfe, 0xd8, 0xff, 0xec, 0xff, 0xec, - 0xff, 0x24, 0xfe, 0xd8, 0xff, 0xec, 0xff, 0xec, 0xff, 0x10, 0xfe, 0xc5, - 0xff, 0xec, 0xff, 0xec, 0xff, 0x10, 0xfe, 0xc5, 0xff, 0xec, 0xff, 0xec, - 0x00, 0x0a, 0x00, 0x14, 0xff, 0xec, 0xff, 0xec, 0x00, 0x0a, 0x00, 0x14, - 0xff, 0xec, 0xff, 0xec, 0x00, 0x7a, 0x00, 0x94, 0xff, 0xec, 0xff, 0xec, - 0x00, 0x7a, 0x00, 0x94, 0xff, 0xec, 0xff, 0xec, 0xff, 0xb6, 0xff, 0x6a, - 0xff, 0xec, 0xff, 0xec, 0x00, 0x1f, 0xff, 0xed, 0xff, 0xec, 0xff, 0xec, - 0x00, 0x08, 0xff, 0xa1, 0xff, 0xec, 0xff, 0xec, 0x00, 0x43, 0x00, 0x0a, - 0xff, 0xec, 0xff, 0xec, 0x00, 0x82, 0x00, 0x47, 0xff, 0xec, 0xff, 0xec, - 0x00, 0x36, 0xff, 0xd5, 0xff, 0xec, 0xff, 0xec, 0x00, 0xde, 0x00, 0xf2, - 0xff, 0xec, 0xff, 0xec, 0x00, 0x4c, 0x00, 0x5a, 0x00, 0x19, 0xff, 0x7c, - 0x00, 0x19, 0xff, 0x7c, 0xff, 0xec, 0xff, 0xec, 0xff, 0x96, 0xff, 0x40, - 0x00, 0x53, 0xff, 0xe0, 0x00, 0x85, 0x00, 0x5f, 0x00, 0xb3, 0x00, 0x5f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, - 0x00, 0xb2, 0x00, 0x25, 0x00, 0xa6, 0x00, 0x8b, 0x00, 0x89, 0x00, 0xc5, - 0x00, 0xe9, 0x00, 0x66, 0x00, 0x89, 0x00, 0xc9, 0x00, 0x6d, 0x00, 0x89, - 0x00, 0xd7, 0x00, 0x56, 0x00, 0x8b, 0x00, 0x75, 0x00, 0xc5, 0x00, 0x75, - 0x00, 0x8f, 0x00, 0x8b, 0x00, 0x2f, 0x00, 0x93, 0x00, 0x39, 0x00, 0x00, - 0x00, 0x12, 0x00, 0x25, 0x00, 0x9c, 0x00, 0x85, 0x00, 0xc1, 0x00, 0xc3, - 0x00, 0x7b, 0x00, 0x7b, 0x00, 0xc3, 0x00, 0x7b, 0x00, 0xc3, 0x00, 0xb2, - 0x00, 0xba, 0x00, 0xec, 0x00, 0xa0, 0x00, 0x6d, 0x00, 0xc3, 0x00, 0x89, - 0x00, 0xbe, 0x00, 0x89, 0x01, 0x6a, 0x00, 0xd5, 0x00, 0x83, 0x00, 0xc3, - 0x00, 0x64, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x68, 0x00, 0xcb, 0x00, 0x85, - 0x00, 0xf6, 0x00, 0x98, 0x00, 0x89, 0x00, 0x66, 0x00, 0x8f, 0x00, 0x85, - 0x00, 0x8b, 0x00, 0x83, 0x00, 0x7f, 0x01, 0xdb, 0x01, 0x3f, 0x01, 0xdb, - 0x01, 0x1f, 0x01, 0x79, 0x01, 0x37, 0x01, 0x37, 0x00, 0x1b, 0x01, 0x2f, - 0x01, 0x2f, 0x02, 0x01, 0x01, 0x58, 0x00, 0xbb, 0x01, 0x66, 0x01, 0x3d, - 0x00, 0x9c, 0x00, 0x06, 0x01, 0x00, 0x01, 0x5e, 0x01, 0x3f, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xff, 0xec, 0xff, 0xec, 0xff, 0xed, - 0xff, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x95, 0x00, 0x45, 0x00, 0x1f, 0x00, 0x45, 0x00, 0x45, - 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0xff, 0xcc, 0xff, 0xb6, 0x00, 0x43, - 0x00, 0x36, 0x00, 0x4c, 0x00, 0x19, 0x00, 0xde, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4c, - 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0xdc, - 0x00, 0x00, 0x01, 0x98, 0x00, 0x00, 0x02, 0x98, 0x00, 0x00, 0x03, 0xa0, - 0x00, 0x00, 0x04, 0xfc, 0x00, 0x00, 0x05, 0x2c, 0x00, 0x00, 0x05, 0x84, - 0x00, 0x00, 0x05, 0xdc, 0x00, 0x00, 0x06, 0x78, 0x00, 0x00, 0x06, 0xd0, - 0x00, 0x00, 0x07, 0x0c, 0x00, 0x00, 0x07, 0x38, 0x00, 0x00, 0x07, 0x64, - 0x00, 0x00, 0x07, 0x98, 0x00, 0x00, 0x09, 0x20, 0x00, 0x00, 0x09, 0x78, - 0x00, 0x00, 0x0a, 0x28, 0x00, 0x00, 0x0a, 0xe8, 0x00, 0x00, 0x0b, 0x64, - 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0xb8, 0x00, 0x00, 0x0d, 0x14, - 0x00, 0x00, 0x0d, 0xe8, 0x00, 0x00, 0x0e, 0x9c, 0x00, 0x00, 0x0e, 0xe0, - 0x00, 0x00, 0x0f, 0x34, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x0f, 0xc4, - 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10, 0xf4, 0x00, 0x00, 0x12, 0x08, - 0x00, 0x00, 0x12, 0xd8, 0x00, 0x00, 0x13, 0x80, 0x00, 0x00, 0x14, 0x0c, - 0x00, 0x00, 0x14, 0x80, 0x00, 0x00, 0x14, 0xdc, 0x00, 0x00, 0x15, 0x2c, - 0x00, 0x00, 0x15, 0xd0, 0x00, 0x00, 0x16, 0x28, 0x00, 0x00, 0x16, 0x80, - 0x00, 0x00, 0x16, 0xec, 0x00, 0x00, 0x17, 0xbc, 0x00, 0x00, 0x17, 0xf4, - 0x00, 0x00, 0x18, 0xb4, 0x00, 0x00, 0x19, 0x50, 0x00, 0x00, 0x19, 0xd0, - 0x00, 0x00, 0x1a, 0x44, 0x00, 0x00, 0x1a, 0xec, 0x00, 0x00, 0x1b, 0xb8, - 0x00, 0x00, 0x1c, 0xb4, 0x00, 0x00, 0x1c, 0xf8, 0x00, 0x00, 0x1d, 0x84, - 0x00, 0x00, 0x1d, 0xf8, 0x00, 0x00, 0x1f, 0x10, 0x00, 0x00, 0x20, 0x14, - 0x00, 0x00, 0x20, 0x9c, 0x00, 0x00, 0x21, 0x10, 0x00, 0x00, 0x21, 0x54, - 0x00, 0x00, 0x21, 0x8c, 0x00, 0x00, 0x21, 0xd0, 0x00, 0x00, 0x22, 0x14, - 0x00, 0x00, 0x22, 0x40, 0x00, 0x00, 0x22, 0x84, 0x00, 0x00, 0x23, 0x70, - 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x24, 0x88, 0x00, 0x00, 0x25, 0x18, - 0x00, 0x00, 0x25, 0xc0, 0x00, 0x00, 0x26, 0x38, 0x00, 0x00, 0x27, 0x00, - 0x00, 0x00, 0x27, 0x70, 0x00, 0x00, 0x27, 0xd8, 0x00, 0x00, 0x28, 0x50, - 0x00, 0x00, 0x29, 0x4c, 0x00, 0x00, 0x29, 0xa4, 0x00, 0x00, 0x2a, 0xb0, - 0x00, 0x00, 0x2b, 0x20, 0x00, 0x00, 0x2b, 0x98, 0x00, 0x00, 0x2c, 0x2c, - 0x00, 0x00, 0x2c, 0xc0, 0x00, 0x00, 0x2d, 0x50, 0x00, 0x00, 0x2e, 0x3c, - 0x00, 0x00, 0x2e, 0xb0, 0x00, 0x00, 0x2f, 0x20, 0x00, 0x00, 0x2f, 0xac, - 0x00, 0x00, 0x30, 0xf8, 0x00, 0x00, 0x31, 0xe4, 0x00, 0x00, 0x32, 0xd0, - 0x00, 0x00, 0x33, 0x58, 0x00, 0x00, 0x34, 0x24, 0x00, 0x00, 0x34, 0x54, - 0x00, 0x00, 0x35, 0x24, 0x00, 0x00, 0x35, 0xa4, 0x00, 0x00, 0x35, 0xa4, - 0x00, 0x00, 0x35, 0xf4, 0x00, 0x00, 0x36, 0xb8, 0x00, 0x00, 0x37, 0x4c, - 0x00, 0x00, 0x38, 0x64, 0x00, 0x00, 0x39, 0x38, 0x00, 0x00, 0x39, 0x84, - 0x00, 0x00, 0x3a, 0xa8, 0x00, 0x00, 0x3a, 0xec, 0x00, 0x00, 0x3c, 0x08, - 0x00, 0x00, 0x3c, 0xec, 0x00, 0x00, 0x3d, 0x60, 0x00, 0x00, 0x3d, 0x98, - 0x00, 0x00, 0x3d, 0xc4, 0x00, 0x00, 0x3f, 0x2c, 0x00, 0x00, 0x3f, 0x58, - 0x00, 0x00, 0x3f, 0xd0, 0x00, 0x00, 0x40, 0x3c, 0x00, 0x00, 0x40, 0xf0, - 0x00, 0x00, 0x41, 0xc0, 0x00, 0x00, 0x42, 0x04, 0x00, 0x00, 0x42, 0xb4, - 0x00, 0x00, 0x43, 0x10, 0x00, 0x00, 0x43, 0x40, 0x00, 0x00, 0x43, 0x50, - 0x00, 0x00, 0x43, 0xb8, 0x00, 0x00, 0x44, 0x48, 0x00, 0x00, 0x44, 0xc0, - 0x00, 0x00, 0x44, 0xe0, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x45, 0x20, - 0x00, 0x00, 0x46, 0x14, 0x00, 0x00, 0x46, 0x38, 0x00, 0x00, 0x46, 0x5c, - 0x00, 0x00, 0x46, 0x8c, 0x00, 0x00, 0x46, 0xb8, 0x00, 0x00, 0x46, 0xf0, - 0x00, 0x00, 0x48, 0x24, 0x00, 0x00, 0x48, 0xdc, 0x00, 0x00, 0x48, 0xf4, - 0x00, 0x00, 0x49, 0x0c, 0x00, 0x00, 0x49, 0x24, 0x00, 0x00, 0x49, 0x3c, - 0x00, 0x00, 0x49, 0x54, 0x00, 0x00, 0x49, 0x6c, 0x00, 0x00, 0x49, 0x84, - 0x00, 0x00, 0x49, 0xac, 0x00, 0x00, 0x49, 0xd0, 0x00, 0x00, 0x4a, 0x6c, - 0x00, 0x00, 0x4a, 0x98, 0x00, 0x00, 0x4a, 0xbc, 0x00, 0x00, 0x4a, 0xe0, - 0x00, 0x00, 0x4b, 0x10, 0x00, 0x00, 0x4b, 0x3c, 0x00, 0x00, 0x4b, 0x74, - 0x00, 0x00, 0x4b, 0xe8, 0x00, 0x00, 0x4c, 0xec, 0x00, 0x00, 0x4d, 0x10, - 0x00, 0x00, 0x4d, 0x34, 0x00, 0x00, 0x4d, 0x64, 0x00, 0x00, 0x4d, 0x9c, - 0x00, 0x00, 0x4d, 0xc0, 0x00, 0x00, 0x4e, 0x40, 0x00, 0x00, 0x4f, 0x24, - 0x00, 0x00, 0x4f, 0x3c, 0x00, 0x00, 0x4f, 0x54, 0x00, 0x00, 0x4f, 0x6c, - 0x00, 0x00, 0x4f, 0x84, 0x00, 0x00, 0x4f, 0x9c, 0x00, 0x00, 0x4f, 0xb4, - 0x00, 0x00, 0x51, 0x04, 0x00, 0x00, 0x51, 0x1c, 0x00, 0x00, 0x51, 0x34, - 0x00, 0x00, 0x51, 0x4c, 0x00, 0x00, 0x51, 0x64, 0x00, 0x00, 0x51, 0x84, - 0x00, 0x00, 0x51, 0x9c, 0x00, 0x00, 0x51, 0xb4, 0x00, 0x00, 0x51, 0xd8, - 0x00, 0x00, 0x51, 0xf8, 0x00, 0x00, 0x53, 0x0c, 0x00, 0x00, 0x53, 0x24, - 0x00, 0x00, 0x53, 0x3c, 0x00, 0x00, 0x53, 0x54, 0x00, 0x00, 0x53, 0x7c, - 0x00, 0x00, 0x53, 0xac, 0x00, 0x00, 0x53, 0xdc, 0x00, 0x00, 0x54, 0x38, - 0x00, 0x00, 0x55, 0x3c, 0x00, 0x00, 0x55, 0x54, 0x00, 0x00, 0x55, 0x6c, - 0x00, 0x00, 0x55, 0x94, 0x00, 0x00, 0x55, 0xc4, 0x00, 0x00, 0x55, 0xdc, - 0x00, 0x00, 0x56, 0x70, 0x00, 0x00, 0x56, 0x88, 0x00, 0x00, 0x56, 0xb4, - 0x00, 0x00, 0x56, 0xcc, 0x00, 0x00, 0x56, 0xfc, 0x00, 0x00, 0x57, 0x14, - 0x00, 0x00, 0x57, 0x2c, 0x00, 0x00, 0x57, 0x44, 0x00, 0x00, 0x57, 0x5c, - 0x00, 0x00, 0x57, 0x74, 0x00, 0x00, 0x57, 0x8c, 0x00, 0x00, 0x57, 0xa4, - 0x00, 0x00, 0x57, 0xbc, 0x00, 0x00, 0x57, 0xd4, 0x00, 0x00, 0x57, 0xec, - 0x00, 0x00, 0x58, 0x04, 0x00, 0x00, 0x58, 0x1c, 0x00, 0x00, 0x58, 0x44, - 0x00, 0x00, 0x58, 0x54, 0x00, 0x00, 0x59, 0x10, 0x00, 0x00, 0x59, 0x28, - 0x00, 0x00, 0x59, 0x40, 0x00, 0x00, 0x59, 0x58, 0x00, 0x00, 0x59, 0x70, - 0x00, 0x00, 0x59, 0x88, 0x00, 0x00, 0x59, 0xa0, 0x00, 0x00, 0x59, 0xb8, - 0x00, 0x00, 0x59, 0xd0, 0x00, 0x00, 0x59, 0xe8, 0x00, 0x00, 0x5a, 0x00, - 0x00, 0x00, 0x5a, 0x18, 0x00, 0x00, 0x5a, 0x30, 0x00, 0x00, 0x5a, 0x48, - 0x00, 0x00, 0x5a, 0x60, 0x00, 0x00, 0x5a, 0x78, 0x00, 0x00, 0x5a, 0x90, - 0x00, 0x00, 0x5a, 0xa8, 0x00, 0x00, 0x5a, 0xc0, 0x00, 0x00, 0x5a, 0xf0, - 0x00, 0x00, 0x5b, 0x24, 0x00, 0x00, 0x5b, 0xb0, 0x00, 0x00, 0x5c, 0x44, - 0x00, 0x00, 0x5c, 0x78, 0x00, 0x00, 0x5c, 0x90, 0x00, 0x00, 0x5c, 0xb8, - 0x00, 0x00, 0x5c, 0xd0, 0x00, 0x00, 0x5c, 0xf8, 0x00, 0x00, 0x5d, 0x10, - 0x00, 0x00, 0x5d, 0x28, 0x00, 0x00, 0x5d, 0x40, 0x00, 0x00, 0x5d, 0x58, - 0x00, 0x00, 0x5d, 0xa8, 0x00, 0x00, 0x5e, 0x50, 0x00, 0x00, 0x5f, 0x00, - 0x00, 0x00, 0x5f, 0x18, 0x00, 0x00, 0x5f, 0x30, 0x00, 0x00, 0x5f, 0x48, - 0x00, 0x00, 0x5f, 0x60, 0x00, 0x00, 0x60, 0x5c, 0x00, 0x00, 0x60, 0x80, - 0x00, 0x00, 0x60, 0xb4, 0x00, 0x00, 0x60, 0xcc, 0x00, 0x00, 0x60, 0xe4, - 0x00, 0x00, 0x60, 0xfc, 0x00, 0x00, 0x61, 0x14, 0x00, 0x00, 0x61, 0x2c, - 0x00, 0x00, 0x61, 0x44, 0x00, 0x00, 0x61, 0xb8, 0x00, 0x00, 0x62, 0x48, - 0x00, 0x00, 0x62, 0x60, 0x00, 0x00, 0x62, 0x78, 0x00, 0x00, 0x62, 0x90, - 0x00, 0x00, 0x62, 0xa8, 0x00, 0x00, 0x62, 0xc0, 0x00, 0x00, 0x62, 0xd8, - 0x00, 0x00, 0x62, 0xf0, 0x00, 0x00, 0x63, 0x80, 0x00, 0x00, 0x64, 0x18, - 0x00, 0x00, 0x64, 0x44, 0x00, 0x00, 0x64, 0x64, 0x00, 0x00, 0x64, 0x8c, - 0x00, 0x00, 0x64, 0xb4, 0x00, 0x00, 0x64, 0xcc, 0x00, 0x00, 0x64, 0xe4, - 0x00, 0x00, 0x65, 0x7c, 0x00, 0x00, 0x66, 0x94, 0x00, 0x00, 0x66, 0xac, - 0x00, 0x00, 0x66, 0xc4, 0x00, 0x00, 0x66, 0xdc, 0x00, 0x00, 0x66, 0xf4, - 0x00, 0x00, 0x67, 0x0c, 0x00, 0x00, 0x67, 0x24, 0x00, 0x00, 0x67, 0x3c, - 0x00, 0x00, 0x67, 0x54, 0x00, 0x00, 0x67, 0x6c, 0x00, 0x00, 0x67, 0x84, - 0x00, 0x00, 0x67, 0x9c, 0x00, 0x00, 0x67, 0xb4, 0x00, 0x00, 0x67, 0xcc, - 0x00, 0x00, 0x67, 0xe4, 0x00, 0x00, 0x67, 0xfc, 0x00, 0x00, 0x68, 0x14, - 0x00, 0x00, 0x68, 0x38, 0x00, 0x00, 0x68, 0x50, 0x00, 0x00, 0x68, 0xb8, - 0x00, 0x00, 0x69, 0x4c, 0x00, 0x00, 0x69, 0x78, 0x00, 0x00, 0x69, 0xa0, - 0x00, 0x00, 0x69, 0xcc, 0x00, 0x00, 0x69, 0xec, 0x00, 0x00, 0x6a, 0x14, - 0x00, 0x00, 0x6a, 0x3c, 0x00, 0x00, 0x6a, 0x54, 0x00, 0x00, 0x6a, 0x6c, - 0x00, 0x00, 0x6a, 0x84, 0x00, 0x00, 0x6a, 0x9c, 0x00, 0x00, 0x6a, 0xb4, - 0x00, 0x00, 0x6a, 0xcc, 0x00, 0x00, 0x6a, 0xf0, 0x00, 0x00, 0x6b, 0x10, - 0x00, 0x00, 0x6b, 0x34, 0x00, 0x00, 0x6b, 0x4c, 0x00, 0x00, 0x6b, 0x70, - 0x00, 0x00, 0x6b, 0x88, 0x00, 0x00, 0x6b, 0xa0, 0x00, 0x00, 0x6b, 0xb8, - 0x00, 0x00, 0x6b, 0xd0, 0x00, 0x00, 0x6b, 0xe8, 0x00, 0x00, 0x6c, 0x00, - 0x00, 0x00, 0x6c, 0x64, 0x00, 0x00, 0x6c, 0xd8, 0x00, 0x00, 0x6d, 0x98, - 0x00, 0x00, 0x6d, 0xa8, 0x00, 0x00, 0x6e, 0x0c, 0x00, 0x00, 0x6e, 0x64, - 0x00, 0x00, 0x6e, 0xd4, 0x00, 0x00, 0x6f, 0x60, 0x00, 0x00, 0x6f, 0xd4, - 0x00, 0x00, 0x70, 0x40, 0x00, 0x00, 0x70, 0x50, 0x00, 0x00, 0x70, 0xb4, - 0x00, 0x00, 0x71, 0x08, 0x00, 0x00, 0x71, 0x6c, 0x00, 0x00, 0x72, 0x18, - 0x00, 0x00, 0x72, 0x74, 0x00, 0x00, 0x73, 0x14, 0x00, 0x00, 0x73, 0xc8, - 0x00, 0x00, 0x74, 0x0c, 0x00, 0x00, 0x74, 0x78, 0x00, 0x00, 0x74, 0xfc, - 0x00, 0x00, 0x75, 0x58, 0x00, 0x00, 0x75, 0xd0, 0x00, 0x00, 0x76, 0x10, - 0x00, 0x00, 0x76, 0x5c, 0x00, 0x00, 0x76, 0xb8, 0x00, 0x00, 0x77, 0x0c, - 0x00, 0x00, 0x77, 0x54, 0x00, 0x00, 0x77, 0xa0, 0x00, 0x00, 0x78, 0x08, - 0x00, 0x00, 0x78, 0x4c, 0x00, 0x00, 0x78, 0x90, 0x00, 0x00, 0x78, 0xfc, - 0x00, 0x00, 0x79, 0x14, 0x00, 0x00, 0x79, 0x2c, 0x00, 0x00, 0x79, 0x90, - 0x00, 0x00, 0x79, 0xfc, 0x00, 0x00, 0x7a, 0x6c, 0x00, 0x00, 0x7a, 0xf0, - 0x00, 0x00, 0x7b, 0x5c, 0x00, 0x00, 0x7b, 0xd4, 0x00, 0x00, 0x7c, 0x4c, - 0x00, 0x00, 0x7c, 0x5c, 0x00, 0x00, 0x7c, 0xc8, 0x00, 0x00, 0x7d, 0x2c, - 0x00, 0x00, 0x7d, 0x68, 0x00, 0x00, 0x7d, 0xc4, 0x00, 0x00, 0x7e, 0x04, - 0x00, 0x00, 0x7e, 0x20, 0x00, 0x00, 0x7e, 0x3c, 0x00, 0x00, 0x7e, 0xa8, - 0x00, 0x00, 0x7e, 0xfc, 0x00, 0x00, 0x7f, 0x54, 0x00, 0x00, 0x7f, 0xb8, - 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x48, 0x00, 0x00, 0x80, 0xb4, - 0x00, 0x00, 0x81, 0x20, 0x00, 0x00, 0x81, 0x8c, 0x00, 0x00, 0x81, 0xf8, - 0x00, 0x00, 0x82, 0x64, 0x00, 0x00, 0x82, 0xd0, 0x00, 0x00, 0x83, 0x30, - 0x00, 0x00, 0x83, 0x94, 0x00, 0x00, 0x83, 0xe8, 0x00, 0x00, 0x84, 0x04, - 0x00, 0x00, 0x84, 0x20, 0x00, 0x00, 0x84, 0x64, 0x00, 0x00, 0x84, 0x74, - 0x00, 0x00, 0x84, 0x8c, 0x00, 0x00, 0x84, 0xa4, 0x00, 0x00, 0x84, 0xbc, - 0x00, 0x00, 0x84, 0xd4, 0x00, 0x00, 0x84, 0xec, 0x00, 0x00, 0x85, 0x04, - 0x00, 0x00, 0x85, 0x34, 0x00, 0x00, 0x85, 0x4c, 0x00, 0x00, 0x85, 0x6c, - 0x00, 0x00, 0x85, 0x8c, 0x00, 0x00, 0x85, 0xac, 0x00, 0x00, 0x85, 0xcc, - 0x00, 0x00, 0x85, 0xec, 0x00, 0x00, 0x86, 0x0c, 0x00, 0x00, 0x86, 0x2c, - 0x00, 0x00, 0x86, 0x44, 0x00, 0x00, 0x86, 0x54, 0x00, 0x00, 0x86, 0x74, - 0x00, 0x00, 0x86, 0x8c, 0x00, 0x00, 0x86, 0xac, 0x00, 0x00, 0x86, 0xc4, - 0x00, 0x00, 0x86, 0xdc, 0x00, 0x00, 0x86, 0xf4, 0x00, 0x00, 0x87, 0x0c, - 0x00, 0x00, 0x87, 0x24, 0x00, 0x00, 0x87, 0x3c, 0x00, 0x00, 0x87, 0x54, - 0x00, 0x00, 0x87, 0x6c, 0x00, 0x00, 0x87, 0x84, 0x00, 0x00, 0x87, 0x9c, - 0x00, 0x00, 0x87, 0xb4, 0x00, 0x00, 0x87, 0xcc, 0x00, 0x00, 0x87, 0xe4, - 0x00, 0x00, 0x87, 0xfc, 0x00, 0x00, 0x88, 0x14, 0x00, 0x00, 0x88, 0x2c, - 0x00, 0x00, 0x88, 0x90, 0x00, 0x00, 0x88, 0xa8, 0x00, 0x00, 0x88, 0xc0, - 0x00, 0x00, 0x88, 0xd8, 0x00, 0x00, 0x88, 0xf0, 0x00, 0x00, 0x89, 0x08, - 0x00, 0x00, 0x89, 0x20, 0x00, 0x00, 0x89, 0x38, 0x00, 0x00, 0x89, 0x50, - 0x00, 0x00, 0x89, 0x68, 0x00, 0x00, 0x89, 0x80, 0x00, 0x00, 0x89, 0x98, - 0x00, 0x00, 0x89, 0xb0, 0x00, 0x00, 0x89, 0xc8, 0x00, 0x00, 0x89, 0xe0, - 0x00, 0x00, 0x89, 0xf8, 0x00, 0x00, 0x8a, 0x10, 0x00, 0x00, 0x8a, 0x28, - 0x00, 0x00, 0x8a, 0x40, 0x00, 0x00, 0x8a, 0x58, 0x00, 0x00, 0x8a, 0x70, - 0x00, 0x00, 0x8a, 0x88, 0x00, 0x00, 0x8a, 0xa0, 0x00, 0x00, 0x8a, 0xb8, - 0x00, 0x00, 0x8a, 0xd0, 0x00, 0x00, 0x8a, 0xe8, 0x00, 0x00, 0x8b, 0x00, - 0x00, 0x00, 0x8b, 0x18, 0x00, 0x00, 0x8b, 0x30, 0x00, 0x00, 0x8b, 0x48, - 0x00, 0x00, 0x8b, 0x60, 0x00, 0x00, 0x8b, 0x78, 0x00, 0x00, 0x8b, 0x90, - 0x00, 0x00, 0x8b, 0xa8, 0x00, 0x00, 0x8b, 0xc0, 0x00, 0x00, 0x8c, 0x4c, - 0x00, 0x00, 0x8c, 0xe0, 0x00, 0x00, 0x8c, 0xf8, 0x00, 0x00, 0x8d, 0x10, - 0x00, 0x00, 0x8d, 0x54, 0x00, 0x00, 0x8d, 0xf4, 0x00, 0x00, 0x8e, 0x44, - 0x00, 0x00, 0x8e, 0x94, 0x00, 0x00, 0x8e, 0xac, 0x00, 0x00, 0x8e, 0xc4, - 0x00, 0x00, 0x8e, 0xdc, 0x00, 0x00, 0x8e, 0xf4, 0x00, 0x00, 0x8f, 0x14, - 0x00, 0x00, 0x8f, 0x2c, 0x00, 0x00, 0x8f, 0x4c, 0x00, 0x00, 0x8f, 0x64, - 0x00, 0x00, 0x8f, 0x7c, 0x00, 0x00, 0x8f, 0x94, 0x00, 0x00, 0x8f, 0xb4, - 0x00, 0x00, 0x8f, 0xcc, 0x00, 0x00, 0x8f, 0xe4, 0x00, 0x00, 0x8f, 0xfc, - 0x00, 0x00, 0x90, 0x60, 0x00, 0x00, 0x90, 0xec, 0x00, 0x00, 0x91, 0x60, - 0x00, 0x00, 0x91, 0xc0, 0x00, 0x00, 0x92, 0x5c, 0x00, 0x00, 0x92, 0xf8, - 0x00, 0x00, 0x93, 0x58, 0x00, 0x00, 0x93, 0xec, 0x00, 0x00, 0x94, 0x78, - 0x00, 0x00, 0x94, 0xb0, 0x00, 0x00, 0x94, 0xfc, 0x00, 0x00, 0x95, 0x9c, - 0x00, 0x00, 0x95, 0xf0, 0x00, 0x00, 0x96, 0x44, 0x00, 0x00, 0x96, 0xc0, - 0x00, 0x00, 0x97, 0x40, 0x00, 0x00, 0x97, 0x68, 0x00, 0x00, 0x97, 0xd4, - 0x00, 0x00, 0x98, 0x28, 0x00, 0x00, 0x98, 0xa4, 0x00, 0x00, 0x99, 0x34, - 0x00, 0x00, 0x99, 0xc4, 0x00, 0x00, 0x9a, 0x70, 0x00, 0x00, 0x9a, 0xf8, - 0x00, 0x00, 0x9b, 0x78, 0x00, 0x00, 0x9b, 0xec, 0x00, 0x00, 0x9c, 0x64, - 0x00, 0x00, 0x9c, 0xc8, 0x00, 0x00, 0x9d, 0x68, 0x00, 0x00, 0x9d, 0xf0, - 0x00, 0x00, 0x9e, 0xb8, 0x00, 0x00, 0x9f, 0x6c, 0x00, 0x00, 0xa0, 0x28, - 0x00, 0x00, 0xa0, 0xa8, 0x00, 0x00, 0xa0, 0xf0, 0x00, 0x00, 0xa1, 0x80, - 0x00, 0x00, 0xa1, 0xf4, 0x00, 0x00, 0xa2, 0x60, 0x00, 0x00, 0xa2, 0xcc, - 0x00, 0x00, 0xa3, 0x1c, 0x00, 0x00, 0xa3, 0x60, 0x00, 0x00, 0xa3, 0xbc, - 0x00, 0x00, 0xa4, 0x30, 0x00, 0x00, 0xa4, 0x80, 0x00, 0x00, 0xa4, 0xb4, - 0x00, 0x00, 0xa4, 0xe4, 0x00, 0x00, 0xa5, 0x58, 0x00, 0x00, 0xa5, 0xb8, - 0x00, 0x00, 0xa5, 0xec, 0x00, 0x00, 0xa6, 0x74, 0x00, 0x00, 0xa6, 0xdc, - 0x00, 0x00, 0xa7, 0x44, 0x00, 0x00, 0xa7, 0xc4, 0x00, 0x00, 0xa8, 0x24, - 0x00, 0x00, 0xa8, 0x88, 0x00, 0x00, 0xa8, 0xb8, 0x00, 0x00, 0xa9, 0x24, - 0x00, 0x00, 0xa9, 0x88, 0x00, 0x00, 0xaa, 0x18, 0x00, 0x00, 0xaa, 0xb0, - 0x00, 0x00, 0xaa, 0xec, 0x00, 0x00, 0xab, 0x28, 0x00, 0x00, 0xab, 0x78, - 0x00, 0x00, 0xab, 0xb8, 0x00, 0x00, 0xac, 0x0c, 0x00, 0x00, 0xac, 0x4c, - 0x00, 0x00, 0xac, 0x88, 0x00, 0x00, 0xac, 0xf8, 0x00, 0x00, 0xad, 0x68, - 0x00, 0x00, 0xae, 0x0c, 0x00, 0x00, 0xae, 0x4c, 0x00, 0x00, 0xae, 0xac, - 0x00, 0x00, 0xae, 0xf4, 0x00, 0x00, 0xaf, 0x58, 0x00, 0x00, 0xaf, 0x9c, - 0x00, 0x00, 0xaf, 0xe0, 0x00, 0x00, 0xb0, 0x48, 0x00, 0x00, 0xb0, 0xb8, - 0x00, 0x00, 0xb1, 0x24, 0x00, 0x00, 0xb1, 0x4c, 0x00, 0x00, 0xb1, 0x84, - 0x00, 0x00, 0xb1, 0xc4, 0x00, 0x00, 0xb1, 0xf4, 0x00, 0x00, 0xb2, 0x3c, - 0x00, 0x00, 0xb2, 0x98, 0x00, 0x00, 0xb3, 0x00, 0x00, 0x00, 0xb3, 0x90, - 0x00, 0x00, 0xb3, 0xec, 0x00, 0x00, 0xb4, 0x4c, 0x00, 0x00, 0xb4, 0xac, - 0x00, 0x00, 0xb5, 0x20, 0x00, 0x00, 0xb5, 0xa4, 0x00, 0x00, 0xb6, 0x3c, - 0x00, 0x00, 0xb6, 0xc4, 0x00, 0x00, 0xb7, 0x54, 0x00, 0x00, 0xb7, 0x84, - 0x00, 0x00, 0xb7, 0xe8, 0x00, 0x00, 0xb8, 0x20, 0x00, 0x00, 0xb8, 0x40, - 0x00, 0x00, 0xb8, 0xc4, 0x00, 0x00, 0xb9, 0x34, 0x00, 0x00, 0xb9, 0xa4, - 0x00, 0x00, 0xba, 0x20, 0x00, 0x00, 0xba, 0xec, 0x00, 0x00, 0xbb, 0x90, - 0x00, 0x00, 0xbc, 0x40, 0x00, 0x00, 0xbc, 0xcc, 0x00, 0x00, 0xbd, 0x88, - 0x00, 0x00, 0xbe, 0x14, 0x00, 0x00, 0xbe, 0xc0, 0x00, 0x00, 0xbe, 0xfc, - 0x00, 0x00, 0xbf, 0x60, 0x00, 0x00, 0xbf, 0xa0, 0x00, 0x00, 0xbf, 0xf0, - 0x00, 0x00, 0xc0, 0x58, 0x00, 0x00, 0xc0, 0xbc, 0x00, 0x00, 0xc1, 0x1c, - 0x00, 0x00, 0xc1, 0x54, 0x00, 0x00, 0xc1, 0x94, 0x00, 0x00, 0xc1, 0xd4, - 0x00, 0x00, 0xc2, 0x34, 0x00, 0x00, 0xc2, 0xa0, 0x00, 0x00, 0xc2, 0xd8, - 0x00, 0x00, 0xc3, 0x18, 0x00, 0x00, 0xc3, 0x28, 0x00, 0x00, 0xc3, 0x38, - 0x00, 0x00, 0xc3, 0x48, 0x00, 0x00, 0xc3, 0x58, 0x00, 0x00, 0xc3, 0x94, - 0x00, 0x00, 0xc3, 0xd0, 0x00, 0x00, 0xc4, 0x2c, 0x00, 0x00, 0xc4, 0x88, - 0x00, 0x00, 0xc4, 0xe4, 0x00, 0x00, 0xc5, 0x40, 0x00, 0x00, 0xc5, 0x70, - 0x00, 0x00, 0xc5, 0x80, 0x00, 0x00, 0xc5, 0xb0, 0x00, 0x00, 0xc5, 0xc0, - 0x00, 0x00, 0xc5, 0xd4, 0x00, 0x00, 0xc5, 0xe8, 0x00, 0x00, 0xc6, 0x10, - 0x00, 0x00, 0xc6, 0x2c, 0x00, 0x00, 0xc6, 0x40, 0x00, 0x00, 0xc6, 0x54, - 0x00, 0x00, 0xc6, 0x80, 0x00, 0x00, 0xc6, 0x9c, 0x00, 0x00, 0xc6, 0xac, - 0x00, 0x00, 0xc6, 0xbc, 0x00, 0x00, 0xc7, 0x60, 0x00, 0x00, 0xc7, 0xc4, - 0x00, 0x00, 0xc8, 0xdc, 0x00, 0x00, 0xc8, 0xec, 0x00, 0x00, 0xc9, 0x28, - 0x00, 0x00, 0xc9, 0x7c, 0x00, 0x00, 0xc9, 0xb0, 0x00, 0x00, 0xca, 0x2c, - 0x00, 0x00, 0xca, 0x64, 0x00, 0x00, 0xca, 0xc0, 0x00, 0x00, 0xca, 0xe0, - 0x00, 0x00, 0xcb, 0x04, 0x00, 0x00, 0xcb, 0x2c, 0x00, 0x00, 0xcb, 0x54, - 0x00, 0x00, 0xcb, 0x74, 0x00, 0x00, 0xcb, 0x84, 0x00, 0x00, 0xcb, 0x94, - 0x00, 0x00, 0xcb, 0xa4, 0x00, 0x00, 0xcb, 0xb4, 0x00, 0x00, 0xcb, 0xc4, - 0x00, 0x00, 0xcb, 0xd4, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0xcc, 0x10, - 0x00, 0x00, 0xcc, 0x64, 0x00, 0x00, 0xcc, 0x94, 0x00, 0x00, 0xcc, 0xa4, - 0x00, 0x00, 0xcc, 0xec, 0x00, 0x00, 0xcc, 0xfc, 0x00, 0x00, 0xcd, 0x4c, - 0x00, 0x00, 0xcd, 0x5c, 0x00, 0x00, 0xcd, 0x78, 0x00, 0x00, 0xcd, 0x94, - 0x00, 0x00, 0xcd, 0xc0, 0x00, 0x00, 0xcd, 0xd8, 0x00, 0x00, 0xce, 0x10, - 0x00, 0x00, 0xce, 0x2c, 0x00, 0x00, 0xce, 0x54, 0x00, 0x00, 0xce, 0x78, - 0x00, 0x00, 0xce, 0x94, 0x00, 0x00, 0xce, 0xa8, 0x00, 0x00, 0xce, 0xbc, - 0x00, 0x00, 0xce, 0xe0, 0x00, 0x00, 0xcf, 0x04, 0x00, 0x00, 0xcf, 0x24, - 0x00, 0x00, 0xcf, 0x68, 0x00, 0x00, 0xcf, 0x98, 0x00, 0x00, 0xcf, 0xbc, - 0x00, 0x00, 0xcf, 0xe0, 0x00, 0x00, 0xd0, 0x0c, 0x00, 0x00, 0xd0, 0x28, - 0x00, 0x00, 0xd0, 0x58, 0x00, 0x00, 0xd0, 0x88, 0x00, 0x00, 0xd0, 0xb4, - 0x00, 0x00, 0xd0, 0xf4, 0x00, 0x00, 0xd1, 0x60, 0x00, 0x00, 0xd1, 0x8c, - 0x00, 0x00, 0xd2, 0x08, 0x00, 0x00, 0xd2, 0x18, 0x00, 0x00, 0xd2, 0x34, - 0x00, 0x00, 0xd2, 0x58, 0x00, 0x00, 0xd2, 0xa0, 0x00, 0x00, 0xd2, 0xe0, - 0x00, 0x00, 0xd3, 0x1c, 0x00, 0x00, 0xd3, 0x70, 0x00, 0x00, 0xd3, 0xa4, - 0x00, 0x00, 0xd4, 0x84, 0x00, 0x00, 0xd4, 0xb0, 0x00, 0x00, 0xd4, 0xc0, - 0x00, 0x00, 0xd4, 0xd0, 0x00, 0x00, 0xd4, 0xe0, 0x00, 0x00, 0xd4, 0xfc, - 0x00, 0x00, 0xd5, 0x14, 0x00, 0x00, 0xd5, 0x30, 0x00, 0x00, 0xd5, 0x4c, - 0x00, 0x00, 0xd5, 0x7c, 0x00, 0x00, 0xd5, 0xa0, 0x00, 0x00, 0xd5, 0xcc, - 0x00, 0x00, 0xd6, 0x14, 0x00, 0x00, 0xd6, 0x48, 0x00, 0x00, 0xd6, 0xa8, - 0x00, 0x00, 0xd6, 0xc0, 0x00, 0x00, 0xd6, 0xd0, 0x00, 0x00, 0xd6, 0xe4, - 0x00, 0x00, 0xd7, 0x24, 0x00, 0x00, 0xd7, 0x44, 0x00, 0x00, 0xd7, 0x60, - 0x00, 0x00, 0xd7, 0x88, 0x00, 0x00, 0xd7, 0x98, 0x00, 0x00, 0xd7, 0xa8, - 0x00, 0x00, 0xd7, 0xc0, 0x00, 0x00, 0xd7, 0xd8, 0x00, 0x00, 0xd7, 0xe8, - 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00, 0xd8, 0x18, 0x00, 0x00, 0xd8, 0x30, - 0x00, 0x00, 0xd8, 0x48, 0x00, 0x00, 0xd8, 0x60, 0x00, 0x00, 0xd8, 0x78, - 0x00, 0x00, 0xd8, 0x90, 0x00, 0x00, 0xd8, 0xa0, 0x00, 0x00, 0xd8, 0xb0, - 0x00, 0x00, 0xd8, 0xc0, 0x00, 0x00, 0xd9, 0x20, 0x00, 0x00, 0xd9, 0x30, - 0x00, 0x00, 0xd9, 0x40, 0x00, 0x00, 0xd9, 0x50, 0x00, 0x00, 0xd9, 0xf0, - 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, 0xda, 0x10, 0x00, 0x00, 0xda, 0x68, - 0x00, 0x00, 0xda, 0x78, 0x00, 0x00, 0xda, 0x88, 0x00, 0x00, 0xda, 0xe8, - 0x00, 0x00, 0xda, 0xf8, 0x00, 0x00, 0xdb, 0x08, 0x00, 0x00, 0xdb, 0x18, - 0x00, 0x00, 0xdb, 0x8c, 0x00, 0x00, 0xdb, 0x9c, 0x00, 0x00, 0xdb, 0xac, - 0x00, 0x00, 0xdc, 0x8c, 0x00, 0x00, 0xdc, 0x9c, 0x00, 0x00, 0xdd, 0x40, - 0x00, 0x00, 0xdd, 0xe8, 0x00, 0x00, 0xde, 0x00, 0x00, 0x00, 0xde, 0x18, - 0x00, 0x00, 0xde, 0x30, 0x00, 0x00, 0xde, 0x48, 0x00, 0x00, 0xde, 0x60, - 0x00, 0x00, 0xde, 0x78, 0x00, 0x00, 0xde, 0x90, 0x00, 0x00, 0xdf, 0x20, - 0x00, 0x00, 0xdf, 0x94, 0x00, 0x00, 0xdf, 0xd0, 0x00, 0x00, 0xe0, 0x74, - 0x00, 0x00, 0xe0, 0x84, 0x00, 0x00, 0xe0, 0xec, 0x00, 0x00, 0xe1, 0x5c, - 0x00, 0x00, 0xe2, 0x04, 0x00, 0x00, 0xe2, 0x5c, 0x00, 0x00, 0xe2, 0x6c, - 0x00, 0x00, 0xe2, 0xac, 0x00, 0x00, 0xe2, 0xbc, 0x00, 0x00, 0xe3, 0x0c, - 0x00, 0x00, 0xe3, 0x88, 0x00, 0x00, 0xe3, 0x98, 0x00, 0x00, 0xe3, 0xe4, - 0x00, 0x00, 0xe4, 0x74, 0x00, 0x00, 0xe4, 0xe8, 0x00, 0x00, 0xe5, 0x7c, - 0x00, 0x00, 0xe5, 0xdc, 0x00, 0x00, 0xe6, 0x40, 0x00, 0x00, 0xe7, 0x14, - 0x00, 0x00, 0xe7, 0x70, 0x00, 0x00, 0xe7, 0xcc, 0x00, 0x00, 0xe8, 0x50, - 0x00, 0x00, 0xe8, 0x68, 0x00, 0x00, 0xe8, 0x80, 0x00, 0x00, 0xe8, 0x98, - 0x00, 0x00, 0xe8, 0xb0, 0x00, 0x00, 0xe8, 0xc8, 0x00, 0x00, 0xe9, 0x54, - 0x00, 0x00, 0xe9, 0xd8, 0x00, 0x00, 0xea, 0x40, 0x00, 0x00, 0xea, 0x58, - 0x00, 0x00, 0xea, 0x70, 0x00, 0x00, 0xea, 0xf8, 0x00, 0x00, 0xeb, 0x6c, - 0x00, 0x00, 0xec, 0x0c, 0x00, 0x00, 0xec, 0x74, 0x00, 0x00, 0xec, 0xd8, - 0x00, 0x00, 0xed, 0x48, 0x00, 0x00, 0xed, 0xbc, 0x00, 0x00, 0xed, 0xcc, - 0x00, 0x00, 0xee, 0x38, 0x00, 0x00, 0xee, 0x94, 0x00, 0x00, 0xee, 0xc0, - 0x00, 0x00, 0xef, 0x34, 0x00, 0x00, 0xef, 0x90, 0x00, 0x00, 0xf0, 0x2c, - 0x00, 0x00, 0xf0, 0x9c, 0x00, 0x00, 0xf0, 0xac, 0x00, 0x00, 0xf0, 0xbc, - 0x00, 0x00, 0xf1, 0x28, 0x00, 0x00, 0xf1, 0x98, 0x00, 0x00, 0xf2, 0x08, - 0x00, 0x00, 0xf2, 0x18, 0x00, 0x00, 0xf2, 0x28, 0x00, 0x00, 0xf2, 0x38, - 0x00, 0x00, 0xf2, 0x74, 0x00, 0x00, 0xf2, 0xac, 0x00, 0x00, 0xf3, 0x1c, - 0x00, 0x00, 0xf3, 0x78, 0x00, 0x00, 0xf3, 0x90, 0x00, 0x00, 0xf3, 0xa8, - 0x00, 0x00, 0xf3, 0xc0, 0x00, 0x00, 0xf3, 0xd8, 0x00, 0x00, 0xf4, 0x68, - 0x00, 0x00, 0xf4, 0x80, 0x00, 0x00, 0xf5, 0x28, 0x00, 0x00, 0xf5, 0x38, - 0x00, 0x00, 0xf5, 0x48, 0x00, 0x00, 0xf5, 0x6c, 0x00, 0x00, 0xf5, 0x7c, - 0x00, 0x00, 0xf5, 0xe0, 0x00, 0x00, 0xf6, 0x3c, 0x00, 0x00, 0xf6, 0xac, - 0x00, 0x00, 0xf6, 0xc4, 0x00, 0x00, 0xf6, 0xdc, 0x00, 0x00, 0xf6, 0xf4, - 0x00, 0x00, 0xf7, 0x24, 0x00, 0x00, 0xf7, 0x34, 0x00, 0x00, 0xf7, 0xbc, - 0x00, 0x00, 0xf7, 0xcc, 0x00, 0x00, 0xf8, 0x04, 0x00, 0x00, 0xf8, 0x94, - 0x00, 0x00, 0xf8, 0xa4, 0x00, 0x00, 0xf9, 0x70, 0x00, 0x00, 0xf9, 0x80, - 0x00, 0x00, 0xf9, 0xec, 0x00, 0x00, 0xfa, 0x04, 0x00, 0x00, 0xfa, 0x14, - 0x00, 0x00, 0xfa, 0x78, 0x00, 0x00, 0xfa, 0x88, 0x00, 0x00, 0xfa, 0x98, - 0x00, 0x00, 0xfa, 0xa8, 0x00, 0x00, 0xfa, 0xec, 0x00, 0x00, 0xfa, 0xfc, - 0x00, 0x00, 0xfb, 0x0c, 0x00, 0x00, 0xfb, 0x1c, 0x00, 0x00, 0xfb, 0xac, - 0x00, 0x00, 0xfc, 0x88, 0x00, 0x00, 0xfc, 0x98, 0x00, 0x00, 0xfc, 0xec, - 0x00, 0x00, 0xfd, 0x50, 0x00, 0x00, 0xfd, 0xa4, 0x00, 0x00, 0xfe, 0x0c, - 0x00, 0x00, 0xfe, 0x80, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x74, - 0x00, 0x01, 0x00, 0x1c, 0x00, 0x01, 0x00, 0xd4, 0x00, 0x01, 0x01, 0x70, - 0x00, 0x01, 0x01, 0x80, 0x00, 0x01, 0x02, 0x4c, 0x00, 0x01, 0x02, 0xe4, - 0x00, 0x01, 0x03, 0x1c, 0x00, 0x01, 0x03, 0xa4, 0x00, 0x01, 0x03, 0xb4, - 0x00, 0x01, 0x04, 0x80, 0x00, 0x01, 0x04, 0x90, 0x00, 0x01, 0x04, 0xfc, - 0x00, 0x01, 0x05, 0x14, 0x00, 0x01, 0x05, 0x24, 0x00, 0x01, 0x05, 0x88, - 0x00, 0x01, 0x06, 0x10, 0x00, 0x01, 0x06, 0x64, 0x00, 0x01, 0x06, 0x74, - 0x00, 0x01, 0x06, 0xb8, 0x00, 0x01, 0x06, 0xc8, 0x00, 0x01, 0x06, 0xd8, - 0x00, 0x01, 0x07, 0x1c, 0x00, 0x01, 0x07, 0x2c, 0x00, 0x01, 0x08, 0x04, - 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x68, 0x00, 0x01, 0x08, 0xcc, - 0x00, 0x01, 0x09, 0x20, 0x00, 0x01, 0x09, 0x84, 0x00, 0x01, 0x09, 0xf8, - 0x00, 0x01, 0x0a, 0x74, 0x00, 0x01, 0x0a, 0xe4, 0x00, 0x01, 0x0b, 0x98, - 0x00, 0x01, 0x0c, 0x40, 0x00, 0x01, 0x0c, 0xd4, 0x00, 0x01, 0x0c, 0xec, - 0x00, 0x01, 0x0d, 0x04, 0x00, 0x01, 0x0d, 0x68, 0x00, 0x01, 0x0d, 0x80, - 0x00, 0x01, 0x0e, 0x38, 0x00, 0x01, 0x0e, 0x48, 0x00, 0x01, 0x0e, 0x58, - 0x00, 0x01, 0x0e, 0x78, 0x00, 0x01, 0x0e, 0x88, 0x00, 0x01, 0x0e, 0xec, - 0x00, 0x01, 0x0f, 0x3c, 0x00, 0x01, 0x0f, 0x94, 0x00, 0x01, 0x0f, 0xac, - 0x00, 0x01, 0x0f, 0xc4, 0x00, 0x01, 0x0f, 0xdc, 0x00, 0x01, 0x10, 0x0c, - 0x00, 0x01, 0x10, 0x64, 0x00, 0x01, 0x10, 0xbc, 0x00, 0x01, 0x10, 0xcc, - 0x00, 0x01, 0x10, 0xdc, 0x00, 0x01, 0x11, 0x20, 0x00, 0x01, 0x11, 0x64, - 0x00, 0x01, 0x11, 0x98, 0x00, 0x01, 0x11, 0xcc, 0x00, 0x01, 0x12, 0x28, - 0x00, 0x01, 0x12, 0x88, 0x00, 0x01, 0x12, 0xe4, 0x00, 0x01, 0x13, 0x40, - 0x00, 0x01, 0x13, 0x58, 0x00, 0x01, 0x13, 0x70, 0x00, 0x01, 0x13, 0xb0, - 0x00, 0x01, 0x13, 0xf0, 0x00, 0x01, 0x14, 0x2c, 0x00, 0x01, 0x14, 0x68, - 0x00, 0x01, 0x14, 0x9c, 0x00, 0x01, 0x14, 0xd0, 0x00, 0x01, 0x14, 0xe8, - 0x00, 0x01, 0x15, 0x00, 0x00, 0x01, 0x15, 0x30, 0x00, 0x01, 0x15, 0x60, - 0x00, 0x01, 0x15, 0x70, 0x00, 0x01, 0x15, 0xa0, 0x00, 0x01, 0x15, 0xe4, - 0x00, 0x01, 0x16, 0x20, 0x00, 0x01, 0x16, 0x68, 0x00, 0x01, 0x16, 0xb0, - 0x00, 0x01, 0x17, 0x10, 0x00, 0x01, 0x17, 0x20, 0x00, 0x01, 0x17, 0x30, - 0x00, 0x01, 0x17, 0x48, 0x00, 0x01, 0x17, 0x60, 0x00, 0x01, 0x17, 0xc0, - 0x00, 0x01, 0x18, 0x24, 0x00, 0x01, 0x18, 0x6c, 0x00, 0x01, 0x18, 0xb4, - 0x00, 0x01, 0x19, 0x1c, 0x00, 0x01, 0x19, 0x70, 0x00, 0x01, 0x19, 0x8c, - 0x00, 0x01, 0x19, 0xbc, 0x00, 0x01, 0x19, 0xd4, 0x00, 0x01, 0x1a, 0x0c, - 0x00, 0x01, 0x1a, 0x24, 0x00, 0x01, 0x1a, 0x34, 0x00, 0x01, 0x1a, 0x44, - 0x00, 0x01, 0x1a, 0x5c, 0x00, 0x01, 0x1a, 0x74, 0x00, 0x01, 0x1a, 0x84, - 0x00, 0x01, 0x1a, 0x94, 0x00, 0x01, 0x1a, 0xac, 0x00, 0x01, 0x1a, 0xc4, - 0x00, 0x01, 0x1a, 0xdc, 0x00, 0x01, 0x1a, 0xf4, 0x00, 0x01, 0x1b, 0x0c, - 0x00, 0x01, 0x1b, 0x24, 0x00, 0x01, 0x1b, 0x34, 0x00, 0x01, 0x1b, 0x44, - 0x00, 0x01, 0x1b, 0x5c, 0x00, 0x01, 0x1b, 0x74, 0x00, 0x01, 0x1b, 0x8c, - 0x00, 0x01, 0x1b, 0xa4, 0x00, 0x01, 0x1b, 0xdc, 0x00, 0x01, 0x1c, 0x08, - 0x00, 0x01, 0x1c, 0x18, 0x00, 0x01, 0x1c, 0x28, 0x00, 0x01, 0x1c, 0x40, - 0x00, 0x01, 0x1c, 0x58, 0x00, 0x01, 0x1c, 0x70, 0x00, 0x01, 0x1c, 0x88, - 0x00, 0x01, 0x1c, 0xa0, 0x00, 0x01, 0x1c, 0xb8, 0x00, 0x01, 0x1c, 0xd0, - 0x00, 0x01, 0x1c, 0xe8, 0x00, 0x01, 0x1d, 0x00, 0x00, 0x01, 0x1d, 0x18, - 0x00, 0x01, 0x1d, 0x30, 0x00, 0x01, 0x1d, 0x48, 0x00, 0x01, 0x1d, 0x74, - 0x00, 0x01, 0x1d, 0xa0, 0x00, 0x01, 0x1d, 0xb8, 0x00, 0x01, 0x1d, 0xd0, - 0x00, 0x01, 0x1d, 0xe0, 0x00, 0x01, 0x1d, 0xf0, 0x00, 0x01, 0x1e, 0x00, - 0x00, 0x01, 0x1e, 0x10, 0x00, 0x01, 0x1e, 0x20, 0x00, 0x01, 0x1e, 0x30, - 0x00, 0x01, 0x1e, 0xac, 0x00, 0x01, 0x1f, 0x04, 0x00, 0x01, 0x1f, 0x78, - 0x00, 0x01, 0x1f, 0xd0, 0x00, 0x01, 0x20, 0x28, 0x00, 0x01, 0x20, 0xa0, - 0x00, 0x01, 0x20, 0xcc, 0x00, 0x01, 0x21, 0x20, 0x00, 0x01, 0x21, 0xc4, - 0x00, 0x01, 0x22, 0x38, 0x00, 0x01, 0x22, 0x88, 0x00, 0x01, 0x22, 0xa8, - 0x00, 0x01, 0x23, 0x04, 0x00, 0x01, 0x23, 0xb8, 0x00, 0x01, 0x24, 0x08, - 0x00, 0x01, 0x24, 0x64, 0x00, 0x01, 0x25, 0x10, 0x00, 0x01, 0x25, 0x64, - 0x00, 0x01, 0x25, 0xdc, 0x00, 0x01, 0x26, 0x30, 0x00, 0x01, 0x26, 0xd0, - 0x00, 0x01, 0x27, 0x24, 0x00, 0x01, 0x27, 0xac, 0x00, 0x01, 0x27, 0xf8, - 0x00, 0x01, 0x28, 0x6c, 0x00, 0x01, 0x28, 0xc4, 0x00, 0x01, 0x29, 0x84, - 0x00, 0x01, 0x29, 0xdc, 0x00, 0x01, 0x2a, 0x2c, 0x00, 0x01, 0x2a, 0x84, - 0x00, 0x01, 0x2b, 0x24, 0x00, 0x01, 0x2b, 0x74, 0x00, 0x01, 0x2c, 0x34, - 0x00, 0x01, 0x2c, 0x5c, 0x00, 0x01, 0x2c, 0xe4, 0x00, 0x01, 0x2d, 0x6c, - 0x00, 0x01, 0x2d, 0x7c, 0x00, 0x01, 0x2e, 0x30, 0x00, 0x01, 0x2e, 0x40, - 0x00, 0x01, 0x2e, 0x64, 0x00, 0x01, 0x2e, 0x74, 0x00, 0x01, 0x2e, 0xbc, - 0x00, 0x01, 0x2e, 0xcc, 0x00, 0x01, 0x2f, 0x48, 0x00, 0x01, 0x2f, 0x68, - 0x00, 0x01, 0x2f, 0xdc, 0x00, 0x01, 0x30, 0x28, 0x00, 0x01, 0x30, 0x90, - 0x00, 0x01, 0x30, 0xdc, 0x00, 0x01, 0x31, 0x28, 0x00, 0x01, 0x31, 0x8c, - 0x00, 0x01, 0x31, 0xb8, 0x00, 0x01, 0x32, 0x00, 0x00, 0x01, 0x32, 0xa4, - 0x00, 0x01, 0x33, 0x18, 0x00, 0x01, 0x33, 0x58, 0x00, 0x01, 0x33, 0x78, - 0x00, 0x01, 0x33, 0xf8, 0x00, 0x01, 0x34, 0x88, 0x00, 0x01, 0x34, 0xcc, - 0x00, 0x01, 0x34, 0xdc, 0x00, 0x01, 0x35, 0xa0, 0x00, 0x01, 0x35, 0xe8, - 0x00, 0x01, 0x36, 0x98, 0x00, 0x01, 0x36, 0xe0, 0x00, 0x01, 0x37, 0x0c, - 0x00, 0x01, 0x37, 0x54, 0x00, 0x01, 0x37, 0xdc, 0x00, 0x01, 0x37, 0xec, - 0x00, 0x01, 0x38, 0x78, 0x00, 0x01, 0x38, 0xf0, 0x00, 0x01, 0x39, 0xb0, - 0x00, 0x01, 0x3a, 0x1c, 0x00, 0x01, 0x3a, 0x2c, 0x00, 0x01, 0x3a, 0x74, - 0x00, 0x01, 0x3a, 0xf4, 0x00, 0x01, 0x3b, 0x38, 0x00, 0x01, 0x3b, 0x48, - 0x00, 0x01, 0x3b, 0x68, 0x00, 0x01, 0x3b, 0xec, 0x00, 0x01, 0x3c, 0x60, - 0x00, 0x01, 0x3c, 0x70, 0x00, 0x01, 0x3d, 0x14, 0x00, 0x01, 0x3d, 0x5c, - 0x00, 0x01, 0x3d, 0x80, 0x00, 0x01, 0x3d, 0xac, 0x00, 0x01, 0x3e, 0x48, - 0x00, 0x01, 0x3e, 0xf4, 0x00, 0x01, 0x3f, 0x34, 0x00, 0x01, 0x3f, 0x80, - 0x00, 0x01, 0x3f, 0xa0, 0x00, 0x01, 0x3f, 0xfc, 0x00, 0x01, 0x40, 0x2c, - 0x00, 0x01, 0x40, 0x9c, 0x00, 0x01, 0x41, 0x0c, 0x00, 0x01, 0x41, 0x24, - 0x00, 0x01, 0x41, 0x3c, 0x00, 0x01, 0x41, 0x54, 0x00, 0x01, 0x41, 0x6c, - 0x00, 0x01, 0x41, 0x84, 0x00, 0x01, 0x41, 0xa0, 0x00, 0x01, 0x41, 0xb8, - 0x00, 0x01, 0x41, 0xd0, 0x00, 0x01, 0x41, 0xe8, 0x00, 0x01, 0x42, 0x00, - 0x00, 0x01, 0x42, 0x18, 0x00, 0x01, 0x42, 0x84, 0x00, 0x01, 0x42, 0x9c, - 0x00, 0x01, 0x42, 0xf0, 0x00, 0x01, 0x43, 0x08, 0x00, 0x01, 0x43, 0x4c, - 0x00, 0x01, 0x43, 0x64, 0x00, 0x01, 0x44, 0x24, 0x00, 0x01, 0x44, 0x3c, - 0x00, 0x01, 0x44, 0xf0, 0x00, 0x01, 0x45, 0x08, 0x00, 0x01, 0x45, 0x6c, - 0x00, 0x01, 0x45, 0x84, 0x00, 0x01, 0x46, 0x04, 0x00, 0x01, 0x46, 0x1c, - 0x00, 0x01, 0x46, 0x34, 0x00, 0x01, 0x46, 0x4c, 0x00, 0x01, 0x46, 0x64, - 0x00, 0x01, 0x47, 0x20, 0x00, 0x01, 0x47, 0x7c, 0x00, 0x01, 0x48, 0x08, - 0x00, 0x01, 0x48, 0x20, 0x00, 0x01, 0x48, 0x88, 0x00, 0x01, 0x49, 0x08, - 0x00, 0x01, 0x49, 0xac, 0x00, 0x01, 0x49, 0xc4, 0x00, 0x01, 0x49, 0xf0, - 0x00, 0x01, 0x4a, 0x90, 0x00, 0x01, 0x4a, 0xbc, 0x00, 0x01, 0x4a, 0xd8, - 0x00, 0x01, 0x4b, 0x68, 0x00, 0x01, 0x4b, 0x84, 0x00, 0x01, 0x4c, 0x08, - 0x00, 0x01, 0x4c, 0x4c, 0x00, 0x01, 0x4c, 0x90, 0x00, 0x01, 0x4c, 0xa0, - 0x00, 0x01, 0x4c, 0xb4, 0x00, 0x01, 0x4c, 0xdc, 0x00, 0x01, 0x4c, 0xf8, - 0x00, 0x01, 0x4d, 0x28, 0x00, 0x01, 0x4d, 0x80, 0x00, 0x01, 0x4d, 0xfc, - 0x00, 0x01, 0x4e, 0x80, 0x00, 0x01, 0x4e, 0xec, 0x00, 0x01, 0x4f, 0x34, - 0x00, 0x01, 0x4f, 0x84, 0x00, 0x01, 0x4f, 0xd4, 0x00, 0x01, 0x50, 0x54, - 0x00, 0x01, 0x50, 0x88, 0x00, 0x01, 0x50, 0xc8, 0x00, 0x01, 0x50, 0xec, - 0x00, 0x01, 0x51, 0x20, 0x00, 0x01, 0x51, 0x78, 0x00, 0x01, 0x51, 0x90, - 0x00, 0x01, 0x51, 0xa8, 0x00, 0x01, 0x51, 0xc0, 0x00, 0x01, 0x51, 0xd8, - 0x00, 0x01, 0x51, 0xf0, 0x00, 0x01, 0x52, 0x08, 0x00, 0x01, 0x52, 0x20, - 0x00, 0x01, 0x52, 0x38, 0x00, 0x01, 0x52, 0x50, 0x00, 0x01, 0x52, 0x68, - 0x00, 0x01, 0x52, 0x80, 0x00, 0x01, 0x52, 0x98, 0x00, 0x01, 0x52, 0xb0, - 0x00, 0x01, 0x53, 0x38, 0x00, 0x01, 0x53, 0x50, 0x00, 0x01, 0x54, 0x20, - 0x00, 0x01, 0x54, 0x30, 0x00, 0x01, 0x54, 0x40, 0x00, 0x01, 0x54, 0x50, - 0x00, 0x01, 0x54, 0x60, 0x00, 0x01, 0x54, 0x70, 0x00, 0x01, 0x54, 0xf0, - 0x00, 0x01, 0x55, 0x74, 0x00, 0x01, 0x55, 0xdc, 0x00, 0x01, 0x55, 0xec, - 0x00, 0x01, 0x55, 0xfc, 0x00, 0x01, 0x56, 0x0c, 0x00, 0x01, 0x56, 0xcc, - 0x00, 0x01, 0x57, 0x5c, 0x00, 0x01, 0x58, 0x14, 0x00, 0x01, 0x58, 0x84, - 0x00, 0x01, 0x59, 0x04, 0x00, 0x01, 0x59, 0xb8, 0x00, 0x01, 0x5a, 0x4c, - 0x00, 0x01, 0x5a, 0xd8, 0x00, 0x01, 0x5b, 0x58, 0x00, 0x01, 0x5b, 0xc8, - 0x00, 0x01, 0x5c, 0x88, 0x00, 0x01, 0x5c, 0xf0, 0x00, 0x01, 0x5d, 0x54, - 0x00, 0x01, 0x5d, 0xb4, 0x00, 0x01, 0x5e, 0x8c, 0x00, 0x01, 0x5f, 0x18, - 0x00, 0x01, 0x5f, 0xa8, 0x00, 0x01, 0x60, 0x38, 0x00, 0x01, 0x60, 0x84, - 0x00, 0x01, 0x61, 0x18, 0x00, 0x01, 0x61, 0xb0, 0x00, 0x01, 0x62, 0x4c, - 0x00, 0x01, 0x62, 0xbc, 0x00, 0x01, 0x63, 0x7c, 0x00, 0x01, 0x64, 0x28, - 0x00, 0x01, 0x64, 0xc4, 0x00, 0x01, 0x65, 0x7c, 0x00, 0x01, 0x65, 0xfc, - 0x00, 0x01, 0x66, 0x18, 0x00, 0x01, 0x66, 0x78, 0x00, 0x01, 0x66, 0xc4, - 0x00, 0x01, 0x66, 0xdc, 0x00, 0x01, 0x67, 0x20, 0x00, 0x01, 0x67, 0x6c, - 0x00, 0x01, 0x67, 0xbc, 0x00, 0x01, 0x68, 0x14, 0x00, 0x01, 0x68, 0x5c, - 0x00, 0x01, 0x68, 0xac, 0x00, 0x01, 0x69, 0x10, 0x00, 0x01, 0x69, 0x64, - 0x00, 0x01, 0x69, 0x80, 0x00, 0x01, 0x69, 0xe0, 0x00, 0x01, 0x6a, 0x7c, - 0x00, 0x01, 0x6a, 0xa8, 0x00, 0x01, 0x6a, 0xbc, 0x00, 0x01, 0x6a, 0xec, - 0x00, 0x01, 0x6b, 0x40, 0x00, 0x01, 0x6b, 0xa4, 0x00, 0x01, 0x6c, 0x20, - 0x00, 0x01, 0x6c, 0xac, 0x00, 0x01, 0x6d, 0x08, 0x00, 0x01, 0x6d, 0x84, - 0x00, 0x01, 0x6e, 0x00, 0x00, 0x01, 0x6e, 0x78, 0x00, 0x01, 0x6e, 0xc4, - 0x00, 0x01, 0x6f, 0x2c, 0x00, 0x01, 0x6f, 0x90, 0x00, 0x01, 0x6f, 0xf4, - 0x00, 0x01, 0x70, 0x58, 0x00, 0x01, 0x70, 0xc4, 0x00, 0x01, 0x71, 0x34, - 0x00, 0x01, 0x71, 0x90, 0x00, 0x01, 0x72, 0x10, 0x00, 0x01, 0x72, 0x60, - 0x00, 0x01, 0x72, 0xbc, 0x00, 0x01, 0x73, 0x40, 0x00, 0x01, 0x73, 0xe0, - 0x00, 0x01, 0x74, 0x48, 0x00, 0x01, 0x74, 0xd0, 0x00, 0x01, 0x75, 0x2c, - 0x00, 0x01, 0x75, 0xac, 0x00, 0x01, 0x76, 0x1c, 0x00, 0x01, 0x76, 0x94, - 0x00, 0x01, 0x76, 0xe4, 0x00, 0x01, 0x77, 0x64, 0x00, 0x01, 0x77, 0xf8, - 0x00, 0x01, 0x78, 0x48, 0x00, 0x01, 0x78, 0xb4, 0x00, 0x01, 0x79, 0x34, - 0x00, 0x01, 0x79, 0xec, 0x00, 0x01, 0x7a, 0x54, 0x00, 0x01, 0x7a, 0xc0, - 0x00, 0x01, 0x7b, 0x38, 0x00, 0x01, 0x7b, 0xbc, 0x00, 0x01, 0x7c, 0x44, - 0x00, 0x01, 0x7c, 0xb8, 0x00, 0x01, 0x7d, 0x1c, 0x00, 0x01, 0x7d, 0x8c, - 0x00, 0x01, 0x7d, 0xf0, 0x00, 0x01, 0x7e, 0x24, 0x00, 0x01, 0x7e, 0x74, - 0x00, 0x01, 0x7f, 0x34, 0x00, 0x01, 0x7f, 0xc0, 0x00, 0x01, 0x7f, 0xf8, - 0x00, 0x01, 0x80, 0xa0, 0x00, 0x01, 0x80, 0xd4, 0x00, 0x01, 0x81, 0x08, - 0x00, 0x01, 0x81, 0x4c, 0x00, 0x01, 0x81, 0xa8, 0x00, 0x01, 0x82, 0x10, - 0x00, 0x01, 0x82, 0x44, 0x00, 0x01, 0x82, 0x8c, 0x00, 0x01, 0x82, 0xf4, - 0x00, 0x01, 0x83, 0x34, 0x00, 0x01, 0x83, 0x64, 0x00, 0x01, 0x83, 0x94, - 0x00, 0x01, 0x83, 0xf0, 0x00, 0x01, 0x84, 0x20, 0x00, 0x01, 0x84, 0x50, - 0x00, 0x01, 0x84, 0x90, 0x00, 0x01, 0x84, 0xc8, 0x00, 0x01, 0x84, 0xe8, - 0x00, 0x01, 0x85, 0x20, 0x00, 0x01, 0x85, 0x50, 0x00, 0x01, 0x85, 0x80, - 0x00, 0x01, 0x85, 0xc8, 0x00, 0x01, 0x86, 0x0c, 0x00, 0x01, 0x86, 0x6c, - 0x00, 0x01, 0x86, 0x94, 0x00, 0x01, 0x86, 0xf8, 0x00, 0x01, 0x87, 0x30, - 0x00, 0x01, 0x87, 0xac, 0x00, 0x01, 0x88, 0x28, 0x00, 0x01, 0x88, 0x7c, - 0x00, 0x01, 0x89, 0x38, 0x00, 0x01, 0x89, 0x8c, 0x00, 0x01, 0x89, 0xe4, - 0x00, 0x01, 0x8a, 0x40, 0x00, 0x01, 0x8a, 0x9c, 0x00, 0x01, 0x8b, 0x10, - 0x00, 0x01, 0x8b, 0x84, 0x00, 0x01, 0x8b, 0xf8, 0x00, 0x01, 0x8c, 0x30, - 0x00, 0x01, 0x8c, 0x68, 0x00, 0x01, 0x8c, 0xd0, 0x00, 0x01, 0x8d, 0x30, - 0x00, 0x01, 0x8d, 0x7c, 0x00, 0x01, 0x8d, 0xcc, 0x00, 0x01, 0x8d, 0xfc, - 0x00, 0x01, 0x8e, 0x2c, 0x00, 0x01, 0x8e, 0x80, 0x00, 0x01, 0x8e, 0xc0, - 0x00, 0x01, 0x8f, 0x04, 0x00, 0x01, 0x8f, 0x48, 0x00, 0x01, 0x8f, 0xb0, - 0x00, 0x01, 0x8f, 0xd8, 0x00, 0x01, 0x8f, 0xec, 0x00, 0x01, 0x90, 0x00, - 0x00, 0x01, 0x90, 0x14, 0x00, 0x01, 0x90, 0x28, 0x00, 0x01, 0x90, 0xa4, - 0x00, 0x01, 0x90, 0xb4, 0x00, 0x01, 0x90, 0xfc, 0x00, 0x01, 0x91, 0x50, - 0x00, 0x01, 0x91, 0xa4, 0x00, 0x01, 0x91, 0xf4, 0x00, 0x01, 0x92, 0x78, - 0x00, 0x01, 0x92, 0xf8, 0x00, 0x01, 0x93, 0x6c, 0x00, 0x01, 0x93, 0xac, - 0x00, 0x01, 0x93, 0xf4, 0x00, 0x01, 0x94, 0x60, 0x00, 0x01, 0x94, 0xa4, - 0x00, 0x01, 0x94, 0xe8, 0x00, 0x01, 0x95, 0x1c, 0x00, 0x01, 0x95, 0x4c, - 0x00, 0x01, 0x95, 0x88, 0x00, 0x01, 0x95, 0xe4, 0x00, 0x01, 0x96, 0x18, - 0x00, 0x01, 0x96, 0x68, 0x00, 0x01, 0x96, 0x88, 0x00, 0x01, 0x97, 0x10, - 0x00, 0x01, 0x97, 0x78, 0x00, 0x01, 0x97, 0xcc, 0x00, 0x01, 0x98, 0x38, - 0x00, 0x01, 0x98, 0x68, 0x00, 0x01, 0x98, 0xd8, 0x00, 0x01, 0x99, 0x6c, - 0x00, 0x01, 0x9a, 0x18, 0x00, 0x01, 0x9a, 0x60, 0x00, 0x01, 0x9a, 0xc4, - 0x00, 0x01, 0x9b, 0x2c, 0x00, 0x01, 0x9b, 0x88, 0x00, 0x01, 0x9b, 0xdc, - 0x00, 0x01, 0x9c, 0x04, 0x00, 0x01, 0x9c, 0x34, 0x00, 0x01, 0x9c, 0x80, - 0x00, 0x01, 0x9c, 0xdc, 0x00, 0x01, 0x9d, 0x38, 0x00, 0x01, 0x9d, 0x90, - 0x00, 0x01, 0x9d, 0xa8, 0x00, 0x01, 0x9d, 0xc0, 0x00, 0x01, 0x9d, 0xd8, - 0x00, 0x01, 0x9d, 0xf0, 0x00, 0x01, 0x9e, 0x08, 0x00, 0x01, 0x9e, 0x20, - 0x00, 0x01, 0x9e, 0x38, 0x00, 0x01, 0x9e, 0x50, 0x00, 0x01, 0x9e, 0x70, - 0x00, 0x01, 0x9e, 0x8c, 0x00, 0x01, 0x9e, 0xa4, 0x00, 0x01, 0x9e, 0xbc, - 0x00, 0x01, 0x9e, 0xd4, 0x00, 0x01, 0x9e, 0xec, 0x00, 0x01, 0x9f, 0x04, - 0x00, 0x01, 0x9f, 0x1c, 0x00, 0x01, 0x9f, 0x34, 0x00, 0x01, 0x9f, 0x4c, - 0x00, 0x01, 0x9f, 0x64, 0x00, 0x01, 0x9f, 0x7c, 0x00, 0x01, 0x9f, 0x94, - 0x00, 0x01, 0x9f, 0xac, 0x00, 0x01, 0x9f, 0xc4, 0x00, 0x01, 0x9f, 0xdc, - 0x00, 0x01, 0x9f, 0xf8, 0x00, 0x01, 0xa0, 0x14, 0x00, 0x01, 0xa0, 0x2c, - 0x00, 0x01, 0xa0, 0x44, 0x00, 0x01, 0xa0, 0x5c, 0x00, 0x01, 0xa0, 0x74, - 0x00, 0x01, 0xa0, 0x8c, 0x00, 0x01, 0xa0, 0xa4, 0x00, 0x01, 0xa0, 0xbc, - 0x00, 0x01, 0xa0, 0xd4, 0x00, 0x01, 0xa0, 0xec, 0x00, 0x01, 0xa1, 0x04, - 0x00, 0x01, 0xa1, 0x1c, 0x00, 0x01, 0xa1, 0x34, 0x00, 0x01, 0xa1, 0x4c, - 0x00, 0x01, 0xa1, 0x64, 0x00, 0x01, 0xa1, 0x7c, 0x00, 0x01, 0xa1, 0x94, - 0x00, 0x01, 0xa1, 0xac, 0x00, 0x01, 0xa1, 0xc4, 0x00, 0x01, 0xa1, 0xdc, - 0x00, 0x01, 0xa1, 0xf4, 0x00, 0x01, 0xa2, 0x0c, 0x00, 0x01, 0xa2, 0x24, - 0x00, 0x01, 0xa2, 0x3c, 0x00, 0x01, 0xa2, 0x54, 0x00, 0x01, 0xa2, 0x6c, - 0x00, 0x01, 0xa2, 0x84, 0x00, 0x01, 0xa2, 0x9c, 0x00, 0x01, 0xa2, 0xb4, - 0x00, 0x01, 0xa2, 0xcc, 0x00, 0x01, 0xa2, 0xe4, 0x00, 0x01, 0xa2, 0xfc, - 0x00, 0x01, 0xa3, 0x14, 0x00, 0x01, 0xa3, 0x2c, 0x00, 0x01, 0xa3, 0x44, - 0x00, 0x01, 0xa3, 0x5c, 0x00, 0x01, 0xa3, 0x74, 0x00, 0x01, 0xa3, 0x8c, - 0x00, 0x01, 0xa3, 0xa4, 0x00, 0x01, 0xa3, 0xbc, 0x00, 0x01, 0xa3, 0xd4, - 0x00, 0x01, 0xa3, 0xec, 0x00, 0x01, 0xa4, 0x04, 0x00, 0x01, 0xa4, 0x1c, - 0x00, 0x01, 0xa4, 0x34, 0x00, 0x01, 0xa4, 0x54, 0x00, 0x01, 0xa4, 0x74, - 0x00, 0x01, 0xa4, 0x8c, 0x00, 0x01, 0xa4, 0xa4, 0x00, 0x01, 0xa4, 0xbc, - 0x00, 0x01, 0xa4, 0xd4, 0x00, 0x01, 0xa4, 0xec, 0x00, 0x01, 0xa5, 0x04, - 0x00, 0x01, 0xa5, 0x1c, 0x00, 0x01, 0xa5, 0x34, 0x00, 0x01, 0xa5, 0x4c, - 0x00, 0x01, 0xa5, 0x64, 0x00, 0x01, 0xa5, 0x7c, 0x00, 0x01, 0xa5, 0x94, - 0x00, 0x01, 0xa5, 0xac, 0x00, 0x01, 0xa5, 0xc4, 0x00, 0x01, 0xa5, 0xdc, - 0x00, 0x01, 0xa5, 0xf4, 0x00, 0x01, 0xa6, 0x10, 0x00, 0x01, 0xa6, 0x2c, - 0x00, 0x01, 0xa6, 0x44, 0x00, 0x01, 0xa6, 0x5c, 0x00, 0x01, 0xa6, 0x74, - 0x00, 0x01, 0xa6, 0x8c, 0x00, 0x01, 0xa6, 0xa4, 0x00, 0x01, 0xa6, 0xbc, - 0x00, 0x01, 0xa6, 0xd4, 0x00, 0x01, 0xa6, 0xec, 0x00, 0x01, 0xa7, 0x04, - 0x00, 0x01, 0xa7, 0x1c, 0x00, 0x01, 0xa7, 0x34, 0x00, 0x01, 0xa7, 0x4c, - 0x00, 0x01, 0xa7, 0x64, 0x00, 0x01, 0xa7, 0x7c, 0x00, 0x01, 0xa7, 0x9c, - 0x00, 0x01, 0xa7, 0xbc, 0x00, 0x01, 0xa7, 0xd4, 0x00, 0x01, 0xa7, 0xec, - 0x00, 0x01, 0xa8, 0x04, 0x00, 0x01, 0xa8, 0x1c, 0x00, 0x01, 0xa8, 0x34, - 0x00, 0x01, 0xa8, 0x4c, 0x00, 0x01, 0xa8, 0x64, 0x00, 0x01, 0xa8, 0x7c, - 0x00, 0x01, 0xa8, 0x94, 0x00, 0x01, 0xa8, 0xac, 0x00, 0x01, 0xa8, 0xc4, - 0x00, 0x01, 0xa8, 0xdc, 0x00, 0x01, 0xa8, 0xf4, 0x00, 0x01, 0xa9, 0x0c, - 0x00, 0x01, 0xa9, 0x24, 0x00, 0x01, 0xa9, 0x3c, 0x00, 0x01, 0xa9, 0x54, - 0x00, 0x01, 0xa9, 0x6c, 0x00, 0x01, 0xa9, 0x84, 0x00, 0x01, 0xa9, 0x9c, - 0x00, 0x01, 0xa9, 0xb4, 0x00, 0x01, 0xa9, 0xcc, 0x00, 0x01, 0xa9, 0xe4, - 0x00, 0x01, 0xa9, 0xfc, 0x00, 0x01, 0xaa, 0x14, 0x00, 0x01, 0xaa, 0x2c, - 0x00, 0x01, 0xaa, 0x44, 0x00, 0x01, 0xaa, 0x5c, 0x00, 0x01, 0xaa, 0x74, - 0x00, 0x01, 0xaa, 0x8c, 0x00, 0x01, 0xaa, 0xa4, 0x00, 0x01, 0xaa, 0xb4, - 0x00, 0x01, 0xaa, 0xcc, 0x00, 0x01, 0xaa, 0xe4, 0x00, 0x01, 0xaa, 0xfc, - 0x00, 0x01, 0xab, 0x14, 0x00, 0x01, 0xab, 0x34, 0x00, 0x01, 0xab, 0x4c, - 0x00, 0x01, 0xab, 0x64, 0x00, 0x01, 0xab, 0x7c, 0x00, 0x01, 0xab, 0x94, - 0x00, 0x01, 0xab, 0xac, 0x00, 0x01, 0xab, 0xc4, 0x00, 0x01, 0xab, 0xdc, - 0x00, 0x01, 0xab, 0xf4, 0x00, 0x01, 0xac, 0x0c, 0x00, 0x01, 0xac, 0x24, - 0x00, 0x01, 0xac, 0x3c, 0x00, 0x01, 0xac, 0x54, 0x00, 0x01, 0xac, 0x6c, - 0x00, 0x01, 0xac, 0x84, 0x00, 0x01, 0xac, 0x9c, 0x00, 0x01, 0xac, 0xb4, - 0x00, 0x01, 0xac, 0xcc, 0x00, 0x01, 0xac, 0xe4, 0x00, 0x01, 0xac, 0xfc, - 0x00, 0x01, 0xad, 0x14, 0x00, 0x01, 0xad, 0x2c, 0x00, 0x01, 0xad, 0x44, - 0x00, 0x01, 0xad, 0x5c, 0x00, 0x01, 0xad, 0x74, 0x00, 0x01, 0xad, 0x8c, - 0x00, 0x01, 0xad, 0xa4, 0x00, 0x01, 0xad, 0xbc, 0x00, 0x01, 0xad, 0xd4, - 0x00, 0x01, 0xad, 0xec, 0x00, 0x01, 0xae, 0x04, 0x00, 0x01, 0xae, 0x1c, - 0x00, 0x01, 0xae, 0x34, 0x00, 0x01, 0xae, 0x4c, 0x00, 0x01, 0xae, 0x64, - 0x00, 0x01, 0xae, 0x7c, 0x00, 0x01, 0xae, 0x94, 0x00, 0x01, 0xae, 0xac, - 0x00, 0x01, 0xae, 0xc4, 0x00, 0x01, 0xae, 0xdc, 0x00, 0x01, 0xae, 0xf4, - 0x00, 0x01, 0xaf, 0x0c, 0x00, 0x01, 0xaf, 0x24, 0x00, 0x01, 0xaf, 0x3c, - 0x00, 0x01, 0xaf, 0x54, 0x00, 0x01, 0xaf, 0x6c, 0x00, 0x01, 0xaf, 0x84, - 0x00, 0x01, 0xaf, 0x9c, 0x00, 0x01, 0xaf, 0xb4, 0x00, 0x01, 0xaf, 0xcc, - 0x00, 0x01, 0xaf, 0xe4, 0x00, 0x01, 0xaf, 0xfc, 0x00, 0x01, 0xb0, 0x14, - 0x00, 0x01, 0xb0, 0x2c, 0x00, 0x01, 0xb0, 0x44, 0x00, 0x01, 0xb0, 0x5c, - 0x00, 0x01, 0xb0, 0x74, 0x00, 0x01, 0xb0, 0x8c, 0x00, 0x01, 0xb0, 0xa4, - 0x00, 0x01, 0xb0, 0xbc, 0x00, 0x01, 0xb0, 0xd4, 0x00, 0x01, 0xb0, 0xec, - 0x00, 0x01, 0xb1, 0x04, 0x00, 0x01, 0xb1, 0x1c, 0x00, 0x01, 0xb1, 0x34, - 0x00, 0x01, 0xb1, 0x4c, 0x00, 0x01, 0xb1, 0x64, 0x00, 0x01, 0xb1, 0x7c, - 0x00, 0x01, 0xb1, 0x94, 0x00, 0x01, 0xb1, 0xac, 0x00, 0x01, 0xb1, 0xc4, - 0x00, 0x01, 0xb1, 0xdc, 0x00, 0x01, 0xb1, 0xf4, 0x00, 0x01, 0xb2, 0x0c, - 0x00, 0x01, 0xb2, 0x24, 0x00, 0x01, 0xb2, 0x3c, 0x00, 0x01, 0xb2, 0x54, - 0x00, 0x01, 0xb2, 0x6c, 0x00, 0x01, 0xb2, 0x84, 0x00, 0x01, 0xb2, 0x9c, - 0x00, 0x01, 0xb2, 0xb4, 0x00, 0x01, 0xb2, 0xcc, 0x00, 0x01, 0xb2, 0xe4, - 0x00, 0x01, 0xb2, 0xfc, 0x00, 0x01, 0xb3, 0x14, 0x00, 0x01, 0xb3, 0x2c, - 0x00, 0x01, 0xb3, 0x44, 0x00, 0x01, 0xb3, 0x5c, 0x00, 0x01, 0xb3, 0x74, - 0x00, 0x01, 0xb3, 0x8c, 0x00, 0x01, 0xb3, 0xa4, 0x00, 0x01, 0xb3, 0xbc, - 0x00, 0x01, 0xb3, 0xd4, 0x00, 0x01, 0xb3, 0xec, 0x00, 0x01, 0xb4, 0x04, - 0x00, 0x01, 0xb4, 0x1c, 0x00, 0x01, 0xb4, 0x34, 0x00, 0x01, 0xb4, 0x4c, - 0x00, 0x01, 0xb4, 0x64, 0x00, 0x01, 0xb4, 0x7c, 0x00, 0x01, 0xb4, 0x94, - 0x00, 0x01, 0xb4, 0xac, 0x00, 0x01, 0xb4, 0xc4, 0x00, 0x01, 0xb4, 0xdc, - 0x00, 0x01, 0xb4, 0xf4, 0x00, 0x01, 0xb5, 0x0c, 0x00, 0x01, 0xb5, 0x24, - 0x00, 0x01, 0xb5, 0x3c, 0x00, 0x01, 0xb5, 0x54, 0x00, 0x01, 0xb5, 0x6c, - 0x00, 0x01, 0xb5, 0x84, 0x00, 0x01, 0xb5, 0x9c, 0x00, 0x01, 0xb5, 0xb4, - 0x00, 0x01, 0xb5, 0xcc, 0x00, 0x01, 0xb5, 0xe4, 0x00, 0x01, 0xb5, 0xfc, - 0x00, 0x01, 0xb6, 0x14, 0x00, 0x01, 0xb6, 0x2c, 0x00, 0x01, 0xb6, 0x44, - 0x00, 0x01, 0xb6, 0x5c, 0x00, 0x01, 0xb6, 0x74, 0x00, 0x01, 0xb6, 0x8c, - 0x00, 0x01, 0xb6, 0xa4, 0x00, 0x01, 0xb6, 0xbc, 0x00, 0x01, 0xb6, 0xd4, - 0x00, 0x01, 0xb6, 0xec, 0x00, 0x01, 0xb7, 0x04, 0x00, 0x01, 0xb7, 0x1c, - 0x00, 0x01, 0xb7, 0x34, 0x00, 0x01, 0xb7, 0x4c, 0x00, 0x01, 0xb7, 0x64, - 0x00, 0x01, 0xb7, 0x7c, 0x00, 0x01, 0xb7, 0x94, 0x00, 0x01, 0xb7, 0xac, - 0x00, 0x01, 0xb7, 0xc4, 0x00, 0x01, 0xb7, 0xdc, 0x00, 0x01, 0xb7, 0xf4, - 0x00, 0x01, 0xb8, 0x0c, 0x00, 0x01, 0xb8, 0x24, 0x00, 0x01, 0xb8, 0x3c, - 0x00, 0x01, 0xb8, 0x54, 0x00, 0x01, 0xb8, 0x64, 0x00, 0x01, 0xb8, 0x7c, - 0x00, 0x01, 0xb8, 0x8c, 0x00, 0x01, 0xb8, 0xa4, 0x00, 0x01, 0xb8, 0xb4, - 0x00, 0x01, 0xb8, 0xcc, 0x00, 0x01, 0xb8, 0xdc, 0x00, 0x01, 0xb8, 0xf4, - 0x00, 0x01, 0xb9, 0x04, 0x00, 0x01, 0xb9, 0x1c, 0x00, 0x01, 0xb9, 0x2c, - 0x00, 0x01, 0xb9, 0x44, 0x00, 0x01, 0xb9, 0x54, 0x00, 0x01, 0xb9, 0x6c, - 0x00, 0x01, 0xb9, 0x84, 0x00, 0x01, 0xb9, 0x9c, 0x00, 0x01, 0xb9, 0xb4, - 0x00, 0x01, 0xb9, 0xcc, 0x00, 0x01, 0xb9, 0xe4, 0x00, 0x01, 0xb9, 0xfc, - 0x00, 0x01, 0xba, 0x14, 0x00, 0x01, 0xba, 0x2c, 0x00, 0x01, 0xba, 0x44, - 0x00, 0x01, 0xba, 0x5c, 0x00, 0x01, 0xba, 0x74, 0x00, 0x01, 0xba, 0x8c, - 0x00, 0x01, 0xba, 0xa4, 0x00, 0x01, 0xba, 0xbc, 0x00, 0x01, 0xba, 0xd4, - 0x00, 0x01, 0xba, 0xec, 0x00, 0x01, 0xbb, 0x04, 0x00, 0x01, 0xbb, 0x1c, - 0x00, 0x01, 0xbb, 0x34, 0x00, 0x01, 0xbb, 0x4c, 0x00, 0x01, 0xbb, 0x64, - 0x00, 0x01, 0xbb, 0x7c, 0x00, 0x01, 0xbb, 0x94, 0x00, 0x01, 0xbb, 0xac, - 0x00, 0x01, 0xbb, 0xc4, 0x00, 0x01, 0xbb, 0xdc, 0x00, 0x01, 0xbb, 0xf4, - 0x00, 0x01, 0xbc, 0x0c, 0x00, 0x01, 0xbc, 0x24, 0x00, 0x01, 0xbc, 0x3c, - 0x00, 0x01, 0xbc, 0x54, 0x00, 0x01, 0xbc, 0x6c, 0x00, 0x01, 0xbc, 0x84, - 0x00, 0x01, 0xbc, 0x9c, 0x00, 0x01, 0xbc, 0xb4, 0x00, 0x01, 0xbc, 0xcc, - 0x00, 0x01, 0xbc, 0xe4, 0x00, 0x01, 0xbc, 0xfc, 0x00, 0x01, 0xbd, 0x14, - 0x00, 0x01, 0xbd, 0x2c, 0x00, 0x01, 0xbd, 0x44, 0x00, 0x01, 0xbd, 0x5c, - 0x00, 0x01, 0xbd, 0x74, 0x00, 0x01, 0xbd, 0x8c, 0x00, 0x01, 0xbd, 0xa4, - 0x00, 0x01, 0xbd, 0xbc, 0x00, 0x01, 0xbd, 0xd4, 0x00, 0x01, 0xbd, 0xec, - 0x00, 0x01, 0xbe, 0x04, 0x00, 0x01, 0xbe, 0x1c, 0x00, 0x01, 0xbe, 0x34, - 0x00, 0x01, 0xbe, 0x4c, 0x00, 0x01, 0xbe, 0x64, 0x00, 0x01, 0xbe, 0x7c, - 0x00, 0x01, 0xbe, 0x94, 0x00, 0x01, 0xbe, 0xac, 0x00, 0x01, 0xbe, 0xc4, - 0x00, 0x01, 0xbe, 0xd4, 0x00, 0x01, 0xbe, 0xec, 0x00, 0x01, 0xbe, 0xfc, - 0x00, 0x01, 0xbf, 0x0c, 0x00, 0x01, 0xbf, 0x30, 0x00, 0x01, 0xbf, 0x40, - 0x00, 0x01, 0xbf, 0x58, 0x00, 0x01, 0xbf, 0x70, 0x00, 0x01, 0xbf, 0x88, - 0x00, 0x01, 0xbf, 0xa0, 0x00, 0x01, 0xbf, 0xb8, 0x00, 0x01, 0xbf, 0xd0, - 0x00, 0x01, 0xbf, 0xe8, 0x00, 0x01, 0xbf, 0xf8, 0x00, 0x01, 0xc0, 0x10, - 0x00, 0x01, 0xc0, 0x20, 0x00, 0x01, 0xc0, 0x38, 0x00, 0x01, 0xc0, 0x54, - 0x00, 0x01, 0xc0, 0x6c, 0x00, 0x01, 0xc0, 0x84, 0x00, 0x01, 0xc0, 0x9c, - 0x00, 0x01, 0xc0, 0xb4, 0x00, 0x01, 0xc0, 0xcc, 0x00, 0x01, 0xc0, 0xdc, - 0x00, 0x01, 0xc0, 0xf4, 0x00, 0x01, 0xc1, 0x0c, 0x00, 0x01, 0xc1, 0x24, - 0x00, 0x01, 0xc1, 0x3c, 0x00, 0x01, 0xc1, 0x54, 0x00, 0x01, 0xc1, 0x64, - 0x00, 0x01, 0xc1, 0x80, 0x00, 0x01, 0xc1, 0x98, 0x00, 0x01, 0xc1, 0xb0, - 0x00, 0x01, 0xc1, 0xc8, 0x00, 0x01, 0xc1, 0xe0, 0x00, 0x01, 0xc1, 0xf8, - 0x00, 0x01, 0xc2, 0x08, 0x00, 0x01, 0xc2, 0x20, 0x00, 0x01, 0xc2, 0x38, - 0x00, 0x01, 0xc2, 0x50, 0x00, 0x01, 0xc2, 0x68, 0x00, 0x01, 0xc2, 0x80, - 0x00, 0x01, 0xc2, 0x98, 0x00, 0x01, 0xc2, 0xb0, 0x00, 0x01, 0xc2, 0xc0, - 0x00, 0x01, 0xc2, 0xd8, 0x00, 0x01, 0xc2, 0xf0, 0x00, 0x01, 0xc3, 0x00, - 0x00, 0x01, 0xc3, 0x10, 0x00, 0x01, 0xc3, 0x28, 0x00, 0x01, 0xc3, 0x40, - 0x00, 0x01, 0xc3, 0x58, 0x00, 0x01, 0xc3, 0x70, 0x00, 0x01, 0xc3, 0x88, - 0x00, 0x01, 0xc3, 0xa0, 0x00, 0x01, 0xc3, 0xb0, 0x00, 0x01, 0xc3, 0xc8, - 0x00, 0x01, 0xc3, 0xd8, 0x00, 0x01, 0xc3, 0xf0, 0x00, 0x01, 0xc4, 0x00, - 0x00, 0x01, 0xc4, 0x24, 0x00, 0x01, 0xc4, 0x24, 0x00, 0x01, 0xc4, 0x24, - 0x00, 0x01, 0xc4, 0x24, 0x00, 0x01, 0xc4, 0x24, 0x00, 0x01, 0xc4, 0x24, - 0x00, 0x01, 0xc4, 0x24, 0x00, 0x01, 0xc4, 0x24, 0x00, 0x01, 0xc4, 0x24, - 0x00, 0x01, 0xc4, 0x24, 0x00, 0x01, 0xc4, 0x24, 0x00, 0x01, 0xc4, 0x24, - 0x00, 0x01, 0xc4, 0x50, 0x00, 0x01, 0xc4, 0x60, 0x00, 0x01, 0xc4, 0x8c, - 0x00, 0x01, 0xc4, 0xb8, 0x00, 0x01, 0xc4, 0xe0, 0x00, 0x01, 0xc5, 0x08, - 0x00, 0x01, 0xc5, 0x24, 0x00, 0x01, 0xc5, 0x3c, 0x00, 0x01, 0xc5, 0x78, - 0x00, 0x01, 0xc5, 0xb4, 0x00, 0x01, 0xc5, 0xf0, 0x00, 0x01, 0xc6, 0x14, - 0x00, 0x01, 0xc6, 0x70, 0x00, 0x01, 0xc6, 0xcc, 0x00, 0x01, 0xc7, 0x2c, - 0x00, 0x01, 0xc7, 0x60, 0x00, 0x01, 0xc7, 0xb8, 0x00, 0x01, 0xc8, 0x3c, - 0x00, 0x01, 0xc8, 0x7c, 0x00, 0x01, 0xc8, 0x98, 0x00, 0x01, 0xc8, 0xf0, - 0x00, 0x01, 0xc8, 0xf0, 0x00, 0x01, 0xca, 0x40, 0x00, 0x01, 0xcb, 0x6c, - 0x00, 0x01, 0xcb, 0x8c, 0x00, 0x01, 0xcb, 0xa8, 0x00, 0x01, 0xcb, 0xc8, - 0x00, 0x01, 0xcb, 0xe4, 0x00, 0x01, 0xcc, 0x00, 0x00, 0x01, 0xcc, 0x20, - 0x00, 0x01, 0xcc, 0x64, 0x00, 0x01, 0xcc, 0xac, 0x00, 0x01, 0xcc, 0xc8, - 0x00, 0x01, 0xcd, 0x44, 0x00, 0x01, 0xcd, 0x58, 0x00, 0x01, 0xcd, 0x88, - 0x00, 0x01, 0xcd, 0xb8, 0x00, 0x01, 0xcd, 0xd4, 0x00, 0x01, 0xcd, 0xf0, - 0x00, 0x01, 0xce, 0x0c, 0x00, 0x01, 0xce, 0x44, 0x00, 0x01, 0xce, 0x44, - 0x00, 0x01, 0xce, 0xcc, 0x00, 0x01, 0xcf, 0x04, 0x00, 0x01, 0xcf, 0x74, - 0x00, 0x01, 0xcf, 0xdc, 0x00, 0x01, 0xd0, 0x5c, 0x00, 0x01, 0xd0, 0x84, - 0x00, 0x01, 0xd1, 0x3c, 0x00, 0x01, 0xd1, 0xc8, 0x00, 0x01, 0xd1, 0xf8, - 0x00, 0x01, 0xd2, 0x14, 0x00, 0x01, 0xd2, 0x3c, 0x00, 0x01, 0xd2, 0x70, - 0x00, 0x01, 0xd2, 0xa4, 0x00, 0x01, 0xd3, 0x08, 0x00, 0x01, 0xd3, 0x1c, - 0x00, 0x01, 0xd3, 0x30, 0x00, 0x01, 0xd3, 0x44, 0x00, 0x01, 0xd3, 0x58, - 0x00, 0x01, 0xd3, 0x6c, 0x00, 0x01, 0xd3, 0x80, 0x00, 0x01, 0xd3, 0x94, - 0x00, 0x01, 0xd3, 0xa8, 0x00, 0x01, 0xd3, 0xbc, 0x00, 0x01, 0xd3, 0xd0, - 0x00, 0x01, 0xd3, 0xe4, 0x00, 0x01, 0xd3, 0xf8, 0x00, 0x01, 0xd4, 0x0c, - 0x00, 0x01, 0xd4, 0x20, 0x00, 0x01, 0xd4, 0x34, 0x00, 0x01, 0xd4, 0x48, - 0x00, 0x01, 0xd4, 0x5c, 0x00, 0x01, 0xd4, 0x70, 0x00, 0x01, 0xd4, 0x84, - 0x00, 0x01, 0xd4, 0x98, 0x00, 0x01, 0xd4, 0xac, 0x00, 0x01, 0xd4, 0xc0, - 0x00, 0x01, 0xd4, 0xd4, 0x00, 0x01, 0xd4, 0xe8, 0x00, 0x01, 0xd4, 0xfc, - 0x00, 0x01, 0xd5, 0x10, 0x00, 0x01, 0xd5, 0x24, 0x00, 0x01, 0xd5, 0x38, - 0x00, 0x01, 0xd5, 0xac, 0x00, 0x01, 0xd6, 0x5c, 0x00, 0x01, 0xd6, 0xec, - 0x00, 0x01, 0xd7, 0x2c, 0x00, 0x01, 0xd7, 0x94, 0x00, 0x01, 0xd8, 0x14, - 0x00, 0x01, 0xd8, 0x98, 0x00, 0x01, 0xd9, 0x78, 0x00, 0x01, 0xda, 0x44, - 0x00, 0x01, 0xda, 0xe8, 0x00, 0x01, 0xdb, 0x48, 0x00, 0x01, 0xdb, 0x60, - 0x00, 0x01, 0xdc, 0x70, 0x00, 0x01, 0xdc, 0xb8, 0x00, 0x01, 0xdd, 0x10, - 0x00, 0x01, 0xde, 0x9c, 0x00, 0x01, 0xdf, 0x38, 0x00, 0x01, 0xdf, 0xb8, - 0x00, 0x01, 0xe0, 0x4c, 0x00, 0x01, 0xe0, 0xb8, 0x00, 0x01, 0xe1, 0x58, - 0x00, 0x01, 0xe1, 0xec, 0x00, 0x01, 0xe2, 0x20, 0x00, 0x01, 0xe2, 0x9c, - 0x00, 0x01, 0xe3, 0x10, 0x00, 0x01, 0xe3, 0xac, 0x00, 0x01, 0xe3, 0xfc, - 0x00, 0x01, 0xe4, 0x58, 0x00, 0x01, 0xe4, 0xc0, 0x00, 0x01, 0xe5, 0x04, - 0x00, 0x01, 0xe5, 0x80, 0x00, 0x01, 0xe6, 0x38, 0x00, 0x01, 0xe6, 0xa8, - 0x00, 0x01, 0xe7, 0x40, 0x00, 0x01, 0xe7, 0xf0, 0x00, 0x01, 0xe8, 0xa4, - 0x00, 0x01, 0xe8, 0xe4, 0x00, 0x01, 0xe8, 0xf4, 0x00, 0x01, 0xe9, 0x04, - 0x00, 0x01, 0xe9, 0x14, 0x00, 0x01, 0xe9, 0x9c, 0x00, 0x01, 0xe9, 0xe8, - 0x00, 0x01, 0xea, 0x08, 0x00, 0x01, 0xea, 0x28, 0x00, 0x01, 0xea, 0x48, - 0x00, 0x01, 0xea, 0x68, 0x00, 0x01, 0xea, 0x88, 0x00, 0x01, 0xea, 0xa8, - 0x00, 0x01, 0xea, 0xc8, 0x00, 0x01, 0xea, 0xe8, 0x00, 0x01, 0xeb, 0x08, - 0x00, 0x01, 0xeb, 0x28, 0x00, 0x01, 0xeb, 0x48, 0x00, 0x01, 0xeb, 0x68, - 0x00, 0x01, 0xeb, 0x80, 0x00, 0x01, 0xeb, 0xb0, 0x00, 0x01, 0xeb, 0xe4, - 0x00, 0x01, 0xec, 0x18, 0x00, 0x01, 0xec, 0x48, 0x00, 0x01, 0xec, 0x90, - 0x00, 0x01, 0xec, 0xd8, 0x00, 0x01, 0xed, 0x08, 0x00, 0x01, 0xed, 0x38, - 0x00, 0x01, 0xed, 0x64, 0x00, 0x01, 0xed, 0x90, 0x00, 0x01, 0xed, 0xd8, - 0x00, 0x01, 0xee, 0x20, 0x00, 0x01, 0xee, 0xc8, 0x00, 0x01, 0xef, 0x70, - 0x00, 0x01, 0xef, 0xb8, 0x00, 0x01, 0xf0, 0x00, 0x00, 0x01, 0xf0, 0x48, - 0x00, 0x01, 0xf0, 0x90, 0x00, 0x01, 0xf0, 0xd0, 0x00, 0x01, 0xf1, 0x10, - 0x00, 0x01, 0xf1, 0x4c, 0x00, 0x01, 0xf1, 0x88, 0x00, 0x01, 0xf1, 0xc4, - 0x00, 0x01, 0xf2, 0x00, 0x00, 0x01, 0xf2, 0x4c, 0x00, 0x01, 0xf2, 0xd4, - 0x00, 0x01, 0xf3, 0x60, 0x00, 0x01, 0xf4, 0x24, 0x00, 0x01, 0xf4, 0xec, - 0x00, 0x01, 0xf6, 0x04, 0x00, 0x01, 0xf6, 0x64, 0x00, 0x01, 0xf6, 0xa8, - 0x00, 0x01, 0xf6, 0xe0, 0x00, 0x01, 0xf7, 0x18, 0x00, 0x01, 0xf7, 0x50, - 0x00, 0x01, 0xf7, 0x88, 0x00, 0x01, 0xf7, 0xc0, 0x00, 0x01, 0xf7, 0xf8, - 0x00, 0x01, 0xf8, 0x84, 0x00, 0x01, 0xf9, 0x14, 0x00, 0x01, 0xf9, 0x50, - 0x00, 0x01, 0xf9, 0xb8, 0x00, 0x01, 0xfa, 0x60, 0x00, 0x01, 0xfb, 0x08, - 0x00, 0x01, 0xfb, 0x2c, 0x00, 0x01, 0xfb, 0x54, 0x00, 0x01, 0xfb, 0x7c, - 0x00, 0x01, 0xfb, 0xa4, 0x00, 0x01, 0xfb, 0xcc, 0x00, 0x01, 0xfb, 0xf4, - 0x00, 0x01, 0xfc, 0x18, 0x00, 0x01, 0xfc, 0x3c, 0x00, 0x01, 0xfc, 0x90, - 0x00, 0x01, 0xfc, 0xe4, 0x00, 0x01, 0xfd, 0x38, 0x00, 0x01, 0xfd, 0x80, - 0x00, 0x01, 0xfd, 0xc8, 0x00, 0x01, 0xfe, 0x10, 0x00, 0x01, 0xfe, 0x58, - 0x00, 0x01, 0xfe, 0x94, 0x00, 0x01, 0xfe, 0xd4, 0x00, 0x01, 0xff, 0x38, - 0x00, 0x01, 0xff, 0xb4, 0x00, 0x02, 0x00, 0x18, 0x00, 0x02, 0x00, 0x58, - 0x00, 0x02, 0x00, 0x98, 0x00, 0x02, 0x00, 0xd8, 0x00, 0x02, 0x01, 0x18, - 0x00, 0x02, 0x01, 0x74, 0x00, 0x02, 0x01, 0xd0, 0x00, 0x02, 0x02, 0x10, - 0x00, 0x02, 0x02, 0x50, 0x00, 0x02, 0x02, 0x90, 0x00, 0x02, 0x02, 0xd0, - 0x00, 0x02, 0x03, 0x10, 0x00, 0x02, 0x03, 0x50, 0x00, 0x02, 0x03, 0xa4, - 0x00, 0x02, 0x03, 0xfc, 0x00, 0x02, 0x04, 0x4c, 0x00, 0x02, 0x04, 0x9c, - 0x00, 0x02, 0x04, 0xe4, 0x00, 0x02, 0x05, 0x30, 0x00, 0x02, 0x05, 0x78, - 0x00, 0x02, 0x05, 0xc4, 0x00, 0x02, 0x06, 0x00, 0x00, 0x02, 0x06, 0x3c, - 0x00, 0x02, 0x06, 0x7c, 0x00, 0x02, 0x06, 0xb8, 0x00, 0x02, 0x06, 0xf4, - 0x00, 0x02, 0x07, 0x30, 0x00, 0x02, 0x07, 0x88, 0x00, 0x02, 0x07, 0xd8, - 0x00, 0x02, 0x08, 0x38, 0x00, 0x02, 0x08, 0x98, 0x00, 0x02, 0x08, 0xf0, - 0x00, 0x02, 0x09, 0x60, 0x00, 0x02, 0x09, 0xb4, 0x00, 0x02, 0x09, 0xf8, - 0x00, 0x02, 0x0a, 0x3c, 0x00, 0x02, 0x0a, 0x8c, 0x00, 0x02, 0x0b, 0x2c, - 0x00, 0x02, 0x0b, 0x7c, 0x00, 0x02, 0x0b, 0xd8, 0x00, 0x02, 0x0c, 0x1c, - 0x00, 0x02, 0x0c, 0x60, 0x00, 0x02, 0x0c, 0xb8, 0x00, 0x02, 0x0d, 0x08, - 0x00, 0x02, 0x0d, 0x58, 0x00, 0x02, 0x0d, 0xc0, 0x00, 0x02, 0x0d, 0xf4, - 0x00, 0x02, 0x0e, 0x28, 0x00, 0x02, 0x0e, 0x78, 0x00, 0x02, 0x0e, 0xb0, - 0x00, 0x02, 0x0f, 0x0c, 0x00, 0x02, 0x0f, 0xa4, 0x00, 0x02, 0x0f, 0xd4, - 0x00, 0x02, 0x10, 0x3c, 0x00, 0x02, 0x11, 0x08, 0x00, 0x02, 0x11, 0x84, - 0x00, 0x02, 0x11, 0xb0, 0x00, 0x02, 0x12, 0x0c, 0x00, 0x02, 0x12, 0x9c, - 0x00, 0x02, 0x13, 0x30, 0x00, 0x02, 0x13, 0x8c, 0x00, 0x02, 0x14, 0x1c, - 0x00, 0x02, 0x14, 0x6c, 0x00, 0x02, 0x14, 0xb4, 0x00, 0x02, 0x15, 0x24, - 0x00, 0x02, 0x15, 0x50, 0x00, 0x02, 0x15, 0x90, 0x00, 0x02, 0x15, 0xa0, - 0x00, 0x02, 0x15, 0xb4, 0x00, 0x02, 0x15, 0xc8, 0x00, 0x02, 0x15, 0xd8, - 0x00, 0x02, 0x16, 0x3c, 0x00, 0x02, 0x16, 0x54, 0x00, 0x02, 0x16, 0x6c, - 0x00, 0x02, 0x16, 0xe4, 0x00, 0x02, 0x17, 0xa8, 0x00, 0x02, 0x17, 0xcc, - 0x00, 0x02, 0x17, 0xf4, 0x00, 0x02, 0x18, 0x1c, 0x00, 0x02, 0x18, 0x44, - 0x00, 0x02, 0x18, 0xb8, 0x00, 0x02, 0x19, 0x30, 0x00, 0x02, 0x19, 0xa0, - 0x00, 0x02, 0x1a, 0x38, 0x00, 0x02, 0x1b, 0x10, 0x00, 0x02, 0x1b, 0x34, - 0x00, 0x02, 0x1b, 0x58, 0x00, 0x02, 0x1b, 0x74, 0x00, 0x02, 0x1b, 0xa0, - 0x00, 0x02, 0x1b, 0xb8, 0x00, 0x02, 0x1b, 0xf0, 0x00, 0x02, 0x1c, 0x20, - 0x00, 0x02, 0x1c, 0x40, 0x00, 0x02, 0x1c, 0x9c, 0x00, 0x02, 0x1c, 0xf8, - 0x00, 0x02, 0x1d, 0x64, 0x00, 0x02, 0x1d, 0xc4, 0x00, 0x02, 0x1e, 0x2c, - 0x00, 0x02, 0x1e, 0xb0, 0x00, 0x02, 0x1f, 0x28, 0x00, 0x02, 0x1f, 0xc0, - 0x00, 0x02, 0x20, 0x58, 0x00, 0x02, 0x21, 0x4c, 0x00, 0x02, 0x21, 0xf8, - 0x00, 0x02, 0x22, 0xb0, 0x00, 0x02, 0x23, 0xa4, 0x00, 0x02, 0x24, 0x1c, - 0x00, 0x02, 0x24, 0x68, 0x00, 0x02, 0x25, 0x24, 0x00, 0x02, 0x25, 0x98, - 0x00, 0x02, 0x25, 0xb0, 0x00, 0x02, 0x25, 0xd8, 0x00, 0x02, 0x25, 0xf8, - 0x00, 0x02, 0x26, 0x18, 0x00, 0x02, 0x26, 0x58, 0x00, 0x02, 0x26, 0xa0, - 0x00, 0x02, 0x26, 0xfc, 0x00, 0x02, 0x27, 0x68, 0x00, 0x02, 0x27, 0xb0, - 0x00, 0x02, 0x27, 0xf0, 0x00, 0x02, 0x28, 0x30, 0x00, 0x02, 0x28, 0x7c, - 0x00, 0x02, 0x28, 0xc4, 0x00, 0x02, 0x29, 0xa8, 0x00, 0x02, 0x2a, 0x2c, - 0x00, 0x02, 0x2a, 0xb8, 0x00, 0x02, 0x2b, 0x3c, 0x00, 0x02, 0x2b, 0x70, - 0x00, 0x02, 0x2b, 0xcc, 0x00, 0x02, 0x2c, 0x0c, 0x00, 0x02, 0x2c, 0x6c, - 0x00, 0x02, 0x2c, 0xc8, 0x00, 0x02, 0x2d, 0x0c, 0x00, 0x02, 0x2d, 0x4c, - 0x00, 0x02, 0x2d, 0xac, 0x00, 0x02, 0x2e, 0x10, 0x00, 0x02, 0x2e, 0x78, - 0x00, 0x02, 0x2e, 0xcc, 0x00, 0x02, 0x2f, 0x20, 0x00, 0x02, 0x2f, 0x88, - 0x00, 0x02, 0x2f, 0xec, 0x00, 0x02, 0x30, 0x64, 0x00, 0x02, 0x30, 0xec, - 0x00, 0x02, 0x31, 0x8c, 0x00, 0x02, 0x32, 0x38, 0x00, 0x02, 0x32, 0x7c, - 0x00, 0x02, 0x32, 0xc0, 0x00, 0x02, 0x33, 0x44, 0x00, 0x02, 0x33, 0xcc, - 0x00, 0x02, 0x34, 0x08, 0x00, 0x02, 0x34, 0x40, 0x00, 0x02, 0x34, 0xa8, - 0x00, 0x02, 0x35, 0x10, 0x00, 0x02, 0x35, 0xa4, 0x00, 0x02, 0x36, 0x34, - 0x00, 0x02, 0x36, 0x9c, 0x00, 0x02, 0x37, 0x04, 0x00, 0x02, 0x37, 0x4c, - 0x00, 0x02, 0x37, 0x90, 0x00, 0x02, 0x37, 0xfc, 0x00, 0x02, 0x38, 0x68, - 0x00, 0x02, 0x38, 0xbc, 0x00, 0x02, 0x39, 0x0c, 0x00, 0x02, 0x39, 0x88, - 0x00, 0x02, 0x3a, 0x14, 0x00, 0x02, 0x3a, 0x7c, 0x00, 0x02, 0x3a, 0xe8, - 0x00, 0x02, 0x3b, 0x40, 0x00, 0x02, 0x3b, 0x98, 0x00, 0x02, 0x3c, 0x14, - 0x00, 0x02, 0x3c, 0x94, 0x00, 0x02, 0x3d, 0x5c, 0x00, 0x02, 0x3e, 0x0c, - 0x00, 0x02, 0x3e, 0xd8, 0x00, 0x02, 0x3f, 0x8c, 0x00, 0x02, 0x40, 0x3c, - 0x00, 0x02, 0x41, 0x24, 0x00, 0x02, 0x42, 0x14, 0x00, 0x02, 0x42, 0xd4, - 0x00, 0x02, 0x43, 0x88, 0x00, 0x02, 0x43, 0xd8, 0x00, 0x02, 0x44, 0x10, - 0x00, 0x02, 0x44, 0x70, 0x00, 0x02, 0x44, 0xa8, 0x00, 0x02, 0x44, 0xd0, - 0x00, 0x02, 0x44, 0xf4, 0x00, 0x02, 0x45, 0x18, 0x00, 0x02, 0x45, 0x40, - 0x00, 0x02, 0x45, 0x70, 0x00, 0x02, 0x45, 0xa0, 0x00, 0x02, 0x46, 0x08, - 0x00, 0x02, 0x46, 0x58, 0x00, 0x02, 0x46, 0xac, 0x00, 0x02, 0x46, 0xe4, - 0x00, 0x02, 0x47, 0x18, 0x00, 0x02, 0x47, 0x80, 0x00, 0x02, 0x47, 0xe8, - 0x00, 0x02, 0x48, 0x80, 0x00, 0x02, 0x49, 0x14, 0x00, 0x02, 0x49, 0x68, - 0x00, 0x02, 0x49, 0xb8, 0x00, 0x02, 0x4a, 0x04, 0x00, 0x02, 0x4a, 0x50, - 0x00, 0x02, 0x4a, 0xcc, 0x00, 0x02, 0x4b, 0x50, 0x00, 0x02, 0x4b, 0xf4, - 0x00, 0x02, 0x4c, 0x94, 0x00, 0x02, 0x4c, 0xa8, 0x00, 0x02, 0x4c, 0xb8, - 0x00, 0x02, 0x4c, 0xe4, 0x00, 0x02, 0x4d, 0x1c, 0x00, 0x02, 0x4d, 0x44, - 0x00, 0x02, 0x4d, 0x6c, 0x00, 0x02, 0x4d, 0xa0, 0x00, 0x02, 0x4d, 0xe0, - 0x00, 0x02, 0x4e, 0x00, 0x00, 0x02, 0x4e, 0x20, 0x00, 0x02, 0x4e, 0x40, - 0x00, 0x02, 0x4e, 0x60, 0x00, 0x02, 0x4e, 0x88, 0x00, 0x02, 0x4e, 0xb0, - 0x00, 0x02, 0x4e, 0xd8, 0x00, 0x02, 0x4f, 0x00, 0x00, 0x02, 0x4f, 0x20, - 0x00, 0x02, 0x4f, 0x74, 0x00, 0x02, 0x4f, 0x84, 0x00, 0x02, 0x4f, 0xc8, - 0x00, 0x02, 0x50, 0x0c, 0x00, 0x02, 0x50, 0x64, 0x00, 0x02, 0x51, 0x4c, - 0x00, 0x02, 0x51, 0x70, 0x00, 0x02, 0x51, 0x94, 0x00, 0x02, 0x51, 0xb4, - 0x00, 0x02, 0x51, 0xd4, 0x00, 0x02, 0x51, 0xf4, 0x00, 0x02, 0x52, 0x4c, - 0x00, 0x02, 0x52, 0xa4, 0x00, 0x02, 0x52, 0xdc, 0x00, 0x02, 0x53, 0x40, - 0x00, 0x02, 0x53, 0x98, 0x00, 0x02, 0x58, 0x44, 0x00, 0x02, 0x58, 0xa8, - 0x00, 0x02, 0x58, 0xd0, 0x00, 0x02, 0x58, 0xfc, 0x00, 0x02, 0x59, 0x40, - 0x00, 0x02, 0x59, 0x90, 0x00, 0x02, 0x59, 0xec, 0x00, 0x02, 0x5a, 0x04, - 0x00, 0x02, 0x5a, 0x90, 0x00, 0x02, 0x5b, 0x14, 0x00, 0x02, 0x5b, 0x2c, - 0x00, 0x02, 0x5b, 0x64, 0x00, 0x02, 0x5b, 0x98, 0x00, 0x02, 0x5b, 0xe4, - 0x00, 0x02, 0x5c, 0x30, 0x00, 0x02, 0x5c, 0x7c, 0x00, 0x02, 0x5c, 0xcc, - 0x00, 0x02, 0x5d, 0x5c, 0x00, 0x02, 0x5d, 0xac, 0x00, 0x02, 0x5d, 0xf4, - 0x00, 0x02, 0x5e, 0x44, 0x00, 0x02, 0x5e, 0x94, 0x00, 0x02, 0x5e, 0xe0, - 0x00, 0x02, 0x5f, 0x2c, 0x00, 0x02, 0x5f, 0x7c, 0x00, 0x02, 0x5f, 0xcc, - 0x00, 0x02, 0x5f, 0xe4, 0x00, 0x02, 0x5f, 0xfc, 0x00, 0x02, 0x60, 0x14, - 0x00, 0x02, 0x60, 0x2c, 0x00, 0x02, 0x60, 0x44, 0x00, 0x02, 0x60, 0x5c, - 0x00, 0x02, 0x60, 0x74, 0x00, 0x02, 0x60, 0x8c, 0x00, 0x02, 0x60, 0xa4, - 0x00, 0x02, 0x60, 0xbc, 0x00, 0x02, 0x60, 0xd8, 0x00, 0x02, 0x60, 0xf0, - 0x00, 0x02, 0x61, 0x08, 0x00, 0x02, 0x61, 0xa4, 0x00, 0x02, 0x62, 0x70, - 0x00, 0x02, 0x62, 0xd4, 0x00, 0x02, 0x63, 0x14, 0x00, 0x02, 0x63, 0x7c, - 0x00, 0x02, 0x63, 0x94, 0x00, 0x02, 0x63, 0xa4, 0x00, 0x02, 0x63, 0xb4, - 0x00, 0x02, 0x63, 0xc4, 0x00, 0x02, 0x63, 0xdc, 0x00, 0x02, 0x63, 0xf4, - 0x00, 0x02, 0x64, 0x0c, 0x00, 0x02, 0x64, 0x24, 0x00, 0x02, 0x64, 0x34, - 0x00, 0x02, 0x64, 0x84, 0x00, 0x02, 0x65, 0x1c, 0x00, 0x02, 0x65, 0xc8, - 0x00, 0x02, 0x66, 0xc8, 0x00, 0x02, 0x67, 0x98, 0x00, 0x02, 0x68, 0xc8, - 0x00, 0x02, 0x69, 0x6c, 0x00, 0x02, 0x6a, 0x18, 0x00, 0x02, 0x6a, 0x98, - 0x00, 0x02, 0x6a, 0xc4, 0x00, 0x02, 0x6a, 0xfc, 0x00, 0x02, 0x6b, 0x18, - 0x00, 0x02, 0x6b, 0x50, 0x00, 0x02, 0x6b, 0x88, 0x00, 0x02, 0x6b, 0xa4, - 0x00, 0x02, 0x6b, 0xdc, 0x00, 0x02, 0x6b, 0xfc, 0x00, 0x02, 0x6c, 0x18, - 0x00, 0x02, 0x6c, 0x3c, 0x00, 0x02, 0x6c, 0x60, 0x00, 0x02, 0x6c, 0x7c, - 0x00, 0x02, 0x6c, 0x9c, 0x00, 0x02, 0x6c, 0xd0, 0x00, 0x02, 0x6d, 0x28, - 0x00, 0x02, 0x6d, 0x60, 0x00, 0x02, 0x6d, 0x7c, 0x00, 0x02, 0x6d, 0xb4, - 0x00, 0x02, 0x6e, 0x0c, 0x00, 0x02, 0x6e, 0x40, 0x00, 0x02, 0x6e, 0x5c, - 0x00, 0x02, 0x6e, 0xa8, 0x00, 0x02, 0x6e, 0xd4, 0x00, 0x02, 0x6f, 0x18, - 0x00, 0x02, 0x6f, 0x34, 0x00, 0x02, 0x6f, 0x50, 0x00, 0x02, 0x6f, 0x6c, - 0x00, 0x02, 0x6f, 0x88, 0x00, 0x02, 0x6f, 0xbc, 0x00, 0x02, 0x6f, 0xf4, - 0x00, 0x02, 0x70, 0x2c, 0x00, 0x02, 0x70, 0x68, 0x00, 0x02, 0x70, 0xa0, - 0x00, 0x02, 0x70, 0xe0, 0x00, 0x02, 0x71, 0x28, 0x00, 0x02, 0x71, 0x74, - 0x00, 0x02, 0x71, 0x98, 0x00, 0x02, 0x71, 0xbc, 0x00, 0x02, 0x71, 0xe0, - 0x00, 0x02, 0x72, 0x04, 0x00, 0x02, 0x72, 0x28, 0x00, 0x02, 0x72, 0x4c, - 0x00, 0x02, 0x72, 0x70, 0x00, 0x02, 0x72, 0x94, 0x00, 0x02, 0x72, 0xb4, - 0x00, 0x02, 0x72, 0xd8, 0x00, 0x02, 0x72, 0xfc, 0x00, 0x02, 0x73, 0x20, - 0x00, 0x02, 0x73, 0x40, 0x00, 0x02, 0x73, 0x60, 0x00, 0x02, 0x73, 0x80, - 0x00, 0x02, 0x73, 0xa4, 0x00, 0x02, 0x73, 0xcc, 0x00, 0x02, 0x73, 0xf4, - 0x00, 0x02, 0x74, 0x20, 0x00, 0x02, 0x74, 0x4c, 0x00, 0x02, 0x74, 0x74, - 0x00, 0x02, 0x74, 0xa4, 0x00, 0x02, 0x74, 0xd0, 0x00, 0x02, 0x74, 0xf8, - 0x00, 0x02, 0x75, 0x20, 0x00, 0x02, 0x75, 0x48, 0x00, 0x02, 0x75, 0x74, - 0x00, 0x02, 0x75, 0xa0, 0x00, 0x02, 0x75, 0xc8, 0x00, 0x02, 0x75, 0xf8, - 0x00, 0x02, 0x76, 0x24, 0x00, 0x02, 0x76, 0x4c, 0x00, 0x02, 0x76, 0x74, - 0x00, 0x02, 0x76, 0xa0, 0x00, 0x02, 0x76, 0xcc, 0x00, 0x02, 0x76, 0xf4, - 0x00, 0x02, 0x77, 0x1c, 0x00, 0x02, 0x77, 0x48, 0x00, 0x02, 0x77, 0x74, - 0x00, 0x02, 0x77, 0x9c, 0x00, 0x02, 0x77, 0xc0, 0x00, 0x02, 0x77, 0xec, - 0x00, 0x02, 0x78, 0x18, 0x00, 0x02, 0x78, 0x40, 0x00, 0x02, 0x78, 0x68, - 0x00, 0x02, 0x78, 0x94, 0x00, 0x02, 0x78, 0xc0, 0x00, 0x02, 0x78, 0xe8, - 0x00, 0x02, 0x79, 0x18, 0x00, 0x02, 0x79, 0x4c, 0x00, 0x02, 0x79, 0x80, - 0x00, 0x02, 0x79, 0xb4, 0x00, 0x02, 0x79, 0xe8, 0x00, 0x02, 0x7a, 0x1c, - 0x00, 0x02, 0x7a, 0x50, 0x00, 0x02, 0x7a, 0x88, 0x00, 0x02, 0x7a, 0xc0, - 0x00, 0x02, 0x7a, 0xf8, 0x00, 0x02, 0x7b, 0x30, 0x00, 0x02, 0x7b, 0x64, - 0x00, 0x02, 0x7b, 0x98, 0x00, 0x02, 0x7b, 0xcc, 0x00, 0x02, 0x7c, 0x00, - 0x00, 0x02, 0x7c, 0x34, 0x00, 0x02, 0x7c, 0x58, 0x00, 0x02, 0x7c, 0x84, - 0x00, 0x02, 0x7c, 0xb0, 0x00, 0x02, 0x7c, 0xdc, 0x00, 0x02, 0x7d, 0x04, - 0x00, 0x02, 0x7d, 0x2c, 0x00, 0x02, 0x7d, 0x58, 0x00, 0x02, 0x7d, 0x84, - 0x00, 0x02, 0x7d, 0xb8, 0x00, 0x02, 0x7d, 0xe4, 0x00, 0x02, 0x7e, 0x10, - 0x00, 0x02, 0x7e, 0x44, 0x00, 0x02, 0x7e, 0x70, 0x00, 0x02, 0x7e, 0x9c, - 0x00, 0x02, 0x7e, 0xd0, 0x00, 0x02, 0x7e, 0xfc, 0x00, 0x02, 0x7f, 0x28, - 0x00, 0x02, 0x7f, 0x5c, 0x00, 0x02, 0x7f, 0x8c, 0x00, 0x02, 0x7f, 0xc0, - 0x00, 0x02, 0x80, 0x04, 0x00, 0x02, 0x80, 0x34, 0x00, 0x02, 0x80, 0x68, - 0x00, 0x02, 0x80, 0xa8, 0x00, 0x02, 0x80, 0xdc, 0x00, 0x02, 0x81, 0x0c, - 0x00, 0x02, 0x81, 0x4c, 0x00, 0x02, 0x81, 0x80, 0x00, 0x02, 0x81, 0xb0, - 0x00, 0x02, 0x81, 0xf0, 0x00, 0x02, 0x82, 0x38, 0x00, 0x02, 0x82, 0x7c, - 0x00, 0x02, 0x82, 0xd8, 0x00, 0x02, 0x83, 0x0c, 0x00, 0x02, 0x83, 0x44, - 0x00, 0x02, 0x83, 0x74, 0x00, 0x02, 0x83, 0xa8, 0x00, 0x02, 0x83, 0xc8, - 0x00, 0x02, 0x83, 0xe4, 0x00, 0x02, 0x84, 0x24, 0x00, 0x02, 0x84, 0x40, - 0x00, 0x02, 0x84, 0x5c, 0x00, 0x02, 0x84, 0x78, 0x00, 0x02, 0x84, 0x94, - 0x00, 0x02, 0x84, 0xb0, 0x00, 0x02, 0x84, 0xcc, 0x00, 0x02, 0x84, 0xe8, - 0x00, 0x02, 0x85, 0x04, 0x00, 0x02, 0x85, 0x28, 0x00, 0x02, 0x85, 0x50, - 0x00, 0x02, 0x85, 0x74, 0x00, 0x02, 0x85, 0x9c, 0x00, 0x02, 0x85, 0xb0, - 0x00, 0x02, 0x85, 0xcc, 0x00, 0x02, 0x85, 0xe8, 0x00, 0x02, 0x86, 0x04, - 0x00, 0x02, 0x86, 0x20, 0x00, 0x02, 0x86, 0x3c, 0x00, 0x02, 0x86, 0x58, - 0x00, 0x02, 0x86, 0x74, 0x00, 0x02, 0x86, 0x90, 0x00, 0x02, 0x86, 0xac, - 0x00, 0x02, 0x86, 0xc8, 0x00, 0x02, 0x86, 0xe4, 0x00, 0x02, 0x87, 0x00, - 0x00, 0x02, 0x87, 0x1c, 0x00, 0x02, 0x87, 0x38, 0x00, 0x02, 0x87, 0x54, - 0x00, 0x02, 0x87, 0x68, 0x00, 0x02, 0x88, 0x1c, 0x00, 0x02, 0x89, 0xa4, - 0x00, 0x02, 0x8a, 0x4c, 0x00, 0x02, 0x8a, 0x60, 0x00, 0x02, 0x8a, 0x74, - 0x00, 0x02, 0x8a, 0x90, 0x00, 0x02, 0x8a, 0xac, 0x00, 0x02, 0x8a, 0xc8, - 0x00, 0x02, 0x8a, 0xec, 0x00, 0x02, 0x8b, 0x14, 0x00, 0x02, 0x8b, 0x38, - 0x00, 0x02, 0x8b, 0x5c, 0x00, 0x02, 0x8b, 0x78, 0x00, 0x02, 0x8b, 0xa4, - 0x00, 0x02, 0x8b, 0xc8, 0x00, 0x02, 0x8b, 0xe4, 0x00, 0x02, 0x8c, 0x10, - 0x00, 0x02, 0x8c, 0x64, 0x00, 0x02, 0x8c, 0x7c, 0x00, 0x02, 0x8c, 0xd4, - 0x00, 0x02, 0x8d, 0x30, 0x00, 0x02, 0x8e, 0x64, 0x00, 0x02, 0x8e, 0xec, - 0x00, 0x02, 0x8f, 0x74, 0x00, 0x02, 0x91, 0x14, 0x00, 0x02, 0x91, 0x30, - 0x00, 0x02, 0x91, 0x5c, 0x00, 0x02, 0x91, 0x78, 0x00, 0x02, 0x91, 0xa4, - 0x00, 0x02, 0x91, 0xc0, 0x00, 0x02, 0x91, 0xec, 0x00, 0x02, 0x92, 0x0c, - 0x00, 0x02, 0x92, 0x3c, 0x00, 0x02, 0x92, 0x58, 0x00, 0x02, 0x92, 0x80, - 0x00, 0x02, 0x92, 0x9c, 0x00, 0x02, 0x92, 0xc8, 0x00, 0x02, 0x92, 0xe4, - 0x00, 0x02, 0x93, 0x10, 0x00, 0x02, 0x93, 0x2c, 0x00, 0x02, 0x93, 0x58, - 0x00, 0x02, 0x93, 0x74, 0x00, 0x02, 0x93, 0x9c, 0x00, 0x02, 0x93, 0xb8, - 0x00, 0x02, 0x93, 0xe4, 0x00, 0x02, 0x94, 0x00, 0x00, 0x02, 0x94, 0x28, - 0x00, 0x02, 0x94, 0x44, 0x00, 0x02, 0x94, 0x70, 0x00, 0x02, 0x94, 0x8c, - 0x00, 0x02, 0x94, 0xb4, 0x00, 0x02, 0x94, 0xd0, 0x00, 0x02, 0x94, 0xf8, - 0x00, 0x02, 0x95, 0x18, 0x00, 0x02, 0x95, 0x4c, 0x00, 0x02, 0x95, 0x90, - 0x00, 0x02, 0x96, 0x1c, 0x00, 0x02, 0x96, 0x70, 0x00, 0x02, 0x96, 0xd4, - 0x00, 0x02, 0x97, 0xcc, 0x00, 0x02, 0x98, 0x80, 0x00, 0x02, 0x99, 0x34, - 0x00, 0x02, 0x99, 0x6c, 0x00, 0x02, 0x99, 0xc0, 0x00, 0x02, 0x9a, 0x14, - 0x00, 0x02, 0x9a, 0x6c, 0x00, 0x02, 0x9a, 0xc4, 0x00, 0x02, 0x9b, 0x28, - 0x00, 0x02, 0x9b, 0x78, 0x00, 0x02, 0x9b, 0xa0, 0x00, 0x02, 0x9b, 0xc8, - 0x00, 0x02, 0x9c, 0x08, 0x00, 0x02, 0x9c, 0x7c, 0x00, 0x02, 0x9c, 0xcc, - 0x00, 0x02, 0x9d, 0x20, 0x00, 0x02, 0x9d, 0x50, 0x00, 0x02, 0x9d, 0x7c, - 0x00, 0x02, 0x9d, 0xa8, 0x00, 0x02, 0x9d, 0xd4, 0x00, 0x02, 0x9e, 0x18, - 0x00, 0x02, 0x9e, 0x5c, 0x00, 0x02, 0x9e, 0x78, 0x00, 0x02, 0x9e, 0x94, - 0x00, 0x02, 0x9e, 0xac, 0x00, 0x02, 0x9e, 0xc4, 0x00, 0x02, 0x9f, 0x10, - 0x00, 0x02, 0x9f, 0x3c, 0x00, 0x02, 0x9f, 0x68, 0x00, 0x02, 0x9f, 0x90, - 0x00, 0x02, 0x9f, 0xb8, 0x00, 0x02, 0x9f, 0xf4, 0x00, 0x02, 0xa0, 0x40, - 0x00, 0x02, 0xa0, 0x6c, 0x00, 0x02, 0xa0, 0x94, 0x00, 0x02, 0xa0, 0xf8, - 0x00, 0x02, 0xa1, 0x38, 0x00, 0x02, 0xa1, 0x74, 0x00, 0x02, 0xa1, 0xb4, - 0x00, 0x02, 0xa1, 0xf4, 0x00, 0x02, 0xa2, 0x68, 0x00, 0x02, 0xa2, 0xdc, - 0x00, 0x02, 0xa3, 0x54, 0x00, 0x02, 0xa3, 0xcc, 0x00, 0x02, 0xa3, 0xf4, - 0x00, 0x02, 0xa4, 0x1c, 0x00, 0x02, 0xa4, 0x44, 0x00, 0x02, 0xa4, 0x70, - 0x00, 0x02, 0xa4, 0x8c, 0x00, 0x02, 0xa4, 0xb8, 0x00, 0x02, 0xa4, 0xd4, - 0x00, 0x02, 0xa4, 0xfc, 0x00, 0x02, 0xa5, 0xec, 0x00, 0x02, 0xa6, 0x58, - 0x00, 0x02, 0xa7, 0x0c, 0x00, 0x02, 0xab, 0x18, 0x00, 0x02, 0xad, 0xd8, - 0x00, 0x02, 0xae, 0x0c, 0x00, 0x02, 0xae, 0x68, 0x00, 0x02, 0xae, 0xb8, - 0x00, 0x02, 0xaf, 0x18, 0x00, 0x02, 0xaf, 0xa0, 0x00, 0x02, 0xb0, 0x68, - 0x00, 0x02, 0xb1, 0x30, 0x00, 0x02, 0xb1, 0x94, 0x00, 0x02, 0xb2, 0x30, - 0x00, 0x02, 0xb4, 0x64, 0x00, 0x02, 0xb7, 0x08, 0x00, 0x02, 0xb7, 0x40, - 0x00, 0x02, 0xb7, 0xb8, 0x00, 0x02, 0xb8, 0x2c, 0x00, 0x02, 0xb8, 0x84, - 0x00, 0x02, 0xb9, 0xdc, 0x00, 0x02, 0xbb, 0x74, 0x00, 0x02, 0xbb, 0xbc, - 0x00, 0x02, 0xbb, 0xf0, 0x00, 0x02, 0xbc, 0xbc, 0x00, 0x02, 0xbd, 0x80, - 0x00, 0x02, 0xbe, 0x18, 0x00, 0x02, 0xbe, 0xb0, 0x00, 0x02, 0xbf, 0x74, - 0x00, 0x02, 0xc0, 0x3c, 0x00, 0x02, 0xc1, 0x00, 0x00, 0x02, 0xc1, 0xc4, - 0x00, 0x02, 0xc5, 0x34, 0x00, 0x02, 0xc5, 0xb0, 0x00, 0x02, 0xc6, 0xc8, - 0x00, 0x02, 0xc8, 0x1c, 0x00, 0x02, 0xcb, 0x44, 0x00, 0x02, 0xcb, 0xc0, - 0x00, 0x02, 0xcc, 0x48, 0x00, 0x02, 0xcc, 0xb8, 0x00, 0x02, 0xcd, 0x1c, - 0x00, 0x02, 0xcd, 0xa0, 0x00, 0x02, 0xce, 0x30, 0x00, 0x02, 0xcf, 0x70, - 0x00, 0x02, 0xd0, 0x94, 0x00, 0x02, 0xd1, 0x2c, 0x00, 0x02, 0xd1, 0xb8, - 0x00, 0x02, 0xd2, 0x60, 0x00, 0x02, 0xd3, 0xd0, 0x00, 0x02, 0xd4, 0x8c, - 0x00, 0x02, 0xd5, 0x4c, 0x00, 0x02, 0xd5, 0xe0, 0x00, 0x02, 0xd6, 0xf8, - 0x00, 0x02, 0xd7, 0x8c, 0x00, 0x02, 0xd8, 0x20, 0x00, 0x02, 0xd8, 0xe0, - 0x00, 0x02, 0xd9, 0x60, 0x00, 0x02, 0xd9, 0xdc, 0x00, 0x02, 0xda, 0x68, - 0x00, 0x02, 0xda, 0xc8, 0x00, 0x02, 0xdb, 0x2c, 0x00, 0x02, 0xdb, 0xcc, - 0x00, 0x02, 0xdc, 0x78, 0x00, 0x02, 0xdc, 0xdc, 0x00, 0x02, 0xdd, 0x48, - 0x00, 0x02, 0xdd, 0xd8, 0x00, 0x02, 0xde, 0x38, 0x00, 0x02, 0xde, 0xf0, - 0x00, 0x02, 0xdf, 0xac, 0x00, 0x02, 0xe0, 0x70, 0x00, 0x02, 0xe0, 0xe0, - 0x00, 0x02, 0xe1, 0x80, 0x00, 0x02, 0xe1, 0xc8, 0x00, 0x02, 0xe2, 0x60, - 0x00, 0x02, 0xe3, 0x24, 0x00, 0x02, 0xe3, 0xa0, 0x00, 0x02, 0xe4, 0xc8, - 0x00, 0x02, 0xe6, 0xec, 0x00, 0x02, 0xe7, 0x84, 0x00, 0x02, 0xe8, 0xa0, - 0x00, 0x02, 0xe9, 0xb4, 0x00, 0x02, 0xea, 0xc4, 0x00, 0x02, 0xec, 0x50, - 0x00, 0x02, 0xed, 0x48, 0x00, 0x02, 0xed, 0xc8, 0x00, 0x02, 0xee, 0x8c, - 0x00, 0x02, 0xef, 0x54, 0x00, 0x02, 0xef, 0xe4, 0x00, 0x02, 0xf0, 0x54, - 0x00, 0x02, 0xf0, 0xf4, 0x00, 0x02, 0xf1, 0x3c, 0x00, 0x02, 0xf1, 0xdc, - 0x00, 0x02, 0xf2, 0xa0, 0x00, 0x02, 0xf2, 0xf4, 0x00, 0x02, 0xf3, 0x24, - 0x00, 0x02, 0xf4, 0x44, 0x00, 0x02, 0xf5, 0x28, 0x00, 0x02, 0xf5, 0x68, - 0x00, 0x02, 0xf5, 0xc4, 0x00, 0x02, 0xf6, 0x28, 0x00, 0x02, 0xf6, 0x88, - 0x00, 0x02, 0xf6, 0xd8, 0x00, 0x02, 0xf7, 0x28, 0x00, 0x02, 0xf7, 0xbc, - 0x00, 0x02, 0xf8, 0x7c, 0x00, 0x02, 0xf9, 0x60, 0x00, 0x02, 0xfb, 0x58, - 0x00, 0x02, 0xfc, 0x3c, 0x00, 0x02, 0xfd, 0x4c, 0x00, 0x02, 0xfe, 0x74, - 0x00, 0x02, 0xff, 0x60, 0x00, 0x03, 0x00, 0x70, 0x00, 0x03, 0x01, 0x90, - 0x00, 0x03, 0x02, 0x6c, 0x00, 0x03, 0x03, 0x2c, 0x00, 0x03, 0x04, 0x30, - 0x00, 0x03, 0x05, 0x60, 0x00, 0x03, 0x06, 0xac, 0x00, 0x03, 0x07, 0xa0, - 0x00, 0x03, 0x08, 0x38, 0x00, 0x03, 0x08, 0xa8, 0x00, 0x03, 0x09, 0x60, - 0x00, 0x03, 0x0a, 0x58, 0x00, 0x03, 0x0b, 0x98, 0x00, 0x03, 0x0d, 0x1c, - 0x00, 0x03, 0x0e, 0xe4, 0x00, 0x03, 0x0f, 0x78, 0x00, 0x03, 0x10, 0x30, - 0x00, 0x03, 0x10, 0x98, 0x00, 0x03, 0x11, 0x24, 0x00, 0x03, 0x11, 0x40, - 0x00, 0x03, 0x11, 0x68, 0x00, 0x03, 0x11, 0xc8, 0x00, 0x03, 0x12, 0x08, - 0x00, 0x03, 0x12, 0x7c, 0x00, 0x03, 0x13, 0x70, 0x00, 0x03, 0x14, 0xa4, - 0x00, 0x03, 0x15, 0xb8, 0x00, 0x03, 0x16, 0x60, 0x00, 0x03, 0x16, 0xdc, - 0x00, 0x03, 0x17, 0x7c, 0x00, 0x03, 0x18, 0x7c, 0x00, 0x03, 0x1a, 0x48, - 0x00, 0x03, 0x1c, 0xdc, 0x00, 0x03, 0x1e, 0x88, 0x00, 0x03, 0x1f, 0x0c, - 0x00, 0x03, 0x1f, 0x58, 0x00, 0x03, 0x1f, 0x80, 0x00, 0x03, 0x1f, 0xc8, - 0x00, 0x03, 0x21, 0x8c, 0x00, 0x03, 0x23, 0x28, 0x00, 0x03, 0x24, 0xe4, - 0x00, 0x03, 0x28, 0x9c, 0x00, 0x03, 0x2a, 0x44, 0x00, 0x03, 0x2b, 0xe8, - 0x00, 0x03, 0x2c, 0x70, 0x00, 0x03, 0x2d, 0x18, 0x00, 0x03, 0x2f, 0xbc, - 0x00, 0x03, 0x31, 0x58, 0x00, 0x03, 0x32, 0x88, 0x00, 0x03, 0x33, 0x84, - 0x00, 0x03, 0x34, 0xb0, 0x00, 0x03, 0x35, 0x90, 0x00, 0x03, 0x36, 0x14, - 0x00, 0x03, 0x36, 0x78, 0x00, 0x03, 0x36, 0xdc, 0x00, 0x03, 0x37, 0x20, - 0x00, 0x03, 0x37, 0x64, 0x00, 0x03, 0x38, 0x2c, 0x00, 0x03, 0x39, 0x20, - 0x00, 0x03, 0x39, 0xa0, 0x00, 0x03, 0x39, 0xd4, 0x00, 0x03, 0x3a, 0x10, - 0x00, 0x03, 0x3a, 0x54, 0x00, 0x03, 0x3a, 0x84, 0x00, 0x03, 0x3a, 0xe4, - 0x00, 0x03, 0x3b, 0x54, 0x00, 0x03, 0x3c, 0x3c, 0x00, 0x03, 0x3c, 0xcc, - 0x00, 0x03, 0x3d, 0x88, 0x00, 0x03, 0x3f, 0x08, 0x00, 0x03, 0x40, 0xd0, - 0x00, 0x03, 0x44, 0x28, 0x00, 0x03, 0x44, 0x90, 0x00, 0x03, 0x45, 0x54, - 0x00, 0x03, 0x45, 0xb8, 0x00, 0x03, 0x46, 0x4c, 0x00, 0x03, 0x46, 0xdc, - 0x00, 0x03, 0x47, 0x98, 0x00, 0x03, 0x48, 0x18, 0x00, 0x03, 0x48, 0x8c, - 0x00, 0x03, 0x49, 0x04, 0x00, 0x03, 0x49, 0x6c, 0x00, 0x03, 0x49, 0xb8, - 0x00, 0x03, 0x4a, 0x18, 0x00, 0x03, 0x4a, 0x7c, 0x00, 0x03, 0x4a, 0xd4, - 0x00, 0x03, 0x4b, 0x84, 0x00, 0x03, 0x4b, 0xc8, 0x00, 0x03, 0x4c, 0x18, - 0x00, 0x03, 0x4c, 0x68, 0x00, 0x03, 0x4c, 0xd0, 0x00, 0x03, 0x4d, 0x7c, - 0x00, 0x03, 0x4f, 0x30, 0x00, 0x03, 0x51, 0x30, 0x00, 0x03, 0x52, 0x70, - 0x00, 0x03, 0x54, 0xa0, 0x00, 0x03, 0x56, 0x3c, 0x00, 0x03, 0x59, 0x08, - 0x00, 0x03, 0x5f, 0x04, 0x00, 0x03, 0x60, 0x60, 0x00, 0x03, 0x62, 0xb0, - 0x00, 0x03, 0x63, 0x70, 0x00, 0x03, 0x64, 0x28, 0x00, 0x03, 0x64, 0xec, - 0x00, 0x03, 0x66, 0x6c, 0x00, 0x03, 0x67, 0xe8, 0x00, 0x03, 0x69, 0x3c, - 0x00, 0x03, 0x6a, 0x8c, 0x00, 0x03, 0x6b, 0xd0, 0x00, 0x03, 0x6c, 0x48, - 0x00, 0x03, 0x6c, 0x7c, 0x00, 0x03, 0x6c, 0xb0, 0x00, 0x03, 0x6c, 0xe0, - 0x00, 0x03, 0x6d, 0x10, 0x00, 0x03, 0x6d, 0x68, 0x00, 0x03, 0x6d, 0x84, - 0x00, 0x03, 0x6d, 0xa0, 0x00, 0x03, 0x6d, 0xbc, 0x00, 0x03, 0x6d, 0xe0, - 0x00, 0x03, 0x6e, 0x04, 0x00, 0x03, 0x6e, 0x20, 0x00, 0x03, 0x6e, 0x3c, - 0x00, 0x03, 0x6f, 0x34, 0x00, 0x03, 0x6f, 0xe0, 0x00, 0x03, 0x70, 0xb4, - 0x00, 0x03, 0x71, 0x30, 0x00, 0x03, 0x71, 0xb0, 0x00, 0x03, 0x72, 0xd0, - 0x00, 0x03, 0x73, 0xb4, 0x00, 0x03, 0x74, 0x20, 0x00, 0x03, 0x74, 0x8c, - 0x00, 0x03, 0x74, 0xc8, 0x00, 0x03, 0x75, 0x08, 0x00, 0x03, 0x75, 0x30, - 0x00, 0x03, 0x75, 0x58, 0x00, 0x03, 0x75, 0x80, 0x00, 0x03, 0x75, 0xa8, - 0x00, 0x03, 0x75, 0xd0, 0x00, 0x03, 0x75, 0xf8, 0x00, 0x03, 0x76, 0x20, - 0x00, 0x03, 0x76, 0x48, 0x00, 0x03, 0x76, 0xac, 0x00, 0x03, 0x77, 0x1c, - 0x00, 0x03, 0x77, 0x4c, 0x00, 0x03, 0x77, 0x78, 0x00, 0x03, 0x77, 0xa4, - 0x00, 0x03, 0x77, 0xd0, 0x00, 0x03, 0x78, 0x00, 0x00, 0x03, 0x78, 0xa4, - 0x00, 0x03, 0x78, 0xcc, 0x00, 0x03, 0x78, 0xf4, 0x00, 0x03, 0x79, 0x44, - 0x00, 0x03, 0x79, 0x94, 0x00, 0x03, 0x79, 0xbc, 0x00, 0x03, 0x79, 0xec, - 0x00, 0x03, 0x7a, 0x1c, 0x00, 0x03, 0x7a, 0x40, 0x00, 0x03, 0x7a, 0x94, - 0x00, 0x03, 0x7a, 0xe8, 0x00, 0x03, 0x7b, 0x14, 0x00, 0x03, 0x7b, 0x40, - 0x00, 0x03, 0x7b, 0x84, 0x00, 0x03, 0x7b, 0xc8, 0x00, 0x03, 0x7c, 0x18, - 0x00, 0x03, 0x7c, 0x64, 0x00, 0x03, 0x7c, 0xb0, 0x00, 0x03, 0x7c, 0xfc, - 0x00, 0x03, 0x7d, 0x50, 0x00, 0x03, 0x7d, 0xa4, 0x00, 0x03, 0x7e, 0x18, - 0x00, 0x03, 0x7e, 0xb4, 0x00, 0x03, 0x7f, 0x0c, 0x00, 0x03, 0x7f, 0x54, - 0x00, 0x03, 0x7f, 0xac, 0x00, 0x03, 0x80, 0x54, 0x00, 0x03, 0x80, 0xec, - 0x00, 0x03, 0x81, 0x90, 0x00, 0x03, 0x82, 0x6c, 0x00, 0x03, 0x83, 0x08, - 0x00, 0x03, 0x84, 0x34, 0x00, 0x03, 0x85, 0x68, 0x00, 0x03, 0x86, 0x00, - 0x00, 0x03, 0x86, 0x10, 0x00, 0x03, 0x86, 0x70, 0x00, 0x03, 0x86, 0xd0, - 0x00, 0x03, 0x87, 0x0c, 0x00, 0x03, 0x87, 0x40, 0x00, 0x03, 0x87, 0x74, - 0x00, 0x03, 0x87, 0x9c, 0x00, 0x03, 0x87, 0xc4, 0x00, 0x03, 0x87, 0xe4, - 0x00, 0x03, 0x88, 0x28, 0x00, 0x03, 0x88, 0x7c, 0x00, 0x03, 0x88, 0x8c, - 0x00, 0x03, 0x88, 0xa4, 0x00, 0x03, 0x88, 0xc4, 0x00, 0x03, 0x88, 0xec, - 0x00, 0x03, 0x89, 0x14, 0x00, 0x03, 0x89, 0x3c, 0x00, 0x03, 0x89, 0x68, - 0x00, 0x03, 0x89, 0x94, 0x00, 0x03, 0x89, 0xc0, 0x00, 0x03, 0x89, 0xec, - 0x00, 0x03, 0x8a, 0x20, 0x00, 0x03, 0x8a, 0x54, 0x00, 0x03, 0x8a, 0x80, - 0x00, 0x03, 0x8a, 0xac, 0x00, 0x03, 0x8a, 0xd4, 0x00, 0x03, 0x8a, 0xfc, - 0x00, 0x03, 0x8b, 0x2c, 0x00, 0x03, 0x8b, 0x5c, 0x00, 0x03, 0x8b, 0x8c, - 0x00, 0x03, 0x8b, 0xbc, 0x00, 0x03, 0x8c, 0x60, 0x00, 0x03, 0x8c, 0xdc, - 0x00, 0x03, 0x8d, 0x50, 0x00, 0x03, 0x8d, 0xa4, 0x00, 0x03, 0x8d, 0xdc, - 0x00, 0x03, 0x8e, 0x50, 0x00, 0x03, 0x8e, 0x74, 0x00, 0x03, 0x8e, 0x9c, - 0x00, 0x03, 0x8f, 0x1c, 0x00, 0x03, 0x8f, 0x6c, 0x00, 0x03, 0x8f, 0xe0, - 0x00, 0x03, 0x8f, 0xf4, 0x00, 0x03, 0x90, 0x1c, 0x00, 0x03, 0x90, 0xc4, - 0x00, 0x03, 0x91, 0x1c, 0x00, 0x03, 0x91, 0x98, 0x00, 0x03, 0x91, 0xb0, - 0x00, 0x03, 0x91, 0xd0, 0x00, 0x03, 0x91, 0xf0, 0x00, 0x03, 0x92, 0x10, - 0x00, 0x03, 0x92, 0x30, 0x00, 0x03, 0x92, 0x40, 0x00, 0x03, 0x92, 0x68, - 0x00, 0x03, 0x92, 0x90, 0x00, 0x03, 0x92, 0xb8, 0x00, 0x03, 0x92, 0xe0, - 0x00, 0x03, 0x93, 0x08, 0x00, 0x03, 0x93, 0x30, 0x00, 0x03, 0x93, 0x58, - 0x00, 0x03, 0x93, 0x80, 0x00, 0x03, 0x93, 0xa8, 0x00, 0x03, 0x93, 0xcc, - 0x00, 0x03, 0x93, 0xec, 0x00, 0x03, 0x94, 0x10, 0x00, 0x03, 0x94, 0x34, - 0x00, 0x03, 0x94, 0x58, 0x00, 0x03, 0x94, 0x78, 0x00, 0x03, 0x94, 0xa4, - 0x00, 0x03, 0x94, 0xd0, 0x00, 0x03, 0x94, 0xfc, 0x00, 0x03, 0x95, 0x28, - 0x00, 0x03, 0x95, 0x3c, 0x00, 0x03, 0x95, 0x80, 0x00, 0x03, 0x95, 0xc4, - 0x00, 0x03, 0x95, 0xf4, 0x00, 0x03, 0x96, 0x24, 0x00, 0x03, 0x96, 0x70, - 0x00, 0x03, 0x96, 0xcc, 0x00, 0x03, 0x96, 0xdc, 0x00, 0x03, 0x97, 0x04, - 0x00, 0x03, 0x97, 0x28, 0x00, 0x03, 0x97, 0x58, 0x00, 0x03, 0x97, 0x68, - 0x00, 0x03, 0x97, 0xc8, 0x00, 0x03, 0x98, 0x00, 0x00, 0x03, 0x98, 0x4c, - 0x00, 0x03, 0x98, 0x90, 0x00, 0x03, 0x99, 0x08, 0x00, 0x03, 0x99, 0xa8, - 0x00, 0x03, 0x9a, 0x30, 0x00, 0x03, 0x9a, 0x48, 0x00, 0x03, 0x9a, 0x60, - 0x00, 0x03, 0x9a, 0x78, 0x00, 0x03, 0x9a, 0x90, 0x00, 0x03, 0x9a, 0xa8, - 0x00, 0x03, 0x9a, 0xc0, 0x00, 0x03, 0x9a, 0xd8, 0x00, 0x03, 0x9a, 0xf0, - 0x00, 0x03, 0x9b, 0x08, 0x00, 0x03, 0x9b, 0x20, 0x00, 0x03, 0x9b, 0x38, - 0x00, 0x03, 0x9b, 0x50, 0x00, 0x03, 0x9b, 0x68, 0x00, 0x03, 0x9b, 0x80, - 0x00, 0x03, 0x9b, 0x98, 0x00, 0x03, 0x9b, 0xb0, 0x00, 0x03, 0x9b, 0xc8, - 0x00, 0x03, 0x9b, 0xe0, 0x00, 0x03, 0x9b, 0xf8, 0x00, 0x03, 0x9c, 0x10, - 0x00, 0x03, 0x9c, 0x28, 0x00, 0x03, 0x9c, 0x40, 0x00, 0x03, 0x9c, 0x58, - 0x00, 0x03, 0x9c, 0x70, 0x00, 0x03, 0x9c, 0x88, 0x00, 0x03, 0x9c, 0xa0, - 0x00, 0x03, 0x9c, 0xb8, 0x00, 0x03, 0x9c, 0xd0, 0x00, 0x03, 0x9c, 0xe8, - 0x00, 0x03, 0x9d, 0x00, 0x00, 0x03, 0x9d, 0x18, 0x00, 0x03, 0x9d, 0x30, - 0x00, 0x03, 0x9d, 0x48, 0x00, 0x03, 0x9d, 0x60, 0x00, 0x03, 0x9d, 0x78, - 0x00, 0x03, 0x9d, 0x90, 0x00, 0x03, 0x9d, 0xa8, 0x00, 0x03, 0x9d, 0xc0, - 0x00, 0x03, 0x9d, 0xd8, 0x00, 0x03, 0x9d, 0xf0, 0x00, 0x03, 0x9e, 0x08, - 0x00, 0x03, 0x9e, 0x20, 0x00, 0x03, 0x9e, 0x38, 0x00, 0x03, 0x9e, 0x50, - 0x00, 0x03, 0x9e, 0x68, 0x00, 0x03, 0x9e, 0x80, 0x00, 0x03, 0x9e, 0x98, - 0x00, 0x03, 0x9e, 0xb0, 0x00, 0x03, 0x9e, 0xc8, 0x00, 0x03, 0x9e, 0xe0, - 0x00, 0x03, 0x9e, 0xf8, 0x00, 0x03, 0x9f, 0x10, 0x00, 0x03, 0x9f, 0x20, - 0x00, 0x03, 0x9f, 0xbc, 0x00, 0x03, 0x9f, 0xcc, 0x00, 0x03, 0x9f, 0xdc, - 0x00, 0x03, 0x9f, 0xf4, 0x00, 0x03, 0xa0, 0x0c, 0x00, 0x03, 0xa0, 0x24, - 0x00, 0x03, 0xa0, 0x3c, 0x00, 0x03, 0xa0, 0x4c, 0x00, 0x03, 0xa0, 0xc4, - 0x00, 0x03, 0xa0, 0xd4, 0x00, 0x03, 0xa1, 0xa4, 0x00, 0x03, 0xa1, 0xb4, - 0x00, 0x03, 0xa2, 0x68, 0x00, 0x03, 0xa2, 0x9c, 0x00, 0x03, 0xa2, 0xe0, - 0x00, 0x03, 0xa2, 0xf0, 0x00, 0x03, 0xa3, 0x00, 0x00, 0x03, 0xa3, 0x18, - 0x00, 0x03, 0xa3, 0x30, 0x00, 0x03, 0xa3, 0x40, 0x00, 0x03, 0xa3, 0x58, - 0x00, 0x03, 0xa3, 0x68, 0x00, 0x03, 0xa3, 0x9c, 0x00, 0x03, 0xa3, 0xac, - 0x00, 0x03, 0xa3, 0xbc, 0x00, 0x03, 0xa3, 0xd4, 0x00, 0x03, 0xa3, 0xe4, - 0x00, 0x03, 0xa3, 0xfc, 0x00, 0x03, 0xa4, 0x0c, 0x00, 0x03, 0xa4, 0x24, - 0x00, 0x03, 0xa4, 0x34, 0x00, 0x03, 0xa4, 0x4c, 0x00, 0x03, 0xa4, 0x5c, - 0x00, 0x03, 0xa4, 0x74, 0x00, 0x03, 0xa4, 0x84, 0x00, 0x03, 0xa4, 0x9c, - 0x00, 0x03, 0xa4, 0xb4, 0x00, 0x03, 0xa4, 0xcc, 0x00, 0x03, 0xa4, 0xe4, - 0x00, 0x03, 0xa4, 0xfc, 0x00, 0x03, 0xa5, 0x14, 0x00, 0x03, 0xa5, 0x2c, - 0x00, 0x03, 0xa5, 0x44, 0x00, 0x03, 0xa5, 0x5c, 0x00, 0x03, 0xa5, 0x74, - 0x00, 0x03, 0xa5, 0x8c, 0x00, 0x03, 0xa5, 0xa4, 0x00, 0x03, 0xa5, 0xb4, - 0x00, 0x03, 0xa5, 0xe8, 0x00, 0x03, 0xa6, 0x00, 0x00, 0x03, 0xa6, 0x18, - 0x00, 0x03, 0xa6, 0x30, 0x00, 0x03, 0xa6, 0x48, 0x00, 0x03, 0xa6, 0x60, - 0x00, 0x03, 0xa6, 0x78, 0x00, 0x03, 0xa6, 0x90, 0x00, 0x03, 0xa6, 0xa8, - 0x00, 0x03, 0xa6, 0xc0, 0x00, 0x03, 0xa6, 0xd8, 0x00, 0x03, 0xa6, 0xf0, - 0x00, 0x03, 0xa7, 0x08, 0x00, 0x03, 0xa7, 0x20, 0x00, 0x03, 0xa7, 0x38, - 0x00, 0x03, 0xa7, 0x50, 0x00, 0x03, 0xa7, 0x68, 0x00, 0x03, 0xa7, 0x80, - 0x00, 0x03, 0xa7, 0x98, 0x00, 0x03, 0xa7, 0xa8, 0x00, 0x03, 0xa8, 0x40, - 0x00, 0x03, 0xa8, 0xa8, 0x00, 0x03, 0xa9, 0x2c, 0x00, 0x03, 0xa9, 0x44, - 0x00, 0x03, 0xa9, 0x5c, 0x00, 0x03, 0xa9, 0x74, 0x00, 0x03, 0xa9, 0x8c, - 0x00, 0x03, 0xa9, 0x9c, 0x00, 0x03, 0xaa, 0x04, 0x00, 0x03, 0xaa, 0x1c, - 0x00, 0x03, 0xaa, 0x34, 0x00, 0x03, 0xaa, 0x44, 0x00, 0x03, 0xaa, 0x9c, - 0x00, 0x03, 0xaa, 0xb4, 0x00, 0x03, 0xaa, 0xcc, 0x00, 0x03, 0xaa, 0xdc, - 0x00, 0x03, 0xab, 0xb0, 0x00, 0x03, 0xac, 0x40, 0x00, 0x03, 0xac, 0xe0, - 0x00, 0x03, 0xac, 0xf8, 0x00, 0x03, 0xad, 0x10, 0x00, 0x03, 0xad, 0x28, - 0x00, 0x03, 0xad, 0x40, 0x00, 0x03, 0xad, 0x50, 0x00, 0x03, 0xae, 0x20, - 0x00, 0x03, 0xae, 0xa4, 0x00, 0x03, 0xaf, 0x40, 0x00, 0x03, 0xaf, 0x58, - 0x00, 0x03, 0xaf, 0x70, 0x00, 0x03, 0xaf, 0x88, 0x00, 0x03, 0xaf, 0xa0, - 0x00, 0x03, 0xaf, 0xb0, 0x00, 0x03, 0xb0, 0x28, 0x00, 0x03, 0xb0, 0x8c, - 0x00, 0x03, 0xb1, 0x04, 0x00, 0x03, 0xb1, 0x1c, 0x00, 0x03, 0xb1, 0x34, - 0x00, 0x03, 0xb1, 0x4c, 0x00, 0x03, 0xb1, 0x64, 0x00, 0x03, 0xb1, 0x74, - 0x00, 0x03, 0xb2, 0x20, 0x00, 0x03, 0xb2, 0x78, 0x00, 0x03, 0xb3, 0x08, - 0x00, 0x03, 0xb3, 0x20, 0x00, 0x03, 0xb3, 0x38, 0x00, 0x03, 0xb3, 0x50, - 0x00, 0x03, 0xb3, 0x68, 0x00, 0x03, 0xb3, 0x80, 0x00, 0x03, 0xb3, 0x98, - 0x00, 0x03, 0xb3, 0xb0, 0x00, 0x03, 0xb3, 0xc8, 0x00, 0x03, 0xb3, 0xe0, - 0x00, 0x03, 0xb3, 0xf8, 0x00, 0x03, 0xb4, 0x10, 0x00, 0x03, 0xb4, 0x28, - 0x00, 0x03, 0xb4, 0x38, 0x00, 0x03, 0xb5, 0x04, 0x00, 0x03, 0xb5, 0x70, - 0x00, 0x03, 0xb5, 0xf8, 0x00, 0x03, 0xb6, 0x08, 0x00, 0x03, 0xb6, 0x7c, - 0x00, 0x03, 0xb6, 0xb4, 0x00, 0x03, 0xb6, 0xfc, 0x00, 0x03, 0xb7, 0x0c, - 0x00, 0x03, 0xb7, 0xa8, 0x00, 0x03, 0xb8, 0x2c, 0x00, 0x03, 0xb8, 0xbc, - 0x00, 0x03, 0xb8, 0xd4, 0x00, 0x03, 0xb8, 0xec, 0x00, 0x03, 0xb9, 0x04, - 0x00, 0x03, 0xb9, 0x1c, 0x00, 0x03, 0xb9, 0x2c, 0x00, 0x03, 0xb9, 0xa4, - 0x00, 0x03, 0xba, 0x60, 0x00, 0x03, 0xba, 0xf0, 0x00, 0x03, 0xbb, 0x00, - 0x00, 0x03, 0xbb, 0x94, 0x00, 0x03, 0xbb, 0xa4, 0x00, 0x03, 0xbc, 0x48, - 0x00, 0x03, 0xbc, 0x60, 0x00, 0x03, 0xbc, 0x78, 0x00, 0x03, 0xbc, 0x90, - 0x00, 0x03, 0xbc, 0xa8, 0x00, 0x03, 0xbc, 0xc0, 0x00, 0x03, 0xbc, 0xd8, - 0x00, 0x03, 0xbc, 0xf0, 0x00, 0x03, 0xbd, 0x08, 0x00, 0x03, 0xbd, 0x20, - 0x00, 0x03, 0xbd, 0x38, 0x00, 0x03, 0xbd, 0x8c, 0x00, 0x03, 0xbd, 0xf4, - 0x00, 0x03, 0xbd, 0xf4, 0x00, 0x03, 0xbd, 0xf4, 0x00, 0x03, 0xbd, 0xf4, - 0x00, 0x03, 0xbd, 0xf4, 0x00, 0x03, 0xbd, 0xf4, 0x00, 0x03, 0xbe, 0x84, - 0x00, 0x03, 0xbe, 0xcc, 0x00, 0x03, 0xbe, 0xdc, 0x00, 0x03, 0xbe, 0xec, - 0x00, 0x03, 0xbe, 0xfc, 0x00, 0x03, 0xbf, 0x0c, 0x00, 0x03, 0xbf, 0x1c, - 0x00, 0x03, 0xbf, 0x2c, 0x00, 0x03, 0xbf, 0x3c, 0x00, 0x03, 0xbf, 0x4c, - 0x00, 0x03, 0xbf, 0x5c, 0x00, 0x03, 0xbf, 0x6c, 0x00, 0x03, 0xbf, 0x7c, - 0x00, 0x03, 0xbf, 0x8c, 0x00, 0x03, 0xbf, 0x9c, 0x00, 0x03, 0xbf, 0xac, - 0x00, 0x03, 0xbf, 0xbc, 0x00, 0x03, 0xbf, 0xcc, 0x00, 0x03, 0xbf, 0xdc, - 0x00, 0x03, 0xbf, 0xec, 0x00, 0x03, 0xbf, 0xfc, 0x00, 0x03, 0xc0, 0x0c, - 0x00, 0x03, 0xc0, 0x1c, 0x00, 0x03, 0xc0, 0x2c, 0x00, 0x03, 0xc0, 0x3c, - 0x00, 0x03, 0xc0, 0x4c, 0x00, 0x03, 0xc0, 0x5c, 0x00, 0x03, 0xc0, 0x6c, - 0x00, 0x03, 0xc0, 0x7c, 0x00, 0x03, 0xc0, 0x8c, 0x00, 0x03, 0xc0, 0x9c, - 0x00, 0x03, 0xc0, 0xac, 0x00, 0x03, 0xc0, 0xbc, 0x00, 0x03, 0xc0, 0xcc, - 0x00, 0x03, 0xc0, 0xdc, 0x00, 0x03, 0xc0, 0xec, 0x00, 0x03, 0xc0, 0xfc, - 0x00, 0x03, 0xc1, 0x0c, 0x00, 0x03, 0xc1, 0x1c, 0x00, 0x03, 0xc1, 0x2c, - 0x00, 0x03, 0xc1, 0x3c, 0x00, 0x03, 0xc1, 0x4c, 0x00, 0x03, 0xc1, 0x5c, - 0x00, 0x03, 0xc1, 0x6c, 0x00, 0x03, 0xc1, 0x7c, 0x00, 0x03, 0xc1, 0x8c, - 0x00, 0x03, 0xc1, 0x9c, 0x00, 0x03, 0xc1, 0xac, 0x00, 0x03, 0xc1, 0xbc, - 0x00, 0x03, 0xc1, 0xcc, 0x00, 0x03, 0xc1, 0xdc, 0x00, 0x03, 0xc1, 0xec, - 0x00, 0x03, 0xc1, 0xfc, 0x00, 0x03, 0xc2, 0x0c, 0x00, 0x03, 0xc2, 0x1c, - 0x00, 0x03, 0xc2, 0x2c, 0x00, 0x03, 0xc2, 0x3c, 0x00, 0x03, 0xc2, 0x4c, - 0x00, 0x03, 0xc2, 0x5c, 0x00, 0x03, 0xc2, 0x6c, 0x00, 0x03, 0xc2, 0x7c, - 0x00, 0x03, 0xc2, 0x8c, 0x00, 0x03, 0xc2, 0x9c, 0x00, 0x03, 0xc2, 0xac, - 0x00, 0x03, 0xc2, 0xd8, 0x00, 0x03, 0xc3, 0x50, 0x00, 0x03, 0xc3, 0xd8, - 0x00, 0x03, 0xc5, 0x04, 0x00, 0x03, 0xc5, 0x8c, 0x00, 0x03, 0xc6, 0x0c, - 0x00, 0x03, 0xc6, 0x9c, 0x00, 0x03, 0xc6, 0xd4, 0x00, 0x03, 0xc7, 0x08, - 0x00, 0x03, 0xc7, 0x5c, 0x00, 0x03, 0xc7, 0x88, 0x00, 0x03, 0xc7, 0xcc, - 0x00, 0x03, 0xc7, 0xf8, 0x00, 0x03, 0xc8, 0x7c, 0x00, 0x03, 0xc8, 0xa8, - 0x00, 0x03, 0xc8, 0xc4, 0x00, 0x03, 0xc8, 0xe0, 0x00, 0x03, 0xc8, 0xfc, - 0x00, 0x03, 0xc9, 0x44, 0x00, 0x03, 0xc9, 0x6c, 0x00, 0x03, 0xc9, 0x84, - 0x00, 0x03, 0xc9, 0xa8, 0x00, 0x03, 0xc9, 0xd8, 0x00, 0x03, 0xca, 0x4c, - 0x00, 0x03, 0xca, 0xe8, 0x00, 0x03, 0xcb, 0x84, 0x00, 0x03, 0xcc, 0x48, - 0x00, 0x03, 0xcd, 0x00, 0x00, 0x03, 0xcd, 0x30, 0x00, 0x03, 0xcd, 0x54, - 0x00, 0x03, 0xcd, 0x8c, 0x00, 0x03, 0xcd, 0xac, 0x00, 0x03, 0xcd, 0xcc, - 0x00, 0x03, 0xce, 0x1c, 0x00, 0x03, 0xce, 0xa8, 0x00, 0x03, 0xce, 0xfc, - 0x00, 0x03, 0xcf, 0xac, 0x00, 0x03, 0xcf, 0xcc, 0x00, 0x03, 0xcf, 0xe4, - 0x00, 0x03, 0xcf, 0xfc, 0x00, 0x03, 0xd0, 0x14, 0x00, 0x03, 0xd0, 0x2c, - 0x00, 0x03, 0xd0, 0x44, 0x00, 0x03, 0xd0, 0xf4, 0x00, 0x03, 0xd1, 0x0c, - 0x00, 0x03, 0xd1, 0x6c, 0x00, 0x03, 0xd1, 0x84, 0x00, 0x03, 0xd1, 0x9c, - 0x00, 0x03, 0xd1, 0xac, 0x00, 0x01, 0x00, 0x00, 0x0c, 0xee, 0x02, 0x0c, - 0x00, 0x2b, 0x00, 0x6b, 0x00, 0x06, 0x00, 0x02, 0x00, 0x10, 0x00, 0x99, - 0x00, 0x08, 0x00, 0x00, 0x05, 0x57, 0x01, 0x11, 0x00, 0x05, 0x00, 0x04, - 0x00, 0x00, 0x00, 0x16, 0x01, 0x0e, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x5f, 0x00, 0xc0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x10, 0x01, 0x42, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x04, 0x01, 0x5d, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x10, 0x01, 0x84, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x00, 0x10, 0x01, 0xb7, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x05, 0x00, 0x0c, 0x01, 0xe2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x06, 0x00, 0x0e, 0x02, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x00, 0x11, 0x02, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0b, 0x00, 0x1d, 0x02, 0x8e, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0d, 0x09, 0x93, 0x15, 0xd4, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x0e, 0x00, 0x34, 0x1f, 0xd2, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, - 0x00, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, - 0x00, 0x01, 0x00, 0x20, 0x01, 0x20, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, - 0x00, 0x02, 0x00, 0x08, 0x01, 0x53, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, - 0x00, 0x03, 0x00, 0x20, 0x01, 0x62, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, - 0x00, 0x04, 0x00, 0x20, 0x01, 0x95, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, - 0x00, 0x05, 0x00, 0x18, 0x01, 0xc8, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, - 0x00, 0x06, 0x00, 0x1c, 0x01, 0xef, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, - 0x00, 0x08, 0x00, 0x22, 0x02, 0x1c, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, - 0x00, 0x0b, 0x00, 0x3a, 0x02, 0x52, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, - 0x00, 0x0d, 0x13, 0x26, 0x02, 0xac, 0x00, 0x03, 0x00, 0x01, 0x04, 0x09, - 0x00, 0x0e, 0x00, 0x68, 0x1f, 0x68, 0x00, 0x43, 0x00, 0x6f, 0x00, 0x70, - 0x00, 0x79, 0x00, 0x72, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68, 0x00, 0x74, - 0x00, 0x20, 0x00, 0x28, 0x00, 0x63, 0x00, 0x29, 0x00, 0x20, 0x00, 0x32, - 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x20, 0x00, 0x62, 0x00, 0x79, - 0x00, 0x20, 0x00, 0x42, 0x00, 0x69, 0x00, 0x74, 0x00, 0x73, 0x00, 0x74, - 0x00, 0x72, 0x00, 0x65, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x2c, 0x00, 0x20, - 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x20, 0x00, 0x41, - 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x52, 0x00, 0x69, 0x00, 0x67, - 0x00, 0x68, 0x00, 0x74, 0x00, 0x73, 0x00, 0x20, 0x00, 0x52, 0x00, 0x65, - 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x76, 0x00, 0x65, 0x00, 0x64, - 0x00, 0x2e, 0x00, 0x0a, 0x00, 0x44, 0x00, 0x65, 0x00, 0x6a, 0x00, 0x61, - 0x00, 0x56, 0x00, 0x75, 0x00, 0x20, 0x00, 0x63, 0x00, 0x68, 0x00, 0x61, - 0x00, 0x6e, 0x00, 0x67, 0x00, 0x65, 0x00, 0x73, 0x00, 0x20, 0x00, 0x61, - 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x20, - 0x00, 0x70, 0x00, 0x75, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x63, - 0x00, 0x20, 0x00, 0x64, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x69, - 0x00, 0x6e, 0x00, 0x0a, 0x00, 0x00, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, - 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x33, - 0x20, 0x62, 0x79, 0x20, 0x42, 0x69, 0x74, 0x73, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x41, 0x6c, 0x6c, 0x20, - 0x52, 0x69, 0x67, 0x68, 0x74, 0x73, 0x20, 0x52, 0x65, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x64, 0x2e, 0x0a, 0x44, 0x65, 0x6a, 0x61, 0x56, 0x75, 0x20, - 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, - 0x69, 0x6e, 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x64, 0x6f, - 0x6d, 0x61, 0x69, 0x6e, 0x0a, 0x00, 0x00, 0x44, 0x00, 0x65, 0x00, 0x6a, - 0x00, 0x61, 0x00, 0x56, 0x00, 0x75, 0x00, 0x20, 0x00, 0x53, 0x00, 0x61, - 0x00, 0x6e, 0x00, 0x73, 0x00, 0x20, 0x00, 0x4d, 0x00, 0x6f, 0x00, 0x6e, - 0x00, 0x6f, 0x00, 0x00, 0x44, 0x65, 0x6a, 0x61, 0x56, 0x75, 0x20, 0x53, - 0x61, 0x6e, 0x73, 0x20, 0x4d, 0x6f, 0x6e, 0x6f, 0x00, 0x00, 0x42, 0x00, - 0x6f, 0x00, 0x6f, 0x00, 0x6b, 0x00, 0x00, 0x42, 0x6f, 0x6f, 0x6b, 0x00, - 0x00, 0x44, 0x00, 0x65, 0x00, 0x6a, 0x00, 0x61, 0x00, 0x56, 0x00, 0x75, - 0x00, 0x20, 0x00, 0x53, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x20, - 0x00, 0x4d, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x00, 0x44, 0x65, - 0x6a, 0x61, 0x56, 0x75, 0x20, 0x53, 0x61, 0x6e, 0x73, 0x20, 0x4d, 0x6f, - 0x6e, 0x6f, 0x00, 0x00, 0x44, 0x00, 0x65, 0x00, 0x6a, 0x00, 0x61, 0x00, - 0x56, 0x00, 0x75, 0x00, 0x20, 0x00, 0x53, 0x00, 0x61, 0x00, 0x6e, 0x00, - 0x73, 0x00, 0x20, 0x00, 0x4d, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x6f, 0x00, - 0x00, 0x44, 0x65, 0x6a, 0x61, 0x56, 0x75, 0x20, 0x53, 0x61, 0x6e, 0x73, - 0x20, 0x4d, 0x6f, 0x6e, 0x6f, 0x00, 0x00, 0x56, 0x00, 0x65, 0x00, 0x72, - 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x32, - 0x00, 0x2e, 0x00, 0x33, 0x00, 0x34, 0x00, 0x00, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x20, 0x32, 0x2e, 0x33, 0x34, 0x00, 0x00, 0x44, 0x00, - 0x65, 0x00, 0x6a, 0x00, 0x61, 0x00, 0x56, 0x00, 0x75, 0x00, 0x53, 0x00, - 0x61, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x4d, 0x00, 0x6f, 0x00, 0x6e, 0x00, - 0x6f, 0x00, 0x00, 0x44, 0x65, 0x6a, 0x61, 0x56, 0x75, 0x53, 0x61, 0x6e, - 0x73, 0x4d, 0x6f, 0x6e, 0x6f, 0x00, 0x00, 0x44, 0x00, 0x65, 0x00, 0x6a, - 0x00, 0x61, 0x00, 0x56, 0x00, 0x75, 0x00, 0x20, 0x00, 0x66, 0x00, 0x6f, - 0x00, 0x6e, 0x00, 0x74, 0x00, 0x73, 0x00, 0x20, 0x00, 0x74, 0x00, 0x65, - 0x00, 0x61, 0x00, 0x6d, 0x00, 0x00, 0x44, 0x65, 0x6a, 0x61, 0x56, 0x75, - 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x65, 0x61, 0x6d, 0x00, - 0x00, 0x68, 0x00, 0x74, 0x00, 0x74, 0x00, 0x70, 0x00, 0x3a, 0x00, 0x2f, - 0x00, 0x2f, 0x00, 0x64, 0x00, 0x65, 0x00, 0x6a, 0x00, 0x61, 0x00, 0x76, - 0x00, 0x75, 0x00, 0x2e, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x72, - 0x00, 0x63, 0x00, 0x65, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x67, - 0x00, 0x65, 0x00, 0x2e, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x74, 0x00, 0x00, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x6a, 0x61, 0x76, - 0x75, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x66, 0x6f, 0x72, 0x67, - 0x65, 0x2e, 0x6e, 0x65, 0x74, 0x00, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x6e, - 0x00, 0x74, 0x00, 0x73, 0x00, 0x20, 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, - 0x00, 0x20, 0x00, 0x28, 0x00, 0x63, 0x00, 0x29, 0x00, 0x20, 0x00, 0x42, - 0x00, 0x69, 0x00, 0x74, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x65, - 0x00, 0x61, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x28, 0x00, 0x73, 0x00, 0x65, - 0x00, 0x65, 0x00, 0x20, 0x00, 0x62, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6f, - 0x00, 0x77, 0x00, 0x29, 0x00, 0x2e, 0x00, 0x20, 0x00, 0x44, 0x00, 0x65, - 0x00, 0x6a, 0x00, 0x61, 0x00, 0x56, 0x00, 0x75, 0x00, 0x20, 0x00, 0x63, - 0x00, 0x68, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x65, 0x00, 0x73, - 0x00, 0x20, 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x69, - 0x00, 0x6e, 0x00, 0x20, 0x00, 0x70, 0x00, 0x75, 0x00, 0x62, 0x00, 0x6c, - 0x00, 0x69, 0x00, 0x63, 0x00, 0x20, 0x00, 0x64, 0x00, 0x6f, 0x00, 0x6d, - 0x00, 0x61, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x2e, 0x00, 0x0a, 0x00, 0x0a, - 0x00, 0x42, 0x00, 0x69, 0x00, 0x74, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, - 0x00, 0x65, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x56, 0x00, 0x65, - 0x00, 0x72, 0x00, 0x61, 0x00, 0x20, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x6e, - 0x00, 0x74, 0x00, 0x73, 0x00, 0x20, 0x00, 0x43, 0x00, 0x6f, 0x00, 0x70, - 0x00, 0x79, 0x00, 0x72, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68, 0x00, 0x74, - 0x00, 0x0a, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, - 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, - 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, - 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, - 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x2d, - 0x00, 0x2d, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x43, 0x00, 0x6f, 0x00, 0x70, - 0x00, 0x79, 0x00, 0x72, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68, 0x00, 0x74, - 0x00, 0x20, 0x00, 0x28, 0x00, 0x63, 0x00, 0x29, 0x00, 0x20, 0x00, 0x32, - 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00, 0x20, 0x00, 0x62, 0x00, 0x79, - 0x00, 0x20, 0x00, 0x42, 0x00, 0x69, 0x00, 0x74, 0x00, 0x73, 0x00, 0x74, - 0x00, 0x72, 0x00, 0x65, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x2c, 0x00, 0x20, - 0x00, 0x49, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x20, 0x00, 0x41, - 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x52, 0x00, 0x69, 0x00, 0x67, - 0x00, 0x68, 0x00, 0x74, 0x00, 0x73, 0x00, 0x20, 0x00, 0x52, 0x00, 0x65, - 0x00, 0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x76, 0x00, 0x65, 0x00, 0x64, - 0x00, 0x2e, 0x00, 0x20, 0x00, 0x42, 0x00, 0x69, 0x00, 0x74, 0x00, 0x73, - 0x00, 0x74, 0x00, 0x72, 0x00, 0x65, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x20, - 0x00, 0x56, 0x00, 0x65, 0x00, 0x72, 0x00, 0x61, 0x00, 0x20, 0x00, 0x69, - 0x00, 0x73, 0x00, 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x74, 0x00, 0x72, - 0x00, 0x61, 0x00, 0x64, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x72, - 0x00, 0x6b, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x42, - 0x00, 0x69, 0x00, 0x74, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x65, - 0x00, 0x61, 0x00, 0x6d, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x49, 0x00, 0x6e, - 0x00, 0x63, 0x00, 0x2e, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x50, 0x00, 0x65, - 0x00, 0x72, 0x00, 0x6d, 0x00, 0x69, 0x00, 0x73, 0x00, 0x73, 0x00, 0x69, - 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x69, 0x00, 0x73, 0x00, 0x20, - 0x00, 0x68, 0x00, 0x65, 0x00, 0x72, 0x00, 0x65, 0x00, 0x62, 0x00, 0x79, - 0x00, 0x20, 0x00, 0x67, 0x00, 0x72, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x74, - 0x00, 0x65, 0x00, 0x64, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x66, 0x00, 0x72, - 0x00, 0x65, 0x00, 0x65, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, - 0x00, 0x63, 0x00, 0x68, 0x00, 0x61, 0x00, 0x72, 0x00, 0x67, 0x00, 0x65, - 0x00, 0x2c, 0x00, 0x20, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x61, - 0x00, 0x6e, 0x00, 0x79, 0x00, 0x20, 0x00, 0x70, 0x00, 0x65, 0x00, 0x72, - 0x00, 0x73, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x62, - 0x00, 0x74, 0x00, 0x61, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x69, 0x00, 0x6e, - 0x00, 0x67, 0x00, 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, - 0x00, 0x70, 0x00, 0x79, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, - 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x66, 0x00, 0x6f, - 0x00, 0x6e, 0x00, 0x74, 0x00, 0x73, 0x00, 0x20, 0x00, 0x61, 0x00, 0x63, - 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x61, 0x00, 0x6e, - 0x00, 0x79, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x20, 0x00, 0x74, - 0x00, 0x68, 0x00, 0x69, 0x00, 0x73, 0x00, 0x20, 0x00, 0x6c, 0x00, 0x69, - 0x00, 0x63, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x65, 0x00, 0x20, - 0x00, 0x28, 0x00, 0x22, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, - 0x00, 0x73, 0x00, 0x22, 0x00, 0x29, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, - 0x00, 0x64, 0x00, 0x20, 0x00, 0x61, 0x00, 0x73, 0x00, 0x73, 0x00, 0x6f, - 0x00, 0x63, 0x00, 0x69, 0x00, 0x61, 0x00, 0x74, 0x00, 0x65, 0x00, 0x64, - 0x00, 0x20, 0x00, 0x64, 0x00, 0x6f, 0x00, 0x63, 0x00, 0x75, 0x00, 0x6d, - 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, - 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x66, 0x00, 0x69, 0x00, 0x6c, - 0x00, 0x65, 0x00, 0x73, 0x00, 0x20, 0x00, 0x28, 0x00, 0x74, 0x00, 0x68, - 0x00, 0x65, 0x00, 0x20, 0x00, 0x22, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x6e, - 0x00, 0x74, 0x00, 0x20, 0x00, 0x53, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x74, - 0x00, 0x77, 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x22, 0x00, 0x29, - 0x00, 0x2c, 0x00, 0x20, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x72, - 0x00, 0x65, 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x75, - 0x00, 0x63, 0x00, 0x65, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, - 0x00, 0x20, 0x00, 0x64, 0x00, 0x69, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, - 0x00, 0x69, 0x00, 0x62, 0x00, 0x75, 0x00, 0x74, 0x00, 0x65, 0x00, 0x20, - 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x46, 0x00, 0x6f, - 0x00, 0x6e, 0x00, 0x74, 0x00, 0x20, 0x00, 0x53, 0x00, 0x6f, 0x00, 0x66, - 0x00, 0x74, 0x00, 0x77, 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x2c, - 0x00, 0x20, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x63, 0x00, 0x6c, 0x00, 0x75, - 0x00, 0x64, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x20, 0x00, 0x77, - 0x00, 0x69, 0x00, 0x74, 0x00, 0x68, 0x00, 0x6f, 0x00, 0x75, 0x00, 0x74, - 0x00, 0x20, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x6d, 0x00, 0x69, 0x00, 0x74, - 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, - 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x72, 0x00, 0x69, - 0x00, 0x67, 0x00, 0x68, 0x00, 0x74, 0x00, 0x73, 0x00, 0x20, 0x00, 0x74, - 0x00, 0x6f, 0x00, 0x20, 0x00, 0x75, 0x00, 0x73, 0x00, 0x65, 0x00, 0x2c, - 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x79, 0x00, 0x2c, - 0x00, 0x20, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x72, 0x00, 0x67, 0x00, 0x65, - 0x00, 0x2c, 0x00, 0x20, 0x00, 0x70, 0x00, 0x75, 0x00, 0x62, 0x00, 0x6c, - 0x00, 0x69, 0x00, 0x73, 0x00, 0x68, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x64, - 0x00, 0x69, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x62, - 0x00, 0x75, 0x00, 0x74, 0x00, 0x65, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, - 0x00, 0x6e, 0x00, 0x64, 0x00, 0x2f, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x20, - 0x00, 0x73, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x63, - 0x00, 0x6f, 0x00, 0x70, 0x00, 0x69, 0x00, 0x65, 0x00, 0x73, 0x00, 0x20, - 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, - 0x00, 0x20, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x20, - 0x00, 0x53, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x74, 0x00, 0x77, 0x00, 0x61, - 0x00, 0x72, 0x00, 0x65, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, - 0x00, 0x64, 0x00, 0x20, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x70, - 0x00, 0x65, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x69, 0x00, 0x74, 0x00, 0x20, - 0x00, 0x70, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x6e, - 0x00, 0x73, 0x00, 0x20, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x77, - 0x00, 0x68, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, - 0x00, 0x65, 0x00, 0x20, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, - 0x00, 0x20, 0x00, 0x53, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x74, 0x00, 0x77, - 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x69, 0x00, 0x73, - 0x00, 0x20, 0x00, 0x66, 0x00, 0x75, 0x00, 0x72, 0x00, 0x6e, 0x00, 0x69, - 0x00, 0x73, 0x00, 0x68, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x74, - 0x00, 0x6f, 0x00, 0x20, 0x00, 0x64, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x73, - 0x00, 0x6f, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x73, 0x00, 0x75, 0x00, 0x62, - 0x00, 0x6a, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, 0x00, 0x20, 0x00, 0x74, - 0x00, 0x6f, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, - 0x00, 0x66, 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6f, 0x00, 0x77, - 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, - 0x00, 0x6e, 0x00, 0x64, 0x00, 0x69, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, - 0x00, 0x6e, 0x00, 0x73, 0x00, 0x3a, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x54, - 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x61, 0x00, 0x62, 0x00, 0x6f, - 0x00, 0x76, 0x00, 0x65, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x70, - 0x00, 0x79, 0x00, 0x72, 0x00, 0x69, 0x00, 0x67, 0x00, 0x68, 0x00, 0x74, - 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x74, - 0x00, 0x72, 0x00, 0x61, 0x00, 0x64, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x61, - 0x00, 0x72, 0x00, 0x6b, 0x00, 0x20, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x74, - 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x73, 0x00, 0x20, 0x00, 0x61, - 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x69, - 0x00, 0x73, 0x00, 0x20, 0x00, 0x70, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6d, - 0x00, 0x69, 0x00, 0x73, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, - 0x00, 0x20, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x74, 0x00, 0x69, 0x00, 0x63, - 0x00, 0x65, 0x00, 0x20, 0x00, 0x73, 0x00, 0x68, 0x00, 0x61, 0x00, 0x6c, - 0x00, 0x6c, 0x00, 0x20, 0x00, 0x62, 0x00, 0x65, 0x00, 0x20, 0x00, 0x69, - 0x00, 0x6e, 0x00, 0x63, 0x00, 0x6c, 0x00, 0x75, 0x00, 0x64, 0x00, 0x65, - 0x00, 0x64, 0x00, 0x20, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x61, - 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x70, - 0x00, 0x69, 0x00, 0x65, 0x00, 0x73, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, - 0x00, 0x20, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x20, 0x00, 0x6f, - 0x00, 0x72, 0x00, 0x20, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x65, - 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, - 0x00, 0x65, 0x00, 0x20, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, - 0x00, 0x20, 0x00, 0x53, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x74, 0x00, 0x77, - 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x74, 0x00, 0x79, - 0x00, 0x70, 0x00, 0x65, 0x00, 0x66, 0x00, 0x61, 0x00, 0x63, 0x00, 0x65, - 0x00, 0x73, 0x00, 0x2e, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x54, 0x00, 0x68, - 0x00, 0x65, 0x00, 0x20, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, - 0x00, 0x20, 0x00, 0x53, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x74, 0x00, 0x77, - 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x6d, 0x00, 0x61, - 0x00, 0x79, 0x00, 0x20, 0x00, 0x62, 0x00, 0x65, 0x00, 0x20, 0x00, 0x6d, - 0x00, 0x6f, 0x00, 0x64, 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, 0x65, - 0x00, 0x64, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x74, - 0x00, 0x65, 0x00, 0x72, 0x00, 0x65, 0x00, 0x64, 0x00, 0x2c, 0x00, 0x20, - 0x00, 0x6f, 0x00, 0x72, 0x00, 0x20, 0x00, 0x61, 0x00, 0x64, 0x00, 0x64, - 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x2c, - 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x69, - 0x00, 0x6e, 0x00, 0x20, 0x00, 0x70, 0x00, 0x61, 0x00, 0x72, 0x00, 0x74, - 0x00, 0x69, 0x00, 0x63, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x72, - 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x64, - 0x00, 0x65, 0x00, 0x73, 0x00, 0x69, 0x00, 0x67, 0x00, 0x6e, 0x00, 0x73, - 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x67, 0x00, 0x6c, - 0x00, 0x79, 0x00, 0x70, 0x00, 0x68, 0x00, 0x73, 0x00, 0x20, 0x00, 0x6f, - 0x00, 0x72, 0x00, 0x20, 0x00, 0x63, 0x00, 0x68, 0x00, 0x61, 0x00, 0x72, - 0x00, 0x61, 0x00, 0x63, 0x00, 0x74, 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, - 0x00, 0x20, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, - 0x00, 0x65, 0x00, 0x20, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, - 0x00, 0x73, 0x00, 0x20, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x79, 0x00, 0x20, - 0x00, 0x62, 0x00, 0x65, 0x00, 0x20, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x64, - 0x00, 0x69, 0x00, 0x66, 0x00, 0x69, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, - 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x61, 0x00, 0x64, - 0x00, 0x64, 0x00, 0x69, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, - 0x00, 0x61, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x67, 0x00, 0x6c, 0x00, 0x79, - 0x00, 0x70, 0x00, 0x68, 0x00, 0x73, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x72, - 0x00, 0x20, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x20, 0x00, 0x63, - 0x00, 0x68, 0x00, 0x61, 0x00, 0x72, 0x00, 0x61, 0x00, 0x63, 0x00, 0x74, - 0x00, 0x65, 0x00, 0x72, 0x00, 0x73, 0x00, 0x20, 0x00, 0x6d, 0x00, 0x61, - 0x00, 0x79, 0x00, 0x20, 0x00, 0x62, 0x00, 0x65, 0x00, 0x20, 0x00, 0x61, - 0x00, 0x64, 0x00, 0x64, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x74, - 0x00, 0x6f, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, - 0x00, 0x46, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x73, 0x00, 0x2c, - 0x00, 0x20, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x6c, 0x00, 0x79, 0x00, 0x20, - 0x00, 0x69, 0x00, 0x66, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, - 0x00, 0x20, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x73, - 0x00, 0x20, 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x72, - 0x00, 0x65, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x64, - 0x00, 0x20, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x6e, 0x00, 0x61, - 0x00, 0x6d, 0x00, 0x65, 0x00, 0x73, 0x00, 0x20, 0x00, 0x6e, 0x00, 0x6f, - 0x00, 0x74, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, - 0x00, 0x61, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, - 0x00, 0x20, 0x00, 0x65, 0x00, 0x69, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, - 0x00, 0x72, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, - 0x00, 0x77, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x64, 0x00, 0x73, 0x00, 0x20, - 0x00, 0x22, 0x00, 0x42, 0x00, 0x69, 0x00, 0x74, 0x00, 0x73, 0x00, 0x74, - 0x00, 0x72, 0x00, 0x65, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x22, 0x00, 0x20, - 0x00, 0x6f, 0x00, 0x72, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, - 0x00, 0x20, 0x00, 0x77, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x64, 0x00, 0x20, - 0x00, 0x22, 0x00, 0x56, 0x00, 0x65, 0x00, 0x72, 0x00, 0x61, 0x00, 0x22, - 0x00, 0x2e, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x54, 0x00, 0x68, 0x00, 0x69, - 0x00, 0x73, 0x00, 0x20, 0x00, 0x4c, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, - 0x00, 0x6e, 0x00, 0x73, 0x00, 0x65, 0x00, 0x20, 0x00, 0x62, 0x00, 0x65, - 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x73, 0x00, 0x20, - 0x00, 0x6e, 0x00, 0x75, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x61, - 0x00, 0x6e, 0x00, 0x64, 0x00, 0x20, 0x00, 0x76, 0x00, 0x6f, 0x00, 0x69, - 0x00, 0x64, 0x00, 0x20, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x74, - 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x65, 0x00, 0x78, 0x00, 0x74, - 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x20, 0x00, 0x61, 0x00, 0x70, - 0x00, 0x70, 0x00, 0x6c, 0x00, 0x69, 0x00, 0x63, 0x00, 0x61, 0x00, 0x62, - 0x00, 0x6c, 0x00, 0x65, 0x00, 0x20, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x20, - 0x00, 0x46, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x73, 0x00, 0x20, - 0x00, 0x6f, 0x00, 0x72, 0x00, 0x20, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x6e, - 0x00, 0x74, 0x00, 0x20, 0x00, 0x53, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x74, - 0x00, 0x77, 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x74, - 0x00, 0x68, 0x00, 0x61, 0x00, 0x74, 0x00, 0x20, 0x00, 0x68, 0x00, 0x61, - 0x00, 0x73, 0x00, 0x20, 0x00, 0x62, 0x00, 0x65, 0x00, 0x65, 0x00, 0x6e, - 0x00, 0x20, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x64, 0x00, 0x69, 0x00, 0x66, - 0x00, 0x69, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, - 0x00, 0x64, 0x00, 0x20, 0x00, 0x69, 0x00, 0x73, 0x00, 0x20, 0x00, 0x64, - 0x00, 0x69, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x62, - 0x00, 0x75, 0x00, 0x74, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x75, - 0x00, 0x6e, 0x00, 0x64, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00, 0x74, - 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x22, 0x00, 0x42, 0x00, 0x69, - 0x00, 0x74, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x65, 0x00, 0x61, - 0x00, 0x6d, 0x00, 0x20, 0x00, 0x56, 0x00, 0x65, 0x00, 0x72, 0x00, 0x61, - 0x00, 0x22, 0x00, 0x20, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, - 0x00, 0x73, 0x00, 0x2e, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x54, 0x00, 0x68, - 0x00, 0x65, 0x00, 0x20, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, - 0x00, 0x20, 0x00, 0x53, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x74, 0x00, 0x77, - 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x6d, 0x00, 0x61, - 0x00, 0x79, 0x00, 0x20, 0x00, 0x62, 0x00, 0x65, 0x00, 0x20, 0x00, 0x73, - 0x00, 0x6f, 0x00, 0x6c, 0x00, 0x64, 0x00, 0x20, 0x00, 0x61, 0x00, 0x73, - 0x00, 0x20, 0x00, 0x70, 0x00, 0x61, 0x00, 0x72, 0x00, 0x74, 0x00, 0x20, - 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x6c, - 0x00, 0x61, 0x00, 0x72, 0x00, 0x67, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, - 0x00, 0x73, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x74, 0x00, 0x77, 0x00, 0x61, - 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x70, 0x00, 0x61, 0x00, 0x63, - 0x00, 0x6b, 0x00, 0x61, 0x00, 0x67, 0x00, 0x65, 0x00, 0x20, 0x00, 0x62, - 0x00, 0x75, 0x00, 0x74, 0x00, 0x20, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x20, - 0x00, 0x63, 0x00, 0x6f, 0x00, 0x70, 0x00, 0x79, 0x00, 0x20, 0x00, 0x6f, - 0x00, 0x66, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x20, - 0x00, 0x6f, 0x00, 0x72, 0x00, 0x20, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x72, - 0x00, 0x65, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x74, - 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x6e, - 0x00, 0x74, 0x00, 0x20, 0x00, 0x53, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x74, - 0x00, 0x77, 0x00, 0x61, 0x00, 0x72, 0x00, 0x65, 0x00, 0x20, 0x00, 0x74, - 0x00, 0x79, 0x00, 0x70, 0x00, 0x65, 0x00, 0x66, 0x00, 0x61, 0x00, 0x63, - 0x00, 0x65, 0x00, 0x73, 0x00, 0x20, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x79, - 0x00, 0x20, 0x00, 0x62, 0x00, 0x65, 0x00, 0x20, 0x00, 0x73, 0x00, 0x6f, - 0x00, 0x6c, 0x00, 0x64, 0x00, 0x20, 0x00, 0x62, 0x00, 0x79, 0x00, 0x20, - 0x00, 0x69, 0x00, 0x74, 0x00, 0x73, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x66, - 0x00, 0x2e, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x54, 0x00, 0x48, 0x00, 0x45, - 0x00, 0x20, 0x00, 0x46, 0x00, 0x4f, 0x00, 0x4e, 0x00, 0x54, 0x00, 0x20, - 0x00, 0x53, 0x00, 0x4f, 0x00, 0x46, 0x00, 0x54, 0x00, 0x57, 0x00, 0x41, - 0x00, 0x52, 0x00, 0x45, 0x00, 0x20, 0x00, 0x49, 0x00, 0x53, 0x00, 0x20, - 0x00, 0x50, 0x00, 0x52, 0x00, 0x4f, 0x00, 0x56, 0x00, 0x49, 0x00, 0x44, - 0x00, 0x45, 0x00, 0x44, 0x00, 0x20, 0x00, 0x22, 0x00, 0x41, 0x00, 0x53, - 0x00, 0x20, 0x00, 0x49, 0x00, 0x53, 0x00, 0x22, 0x00, 0x2c, 0x00, 0x20, - 0x00, 0x57, 0x00, 0x49, 0x00, 0x54, 0x00, 0x48, 0x00, 0x4f, 0x00, 0x55, - 0x00, 0x54, 0x00, 0x20, 0x00, 0x57, 0x00, 0x41, 0x00, 0x52, 0x00, 0x52, - 0x00, 0x41, 0x00, 0x4e, 0x00, 0x54, 0x00, 0x59, 0x00, 0x20, 0x00, 0x4f, - 0x00, 0x46, 0x00, 0x20, 0x00, 0x41, 0x00, 0x4e, 0x00, 0x59, 0x00, 0x20, - 0x00, 0x4b, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x44, 0x00, 0x2c, 0x00, 0x20, - 0x00, 0x45, 0x00, 0x58, 0x00, 0x50, 0x00, 0x52, 0x00, 0x45, 0x00, 0x53, - 0x00, 0x53, 0x00, 0x20, 0x00, 0x4f, 0x00, 0x52, 0x00, 0x20, 0x00, 0x49, - 0x00, 0x4d, 0x00, 0x50, 0x00, 0x4c, 0x00, 0x49, 0x00, 0x45, 0x00, 0x44, - 0x00, 0x2c, 0x00, 0x20, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x43, 0x00, 0x4c, - 0x00, 0x55, 0x00, 0x44, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x47, 0x00, 0x20, - 0x00, 0x42, 0x00, 0x55, 0x00, 0x54, 0x00, 0x20, 0x00, 0x4e, 0x00, 0x4f, - 0x00, 0x54, 0x00, 0x20, 0x00, 0x4c, 0x00, 0x49, 0x00, 0x4d, 0x00, 0x49, - 0x00, 0x54, 0x00, 0x45, 0x00, 0x44, 0x00, 0x20, 0x00, 0x54, 0x00, 0x4f, - 0x00, 0x20, 0x00, 0x41, 0x00, 0x4e, 0x00, 0x59, 0x00, 0x20, 0x00, 0x57, - 0x00, 0x41, 0x00, 0x52, 0x00, 0x52, 0x00, 0x41, 0x00, 0x4e, 0x00, 0x54, - 0x00, 0x49, 0x00, 0x45, 0x00, 0x53, 0x00, 0x20, 0x00, 0x4f, 0x00, 0x46, - 0x00, 0x20, 0x00, 0x4d, 0x00, 0x45, 0x00, 0x52, 0x00, 0x43, 0x00, 0x48, - 0x00, 0x41, 0x00, 0x4e, 0x00, 0x54, 0x00, 0x41, 0x00, 0x42, 0x00, 0x49, - 0x00, 0x4c, 0x00, 0x49, 0x00, 0x54, 0x00, 0x59, 0x00, 0x2c, 0x00, 0x20, - 0x00, 0x46, 0x00, 0x49, 0x00, 0x54, 0x00, 0x4e, 0x00, 0x45, 0x00, 0x53, - 0x00, 0x53, 0x00, 0x20, 0x00, 0x46, 0x00, 0x4f, 0x00, 0x52, 0x00, 0x20, - 0x00, 0x41, 0x00, 0x20, 0x00, 0x50, 0x00, 0x41, 0x00, 0x52, 0x00, 0x54, - 0x00, 0x49, 0x00, 0x43, 0x00, 0x55, 0x00, 0x4c, 0x00, 0x41, 0x00, 0x52, - 0x00, 0x20, 0x00, 0x50, 0x00, 0x55, 0x00, 0x52, 0x00, 0x50, 0x00, 0x4f, - 0x00, 0x53, 0x00, 0x45, 0x00, 0x20, 0x00, 0x41, 0x00, 0x4e, 0x00, 0x44, - 0x00, 0x20, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x4e, 0x00, 0x49, 0x00, 0x4e, - 0x00, 0x46, 0x00, 0x52, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x47, 0x00, 0x45, - 0x00, 0x4d, 0x00, 0x45, 0x00, 0x4e, 0x00, 0x54, 0x00, 0x20, 0x00, 0x4f, - 0x00, 0x46, 0x00, 0x20, 0x00, 0x43, 0x00, 0x4f, 0x00, 0x50, 0x00, 0x59, - 0x00, 0x52, 0x00, 0x49, 0x00, 0x47, 0x00, 0x48, 0x00, 0x54, 0x00, 0x2c, - 0x00, 0x20, 0x00, 0x50, 0x00, 0x41, 0x00, 0x54, 0x00, 0x45, 0x00, 0x4e, - 0x00, 0x54, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x54, 0x00, 0x52, 0x00, 0x41, - 0x00, 0x44, 0x00, 0x45, 0x00, 0x4d, 0x00, 0x41, 0x00, 0x52, 0x00, 0x4b, - 0x00, 0x2c, 0x00, 0x20, 0x00, 0x4f, 0x00, 0x52, 0x00, 0x20, 0x00, 0x4f, - 0x00, 0x54, 0x00, 0x48, 0x00, 0x45, 0x00, 0x52, 0x00, 0x20, 0x00, 0x52, - 0x00, 0x49, 0x00, 0x47, 0x00, 0x48, 0x00, 0x54, 0x00, 0x2e, 0x00, 0x20, - 0x00, 0x49, 0x00, 0x4e, 0x00, 0x20, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x20, - 0x00, 0x45, 0x00, 0x56, 0x00, 0x45, 0x00, 0x4e, 0x00, 0x54, 0x00, 0x20, - 0x00, 0x53, 0x00, 0x48, 0x00, 0x41, 0x00, 0x4c, 0x00, 0x4c, 0x00, 0x20, - 0x00, 0x42, 0x00, 0x49, 0x00, 0x54, 0x00, 0x53, 0x00, 0x54, 0x00, 0x52, - 0x00, 0x45, 0x00, 0x41, 0x00, 0x4d, 0x00, 0x20, 0x00, 0x4f, 0x00, 0x52, - 0x00, 0x20, 0x00, 0x54, 0x00, 0x48, 0x00, 0x45, 0x00, 0x20, 0x00, 0x47, - 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x4d, 0x00, 0x45, 0x00, 0x20, 0x00, 0x46, - 0x00, 0x4f, 0x00, 0x55, 0x00, 0x4e, 0x00, 0x44, 0x00, 0x41, 0x00, 0x54, - 0x00, 0x49, 0x00, 0x4f, 0x00, 0x4e, 0x00, 0x20, 0x00, 0x42, 0x00, 0x45, - 0x00, 0x20, 0x00, 0x4c, 0x00, 0x49, 0x00, 0x41, 0x00, 0x42, 0x00, 0x4c, - 0x00, 0x45, 0x00, 0x20, 0x00, 0x46, 0x00, 0x4f, 0x00, 0x52, 0x00, 0x20, - 0x00, 0x41, 0x00, 0x4e, 0x00, 0x59, 0x00, 0x20, 0x00, 0x43, 0x00, 0x4c, - 0x00, 0x41, 0x00, 0x49, 0x00, 0x4d, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x44, - 0x00, 0x41, 0x00, 0x4d, 0x00, 0x41, 0x00, 0x47, 0x00, 0x45, 0x00, 0x53, - 0x00, 0x20, 0x00, 0x4f, 0x00, 0x52, 0x00, 0x20, 0x00, 0x4f, 0x00, 0x54, - 0x00, 0x48, 0x00, 0x45, 0x00, 0x52, 0x00, 0x20, 0x00, 0x4c, 0x00, 0x49, - 0x00, 0x41, 0x00, 0x42, 0x00, 0x49, 0x00, 0x4c, 0x00, 0x49, 0x00, 0x54, - 0x00, 0x59, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x43, - 0x00, 0x4c, 0x00, 0x55, 0x00, 0x44, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x47, - 0x00, 0x20, 0x00, 0x41, 0x00, 0x4e, 0x00, 0x59, 0x00, 0x20, 0x00, 0x47, - 0x00, 0x45, 0x00, 0x4e, 0x00, 0x45, 0x00, 0x52, 0x00, 0x41, 0x00, 0x4c, - 0x00, 0x2c, 0x00, 0x20, 0x00, 0x53, 0x00, 0x50, 0x00, 0x45, 0x00, 0x43, - 0x00, 0x49, 0x00, 0x41, 0x00, 0x4c, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x49, - 0x00, 0x4e, 0x00, 0x44, 0x00, 0x49, 0x00, 0x52, 0x00, 0x45, 0x00, 0x43, - 0x00, 0x54, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x43, - 0x00, 0x49, 0x00, 0x44, 0x00, 0x45, 0x00, 0x4e, 0x00, 0x54, 0x00, 0x41, - 0x00, 0x4c, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x4f, 0x00, 0x52, 0x00, 0x20, - 0x00, 0x43, 0x00, 0x4f, 0x00, 0x4e, 0x00, 0x53, 0x00, 0x45, 0x00, 0x51, - 0x00, 0x55, 0x00, 0x45, 0x00, 0x4e, 0x00, 0x54, 0x00, 0x49, 0x00, 0x41, - 0x00, 0x4c, 0x00, 0x20, 0x00, 0x44, 0x00, 0x41, 0x00, 0x4d, 0x00, 0x41, - 0x00, 0x47, 0x00, 0x45, 0x00, 0x53, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x57, - 0x00, 0x48, 0x00, 0x45, 0x00, 0x54, 0x00, 0x48, 0x00, 0x45, 0x00, 0x52, - 0x00, 0x20, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x20, 0x00, 0x41, 0x00, 0x4e, - 0x00, 0x20, 0x00, 0x41, 0x00, 0x43, 0x00, 0x54, 0x00, 0x49, 0x00, 0x4f, - 0x00, 0x4e, 0x00, 0x20, 0x00, 0x4f, 0x00, 0x46, 0x00, 0x20, 0x00, 0x43, - 0x00, 0x4f, 0x00, 0x4e, 0x00, 0x54, 0x00, 0x52, 0x00, 0x41, 0x00, 0x43, - 0x00, 0x54, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x54, 0x00, 0x4f, 0x00, 0x52, - 0x00, 0x54, 0x00, 0x20, 0x00, 0x4f, 0x00, 0x52, 0x00, 0x20, 0x00, 0x4f, - 0x00, 0x54, 0x00, 0x48, 0x00, 0x45, 0x00, 0x52, 0x00, 0x57, 0x00, 0x49, - 0x00, 0x53, 0x00, 0x45, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x41, 0x00, 0x52, - 0x00, 0x49, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x47, 0x00, 0x20, - 0x00, 0x46, 0x00, 0x52, 0x00, 0x4f, 0x00, 0x4d, 0x00, 0x2c, 0x00, 0x20, - 0x00, 0x4f, 0x00, 0x55, 0x00, 0x54, 0x00, 0x20, 0x00, 0x4f, 0x00, 0x46, - 0x00, 0x20, 0x00, 0x54, 0x00, 0x48, 0x00, 0x45, 0x00, 0x20, 0x00, 0x55, - 0x00, 0x53, 0x00, 0x45, 0x00, 0x20, 0x00, 0x4f, 0x00, 0x52, 0x00, 0x20, - 0x00, 0x49, 0x00, 0x4e, 0x00, 0x41, 0x00, 0x42, 0x00, 0x49, 0x00, 0x4c, - 0x00, 0x49, 0x00, 0x54, 0x00, 0x59, 0x00, 0x20, 0x00, 0x54, 0x00, 0x4f, - 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, 0x00, 0x45, 0x00, 0x20, 0x00, 0x54, - 0x00, 0x48, 0x00, 0x45, 0x00, 0x20, 0x00, 0x46, 0x00, 0x4f, 0x00, 0x4e, - 0x00, 0x54, 0x00, 0x20, 0x00, 0x53, 0x00, 0x4f, 0x00, 0x46, 0x00, 0x54, - 0x00, 0x57, 0x00, 0x41, 0x00, 0x52, 0x00, 0x45, 0x00, 0x20, 0x00, 0x4f, - 0x00, 0x52, 0x00, 0x20, 0x00, 0x46, 0x00, 0x52, 0x00, 0x4f, 0x00, 0x4d, - 0x00, 0x20, 0x00, 0x4f, 0x00, 0x54, 0x00, 0x48, 0x00, 0x45, 0x00, 0x52, - 0x00, 0x20, 0x00, 0x44, 0x00, 0x45, 0x00, 0x41, 0x00, 0x4c, 0x00, 0x49, - 0x00, 0x4e, 0x00, 0x47, 0x00, 0x53, 0x00, 0x20, 0x00, 0x49, 0x00, 0x4e, - 0x00, 0x20, 0x00, 0x54, 0x00, 0x48, 0x00, 0x45, 0x00, 0x20, 0x00, 0x46, - 0x00, 0x4f, 0x00, 0x4e, 0x00, 0x54, 0x00, 0x20, 0x00, 0x53, 0x00, 0x4f, - 0x00, 0x46, 0x00, 0x54, 0x00, 0x57, 0x00, 0x41, 0x00, 0x52, 0x00, 0x45, - 0x00, 0x2e, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x45, 0x00, 0x78, 0x00, 0x63, - 0x00, 0x65, 0x00, 0x70, 0x00, 0x74, 0x00, 0x20, 0x00, 0x61, 0x00, 0x73, - 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x61, - 0x00, 0x69, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x69, - 0x00, 0x6e, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x69, 0x00, 0x73, - 0x00, 0x20, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x74, 0x00, 0x69, 0x00, 0x63, - 0x00, 0x65, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, - 0x00, 0x20, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x73, - 0x00, 0x20, 0x00, 0x6f, 0x00, 0x66, 0x00, 0x20, 0x00, 0x47, 0x00, 0x6e, - 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x74, - 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x47, 0x00, 0x6e, 0x00, 0x6f, - 0x00, 0x6d, 0x00, 0x65, 0x00, 0x20, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x75, - 0x00, 0x6e, 0x00, 0x64, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, - 0x00, 0x6e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, - 0x00, 0x20, 0x00, 0x42, 0x00, 0x69, 0x00, 0x74, 0x00, 0x73, 0x00, 0x74, - 0x00, 0x72, 0x00, 0x65, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x49, - 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x73, - 0x00, 0x68, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x20, 0x00, 0x6e, - 0x00, 0x6f, 0x00, 0x74, 0x00, 0x20, 0x00, 0x62, 0x00, 0x65, 0x00, 0x20, - 0x00, 0x75, 0x00, 0x73, 0x00, 0x65, 0x00, 0x64, 0x00, 0x20, 0x00, 0x69, - 0x00, 0x6e, 0x00, 0x20, 0x00, 0x61, 0x00, 0x64, 0x00, 0x76, 0x00, 0x65, - 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, - 0x00, 0x67, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x20, 0x00, 0x6f, - 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x72, 0x00, 0x77, 0x00, 0x69, - 0x00, 0x73, 0x00, 0x65, 0x00, 0x20, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x20, - 0x00, 0x70, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x6f, 0x00, 0x74, - 0x00, 0x65, 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, - 0x00, 0x73, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x2c, 0x00, 0x20, - 0x00, 0x75, 0x00, 0x73, 0x00, 0x65, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x72, - 0x00, 0x20, 0x00, 0x6f, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x72, - 0x00, 0x20, 0x00, 0x64, 0x00, 0x65, 0x00, 0x61, 0x00, 0x6c, 0x00, 0x69, - 0x00, 0x6e, 0x00, 0x67, 0x00, 0x73, 0x00, 0x20, 0x00, 0x69, 0x00, 0x6e, - 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x69, 0x00, 0x73, 0x00, 0x20, - 0x00, 0x46, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x20, 0x00, 0x53, - 0x00, 0x6f, 0x00, 0x66, 0x00, 0x74, 0x00, 0x77, 0x00, 0x61, 0x00, 0x72, - 0x00, 0x65, 0x00, 0x20, 0x00, 0x77, 0x00, 0x69, 0x00, 0x74, 0x00, 0x68, - 0x00, 0x6f, 0x00, 0x75, 0x00, 0x74, 0x00, 0x20, 0x00, 0x70, 0x00, 0x72, - 0x00, 0x69, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x20, 0x00, 0x77, 0x00, 0x72, - 0x00, 0x69, 0x00, 0x74, 0x00, 0x74, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x20, - 0x00, 0x61, 0x00, 0x75, 0x00, 0x74, 0x00, 0x68, 0x00, 0x6f, 0x00, 0x72, - 0x00, 0x69, 0x00, 0x7a, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, - 0x00, 0x6e, 0x00, 0x20, 0x00, 0x66, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x6d, - 0x00, 0x20, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x20, 0x00, 0x47, - 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x20, 0x00, 0x46, - 0x00, 0x6f, 0x00, 0x75, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x61, 0x00, 0x74, - 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x20, 0x00, 0x6f, 0x00, 0x72, - 0x00, 0x20, 0x00, 0x42, 0x00, 0x69, 0x00, 0x74, 0x00, 0x73, 0x00, 0x74, - 0x00, 0x72, 0x00, 0x65, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x20, 0x00, 0x49, - 0x00, 0x6e, 0x00, 0x63, 0x00, 0x2e, 0x00, 0x2c, 0x00, 0x20, 0x00, 0x72, - 0x00, 0x65, 0x00, 0x73, 0x00, 0x70, 0x00, 0x65, 0x00, 0x63, 0x00, 0x74, - 0x00, 0x69, 0x00, 0x76, 0x00, 0x65, 0x00, 0x6c, 0x00, 0x79, 0x00, 0x2e, - 0x00, 0x20, 0x00, 0x46, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x20, 0x00, 0x66, - 0x00, 0x75, 0x00, 0x72, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x72, - 0x00, 0x20, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x72, - 0x00, 0x6d, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e, - 0x00, 0x2c, 0x00, 0x20, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, - 0x00, 0x61, 0x00, 0x63, 0x00, 0x74, 0x00, 0x3a, 0x00, 0x20, 0x00, 0x66, - 0x00, 0x6f, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x73, 0x00, 0x20, 0x00, 0x61, - 0x00, 0x74, 0x00, 0x20, 0x00, 0x67, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x6d, - 0x00, 0x65, 0x00, 0x20, 0x00, 0x64, 0x00, 0x6f, 0x00, 0x74, 0x00, 0x20, - 0x00, 0x6f, 0x00, 0x72, 0x00, 0x67, 0x00, 0x2e, 0x00, 0x20, 0x00, 0x0a, - 0x00, 0x00, 0x46, 0x6f, 0x6e, 0x74, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, - 0x28, 0x63, 0x29, 0x20, 0x42, 0x69, 0x74, 0x73, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x20, 0x28, 0x73, 0x65, 0x65, 0x20, 0x62, 0x65, 0x6c, 0x6f, 0x77, - 0x29, 0x2e, 0x20, 0x44, 0x65, 0x6a, 0x61, 0x56, 0x75, 0x20, 0x63, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x69, 0x6e, - 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x20, 0x64, 0x6f, 0x6d, 0x61, - 0x69, 0x6e, 0x2e, 0x0a, 0x0a, 0x42, 0x69, 0x74, 0x73, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x20, 0x56, 0x65, 0x72, 0x61, 0x20, 0x46, 0x6f, 0x6e, 0x74, - 0x73, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x0a, - 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, - 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, - 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a, 0x0a, 0x43, 0x6f, 0x70, 0x79, - 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, - 0x30, 0x33, 0x20, 0x62, 0x79, 0x20, 0x42, 0x69, 0x74, 0x73, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x20, 0x41, 0x6c, - 0x6c, 0x20, 0x52, 0x69, 0x67, 0x68, 0x74, 0x73, 0x20, 0x52, 0x65, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x64, 0x2e, 0x20, 0x42, 0x69, 0x74, 0x73, 0x74, - 0x72, 0x65, 0x61, 0x6d, 0x20, 0x56, 0x65, 0x72, 0x61, 0x20, 0x69, 0x73, - 0x20, 0x61, 0x20, 0x74, 0x72, 0x61, 0x64, 0x65, 0x6d, 0x61, 0x72, 0x6b, - 0x20, 0x6f, 0x66, 0x20, 0x42, 0x69, 0x74, 0x73, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x0a, 0x0a, 0x50, 0x65, 0x72, - 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x73, 0x20, 0x68, - 0x65, 0x72, 0x65, 0x62, 0x79, 0x20, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, - 0x64, 0x2c, 0x20, 0x66, 0x72, 0x65, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x63, - 0x68, 0x61, 0x72, 0x67, 0x65, 0x2c, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x6e, - 0x79, 0x20, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x20, 0x6f, 0x62, 0x74, - 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x70, - 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6e, - 0x74, 0x73, 0x20, 0x61, 0x63, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, - 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6c, 0x69, 0x63, - 0x65, 0x6e, 0x73, 0x65, 0x20, 0x28, 0x22, 0x46, 0x6f, 0x6e, 0x74, 0x73, - 0x22, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x73, 0x73, 0x6f, 0x63, - 0x69, 0x61, 0x74, 0x65, 0x64, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, - 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x69, 0x6c, 0x65, - 0x73, 0x20, 0x28, 0x74, 0x68, 0x65, 0x20, 0x22, 0x46, 0x6f, 0x6e, 0x74, - 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x22, 0x29, 0x2c, - 0x20, 0x74, 0x6f, 0x20, 0x72, 0x65, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, - 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x6f, 0x6e, - 0x74, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x2c, 0x20, - 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x69, - 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x69, 0x67, - 0x68, 0x74, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x75, 0x73, 0x65, 0x2c, 0x20, - 0x63, 0x6f, 0x70, 0x79, 0x2c, 0x20, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x2c, - 0x20, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x2c, 0x20, 0x64, 0x69, - 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x2c, 0x20, 0x61, 0x6e, - 0x64, 0x2f, 0x6f, 0x72, 0x20, 0x73, 0x65, 0x6c, 0x6c, 0x20, 0x63, 0x6f, - 0x70, 0x69, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x46, 0x6f, 0x6e, 0x74, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, - 0x65, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x65, - 0x72, 0x6d, 0x69, 0x74, 0x20, 0x70, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x73, - 0x20, 0x74, 0x6f, 0x20, 0x77, 0x68, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x46, 0x6f, 0x6e, 0x74, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, - 0x72, 0x65, 0x20, 0x69, 0x73, 0x20, 0x66, 0x75, 0x72, 0x6e, 0x69, 0x73, - 0x68, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x64, 0x6f, 0x20, 0x73, 0x6f, - 0x2c, 0x20, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x69, - 0x6e, 0x67, 0x20, 0x63, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x3a, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x61, 0x62, 0x6f, 0x76, - 0x65, 0x20, 0x63, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, - 0x61, 0x6e, 0x64, 0x20, 0x74, 0x72, 0x61, 0x64, 0x65, 0x6d, 0x61, 0x72, - 0x6b, 0x20, 0x6e, 0x6f, 0x74, 0x69, 0x63, 0x65, 0x73, 0x20, 0x61, 0x6e, - 0x64, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x70, 0x65, 0x72, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x6f, 0x74, 0x69, 0x63, 0x65, - 0x20, 0x73, 0x68, 0x61, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x69, 0x6e, - 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x6c, - 0x6c, 0x20, 0x63, 0x6f, 0x70, 0x69, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, - 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x6d, 0x6f, 0x72, 0x65, 0x20, - 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x6f, 0x6e, 0x74, 0x20, - 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x74, 0x79, 0x70, - 0x65, 0x66, 0x61, 0x63, 0x65, 0x73, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, - 0x20, 0x46, 0x6f, 0x6e, 0x74, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, - 0x72, 0x65, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x6d, 0x6f, - 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2c, 0x20, 0x61, 0x6c, 0x74, 0x65, - 0x72, 0x65, 0x64, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x64, 0x64, 0x65, - 0x64, 0x20, 0x74, 0x6f, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x69, 0x6e, - 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x73, 0x20, - 0x6f, 0x66, 0x20, 0x67, 0x6c, 0x79, 0x70, 0x68, 0x73, 0x20, 0x6f, 0x72, - 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x20, - 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x6f, 0x6e, 0x74, 0x73, - 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x6d, 0x6f, 0x64, 0x69, - 0x66, 0x69, 0x65, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x61, 0x64, 0x64, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x67, 0x6c, 0x79, 0x70, - 0x68, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x20, 0x6f, 0x72, 0x20, 0x63, 0x68, - 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x20, 0x6d, 0x61, 0x79, - 0x20, 0x62, 0x65, 0x20, 0x61, 0x64, 0x64, 0x65, 0x64, 0x20, 0x74, 0x6f, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x6f, 0x6e, 0x74, 0x73, 0x2c, 0x20, - 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x66, 0x6f, 0x6e, 0x74, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x72, 0x65, - 0x6e, 0x61, 0x6d, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6e, 0x61, 0x6d, - 0x65, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x69, 0x74, 0x68, 0x65, 0x72, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x20, 0x22, - 0x42, 0x69, 0x74, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x22, 0x20, 0x6f, - 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x64, 0x20, 0x22, - 0x56, 0x65, 0x72, 0x61, 0x22, 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x69, 0x73, - 0x20, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x20, 0x62, 0x65, 0x63, - 0x6f, 0x6d, 0x65, 0x73, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x20, 0x61, 0x6e, - 0x64, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x61, 0x70, 0x70, - 0x6c, 0x69, 0x63, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x46, - 0x6f, 0x6e, 0x74, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x46, 0x6f, 0x6e, 0x74, - 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x74, 0x68, - 0x61, 0x74, 0x20, 0x68, 0x61, 0x73, 0x20, 0x62, 0x65, 0x65, 0x6e, 0x20, - 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x61, 0x6e, 0x64, - 0x20, 0x69, 0x73, 0x20, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x22, 0x42, 0x69, 0x74, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x20, 0x56, 0x65, 0x72, 0x61, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, - 0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x46, 0x6f, 0x6e, 0x74, 0x20, - 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x6d, 0x61, 0x79, - 0x20, 0x62, 0x65, 0x20, 0x73, 0x6f, 0x6c, 0x64, 0x20, 0x61, 0x73, 0x20, - 0x70, 0x61, 0x72, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x6c, 0x61, - 0x72, 0x67, 0x65, 0x72, 0x20, 0x73, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, - 0x65, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x62, 0x75, - 0x74, 0x20, 0x6e, 0x6f, 0x20, 0x63, 0x6f, 0x70, 0x79, 0x20, 0x6f, 0x66, - 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x6d, 0x6f, 0x72, 0x65, - 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x46, 0x6f, 0x6e, 0x74, - 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x74, 0x79, - 0x70, 0x65, 0x66, 0x61, 0x63, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, - 0x62, 0x65, 0x20, 0x73, 0x6f, 0x6c, 0x64, 0x20, 0x62, 0x79, 0x20, 0x69, - 0x74, 0x73, 0x65, 0x6c, 0x66, 0x2e, 0x0a, 0x0a, 0x54, 0x48, 0x45, 0x20, - 0x46, 0x4f, 0x4e, 0x54, 0x20, 0x53, 0x4f, 0x46, 0x54, 0x57, 0x41, 0x52, - 0x45, 0x20, 0x49, 0x53, 0x20, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x44, 0x45, - 0x44, 0x20, 0x22, 0x41, 0x53, 0x20, 0x49, 0x53, 0x22, 0x2c, 0x20, 0x57, - 0x49, 0x54, 0x48, 0x4f, 0x55, 0x54, 0x20, 0x57, 0x41, 0x52, 0x52, 0x41, - 0x4e, 0x54, 0x59, 0x20, 0x4f, 0x46, 0x20, 0x41, 0x4e, 0x59, 0x20, 0x4b, - 0x49, 0x4e, 0x44, 0x2c, 0x20, 0x45, 0x58, 0x50, 0x52, 0x45, 0x53, 0x53, - 0x20, 0x4f, 0x52, 0x20, 0x49, 0x4d, 0x50, 0x4c, 0x49, 0x45, 0x44, 0x2c, - 0x20, 0x49, 0x4e, 0x43, 0x4c, 0x55, 0x44, 0x49, 0x4e, 0x47, 0x20, 0x42, - 0x55, 0x54, 0x20, 0x4e, 0x4f, 0x54, 0x20, 0x4c, 0x49, 0x4d, 0x49, 0x54, - 0x45, 0x44, 0x20, 0x54, 0x4f, 0x20, 0x41, 0x4e, 0x59, 0x20, 0x57, 0x41, - 0x52, 0x52, 0x41, 0x4e, 0x54, 0x49, 0x45, 0x53, 0x20, 0x4f, 0x46, 0x20, - 0x4d, 0x45, 0x52, 0x43, 0x48, 0x41, 0x4e, 0x54, 0x41, 0x42, 0x49, 0x4c, - 0x49, 0x54, 0x59, 0x2c, 0x20, 0x46, 0x49, 0x54, 0x4e, 0x45, 0x53, 0x53, - 0x20, 0x46, 0x4f, 0x52, 0x20, 0x41, 0x20, 0x50, 0x41, 0x52, 0x54, 0x49, - 0x43, 0x55, 0x4c, 0x41, 0x52, 0x20, 0x50, 0x55, 0x52, 0x50, 0x4f, 0x53, - 0x45, 0x20, 0x41, 0x4e, 0x44, 0x20, 0x4e, 0x4f, 0x4e, 0x49, 0x4e, 0x46, - 0x52, 0x49, 0x4e, 0x47, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x20, 0x4f, 0x46, - 0x20, 0x43, 0x4f, 0x50, 0x59, 0x52, 0x49, 0x47, 0x48, 0x54, 0x2c, 0x20, - 0x50, 0x41, 0x54, 0x45, 0x4e, 0x54, 0x2c, 0x20, 0x54, 0x52, 0x41, 0x44, - 0x45, 0x4d, 0x41, 0x52, 0x4b, 0x2c, 0x20, 0x4f, 0x52, 0x20, 0x4f, 0x54, - 0x48, 0x45, 0x52, 0x20, 0x52, 0x49, 0x47, 0x48, 0x54, 0x2e, 0x20, 0x49, - 0x4e, 0x20, 0x4e, 0x4f, 0x20, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x20, 0x53, - 0x48, 0x41, 0x4c, 0x4c, 0x20, 0x42, 0x49, 0x54, 0x53, 0x54, 0x52, 0x45, - 0x41, 0x4d, 0x20, 0x4f, 0x52, 0x20, 0x54, 0x48, 0x45, 0x20, 0x47, 0x4e, - 0x4f, 0x4d, 0x45, 0x20, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x41, 0x54, 0x49, - 0x4f, 0x4e, 0x20, 0x42, 0x45, 0x20, 0x4c, 0x49, 0x41, 0x42, 0x4c, 0x45, - 0x20, 0x46, 0x4f, 0x52, 0x20, 0x41, 0x4e, 0x59, 0x20, 0x43, 0x4c, 0x41, - 0x49, 0x4d, 0x2c, 0x20, 0x44, 0x41, 0x4d, 0x41, 0x47, 0x45, 0x53, 0x20, - 0x4f, 0x52, 0x20, 0x4f, 0x54, 0x48, 0x45, 0x52, 0x20, 0x4c, 0x49, 0x41, - 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x2c, 0x20, 0x49, 0x4e, 0x43, 0x4c, - 0x55, 0x44, 0x49, 0x4e, 0x47, 0x20, 0x41, 0x4e, 0x59, 0x20, 0x47, 0x45, - 0x4e, 0x45, 0x52, 0x41, 0x4c, 0x2c, 0x20, 0x53, 0x50, 0x45, 0x43, 0x49, - 0x41, 0x4c, 0x2c, 0x20, 0x49, 0x4e, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, - 0x2c, 0x20, 0x49, 0x4e, 0x43, 0x49, 0x44, 0x45, 0x4e, 0x54, 0x41, 0x4c, - 0x2c, 0x20, 0x4f, 0x52, 0x20, 0x43, 0x4f, 0x4e, 0x53, 0x45, 0x51, 0x55, - 0x45, 0x4e, 0x54, 0x49, 0x41, 0x4c, 0x20, 0x44, 0x41, 0x4d, 0x41, 0x47, - 0x45, 0x53, 0x2c, 0x20, 0x57, 0x48, 0x45, 0x54, 0x48, 0x45, 0x52, 0x20, - 0x49, 0x4e, 0x20, 0x41, 0x4e, 0x20, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, - 0x20, 0x4f, 0x46, 0x20, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x54, - 0x2c, 0x20, 0x54, 0x4f, 0x52, 0x54, 0x20, 0x4f, 0x52, 0x20, 0x4f, 0x54, - 0x48, 0x45, 0x52, 0x57, 0x49, 0x53, 0x45, 0x2c, 0x20, 0x41, 0x52, 0x49, - 0x53, 0x49, 0x4e, 0x47, 0x20, 0x46, 0x52, 0x4f, 0x4d, 0x2c, 0x20, 0x4f, - 0x55, 0x54, 0x20, 0x4f, 0x46, 0x20, 0x54, 0x48, 0x45, 0x20, 0x55, 0x53, - 0x45, 0x20, 0x4f, 0x52, 0x20, 0x49, 0x4e, 0x41, 0x42, 0x49, 0x4c, 0x49, - 0x54, 0x59, 0x20, 0x54, 0x4f, 0x20, 0x55, 0x53, 0x45, 0x20, 0x54, 0x48, - 0x45, 0x20, 0x46, 0x4f, 0x4e, 0x54, 0x20, 0x53, 0x4f, 0x46, 0x54, 0x57, - 0x41, 0x52, 0x45, 0x20, 0x4f, 0x52, 0x20, 0x46, 0x52, 0x4f, 0x4d, 0x20, - 0x4f, 0x54, 0x48, 0x45, 0x52, 0x20, 0x44, 0x45, 0x41, 0x4c, 0x49, 0x4e, - 0x47, 0x53, 0x20, 0x49, 0x4e, 0x20, 0x54, 0x48, 0x45, 0x20, 0x46, 0x4f, - 0x4e, 0x54, 0x20, 0x53, 0x4f, 0x46, 0x54, 0x57, 0x41, 0x52, 0x45, 0x2e, - 0x0a, 0x0a, 0x45, 0x78, 0x63, 0x65, 0x70, 0x74, 0x20, 0x61, 0x73, 0x20, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x69, 0x6e, - 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x69, 0x63, 0x65, - 0x2c, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x20, - 0x6f, 0x66, 0x20, 0x47, 0x6e, 0x6f, 0x6d, 0x65, 0x2c, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x47, 0x6e, 0x6f, 0x6d, 0x65, 0x20, 0x46, 0x6f, 0x75, 0x6e, - 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, - 0x42, 0x69, 0x74, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x20, 0x49, 0x6e, - 0x63, 0x2e, 0x2c, 0x20, 0x73, 0x68, 0x61, 0x6c, 0x6c, 0x20, 0x6e, 0x6f, - 0x74, 0x20, 0x62, 0x65, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x69, 0x6e, - 0x20, 0x61, 0x64, 0x76, 0x65, 0x72, 0x74, 0x69, 0x73, 0x69, 0x6e, 0x67, - 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x77, 0x69, 0x73, - 0x65, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x6d, 0x6f, 0x74, 0x65, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x61, 0x6c, 0x65, 0x2c, 0x20, 0x75, - 0x73, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, - 0x64, 0x65, 0x61, 0x6c, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x69, 0x6e, 0x20, - 0x74, 0x68, 0x69, 0x73, 0x20, 0x46, 0x6f, 0x6e, 0x74, 0x20, 0x53, 0x6f, - 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x20, 0x77, 0x69, 0x74, 0x68, 0x6f, - 0x75, 0x74, 0x20, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x20, 0x77, 0x72, 0x69, - 0x74, 0x74, 0x65, 0x6e, 0x20, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, - 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, - 0x74, 0x68, 0x65, 0x20, 0x47, 0x6e, 0x6f, 0x6d, 0x65, 0x20, 0x46, 0x6f, - 0x75, 0x6e, 0x64, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x72, 0x20, - 0x42, 0x69, 0x74, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x20, 0x49, 0x6e, - 0x63, 0x2e, 0x2c, 0x20, 0x72, 0x65, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, - 0x76, 0x65, 0x6c, 0x79, 0x2e, 0x20, 0x46, 0x6f, 0x72, 0x20, 0x66, 0x75, - 0x72, 0x74, 0x68, 0x65, 0x72, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x63, 0x74, 0x3a, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x73, 0x20, 0x61, 0x74, - 0x20, 0x67, 0x6e, 0x6f, 0x6d, 0x65, 0x20, 0x64, 0x6f, 0x74, 0x20, 0x6f, - 0x72, 0x67, 0x2e, 0x20, 0x0a, 0x00, 0x00, 0x68, 0x00, 0x74, 0x00, 0x74, - 0x00, 0x70, 0x00, 0x3a, 0x00, 0x2f, 0x00, 0x2f, 0x00, 0x64, 0x00, 0x65, - 0x00, 0x6a, 0x00, 0x61, 0x00, 0x76, 0x00, 0x75, 0x00, 0x2e, 0x00, 0x73, - 0x00, 0x6f, 0x00, 0x75, 0x00, 0x72, 0x00, 0x63, 0x00, 0x65, 0x00, 0x66, - 0x00, 0x6f, 0x00, 0x72, 0x00, 0x67, 0x00, 0x65, 0x00, 0x2e, 0x00, 0x6e, - 0x00, 0x65, 0x00, 0x74, 0x00, 0x2f, 0x00, 0x77, 0x00, 0x69, 0x00, 0x6b, - 0x00, 0x69, 0x00, 0x2f, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x65, - 0x00, 0x78, 0x00, 0x2e, 0x00, 0x70, 0x00, 0x68, 0x00, 0x70, 0x00, 0x2f, - 0x00, 0x4c, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x73, - 0x00, 0x65, 0x00, 0x00, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x64, - 0x65, 0x6a, 0x61, 0x76, 0x75, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x66, 0x6f, 0x72, 0x67, 0x65, 0x2e, 0x6e, 0x65, 0x74, 0x2f, 0x77, 0x69, - 0x6b, 0x69, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x70, 0x68, 0x70, - 0x2f, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7e, 0x00, 0x5a, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xee, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, - 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, 0x0c, - 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00, 0x11, 0x00, 0x12, - 0x00, 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, 0x18, - 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1b, 0x00, 0x1c, 0x00, 0x1d, 0x00, 0x1e, - 0x00, 0x1f, 0x00, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, - 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2a, - 0x00, 0x2b, 0x00, 0x2c, 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f, 0x00, 0x30, - 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, - 0x00, 0x37, 0x00, 0x38, 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, 0x00, 0x3c, - 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x40, 0x00, 0x41, 0x00, 0x42, - 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, 0x48, - 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b, 0x00, 0x4c, 0x00, 0x4d, 0x00, 0x4e, - 0x00, 0x4f, 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, - 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, 0x58, 0x00, 0x59, 0x00, 0x5a, - 0x00, 0x5b, 0x00, 0x5c, 0x00, 0x5d, 0x00, 0x5e, 0x00, 0x5f, 0x00, 0x60, - 0x00, 0x61, 0x00, 0xac, 0x00, 0xa3, 0x00, 0x84, 0x00, 0x85, 0x00, 0xbd, - 0x00, 0x96, 0x00, 0xe8, 0x00, 0x86, 0x00, 0x8e, 0x00, 0x8b, 0x00, 0x9d, - 0x00, 0xa9, 0x00, 0xa4, 0x01, 0x02, 0x00, 0x8a, 0x00, 0xda, 0x00, 0x83, - 0x00, 0x93, 0x00, 0xf2, 0x00, 0xf3, 0x00, 0x8d, 0x00, 0x97, 0x00, 0x88, - 0x00, 0xc3, 0x00, 0xde, 0x00, 0xf1, 0x00, 0x9e, 0x00, 0xaa, 0x00, 0xf5, - 0x00, 0xf4, 0x00, 0xf6, 0x00, 0xa2, 0x00, 0xad, 0x00, 0xc9, 0x00, 0xc7, - 0x00, 0xae, 0x00, 0x62, 0x00, 0x63, 0x00, 0x90, 0x00, 0x64, 0x00, 0xcb, - 0x00, 0x65, 0x00, 0xc8, 0x00, 0xca, 0x00, 0xcf, 0x00, 0xcc, 0x00, 0xcd, - 0x00, 0xce, 0x00, 0xe9, 0x00, 0x66, 0x00, 0xd3, 0x00, 0xd0, 0x00, 0xd1, - 0x00, 0xaf, 0x00, 0x67, 0x00, 0xf0, 0x00, 0x91, 0x00, 0xd6, 0x00, 0xd4, - 0x00, 0xd5, 0x00, 0x68, 0x00, 0xeb, 0x00, 0xed, 0x00, 0x89, 0x00, 0x6a, - 0x00, 0x69, 0x00, 0x6b, 0x00, 0x6d, 0x00, 0x6c, 0x00, 0x6e, 0x00, 0xa0, - 0x00, 0x6f, 0x00, 0x71, 0x00, 0x70, 0x00, 0x72, 0x00, 0x73, 0x00, 0x75, - 0x00, 0x74, 0x00, 0x76, 0x00, 0x77, 0x00, 0xea, 0x00, 0x78, 0x00, 0x7a, - 0x00, 0x79, 0x00, 0x7b, 0x00, 0x7d, 0x00, 0x7c, 0x00, 0xb8, 0x00, 0xa1, - 0x00, 0x7f, 0x00, 0x7e, 0x00, 0x80, 0x00, 0x81, 0x00, 0xec, 0x00, 0xee, - 0x00, 0xba, 0x01, 0x03, 0x01, 0x04, 0x01, 0x05, 0x01, 0x06, 0x01, 0x07, - 0x01, 0x08, 0x00, 0xfd, 0x00, 0xfe, 0x01, 0x09, 0x01, 0x0a, 0x01, 0x0b, - 0x01, 0x0c, 0x00, 0xff, 0x01, 0x00, 0x01, 0x0d, 0x01, 0x0e, 0x01, 0x0f, - 0x01, 0x01, 0x01, 0x10, 0x01, 0x11, 0x01, 0x12, 0x01, 0x13, 0x01, 0x14, - 0x01, 0x15, 0x01, 0x16, 0x01, 0x17, 0x01, 0x18, 0x01, 0x19, 0x01, 0x1a, - 0x01, 0x1b, 0x00, 0xf8, 0x00, 0xf9, 0x01, 0x1c, 0x01, 0x1d, 0x01, 0x1e, - 0x01, 0x1f, 0x01, 0x20, 0x01, 0x21, 0x01, 0x22, 0x01, 0x23, 0x01, 0x24, - 0x01, 0x25, 0x01, 0x26, 0x01, 0x27, 0x01, 0x28, 0x01, 0x29, 0x01, 0x2a, - 0x01, 0x2b, 0x00, 0xfa, 0x00, 0xd7, 0x01, 0x2c, 0x01, 0x2d, 0x01, 0x2e, - 0x01, 0x2f, 0x01, 0x30, 0x01, 0x31, 0x01, 0x32, 0x01, 0x33, 0x01, 0x34, - 0x01, 0x35, 0x01, 0x36, 0x01, 0x37, 0x01, 0x38, 0x01, 0x39, 0x01, 0x3a, - 0x00, 0xe2, 0x00, 0xe3, 0x01, 0x3b, 0x01, 0x3c, 0x01, 0x3d, 0x01, 0x3e, - 0x01, 0x3f, 0x01, 0x40, 0x01, 0x41, 0x01, 0x42, 0x01, 0x43, 0x01, 0x44, - 0x01, 0x45, 0x01, 0x46, 0x01, 0x47, 0x01, 0x48, 0x01, 0x49, 0x00, 0xb0, - 0x00, 0xb1, 0x01, 0x4a, 0x01, 0x4b, 0x01, 0x4c, 0x01, 0x4d, 0x01, 0x4e, - 0x01, 0x4f, 0x01, 0x50, 0x01, 0x51, 0x01, 0x52, 0x01, 0x53, 0x00, 0xfb, - 0x00, 0xfc, 0x00, 0xe4, 0x00, 0xe5, 0x01, 0x54, 0x01, 0x55, 0x01, 0x56, - 0x01, 0x57, 0x01, 0x58, 0x01, 0x59, 0x01, 0x5a, 0x01, 0x5b, 0x01, 0x5c, - 0x01, 0x5d, 0x01, 0x5e, 0x01, 0x5f, 0x01, 0x60, 0x01, 0x61, 0x01, 0x62, - 0x01, 0x63, 0x01, 0x64, 0x01, 0x65, 0x01, 0x66, 0x01, 0x67, 0x01, 0x68, - 0x01, 0x69, 0x00, 0xbb, 0x01, 0x6a, 0x01, 0x6b, 0x01, 0x6c, 0x01, 0x6d, - 0x00, 0xe6, 0x00, 0xe7, 0x01, 0x6e, 0x01, 0x6f, 0x01, 0x70, 0x01, 0x71, - 0x01, 0x72, 0x01, 0x73, 0x01, 0x74, 0x01, 0x75, 0x01, 0x76, 0x01, 0x77, - 0x01, 0x78, 0x01, 0x79, 0x01, 0x7a, 0x01, 0x7b, 0x01, 0x7c, 0x01, 0x7d, - 0x01, 0x7e, 0x01, 0x7f, 0x01, 0x80, 0x00, 0xa6, 0x01, 0x81, 0x01, 0x82, - 0x01, 0x83, 0x01, 0x84, 0x01, 0x85, 0x01, 0x86, 0x01, 0x87, 0x01, 0x88, - 0x01, 0x89, 0x01, 0x8a, 0x01, 0x8b, 0x01, 0x8c, 0x01, 0x8d, 0x01, 0x8e, - 0x01, 0x8f, 0x01, 0x90, 0x01, 0x91, 0x01, 0x92, 0x01, 0x93, 0x01, 0x94, - 0x01, 0x95, 0x01, 0x96, 0x01, 0x97, 0x01, 0x98, 0x01, 0x99, 0x01, 0x9a, - 0x01, 0x9b, 0x01, 0x9c, 0x01, 0x9d, 0x01, 0x9e, 0x01, 0x9f, 0x01, 0xa0, - 0x01, 0xa1, 0x01, 0xa2, 0x01, 0xa3, 0x01, 0xa4, 0x01, 0xa5, 0x01, 0xa6, - 0x01, 0xa7, 0x01, 0xa8, 0x01, 0xa9, 0x01, 0xaa, 0x01, 0xab, 0x01, 0xac, - 0x01, 0xad, 0x01, 0xae, 0x01, 0xaf, 0x01, 0xb0, 0x01, 0xb1, 0x01, 0xb2, - 0x01, 0xb3, 0x01, 0xb4, 0x01, 0xb5, 0x01, 0xb6, 0x01, 0xb7, 0x01, 0xb8, - 0x01, 0xb9, 0x01, 0xba, 0x01, 0xbb, 0x01, 0xbc, 0x01, 0xbd, 0x01, 0xbe, - 0x01, 0xbf, 0x01, 0xc0, 0x01, 0xc1, 0x01, 0xc2, 0x01, 0xc3, 0x01, 0xc4, - 0x01, 0xc5, 0x01, 0xc6, 0x01, 0xc7, 0x01, 0xc8, 0x01, 0xc9, 0x01, 0xca, - 0x01, 0xcb, 0x01, 0xcc, 0x01, 0xcd, 0x01, 0xce, 0x01, 0xcf, 0x01, 0xd0, - 0x01, 0xd1, 0x01, 0xd2, 0x01, 0xd3, 0x01, 0xd4, 0x01, 0xd5, 0x01, 0xd6, - 0x01, 0xd7, 0x01, 0xd8, 0x01, 0xd9, 0x01, 0xda, 0x01, 0xdb, 0x01, 0xdc, - 0x01, 0xdd, 0x01, 0xde, 0x01, 0xdf, 0x01, 0xe0, 0x01, 0xe1, 0x01, 0xe2, - 0x01, 0xe3, 0x01, 0xe4, 0x01, 0xe5, 0x01, 0xe6, 0x01, 0xe7, 0x01, 0xe8, - 0x01, 0xe9, 0x01, 0xea, 0x01, 0xeb, 0x01, 0xec, 0x01, 0xed, 0x01, 0xee, - 0x01, 0xef, 0x01, 0xf0, 0x01, 0xf1, 0x01, 0xf2, 0x01, 0xf3, 0x01, 0xf4, - 0x01, 0xf5, 0x01, 0xf6, 0x01, 0xf7, 0x01, 0xf8, 0x01, 0xf9, 0x01, 0xfa, - 0x01, 0xfb, 0x01, 0xfc, 0x01, 0xfd, 0x01, 0xfe, 0x01, 0xff, 0x02, 0x00, - 0x02, 0x01, 0x02, 0x02, 0x02, 0x03, 0x02, 0x04, 0x02, 0x05, 0x02, 0x06, - 0x02, 0x07, 0x02, 0x08, 0x02, 0x09, 0x02, 0x0a, 0x02, 0x0b, 0x02, 0x0c, - 0x02, 0x0d, 0x02, 0x0e, 0x02, 0x0f, 0x02, 0x10, 0x02, 0x11, 0x02, 0x12, - 0x02, 0x13, 0x02, 0x14, 0x02, 0x15, 0x02, 0x16, 0x02, 0x17, 0x02, 0x18, - 0x02, 0x19, 0x02, 0x1a, 0x02, 0x1b, 0x02, 0x1c, 0x02, 0x1d, 0x02, 0x1e, - 0x02, 0x1f, 0x02, 0x20, 0x02, 0x21, 0x02, 0x22, 0x02, 0x23, 0x02, 0x24, - 0x02, 0x25, 0x02, 0x26, 0x02, 0x27, 0x02, 0x28, 0x02, 0x29, 0x02, 0x2a, - 0x02, 0x2b, 0x02, 0x2c, 0x02, 0x2d, 0x02, 0x2e, 0x02, 0x2f, 0x02, 0x30, - 0x02, 0x31, 0x02, 0x32, 0x02, 0x33, 0x02, 0x34, 0x02, 0x35, 0x02, 0x36, - 0x02, 0x37, 0x02, 0x38, 0x02, 0x39, 0x02, 0x3a, 0x02, 0x3b, 0x02, 0x3c, - 0x02, 0x3d, 0x02, 0x3e, 0x02, 0x3f, 0x02, 0x40, 0x02, 0x41, 0x02, 0x42, - 0x02, 0x43, 0x02, 0x44, 0x02, 0x45, 0x02, 0x46, 0x02, 0x47, 0x02, 0x48, - 0x02, 0x49, 0x02, 0x4a, 0x02, 0x4b, 0x02, 0x4c, 0x02, 0x4d, 0x02, 0x4e, - 0x02, 0x4f, 0x02, 0x50, 0x02, 0x51, 0x02, 0x52, 0x02, 0x53, 0x02, 0x54, - 0x02, 0x55, 0x02, 0x56, 0x02, 0x57, 0x02, 0x58, 0x02, 0x59, 0x02, 0x5a, - 0x02, 0x5b, 0x02, 0x5c, 0x02, 0x5d, 0x02, 0x5e, 0x02, 0x5f, 0x02, 0x60, - 0x02, 0x61, 0x02, 0x62, 0x02, 0x63, 0x02, 0x64, 0x02, 0x65, 0x02, 0x66, - 0x02, 0x67, 0x02, 0x68, 0x02, 0x69, 0x02, 0x6a, 0x02, 0x6b, 0x02, 0x6c, - 0x02, 0x6d, 0x02, 0x6e, 0x02, 0x6f, 0x02, 0x70, 0x02, 0x71, 0x02, 0x72, - 0x02, 0x73, 0x02, 0x74, 0x02, 0x75, 0x02, 0x76, 0x02, 0x77, 0x02, 0x78, - 0x02, 0x79, 0x02, 0x7a, 0x02, 0x7b, 0x02, 0x7c, 0x02, 0x7d, 0x02, 0x7e, - 0x02, 0x7f, 0x02, 0x80, 0x02, 0x81, 0x02, 0x82, 0x02, 0x83, 0x02, 0x84, - 0x02, 0x85, 0x02, 0x86, 0x02, 0x87, 0x02, 0x88, 0x02, 0x89, 0x02, 0x8a, - 0x02, 0x8b, 0x02, 0x8c, 0x02, 0x8d, 0x02, 0x8e, 0x02, 0x8f, 0x02, 0x90, - 0x02, 0x91, 0x02, 0x92, 0x00, 0xd8, 0x00, 0xe1, 0x02, 0x93, 0x02, 0x94, - 0x02, 0x95, 0x02, 0x96, 0x02, 0x97, 0x02, 0x98, 0x02, 0x99, 0x02, 0x9a, - 0x02, 0x9b, 0x02, 0x9c, 0x02, 0x9d, 0x02, 0x9e, 0x00, 0xdb, 0x00, 0xdc, - 0x00, 0xdd, 0x00, 0xe0, 0x00, 0xd9, 0x00, 0xdf, 0x02, 0x9f, 0x02, 0xa0, - 0x02, 0xa1, 0x02, 0xa2, 0x02, 0xa3, 0x02, 0xa4, 0x02, 0xa5, 0x02, 0xa6, - 0x02, 0xa7, 0x02, 0xa8, 0x02, 0xa9, 0x02, 0xaa, 0x02, 0xab, 0x02, 0xac, - 0x02, 0xad, 0x02, 0xae, 0x02, 0xaf, 0x02, 0xb0, 0x02, 0xb1, 0x02, 0xb2, - 0x02, 0xb3, 0x02, 0xb4, 0x02, 0xb5, 0x02, 0xb6, 0x02, 0xb7, 0x02, 0xb8, - 0x02, 0xb9, 0x02, 0xba, 0x02, 0xbb, 0x02, 0xbc, 0x02, 0xbd, 0x02, 0xbe, - 0x02, 0xbf, 0x02, 0xc0, 0x02, 0xc1, 0x02, 0xc2, 0x02, 0xc3, 0x02, 0xc4, - 0x02, 0xc5, 0x02, 0xc6, 0x02, 0xc7, 0x02, 0xc8, 0x02, 0xc9, 0x02, 0xca, - 0x02, 0xcb, 0x02, 0xcc, 0x02, 0xcd, 0x02, 0xce, 0x02, 0xcf, 0x02, 0xd0, - 0x02, 0xd1, 0x02, 0xd2, 0x02, 0xd3, 0x02, 0xd4, 0x02, 0xd5, 0x02, 0xd6, - 0x02, 0xd7, 0x02, 0xd8, 0x02, 0xd9, 0x02, 0xda, 0x02, 0xdb, 0x02, 0xdc, - 0x02, 0xdd, 0x02, 0xde, 0x02, 0xdf, 0x02, 0xe0, 0x02, 0xe1, 0x02, 0xe2, - 0x02, 0xe3, 0x02, 0xe4, 0x02, 0xe5, 0x02, 0xe6, 0x02, 0xe7, 0x02, 0xe8, - 0x02, 0xe9, 0x02, 0xea, 0x02, 0xeb, 0x02, 0xec, 0x02, 0xed, 0x02, 0xee, - 0x02, 0xef, 0x02, 0xf0, 0x02, 0xf1, 0x02, 0xf2, 0x02, 0xf3, 0x02, 0xf4, - 0x02, 0xf5, 0x02, 0xf6, 0x02, 0xf7, 0x02, 0xf8, 0x02, 0xf9, 0x02, 0xfa, - 0x02, 0xfb, 0x02, 0xfc, 0x02, 0xfd, 0x02, 0xfe, 0x02, 0xff, 0x03, 0x00, - 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, 0x03, 0x04, 0x03, 0x05, 0x03, 0x06, - 0x03, 0x07, 0x03, 0x08, 0x03, 0x09, 0x03, 0x0a, 0x03, 0x0b, 0x03, 0x0c, - 0x03, 0x0d, 0x03, 0x0e, 0x03, 0x0f, 0x03, 0x10, 0x03, 0x11, 0x03, 0x12, - 0x03, 0x13, 0x03, 0x14, 0x00, 0x9f, 0x03, 0x15, 0x03, 0x16, 0x03, 0x17, - 0x03, 0x18, 0x03, 0x19, 0x03, 0x1a, 0x03, 0x1b, 0x03, 0x1c, 0x03, 0x1d, - 0x03, 0x1e, 0x03, 0x1f, 0x03, 0x20, 0x03, 0x21, 0x03, 0x22, 0x03, 0x23, - 0x03, 0x24, 0x03, 0x25, 0x03, 0x26, 0x03, 0x27, 0x03, 0x28, 0x03, 0x29, - 0x03, 0x2a, 0x00, 0x9b, 0x03, 0x2b, 0x03, 0x2c, 0x03, 0x2d, 0x03, 0x2e, - 0x03, 0x2f, 0x03, 0x30, 0x03, 0x31, 0x03, 0x32, 0x03, 0x33, 0x03, 0x34, - 0x03, 0x35, 0x03, 0x36, 0x03, 0x37, 0x03, 0x38, 0x03, 0x39, 0x03, 0x3a, - 0x03, 0x3b, 0x03, 0x3c, 0x03, 0x3d, 0x03, 0x3e, 0x03, 0x3f, 0x03, 0x40, - 0x03, 0x41, 0x03, 0x42, 0x03, 0x43, 0x03, 0x44, 0x03, 0x45, 0x03, 0x46, - 0x03, 0x47, 0x03, 0x48, 0x03, 0x49, 0x03, 0x4a, 0x03, 0x4b, 0x03, 0x4c, - 0x03, 0x4d, 0x03, 0x4e, 0x03, 0x4f, 0x03, 0x50, 0x03, 0x51, 0x03, 0x52, - 0x03, 0x53, 0x03, 0x54, 0x03, 0x55, 0x03, 0x56, 0x03, 0x57, 0x03, 0x58, - 0x03, 0x59, 0x03, 0x5a, 0x03, 0x5b, 0x03, 0x5c, 0x03, 0x5d, 0x03, 0x5e, - 0x03, 0x5f, 0x03, 0x60, 0x03, 0x61, 0x03, 0x62, 0x03, 0x63, 0x03, 0x64, - 0x03, 0x65, 0x03, 0x66, 0x03, 0x67, 0x03, 0x68, 0x03, 0x69, 0x03, 0x6a, - 0x03, 0x6b, 0x03, 0x6c, 0x03, 0x6d, 0x03, 0x6e, 0x03, 0x6f, 0x03, 0x70, - 0x03, 0x71, 0x03, 0x72, 0x03, 0x73, 0x03, 0x74, 0x03, 0x75, 0x03, 0x76, - 0x03, 0x77, 0x03, 0x78, 0x03, 0x79, 0x03, 0x7a, 0x03, 0x7b, 0x03, 0x7c, - 0x03, 0x7d, 0x03, 0x7e, 0x03, 0x7f, 0x03, 0x80, 0x03, 0x81, 0x03, 0x82, - 0x03, 0x83, 0x03, 0x84, 0x03, 0x85, 0x03, 0x86, 0x03, 0x87, 0x03, 0x88, - 0x03, 0x89, 0x03, 0x8a, 0x03, 0x8b, 0x03, 0x8c, 0x03, 0x8d, 0x03, 0x8e, - 0x03, 0x8f, 0x03, 0x90, 0x03, 0x91, 0x03, 0x92, 0x03, 0x93, 0x03, 0x94, - 0x03, 0x95, 0x03, 0x96, 0x03, 0x97, 0x03, 0x98, 0x03, 0x99, 0x03, 0x9a, - 0x03, 0x9b, 0x03, 0x9c, 0x03, 0x9d, 0x03, 0x9e, 0x03, 0x9f, 0x03, 0xa0, - 0x03, 0xa1, 0x03, 0xa2, 0x03, 0xa3, 0x03, 0xa4, 0x03, 0xa5, 0x03, 0xa6, - 0x03, 0xa7, 0x03, 0xa8, 0x03, 0xa9, 0x03, 0xaa, 0x03, 0xab, 0x03, 0xac, - 0x03, 0xad, 0x03, 0xae, 0x03, 0xaf, 0x03, 0xb0, 0x03, 0xb1, 0x03, 0xb2, - 0x03, 0xb3, 0x03, 0xb4, 0x03, 0xb5, 0x03, 0xb6, 0x03, 0xb7, 0x03, 0xb8, - 0x03, 0xb9, 0x03, 0xba, 0x03, 0xbb, 0x03, 0xbc, 0x03, 0xbd, 0x03, 0xbe, - 0x03, 0xbf, 0x03, 0xc0, 0x03, 0xc1, 0x03, 0xc2, 0x03, 0xc3, 0x03, 0xc4, - 0x03, 0xc5, 0x03, 0xc6, 0x03, 0xc7, 0x03, 0xc8, 0x03, 0xc9, 0x03, 0xca, - 0x03, 0xcb, 0x03, 0xcc, 0x03, 0xcd, 0x03, 0xce, 0x03, 0xcf, 0x03, 0xd0, - 0x03, 0xd1, 0x03, 0xd2, 0x03, 0xd3, 0x03, 0xd4, 0x03, 0xd5, 0x03, 0xd6, - 0x03, 0xd7, 0x03, 0xd8, 0x03, 0xd9, 0x03, 0xda, 0x03, 0xdb, 0x03, 0xdc, - 0x03, 0xdd, 0x03, 0xde, 0x03, 0xdf, 0x03, 0xe0, 0x03, 0xe1, 0x03, 0xe2, - 0x03, 0xe3, 0x03, 0xe4, 0x03, 0xe5, 0x03, 0xe6, 0x03, 0xe7, 0x03, 0xe8, - 0x03, 0xe9, 0x03, 0xea, 0x03, 0xeb, 0x03, 0xec, 0x03, 0xed, 0x03, 0xee, - 0x03, 0xef, 0x03, 0xf0, 0x03, 0xf1, 0x03, 0xf2, 0x03, 0xf3, 0x03, 0xf4, - 0x03, 0xf5, 0x03, 0xf6, 0x03, 0xf7, 0x03, 0xf8, 0x03, 0xf9, 0x03, 0xfa, - 0x03, 0xfb, 0x03, 0xfc, 0x03, 0xfd, 0x03, 0xfe, 0x03, 0xff, 0x04, 0x00, - 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x04, 0x04, 0x04, 0x05, 0x04, 0x06, - 0x04, 0x07, 0x04, 0x08, 0x04, 0x09, 0x04, 0x0a, 0x04, 0x0b, 0x04, 0x0c, - 0x04, 0x0d, 0x04, 0x0e, 0x04, 0x0f, 0x04, 0x10, 0x04, 0x11, 0x04, 0x12, - 0x04, 0x13, 0x04, 0x14, 0x04, 0x15, 0x04, 0x16, 0x04, 0x17, 0x04, 0x18, - 0x04, 0x19, 0x04, 0x1a, 0x04, 0x1b, 0x04, 0x1c, 0x04, 0x1d, 0x04, 0x1e, - 0x04, 0x1f, 0x04, 0x20, 0x04, 0x21, 0x04, 0x22, 0x04, 0x23, 0x04, 0x24, - 0x04, 0x25, 0x04, 0x26, 0x04, 0x27, 0x04, 0x28, 0x04, 0x29, 0x04, 0x2a, - 0x04, 0x2b, 0x04, 0x2c, 0x04, 0x2d, 0x04, 0x2e, 0x04, 0x2f, 0x04, 0x30, - 0x04, 0x31, 0x04, 0x32, 0x04, 0x33, 0x04, 0x34, 0x04, 0x35, 0x04, 0x36, - 0x04, 0x37, 0x04, 0x38, 0x04, 0x39, 0x04, 0x3a, 0x04, 0x3b, 0x04, 0x3c, - 0x04, 0x3d, 0x04, 0x3e, 0x04, 0x3f, 0x04, 0x40, 0x04, 0x41, 0x04, 0x42, - 0x04, 0x43, 0x04, 0x44, 0x04, 0x45, 0x04, 0x46, 0x04, 0x47, 0x04, 0x48, - 0x04, 0x49, 0x04, 0x4a, 0x04, 0x4b, 0x04, 0x4c, 0x04, 0x4d, 0x04, 0x4e, - 0x04, 0x4f, 0x04, 0x50, 0x04, 0x51, 0x04, 0x52, 0x04, 0x53, 0x04, 0x54, - 0x04, 0x55, 0x04, 0x56, 0x04, 0x57, 0x04, 0x58, 0x04, 0x59, 0x04, 0x5a, - 0x04, 0x5b, 0x04, 0x5c, 0x04, 0x5d, 0x04, 0x5e, 0x04, 0x5f, 0x04, 0x60, - 0x04, 0x61, 0x04, 0x62, 0x04, 0x63, 0x04, 0x64, 0x04, 0x65, 0x04, 0x66, - 0x04, 0x67, 0x04, 0x68, 0x04, 0x69, 0x04, 0x6a, 0x04, 0x6b, 0x04, 0x6c, - 0x04, 0x6d, 0x04, 0x6e, 0x04, 0x6f, 0x04, 0x70, 0x04, 0x71, 0x04, 0x72, - 0x04, 0x73, 0x04, 0x74, 0x04, 0x75, 0x04, 0x76, 0x04, 0x77, 0x04, 0x78, - 0x04, 0x79, 0x04, 0x7a, 0x04, 0x7b, 0x04, 0x7c, 0x04, 0x7d, 0x04, 0x7e, - 0x04, 0x7f, 0x04, 0x80, 0x04, 0x81, 0x04, 0x82, 0x04, 0x83, 0x04, 0x84, - 0x04, 0x85, 0x04, 0x86, 0x04, 0x87, 0x04, 0x88, 0x04, 0x89, 0x04, 0x8a, - 0x04, 0x8b, 0x04, 0x8c, 0x04, 0x8d, 0x04, 0x8e, 0x04, 0x8f, 0x04, 0x90, - 0x04, 0x91, 0x04, 0x92, 0x04, 0x93, 0x04, 0x94, 0x04, 0x95, 0x04, 0x96, - 0x04, 0x97, 0x04, 0x98, 0x04, 0x99, 0x04, 0x9a, 0x04, 0x9b, 0x04, 0x9c, - 0x04, 0x9d, 0x04, 0x9e, 0x04, 0x9f, 0x04, 0xa0, 0x04, 0xa1, 0x04, 0xa2, - 0x04, 0xa3, 0x04, 0xa4, 0x04, 0xa5, 0x04, 0xa6, 0x04, 0xa7, 0x04, 0xa8, - 0x04, 0xa9, 0x04, 0xaa, 0x04, 0xab, 0x04, 0xac, 0x04, 0xad, 0x04, 0xae, - 0x04, 0xaf, 0x04, 0xb0, 0x04, 0xb1, 0x04, 0xb2, 0x04, 0xb3, 0x04, 0xb4, - 0x04, 0xb5, 0x04, 0xb6, 0x04, 0xb7, 0x04, 0xb8, 0x04, 0xb9, 0x04, 0xba, - 0x04, 0xbb, 0x04, 0xbc, 0x04, 0xbd, 0x04, 0xbe, 0x04, 0xbf, 0x04, 0xc0, - 0x04, 0xc1, 0x04, 0xc2, 0x04, 0xc3, 0x04, 0xc4, 0x04, 0xc5, 0x04, 0xc6, - 0x04, 0xc7, 0x04, 0xc8, 0x04, 0xc9, 0x04, 0xca, 0x04, 0xcb, 0x04, 0xcc, - 0x04, 0xcd, 0x04, 0xce, 0x04, 0xcf, 0x04, 0xd0, 0x04, 0xd1, 0x04, 0xd2, - 0x04, 0xd3, 0x04, 0xd4, 0x04, 0xd5, 0x04, 0xd6, 0x04, 0xd7, 0x04, 0xd8, - 0x04, 0xd9, 0x04, 0xda, 0x04, 0xdb, 0x04, 0xdc, 0x04, 0xdd, 0x04, 0xde, - 0x04, 0xdf, 0x04, 0xe0, 0x04, 0xe1, 0x04, 0xe2, 0x04, 0xe3, 0x04, 0xe4, - 0x04, 0xe5, 0x04, 0xe6, 0x04, 0xe7, 0x04, 0xe8, 0x04, 0xe9, 0x04, 0xea, - 0x04, 0xeb, 0x04, 0xec, 0x04, 0xed, 0x04, 0xee, 0x04, 0xef, 0x04, 0xf0, - 0x04, 0xf1, 0x04, 0xf2, 0x04, 0xf3, 0x04, 0xf4, 0x04, 0xf5, 0x04, 0xf6, - 0x04, 0xf7, 0x04, 0xf8, 0x04, 0xf9, 0x04, 0xfa, 0x04, 0xfb, 0x04, 0xfc, - 0x04, 0xfd, 0x04, 0xfe, 0x04, 0xff, 0x05, 0x00, 0x05, 0x01, 0x05, 0x02, - 0x05, 0x03, 0x05, 0x04, 0x05, 0x05, 0x05, 0x06, 0x05, 0x07, 0x05, 0x08, - 0x05, 0x09, 0x05, 0x0a, 0x05, 0x0b, 0x05, 0x0c, 0x05, 0x0d, 0x05, 0x0e, - 0x05, 0x0f, 0x05, 0x10, 0x05, 0x11, 0x05, 0x12, 0x05, 0x13, 0x05, 0x14, - 0x05, 0x15, 0x05, 0x16, 0x05, 0x17, 0x05, 0x18, 0x05, 0x19, 0x05, 0x1a, - 0x05, 0x1b, 0x05, 0x1c, 0x05, 0x1d, 0x05, 0x1e, 0x05, 0x1f, 0x05, 0x20, - 0x05, 0x21, 0x05, 0x22, 0x05, 0x23, 0x05, 0x24, 0x05, 0x25, 0x05, 0x26, - 0x05, 0x27, 0x05, 0x28, 0x05, 0x29, 0x05, 0x2a, 0x05, 0x2b, 0x05, 0x2c, - 0x05, 0x2d, 0x05, 0x2e, 0x05, 0x2f, 0x05, 0x30, 0x05, 0x31, 0x05, 0x32, - 0x05, 0x33, 0x05, 0x34, 0x05, 0x35, 0x05, 0x36, 0x05, 0x37, 0x05, 0x38, - 0x05, 0x39, 0x05, 0x3a, 0x05, 0x3b, 0x05, 0x3c, 0x05, 0x3d, 0x05, 0x3e, - 0x05, 0x3f, 0x05, 0x40, 0x05, 0x41, 0x05, 0x42, 0x05, 0x43, 0x05, 0x44, - 0x05, 0x45, 0x05, 0x46, 0x05, 0x47, 0x05, 0x48, 0x05, 0x49, 0x05, 0x4a, - 0x05, 0x4b, 0x05, 0x4c, 0x05, 0x4d, 0x05, 0x4e, 0x05, 0x4f, 0x05, 0x50, - 0x05, 0x51, 0x05, 0x52, 0x05, 0x53, 0x05, 0x54, 0x05, 0x55, 0x05, 0x56, - 0x05, 0x57, 0x05, 0x58, 0x05, 0x59, 0x05, 0x5a, 0x05, 0x5b, 0x05, 0x5c, - 0x05, 0x5d, 0x05, 0x5e, 0x05, 0x5f, 0x05, 0x60, 0x05, 0x61, 0x05, 0x62, - 0x05, 0x63, 0x05, 0x64, 0x05, 0x65, 0x05, 0x66, 0x05, 0x67, 0x05, 0x68, - 0x05, 0x69, 0x05, 0x6a, 0x05, 0x6b, 0x05, 0x6c, 0x05, 0x6d, 0x05, 0x6e, - 0x05, 0x6f, 0x05, 0x70, 0x05, 0x71, 0x05, 0x72, 0x05, 0x73, 0x05, 0x74, - 0x05, 0x75, 0x05, 0x76, 0x05, 0x77, 0x05, 0x78, 0x05, 0x79, 0x05, 0x7a, - 0x05, 0x7b, 0x05, 0x7c, 0x05, 0x7d, 0x05, 0x7e, 0x05, 0x7f, 0x05, 0x80, - 0x05, 0x81, 0x05, 0x82, 0x05, 0x83, 0x05, 0x84, 0x05, 0x85, 0x05, 0x86, - 0x05, 0x87, 0x05, 0x88, 0x05, 0x89, 0x05, 0x8a, 0x05, 0x8b, 0x05, 0x8c, - 0x05, 0x8d, 0x05, 0x8e, 0x05, 0x8f, 0x05, 0x90, 0x05, 0x91, 0x05, 0x92, - 0x05, 0x93, 0x05, 0x94, 0x05, 0x95, 0x05, 0x96, 0x05, 0x97, 0x05, 0x98, - 0x05, 0x99, 0x05, 0x9a, 0x05, 0x9b, 0x05, 0x9c, 0x05, 0x9d, 0x05, 0x9e, - 0x05, 0x9f, 0x05, 0xa0, 0x05, 0xa1, 0x05, 0xa2, 0x05, 0xa3, 0x05, 0xa4, - 0x05, 0xa5, 0x05, 0xa6, 0x05, 0xa7, 0x05, 0xa8, 0x05, 0xa9, 0x05, 0xaa, - 0x05, 0xab, 0x05, 0xac, 0x05, 0xad, 0x05, 0xae, 0x05, 0xaf, 0x05, 0xb0, - 0x05, 0xb1, 0x05, 0xb2, 0x05, 0xb3, 0x05, 0xb4, 0x05, 0xb5, 0x05, 0xb6, - 0x05, 0xb7, 0x05, 0xb8, 0x05, 0xb9, 0x05, 0xba, 0x05, 0xbb, 0x05, 0xbc, - 0x05, 0xbd, 0x05, 0xbe, 0x05, 0xbf, 0x05, 0xc0, 0x05, 0xc1, 0x05, 0xc2, - 0x05, 0xc3, 0x05, 0xc4, 0x05, 0xc5, 0x05, 0xc6, 0x05, 0xc7, 0x05, 0xc8, - 0x05, 0xc9, 0x05, 0xca, 0x05, 0xcb, 0x05, 0xcc, 0x05, 0xcd, 0x05, 0xce, - 0x05, 0xcf, 0x05, 0xd0, 0x05, 0xd1, 0x05, 0xd2, 0x05, 0xd3, 0x05, 0xd4, - 0x05, 0xd5, 0x05, 0xd6, 0x05, 0xd7, 0x05, 0xd8, 0x05, 0xd9, 0x05, 0xda, - 0x05, 0xdb, 0x05, 0xdc, 0x05, 0xdd, 0x05, 0xde, 0x05, 0xdf, 0x05, 0xe0, - 0x05, 0xe1, 0x05, 0xe2, 0x05, 0xe3, 0x05, 0xe4, 0x05, 0xe5, 0x05, 0xe6, - 0x05, 0xe7, 0x05, 0xe8, 0x05, 0xe9, 0x05, 0xea, 0x05, 0xeb, 0x05, 0xec, - 0x05, 0xed, 0x05, 0xee, 0x05, 0xef, 0x05, 0xf0, 0x05, 0xf1, 0x05, 0xf2, - 0x05, 0xf3, 0x05, 0xf4, 0x05, 0xf5, 0x05, 0xf6, 0x05, 0xf7, 0x05, 0xf8, - 0x05, 0xf9, 0x05, 0xfa, 0x05, 0xfb, 0x05, 0xfc, 0x05, 0xfd, 0x05, 0xfe, - 0x05, 0xff, 0x06, 0x00, 0x06, 0x01, 0x06, 0x02, 0x06, 0x03, 0x06, 0x04, - 0x06, 0x05, 0x06, 0x06, 0x06, 0x07, 0x06, 0x08, 0x06, 0x09, 0x06, 0x0a, - 0x06, 0x0b, 0x06, 0x0c, 0x06, 0x0d, 0x06, 0x0e, 0x06, 0x0f, 0x06, 0x10, - 0x06, 0x11, 0x06, 0x12, 0x06, 0x13, 0x06, 0x14, 0x06, 0x15, 0x06, 0x16, - 0x06, 0x17, 0x06, 0x18, 0x06, 0x19, 0x06, 0x1a, 0x06, 0x1b, 0x06, 0x1c, - 0x06, 0x1d, 0x06, 0x1e, 0x06, 0x1f, 0x06, 0x20, 0x06, 0x21, 0x06, 0x22, - 0x06, 0x23, 0x06, 0x24, 0x06, 0x25, 0x06, 0x26, 0x06, 0x27, 0x06, 0x28, - 0x06, 0x29, 0x06, 0x2a, 0x06, 0x2b, 0x06, 0x2c, 0x06, 0x2d, 0x06, 0x2e, - 0x06, 0x2f, 0x06, 0x30, 0x06, 0x31, 0x06, 0x32, 0x06, 0x33, 0x06, 0x34, - 0x06, 0x35, 0x06, 0x36, 0x06, 0x37, 0x06, 0x38, 0x06, 0x39, 0x06, 0x3a, - 0x06, 0x3b, 0x06, 0x3c, 0x06, 0x3d, 0x06, 0x3e, 0x06, 0x3f, 0x06, 0x40, - 0x06, 0x41, 0x06, 0x42, 0x06, 0x43, 0x06, 0x44, 0x06, 0x45, 0x06, 0x46, - 0x06, 0x47, 0x06, 0x48, 0x06, 0x49, 0x06, 0x4a, 0x06, 0x4b, 0x06, 0x4c, - 0x06, 0x4d, 0x06, 0x4e, 0x06, 0x4f, 0x06, 0x50, 0x06, 0x51, 0x06, 0x52, - 0x06, 0x53, 0x06, 0x54, 0x06, 0x55, 0x06, 0x56, 0x06, 0x57, 0x06, 0x58, - 0x06, 0x59, 0x06, 0x5a, 0x06, 0x5b, 0x06, 0x5c, 0x06, 0x5d, 0x06, 0x5e, - 0x06, 0x5f, 0x06, 0x60, 0x06, 0x61, 0x06, 0x62, 0x06, 0x63, 0x06, 0x64, - 0x06, 0x65, 0x06, 0x66, 0x06, 0x67, 0x06, 0x68, 0x06, 0x69, 0x06, 0x6a, - 0x06, 0x6b, 0x06, 0x6c, 0x06, 0x6d, 0x06, 0x6e, 0x06, 0x6f, 0x06, 0x70, - 0x06, 0x71, 0x06, 0x72, 0x06, 0x73, 0x06, 0x74, 0x06, 0x75, 0x06, 0x76, - 0x06, 0x77, 0x06, 0x78, 0x06, 0x79, 0x06, 0x7a, 0x06, 0x7b, 0x06, 0x7c, - 0x06, 0x7d, 0x06, 0x7e, 0x06, 0x7f, 0x06, 0x80, 0x06, 0x81, 0x06, 0x82, - 0x06, 0x83, 0x06, 0x84, 0x06, 0x85, 0x06, 0x86, 0x06, 0x87, 0x06, 0x88, - 0x06, 0x89, 0x06, 0x8a, 0x06, 0x8b, 0x06, 0x8c, 0x06, 0x8d, 0x06, 0x8e, - 0x06, 0x8f, 0x06, 0x90, 0x06, 0x91, 0x06, 0x92, 0x06, 0x93, 0x06, 0x94, - 0x06, 0x95, 0x06, 0x96, 0x06, 0x97, 0x06, 0x98, 0x06, 0x99, 0x06, 0x9a, - 0x06, 0x9b, 0x06, 0x9c, 0x06, 0x9d, 0x06, 0x9e, 0x06, 0x9f, 0x06, 0xa0, - 0x06, 0xa1, 0x06, 0xa2, 0x06, 0xa3, 0x06, 0xa4, 0x06, 0xa5, 0x06, 0xa6, - 0x06, 0xa7, 0x06, 0xa8, 0x06, 0xa9, 0x06, 0xaa, 0x06, 0xab, 0x06, 0xac, - 0x06, 0xad, 0x06, 0xae, 0x06, 0xaf, 0x06, 0xb0, 0x06, 0xb1, 0x06, 0xb2, - 0x06, 0xb3, 0x06, 0xb4, 0x06, 0xb5, 0x06, 0xb6, 0x06, 0xb7, 0x06, 0xb8, - 0x06, 0xb9, 0x06, 0xba, 0x06, 0xbb, 0x06, 0xbc, 0x06, 0xbd, 0x06, 0xbe, - 0x06, 0xbf, 0x06, 0xc0, 0x06, 0xc1, 0x06, 0xc2, 0x06, 0xc3, 0x06, 0xc4, - 0x06, 0xc5, 0x06, 0xc6, 0x06, 0xc7, 0x06, 0xc8, 0x06, 0xc9, 0x06, 0xca, - 0x06, 0xcb, 0x06, 0xcc, 0x06, 0xcd, 0x06, 0xce, 0x06, 0xcf, 0x06, 0xd0, - 0x06, 0xd1, 0x06, 0xd2, 0x06, 0xd3, 0x06, 0xd4, 0x06, 0xd5, 0x06, 0xd6, - 0x06, 0xd7, 0x06, 0xd8, 0x06, 0xd9, 0x06, 0xda, 0x06, 0xdb, 0x06, 0xdc, - 0x06, 0xdd, 0x06, 0xde, 0x06, 0xdf, 0x06, 0xe0, 0x06, 0xe1, 0x06, 0xe2, - 0x06, 0xe3, 0x06, 0xe4, 0x06, 0xe5, 0x06, 0xe6, 0x06, 0xe7, 0x06, 0xe8, - 0x06, 0xe9, 0x06, 0xea, 0x06, 0xeb, 0x06, 0xec, 0x06, 0xed, 0x06, 0xee, - 0x06, 0xef, 0x06, 0xf0, 0x06, 0xf1, 0x06, 0xf2, 0x06, 0xf3, 0x06, 0xf4, - 0x06, 0xf5, 0x06, 0xf6, 0x06, 0xf7, 0x06, 0xf8, 0x06, 0xf9, 0x06, 0xfa, - 0x06, 0xfb, 0x06, 0xfc, 0x06, 0xfd, 0x06, 0xfe, 0x06, 0xff, 0x07, 0x00, - 0x07, 0x01, 0x07, 0x02, 0x07, 0x03, 0x07, 0x04, 0x07, 0x05, 0x07, 0x06, - 0x07, 0x07, 0x07, 0x08, 0x07, 0x09, 0x07, 0x0a, 0x07, 0x0b, 0x07, 0x0c, - 0x07, 0x0d, 0x07, 0x0e, 0x07, 0x0f, 0x07, 0x10, 0x07, 0x11, 0x07, 0x12, - 0x07, 0x13, 0x07, 0x14, 0x07, 0x15, 0x07, 0x16, 0x07, 0x17, 0x07, 0x18, - 0x07, 0x19, 0x07, 0x1a, 0x07, 0x1b, 0x07, 0x1c, 0x07, 0x1d, 0x07, 0x1e, - 0x07, 0x1f, 0x07, 0x20, 0x07, 0x21, 0x07, 0x22, 0x07, 0x23, 0x07, 0x24, - 0x07, 0x25, 0x07, 0x26, 0x07, 0x27, 0x07, 0x28, 0x07, 0x29, 0x07, 0x2a, - 0x07, 0x2b, 0x07, 0x2c, 0x07, 0x2d, 0x07, 0x2e, 0x07, 0x2f, 0x07, 0x30, - 0x07, 0x31, 0x07, 0x32, 0x07, 0x33, 0x07, 0x34, 0x07, 0x35, 0x07, 0x36, - 0x07, 0x37, 0x07, 0x38, 0x00, 0xb2, 0x00, 0xb3, 0x07, 0x39, 0x07, 0x3a, - 0x07, 0x3b, 0x00, 0xb6, 0x00, 0xb7, 0x00, 0xc4, 0x07, 0x3c, 0x00, 0xb4, - 0x00, 0xb5, 0x00, 0xc5, 0x07, 0x3d, 0x00, 0x82, 0x00, 0xc2, 0x00, 0x87, - 0x07, 0x3e, 0x00, 0xab, 0x07, 0x3f, 0x00, 0xc6, 0x07, 0x40, 0x07, 0x41, - 0x07, 0x42, 0x07, 0x43, 0x07, 0x44, 0x07, 0x45, 0x07, 0x46, 0x00, 0xbe, - 0x00, 0xbf, 0x07, 0x47, 0x07, 0x48, 0x07, 0x49, 0x07, 0x4a, 0x07, 0x4b, - 0x07, 0x4c, 0x07, 0x4d, 0x07, 0x4e, 0x07, 0x4f, 0x07, 0x50, 0x07, 0x51, - 0x07, 0x52, 0x07, 0x53, 0x07, 0x54, 0x07, 0x55, 0x07, 0x56, 0x07, 0x57, - 0x07, 0x58, 0x07, 0x59, 0x07, 0x5a, 0x07, 0x5b, 0x07, 0x5c, 0x07, 0x5d, - 0x07, 0x5e, 0x07, 0x5f, 0x07, 0x60, 0x07, 0x61, 0x07, 0x62, 0x07, 0x63, - 0x07, 0x64, 0x07, 0x65, 0x07, 0x66, 0x07, 0x67, 0x07, 0x68, 0x07, 0x69, - 0x07, 0x6a, 0x07, 0x6b, 0x07, 0x6c, 0x07, 0x6d, 0x07, 0x6e, 0x07, 0x6f, - 0x07, 0x70, 0x07, 0x71, 0x07, 0x72, 0x07, 0x73, 0x07, 0x74, 0x07, 0x75, - 0x07, 0x76, 0x07, 0x77, 0x07, 0x78, 0x07, 0x79, 0x07, 0x7a, 0x07, 0x7b, - 0x07, 0x7c, 0x07, 0x7d, 0x00, 0xf7, 0x07, 0x7e, 0x07, 0x7f, 0x07, 0x80, - 0x07, 0x81, 0x07, 0x82, 0x07, 0x83, 0x07, 0x84, 0x07, 0x85, 0x07, 0x86, - 0x07, 0x87, 0x07, 0x88, 0x07, 0x89, 0x07, 0x8a, 0x07, 0x8b, 0x07, 0x8c, - 0x07, 0x8d, 0x07, 0x8e, 0x07, 0x8f, 0x07, 0x90, 0x07, 0x91, 0x07, 0x92, - 0x07, 0x93, 0x07, 0x94, 0x07, 0x95, 0x07, 0x96, 0x07, 0x97, 0x07, 0x98, - 0x07, 0x99, 0x07, 0x9a, 0x07, 0x9b, 0x07, 0x9c, 0x00, 0x8c, 0x07, 0x9d, - 0x07, 0x9e, 0x07, 0x9f, 0x07, 0xa0, 0x07, 0xa1, 0x07, 0xa2, 0x07, 0xa3, - 0x07, 0xa4, 0x07, 0xa5, 0x07, 0xa6, 0x07, 0xa7, 0x07, 0xa8, 0x07, 0xa9, - 0x07, 0xaa, 0x07, 0xab, 0x07, 0xac, 0x07, 0xad, 0x07, 0xae, 0x07, 0xaf, - 0x07, 0xb0, 0x07, 0xb1, 0x07, 0xb2, 0x07, 0xb3, 0x07, 0xb4, 0x07, 0xb5, - 0x07, 0xb6, 0x07, 0xb7, 0x07, 0xb8, 0x07, 0xb9, 0x07, 0xba, 0x07, 0xbb, - 0x07, 0xbc, 0x07, 0xbd, 0x07, 0xbe, 0x07, 0xbf, 0x07, 0xc0, 0x07, 0xc1, - 0x07, 0xc2, 0x07, 0xc3, 0x07, 0xc4, 0x07, 0xc5, 0x07, 0xc6, 0x07, 0xc7, - 0x07, 0xc8, 0x07, 0xc9, 0x07, 0xca, 0x07, 0xcb, 0x07, 0xcc, 0x07, 0xcd, - 0x07, 0xce, 0x07, 0xcf, 0x07, 0xd0, 0x07, 0xd1, 0x07, 0xd2, 0x07, 0xd3, - 0x07, 0xd4, 0x07, 0xd5, 0x07, 0xd6, 0x07, 0xd7, 0x07, 0xd8, 0x07, 0xd9, - 0x07, 0xda, 0x07, 0xdb, 0x07, 0xdc, 0x07, 0xdd, 0x07, 0xde, 0x07, 0xdf, - 0x07, 0xe0, 0x07, 0xe1, 0x07, 0xe2, 0x07, 0xe3, 0x07, 0xe4, 0x07, 0xe5, - 0x07, 0xe6, 0x07, 0xe7, 0x07, 0xe8, 0x07, 0xe9, 0x07, 0xea, 0x07, 0xeb, - 0x07, 0xec, 0x07, 0xed, 0x07, 0xee, 0x07, 0xef, 0x07, 0xf0, 0x07, 0xf1, - 0x07, 0xf2, 0x07, 0xf3, 0x07, 0xf4, 0x07, 0xf5, 0x07, 0xf6, 0x07, 0xf7, - 0x07, 0xf8, 0x07, 0xf9, 0x07, 0xfa, 0x07, 0xfb, 0x07, 0xfc, 0x07, 0xfd, - 0x07, 0xfe, 0x07, 0xff, 0x08, 0x00, 0x08, 0x01, 0x08, 0x02, 0x08, 0x03, - 0x08, 0x04, 0x08, 0x05, 0x08, 0x06, 0x08, 0x07, 0x08, 0x08, 0x08, 0x09, - 0x08, 0x0a, 0x08, 0x0b, 0x08, 0x0c, 0x08, 0x0d, 0x08, 0x0e, 0x08, 0x0f, - 0x08, 0x10, 0x08, 0x11, 0x08, 0x12, 0x08, 0x13, 0x08, 0x14, 0x08, 0x15, - 0x08, 0x16, 0x08, 0x17, 0x08, 0x18, 0x08, 0x19, 0x08, 0x1a, 0x08, 0x1b, - 0x08, 0x1c, 0x08, 0x1d, 0x08, 0x1e, 0x08, 0x1f, 0x08, 0x20, 0x08, 0x21, - 0x00, 0x98, 0x08, 0x22, 0x08, 0x23, 0x08, 0x24, 0x00, 0xa8, 0x08, 0x25, - 0x08, 0x26, 0x08, 0x27, 0x08, 0x28, 0x08, 0x29, 0x08, 0x2a, 0x08, 0x2b, - 0x00, 0x9a, 0x00, 0x99, 0x00, 0xef, 0x08, 0x2c, 0x08, 0x2d, 0x08, 0x2e, - 0x08, 0x2f, 0x08, 0x30, 0x00, 0xa5, 0x08, 0x31, 0x08, 0x32, 0x08, 0x33, - 0x00, 0x92, 0x08, 0x34, 0x08, 0x35, 0x08, 0x36, 0x08, 0x37, 0x08, 0x38, - 0x08, 0x39, 0x00, 0x9c, 0x08, 0x3a, 0x08, 0x3b, 0x08, 0x3c, 0x08, 0x3d, - 0x08, 0x3e, 0x08, 0x3f, 0x08, 0x40, 0x08, 0x41, 0x08, 0x42, 0x08, 0x43, - 0x08, 0x44, 0x08, 0x45, 0x08, 0x46, 0x08, 0x47, 0x08, 0x48, 0x08, 0x49, - 0x08, 0x4a, 0x08, 0x4b, 0x08, 0x4c, 0x00, 0xa7, 0x08, 0x4d, 0x08, 0x4e, - 0x08, 0x4f, 0x08, 0x50, 0x08, 0x51, 0x08, 0x52, 0x08, 0x53, 0x08, 0x54, - 0x08, 0x55, 0x08, 0x56, 0x08, 0x57, 0x08, 0x58, 0x08, 0x59, 0x08, 0x5a, - 0x08, 0x5b, 0x08, 0x5c, 0x08, 0x5d, 0x08, 0x5e, 0x08, 0x5f, 0x08, 0x60, - 0x08, 0x61, 0x08, 0x62, 0x08, 0x63, 0x00, 0x8f, 0x08, 0x64, 0x08, 0x65, - 0x08, 0x66, 0x00, 0x94, 0x00, 0x95, 0x08, 0x67, 0x08, 0x68, 0x08, 0x69, - 0x08, 0x6a, 0x08, 0x6b, 0x08, 0x6c, 0x08, 0x6d, 0x08, 0x6e, 0x08, 0x6f, - 0x08, 0x70, 0x08, 0x71, 0x08, 0x72, 0x08, 0x73, 0x08, 0x74, 0x08, 0x75, - 0x08, 0x76, 0x08, 0x77, 0x08, 0x78, 0x08, 0x79, 0x08, 0x7a, 0x08, 0x7b, - 0x08, 0x7c, 0x08, 0x7d, 0x08, 0x7e, 0x08, 0x7f, 0x08, 0x80, 0x08, 0x81, - 0x08, 0x82, 0x08, 0x83, 0x08, 0x84, 0x08, 0x85, 0x08, 0x86, 0x08, 0x87, - 0x08, 0x88, 0x08, 0x89, 0x08, 0x8a, 0x08, 0x8b, 0x08, 0x8c, 0x08, 0x8d, - 0x08, 0x8e, 0x08, 0x8f, 0x08, 0x90, 0x08, 0x91, 0x08, 0x92, 0x08, 0x93, - 0x08, 0x94, 0x08, 0x95, 0x08, 0x96, 0x08, 0x97, 0x08, 0x98, 0x08, 0x99, - 0x08, 0x9a, 0x08, 0x9b, 0x08, 0x9c, 0x08, 0x9d, 0x08, 0x9e, 0x08, 0x9f, - 0x08, 0xa0, 0x08, 0xa1, 0x08, 0xa2, 0x08, 0xa3, 0x08, 0xa4, 0x08, 0xa5, - 0x08, 0xa6, 0x08, 0xa7, 0x08, 0xa8, 0x08, 0xa9, 0x08, 0xaa, 0x08, 0xab, - 0x08, 0xac, 0x08, 0xad, 0x08, 0xae, 0x08, 0xaf, 0x08, 0xb0, 0x08, 0xb1, - 0x08, 0xb2, 0x08, 0xb3, 0x08, 0xb4, 0x08, 0xb5, 0x08, 0xb6, 0x08, 0xb7, - 0x08, 0xb8, 0x08, 0xb9, 0x08, 0xba, 0x08, 0xbb, 0x08, 0xbc, 0x08, 0xbd, - 0x08, 0xbe, 0x08, 0xbf, 0x08, 0xc0, 0x08, 0xc1, 0x08, 0xc2, 0x08, 0xc3, - 0x08, 0xc4, 0x08, 0xc5, 0x08, 0xc6, 0x08, 0xc7, 0x08, 0xc8, 0x08, 0xc9, - 0x08, 0xca, 0x08, 0xcb, 0x08, 0xcc, 0x08, 0xcd, 0x08, 0xce, 0x08, 0xcf, - 0x08, 0xd0, 0x08, 0xd1, 0x08, 0xd2, 0x08, 0xd3, 0x08, 0xd4, 0x08, 0xd5, - 0x08, 0xd6, 0x08, 0xd7, 0x08, 0xd8, 0x08, 0xd9, 0x08, 0xda, 0x08, 0xdb, - 0x08, 0xdc, 0x08, 0xdd, 0x08, 0xde, 0x08, 0xdf, 0x08, 0xe0, 0x08, 0xe1, - 0x08, 0xe2, 0x08, 0xe3, 0x08, 0xe4, 0x08, 0xe5, 0x08, 0xe6, 0x08, 0xe7, - 0x08, 0xe8, 0x08, 0xe9, 0x08, 0xea, 0x08, 0xeb, 0x08, 0xec, 0x08, 0xed, - 0x08, 0xee, 0x08, 0xef, 0x08, 0xf0, 0x08, 0xf1, 0x08, 0xf2, 0x08, 0xf3, - 0x08, 0xf4, 0x08, 0xf5, 0x08, 0xf6, 0x08, 0xf7, 0x08, 0xf8, 0x08, 0xf9, - 0x08, 0xfa, 0x08, 0xfb, 0x08, 0xfc, 0x08, 0xfd, 0x08, 0xfe, 0x08, 0xff, - 0x09, 0x00, 0x09, 0x01, 0x09, 0x02, 0x09, 0x03, 0x09, 0x04, 0x09, 0x05, - 0x09, 0x06, 0x09, 0x07, 0x09, 0x08, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x0b, - 0x09, 0x0c, 0x09, 0x0d, 0x09, 0x0e, 0x09, 0x0f, 0x09, 0x10, 0x09, 0x11, - 0x09, 0x12, 0x09, 0x13, 0x09, 0x14, 0x09, 0x15, 0x09, 0x16, 0x09, 0x17, - 0x09, 0x18, 0x09, 0x19, 0x09, 0x1a, 0x09, 0x1b, 0x09, 0x1c, 0x09, 0x1d, - 0x09, 0x1e, 0x09, 0x1f, 0x09, 0x20, 0x09, 0x21, 0x09, 0x22, 0x09, 0x23, - 0x09, 0x24, 0x09, 0x25, 0x09, 0x26, 0x09, 0x27, 0x09, 0x28, 0x09, 0x29, - 0x09, 0x2a, 0x09, 0x2b, 0x09, 0x2c, 0x09, 0x2d, 0x09, 0x2e, 0x09, 0x2f, - 0x09, 0x30, 0x09, 0x31, 0x09, 0x32, 0x09, 0x33, 0x09, 0x34, 0x09, 0x35, - 0x09, 0x36, 0x09, 0x37, 0x09, 0x38, 0x09, 0x39, 0x09, 0x3a, 0x09, 0x3b, - 0x09, 0x3c, 0x09, 0x3d, 0x09, 0x3e, 0x09, 0x3f, 0x09, 0x40, 0x09, 0x41, - 0x09, 0x42, 0x09, 0x43, 0x09, 0x44, 0x09, 0x45, 0x09, 0x46, 0x09, 0x47, - 0x09, 0x48, 0x09, 0x49, 0x09, 0x4a, 0x09, 0x4b, 0x09, 0x4c, 0x09, 0x4d, - 0x09, 0x4e, 0x09, 0x4f, 0x09, 0x50, 0x09, 0x51, 0x09, 0x52, 0x09, 0x53, - 0x09, 0x54, 0x09, 0x55, 0x09, 0x56, 0x09, 0x57, 0x09, 0x58, 0x09, 0x59, - 0x09, 0x5a, 0x09, 0x5b, 0x09, 0x5c, 0x09, 0x5d, 0x09, 0x5e, 0x09, 0x5f, - 0x09, 0x60, 0x09, 0x61, 0x09, 0x62, 0x09, 0x63, 0x09, 0x64, 0x09, 0x65, - 0x09, 0x66, 0x09, 0x67, 0x09, 0x68, 0x09, 0x69, 0x09, 0x6a, 0x09, 0x6b, - 0x09, 0x6c, 0x09, 0x6d, 0x09, 0x6e, 0x09, 0x6f, 0x09, 0x70, 0x09, 0x71, - 0x09, 0x72, 0x09, 0x73, 0x09, 0x74, 0x09, 0x75, 0x09, 0x76, 0x09, 0x77, - 0x09, 0x78, 0x09, 0x79, 0x09, 0x7a, 0x09, 0x7b, 0x09, 0x7c, 0x09, 0x7d, - 0x09, 0x7e, 0x09, 0x7f, 0x09, 0x80, 0x09, 0x81, 0x09, 0x82, 0x09, 0x83, - 0x09, 0x84, 0x09, 0x85, 0x09, 0x86, 0x09, 0x87, 0x09, 0x88, 0x09, 0x89, - 0x09, 0x8a, 0x09, 0x8b, 0x09, 0x8c, 0x09, 0x8d, 0x09, 0x8e, 0x09, 0x8f, - 0x09, 0x90, 0x09, 0x91, 0x09, 0x92, 0x09, 0x93, 0x09, 0x94, 0x09, 0x95, - 0x09, 0x96, 0x09, 0x97, 0x09, 0x98, 0x09, 0x99, 0x09, 0x9a, 0x09, 0x9b, - 0x09, 0x9c, 0x09, 0x9d, 0x09, 0x9e, 0x09, 0x9f, 0x09, 0xa0, 0x09, 0xa1, - 0x09, 0xa2, 0x09, 0xa3, 0x09, 0xa4, 0x09, 0xa5, 0x09, 0xa6, 0x09, 0xa7, - 0x09, 0xa8, 0x09, 0xa9, 0x09, 0xaa, 0x09, 0xab, 0x09, 0xac, 0x09, 0xad, - 0x09, 0xae, 0x09, 0xaf, 0x09, 0xb0, 0x09, 0xb1, 0x09, 0xb2, 0x09, 0xb3, - 0x09, 0xb4, 0x09, 0xb5, 0x09, 0xb6, 0x09, 0xb7, 0x09, 0xb8, 0x09, 0xb9, - 0x09, 0xba, 0x09, 0xbb, 0x09, 0xbc, 0x09, 0xbd, 0x09, 0xbe, 0x09, 0xbf, - 0x09, 0xc0, 0x09, 0xc1, 0x09, 0xc2, 0x09, 0xc3, 0x09, 0xc4, 0x09, 0xc5, - 0x09, 0xc6, 0x09, 0xc7, 0x09, 0xc8, 0x09, 0xc9, 0x09, 0xca, 0x09, 0xcb, - 0x09, 0xcc, 0x09, 0xcd, 0x09, 0xce, 0x09, 0xcf, 0x09, 0xd0, 0x09, 0xd1, - 0x09, 0xd2, 0x09, 0xd3, 0x09, 0xd4, 0x09, 0xd5, 0x09, 0xd6, 0x09, 0xd7, - 0x09, 0xd8, 0x09, 0xd9, 0x09, 0xda, 0x09, 0xdb, 0x09, 0xdc, 0x09, 0xdd, - 0x09, 0xde, 0x09, 0xdf, 0x09, 0xe0, 0x09, 0xe1, 0x09, 0xe2, 0x09, 0xe3, - 0x09, 0xe4, 0x09, 0xe5, 0x09, 0xe6, 0x09, 0xe7, 0x09, 0xe8, 0x09, 0xe9, - 0x09, 0xea, 0x09, 0xeb, 0x09, 0xec, 0x09, 0xed, 0x09, 0xee, 0x09, 0xef, - 0x09, 0xf0, 0x09, 0xf1, 0x09, 0xf2, 0x00, 0xb9, 0x09, 0xf3, 0x09, 0xf4, - 0x09, 0xf5, 0x09, 0xf6, 0x09, 0xf7, 0x09, 0xf8, 0x09, 0xf9, 0x09, 0xfa, - 0x09, 0xfb, 0x09, 0xfc, 0x09, 0xfd, 0x09, 0xfe, 0x09, 0xff, 0x0a, 0x00, - 0x0a, 0x01, 0x0a, 0x02, 0x0a, 0x03, 0x0a, 0x04, 0x0a, 0x05, 0x0a, 0x06, - 0x0a, 0x07, 0x0a, 0x08, 0x0a, 0x09, 0x0a, 0x0a, 0x0a, 0x0b, 0x0a, 0x0c, - 0x0a, 0x0d, 0x0a, 0x0e, 0x0a, 0x0f, 0x0a, 0x10, 0x0a, 0x11, 0x0a, 0x12, - 0x0a, 0x13, 0x0a, 0x14, 0x0a, 0x15, 0x0a, 0x16, 0x0a, 0x17, 0x0a, 0x18, - 0x0a, 0x19, 0x0a, 0x1a, 0x0a, 0x1b, 0x0a, 0x1c, 0x0a, 0x1d, 0x0a, 0x1e, - 0x0a, 0x1f, 0x0a, 0x20, 0x0a, 0x21, 0x0a, 0x22, 0x0a, 0x23, 0x0a, 0x24, - 0x0a, 0x25, 0x0a, 0x26, 0x0a, 0x27, 0x0a, 0x28, 0x0a, 0x29, 0x0a, 0x2a, - 0x0a, 0x2b, 0x0a, 0x2c, 0x0a, 0x2d, 0x0a, 0x2e, 0x0a, 0x2f, 0x0a, 0x30, - 0x0a, 0x31, 0x0a, 0x32, 0x0a, 0x33, 0x0a, 0x34, 0x0a, 0x35, 0x0a, 0x36, - 0x0a, 0x37, 0x0a, 0x38, 0x0a, 0x39, 0x0a, 0x3a, 0x0a, 0x3b, 0x0a, 0x3c, - 0x0a, 0x3d, 0x0a, 0x3e, 0x0a, 0x3f, 0x0a, 0x40, 0x0a, 0x41, 0x0a, 0x42, - 0x0a, 0x43, 0x0a, 0x44, 0x0a, 0x45, 0x0a, 0x46, 0x0a, 0x47, 0x0a, 0x48, - 0x0a, 0x49, 0x0a, 0x4a, 0x0a, 0x4b, 0x0a, 0x4c, 0x0a, 0x4d, 0x0a, 0x4e, - 0x0a, 0x4f, 0x0a, 0x50, 0x0a, 0x51, 0x0a, 0x52, 0x0a, 0x53, 0x0a, 0x54, - 0x0a, 0x55, 0x0a, 0x56, 0x0a, 0x57, 0x0a, 0x58, 0x0a, 0x59, 0x0a, 0x5a, - 0x0a, 0x5b, 0x0a, 0x5c, 0x0a, 0x5d, 0x0a, 0x5e, 0x0a, 0x5f, 0x0a, 0x60, - 0x0a, 0x61, 0x0a, 0x62, 0x0a, 0x63, 0x0a, 0x64, 0x0a, 0x65, 0x0a, 0x66, - 0x0a, 0x67, 0x0a, 0x68, 0x0a, 0x69, 0x0a, 0x6a, 0x0a, 0x6b, 0x0a, 0x6c, - 0x0a, 0x6d, 0x0a, 0x6e, 0x0a, 0x6f, 0x0a, 0x70, 0x0a, 0x71, 0x0a, 0x72, - 0x0a, 0x73, 0x0a, 0x74, 0x0a, 0x75, 0x0a, 0x76, 0x0a, 0x77, 0x0a, 0x78, - 0x0a, 0x79, 0x0a, 0x7a, 0x0a, 0x7b, 0x0a, 0x7c, 0x0a, 0x7d, 0x0a, 0x7e, - 0x0a, 0x7f, 0x0a, 0x80, 0x0a, 0x81, 0x0a, 0x82, 0x0a, 0x83, 0x0a, 0x84, - 0x0a, 0x85, 0x0a, 0x86, 0x0a, 0x87, 0x0a, 0x88, 0x0a, 0x89, 0x0a, 0x8a, - 0x0a, 0x8b, 0x0a, 0x8c, 0x0a, 0x8d, 0x0a, 0x8e, 0x0a, 0x8f, 0x0a, 0x90, - 0x0a, 0x91, 0x0a, 0x92, 0x0a, 0x93, 0x0a, 0x94, 0x0a, 0x95, 0x0a, 0x96, - 0x0a, 0x97, 0x0a, 0x98, 0x0a, 0x99, 0x0a, 0x9a, 0x0a, 0x9b, 0x0a, 0x9c, - 0x0a, 0x9d, 0x0a, 0x9e, 0x0a, 0x9f, 0x0a, 0xa0, 0x0a, 0xa1, 0x0a, 0xa2, - 0x0a, 0xa3, 0x0a, 0xa4, 0x0a, 0xa5, 0x0a, 0xa6, 0x0a, 0xa7, 0x0a, 0xa8, - 0x0a, 0xa9, 0x0a, 0xaa, 0x0a, 0xab, 0x0a, 0xac, 0x0a, 0xad, 0x0a, 0xae, - 0x0a, 0xaf, 0x0a, 0xb0, 0x0a, 0xb1, 0x0a, 0xb2, 0x0a, 0xb3, 0x0a, 0xb4, - 0x0a, 0xb5, 0x0a, 0xb6, 0x0a, 0xb7, 0x0a, 0xb8, 0x0a, 0xb9, 0x0a, 0xba, - 0x0a, 0xbb, 0x0a, 0xbc, 0x0a, 0xbd, 0x0a, 0xbe, 0x0a, 0xbf, 0x0a, 0xc0, - 0x0a, 0xc1, 0x0a, 0xc2, 0x0a, 0xc3, 0x0a, 0xc4, 0x0a, 0xc5, 0x0a, 0xc6, - 0x0a, 0xc7, 0x0a, 0xc8, 0x0a, 0xc9, 0x0a, 0xca, 0x0a, 0xcb, 0x0a, 0xcc, - 0x0a, 0xcd, 0x0a, 0xce, 0x0a, 0xcf, 0x0a, 0xd0, 0x0a, 0xd1, 0x0a, 0xd2, - 0x0a, 0xd3, 0x0a, 0xd4, 0x0a, 0xd5, 0x0a, 0xd6, 0x0a, 0xd7, 0x0a, 0xd8, - 0x0a, 0xd9, 0x0a, 0xda, 0x0a, 0xdb, 0x0a, 0xdc, 0x0a, 0xdd, 0x0a, 0xde, - 0x0a, 0xdf, 0x0a, 0xe0, 0x0a, 0xe1, 0x0a, 0xe2, 0x0a, 0xe3, 0x0a, 0xe4, - 0x0a, 0xe5, 0x0a, 0xe6, 0x0a, 0xe7, 0x0a, 0xe8, 0x0a, 0xe9, 0x0a, 0xea, - 0x0a, 0xeb, 0x0a, 0xec, 0x0a, 0xed, 0x0a, 0xee, 0x0a, 0xef, 0x0a, 0xf0, - 0x0a, 0xf1, 0x0a, 0xf2, 0x0a, 0xf3, 0x0a, 0xf4, 0x0a, 0xf5, 0x0a, 0xf6, - 0x0a, 0xf7, 0x0a, 0xf8, 0x0a, 0xf9, 0x0a, 0xfa, 0x0a, 0xfb, 0x0a, 0xfc, - 0x0a, 0xfd, 0x0a, 0xfe, 0x0a, 0xff, 0x0b, 0x00, 0x0b, 0x01, 0x0b, 0x02, - 0x0b, 0x03, 0x0b, 0x04, 0x0b, 0x05, 0x0b, 0x06, 0x0b, 0x07, 0x0b, 0x08, - 0x0b, 0x09, 0x0b, 0x0a, 0x0b, 0x0b, 0x0b, 0x0c, 0x0b, 0x0d, 0x0b, 0x0e, - 0x0b, 0x0f, 0x0b, 0x10, 0x0b, 0x11, 0x0b, 0x12, 0x0b, 0x13, 0x0b, 0x14, - 0x0b, 0x15, 0x0b, 0x16, 0x0b, 0x17, 0x0b, 0x18, 0x0b, 0x19, 0x0b, 0x1a, - 0x0b, 0x1b, 0x0b, 0x1c, 0x0b, 0x1d, 0x0b, 0x1e, 0x0b, 0x1f, 0x0b, 0x20, - 0x0b, 0x21, 0x0b, 0x22, 0x0b, 0x23, 0x0b, 0x24, 0x0b, 0x25, 0x0b, 0x26, - 0x0b, 0x27, 0x0b, 0x28, 0x0b, 0x29, 0x0b, 0x2a, 0x0b, 0x2b, 0x0b, 0x2c, - 0x0b, 0x2d, 0x0b, 0x2e, 0x0b, 0x2f, 0x0b, 0x30, 0x0b, 0x31, 0x0b, 0x32, - 0x0b, 0x33, 0x0b, 0x34, 0x0b, 0x35, 0x0b, 0x36, 0x0b, 0x37, 0x0b, 0x38, - 0x0b, 0x39, 0x0b, 0x3a, 0x0b, 0x3b, 0x0b, 0x3c, 0x0b, 0x3d, 0x0b, 0x3e, - 0x0b, 0x3f, 0x0b, 0x40, 0x0b, 0x41, 0x0b, 0x42, 0x0b, 0x43, 0x0b, 0x44, - 0x0b, 0x45, 0x0b, 0x46, 0x0b, 0x47, 0x0b, 0x48, 0x0b, 0x49, 0x0b, 0x4a, - 0x0b, 0x4b, 0x0b, 0x4c, 0x0b, 0x4d, 0x0b, 0x4e, 0x0b, 0x4f, 0x0b, 0x50, - 0x0b, 0x51, 0x0b, 0x52, 0x0b, 0x53, 0x0b, 0x54, 0x0b, 0x55, 0x0b, 0x56, - 0x0b, 0x57, 0x0b, 0x58, 0x0b, 0x59, 0x0b, 0x5a, 0x0b, 0x5b, 0x0b, 0x5c, - 0x0b, 0x5d, 0x0b, 0x5e, 0x0b, 0x5f, 0x0b, 0x60, 0x0b, 0x61, 0x0b, 0x62, - 0x0b, 0x63, 0x0b, 0x64, 0x0b, 0x65, 0x0b, 0x66, 0x0b, 0x67, 0x0b, 0x68, - 0x0b, 0x69, 0x0b, 0x6a, 0x0b, 0x6b, 0x0b, 0x6c, 0x0b, 0x6d, 0x0b, 0x6e, - 0x0b, 0x6f, 0x0b, 0x70, 0x0b, 0x71, 0x0b, 0x72, 0x0b, 0x73, 0x0b, 0x74, - 0x0b, 0x75, 0x0b, 0x76, 0x0b, 0x77, 0x0b, 0x78, 0x0b, 0x79, 0x0b, 0x7a, - 0x0b, 0x7b, 0x0b, 0x7c, 0x0b, 0x7d, 0x0b, 0x7e, 0x0b, 0x7f, 0x0b, 0x80, - 0x0b, 0x81, 0x0b, 0x82, 0x0b, 0x83, 0x0b, 0x84, 0x0b, 0x85, 0x0b, 0x86, - 0x0b, 0x87, 0x0b, 0x88, 0x0b, 0x89, 0x0b, 0x8a, 0x0b, 0x8b, 0x0b, 0x8c, - 0x0b, 0x8d, 0x0b, 0x8e, 0x0b, 0x8f, 0x0b, 0x90, 0x0b, 0x91, 0x0b, 0x92, - 0x0b, 0x93, 0x0b, 0x94, 0x0b, 0x95, 0x0b, 0x96, 0x0b, 0x97, 0x0b, 0x98, - 0x0b, 0x99, 0x0b, 0x9a, 0x0b, 0x9b, 0x0b, 0x9c, 0x0b, 0x9d, 0x0b, 0x9e, - 0x0b, 0x9f, 0x0b, 0xa0, 0x0b, 0xa1, 0x0b, 0xa2, 0x0b, 0xa3, 0x0b, 0xa4, - 0x0b, 0xa5, 0x00, 0xc0, 0x00, 0xc1, 0x0b, 0xa6, 0x0b, 0xa7, 0x0b, 0xa8, - 0x0b, 0xa9, 0x0b, 0xaa, 0x0b, 0xab, 0x0b, 0xac, 0x0b, 0xad, 0x0b, 0xae, - 0x0b, 0xaf, 0x0b, 0xb0, 0x0b, 0xb1, 0x0b, 0xb2, 0x0b, 0xb3, 0x0b, 0xb4, - 0x0b, 0xb5, 0x0b, 0xb6, 0x0b, 0xb7, 0x0b, 0xb8, 0x0b, 0xb9, 0x0b, 0xba, - 0x0b, 0xbb, 0x0b, 0xbc, 0x0b, 0xbd, 0x0b, 0xbe, 0x0b, 0xbf, 0x0b, 0xc0, - 0x0b, 0xc1, 0x0b, 0xc2, 0x0b, 0xc3, 0x0b, 0xc4, 0x0b, 0xc5, 0x0b, 0xc6, - 0x0b, 0xc7, 0x0b, 0xc8, 0x0b, 0xc9, 0x0b, 0xca, 0x0b, 0xcb, 0x0b, 0xcc, - 0x0b, 0xcd, 0x0b, 0xce, 0x0b, 0xcf, 0x0b, 0xd0, 0x0b, 0xd1, 0x0b, 0xd2, - 0x0b, 0xd3, 0x0b, 0xd4, 0x0b, 0xd5, 0x0b, 0xd6, 0x0b, 0xd7, 0x0b, 0xd8, - 0x0b, 0xd9, 0x0b, 0xda, 0x0b, 0xdb, 0x0b, 0xdc, 0x0b, 0xdd, 0x0b, 0xde, - 0x0b, 0xdf, 0x0b, 0xe0, 0x0b, 0xe1, 0x0b, 0xe2, 0x0b, 0xe3, 0x0b, 0xe4, - 0x0b, 0xe5, 0x0b, 0xe6, 0x0b, 0xe7, 0x0b, 0xe8, 0x0b, 0xe9, 0x0b, 0xea, - 0x0b, 0xeb, 0x0b, 0xec, 0x0b, 0xed, 0x0b, 0xee, 0x0b, 0xef, 0x0b, 0xf0, - 0x0b, 0xf1, 0x0b, 0xf2, 0x0b, 0xf3, 0x0b, 0xf4, 0x0b, 0xf5, 0x0b, 0xf6, - 0x0b, 0xf7, 0x0b, 0xf8, 0x0b, 0xf9, 0x0b, 0xfa, 0x0b, 0xfb, 0x0b, 0xfc, - 0x0b, 0xfd, 0x0b, 0xfe, 0x0b, 0xff, 0x0c, 0x00, 0x0c, 0x01, 0x0c, 0x02, - 0x0c, 0x03, 0x0c, 0x04, 0x0c, 0x05, 0x0c, 0x06, 0x0c, 0x07, 0x0c, 0x08, - 0x0c, 0x09, 0x0c, 0x0a, 0x0c, 0x0b, 0x0c, 0x0c, 0x0c, 0x0d, 0x0c, 0x0e, - 0x0c, 0x0f, 0x0c, 0x10, 0x0c, 0x11, 0x0c, 0x12, 0x0c, 0x13, 0x0c, 0x14, - 0x0c, 0x15, 0x0c, 0x16, 0x0c, 0x17, 0x0c, 0x18, 0x0c, 0x19, 0x0c, 0x1a, - 0x0c, 0x1b, 0x0c, 0x1c, 0x0c, 0x1d, 0x0c, 0x1e, 0x0c, 0x1f, 0x0c, 0x20, - 0x0c, 0x21, 0x0c, 0x22, 0x0c, 0x23, 0x0c, 0x24, 0x0c, 0x25, 0x0c, 0x26, - 0x0c, 0x27, 0x0c, 0x28, 0x0c, 0x29, 0x0c, 0x2a, 0x0c, 0x2b, 0x0c, 0x2c, - 0x0c, 0x2d, 0x0c, 0x2e, 0x0c, 0x2f, 0x0c, 0x30, 0x0c, 0x31, 0x0c, 0x32, - 0x0c, 0x33, 0x0c, 0x34, 0x0c, 0x35, 0x0c, 0x36, 0x0c, 0x37, 0x0c, 0x38, - 0x0c, 0x39, 0x0c, 0x3a, 0x0c, 0x3b, 0x0c, 0x3c, 0x0c, 0x3d, 0x0c, 0x3e, - 0x0c, 0x3f, 0x0c, 0x40, 0x0c, 0x41, 0x0c, 0x42, 0x0c, 0x43, 0x0c, 0x44, - 0x0c, 0x45, 0x0c, 0x46, 0x0c, 0x47, 0x0c, 0x48, 0x0c, 0x49, 0x0c, 0x4a, - 0x0c, 0x4b, 0x0c, 0x4c, 0x0c, 0x4d, 0x0c, 0x4e, 0x0c, 0x4f, 0x0c, 0x50, - 0x0c, 0x51, 0x0c, 0x52, 0x0c, 0x53, 0x0c, 0x54, 0x0c, 0x55, 0x0c, 0x56, - 0x0c, 0x57, 0x0c, 0x58, 0x0c, 0x59, 0x0c, 0x5a, 0x0c, 0x5b, 0x0c, 0x5c, - 0x0c, 0x5d, 0x0c, 0x5e, 0x0c, 0x5f, 0x0c, 0x60, 0x0c, 0x61, 0x0c, 0x62, - 0x0c, 0x63, 0x0c, 0x64, 0x0c, 0x65, 0x0c, 0x66, 0x0c, 0x67, 0x0c, 0x68, - 0x0c, 0x69, 0x0c, 0x6a, 0x0c, 0x6b, 0x0c, 0x6c, 0x0c, 0x6d, 0x0c, 0x6e, - 0x0c, 0x6f, 0x0c, 0x70, 0x0c, 0x71, 0x0c, 0x72, 0x0c, 0x73, 0x0c, 0x74, - 0x0c, 0x75, 0x0c, 0x76, 0x0c, 0x77, 0x0c, 0x78, 0x0c, 0x79, 0x0c, 0x7a, - 0x0c, 0x7b, 0x0c, 0x7c, 0x0c, 0x7d, 0x0c, 0x7e, 0x0c, 0x7f, 0x0c, 0x80, - 0x0c, 0x81, 0x0c, 0x82, 0x0c, 0x83, 0x0c, 0x84, 0x0c, 0x85, 0x0c, 0x86, - 0x0c, 0x87, 0x0c, 0x88, 0x0c, 0x89, 0x0c, 0x8a, 0x0c, 0x8b, 0x0c, 0x8c, - 0x0c, 0x8d, 0x0c, 0x8e, 0x0c, 0x8f, 0x0c, 0x90, 0x0c, 0x91, 0x0c, 0x92, - 0x0c, 0x93, 0x0c, 0x94, 0x0c, 0x95, 0x0c, 0x96, 0x0c, 0x97, 0x0c, 0x98, - 0x0c, 0x99, 0x0c, 0x9a, 0x0c, 0x9b, 0x0c, 0x9c, 0x0c, 0x9d, 0x0c, 0x9e, - 0x0c, 0x9f, 0x0c, 0xa0, 0x0c, 0xa1, 0x0c, 0xa2, 0x0c, 0xa3, 0x0c, 0xa4, - 0x0c, 0xa5, 0x0c, 0xa6, 0x0c, 0xa7, 0x0c, 0xa8, 0x0c, 0xa9, 0x0c, 0xaa, - 0x0c, 0xab, 0x0c, 0xac, 0x0c, 0xad, 0x0c, 0xae, 0x0c, 0xaf, 0x0c, 0xb0, - 0x0c, 0xb1, 0x0c, 0xb2, 0x0c, 0xb3, 0x0c, 0xb4, 0x0c, 0xb5, 0x0c, 0xb6, - 0x0c, 0xb7, 0x0c, 0xb8, 0x0c, 0xb9, 0x0c, 0xba, 0x0c, 0xbb, 0x0c, 0xbc, - 0x0c, 0xbd, 0x0c, 0xbe, 0x0c, 0xbf, 0x0c, 0xc0, 0x0c, 0xc1, 0x0c, 0xc2, - 0x0c, 0xc3, 0x0c, 0xc4, 0x0c, 0xc5, 0x0c, 0xc6, 0x0c, 0xc7, 0x0c, 0xc8, - 0x0c, 0xc9, 0x0c, 0xca, 0x0c, 0xcb, 0x0c, 0xcc, 0x0c, 0xcd, 0x0c, 0xce, - 0x0c, 0xcf, 0x0c, 0xd0, 0x0c, 0xd1, 0x0c, 0xd2, 0x0c, 0xd3, 0x0c, 0xd4, - 0x0c, 0xd5, 0x0c, 0xd6, 0x0c, 0xd7, 0x0c, 0xd8, 0x0c, 0xd9, 0x0c, 0xda, - 0x0c, 0xdb, 0x0c, 0xdc, 0x0c, 0xdd, 0x0c, 0xde, 0x0c, 0xdf, 0x0c, 0xe0, - 0x0c, 0xe1, 0x0c, 0xe2, 0x0c, 0xe3, 0x0c, 0xe4, 0x0c, 0xe5, 0x0c, 0xe6, - 0x0c, 0xe7, 0x0c, 0xe8, 0x0c, 0xe9, 0x0c, 0xea, 0x0c, 0xeb, 0x0c, 0xec, - 0x0c, 0xed, 0x0c, 0xee, 0x0c, 0xef, 0x09, 0x73, 0x66, 0x74, 0x68, 0x79, - 0x70, 0x68, 0x65, 0x6e, 0x07, 0x41, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x6e, - 0x07, 0x61, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x6e, 0x06, 0x41, 0x62, 0x72, - 0x65, 0x76, 0x65, 0x06, 0x61, 0x62, 0x72, 0x65, 0x76, 0x65, 0x07, 0x41, - 0x6f, 0x67, 0x6f, 0x6e, 0x65, 0x6b, 0x07, 0x61, 0x6f, 0x67, 0x6f, 0x6e, - 0x65, 0x6b, 0x0b, 0x43, 0x63, 0x69, 0x72, 0x63, 0x75, 0x6d, 0x66, 0x6c, - 0x65, 0x78, 0x0b, 0x63, 0x63, 0x69, 0x72, 0x63, 0x75, 0x6d, 0x66, 0x6c, - 0x65, 0x78, 0x0a, 0x43, 0x64, 0x6f, 0x74, 0x61, 0x63, 0x63, 0x65, 0x6e, - 0x74, 0x0a, 0x63, 0x64, 0x6f, 0x74, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, - 0x06, 0x44, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x06, 0x64, 0x63, 0x61, 0x72, - 0x6f, 0x6e, 0x06, 0x44, 0x63, 0x72, 0x6f, 0x61, 0x74, 0x07, 0x45, 0x6d, - 0x61, 0x63, 0x72, 0x6f, 0x6e, 0x07, 0x65, 0x6d, 0x61, 0x63, 0x72, 0x6f, - 0x6e, 0x06, 0x45, 0x62, 0x72, 0x65, 0x76, 0x65, 0x06, 0x65, 0x62, 0x72, - 0x65, 0x76, 0x65, 0x0a, 0x45, 0x64, 0x6f, 0x74, 0x61, 0x63, 0x63, 0x65, - 0x6e, 0x74, 0x0a, 0x65, 0x64, 0x6f, 0x74, 0x61, 0x63, 0x63, 0x65, 0x6e, - 0x74, 0x07, 0x45, 0x6f, 0x67, 0x6f, 0x6e, 0x65, 0x6b, 0x07, 0x65, 0x6f, - 0x67, 0x6f, 0x6e, 0x65, 0x6b, 0x06, 0x45, 0x63, 0x61, 0x72, 0x6f, 0x6e, - 0x06, 0x65, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x0b, 0x47, 0x63, 0x69, 0x72, - 0x63, 0x75, 0x6d, 0x66, 0x6c, 0x65, 0x78, 0x0b, 0x67, 0x63, 0x69, 0x72, - 0x63, 0x75, 0x6d, 0x66, 0x6c, 0x65, 0x78, 0x0a, 0x47, 0x64, 0x6f, 0x74, - 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0a, 0x67, 0x64, 0x6f, 0x74, 0x61, - 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0c, 0x47, 0x63, 0x6f, 0x6d, 0x6d, 0x61, - 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0c, 0x67, 0x63, 0x6f, 0x6d, 0x6d, - 0x61, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0b, 0x48, 0x63, 0x69, 0x72, - 0x63, 0x75, 0x6d, 0x66, 0x6c, 0x65, 0x78, 0x0b, 0x68, 0x63, 0x69, 0x72, - 0x63, 0x75, 0x6d, 0x66, 0x6c, 0x65, 0x78, 0x04, 0x48, 0x62, 0x61, 0x72, - 0x04, 0x68, 0x62, 0x61, 0x72, 0x06, 0x49, 0x74, 0x69, 0x6c, 0x64, 0x65, - 0x06, 0x69, 0x74, 0x69, 0x6c, 0x64, 0x65, 0x07, 0x49, 0x6d, 0x61, 0x63, - 0x72, 0x6f, 0x6e, 0x07, 0x69, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x6e, 0x06, - 0x49, 0x62, 0x72, 0x65, 0x76, 0x65, 0x06, 0x69, 0x62, 0x72, 0x65, 0x76, - 0x65, 0x07, 0x49, 0x6f, 0x67, 0x6f, 0x6e, 0x65, 0x6b, 0x07, 0x69, 0x6f, - 0x67, 0x6f, 0x6e, 0x65, 0x6b, 0x02, 0x49, 0x4a, 0x02, 0x69, 0x6a, 0x0b, - 0x4a, 0x63, 0x69, 0x72, 0x63, 0x75, 0x6d, 0x66, 0x6c, 0x65, 0x78, 0x0b, - 0x6a, 0x63, 0x69, 0x72, 0x63, 0x75, 0x6d, 0x66, 0x6c, 0x65, 0x78, 0x0c, - 0x4b, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, - 0x0c, 0x6b, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61, 0x63, 0x63, 0x65, 0x6e, - 0x74, 0x0c, 0x6b, 0x67, 0x72, 0x65, 0x65, 0x6e, 0x6c, 0x61, 0x6e, 0x64, - 0x69, 0x63, 0x06, 0x4c, 0x61, 0x63, 0x75, 0x74, 0x65, 0x06, 0x6c, 0x61, - 0x63, 0x75, 0x74, 0x65, 0x0c, 0x4c, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61, - 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0c, 0x6c, 0x63, 0x6f, 0x6d, 0x6d, 0x61, - 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x06, 0x4c, 0x63, 0x61, 0x72, 0x6f, - 0x6e, 0x06, 0x6c, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x04, 0x4c, 0x64, 0x6f, - 0x74, 0x04, 0x6c, 0x64, 0x6f, 0x74, 0x06, 0x4e, 0x61, 0x63, 0x75, 0x74, - 0x65, 0x06, 0x6e, 0x61, 0x63, 0x75, 0x74, 0x65, 0x0c, 0x4e, 0x63, 0x6f, - 0x6d, 0x6d, 0x61, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0c, 0x6e, 0x63, - 0x6f, 0x6d, 0x6d, 0x61, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x06, 0x4e, - 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x06, 0x6e, 0x63, 0x61, 0x72, 0x6f, 0x6e, - 0x0b, 0x6e, 0x61, 0x70, 0x6f, 0x73, 0x74, 0x72, 0x6f, 0x70, 0x68, 0x65, - 0x03, 0x45, 0x6e, 0x67, 0x03, 0x65, 0x6e, 0x67, 0x07, 0x4f, 0x6d, 0x61, - 0x63, 0x72, 0x6f, 0x6e, 0x07, 0x6f, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x6e, - 0x06, 0x4f, 0x62, 0x72, 0x65, 0x76, 0x65, 0x06, 0x6f, 0x62, 0x72, 0x65, - 0x76, 0x65, 0x0d, 0x4f, 0x68, 0x75, 0x6e, 0x67, 0x61, 0x72, 0x75, 0x6d, - 0x6c, 0x61, 0x75, 0x74, 0x0d, 0x6f, 0x68, 0x75, 0x6e, 0x67, 0x61, 0x72, - 0x75, 0x6d, 0x6c, 0x61, 0x75, 0x74, 0x06, 0x52, 0x61, 0x63, 0x75, 0x74, - 0x65, 0x06, 0x72, 0x61, 0x63, 0x75, 0x74, 0x65, 0x0c, 0x52, 0x63, 0x6f, - 0x6d, 0x6d, 0x61, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0c, 0x72, 0x63, - 0x6f, 0x6d, 0x6d, 0x61, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x06, 0x52, - 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x06, 0x72, 0x63, 0x61, 0x72, 0x6f, 0x6e, - 0x06, 0x53, 0x61, 0x63, 0x75, 0x74, 0x65, 0x06, 0x73, 0x61, 0x63, 0x75, - 0x74, 0x65, 0x0b, 0x53, 0x63, 0x69, 0x72, 0x63, 0x75, 0x6d, 0x66, 0x6c, - 0x65, 0x78, 0x0b, 0x73, 0x63, 0x69, 0x72, 0x63, 0x75, 0x6d, 0x66, 0x6c, - 0x65, 0x78, 0x0c, 0x54, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61, 0x63, 0x63, - 0x65, 0x6e, 0x74, 0x0c, 0x74, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61, 0x63, - 0x63, 0x65, 0x6e, 0x74, 0x06, 0x54, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x06, - 0x74, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x04, 0x54, 0x62, 0x61, 0x72, 0x04, - 0x74, 0x62, 0x61, 0x72, 0x06, 0x55, 0x74, 0x69, 0x6c, 0x64, 0x65, 0x06, - 0x75, 0x74, 0x69, 0x6c, 0x64, 0x65, 0x07, 0x55, 0x6d, 0x61, 0x63, 0x72, - 0x6f, 0x6e, 0x07, 0x75, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x6e, 0x06, 0x55, - 0x62, 0x72, 0x65, 0x76, 0x65, 0x06, 0x75, 0x62, 0x72, 0x65, 0x76, 0x65, - 0x05, 0x55, 0x72, 0x69, 0x6e, 0x67, 0x05, 0x75, 0x72, 0x69, 0x6e, 0x67, - 0x0d, 0x55, 0x68, 0x75, 0x6e, 0x67, 0x61, 0x72, 0x75, 0x6d, 0x6c, 0x61, - 0x75, 0x74, 0x0d, 0x75, 0x68, 0x75, 0x6e, 0x67, 0x61, 0x72, 0x75, 0x6d, - 0x6c, 0x61, 0x75, 0x74, 0x07, 0x55, 0x6f, 0x67, 0x6f, 0x6e, 0x65, 0x6b, - 0x07, 0x75, 0x6f, 0x67, 0x6f, 0x6e, 0x65, 0x6b, 0x0b, 0x57, 0x63, 0x69, - 0x72, 0x63, 0x75, 0x6d, 0x66, 0x6c, 0x65, 0x78, 0x0b, 0x77, 0x63, 0x69, - 0x72, 0x63, 0x75, 0x6d, 0x66, 0x6c, 0x65, 0x78, 0x0b, 0x59, 0x63, 0x69, - 0x72, 0x63, 0x75, 0x6d, 0x66, 0x6c, 0x65, 0x78, 0x0b, 0x79, 0x63, 0x69, - 0x72, 0x63, 0x75, 0x6d, 0x66, 0x6c, 0x65, 0x78, 0x06, 0x5a, 0x61, 0x63, - 0x75, 0x74, 0x65, 0x06, 0x7a, 0x61, 0x63, 0x75, 0x74, 0x65, 0x0a, 0x5a, - 0x64, 0x6f, 0x74, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0a, 0x7a, 0x64, - 0x6f, 0x74, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x05, 0x6c, 0x6f, 0x6e, - 0x67, 0x73, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x38, 0x30, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x38, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x38, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x38, 0x33, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x38, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x38, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x38, 0x36, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x38, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x38, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x38, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x38, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x38, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x38, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x38, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x38, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x38, 0x46, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x39, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x39, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x39, 0x33, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x39, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x39, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x39, 0x36, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x39, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x39, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x39, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x39, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x39, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x39, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x39, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x39, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x39, 0x46, 0x05, 0x4f, - 0x68, 0x6f, 0x72, 0x6e, 0x05, 0x6f, 0x68, 0x6f, 0x72, 0x6e, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x41, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x41, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x41, 0x34, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x41, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x41, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x41, 0x37, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x41, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x41, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x41, 0x41, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x41, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x41, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x41, 0x44, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x41, 0x45, 0x05, 0x55, 0x68, 0x6f, 0x72, 0x6e, - 0x05, 0x75, 0x68, 0x6f, 0x72, 0x6e, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x42, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x42, 0x32, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x42, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x42, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x42, 0x35, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x42, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x42, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x42, 0x38, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x42, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x42, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x42, 0x42, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x42, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x42, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x42, 0x45, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x42, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x43, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x43, 0x31, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x43, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x43, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x43, 0x44, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x43, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x43, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x44, 0x30, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x44, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x44, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x44, 0x33, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x44, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x44, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x44, 0x36, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x44, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x44, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x44, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x44, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x44, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x44, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x44, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x44, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x44, 0x46, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x45, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, - 0x45, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x45, 0x32, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x31, 0x45, 0x33, 0x06, 0x47, 0x63, 0x61, 0x72, 0x6f, - 0x6e, 0x06, 0x67, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x31, 0x45, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x45, 0x39, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x45, 0x41, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x31, 0x45, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x45, 0x43, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x45, 0x44, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x31, 0x45, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x45, 0x46, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x46, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x31, 0x46, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x46, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x46, 0x36, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x31, 0x46, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x31, 0x46, 0x39, - 0x07, 0x41, 0x45, 0x61, 0x63, 0x75, 0x74, 0x65, 0x07, 0x61, 0x65, 0x61, - 0x63, 0x75, 0x74, 0x65, 0x0b, 0x4f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x61, - 0x63, 0x75, 0x74, 0x65, 0x0b, 0x6f, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x61, - 0x63, 0x75, 0x74, 0x65, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x30, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x30, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x32, 0x30, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x30, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x30, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x32, 0x30, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x30, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x30, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x32, 0x30, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x30, 0x39, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x30, 0x41, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x32, 0x30, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x30, 0x43, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x30, 0x44, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x32, 0x30, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x30, 0x46, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x31, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x32, 0x31, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x31, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x31, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x32, 0x31, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x31, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x31, 0x36, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x32, 0x31, 0x37, 0x0c, 0x53, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61, - 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0c, 0x73, 0x63, 0x6f, 0x6d, 0x6d, 0x61, - 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, - 0x31, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x31, 0x42, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x32, 0x31, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, - 0x31, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x31, 0x45, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x32, 0x31, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, - 0x32, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x32, 0x31, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x32, 0x32, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, - 0x32, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x32, 0x36, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x32, 0x32, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, - 0x32, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x32, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x32, 0x32, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, - 0x32, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x32, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x32, 0x32, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, - 0x32, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x32, 0x46, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x32, 0x33, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, - 0x33, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x33, 0x32, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x32, 0x33, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, - 0x33, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x33, 0x35, 0x07, 0x75, - 0x6e, 0x69, 0x30, 0x32, 0x33, 0x36, 0x08, 0x64, 0x6f, 0x74, 0x6c, 0x65, - 0x73, 0x73, 0x6a, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x33, 0x38, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x33, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x33, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x33, 0x42, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x33, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x33, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x33, 0x45, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x33, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x34, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x34, 0x31, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x34, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x34, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x34, 0x35, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x34, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x34, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x35, 0x30, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x35, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x35, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x35, 0x33, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x35, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x35, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x35, 0x36, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x35, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x35, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x35, 0x39, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x35, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x35, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x35, 0x43, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x35, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x35, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x35, 0x46, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x36, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x36, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x36, 0x32, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x36, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x36, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x36, 0x35, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x36, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x36, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x36, 0x38, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x36, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x36, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x36, 0x42, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x36, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x36, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x36, 0x45, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x36, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x37, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x37, 0x31, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x37, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x37, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x37, 0x34, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x37, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x37, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x37, 0x37, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x37, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x37, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x37, 0x41, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x37, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x37, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x37, 0x44, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x37, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x37, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x38, 0x30, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x38, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x38, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x38, 0x33, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x38, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x38, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x38, 0x36, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x38, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x38, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x38, 0x39, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x38, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x38, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x38, 0x43, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x38, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x38, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x38, 0x46, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x39, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x39, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x39, 0x32, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x39, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x39, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x39, 0x35, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x39, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x39, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x39, 0x38, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x39, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x39, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x39, 0x42, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x39, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x39, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x39, 0x45, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x39, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x41, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x41, 0x31, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x41, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x41, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x41, 0x34, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x41, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x41, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x41, 0x37, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x41, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x41, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x41, 0x41, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x41, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x41, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x41, 0x44, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x41, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x41, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x42, 0x30, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x42, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x42, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x42, 0x33, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x42, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x42, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x42, 0x36, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x42, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x42, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x42, 0x39, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x42, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x42, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x42, 0x44, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x42, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x42, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x43, 0x30, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x43, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x43, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x43, 0x39, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x43, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x43, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x43, 0x45, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x43, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x44, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x44, 0x31, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x44, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x44, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x44, 0x36, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x44, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x44, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x45, 0x30, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x45, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x45, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x45, 0x33, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x45, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x45, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x45, 0x36, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x45, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x45, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x32, 0x45, 0x39, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x32, 0x45, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x32, 0x46, 0x33, 0x09, 0x67, 0x72, 0x61, 0x76, 0x65, 0x63, 0x6f, 0x6d, - 0x62, 0x09, 0x61, 0x63, 0x75, 0x74, 0x65, 0x63, 0x6f, 0x6d, 0x62, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x33, 0x30, 0x32, 0x09, 0x74, 0x69, 0x6c, 0x64, - 0x65, 0x63, 0x6f, 0x6d, 0x62, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x30, - 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x30, 0x35, 0x07, 0x75, 0x6e, - 0x69, 0x30, 0x33, 0x30, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x30, - 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x30, 0x38, 0x0d, 0x68, 0x6f, - 0x6f, 0x6b, 0x61, 0x62, 0x6f, 0x76, 0x65, 0x63, 0x6f, 0x6d, 0x62, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x33, 0x30, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x33, 0x30, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x30, 0x43, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x33, 0x30, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x33, 0x30, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x30, 0x46, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x33, 0x31, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x33, 0x31, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x31, 0x32, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x33, 0x31, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x33, 0x31, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x31, 0x35, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x33, 0x31, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x33, 0x31, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x31, 0x38, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x33, 0x31, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x33, 0x31, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x31, 0x42, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x33, 0x31, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x33, 0x31, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x31, 0x45, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x33, 0x31, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, - 0x33, 0x32, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x32, 0x31, 0x07, - 0x75, 0x6e, 0x69, 0x30, 0x33, 0x32, 0x32, 0x0c, 0x64, 0x6f, 0x74, 0x62, - 0x65, 0x6c, 0x6f, 0x77, 0x63, 0x6f, 0x6d, 0x62, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x33, 0x32, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x32, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x32, 0x36, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x33, 0x32, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x32, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x32, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x33, 0x32, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x32, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x32, 0x43, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x33, 0x32, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x32, 0x45, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x32, 0x46, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x33, 0x33, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x33, 0x31, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x33, 0x32, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x33, 0x33, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x33, 0x34, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x33, 0x35, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x33, 0x33, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x33, 0x37, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x33, 0x38, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x33, 0x33, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x33, 0x41, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x33, 0x42, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x33, 0x33, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x33, 0x44, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x33, 0x45, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x33, 0x33, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x34, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x35, 0x38, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x33, 0x36, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x37, 0x34, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x37, 0x35, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x33, 0x37, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x37, 0x45, - 0x05, 0x74, 0x6f, 0x6e, 0x6f, 0x73, 0x0d, 0x64, 0x69, 0x65, 0x72, 0x65, - 0x73, 0x69, 0x73, 0x74, 0x6f, 0x6e, 0x6f, 0x73, 0x0a, 0x41, 0x6c, 0x70, - 0x68, 0x61, 0x74, 0x6f, 0x6e, 0x6f, 0x73, 0x09, 0x61, 0x6e, 0x6f, 0x74, - 0x65, 0x6c, 0x65, 0x69, 0x61, 0x0c, 0x45, 0x70, 0x73, 0x69, 0x6c, 0x6f, - 0x6e, 0x74, 0x6f, 0x6e, 0x6f, 0x73, 0x08, 0x45, 0x74, 0x61, 0x74, 0x6f, - 0x6e, 0x6f, 0x73, 0x09, 0x49, 0x6f, 0x74, 0x61, 0x74, 0x6f, 0x6e, 0x6f, - 0x73, 0x0c, 0x4f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x6e, 0x74, 0x6f, 0x6e, - 0x6f, 0x73, 0x0c, 0x55, 0x70, 0x73, 0x69, 0x6c, 0x6f, 0x6e, 0x74, 0x6f, - 0x6e, 0x6f, 0x73, 0x0a, 0x4f, 0x6d, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x6e, - 0x6f, 0x73, 0x11, 0x69, 0x6f, 0x74, 0x61, 0x64, 0x69, 0x65, 0x72, 0x65, - 0x73, 0x69, 0x73, 0x74, 0x6f, 0x6e, 0x6f, 0x73, 0x05, 0x41, 0x6c, 0x70, - 0x68, 0x61, 0x04, 0x42, 0x65, 0x74, 0x61, 0x05, 0x47, 0x61, 0x6d, 0x6d, - 0x61, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x39, 0x34, 0x07, 0x45, 0x70, - 0x73, 0x69, 0x6c, 0x6f, 0x6e, 0x04, 0x5a, 0x65, 0x74, 0x61, 0x03, 0x45, - 0x74, 0x61, 0x05, 0x54, 0x68, 0x65, 0x74, 0x61, 0x04, 0x49, 0x6f, 0x74, - 0x61, 0x05, 0x4b, 0x61, 0x70, 0x70, 0x61, 0x06, 0x4c, 0x61, 0x6d, 0x62, - 0x64, 0x61, 0x02, 0x4d, 0x75, 0x02, 0x4e, 0x75, 0x02, 0x58, 0x69, 0x07, - 0x4f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x6e, 0x02, 0x50, 0x69, 0x03, 0x52, - 0x68, 0x6f, 0x05, 0x53, 0x69, 0x67, 0x6d, 0x61, 0x03, 0x54, 0x61, 0x75, - 0x07, 0x55, 0x70, 0x73, 0x69, 0x6c, 0x6f, 0x6e, 0x03, 0x50, 0x68, 0x69, - 0x03, 0x43, 0x68, 0x69, 0x03, 0x50, 0x73, 0x69, 0x0c, 0x49, 0x6f, 0x74, - 0x61, 0x64, 0x69, 0x65, 0x72, 0x65, 0x73, 0x69, 0x73, 0x0f, 0x55, 0x70, - 0x73, 0x69, 0x6c, 0x6f, 0x6e, 0x64, 0x69, 0x65, 0x72, 0x65, 0x73, 0x69, - 0x73, 0x0a, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x74, 0x6f, 0x6e, 0x6f, 0x73, - 0x0c, 0x65, 0x70, 0x73, 0x69, 0x6c, 0x6f, 0x6e, 0x74, 0x6f, 0x6e, 0x6f, - 0x73, 0x08, 0x65, 0x74, 0x61, 0x74, 0x6f, 0x6e, 0x6f, 0x73, 0x09, 0x69, - 0x6f, 0x74, 0x61, 0x74, 0x6f, 0x6e, 0x6f, 0x73, 0x14, 0x75, 0x70, 0x73, - 0x69, 0x6c, 0x6f, 0x6e, 0x64, 0x69, 0x65, 0x72, 0x65, 0x73, 0x69, 0x73, - 0x74, 0x6f, 0x6e, 0x6f, 0x73, 0x05, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x04, - 0x62, 0x65, 0x74, 0x61, 0x05, 0x67, 0x61, 0x6d, 0x6d, 0x61, 0x05, 0x64, - 0x65, 0x6c, 0x74, 0x61, 0x07, 0x65, 0x70, 0x73, 0x69, 0x6c, 0x6f, 0x6e, - 0x04, 0x7a, 0x65, 0x74, 0x61, 0x03, 0x65, 0x74, 0x61, 0x05, 0x74, 0x68, - 0x65, 0x74, 0x61, 0x04, 0x69, 0x6f, 0x74, 0x61, 0x05, 0x6b, 0x61, 0x70, - 0x70, 0x61, 0x06, 0x6c, 0x61, 0x6d, 0x62, 0x64, 0x61, 0x07, 0x75, 0x6e, - 0x69, 0x30, 0x33, 0x42, 0x43, 0x02, 0x6e, 0x75, 0x02, 0x78, 0x69, 0x07, - 0x6f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x6e, 0x03, 0x72, 0x68, 0x6f, 0x06, - 0x73, 0x69, 0x67, 0x6d, 0x61, 0x31, 0x05, 0x73, 0x69, 0x67, 0x6d, 0x61, - 0x03, 0x74, 0x61, 0x75, 0x07, 0x75, 0x70, 0x73, 0x69, 0x6c, 0x6f, 0x6e, - 0x03, 0x70, 0x68, 0x69, 0x03, 0x63, 0x68, 0x69, 0x03, 0x70, 0x73, 0x69, - 0x05, 0x6f, 0x6d, 0x65, 0x67, 0x61, 0x0c, 0x69, 0x6f, 0x74, 0x61, 0x64, - 0x69, 0x65, 0x72, 0x65, 0x73, 0x69, 0x73, 0x0f, 0x75, 0x70, 0x73, 0x69, - 0x6c, 0x6f, 0x6e, 0x64, 0x69, 0x65, 0x72, 0x65, 0x73, 0x69, 0x73, 0x0c, - 0x6f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x6e, 0x74, 0x6f, 0x6e, 0x6f, 0x73, - 0x0c, 0x75, 0x70, 0x73, 0x69, 0x6c, 0x6f, 0x6e, 0x74, 0x6f, 0x6e, 0x6f, - 0x73, 0x0a, 0x6f, 0x6d, 0x65, 0x67, 0x61, 0x74, 0x6f, 0x6e, 0x6f, 0x73, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x44, 0x30, 0x06, 0x74, 0x68, 0x65, - 0x74, 0x61, 0x31, 0x08, 0x55, 0x70, 0x73, 0x69, 0x6c, 0x6f, 0x6e, 0x31, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x44, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x33, 0x44, 0x34, 0x04, 0x70, 0x68, 0x69, 0x31, 0x06, 0x6f, 0x6d, - 0x65, 0x67, 0x61, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x44, 0x37, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x44, 0x38, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x33, 0x44, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x44, 0x41, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x44, 0x42, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x33, 0x44, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x44, 0x44, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x44, 0x45, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x33, 0x44, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x45, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x45, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x33, 0x46, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x46, 0x31, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x46, 0x32, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x33, 0x46, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x46, 0x34, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x46, 0x35, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x33, 0x46, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x46, 0x37, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x46, 0x38, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x33, 0x46, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x46, 0x41, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x46, 0x42, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x33, 0x46, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x46, 0x44, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x46, 0x45, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x33, 0x46, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x30, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x30, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x30, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x30, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x30, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x30, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x30, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x30, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x30, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x30, 0x39, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x30, 0x41, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x30, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x30, 0x43, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x30, 0x44, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x30, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x30, 0x46, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x31, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x31, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x31, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x31, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x31, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x31, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x31, 0x36, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x31, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x31, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x31, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x31, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x31, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x31, 0x43, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x31, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x31, 0x45, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x31, 0x46, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x32, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x32, 0x31, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x32, 0x32, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x32, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x32, 0x34, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x32, 0x35, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x32, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x32, 0x37, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x32, 0x38, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x32, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x32, 0x41, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x32, 0x42, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x32, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x32, 0x44, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x32, 0x45, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x32, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x33, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x33, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x33, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x33, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x33, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x33, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x33, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x33, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x33, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x33, 0x39, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x33, 0x41, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x33, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x33, 0x43, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x33, 0x44, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x33, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x33, 0x46, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x34, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x34, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x34, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x34, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x34, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x34, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x34, 0x36, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x34, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x34, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x34, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x34, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x34, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x34, 0x43, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x34, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x34, 0x45, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x34, 0x46, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x35, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x35, 0x31, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x35, 0x32, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x35, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x35, 0x34, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x35, 0x35, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x35, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x35, 0x37, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x35, 0x38, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x35, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x35, 0x41, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x35, 0x42, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x35, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x35, 0x44, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x35, 0x45, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x35, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x36, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x36, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x37, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x37, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x39, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x39, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x39, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x39, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x39, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x39, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x39, 0x36, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x39, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x39, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x39, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x39, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x39, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x41, 0x32, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x41, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x41, 0x34, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x41, 0x35, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x41, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x41, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x41, 0x43, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x41, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x41, 0x45, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x41, 0x46, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x42, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x42, 0x31, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x42, 0x32, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x42, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x42, 0x41, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x42, 0x42, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x43, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x43, 0x31, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x43, 0x32, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x43, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x43, 0x34, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x43, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x43, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x43, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x43, 0x43, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x43, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x44, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x44, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x44, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x44, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x44, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x44, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x44, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x44, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x44, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x44, 0x39, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x44, 0x41, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x44, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x44, 0x43, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x44, 0x44, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x44, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x44, 0x46, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x45, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x45, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x45, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x45, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x45, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x45, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x45, 0x36, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x45, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x45, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x45, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x45, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x45, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x45, 0x43, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x45, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x45, 0x45, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x45, 0x46, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x46, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x46, 0x31, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x46, 0x32, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x46, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x46, 0x34, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x46, 0x35, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x46, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x46, 0x37, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x34, 0x46, 0x38, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x34, 0x46, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x31, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x31, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x31, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x31, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x31, 0x43, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x31, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x33, 0x31, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x33, 0x32, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x33, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x33, 0x34, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x33, 0x35, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x33, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x33, 0x37, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x33, 0x38, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x33, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x33, 0x41, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x33, 0x42, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x33, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x33, 0x44, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x33, 0x45, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x33, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x34, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x34, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x34, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x34, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x34, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x34, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x34, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x34, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x34, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x34, 0x39, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x34, 0x41, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x34, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x34, 0x43, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x34, 0x44, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x34, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x34, 0x46, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x35, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x35, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x35, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x35, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x35, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x35, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x35, 0x36, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x35, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x35, 0x41, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x35, 0x42, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x35, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x35, 0x44, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x35, 0x45, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x35, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x36, 0x31, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x36, 0x32, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x36, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x36, 0x34, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x36, 0x35, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x36, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x36, 0x37, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x36, 0x38, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x36, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x36, 0x41, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x36, 0x42, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x36, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x36, 0x44, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x36, 0x45, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x36, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x37, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x37, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x37, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x37, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x37, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x37, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x37, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x37, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x37, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x37, 0x39, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x37, 0x41, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x37, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x37, 0x43, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x37, 0x44, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x37, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x37, 0x46, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x38, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x38, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x38, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x38, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x38, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x38, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x38, 0x36, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x35, 0x38, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x38, 0x39, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x35, 0x38, 0x41, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x30, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x30, 0x37, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x30, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x30, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x30, 0x43, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x31, 0x35, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x31, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x31, 0x46, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x32, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x32, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x32, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x32, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x32, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x32, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x32, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x32, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x32, 0x39, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x32, 0x41, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x32, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x32, 0x43, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x32, 0x44, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x32, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x32, 0x46, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x33, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x33, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x33, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x33, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x33, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x33, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x33, 0x36, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x33, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x33, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x33, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x33, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x34, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x34, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x34, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x34, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x34, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x34, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x34, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x34, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x34, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x34, 0x39, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x34, 0x41, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x34, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x34, 0x43, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x34, 0x44, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x34, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x34, 0x46, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x35, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x35, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x35, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x35, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x35, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x35, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x35, 0x41, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x36, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x36, 0x31, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x36, 0x32, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x36, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x36, 0x34, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x36, 0x35, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x36, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x36, 0x37, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x36, 0x38, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x36, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x36, 0x41, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x36, 0x42, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x36, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x36, 0x44, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x37, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x37, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x37, 0x41, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x37, 0x42, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x37, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x37, 0x46, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x38, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x38, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x38, 0x34, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x38, 0x36, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x38, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x39, 0x31, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x39, 0x38, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x41, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x41, 0x39, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x41, 0x46, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x42, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x43, 0x43, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x46, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x46, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x46, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x46, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x46, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x46, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x46, 0x36, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x46, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x46, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x46, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x45, 0x38, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x38, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x38, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x45, 0x38, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x38, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x38, 0x41, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x45, 0x38, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x39, 0x34, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x39, 0x35, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x45, 0x39, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x39, 0x37, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x39, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x45, 0x39, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x39, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x39, 0x43, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x45, 0x39, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x39, 0x45, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x39, 0x46, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x45, 0x41, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x41, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x41, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x45, 0x41, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x41, 0x37, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x41, 0x41, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x45, 0x41, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x41, 0x44, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x41, 0x45, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x45, 0x41, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x42, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x42, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x45, 0x42, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x42, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x42, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x45, 0x42, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x42, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x42, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x45, 0x42, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x42, 0x39, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x42, 0x42, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x45, 0x42, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x43, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x43, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x45, 0x43, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x43, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x45, 0x43, 0x43, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x45, 0x43, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x44, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x44, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x30, 0x44, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x44, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x44, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x30, 0x44, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x44, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x44, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x30, 0x44, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x44, 0x39, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x44, 0x41, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x30, 0x44, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x44, 0x43, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x44, 0x44, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x30, 0x44, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x44, 0x46, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x45, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x30, 0x45, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x45, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x45, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x30, 0x45, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x45, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x45, 0x36, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x30, 0x45, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x45, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x45, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x30, 0x45, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x45, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x45, 0x43, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x30, 0x45, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x45, 0x45, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x45, 0x46, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x30, 0x46, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x46, 0x31, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x46, 0x32, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x30, 0x46, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x46, 0x34, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x46, 0x35, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x30, 0x46, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x46, 0x37, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x46, 0x38, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x30, 0x46, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x46, 0x41, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x30, 0x46, 0x42, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x30, 0x46, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x30, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x30, 0x38, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x30, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x31, 0x34, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x31, 0x36, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x31, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x31, 0x44, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x31, 0x45, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x31, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x32, 0x43, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x32, 0x44, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x32, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x33, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x33, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x33, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x33, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x33, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x33, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x33, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x33, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x33, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x33, 0x39, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x33, 0x41, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x33, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x33, 0x43, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x33, 0x45, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x33, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x34, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x34, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x34, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x34, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x34, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x34, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x34, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x34, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x34, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x34, 0x39, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x34, 0x41, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x34, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x34, 0x43, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x34, 0x44, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x34, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x34, 0x46, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x35, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x35, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x35, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x35, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x35, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x35, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x35, 0x36, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x35, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x35, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x35, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x35, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x35, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x36, 0x32, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x36, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x36, 0x34, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x36, 0x35, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x37, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x37, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x37, 0x42, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x38, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x39, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x39, 0x43, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x39, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x39, 0x45, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x39, 0x46, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x41, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x41, 0x31, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x41, 0x32, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x41, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x41, 0x34, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x41, 0x35, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x41, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x41, 0x37, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x41, 0x38, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x41, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x41, 0x41, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x41, 0x42, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x41, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x41, 0x44, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x41, 0x45, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x41, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x42, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x42, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x42, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x42, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x42, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x42, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x42, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x42, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x42, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x42, 0x41, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x42, 0x42, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x42, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x42, 0x44, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x44, 0x42, 0x45, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x44, 0x42, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x30, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x30, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x30, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x30, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x30, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x30, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x30, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x30, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x30, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x30, 0x39, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x30, 0x41, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x30, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x30, 0x43, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x30, 0x44, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x30, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x30, 0x46, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x31, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x31, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x31, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x31, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x31, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x31, 0x39, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x31, 0x41, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x31, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x31, 0x43, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x31, 0x44, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x31, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x31, 0x46, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x32, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x32, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x32, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x32, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x32, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x32, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x32, 0x36, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x32, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x32, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x32, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x32, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x32, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x32, 0x43, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x32, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x33, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x33, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x33, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x33, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x33, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x33, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x33, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x33, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x33, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x33, 0x39, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x33, 0x41, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x33, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x33, 0x43, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x33, 0x44, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x33, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x33, 0x46, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x34, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x34, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x34, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x34, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x34, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x34, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x34, 0x36, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x34, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x34, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x34, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x34, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x34, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x34, 0x43, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x34, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x35, 0x34, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x35, 0x35, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x35, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x35, 0x37, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x35, 0x38, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x35, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x35, 0x41, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x35, 0x42, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x35, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x35, 0x44, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x35, 0x45, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x35, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x36, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x36, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x36, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x36, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x36, 0x38, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x36, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x36, 0x41, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x36, 0x42, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x36, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x36, 0x44, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x36, 0x45, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x36, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x37, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x37, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x37, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x37, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x37, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x37, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x37, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x37, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x37, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x37, 0x39, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x37, 0x43, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x37, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x37, 0x45, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x37, 0x46, 0x06, 0x57, 0x67, 0x72, - 0x61, 0x76, 0x65, 0x06, 0x77, 0x67, 0x72, 0x61, 0x76, 0x65, 0x06, 0x57, - 0x61, 0x63, 0x75, 0x74, 0x65, 0x06, 0x77, 0x61, 0x63, 0x75, 0x74, 0x65, - 0x09, 0x57, 0x64, 0x69, 0x65, 0x72, 0x65, 0x73, 0x69, 0x73, 0x09, 0x77, - 0x64, 0x69, 0x65, 0x72, 0x65, 0x73, 0x69, 0x73, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x38, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x38, 0x37, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x38, 0x38, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x38, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x38, 0x41, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x38, 0x42, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x38, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x38, 0x44, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x38, 0x45, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x38, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x39, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x39, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x39, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x39, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x39, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x39, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x39, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x39, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x39, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x39, 0x39, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x39, 0x42, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x39, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x41, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x41, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x41, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x41, 0x44, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x42, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x42, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x42, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x42, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x42, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x42, 0x39, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x42, 0x43, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x42, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x43, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x43, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x43, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x43, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x43, 0x43, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x43, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x44, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x44, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x44, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x44, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x44, 0x43, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x44, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x45, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x45, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x45, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x45, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x45, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x45, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x45, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x45, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x45, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x45, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x45, 0x45, 0x07, 0x75, 0x6e, 0x69, - 0x31, 0x45, 0x45, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x46, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x46, 0x31, 0x06, 0x59, 0x67, 0x72, - 0x61, 0x76, 0x65, 0x06, 0x79, 0x67, 0x72, 0x61, 0x76, 0x65, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x45, 0x46, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, - 0x46, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x45, 0x46, 0x38, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x45, 0x46, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x30, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x30, 0x31, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x30, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x30, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x30, 0x34, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x30, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x30, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x30, 0x37, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x30, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x30, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x30, 0x41, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x30, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x30, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x30, 0x44, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x30, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x30, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x31, 0x30, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x31, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x31, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x31, 0x33, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x31, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x31, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x31, 0x38, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x31, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x31, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x31, 0x42, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x31, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x31, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x32, 0x30, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x32, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x32, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x32, 0x33, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x32, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x32, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x32, 0x36, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x32, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x32, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x32, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x32, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x32, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x32, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x32, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x32, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x32, 0x46, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x33, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x33, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x33, 0x32, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x33, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x33, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x33, 0x35, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x33, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x33, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x33, 0x38, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x33, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x33, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x33, 0x42, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x33, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x33, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x33, 0x45, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x33, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x34, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x34, 0x31, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x34, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x34, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x34, 0x34, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x34, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x34, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x34, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x34, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x34, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x34, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x34, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x35, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x35, 0x31, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x35, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x35, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x35, 0x34, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x35, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x35, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x35, 0x37, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x35, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x35, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x35, 0x44, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x35, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x36, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x36, 0x31, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x36, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x36, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x36, 0x34, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x36, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x36, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x36, 0x37, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x36, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x36, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x36, 0x41, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x36, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x36, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x36, 0x44, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x36, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x36, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x37, 0x30, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x37, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x37, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x37, 0x33, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x37, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x37, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x37, 0x36, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x37, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x37, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x37, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x37, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x37, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x37, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x37, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x38, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x38, 0x31, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x38, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x38, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x38, 0x34, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x38, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x38, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x38, 0x37, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x38, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x38, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x38, 0x41, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x38, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x38, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x38, 0x44, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x38, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x38, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x39, 0x30, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x39, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x39, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x39, 0x33, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x39, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x39, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x39, 0x36, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x39, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x39, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x39, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x39, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x39, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x39, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x39, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x39, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x39, 0x46, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x41, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x41, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x41, 0x32, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x41, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x41, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x41, 0x35, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x41, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x41, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x41, 0x38, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x41, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x41, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x41, 0x42, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x41, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x41, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x41, 0x45, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x41, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x42, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x42, 0x31, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x42, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x42, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x42, 0x34, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x42, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x42, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x42, 0x38, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x42, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x42, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x42, 0x42, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x42, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x42, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x42, 0x45, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x42, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x43, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x43, 0x31, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x43, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x43, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x43, 0x34, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x43, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x43, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x43, 0x38, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x43, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x43, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x43, 0x42, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x43, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x43, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x43, 0x45, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x43, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x44, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x44, 0x31, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x44, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x44, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x44, 0x36, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x44, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x44, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x44, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x44, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x44, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x44, 0x44, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x44, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x44, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x45, 0x30, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x45, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x45, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x45, 0x33, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x45, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x45, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x45, 0x36, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x45, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x45, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x45, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x45, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x45, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x45, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x45, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x45, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x45, 0x46, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x46, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x46, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x46, 0x34, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x46, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x46, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x46, 0x38, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x46, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x46, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x46, 0x42, 0x07, 0x75, - 0x6e, 0x69, 0x31, 0x46, 0x46, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, - 0x46, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x31, 0x46, 0x46, 0x45, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x30, 0x30, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, - 0x30, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x30, 0x32, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x30, 0x30, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, - 0x30, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x30, 0x35, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x30, 0x30, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, - 0x30, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x30, 0x38, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x30, 0x30, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, - 0x30, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x31, 0x30, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x30, 0x31, 0x31, 0x0a, 0x66, 0x69, 0x67, 0x75, 0x72, - 0x65, 0x64, 0x61, 0x73, 0x68, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x31, - 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x31, 0x36, 0x0d, 0x75, 0x6e, - 0x64, 0x65, 0x72, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x64, 0x62, 0x6c, 0x0d, - 0x71, 0x75, 0x6f, 0x74, 0x65, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, - 0x64, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x31, 0x46, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x30, 0x32, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x32, - 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x33, 0x31, 0x06, 0x6d, 0x69, - 0x6e, 0x75, 0x74, 0x65, 0x06, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x30, 0x33, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x30, 0x33, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x33, 0x36, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x30, 0x33, 0x37, 0x09, 0x65, 0x78, 0x63, 0x6c, - 0x61, 0x6d, 0x64, 0x62, 0x6c, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x33, - 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x33, 0x45, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x30, 0x34, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x34, - 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x34, 0x37, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x30, 0x34, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x34, - 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x34, 0x42, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x30, 0x35, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x37, - 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x37, 0x31, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x30, 0x37, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x37, - 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x37, 0x36, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x30, 0x37, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x37, - 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x37, 0x39, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x30, 0x37, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x37, - 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x37, 0x43, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x30, 0x37, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x37, - 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x37, 0x46, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x30, 0x38, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x38, - 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x38, 0x32, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x30, 0x38, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x38, - 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x38, 0x35, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x30, 0x38, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x38, - 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x38, 0x38, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x30, 0x38, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x38, - 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x38, 0x42, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x30, 0x38, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x38, - 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x38, 0x45, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x30, 0x39, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x39, - 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x39, 0x32, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x30, 0x39, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x39, - 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x39, 0x35, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x30, 0x39, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x39, - 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x39, 0x38, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x30, 0x39, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x39, - 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x39, 0x42, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x30, 0x39, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x41, - 0x30, 0x0d, 0x63, 0x6f, 0x6c, 0x6f, 0x6e, 0x6d, 0x6f, 0x6e, 0x65, 0x74, - 0x61, 0x72, 0x79, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x41, 0x32, 0x04, - 0x6c, 0x69, 0x72, 0x61, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x41, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x41, 0x36, 0x06, 0x70, 0x65, 0x73, - 0x65, 0x74, 0x61, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x41, 0x38, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x30, 0x41, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x30, 0x41, 0x41, 0x04, 0x64, 0x6f, 0x6e, 0x67, 0x04, 0x45, 0x75, 0x72, - 0x6f, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x41, 0x44, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x30, 0x41, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x41, - 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x42, 0x30, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x30, 0x42, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x42, - 0x32, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x42, 0x33, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x30, 0x42, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x42, - 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x30, 0x42, 0x38, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x30, 0x42, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x30, - 0x32, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x30, 0x35, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x30, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x30, - 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x30, 0x46, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x31, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x31, - 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x31, 0x37, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x31, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x31, - 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x31, 0x44, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x32, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x32, - 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x32, 0x41, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x32, 0x42, 0x09, 0x65, 0x73, 0x74, 0x69, 0x6d, 0x61, - 0x74, 0x65, 0x64, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x34, 0x38, 0x08, - 0x6f, 0x6e, 0x65, 0x74, 0x68, 0x69, 0x72, 0x64, 0x09, 0x74, 0x77, 0x6f, - 0x74, 0x68, 0x69, 0x72, 0x64, 0x73, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, - 0x35, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x35, 0x36, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x31, 0x35, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, - 0x35, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x35, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x31, 0x35, 0x41, 0x09, 0x6f, 0x6e, 0x65, 0x65, 0x69, - 0x67, 0x68, 0x74, 0x68, 0x0c, 0x74, 0x68, 0x72, 0x65, 0x65, 0x65, 0x69, - 0x67, 0x68, 0x74, 0x68, 0x73, 0x0b, 0x66, 0x69, 0x76, 0x65, 0x65, 0x69, - 0x67, 0x68, 0x74, 0x68, 0x73, 0x0c, 0x73, 0x65, 0x76, 0x65, 0x6e, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x68, 0x73, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, - 0x35, 0x46, 0x09, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x6c, 0x65, 0x66, 0x74, - 0x07, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x75, 0x70, 0x0a, 0x61, 0x72, 0x72, - 0x6f, 0x77, 0x72, 0x69, 0x67, 0x68, 0x74, 0x09, 0x61, 0x72, 0x72, 0x6f, - 0x77, 0x64, 0x6f, 0x77, 0x6e, 0x09, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x62, - 0x6f, 0x74, 0x68, 0x09, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x75, 0x70, 0x64, - 0x6e, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x39, 0x36, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x39, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x39, - 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x39, 0x39, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x39, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x39, - 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x39, 0x43, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x39, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x39, - 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x39, 0x46, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x41, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x41, - 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x41, 0x32, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x41, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x41, - 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x41, 0x35, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x41, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x41, - 0x37, 0x0c, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x75, 0x70, 0x64, 0x6e, 0x62, - 0x73, 0x65, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x41, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x31, 0x41, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, - 0x41, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x41, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x31, 0x41, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, - 0x41, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x41, 0x46, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x31, 0x42, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, - 0x42, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x42, 0x32, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x31, 0x42, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, - 0x42, 0x34, 0x0e, 0x63, 0x61, 0x72, 0x72, 0x69, 0x61, 0x67, 0x65, 0x72, - 0x65, 0x74, 0x75, 0x72, 0x6e, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x42, - 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x42, 0x37, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x42, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x42, - 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x42, 0x41, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x42, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x42, - 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x42, 0x44, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x42, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x42, - 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x43, 0x30, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x43, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x43, - 0x32, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x43, 0x33, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x43, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x43, - 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x43, 0x36, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x43, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x43, - 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x43, 0x39, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x43, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x43, - 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x43, 0x43, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x43, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x43, - 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x43, 0x46, 0x0c, 0x61, 0x72, - 0x72, 0x6f, 0x77, 0x64, 0x62, 0x6c, 0x6c, 0x65, 0x66, 0x74, 0x0a, 0x61, - 0x72, 0x72, 0x6f, 0x77, 0x64, 0x62, 0x6c, 0x75, 0x70, 0x0d, 0x61, 0x72, - 0x72, 0x6f, 0x77, 0x64, 0x62, 0x6c, 0x72, 0x69, 0x67, 0x68, 0x74, 0x0c, - 0x61, 0x72, 0x72, 0x6f, 0x77, 0x64, 0x62, 0x6c, 0x64, 0x6f, 0x77, 0x6e, - 0x0c, 0x61, 0x72, 0x72, 0x6f, 0x77, 0x64, 0x62, 0x6c, 0x62, 0x6f, 0x74, - 0x68, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x44, 0x35, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x44, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x44, - 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x44, 0x38, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x44, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x44, - 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x44, 0x42, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x44, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x44, - 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x44, 0x45, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x44, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x45, - 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x45, 0x31, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x45, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x45, - 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x45, 0x34, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x45, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x45, - 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x45, 0x37, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x45, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x45, - 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x45, 0x41, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x45, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x45, - 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x45, 0x44, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x45, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x45, - 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x46, 0x30, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x46, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x46, - 0x32, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x46, 0x33, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x46, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x46, - 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x46, 0x36, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x46, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x46, - 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x46, 0x39, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x46, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x46, - 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x46, 0x43, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x31, 0x46, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x46, - 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x31, 0x46, 0x46, 0x09, 0x75, 0x6e, - 0x69, 0x76, 0x65, 0x72, 0x73, 0x61, 0x6c, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x32, 0x30, 0x31, 0x0b, 0x65, 0x78, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x74, - 0x69, 0x61, 0x6c, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x30, 0x34, 0x08, - 0x65, 0x6d, 0x70, 0x74, 0x79, 0x73, 0x65, 0x74, 0x08, 0x67, 0x72, 0x61, - 0x64, 0x69, 0x65, 0x6e, 0x74, 0x07, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x0a, 0x6e, 0x6f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x30, 0x41, 0x08, 0x73, 0x75, 0x63, - 0x68, 0x74, 0x68, 0x61, 0x74, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x30, - 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x30, 0x44, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x32, 0x31, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x31, - 0x35, 0x0c, 0x61, 0x73, 0x74, 0x65, 0x72, 0x69, 0x73, 0x6b, 0x6d, 0x61, - 0x74, 0x68, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x31, 0x38, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x32, 0x31, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, - 0x31, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x31, 0x43, 0x0c, 0x70, - 0x72, 0x6f, 0x70, 0x6f, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x0a, - 0x6f, 0x72, 0x74, 0x68, 0x6f, 0x67, 0x6f, 0x6e, 0x61, 0x6c, 0x05, 0x61, - 0x6e, 0x67, 0x6c, 0x65, 0x0a, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, - 0x61, 0x6e, 0x64, 0x09, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x61, 0x6c, 0x6f, - 0x72, 0x0c, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x05, 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x32, 0x32, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x32, 0x44, - 0x09, 0x74, 0x68, 0x65, 0x72, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x32, 0x33, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, - 0x33, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x33, 0x37, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x32, 0x33, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, - 0x33, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x33, 0x41, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x32, 0x33, 0x42, 0x07, 0x73, 0x69, 0x6d, 0x69, 0x6c, - 0x61, 0x72, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x33, 0x44, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x32, 0x34, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, - 0x34, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x34, 0x33, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x32, 0x34, 0x34, 0x09, 0x63, 0x6f, 0x6e, 0x67, 0x72, - 0x75, 0x65, 0x6e, 0x74, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x34, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x34, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x32, 0x34, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x34, 0x41, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x34, 0x42, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x32, 0x34, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x34, 0x44, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x34, 0x45, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x32, 0x34, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x35, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x35, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x32, 0x35, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x35, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x35, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x32, 0x35, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x35, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x35, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x32, 0x35, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x35, 0x39, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x35, 0x41, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x32, 0x35, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x35, 0x43, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x35, 0x44, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x32, 0x35, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x35, 0x46, - 0x0b, 0x65, 0x71, 0x75, 0x69, 0x76, 0x61, 0x6c, 0x65, 0x6e, 0x63, 0x65, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x36, 0x32, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x32, 0x36, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x36, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x36, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x32, 0x36, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x36, 0x39, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x36, 0x44, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x32, 0x36, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x36, 0x46, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x37, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x32, 0x37, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x37, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x37, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x32, 0x37, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x37, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x37, 0x36, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x32, 0x37, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x37, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x37, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x32, 0x37, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x37, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x37, 0x43, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x32, 0x37, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x37, 0x45, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x37, 0x46, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x32, 0x38, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x38, 0x31, - 0x0c, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x73, 0x75, 0x62, 0x73, 0x65, - 0x74, 0x0e, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x73, 0x75, 0x70, 0x65, - 0x72, 0x73, 0x65, 0x74, 0x09, 0x6e, 0x6f, 0x74, 0x73, 0x75, 0x62, 0x73, - 0x65, 0x74, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x38, 0x35, 0x0c, 0x72, - 0x65, 0x66, 0x6c, 0x65, 0x78, 0x73, 0x75, 0x62, 0x73, 0x65, 0x74, 0x0e, - 0x72, 0x65, 0x66, 0x6c, 0x65, 0x78, 0x73, 0x75, 0x70, 0x65, 0x72, 0x73, - 0x65, 0x74, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x38, 0x38, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x32, 0x38, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, - 0x38, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x38, 0x42, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x32, 0x38, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, - 0x39, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x39, 0x31, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x32, 0x39, 0x32, 0x0a, 0x63, 0x69, 0x72, 0x63, 0x6c, - 0x65, 0x70, 0x6c, 0x75, 0x73, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x39, - 0x36, 0x0e, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x6d, 0x75, 0x6c, 0x74, - 0x69, 0x70, 0x6c, 0x79, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x39, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x39, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x32, 0x39, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x39, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x39, 0x43, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x32, 0x39, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x39, 0x45, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x39, 0x46, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x32, 0x41, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x41, 0x31, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x41, 0x32, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x32, 0x41, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x41, 0x34, - 0x0d, 0x70, 0x65, 0x72, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x63, 0x75, 0x6c, - 0x61, 0x72, 0x07, 0x64, 0x6f, 0x74, 0x6d, 0x61, 0x74, 0x68, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x32, 0x43, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, - 0x43, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x44, 0x41, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x32, 0x44, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, - 0x44, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x44, 0x44, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x32, 0x44, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, - 0x44, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x45, 0x30, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x32, 0x45, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, - 0x45, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x45, 0x33, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x32, 0x45, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, - 0x45, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x45, 0x36, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x32, 0x45, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, - 0x45, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x32, 0x45, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x32, 0x45, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, - 0x30, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x30, 0x31, 0x05, 0x68, - 0x6f, 0x75, 0x73, 0x65, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x30, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x30, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x30, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x30, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x30, 0x38, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x30, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x30, 0x41, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x30, 0x42, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x30, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x30, 0x44, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x30, 0x45, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x30, 0x46, 0x0d, 0x72, 0x65, 0x76, 0x6c, 0x6f, 0x67, 0x69, - 0x63, 0x61, 0x6c, 0x6e, 0x6f, 0x74, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, - 0x31, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x31, 0x32, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x33, 0x31, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, - 0x31, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x31, 0x35, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x33, 0x31, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, - 0x31, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x31, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x33, 0x31, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, - 0x31, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x31, 0x46, 0x0a, 0x69, - 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x6c, 0x74, 0x70, 0x0a, 0x69, 0x6e, - 0x74, 0x65, 0x67, 0x72, 0x61, 0x6c, 0x62, 0x74, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x32, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x32, 0x36, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x32, 0x37, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x32, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x32, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x33, 0x35, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x33, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x33, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x33, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x33, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x33, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x33, 0x43, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x33, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x33, 0x45, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x34, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x34, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x34, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x34, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x34, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x34, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x34, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x34, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x34, 0x43, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x34, 0x44, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x35, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x35, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x35, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x35, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x35, 0x37, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x35, 0x38, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x35, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x35, 0x41, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x35, 0x42, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x35, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x35, 0x45, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x35, 0x46, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x36, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x36, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x36, 0x34, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x36, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x36, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x36, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x36, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x36, 0x43, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x36, 0x44, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x36, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x36, 0x46, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x37, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x37, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x37, 0x34, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x37, 0x35, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x37, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x37, 0x37, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x37, 0x38, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x37, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x37, 0x41, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x37, 0x44, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x38, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x38, 0x31, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x38, 0x32, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x38, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x38, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x38, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x38, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x38, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x39, 0x35, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x39, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x39, 0x43, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x39, 0x44, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x39, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x39, 0x46, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x41, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x41, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x41, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x41, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x41, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x41, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x41, 0x36, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x41, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x41, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x41, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x41, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x41, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x41, 0x43, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x41, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x41, 0x45, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x33, 0x43, 0x45, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x33, 0x43, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x34, 0x32, 0x33, - 0x08, 0x53, 0x46, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x35, 0x30, 0x31, 0x08, 0x53, 0x46, 0x31, 0x31, 0x30, 0x30, - 0x30, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x30, 0x33, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x35, 0x30, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, - 0x30, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x30, 0x36, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x35, 0x30, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, - 0x30, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x30, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x35, 0x30, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, - 0x30, 0x42, 0x08, 0x53, 0x46, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x35, 0x30, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x35, 0x30, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x30, 0x46, 0x08, - 0x53, 0x46, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x35, 0x31, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x31, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x31, 0x33, 0x08, 0x53, 0x46, 0x30, - 0x32, 0x30, 0x30, 0x30, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x31, - 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x31, 0x36, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x35, 0x31, 0x37, 0x08, 0x53, 0x46, 0x30, 0x34, 0x30, 0x30, - 0x30, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x31, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x35, 0x31, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, - 0x31, 0x42, 0x08, 0x53, 0x46, 0x30, 0x38, 0x30, 0x30, 0x30, 0x30, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x35, 0x31, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x35, 0x31, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x31, 0x46, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x35, 0x32, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x35, 0x32, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x32, 0x32, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x35, 0x32, 0x33, 0x08, 0x53, 0x46, 0x30, 0x39, - 0x30, 0x30, 0x30, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x32, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x32, 0x36, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x35, 0x32, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x32, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x32, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x35, 0x32, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x32, 0x42, - 0x08, 0x53, 0x46, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x35, 0x32, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x32, - 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x32, 0x46, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x35, 0x33, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x33, - 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x33, 0x32, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x35, 0x33, 0x33, 0x08, 0x53, 0x46, 0x30, 0x37, 0x30, 0x30, - 0x30, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x33, 0x35, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x35, 0x33, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, - 0x33, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x33, 0x38, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x35, 0x33, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, - 0x33, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x33, 0x42, 0x08, 0x53, - 0x46, 0x30, 0x35, 0x30, 0x30, 0x30, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x35, 0x33, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x33, 0x45, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x35, 0x33, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x35, 0x34, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x34, 0x31, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x35, 0x34, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x35, 0x34, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x34, 0x34, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x35, 0x34, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x35, 0x34, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x34, 0x37, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x35, 0x34, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x35, 0x34, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x34, 0x41, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x35, 0x34, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x35, 0x34, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x34, 0x44, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x35, 0x34, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x35, 0x34, 0x46, 0x08, 0x53, 0x46, 0x34, 0x33, 0x30, 0x30, 0x30, 0x30, - 0x08, 0x53, 0x46, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, - 0x35, 0x31, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x35, 0x32, 0x30, - 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x33, 0x39, 0x30, 0x30, 0x30, 0x30, - 0x08, 0x53, 0x46, 0x32, 0x32, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, - 0x32, 0x31, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x32, 0x35, 0x30, - 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, - 0x08, 0x53, 0x46, 0x34, 0x39, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, - 0x33, 0x38, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x32, 0x38, 0x30, - 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x32, 0x37, 0x30, 0x30, 0x30, 0x30, - 0x08, 0x53, 0x46, 0x32, 0x36, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, - 0x33, 0x36, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x33, 0x37, 0x30, - 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x34, 0x32, 0x30, 0x30, 0x30, 0x30, - 0x08, 0x53, 0x46, 0x31, 0x39, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, - 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x32, 0x33, 0x30, - 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x34, 0x37, 0x30, 0x30, 0x30, 0x30, - 0x08, 0x53, 0x46, 0x34, 0x38, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, - 0x34, 0x31, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x34, 0x35, 0x30, - 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x34, 0x36, 0x30, 0x30, 0x30, 0x30, - 0x08, 0x53, 0x46, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, - 0x35, 0x34, 0x30, 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x35, 0x33, 0x30, - 0x30, 0x30, 0x30, 0x08, 0x53, 0x46, 0x34, 0x34, 0x30, 0x30, 0x30, 0x30, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x36, 0x44, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x35, 0x36, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x36, 0x46, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x37, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x35, 0x37, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x37, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x37, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x35, 0x37, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x37, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x37, 0x36, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x35, 0x37, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x37, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x37, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x35, 0x37, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x37, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x37, 0x43, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x35, 0x37, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x37, 0x45, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x37, 0x46, 0x07, 0x75, 0x70, 0x62, - 0x6c, 0x6f, 0x63, 0x6b, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x38, 0x31, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x38, 0x32, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x35, 0x38, 0x33, 0x07, 0x64, 0x6e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x38, 0x35, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x35, 0x38, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x38, 0x37, - 0x05, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, - 0x38, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x38, 0x41, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x35, 0x38, 0x42, 0x07, 0x6c, 0x66, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x38, 0x44, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x35, 0x38, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, - 0x38, 0x46, 0x07, 0x72, 0x74, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x07, 0x6c, - 0x74, 0x73, 0x68, 0x61, 0x64, 0x65, 0x05, 0x73, 0x68, 0x61, 0x64, 0x65, - 0x07, 0x64, 0x6b, 0x73, 0x68, 0x61, 0x64, 0x65, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x35, 0x39, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x39, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x39, 0x36, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x35, 0x39, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x39, 0x38, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x39, 0x39, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x35, 0x39, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x39, 0x42, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x39, 0x43, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x35, 0x39, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x39, 0x45, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x39, 0x46, 0x09, 0x66, 0x69, 0x6c, - 0x6c, 0x65, 0x64, 0x62, 0x6f, 0x78, 0x06, 0x48, 0x32, 0x32, 0x30, 0x37, - 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x41, 0x32, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x35, 0x41, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x41, - 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x41, 0x35, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x35, 0x41, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x41, - 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x41, 0x38, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x35, 0x41, 0x39, 0x06, 0x48, 0x31, 0x38, 0x35, 0x34, 0x33, - 0x06, 0x48, 0x31, 0x38, 0x35, 0x35, 0x31, 0x0a, 0x66, 0x69, 0x6c, 0x6c, - 0x65, 0x64, 0x72, 0x65, 0x63, 0x74, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, - 0x41, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x41, 0x45, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x35, 0x41, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, - 0x42, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x42, 0x31, 0x07, 0x74, - 0x72, 0x69, 0x61, 0x67, 0x75, 0x70, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, - 0x42, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x42, 0x34, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x35, 0x42, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, - 0x42, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x42, 0x37, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x35, 0x42, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, - 0x42, 0x39, 0x07, 0x74, 0x72, 0x69, 0x61, 0x67, 0x72, 0x74, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x35, 0x42, 0x42, 0x07, 0x74, 0x72, 0x69, 0x61, 0x67, - 0x64, 0x6e, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x42, 0x44, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x35, 0x42, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, - 0x42, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x43, 0x30, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x35, 0x43, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, - 0x43, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x43, 0x33, 0x07, 0x74, - 0x72, 0x69, 0x61, 0x67, 0x6c, 0x66, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, - 0x43, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x43, 0x36, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x35, 0x43, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, - 0x43, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x43, 0x39, 0x06, 0x63, - 0x69, 0x72, 0x63, 0x6c, 0x65, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x43, - 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x43, 0x44, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x35, 0x43, 0x45, 0x06, 0x48, 0x31, 0x38, 0x35, 0x33, 0x33, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x44, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x35, 0x44, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x44, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x44, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x35, 0x44, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x44, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x44, 0x36, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x35, 0x44, 0x37, 0x09, 0x69, 0x6e, 0x76, 0x62, 0x75, 0x6c, 0x6c, - 0x65, 0x74, 0x09, 0x69, 0x6e, 0x76, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x44, 0x41, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x35, 0x44, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x44, 0x43, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x44, 0x44, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x35, 0x44, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x44, 0x46, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x45, 0x30, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x35, 0x45, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x45, 0x32, - 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x45, 0x33, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x35, 0x45, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x45, 0x35, - 0x0a, 0x6f, 0x70, 0x65, 0x6e, 0x62, 0x75, 0x6c, 0x6c, 0x65, 0x74, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x35, 0x45, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x35, 0x45, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x45, 0x39, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x35, 0x45, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x35, 0x45, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x45, 0x43, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x35, 0x45, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x35, 0x45, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x45, 0x46, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x35, 0x46, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x35, 0x46, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x46, 0x32, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x35, 0x46, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x35, 0x46, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x46, 0x35, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x35, 0x46, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x35, 0x46, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x46, 0x38, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x35, 0x46, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x35, 0x46, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x46, 0x42, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x35, 0x46, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x35, 0x46, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x35, 0x46, 0x45, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x35, 0x46, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x36, 0x30, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x30, 0x31, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x36, 0x30, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x36, 0x30, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x30, 0x34, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x36, 0x30, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x36, 0x30, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x30, 0x37, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x36, 0x30, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x36, 0x30, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x30, 0x41, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x36, 0x30, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x36, 0x30, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x30, 0x44, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x36, 0x30, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x36, 0x30, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x31, 0x30, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x36, 0x31, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x36, 0x31, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x31, 0x33, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x36, 0x31, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x36, 0x31, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x31, 0x36, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x36, 0x31, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x36, 0x31, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x31, 0x39, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x36, 0x31, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x36, 0x31, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x31, 0x43, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x36, 0x31, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x36, 0x31, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x31, 0x46, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x36, 0x32, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x36, 0x32, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x32, 0x32, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x36, 0x32, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x36, 0x32, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x32, 0x35, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x36, 0x32, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x36, 0x32, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x32, 0x38, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x36, 0x32, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x36, 0x32, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x32, 0x42, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x36, 0x32, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x36, 0x32, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x32, 0x45, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x36, 0x32, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x36, 0x33, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x33, 0x39, 0x09, - 0x73, 0x6d, 0x69, 0x6c, 0x65, 0x66, 0x61, 0x63, 0x65, 0x0c, 0x69, 0x6e, - 0x76, 0x73, 0x6d, 0x69, 0x6c, 0x65, 0x66, 0x61, 0x63, 0x65, 0x03, 0x73, - 0x75, 0x6e, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x33, 0x44, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x33, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x33, 0x46, 0x06, 0x66, 0x65, 0x6d, 0x61, 0x6c, 0x65, 0x07, 0x75, 0x6e, - 0x69, 0x32, 0x36, 0x34, 0x31, 0x04, 0x6d, 0x61, 0x6c, 0x65, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x34, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x34, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x34, 0x35, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x34, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x34, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x34, 0x38, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x34, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x34, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x34, 0x42, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x34, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x34, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x34, 0x45, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x34, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x35, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x35, 0x31, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x35, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x35, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x35, 0x34, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x35, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x35, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x35, 0x37, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x35, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x35, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x35, 0x41, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x35, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x35, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x35, 0x44, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x35, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x35, 0x46, 0x05, 0x73, 0x70, 0x61, 0x64, 0x65, 0x07, 0x75, 0x6e, 0x69, - 0x32, 0x36, 0x36, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x36, 0x32, - 0x04, 0x63, 0x6c, 0x75, 0x62, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x36, - 0x34, 0x05, 0x68, 0x65, 0x61, 0x72, 0x74, 0x07, 0x64, 0x69, 0x61, 0x6d, - 0x6f, 0x6e, 0x64, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x36, 0x37, 0x07, - 0x75, 0x6e, 0x69, 0x32, 0x36, 0x36, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, - 0x36, 0x36, 0x39, 0x0b, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x6e, - 0x6f, 0x74, 0x65, 0x0e, 0x6d, 0x75, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x6e, - 0x6f, 0x74, 0x65, 0x64, 0x62, 0x6c, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x36, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x36, 0x44, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x36, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x36, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x37, 0x30, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x37, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x37, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x37, 0x33, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x37, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x37, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x37, 0x36, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x37, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x37, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x37, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x37, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x37, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x37, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x37, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x37, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x37, 0x46, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x38, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x38, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x38, 0x32, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x38, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x38, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x38, 0x35, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x38, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x38, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x38, 0x38, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x38, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x38, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x38, 0x42, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x39, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x39, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x39, 0x32, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x39, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x39, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x39, 0x35, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x39, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x39, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x39, 0x38, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x39, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x39, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x39, 0x42, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x39, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x41, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, 0x41, 0x31, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x36, 0x42, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x36, - 0x42, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x30, 0x31, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x30, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x30, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x30, 0x34, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x30, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x30, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x30, 0x38, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x30, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x30, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x30, 0x44, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x30, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x30, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x31, 0x30, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x31, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x31, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x31, 0x33, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x31, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x31, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x31, 0x36, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x31, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x31, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x31, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x31, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x31, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x31, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x31, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x31, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x31, 0x46, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x32, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x32, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x32, 0x32, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x32, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x32, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x32, 0x35, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x32, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x32, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x32, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x32, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x32, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x32, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x32, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x32, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x32, 0x46, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x33, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x33, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x33, 0x32, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x33, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x33, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x33, 0x35, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x33, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x33, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x33, 0x38, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x33, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x33, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x33, 0x42, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x33, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x33, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x33, 0x45, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x33, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x34, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x34, 0x31, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x34, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x34, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x34, 0x34, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x34, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x34, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x34, 0x37, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x34, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x34, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x34, 0x41, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x34, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x34, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x34, 0x46, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x35, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x35, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x35, 0x32, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x35, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x35, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x35, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x35, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x35, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x35, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x35, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x35, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x36, 0x31, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x36, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x36, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x36, 0x34, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x36, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x36, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x36, 0x37, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x36, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x36, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x36, 0x41, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x36, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x36, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x36, 0x44, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x36, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x36, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x37, 0x30, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x37, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x37, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x37, 0x33, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x37, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x37, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x39, 0x34, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x39, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x39, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x39, 0x41, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x39, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x39, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x39, 0x44, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x39, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x39, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x41, 0x30, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x41, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x41, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x41, 0x33, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x41, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x41, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x41, 0x36, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x41, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x41, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x41, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x41, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x41, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x41, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x41, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x41, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x41, 0x46, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x42, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x42, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x42, 0x33, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x42, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x42, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x42, 0x36, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x42, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x42, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x42, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x42, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x42, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x42, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x42, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x42, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x43, 0x32, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x43, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x43, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x45, 0x30, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x45, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, - 0x45, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x37, 0x45, 0x38, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x37, 0x45, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x39, - 0x45, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x39, 0x46, 0x41, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x39, 0x46, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x41, - 0x32, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x41, 0x36, 0x41, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x41, 0x36, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x42, - 0x30, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x42, 0x30, 0x36, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x42, 0x30, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x42, - 0x30, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x42, 0x30, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x42, 0x30, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x42, - 0x30, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x42, 0x30, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x42, 0x30, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x42, - 0x31, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x42, 0x31, 0x33, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x42, 0x31, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x42, - 0x31, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x42, 0x31, 0x36, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x42, 0x31, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x42, - 0x31, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x42, 0x31, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x42, 0x31, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x43, - 0x36, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x43, 0x36, 0x44, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x43, 0x36, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x43, - 0x36, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x43, 0x37, 0x30, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x43, 0x37, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x43, - 0x37, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x43, 0x37, 0x37, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x43, 0x37, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x43, - 0x37, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x43, 0x37, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x43, 0x37, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x43, - 0x37, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x43, 0x37, 0x46, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x45, 0x31, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x45, - 0x31, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x45, 0x32, 0x32, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x45, 0x32, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x45, - 0x32, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x32, 0x45, 0x32, 0x35, 0x07, 0x75, - 0x6e, 0x69, 0x32, 0x45, 0x32, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, - 0x30, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, 0x30, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x41, 0x37, 0x30, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, - 0x30, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, 0x30, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x41, 0x37, 0x30, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, - 0x30, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, 0x30, 0x46, 0x07, 0x75, - 0x6e, 0x69, 0x41, 0x37, 0x31, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, - 0x31, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, 0x31, 0x32, 0x07, 0x75, - 0x6e, 0x69, 0x41, 0x37, 0x31, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, - 0x31, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, 0x31, 0x35, 0x07, 0x75, - 0x6e, 0x69, 0x41, 0x37, 0x31, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, - 0x31, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, 0x31, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x41, 0x37, 0x31, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, - 0x31, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, 0x31, 0x46, 0x07, 0x75, - 0x6e, 0x69, 0x41, 0x37, 0x32, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, - 0x32, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, 0x32, 0x34, 0x07, 0x75, - 0x6e, 0x69, 0x41, 0x37, 0x32, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, - 0x32, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, 0x32, 0x37, 0x07, 0x75, - 0x6e, 0x69, 0x41, 0x37, 0x38, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, - 0x38, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, 0x38, 0x42, 0x07, 0x75, - 0x6e, 0x69, 0x41, 0x37, 0x38, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, - 0x38, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, 0x38, 0x45, 0x07, 0x75, - 0x6e, 0x69, 0x41, 0x37, 0x39, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, - 0x39, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x41, 0x37, 0x41, 0x41, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x36, 0x43, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x35, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x35, 0x33, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x35, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x35, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x35, 0x36, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x35, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x35, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x35, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x35, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x35, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x35, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x35, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x35, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x35, 0x46, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x36, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x36, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x36, 0x32, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x36, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x36, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x36, 0x35, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x36, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x36, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x36, 0x38, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x36, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x36, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x36, 0x42, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x36, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x36, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x36, 0x45, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x36, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x37, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x37, 0x31, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x37, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x37, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x37, 0x34, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x37, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x37, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x37, 0x37, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x37, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x37, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x37, 0x41, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x37, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x37, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x37, 0x44, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x37, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x37, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x38, 0x30, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x38, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x38, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x38, 0x42, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x38, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x38, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x38, 0x45, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x38, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x39, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x39, 0x31, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x39, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x39, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x39, 0x34, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x39, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x39, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x39, 0x46, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x41, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x41, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x41, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x41, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x45, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x45, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x46, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, - 0x46, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x42, 0x46, 0x45, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x42, 0x46, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x37, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x37, 0x31, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x37, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x37, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x37, 0x34, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x37, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x37, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x37, 0x38, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x37, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x37, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x37, 0x42, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x37, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x37, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x37, 0x45, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x37, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x38, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x38, 0x31, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x38, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x38, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x38, 0x34, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x38, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x38, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x38, 0x37, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x38, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x38, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x38, 0x41, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x38, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x38, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x38, 0x44, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x38, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x38, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x39, 0x30, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x39, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x39, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x39, 0x33, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x39, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x39, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x39, 0x36, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x39, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x39, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x39, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x39, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x39, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x39, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x39, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x39, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x39, 0x46, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x41, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x41, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x41, 0x32, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x41, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x41, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x41, 0x35, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x41, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x41, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x41, 0x38, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x41, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x41, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x41, 0x42, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x41, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x41, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x41, 0x45, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x41, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x42, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x42, 0x31, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x42, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x42, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x42, 0x34, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x42, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x42, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x42, 0x37, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x42, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x42, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x42, 0x41, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x42, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x42, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x42, 0x44, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x42, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x42, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x43, 0x30, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x43, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x43, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x43, 0x33, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x43, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x43, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x43, 0x36, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x43, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x43, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x43, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x43, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x43, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x43, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x43, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x43, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x43, 0x46, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x44, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x44, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x44, 0x32, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x44, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x44, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x44, 0x35, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x44, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x44, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x44, 0x38, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x44, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x44, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x44, 0x42, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x44, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x44, 0x44, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x44, 0x45, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x44, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x45, 0x30, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x45, 0x31, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x45, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x45, 0x33, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x45, 0x34, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x45, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x45, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x45, 0x37, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x45, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x45, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x45, 0x41, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x45, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x45, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x45, 0x44, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x45, 0x45, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x45, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x46, 0x30, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x46, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x46, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x46, 0x33, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x46, 0x34, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x46, 0x35, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x46, 0x36, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x46, 0x37, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x46, 0x38, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x46, 0x39, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x46, 0x41, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, - 0x46, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x45, 0x46, 0x43, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x45, 0x46, 0x46, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x46, - 0x46, 0x39, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x46, 0x46, 0x41, 0x07, 0x75, - 0x6e, 0x69, 0x46, 0x46, 0x46, 0x42, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x46, - 0x46, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x46, 0x46, 0x46, 0x44, 0x06, 0x75, - 0x31, 0x44, 0x35, 0x35, 0x41, 0x06, 0x75, 0x31, 0x44, 0x36, 0x37, 0x30, - 0x06, 0x75, 0x31, 0x44, 0x36, 0x37, 0x31, 0x06, 0x75, 0x31, 0x44, 0x36, - 0x37, 0x32, 0x06, 0x75, 0x31, 0x44, 0x36, 0x37, 0x33, 0x06, 0x75, 0x31, - 0x44, 0x36, 0x37, 0x34, 0x06, 0x75, 0x31, 0x44, 0x36, 0x37, 0x35, 0x06, - 0x75, 0x31, 0x44, 0x36, 0x37, 0x36, 0x06, 0x75, 0x31, 0x44, 0x36, 0x37, - 0x37, 0x06, 0x75, 0x31, 0x44, 0x36, 0x37, 0x38, 0x06, 0x75, 0x31, 0x44, - 0x36, 0x37, 0x39, 0x06, 0x75, 0x31, 0x44, 0x36, 0x37, 0x41, 0x06, 0x75, - 0x31, 0x44, 0x36, 0x37, 0x42, 0x06, 0x75, 0x31, 0x44, 0x36, 0x37, 0x43, - 0x06, 0x75, 0x31, 0x44, 0x36, 0x37, 0x44, 0x06, 0x75, 0x31, 0x44, 0x36, - 0x37, 0x45, 0x06, 0x75, 0x31, 0x44, 0x36, 0x37, 0x46, 0x06, 0x75, 0x31, - 0x44, 0x36, 0x38, 0x30, 0x06, 0x75, 0x31, 0x44, 0x36, 0x38, 0x31, 0x06, - 0x75, 0x31, 0x44, 0x36, 0x38, 0x32, 0x06, 0x75, 0x31, 0x44, 0x36, 0x38, - 0x33, 0x06, 0x75, 0x31, 0x44, 0x36, 0x38, 0x34, 0x06, 0x75, 0x31, 0x44, - 0x36, 0x38, 0x35, 0x06, 0x75, 0x31, 0x44, 0x36, 0x38, 0x36, 0x06, 0x75, - 0x31, 0x44, 0x36, 0x38, 0x37, 0x06, 0x75, 0x31, 0x44, 0x36, 0x38, 0x38, - 0x06, 0x75, 0x31, 0x44, 0x36, 0x38, 0x39, 0x06, 0x75, 0x31, 0x44, 0x36, - 0x38, 0x41, 0x06, 0x75, 0x31, 0x44, 0x36, 0x38, 0x42, 0x06, 0x75, 0x31, - 0x44, 0x36, 0x38, 0x43, 0x06, 0x75, 0x31, 0x44, 0x36, 0x38, 0x44, 0x06, - 0x75, 0x31, 0x44, 0x36, 0x38, 0x45, 0x06, 0x75, 0x31, 0x44, 0x36, 0x38, - 0x46, 0x06, 0x75, 0x31, 0x44, 0x36, 0x39, 0x30, 0x06, 0x75, 0x31, 0x44, - 0x36, 0x39, 0x31, 0x06, 0x75, 0x31, 0x44, 0x36, 0x39, 0x32, 0x06, 0x75, - 0x31, 0x44, 0x36, 0x39, 0x33, 0x06, 0x75, 0x31, 0x44, 0x36, 0x39, 0x34, - 0x06, 0x75, 0x31, 0x44, 0x36, 0x39, 0x35, 0x06, 0x75, 0x31, 0x44, 0x36, - 0x39, 0x36, 0x06, 0x75, 0x31, 0x44, 0x36, 0x39, 0x37, 0x06, 0x75, 0x31, - 0x44, 0x36, 0x39, 0x38, 0x06, 0x75, 0x31, 0x44, 0x36, 0x39, 0x39, 0x06, - 0x75, 0x31, 0x44, 0x36, 0x39, 0x41, 0x06, 0x75, 0x31, 0x44, 0x36, 0x39, - 0x42, 0x06, 0x75, 0x31, 0x44, 0x36, 0x39, 0x43, 0x06, 0x75, 0x31, 0x44, - 0x36, 0x39, 0x44, 0x06, 0x75, 0x31, 0x44, 0x36, 0x39, 0x45, 0x06, 0x75, - 0x31, 0x44, 0x36, 0x39, 0x46, 0x06, 0x75, 0x31, 0x44, 0x36, 0x41, 0x30, - 0x06, 0x75, 0x31, 0x44, 0x36, 0x41, 0x31, 0x06, 0x75, 0x31, 0x44, 0x36, - 0x41, 0x32, 0x06, 0x75, 0x31, 0x44, 0x36, 0x41, 0x33, 0x06, 0x75, 0x31, - 0x44, 0x37, 0x46, 0x36, 0x06, 0x75, 0x31, 0x44, 0x37, 0x46, 0x37, 0x06, - 0x75, 0x31, 0x44, 0x37, 0x46, 0x38, 0x06, 0x75, 0x31, 0x44, 0x37, 0x46, - 0x39, 0x06, 0x75, 0x31, 0x44, 0x37, 0x46, 0x41, 0x06, 0x75, 0x31, 0x44, - 0x37, 0x46, 0x42, 0x06, 0x75, 0x31, 0x44, 0x37, 0x46, 0x43, 0x06, 0x75, - 0x31, 0x44, 0x37, 0x46, 0x44, 0x06, 0x75, 0x31, 0x44, 0x37, 0x46, 0x45, - 0x06, 0x75, 0x31, 0x44, 0x37, 0x46, 0x46, 0x09, 0x64, 0x6c, 0x4c, 0x74, - 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x09, 0x44, 0x69, 0x61, 0x65, 0x72, 0x65, - 0x73, 0x69, 0x73, 0x05, 0x41, 0x63, 0x75, 0x74, 0x65, 0x05, 0x54, 0x69, - 0x6c, 0x64, 0x65, 0x05, 0x47, 0x72, 0x61, 0x76, 0x65, 0x0a, 0x43, 0x69, - 0x72, 0x63, 0x75, 0x6d, 0x66, 0x6c, 0x65, 0x78, 0x05, 0x43, 0x61, 0x72, - 0x6f, 0x6e, 0x0d, 0x66, 0x72, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x6c, 0x61, 0x73, 0x68, 0x0c, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x31, 0x31, - 0x2e, 0x63, 0x61, 0x73, 0x65, 0x0c, 0x75, 0x6e, 0x69, 0x30, 0x33, 0x30, - 0x36, 0x2e, 0x63, 0x61, 0x73, 0x65, 0x0c, 0x75, 0x6e, 0x69, 0x30, 0x33, - 0x30, 0x37, 0x2e, 0x63, 0x61, 0x73, 0x65, 0x0c, 0x75, 0x6e, 0x69, 0x30, - 0x33, 0x30, 0x42, 0x2e, 0x63, 0x61, 0x73, 0x65, 0x0c, 0x75, 0x6e, 0x69, - 0x30, 0x33, 0x30, 0x46, 0x2e, 0x63, 0x61, 0x73, 0x65, 0x0c, 0x74, 0x68, - 0x69, 0x6e, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, 0x0c, 0x75, - 0x6e, 0x69, 0x30, 0x33, 0x30, 0x34, 0x2e, 0x63, 0x61, 0x73, 0x65, 0x08, - 0x75, 0x6e, 0x64, 0x65, 0x72, 0x62, 0x61, 0x72, 0x0d, 0x75, 0x6e, 0x64, - 0x65, 0x72, 0x62, 0x61, 0x72, 0x2e, 0x77, 0x69, 0x64, 0x65, 0x0e, 0x75, - 0x6e, 0x64, 0x65, 0x72, 0x62, 0x61, 0x72, 0x2e, 0x73, 0x6d, 0x61, 0x6c, - 0x6c, 0x03, 0x6a, 0x6f, 0x74, 0x11, 0x64, 0x69, 0x61, 0x65, 0x72, 0x65, - 0x73, 0x69, 0x73, 0x2e, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x73, 0x0a, - 0x61, 0x72, 0x61, 0x62, 0x69, 0x63, 0x5f, 0x64, 0x6f, 0x74, 0x0c, 0x61, - 0x72, 0x61, 0x62, 0x69, 0x63, 0x5f, 0x32, 0x64, 0x6f, 0x74, 0x73, 0x0c, - 0x61, 0x72, 0x61, 0x62, 0x69, 0x63, 0x5f, 0x33, 0x64, 0x6f, 0x74, 0x73, - 0x0c, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x36, 0x45, 0x2e, 0x66, 0x69, 0x6e, - 0x61, 0x0c, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x41, 0x31, 0x2e, 0x69, 0x6e, - 0x69, 0x74, 0x0c, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x41, 0x31, 0x2e, 0x6d, - 0x65, 0x64, 0x69, 0x0c, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x36, 0x46, 0x2e, - 0x66, 0x69, 0x6e, 0x61, 0x0c, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x41, 0x31, - 0x2e, 0x66, 0x69, 0x6e, 0x61, 0x0e, 0x61, 0x72, 0x61, 0x62, 0x69, 0x63, - 0x5f, 0x33, 0x64, 0x6f, 0x74, 0x73, 0x5f, 0x61, 0x0e, 0x61, 0x72, 0x61, - 0x62, 0x69, 0x63, 0x5f, 0x32, 0x64, 0x6f, 0x74, 0x73, 0x5f, 0x61, 0x0c, - 0x61, 0x72, 0x61, 0x62, 0x69, 0x63, 0x5f, 0x34, 0x64, 0x6f, 0x74, 0x73, - 0x0e, 0x61, 0x72, 0x61, 0x62, 0x69, 0x63, 0x5f, 0x67, 0x61, 0x66, 0x5f, - 0x62, 0x61, 0x72, 0x10, 0x61, 0x72, 0x61, 0x62, 0x69, 0x63, 0x5f, 0x67, - 0x61, 0x66, 0x5f, 0x62, 0x61, 0x72, 0x5f, 0x61, 0x0b, 0x61, 0x72, 0x61, - 0x62, 0x69, 0x63, 0x5f, 0x72, 0x69, 0x6e, 0x67, 0x07, 0x45, 0x6e, 0x67, - 0x2e, 0x61, 0x6c, 0x74, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x36, 0x45, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x36, 0x46, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x37, 0x43, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x37, 0x44, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x38, 0x31, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x38, 0x32, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x38, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x39, 0x32, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x41, 0x31, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x42, 0x35, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x42, 0x41, 0x07, 0x75, 0x6e, 0x69, - 0x30, 0x36, 0x43, 0x36, 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x43, 0x45, - 0x07, 0x75, 0x6e, 0x69, 0x30, 0x36, 0x44, 0x35, 0xb9, 0x02, 0x80, 0x01, - 0x15, 0xb2, 0x94, 0x5d, 0x05, 0x41, 0x1c, 0x01, 0x15, 0x00, 0x96, 0x00, - 0x03, 0x01, 0x15, 0x00, 0x80, 0x00, 0x04, 0x01, 0x14, 0x00, 0xfe, 0x00, - 0x03, 0x01, 0x13, 0x00, 0xfe, 0x00, 0x03, 0x01, 0x12, 0x00, 0x12, 0x00, - 0x03, 0x01, 0x11, 0x00, 0xfe, 0x00, 0x03, 0x01, 0x10, 0x00, 0xfe, 0x00, - 0x03, 0x01, 0x0f, 0x00, 0x9a, 0x00, 0x03, 0x01, 0x0e, 0x00, 0xfe, 0x00, - 0x03, 0x01, 0x0d, 0xb2, 0xeb, 0x47, 0x05, 0x41, 0x25, 0x01, 0x0d, 0x00, - 0x7d, 0x00, 0x03, 0x01, 0x0c, 0x00, 0x25, 0x00, 0x03, 0x01, 0x0b, 0x00, - 0x32, 0x00, 0x03, 0x01, 0x0a, 0x00, 0x96, 0x00, 0x03, 0x01, 0x09, 0x00, - 0xfe, 0x00, 0x03, 0x01, 0x08, 0x00, 0x0e, 0x00, 0x03, 0x01, 0x07, 0x00, - 0xfe, 0x00, 0x03, 0x01, 0x06, 0x00, 0x25, 0x00, 0x03, 0x01, 0x05, 0x00, - 0xfe, 0x00, 0x03, 0x01, 0x04, 0x00, 0x0e, 0x00, 0x03, 0x01, 0x03, 0x00, - 0x25, 0x00, 0x03, 0x01, 0x02, 0x00, 0xfe, 0x00, 0x03, 0x01, 0x01, 0x40, - 0x59, 0xfe, 0x03, 0xfe, 0xfe, 0x03, 0xfd, 0x7d, 0x03, 0xfc, 0xfe, 0x03, - 0xfb, 0xfe, 0x03, 0xfa, 0x32, 0x03, 0xf9, 0xbb, 0x03, 0xf8, 0x7d, 0x03, - 0xf7, 0xf6, 0x8c, 0x05, 0xf7, 0xfe, 0x03, 0xf7, 0xc0, 0x04, 0xf6, 0xf5, - 0x59, 0x05, 0xf6, 0x8c, 0x03, 0xf6, 0x80, 0x04, 0xf5, 0xf4, 0x26, 0x05, - 0xf5, 0x59, 0x03, 0xf5, 0x40, 0x04, 0xf4, 0x26, 0x03, 0xf3, 0xf2, 0x2f, - 0x05, 0xf3, 0xfa, 0x03, 0xf2, 0x2f, 0x03, 0xf1, 0xfe, 0x03, 0xf0, 0xfe, - 0x03, 0xef, 0x32, 0x03, 0xee, 0x14, 0x03, 0xed, 0x96, 0x03, 0xec, 0xeb, - 0x47, 0x05, 0xec, 0xfe, 0x03, 0xec, 0xb8, 0xff, 0xd1, 0x40, 0xff, 0x04, - 0xeb, 0x47, 0x03, 0xea, 0xe9, 0x64, 0x05, 0xea, 0x96, 0x03, 0xe9, 0x64, - 0x03, 0xe8, 0xfe, 0x03, 0xe7, 0xe6, 0x1b, 0x05, 0xe7, 0xfe, 0x03, 0xe6, - 0x1b, 0x03, 0xe5, 0xfe, 0x03, 0xe4, 0x6b, 0x03, 0xe3, 0xfe, 0x03, 0xe2, - 0xbb, 0x03, 0xe1, 0xe0, 0x19, 0x05, 0xe1, 0xfa, 0x03, 0xe0, 0x19, 0x03, - 0xdf, 0x96, 0x03, 0xde, 0xfe, 0x03, 0xdd, 0xfe, 0x03, 0xdc, 0xdb, 0x15, - 0x05, 0xdc, 0xfe, 0x03, 0xdb, 0x15, 0x03, 0xda, 0x96, 0x03, 0xd9, 0xd8, - 0x15, 0x05, 0xd9, 0xfe, 0x03, 0xd8, 0x8d, 0x0b, 0x05, 0xd8, 0x15, 0x03, - 0xd7, 0x7d, 0x03, 0xd6, 0x3a, 0x03, 0xd5, 0x8d, 0x0b, 0x05, 0xd5, 0x3a, - 0x03, 0xd4, 0xfe, 0x03, 0xd3, 0xd2, 0x0a, 0x05, 0xd3, 0xfe, 0x03, 0xd2, - 0x0a, 0x03, 0xd1, 0xfe, 0x03, 0xd0, 0xfe, 0x03, 0xcf, 0x8a, 0x11, 0x05, - 0xcf, 0x1c, 0x03, 0xce, 0x16, 0x03, 0xcd, 0xfe, 0x03, 0xcc, 0x96, 0x03, - 0xcb, 0x8b, 0x25, 0x05, 0xcb, 0xfe, 0x03, 0xca, 0xfe, 0x03, 0xc9, 0x7d, - 0x03, 0xc8, 0xfe, 0x03, 0xc7, 0xfe, 0x03, 0xc6, 0xfe, 0x03, 0xc5, 0x9a, - 0x0d, 0x05, 0xc4, 0xfe, 0x03, 0xc3, 0xfe, 0x03, 0xc2, 0xfe, 0x03, 0xc1, - 0xfe, 0x03, 0xc0, 0x8d, 0x0b, 0x05, 0xc0, 0x14, 0x03, 0xbf, 0x0c, 0x03, - 0xbe, 0xbd, 0xbb, 0x05, 0xbe, 0xfe, 0x03, 0xbd, 0xbc, 0x5d, 0x05, 0xbd, - 0xbb, 0x03, 0xbd, 0x80, 0x04, 0xbc, 0xbb, 0x25, 0x05, 0xbc, 0x5d, 0x03, - 0xbc, 0x40, 0x04, 0xbb, 0x25, 0x03, 0xba, 0xfe, 0x03, 0xb9, 0x96, 0x03, - 0xb8, 0x8f, 0x41, 0x05, 0xb7, 0xfe, 0x03, 0xb6, 0x8f, 0x41, 0x05, 0xb6, - 0xfa, 0x03, 0xb5, 0x9a, 0x0d, 0x05, 0xb4, 0xfe, 0x03, 0xb3, 0x64, 0x03, - 0xb2, 0x64, 0x03, 0xb1, 0x0e, 0x03, 0xb0, 0x12, 0x03, 0xaf, 0xfe, 0x03, - 0xae, 0xfe, 0x40, 0xfd, 0x03, 0xad, 0xfe, 0x03, 0xac, 0xfe, 0x03, 0xab, - 0x12, 0x03, 0xaa, 0xfe, 0x03, 0xa9, 0xa8, 0x0e, 0x05, 0xa9, 0x32, 0x03, - 0xa8, 0x0e, 0x03, 0xa7, 0xa6, 0x11, 0x05, 0xa7, 0x28, 0x03, 0xa6, 0x11, - 0x03, 0xa5, 0xa4, 0x2d, 0x05, 0xa5, 0x7d, 0x03, 0xa4, 0x2d, 0x03, 0xa3, - 0xfe, 0x03, 0xa2, 0xfe, 0x03, 0xa1, 0xfe, 0x03, 0xa0, 0x9f, 0x19, 0x05, - 0xa0, 0x64, 0x03, 0x9f, 0x9e, 0x10, 0x05, 0x9f, 0x19, 0x03, 0x9e, 0x10, - 0x03, 0x9d, 0x0a, 0x03, 0x9c, 0xfe, 0x03, 0x9b, 0x9a, 0x0d, 0x05, 0x9b, - 0xfe, 0x03, 0x9a, 0x0d, 0x03, 0x99, 0x98, 0x2e, 0x05, 0x99, 0xfe, 0x03, - 0x98, 0x2e, 0x03, 0x97, 0x8f, 0x41, 0x05, 0x97, 0x96, 0x03, 0x96, 0x95, - 0xbb, 0x05, 0x96, 0xfe, 0x03, 0x95, 0x94, 0x5d, 0x05, 0x95, 0xbb, 0x03, - 0x95, 0x80, 0x04, 0x94, 0x90, 0x25, 0x05, 0x94, 0x5d, 0x03, 0x94, 0x40, - 0x04, 0x93, 0xfe, 0x03, 0x92, 0xfe, 0x03, 0x91, 0x90, 0x25, 0x05, 0x91, - 0xbb, 0x03, 0x90, 0x25, 0x03, 0x8f, 0x8b, 0x25, 0x05, 0x8f, 0x41, 0x03, - 0x8e, 0x8d, 0x0b, 0x05, 0x8e, 0x14, 0x03, 0x8d, 0x0b, 0x03, 0x8c, 0x8b, - 0x25, 0x05, 0x8c, 0x64, 0x03, 0x8b, 0x8a, 0x11, 0x05, 0x8b, 0x25, 0x03, - 0x8a, 0x11, 0x03, 0x89, 0xfe, 0x03, 0x88, 0xfe, 0x03, 0x87, 0xfe, 0x03, - 0x86, 0x85, 0x11, 0x05, 0x86, 0xfe, 0x03, 0x85, 0x11, 0x03, 0x84, 0xfe, - 0x03, 0x83, 0xfe, 0x03, 0x82, 0x11, 0x42, 0x05, 0x82, 0x53, 0x03, 0x81, - 0xfe, 0x03, 0x80, 0x78, 0x03, 0x7f, 0x7e, 0x7d, 0x05, 0x7f, 0xfe, 0x03, - 0x7e, 0x7d, 0x03, 0x7d, 0x1e, 0x03, 0x7c, 0xfe, 0x03, 0x7b, 0x0e, 0x03, - 0x7a, 0xfe, 0x03, 0x77, 0xfe, 0x03, 0x76, 0xfe, 0x03, 0x75, 0x74, 0x0c, - 0x05, 0x75, 0x0f, 0x03, 0x75, 0xb8, 0x01, 0x00, 0x40, 0xda, 0x04, 0x74, - 0x0c, 0x03, 0x74, 0xc0, 0x04, 0x73, 0x12, 0x03, 0x73, 0x40, 0x04, 0x72, - 0xfe, 0x03, 0x71, 0xfe, 0x03, 0x70, 0xfe, 0x03, 0x6f, 0x6e, 0x53, 0x05, - 0x6f, 0x96, 0x03, 0x6e, 0x6d, 0x28, 0x05, 0x6e, 0x53, 0x03, 0x6d, 0x28, - 0x03, 0x6c, 0xfe, 0x03, 0x6b, 0x32, 0x03, 0x6a, 0xfe, 0x03, 0x69, 0x32, - 0x03, 0x68, 0xfa, 0x03, 0x67, 0xbb, 0x03, 0x66, 0xfe, 0x03, 0x65, 0xfe, - 0x03, 0x64, 0xfe, 0x03, 0x63, 0x62, 0x1e, 0x05, 0x63, 0xfe, 0x03, 0x62, - 0x00, 0x10, 0x05, 0x62, 0x1e, 0x03, 0x61, 0xfe, 0x03, 0x60, 0xfe, 0x03, - 0x5f, 0xfe, 0x03, 0x5e, 0x5a, 0x0b, 0x05, 0x5e, 0x0e, 0x03, 0x5d, 0x64, - 0x03, 0x5c, 0xc8, 0x03, 0x5b, 0x5a, 0x0b, 0x05, 0x5b, 0x14, 0x03, 0x5a, - 0x0b, 0x03, 0x59, 0xfe, 0x03, 0x58, 0x14, 0x03, 0x57, 0xfe, 0x03, 0x56, - 0xfe, 0x03, 0x55, 0x1b, 0x19, 0x05, 0x55, 0x32, 0x03, 0x54, 0xfe, 0x03, - 0x53, 0xfe, 0x03, 0x52, 0xfe, 0x03, 0x51, 0x7d, 0x03, 0x50, 0xfe, 0x03, - 0x4f, 0x14, 0x03, 0x4e, 0xfe, 0x03, 0x4d, 0x01, 0x2d, 0x05, 0x4d, 0xfe, - 0x03, 0x4c, 0xbb, 0x03, 0x4b, 0x28, 0x03, 0x4a, 0x49, 0x18, 0x05, 0x4a, - 0x37, 0x03, 0x49, 0x43, 0x12, 0x05, 0x49, 0x18, 0x03, 0x48, 0x45, 0x18, - 0x05, 0x48, 0xfe, 0x03, 0x47, 0x43, 0x12, 0x05, 0x47, 0x64, 0x03, 0x46, - 0x45, 0x18, 0x05, 0x46, 0xbb, 0x03, 0x45, 0x18, 0x03, 0x44, 0x43, 0x12, - 0x05, 0x44, 0x37, 0x03, 0x43, 0x42, 0x11, 0x05, 0x43, 0x12, 0x03, 0x43, - 0xb8, 0x02, 0x40, 0x40, 0x09, 0x04, 0x42, 0x41, 0x0f, 0x05, 0x42, 0x11, - 0x03, 0x42, 0xb8, 0x02, 0x00, 0x40, 0x09, 0x04, 0x41, 0x40, 0x0e, 0x05, - 0x41, 0x0f, 0x03, 0x41, 0xb8, 0x01, 0xc0, 0x40, 0x09, 0x04, 0x40, 0x3f, - 0x0c, 0x05, 0x40, 0x0e, 0x03, 0x40, 0xb8, 0x01, 0x80, 0x40, 0x09, 0x04, - 0x3f, 0x0c, 0x09, 0x05, 0x3f, 0x0c, 0x03, 0x3f, 0xb8, 0x01, 0x40, 0x40, - 0x64, 0x04, 0x3e, 0xfe, 0x03, 0x3d, 0x01, 0x2d, 0x05, 0x3d, 0xfa, 0x03, - 0x3c, 0xfe, 0x03, 0x3b, 0x28, 0x03, 0x3a, 0xfe, 0x03, 0x39, 0x11, 0x42, - 0x05, 0x39, 0x64, 0x03, 0x38, 0x31, 0x1a, 0x05, 0x38, 0x4b, 0x03, 0x37, - 0xfe, 0x03, 0x36, 0x2d, 0x14, 0x05, 0x36, 0xfe, 0x03, 0x35, 0x4b, 0x03, - 0x34, 0x30, 0x1a, 0x05, 0x34, 0x4b, 0x03, 0x33, 0x30, 0x1a, 0x05, 0x33, - 0xfe, 0x03, 0x32, 0x11, 0x42, 0x05, 0x32, 0xfe, 0x03, 0x31, 0x2d, 0x14, - 0x05, 0x31, 0x1a, 0x03, 0x30, 0x1a, 0x03, 0x2f, 0x2d, 0x14, 0x05, 0x2f, - 0x18, 0x03, 0x2e, 0x09, 0x16, 0x05, 0x2e, 0xbb, 0x03, 0x2d, 0x2c, 0x13, - 0x05, 0x2d, 0x14, 0x03, 0x2d, 0xb8, 0x02, 0x80, 0x40, 0x09, 0x04, 0x2c, - 0x10, 0x11, 0x05, 0x2c, 0x13, 0x03, 0x2c, 0xb8, 0x02, 0x40, 0x40, 0x96, - 0x04, 0x2b, 0x2a, 0x25, 0x05, 0x2b, 0xfe, 0x03, 0x2a, 0x09, 0x16, 0x05, - 0x2a, 0x25, 0x03, 0x29, 0x02, 0x3a, 0x05, 0x29, 0xfe, 0x03, 0x28, 0xfe, - 0x03, 0x27, 0xfe, 0x03, 0x26, 0x0f, 0x03, 0x25, 0x16, 0x42, 0x05, 0x25, - 0x45, 0x03, 0x24, 0x0f, 0x03, 0x23, 0xfe, 0x03, 0x22, 0x0f, 0x0f, 0x05, - 0x22, 0xfe, 0x03, 0x21, 0x20, 0x2d, 0x05, 0x21, 0x7d, 0x03, 0x20, 0x2d, - 0x03, 0x1f, 0x4b, 0x03, 0x1e, 0x11, 0x42, 0x05, 0x1e, 0xfe, 0x03, 0x1d, - 0xfe, 0x03, 0x1c, 0x1b, 0x19, 0x05, 0x1c, 0xfe, 0x03, 0x1b, 0x00, 0x10, - 0x05, 0x1b, 0x19, 0x03, 0x1a, 0xfe, 0x03, 0x19, 0xfe, 0x03, 0x18, 0xfe, - 0x03, 0x17, 0x16, 0x42, 0x05, 0x17, 0x46, 0x03, 0x16, 0x15, 0x2d, 0x05, - 0x16, 0x42, 0x03, 0x15, 0x14, 0x10, 0x05, 0x15, 0x2d, 0x03, 0x14, 0x10, - 0x03, 0x13, 0x00, 0x10, 0x05, 0x13, 0x14, 0x03, 0x12, 0x11, 0x42, 0x05, - 0x12, 0xfe, 0x03, 0x11, 0x01, 0x2d, 0x05, 0x11, 0x42, 0x03, 0x10, 0x0f, - 0x0f, 0x05, 0x10, 0x11, 0x03, 0x10, 0xb8, 0x02, 0x00, 0x40, 0x09, 0x04, - 0x0f, 0x0e, 0x0c, 0x05, 0x0f, 0x0f, 0x03, 0x0f, 0xb8, 0x01, 0xc0, 0x40, - 0x09, 0x04, 0x0e, 0x0d, 0x0a, 0x05, 0x0e, 0x0c, 0x03, 0x0e, 0xb8, 0x01, - 0x80, 0x40, 0x09, 0x04, 0x0d, 0x0c, 0x09, 0x05, 0x0d, 0x0a, 0x03, 0x0d, - 0xb8, 0x01, 0x40, 0xb4, 0x04, 0x0c, 0x09, 0x03, 0x0c, 0xb8, 0x01, 0x00, - 0x40, 0x37, 0x04, 0x0b, 0xfe, 0x03, 0x0a, 0x09, 0x16, 0x05, 0x0a, 0xfe, - 0x03, 0x09, 0x16, 0x03, 0x08, 0x10, 0x03, 0x07, 0xfe, 0x03, 0x06, 0x01, - 0x2d, 0x05, 0x06, 0xfe, 0x03, 0x05, 0x14, 0x03, 0x03, 0x02, 0x3a, 0x05, - 0x03, 0xfa, 0x03, 0x02, 0x01, 0x2d, 0x05, 0x02, 0x3a, 0x03, 0x01, 0x00, - 0x10, 0x05, 0x01, 0x2d, 0x03, 0x00, 0x10, 0x03, 0x01, 0xb8, 0x01, 0x64, - 0x85, 0x8d, 0x01, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x00, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, - 0x2b, 0x2b, 0x1d, 0x00 -}; -unsigned int g_nk_dejavusansmono_ttf_len = 335068; diff --git a/test/test_ui.c b/test/test_ui.c deleted file mode 100644 index 04ac7be..0000000 --- a/test/test_ui.c +++ /dev/null @@ -1,1585 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#define WINDOW_WIDTH 1600 -#define WINDOW_HEIGHT 800 -#define USER_TEXTURES 6 - -#define MAX_VERTEX_BUFFER (1 * MB) -#define MAX_INDEX_BUFFER (256 * KB) - -#define NK_CONTEXT_MEMORY_SIZE (40 * MB) -#define NK_TEXT_CACHE_SIZE (32 * MB) -#define NK_TEXT_TEMPORARY_SIZE (1 * MB) -#define KB_CONTEXT_MEMORY_SIZE (32 * MB) - -#include "arena.h" -#include "builtin.h" -#include "config.h" -#include "globals.h" -#include "input.h" -#include "log.h" -#include "mod_manager.h" -#include "nk_kb_text_shape.h" -#include "nk_font_runtime.h" -#include "path.h" -#include "profiler.h" -#include "scratch.h" -#include "str.h" -#include "types.h" -#include "ui_manager.h" -#include "ui_nuklear.h" - -#include "vendor/nuklear/d3d11/nuklear_d3d11.h" -#include "vendor_stb.h" - -extern int -test_ui_overview(struct nk_context *ctx, unsigned int vw, unsigned int vh); -extern int -test_ui_style_configurator(struct nk_context *ctx, struct nk_color color_table[NK_COLOR_COUNT], unsigned int vw, unsigned int vh); - -static void -test_ui_text_profile(struct nk_context *ctx, unsigned int vw, unsigned int vh) -{ - static const char row[] = - "MovieSceneBuiltInEasingFunction /Game/Hibiki/Blueprints/HUD/SpecialItemGetPopup/LifecoreIcon_UI." - "LifecoreIcon_UI_C.Piece4Get_Anim_INST.Piece4Get_Anim.MovieScenePieceGet_Anim.MovieSceneBuiltInEasingFunction"; - char text[512]; - - if (globals.frame_counter < 60) { - int begin = (int)globals.frame_counter * 700; - int end = begin + 700; - - for (int i = begin; i < end; ++i) { - int len = stbsp_snprintf(text, sizeof(text), "MovieSceneBuiltInEasingFunction /Game/Hibiki/TextCachePressure/Object_%05d", i); - nk_text_width(ctx, ctx->style.font, ctx->style.font->height, text, len); - } - } - - if (nk_begin(ctx, "Text profile", nk_rect(0.0f, 0.0f, (float)vw, (float)vh), 0)) { - int rows = (int)(vh / 20); - for (int i = 0; i < rows; ++i) { - int len = stbsp_snprintf(text, sizeof(text), "%s_%d", row, i); - nk_layout_row_dynamic(ctx, 20.0f, 1); - nk_text(ctx, text, len, NK_TEXT_LEFT); - } - } - nk_end(ctx); -} - -static void -test_ui_text_selection(struct nk_context *ctx, unsigned int vw, unsigned int vh) -{ - static const char *lines[] = { - "office affinity -> ffi fi fl", - "a\xcc\x81 combining mark, emoji \xf0\x9f\x91\xa8\xe2\x80\x8d\xf0\x9f\x8c\xb3", - "\xd8\xa7\xd9\x84\xd8\xb3\xd9\x84\xd8\xa7\xd9\x85 \xd8\xb9\xd9\x84\xd9\x8a\xd9\x83\xd9\x85", - "hello 123 - \xd7\xa9\xd7\x9c\xd7\x95\xd7\x9d - done 456" - }; - static struct nk_text_selection_context selection; - - if (nk_begin(ctx, "Text selection", nk_rect(0, 0, (float)vw, (float)vh), 0)) { - for (int i = 0; i < COUNTOF(lines); ++i) { - nk_layout_row_dynamic(ctx, 24.0f, 1); - if (i == 1) { - nk_label_selectable_colored_ctx(ctx, lines[i], NK_TEXT_LEFT, nk_rgb(255, 190, 120), &selection); - } else { - nk_label_selectable_ctx(ctx, lines[i], NK_TEXT_LEFT, &selection); - } - } - - nk_layout_row_dynamic(ctx, 24.0f, 1); - nk_labelf_selectable_ctx(ctx, NK_TEXT_LEFT, &selection, "Formatted selectable: row %d of %d", 5, 5); - } - nk_end(ctx); -} - -static IDXGISwapChain *swap_chain; -static ID3D11Device *device; -static ID3D11DeviceContext *context; -static ID3D11RenderTargetView *rt_view; - -static void -test_ui_kb_allocator(void *data, kbts_allocator_op *op) -{ - if (op->Kind == KBTS_ALLOCATOR_OP_KIND_ALLOCATE) { - op->Allocate.Pointer = arena_push_aligned(data, op->Allocate.Size, 16); - } -} - -#if 0 -static void -test_ui_text_lines(struct nk_context *ctx, str_t text) -{ - const char *data = (const char *)text.data; - uint64_t line_begin = 0; - - for (uint64_t i = 0; i < text.len; ++i) { - if (text.data[i] == '\n') { - nk_layout_row_dynamic(ctx, 16, 1); - nk_text(ctx, data + line_begin, (int)(i - line_begin), NK_TEXT_LEFT); - line_begin = i + 1; - } - } - - if (line_begin < text.len) { - nk_layout_row_dynamic(ctx, 16, 1); - nk_text(ctx, data + line_begin, (int)(text.len - line_begin), NK_TEXT_LEFT); - } -} - -static void -test_ui_text_shaping(struct nk_context *ctx, struct nk_runtime_fonts *fonts, struct nk_font *utf8_font, int system_font_count, str_t utf8_demo, unsigned int vw, unsigned int vh) -{ - struct nk_font *bold = nk_runtime_font(fonts, NK_RUNTIME_FONT_BOLD); - struct nk_font *italic = nk_runtime_font(fonts, NK_RUNTIME_FONT_ITALIC); - struct nk_font *bold_italic = nk_runtime_font(fonts, NK_RUNTIME_FONT_BOLD_ITALIC); - nk_flags flags = 0; // NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE | NK_WINDOW_MINIMIZABLE NK_WINDOW_TITLE; - - if (nk_begin(ctx, "Text shaping", nk_rect(0, 0, (float)vw, (float)vh), flags)) { - #if 0 - nk_layout_row_dynamic(ctx, 34, 1); - nk_style_push_font_size(ctx, 24.0f); - nk_label(ctx, "Text shaping integration", NK_TEXT_LEFT); - nk_style_pop_font_size(ctx); - - nk_layout_row_dynamic(ctx, 24, 1); - nk_label(ctx, "One face, stackable sizes: 12 / 18 / 28 px", NK_TEXT_LEFT); - { - const float sizes[] = {12.0f, 18.0f, 28.0f}; - for (int i = 0; i < COUNTOF(sizes); ++i) { - nk_layout_row_dynamic(ctx, sizes[i] + 10.0f, 1); - nk_style_push_font_size(ctx, sizes[i]); - nk_label(ctx, "Hamburgefonts office affinity -> ffi fi fl", NK_TEXT_LEFT); - nk_style_pop_font_size(ctx); - } - } - - nk_layout_row_dynamic(ctx, 22, 1); - nk_label(ctx, "Font faces", NK_TEXT_LEFT); - if (bold) { - nk_style_push_font(ctx, &bold->handle); - nk_label(ctx, "Bold: AVATAR office", NK_TEXT_LEFT); - nk_style_pop_font(ctx); - } - - if (italic) { - nk_style_push_font(ctx, &italic->handle); - nk_label(ctx, "Italic: AVATAR office", NK_TEXT_LEFT); - nk_style_pop_font(ctx); - } - - if (bold_italic) { - nk_style_push_font(ctx, &bold_italic->handle); - nk_label(ctx, "Bold italic: AVATAR office", NK_TEXT_LEFT); - nk_style_pop_font(ctx); - } - - nk_layout_row_dynamic(ctx, 22, 1); - nk_label(ctx, "Scripts and automatic direction", NK_TEXT_LEFT); - nk_label(ctx, "Русский: Съешь ещё этих мягких французских булок", NK_TEXT_LEFT); - nk_label(ctx, "Ελληνικά: Καλημέρα κόσμε", NK_TEXT_LEFT); - nk_label(ctx, "العربية: مرحباً بالعالم", NK_TEXT_LEFT); - nk_label(ctx, "עברית: שלום עולם", NK_TEXT_LEFT); - nk_label(ctx, "Mixed bidi: build 123 — مرحباً — done 456", NK_TEXT_LEFT); - - nk_layout_row_dynamic(ctx, 22, 1); - nk_label(ctx, system_font_count ? "System-font fallback" : "System fonts unavailable", NK_TEXT_LEFT); - nk_label(ctx, "日本語: こんにちは世界 中文: 你好世界", NK_TEXT_LEFT); - nk_label(ctx, "Emoji: 😀 🎉 ❤️ Icons:   󰏌", NK_TEXT_LEFT); - #endif - - struct nk_font *consolas = nk_runtime_font(fonts, NK_RUNTIME_FONT_REGULAR); - if (consolas) { - nk_style_push_font(ctx, &consolas->handle); - nk_style_push_font_size(ctx, 16.0f); - } - - static const char *refterm_simple_text[] = { - "[0] The quick brown fox jumped over the lazy dog.", - "[1] السلام عليكم", - "[2] السَّلَامُ عَلَيْكُمْ", - "[3] hello こんにちは 你好 مرحبا שלום မင်္ဂလာပါ 👨‍🍳 👶 👅 👀 ™ 🅱️", - "[4] I love you אני אוהב אותך", - "[5] Ňuňatý, šišatý a žluťoučký koníček s ďolíčkatými tvářemi úpí nad bezútěšností zvůle světa.", - "[6] ﷲ", - "[7] כָּכָה־מָה, וַיֹּאמֶר הַמֶּלֶךְ", - "[8] ∮ E⋅da = Q, n → ∞, ∑ f(i) = ∏ g(i)", - "[9] ๏ แผ่นดินฮั่นเสื่อมโทรมแสนสังเวช พระปกเกศกองบู๊กู้ขึ้นใหม่", - "[10] ╔══╦══╗ ┌──┬──┐ ╭──┬──╮ ╭──┬──╮ ┏━━┳━━┓", - }; - - nk_layout_row_dynamic(ctx, 22, 1); - nk_label(ctx, "refterm simple_text", NK_TEXT_LEFT); - for (int i = 0; i < COUNTOF(refterm_simple_text); ++i) { - nk_label(ctx, refterm_simple_text[i], NK_TEXT_LEFT); - } - - if (consolas) { - nk_style_pop_font_size(ctx); - nk_style_pop_font(ctx); - } - - nk_style_push_font(ctx, &utf8_font->handle); - nk_style_push_font_size(ctx, 16.0f); - nk_style_push_vec2(ctx, &ctx->style.window.spacing, nk_vec2(ctx->style.window.spacing.x, 0.0f)); - test_ui_text_lines(ctx, utf8_demo); - nk_style_pop_vec2(ctx); - nk_style_pop_font_size(ctx); - nk_style_pop_font(ctx); - } - nk_end(ctx); -} -#endif - -static void -set_swap_chain_size(int width, int height) -{ - if (rt_view) { - ID3D11RenderTargetView_Release(rt_view); - } - - ID3D11DeviceContext_OMSetRenderTargets(context, 0, NULL, NULL); - - HRESULT hr = IDXGISwapChain_ResizeBuffers(swap_chain, 0, width, height, DXGI_FORMAT_UNKNOWN, 0); - if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET || hr == DXGI_ERROR_DRIVER_INTERNAL_ERROR) { - MessageBoxW(NULL, L"DXGI device is removed or reset!", L"Error", 0); - exit(0); - } - ASSERT(SUCCEEDED(hr)); - - ID3D11Texture2D *back_buffer = NULL; - D3D11_RENDER_TARGET_VIEW_DESC desc = { - .Format = DXGI_FORMAT_R8G8B8A8_UNORM, - .ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D, - }; - - hr = IDXGISwapChain_GetBuffer(swap_chain, 0, &IID_ID3D11Texture2D, (void **)&back_buffer); - ASSERT(SUCCEEDED(hr)); - - hr = ID3D11Device_CreateRenderTargetView(device, (ID3D11Resource *)back_buffer, &desc, &rt_view); - ASSERT(SUCCEEDED(hr)); - - ID3D11Texture2D_Release(back_buffer); -} - -static struct nk_colorf bg = {.r = 1.0f, .g = 1.0f, .b = 1.0f, .a = 1.0f}; -static int g_width = WINDOW_WIDTH; -static int g_height = WINDOW_HEIGHT; - -static input_mod_flags_t -ui_input_mods_from_win32(void) -{ - input_mod_flags_t mods = 0; - - if (GetKeyState(VK_SHIFT) & 0x8000) { - mods |= INPUT_MOD_SHIFT; - } - - if (GetKeyState(VK_CONTROL) & 0x8000) { - mods |= INPUT_MOD_CTRL; - } - - if (GetKeyState(VK_MENU) & 0x8000) { - mods |= INPUT_MOD_ALT; - } - - return mods; -} - -static input_key_kind_t -ui_input_key_from_vk(WPARAM vk, LPARAM lparam) -{ - switch (vk) { - case 'A': - return INPUT_KEY_A; - case 'B': - return INPUT_KEY_B; - case 'C': - return INPUT_KEY_C; - case 'D': - return INPUT_KEY_D; - case 'E': - return INPUT_KEY_E; - case 'F': - return INPUT_KEY_F; - case 'G': - return INPUT_KEY_G; - case 'H': - return INPUT_KEY_H; - case 'I': - return INPUT_KEY_I; - case 'J': - return INPUT_KEY_J; - case 'K': - return INPUT_KEY_K; - case 'L': - return INPUT_KEY_L; - case 'M': - return INPUT_KEY_M; - case 'N': - return INPUT_KEY_N; - case 'O': - return INPUT_KEY_O; - case 'P': - return INPUT_KEY_P; - case 'Q': - return INPUT_KEY_Q; - case 'R': - return INPUT_KEY_R; - case 'S': - return INPUT_KEY_S; - case 'T': - return INPUT_KEY_T; - case 'U': - return INPUT_KEY_U; - case 'V': - return INPUT_KEY_V; - case 'W': - return INPUT_KEY_W; - case 'X': - return INPUT_KEY_X; - case 'Y': - return INPUT_KEY_Y; - case 'Z': - return INPUT_KEY_Z; - - case '0': - return INPUT_KEY_0; - case '1': - return INPUT_KEY_1; - case '2': - return INPUT_KEY_2; - case '3': - return INPUT_KEY_3; - case '4': - return INPUT_KEY_4; - case '5': - return INPUT_KEY_5; - case '6': - return INPUT_KEY_6; - case '7': - return INPUT_KEY_7; - case '8': - return INPUT_KEY_8; - case '9': - return INPUT_KEY_9; - - case VK_F1: - return INPUT_KEY_F1; - case VK_F2: - return INPUT_KEY_F2; - case VK_F3: - return INPUT_KEY_F3; - case VK_F4: - return INPUT_KEY_F4; - case VK_F5: - return INPUT_KEY_F5; - case VK_F6: - return INPUT_KEY_F6; - case VK_F7: - return INPUT_KEY_F7; - case VK_F8: - return INPUT_KEY_F8; - case VK_F9: - return INPUT_KEY_F9; - case VK_F10: - return INPUT_KEY_F10; - case VK_F11: - return INPUT_KEY_F11; - case VK_F12: - return INPUT_KEY_F12; - - case VK_LEFT: - return INPUT_KEY_LEFT; - case VK_RIGHT: - return INPUT_KEY_RIGHT; - case VK_UP: - return INPUT_KEY_UP; - case VK_DOWN: - return INPUT_KEY_DOWN; - case VK_HOME: - return INPUT_KEY_HOME; - case VK_END: - return INPUT_KEY_END; - case VK_PRIOR: - return INPUT_KEY_PAGE_UP; - case VK_NEXT: - return INPUT_KEY_PAGE_DOWN; - case VK_RETURN: - return INPUT_KEY_ENTER; - case VK_TAB: - return INPUT_KEY_TAB; - case VK_BACK: - return INPUT_KEY_BACKSPACE; - case VK_ESCAPE: - return INPUT_KEY_ESCAPE; - case VK_SPACE: - return INPUT_KEY_SPACE; - case VK_INSERT: - return INPUT_KEY_INSERT; - case VK_DELETE: - return INPUT_KEY_DELETE; - - case VK_OEM_COMMA: - return INPUT_KEY_COMMA; - case VK_OEM_PERIOD: - return INPUT_KEY_PERIOD; - case VK_OEM_2: - return INPUT_KEY_SLASH; - case VK_OEM_1: - return INPUT_KEY_SEMICOLON; - case VK_OEM_7: - return INPUT_KEY_APOSTROPHE; - case VK_OEM_4: - return INPUT_KEY_LEFT_BRACKET; - case VK_OEM_6: - return INPUT_KEY_RIGHT_BRACKET; - case VK_OEM_5: - return INPUT_KEY_BACKSLASH; - case VK_OEM_MINUS: - return INPUT_KEY_HYPHEN; - case VK_OEM_PLUS: - return INPUT_KEY_EQUALS; - case VK_OEM_3: - return INPUT_KEY_BACKTICK; - - case VK_LSHIFT: - return INPUT_KEY_LEFT_SHIFT; - case VK_RSHIFT: - return INPUT_KEY_RIGHT_SHIFT; - case VK_LCONTROL: - return INPUT_KEY_LEFT_CTRL; - case VK_RCONTROL: - return INPUT_KEY_RIGHT_CTRL; - case VK_LMENU: - return INPUT_KEY_LEFT_ALT; - case VK_RMENU: - return INPUT_KEY_RIGHT_ALT; - - case VK_SHIFT: { - UINT sc = (UINT)((lparam >> 16) & 0xFF); - UINT lvk = MapVirtualKeyW(sc, MAPVK_VSC_TO_VK_EX); - return (lvk == VK_RSHIFT) ? INPUT_KEY_RIGHT_SHIFT : INPUT_KEY_LEFT_SHIFT; - } - - case VK_CONTROL: - return ((lparam & (1u << 24)) != 0) ? INPUT_KEY_RIGHT_CTRL : INPUT_KEY_LEFT_CTRL; - - case VK_MENU: - return ((lparam & (1u << 24)) != 0) ? INPUT_KEY_RIGHT_ALT : INPUT_KEY_LEFT_ALT; - } - - return INPUT_KEY_NONE; -} - -static bool -ui_input_event_from_win32(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam, input_event_t *out) -{ - if (!out) { - return false; - } - - mem_zero(out, sizeof(*out)); - out->modifiers = ui_input_mods_from_win32(); - - POINT pt = {0}; - GetCursorPos(&pt); - out->screen_x = (uint32_t)pt.x; - out->screen_y = (uint32_t)pt.y; - - POINT client_pt = pt; - ScreenToClient(wnd, &client_pt); - out->client_x = (uint32_t)client_pt.x; - out->client_y = (uint32_t)client_pt.y; - - switch (msg) { - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - out->kind = INPUT_EVENT_KEY_DOWN; - out->key = ui_input_key_from_vk(wparam, lparam); - out->is_repeat = (((uint32_t)lparam >> 30) & 1) != 0; - return out->key != INPUT_KEY_NONE; - - case WM_KEYUP: - case WM_SYSKEYUP: - out->kind = INPUT_EVENT_KEY_UP; - out->key = ui_input_key_from_vk(wparam, lparam); - out->is_repeat = false; - return out->key != INPUT_KEY_NONE; - - case WM_CHAR: - out->kind = INPUT_EVENT_KEY_CHAR; - out->character = (uint32_t)wparam; - return true; - - case WM_LBUTTONDOWN: - out->kind = INPUT_EVENT_MOUSE_DOWN; - out->key = INPUT_KEY_MOUSE_LEFT; - return true; - - case WM_LBUTTONUP: - out->kind = INPUT_EVENT_MOUSE_UP; - out->key = INPUT_KEY_MOUSE_LEFT; - return true; - - case WM_LBUTTONDBLCLK: - out->kind = INPUT_EVENT_MOUSE_DBLCLICK; - out->key = INPUT_KEY_MOUSE_LEFT; - return true; - - case WM_RBUTTONDBLCLK: - out->kind = INPUT_EVENT_MOUSE_DBLCLICK; - out->key = INPUT_KEY_MOUSE_RIGHT; - return true; - - case WM_RBUTTONDOWN: - out->kind = INPUT_EVENT_MOUSE_DOWN; - out->key = INPUT_KEY_MOUSE_RIGHT; - return true; - - case WM_RBUTTONUP: - out->kind = INPUT_EVENT_MOUSE_UP; - out->key = INPUT_KEY_MOUSE_RIGHT; - return true; - - case WM_MBUTTONDOWN: - out->kind = INPUT_EVENT_MOUSE_DOWN; - out->key = INPUT_KEY_MOUSE_MIDDLE; - return true; - - case WM_MBUTTONUP: - out->kind = INPUT_EVENT_MOUSE_UP; - out->key = INPUT_KEY_MOUSE_MIDDLE; - return true; - - case WM_XBUTTONDOWN: - out->kind = INPUT_EVENT_MOUSE_DOWN; - out->key = (GET_XBUTTON_WPARAM(wparam) == XBUTTON2) ? INPUT_KEY_MOUSE_THUMB_2 : INPUT_KEY_MOUSE_THUMB_1; - return true; - - case WM_XBUTTONUP: - out->kind = INPUT_EVENT_MOUSE_UP; - out->key = (GET_XBUTTON_WPARAM(wparam) == XBUTTON2) ? INPUT_KEY_MOUSE_THUMB_2 : INPUT_KEY_MOUSE_THUMB_1; - return true; - - case WM_MOUSEMOVE: - out->kind = INPUT_EVENT_MOUSE_MOVE; - out->key = INPUT_KEY_MOUSE_X; - out->delta_x = 0.0f; - out->delta_y = 0.0f; - return true; - - case WM_MOUSEWHEEL: { - short delta = (short)HIWORD(wparam); - out->kind = INPUT_EVENT_MOUSE_WHEEL; - out->wheel_delta = (float)delta / (float)WHEEL_DELTA; - out->key = (delta > 0) ? INPUT_KEY_MOUSE_WHEEL_UP : INPUT_KEY_MOUSE_WHEEL_DOWN; - return true; - } - - case WM_MOUSELEAVE: { - out->kind = INPUT_EVENT_APP_ACTIVATION; - out->app_activated = false; - return true; - } - } - - return false; -} - -static void -test_input_key_down(input_key_state_t *key) -{ - if (!key->down) { - key->pressed = true; - } - key->down = true; -} - -static void -test_input_key_up(input_key_state_t *key) -{ - if (key->down) { - key->released = true; - } - key->down = false; -} - -static void -test_input_sync_virtual_modifier(input_key_kind_t key) -{ - input_key_kind_t virt, left, right; - - switch (key) { - case INPUT_KEY_LEFT_CTRL: - case INPUT_KEY_RIGHT_CTRL: - virt = INPUT_KEY_CTRL; - left = INPUT_KEY_LEFT_CTRL; - right = INPUT_KEY_RIGHT_CTRL; - break; - - case INPUT_KEY_LEFT_SHIFT: - case INPUT_KEY_RIGHT_SHIFT: - virt = INPUT_KEY_SHIFT; - left = INPUT_KEY_LEFT_SHIFT; - right = INPUT_KEY_RIGHT_SHIFT; - break; - - case INPUT_KEY_LEFT_ALT: - case INPUT_KEY_RIGHT_ALT: - virt = INPUT_KEY_ALT; - left = INPUT_KEY_LEFT_ALT; - right = INPUT_KEY_RIGHT_ALT; - break; - - default: - return; - } - - input_key_state_t *state = &globals.keys[virt]; - bool down = globals.keys[left].down || globals.keys[right].down; - if (down) { - test_input_key_down(state); - } else { - test_input_key_up(state); - } -} - -static bool -on_input_event(input_event_t *ev) -{ - ASSERT(ev->key < INPUT_KEY_MAX); - - switch (ev->kind) { - case INPUT_EVENT_KEY_DOWN: - case INPUT_EVENT_MOUSE_DOWN: - case INPUT_EVENT_MOUSE_DBLCLICK: { - if (ev->key != INPUT_KEY_NONE) { - test_input_key_down(&globals.keys[ev->key]); - test_input_sync_virtual_modifier(ev->key); - } - break; - } - - case INPUT_EVENT_KEY_UP: - case INPUT_EVENT_MOUSE_UP: { - if (ev->key != INPUT_KEY_NONE) { - test_input_key_up(&globals.keys[ev->key]); - test_input_sync_virtual_modifier(ev->key); - } - break; - } - - case INPUT_EVENT_MOUSE_WHEEL: { - if (ev->wheel_delta > 0.0f) { - globals.keys[INPUT_KEY_MOUSE_WHEEL_UP].pressed = true; - } else if (ev->wheel_delta < 0.0f) { - globals.keys[INPUT_KEY_MOUSE_WHEEL_DOWN].pressed = true; - } - globals.wheel_delta += ev->wheel_delta; - break; - } - - case INPUT_EVENT_APP_ACTIVATION: { - if (!ev->app_activated) { - /* out of focus, all held keys should be released */ - input_key_lost_focus(); - } - break; - } - } - - bool force_consume = false; - if ((ev->kind == INPUT_EVENT_KEY_UP || ev->kind == INPUT_EVENT_MOUSE_UP) && - ev->key != INPUT_KEY_NONE && globals.consumed_down[ev->key]) { - globals.consumed_down[ev->key] = false; - force_consume = true; - } - - bool consumed = false; - const char *consumer = "Engine"; - - if (ui_manager_on_input_event_pre(&globals.ui_manager, globals.frame_counter, ev)) { - consumed = true; - consumer = "UI (pre)"; - } - - if (!consumed && globals.engine_inited && mod_manager_dispatch_input(&globals.mod_manager, ev)) { - consumed = true; - consumer = "Mods"; - } - - if (!consumed && ui_manager_on_input_event_post(&globals.ui_manager, ev)) { - consumed = true; - consumer = "UI (post)"; - } - -#if 0 - if (ev->kind != INPUT_EVENT_MOUSE_MOVE) { - str_t kind_str = input_event_kind_to_str(ev->kind); - if (ev->kind == INPUT_EVENT_KEY_CHAR) { - LOG_WARN("%-10s: kind: %.*s, key: %u", consumer, STR_ARG(kind_str), ev->character); - } else { - LOG_WARN("%-10s: kind: %.*s, key: %.*s", consumer, STR_ARG(kind_str), STR_ARG(input_key_to_str(ev->key))); - } - - bg.r = (rand() % 256) / 255.0f; - bg.g = (rand() % 256) / 255.0f; - bg.b = (rand() % 256) / 255.0f; - } -#else - (void)consumer; -#endif - - if (consumed && - (ev->kind == INPUT_EVENT_KEY_DOWN || ev->kind == INPUT_EVENT_MOUSE_DOWN) && - ev->key != INPUT_KEY_NONE) { - globals.consumed_down[ev->key] = true; - } - - return consumed || force_consume; -} - -static LRESULT CALLBACK -WindowProc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam) -{ - switch (msg) { - case WM_DESTROY: - PostQuitMessage(0); - return 0; - - case WM_SIZE: - if (swap_chain) { - g_width = LOWORD(lparam); - g_height = HIWORD(lparam); - set_swap_chain_size(g_width, g_height); - nk_d3d11_resize(context, g_width, g_height); - } - break; - case WM_MOUSEMOVE: { - TRACKMOUSEEVENT tme = { - .cbSize = sizeof(tme), - .dwFlags = TME_LEAVE, - .hwndTrack = wnd, - }; - TrackMouseEvent(&tme); - break; - } - } - - input_event_t ev = {0}; - if (ui_input_event_from_win32(wnd, msg, wparam, lparam, &ev)) { - if (on_input_event(&ev)) { - // if (ev.kind != INPUT_EVENT_MOUSE_MOVE) { - // LOG_INFO("KIND: %.*s, KEY: %.*s", STR_ARG(input_event_kind_to_str(ev.kind)), - // STR_ARG(input_key_to_str(ev.key))); - // } - return 0; - } - } - - return DefWindowProcW(wnd, msg, wparam, lparam); -} - -static void -ui_seed_test_manager(mod_manager_t *manager) -{ - str_t difficulties[] = { - STR_CLIT("easy"), - STR_CLIT("normal"), - STR_CLIT("insane"), - STR_CLIT("hard"), - STR_CLIT("rhythm_master"), - }; - - str_t camera_modes[] = { - STR_CLIT("tight"), - STR_CLIT("default"), - STR_CLIT("wide"), - }; - - struct { - mod_info_t info; - mod_dll_info_t dll; - mod_asset_info_t asset; - mod_blueprint_info_t blueprints[10]; - int blueprint_count; - mod_option_info_t options[10]; - int option_count; - } entries[] = { - { - .info = - { - .id = STR_CLIT("boss-rush"), - .name = STR_CLIT("Boss RUSH"), - .author = STR_CLIT("akmubi"), - .description = STR_CLIT("Adds a mode where you can fight all the bosses in the game one after another. Replaces Rhythm Tower"), - .kind = MOD_KIND_MOD, - .version = MAKE_VERSION(1, 0, 0), - }, - .dll = - { - .path = STR_CLIT("main.dll"), - }, - .asset = - { - .pak_path = STR_CLIT("assets/BossRUSH.pak"), - .utoc_path = STR_CLIT("assets/BossRUSH.utoc"), - .ucas_path = STR_CLIT("assets/BossRUSH.ucas"), - }, - .blueprint_count = 2, - .blueprints = - { - { - .id = STR_CLIT("boss-rush-main"), - .mod_actor_class_path = STR_CLIT("/Game/BossRUSH/BossRUSHActorMain.BossRUSHActorMain_C"), - .attach_to = MOD_SPAWN_CONTEXT_CUSTOM, - .custom_attach_class_path = STR_CLIT("/Game/Hibiki/HbkPlayerController.HbkPlayerController_C"), - .auto_spawn = true, - }, - { - .id = STR_CLIT("boss-rush-debug-ui"), - .mod_actor_class_path = STR_CLIT("/Game/BossRUSH/BossRUSHActorDebugUI.BossRUSHActorDebugUI_C"), - .attach_to = MOD_SPAWN_CONTEXT_PLAYER_CONTROLLER, - .auto_spawn = false, - .default_spawn_keybind = keybind_parse(STR_LIT("dpad_left+dpad_right"), KEYBIND_NULL), - }, - }, - .option_count = 4, - .options = - { - { - .type = MOD_OPTION_BOOL, - .id = STR_CLIT("include_korsica"), - .label = STR_CLIT("Include Korsica"), - .description = STR_CLIT("Include Korsica boss fight (which is weird)"), - .val.boolean.default_val = true, - }, - { - .type = MOD_OPTION_BOOL, - .id = STR_CLIT("enable_timer"), - .label = STR_CLIT("Enable timer"), - .description = STR_CLIT("Enable in-game timer (from Rhythm Tower)"), - .val.boolean.default_val = false, - }, - { - .type = MOD_OPTION_ENUM, - .id = STR_CLIT("difficulty"), - .label = STR_CLIT("Difficulty"), - .description = STR_CLIT("Difficulty of the boss fights"), - .val.enumeration = - { - .values = - { - .items = difficulties, - .count = COUNTOF(difficulties), - }, - .default_val = STR_CLIT("normal"), - }, - }, - { - .type = MOD_OPTION_BOOL, - .id = STR_CLIT("enable_score"), - .label = STR_CLIT("Enable score"), - .description = STR_CLIT("Enable default scoring system from Rhythm Tower"), - .val.boolean.default_val = false, - }, - }, - }, - { - .info = - { - .id = STR_CLIT("no-tutorials"), - .name = STR_CLIT("No tutorials"), - .author = STR_CLIT("akmubi"), - .description = STR_CLIT("Disable tutorial popups and some sequences."), - .kind = MOD_KIND_MOD, - .version = MAKE_VERSION(1, 2, 0), - }, - .dll = - { - .path = STR_CLIT("main.dll"), - }, - .option_count = 5, - .options = - { - { - .type = MOD_OPTION_BOOL, - .id = STR_CLIT("enabled"), - .label = STR_CLIT("Enabled"), - .description = STR_CLIT("Enable camera override."), - .val.boolean.default_val = true, - }, - { - .type = MOD_OPTION_INT, - .id = STR_CLIT("fov"), - .label = STR_CLIT("Camera FOV"), - .description = STR_CLIT("Vertical field of view."), - .val.integer = {.default_val = 82, .min_val = 60, .max_val = 130, .step = 1}, - }, - { - .type = MOD_OPTION_FLOAT, - .id = STR_CLIT("sensitivity"), - .label = STR_CLIT("Sensitivity"), - .description = STR_CLIT("Camera sensitivity multiplier."), - .val.floating = {.default_val = 1.15f, .min_val = 0.10f, .max_val = 3.0f, .step = 0.05f}, - }, - { - .type = MOD_OPTION_ENUM, - .id = STR_CLIT("mode"), - .label = STR_CLIT("Mode"), - .description = STR_CLIT("Camera framing mode."), - .val.enumeration = - { - .values = {.items = camera_modes, .count = COUNTOF(camera_modes)}, - .default_val = STR_CLIT("default"), - }, - }, - { - .type = MOD_OPTION_COLOR, - .id = STR_CLIT("debug_color"), - .label = STR_CLIT("Debug color"), - .description = STR_CLIT("Debug draw color."), - .val.color.default_val = {255, 64, 64, 255}, - }, - }, - }, -#if 0 - { - .info = - { - .id = STR_CLIT("hd-texture-pack"), - .name = STR_CLIT("HD Texture Pack"), - .author = STR_CLIT("art-team"), - .description = STR_CLIT("Assets-only pack used to exercise mount state and ordering."), - .kind = MOD_KIND_MOD, - .version = MAKE_VERSION(2, 0, 1), - }, - .asset = - { - .pak_path = STR_CLIT("assets/HDTexturePack.pak"), - .utoc_path = STR_CLIT("assets/HDTexturePack.utoc"), - .ucas_path = STR_CLIT("assets/HDTexturePack.ucas"), - }, - }, - { - .info = - { - .id = STR_CLIT("combo-meter-plus"), - .name = STR_CLIT("Combo Meter Plus"), - .author = STR_CLIT("akmubi"), - .description = STR_CLIT("UI/gameplay mod with code, assets and a few editor-friendly options."), - .kind = MOD_KIND_MOD, - .version = MAKE_VERSION(0, 9, 4), - }, - .dll = - { - .path = STR_CLIT("combo_meter.dll"), - }, - .asset = - { - .pak_path = STR_CLIT("assets/ComboMeterPlus.pak"), - .utoc_path = STR_CLIT("assets/ComboMeterPlus.utoc"), - .ucas_path = STR_CLIT("assets/ComboMeterPlus.ucas"), - }, - .option_count = 4, - .options = - { - { - .type = MOD_OPTION_BOOL, - .id = STR_CLIT("show_hit_sparks"), - .label = STR_CLIT("Show hit sparks"), - .description = STR_CLIT("Enable extra UI hit spark effects."), - .boolean.default_val = true, - }, - { - .type = MOD_OPTION_INT, - .id = STR_CLIT("meter_scale"), - .label = STR_CLIT("Meter scale"), - .description = STR_CLIT("UI scale percent."), - .integer = {.default_val = 100, .min_val = 50, .max_val = 200, .step = 5}, - }, - { - .type = MOD_OPTION_ENUM, - .id = STR_CLIT("meter_style"), - .label = STR_CLIT("Meter style"), - .description = STR_CLIT("Visual style of the combo meter."), - .enumeration = - { - .values = {.items = meter_styles, .count = COUNTOF(meter_styles)}, - .default_val = STR_CLIT("arcade"), - }, - }, - { - .type = MOD_OPTION_STRING, - .id = STR_CLIT("profile_name"), - .label = STR_CLIT("Profile"), - .description = STR_CLIT("Preset name."), - .string.default_val = STR_CLIT("Default"), - }, - }, - }, - { - .info = - { - .id = STR_CLIT("object-browser"), - .name = STR_CLIT("Object Browser"), - .author = STR_CLIT("akmubi"), - .description = STR_CLIT("Inspection-oriented tool with code-backed UI only.\n" - "\n" - "Test.\n"), - .kind = MOD_KIND_TOOL, - .version = MAKE_VERSION(0, 2, 1), - }, - .dll = - { - .path = STR_CLIT("object_browser.dll"), - }, - }, - { - .info = - { - .id = STR_CLIT("training-room-plus"), - .name = STR_CLIT("Training Room Plus"), - .author = STR_CLIT("someone"), - .description = STR_CLIT("Blueprint-heavy gameplay mod with spawnable helpers."), - .kind = MOD_KIND_MOD, - .version = MAKE_VERSION(0, 3, 0), - }, - .asset = - { - .pak_path = STR_CLIT("assets/TrainingRoomPlus.pak"), - .utoc_path = STR_CLIT("assets/TrainingRoomPlus.utoc"), - .ucas_path = STR_CLIT("assets/TrainingRoomPlus.ucas"), - }, - .blueprint_count = 2, - .blueprints = - { - { - .id = STR_CLIT("training-room-main"), - .mod_actor_class_path = STR_CLIT("/Game/TRP/BP_TrainingRoomMain.BP_TrainingRoomMain_C"), - .attach_to = MOD_SPAWN_CONTEXT_WORLD, - .auto_spawn = true, - }, - { - .id = STR_CLIT("training-room-helper"), - .mod_actor_class_path = STR_CLIT("/Game/TRP/BP_TrainingRoomHelper.BP_TrainingRoomHelper_C"), - .attach_to = MOD_SPAWN_CONTEXT_PLAYER_CONTROLLER, - .auto_spawn = false, - .default_spawn_keybind = keybind_parse(STR_LIT("f7"), KEYBIND_NULL), - }, - }, - }, -#endif - }; - - for (int i = 0; i < COUNTOF(entries); ++i) { - mod_manifest_t manifest = { - .mod_dir = STR_NULL, - .manifest_path = STR_NULL, - .config_path = STR_NULL, - .info = entries[i].info, - .dll = entries[i].dll, - .asset = entries[i].asset, - .blueprints = entries[i].blueprints, - .blueprint_count = entries[i].blueprint_count, - .options = entries[i].options, - .option_count = entries[i].option_count, - }; - - mod_handle_t h = mod_register(manager, &manifest); - ASSERT(h != MOD_HANDLE_INVALID); - } -} - -typedef enum { - UOBJECT_KIND_UNKNOWN = 0, - UOBJECT_KIND_CDO, - UOBJECT_KIND_CLASS, - UOBJECT_KIND_STRUCT, - UOBJECT_KIND_ENUM, - UOBJECT_KIND_FUNC, - UOBJECT_KIND_PACKAGE, - UOBJECT_KIND_MAX, -} uobject_kind_t; - -static struct nk_color -uobject_kind_color(uobject_kind_t kind) -{ - switch (kind) { - case UOBJECT_KIND_CDO: - return nk_rgb(181, 192, 201); - case UOBJECT_KIND_CLASS: - return nk_rgb(0, 191, 255); - case UOBJECT_KIND_STRUCT: - return nk_rgb(255, 215, 0); - case UOBJECT_KIND_ENUM: - return nk_rgb(76, 175, 80); - case UOBJECT_KIND_FUNC: - return nk_rgb(255, 79, 0); - case UOBJECT_KIND_PACKAGE: - return nk_rgb(255, 64, 129); - case UOBJECT_KIND_UNKNOWN: - default: - return nk_rgb(222, 226, 230); - } -} - -static str_t -uobject_kind_to_str(uobject_kind_t kind) -{ - switch (kind) { - case UOBJECT_KIND_CDO: - return STR_LIT("CDO"); - case UOBJECT_KIND_CLASS: - return STR_LIT("Class"); - case UOBJECT_KIND_STRUCT: - return STR_LIT("Struct"); - case UOBJECT_KIND_ENUM: - return STR_LIT("Enum"); - case UOBJECT_KIND_FUNC: - return STR_LIT("Function"); - case UOBJECT_KIND_PACKAGE: - return STR_LIT("Package"); - case UOBJECT_KIND_UNKNOWN: - return STR_LIT("Instance/Other"); - default: - return STR_LIT("-"); - } -} - -static void -ui_tabs(struct nk_context *ctx, const char *group_name, str_t tab_names[], int tab_count, int *selected_idx, int *closed_idx) -{ - ASSERT(ctx != NULL); - ASSERT(group_name != NULL && group_name[0] != '\0'); - - if (!tab_names || tab_count == 0) { - return; - } - - if (closed_idx) { - *closed_idx = -1; - } - - nk_style_push_vec2(ctx, &ctx->style.scrollh.padding, nk_vec2(0.0f, 0.0f)); - nk_style_push_vec2(ctx, &ctx->style.window.group_padding, nk_vec2(0.0f, 0.0f)); - nk_style_push_vec2(ctx, &ctx->style.window.spacing, nk_vec2(0.0f, 0.0f)); - nk_style_push_float(ctx, &ctx->style.button.rounding, 0.0f); - nk_style_push_style_item(ctx, &ctx->style.button.normal, ctx->style.property.normal); - nk_style_push_style_item(ctx, &ctx->style.button.hover, ctx->style.property.hover); - nk_style_push_style_item(ctx, &ctx->style.button.active, ctx->style.property.active); - nk_style_push_color(ctx, &ctx->style.button.border_color, ctx->style.property.border_color); - - tmp_arena_t tmp = scratch_begin(NULL); - { - float *widths = ARENA_PUSH_ARRAY(tmp.arena, float, tab_count); - ASSERT(widths != NULL); - - float tab_h = 18.0f; - float text_pad = 4.0f; - float group_pad_y = ctx->style.window.group_padding.y; - float group_pad_x = ctx->style.window.group_padding.x; - float scroll_h = ctx->style.window.scrollbar_size.y; - - float button_pad = ctx->style.button.padding.x + ctx->style.button.border; - float x_width = ui_text_width(ctx, STR_LIT("X")) + 2.0f * button_pad; - - float total_width = 0.0f; - for (int i = 0; i < tab_count; ++i) { - widths[i] = ui_text_width(ctx, tab_names[i]) + 2.0f * (text_pad + button_pad); - total_width += widths[i] + x_width; - } - - float max_content_width = nk_window_get_content_region_size(ctx).x; - float total_content_width = total_width + 2.0f * group_pad_x; - - bool has_scrollbar = (total_content_width > max_content_width); - - float total_h = group_pad_y + tab_h + group_pad_y + (has_scrollbar)*scroll_h; - nk_flags group_flags = (has_scrollbar) ? NK_WINDOW_NO_SCROLLBAR_V : NK_WINDOW_NO_SCROLLBAR; - - nk_layout_row_dynamic(ctx, total_h, 1); - - if (nk_group_begin(ctx, group_name, group_flags)) { - nk_layout_row_begin(ctx, NK_STATIC, tab_h, tab_count * 2); - { - for (int i = 0; i < tab_count; ++i) { - nk_layout_row_push(ctx, widths[i]); - bool is_selected = (selected_idx) ? (*selected_idx == i) : false; - - if (is_selected) { - nk_style_push_style_item(ctx, &ctx->style.button.normal, UI_ITEM(UI_C_ACCENT)); - nk_style_push_style_item(ctx, &ctx->style.button.hover, UI_ITEM(UI_C_ACCENT_HOVER)); - nk_style_push_style_item(ctx, &ctx->style.button.active, UI_ITEM(UI_C_ACCENT_ACTIVE)); - nk_style_push_color(ctx, &ctx->style.button.border_color, UI_C_BORDER_FOCUS); - } - - if (ui_button_str(ctx, tab_names[i])) { - if (selected_idx) { - *selected_idx = i; - } - } - - nk_layout_row_push(ctx, x_width); - if (nk_button_symbol(ctx, NK_SYMBOL_X)) { - if (closed_idx) { - *closed_idx = i; - } - } - - if (is_selected) { - nk_style_pop_color(ctx); - nk_style_pop_style_item(ctx); - nk_style_pop_style_item(ctx); - nk_style_pop_style_item(ctx); - } - } - } - nk_layout_row_end(ctx); - nk_group_end(ctx); - } - } - scratch_end(tmp); - - nk_style_pop_color(ctx); - nk_style_pop_style_item(ctx); - nk_style_pop_style_item(ctx); - nk_style_pop_style_item(ctx); - nk_style_pop_float(ctx); - nk_style_pop_vec2(ctx); - nk_style_pop_vec2(ctx); - nk_style_pop_vec2(ctx); -} - -static void -draw_test_window(struct nk_context *ctx) -{ - float width = (float)NK_MAX(0, g_width - (g_width / 10)); - float height = (float)NK_MAX(0, g_height - (g_height / 10)); - - nk_flags flags = NK_WINDOW_BORDER | NK_WINDOW_TITLE | NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE | NK_WINDOW_MINIMIZABLE; - struct nk_rect bounds = nk_rect((g_width - width) * 0.5f, (g_height - height) * 0.5f, width, height); - const char *name = "Test Window"; - - if (nk_begin(ctx, name, bounds, flags)) { - // static arena_t arenas[64]; - static uint64_t cap = 8; - static str_array_t tabs = {0}; - - if (!tabs.items) { - // needs to be initialized and allocated from tool's arena - tabs.items = ARENA_PUSH_ARRAY_ZERO(&globals.perm, str_t, cap); - tabs.count = 0; - } - - static int current_tab = 0; - - struct nk_input *in = NULL; - if (!(ctx->current->layout->flags & NK_WINDOW_ROM) && !(ctx->current->layout->flags & NK_WINDOW_NO_INPUT) && ui_nk_current_panel_accepts_input(ctx)) { - in = &ctx->input; - } - - if (in) { - if (tabs.count > 0 && nk_input_is_key_pressed(in, NK_KEY_TAB)) { - if (in->keyboard.keys[NK_KEY_SHIFT].down) { - current_tab = (current_tab == 0) ? (int)tabs.count - 1 : current_tab - 1; - } else { - current_tab = (current_tab + 1) % tabs.count; - } - } - - str_t text = str_from_cstr_with_cap(in->keyboard.text, in->keyboard.text_len); - if (str_equal(text, STR_LIT("+"), 0)) { - // when new tab is created, are new dedicated arena should be created - - if (tabs.count < cap) { - tabs.items[tabs.count] = str_push_fmt(&globals.perm, "Tab-%llu", tabs.count + 1); - tabs.count += 1; - } - } - - if (str_equal(text, STR_LIT("-"), 0)) { - // when the tab is closed the respective arena should be destroyed - - if ((uint64_t)current_tab < tabs.count) { - for (uint64_t i = current_tab; i < tabs.count - 1; ++i) { - tabs.items[i] = tabs.items[i + 1]; - } - tabs.count -= 1; - } - } - } - - int closed_tab = -1; - ui_tabs(ctx, "test.tabs", tabs.items, (int)tabs.count, ¤t_tab, &closed_tab); - - if (closed_tab >= 0 && (uint64_t)closed_tab < tabs.count) { - for (uint64_t i = closed_tab; i < tabs.count - 1; ++i) { - tabs.items[i] = tabs.items[i + 1]; - } - tabs.count -= 1; - } - - if (tabs.count > 0 && (uint64_t)current_tab >= tabs.count) { - current_tab = (int)tabs.count - 1; - } - } - nk_end(ctx); -} - -int -main(int argc, char **argv) -{ - (void)argc; - (void)argv; - - globals.perm = arena_new_dynamic(CONFIG_PERM_ARENA_SIZE, 64 * KB); - globals.module = GetModuleHandleW(NULL); - globals.game_dir = path_module_dir(&globals.perm); - - log_init(STR_LIT(CONFIG_LOG_FILE_NAME), CONFIG_LOG_LEVEL, false); - bool text_profile = GetEnvironmentVariableA("OVERDUB_TEXT_PROFILE", NULL, 0) != 0; - bool text_selection_test = GetEnvironmentVariableA("OVERDUB_TEXT_SELECTION_TEST", NULL, 0) != 0; - - WNDCLASSW wc = { - .style = CS_DBLCLKS, - .lpfnWndProc = WindowProc, - .hInstance = GetModuleHandleW(0), - .hIcon = LoadIcon(NULL, IDI_APPLICATION), - .hCursor = LoadCursor(NULL, IDC_ARROW), - .lpszClassName = L"NuklearWindowClass", - }; - RegisterClassW(&wc); - - RECT rect = {0, 0, WINDOW_WIDTH, WINDOW_HEIGHT}; - DWORD style = WS_OVERLAPPEDWINDOW; - DWORD exstyle = WS_EX_APPWINDOW; - - AdjustWindowRectEx(&rect, style, FALSE, exstyle); - HWND wnd = CreateWindowExW(exstyle, - wc.lpszClassName, - L"Nuklear Direct3D 11 Demo", - style | WS_VISIBLE, - CW_USEDEFAULT, - CW_USEDEFAULT, - rect.right - rect.left, - rect.bottom - rect.top, - NULL, - NULL, - wc.hInstance, - NULL); - - D3D_FEATURE_LEVEL feature_level = {0}; - DXGI_SWAP_CHAIN_DESC swap_chain_desc = { - .BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM, - .BufferDesc.RefreshRate.Numerator = 180, - .BufferDesc.RefreshRate.Denominator = 1, - .SampleDesc.Count = 1, - .SampleDesc.Quality = 0, - .BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT, - .BufferCount = 1, - .OutputWindow = wnd, - .Windowed = TRUE, - .SwapEffect = DXGI_SWAP_EFFECT_DISCARD, - .Flags = 0, - }; - - if (FAILED(D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &swap_chain_desc, &swap_chain, &device, &feature_level, &context))) { - HRESULT hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_WARP, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &swap_chain_desc, &swap_chain, &device, &feature_level, &context); - ASSERT(SUCCEEDED(hr)); - } - set_swap_chain_size(WINDOW_WIDTH, WINDOW_HEIGHT); - - void *nk_memory = arena_push_aligned(&globals.perm, NK_CONTEXT_MEMORY_SIZE, 16); - struct nk_context *ctx = nk_d3d11_init_fixed(device, WINDOW_WIDTH, WINDOW_HEIGHT, MAX_VERTEX_BUFFER, MAX_INDEX_BUFFER, nk_memory, NK_CONTEXT_MEMORY_SIZE, NK_TEXT_CACHE_SIZE); - ASSERT(ctx != NULL); - - static const struct { - const char *name; - enum nk_runtime_font_style style; - } system_fonts[] = { - {"consola.ttf", NK_RUNTIME_FONT_REGULAR}, - {"consolab.ttf", NK_RUNTIME_FONT_BOLD}, - {"consolai.ttf", NK_RUNTIME_FONT_ITALIC}, - {"consolaz.ttf", NK_RUNTIME_FONT_BOLD_ITALIC}, - {"segoeui.ttf", NK_RUNTIME_FONT_FALLBACK}, - {"seguisym.ttf", NK_RUNTIME_FONT_FALLBACK}, - }; - struct nk_runtime_font_source font_sources[COUNTOF(system_fonts)]; - int font_source_count = 0; - - for (int i = 0; i < COUNTOF(system_fonts); ++i) { - if (nk_runtime_font_source_system(&font_sources[font_source_count], &globals.perm, system_fonts[i].name, system_fonts[i].style)) { - font_source_count += 1; - } else if (i == 0) { - MASSERT(false, "failed to load the Consolas system font"); - } - } - - struct nk_runtime_fonts fonts = {0}; - tmp_arena_t font_tmp = scratch_begin(NULL); - { - MASSERT(nk_runtime_fonts_bake(&fonts, &globals.perm, font_tmp.arena, font_sources, font_source_count, CONFIG_NK_FONT_SIZE), "failed to bake font atlas"); - nk_d3d11_setup_fonts(&fonts); - } - scratch_end(font_tmp); - - void *kb_context_memory = arena_push_aligned(&globals.perm, KB_CONTEXT_MEMORY_SIZE, 16); - void *text_temporary_memory = arena_push_aligned(&globals.perm, NK_TEXT_TEMPORARY_SIZE, 16); - kbts_shape_context *kb_context = kbts_PlaceShapeContextFixedMemory(kb_context_memory, KB_CONTEXT_MEMORY_SIZE); - kbts_font kb_font_data[NK_RUNTIME_FONT_CAPACITY]; - kbts_font *kb_fonts[NK_RUNTIME_FONT_CAPACITY]; - struct nk_buffer text_temporary; - struct nk_kb_text_backend kb_backend; - struct nk_text_backend text_backend = {0}; - - ASSERT(kb_context != NULL); - - for (int i = 0; i < fonts.face_count; ++i) { - struct nk_runtime_font_face *face = &fonts.faces[i]; - kb_font_data[i] = kbts_FontFromMemory(face->ttf, (int)face->ttf_size, 0, test_ui_kb_allocator, &globals.perm); - kb_font_data[i].UserData = &face->font->handle; - kb_fonts[i] = &kb_font_data[i]; - ASSERT(kbts_FontIsValid(&kb_font_data[i])); - } - - nk_buffer_init_fixed(&text_temporary, text_temporary_memory, NK_TEXT_TEMPORARY_SIZE); - kb_backend.context = kb_context; - kb_backend.fonts = kb_fonts; - kb_backend.temporary = &text_temporary; - kb_backend.num_fonts = fonts.face_count; - text_backend.userdata.ptr = &kb_backend; - text_backend.build = nk_kb_text_shape_build; - text_backend.temporary = &text_temporary; - nk_text_backend_set(ctx, &text_backend); - - nk_style_set_font(ctx, &fonts.faces[0].font->handle); - - mod_manager_init(&globals.mod_manager, globals.game_dir); - mod_manager_startup_load_cfg(&globals.mod_manager); - { - register_builtin_uobject_search(&globals.mod_manager); - register_builtin_ufunction_tracer(&globals.mod_manager); - register_builtin_tweaks(&globals.mod_manager); - - ui_seed_test_manager(&globals.mod_manager); - } - mod_manager_startup_load_mods(&globals.mod_manager); - - ui_manager_preinit(&globals.ui_manager, &globals.mod_manager, &globals.perm); - ui_manager_init(&globals.ui_manager, ctx, fonts.faces[0].font, g_width, g_height); - - // ui_mod_manager_open(&globals.ui_manager.main); - if (GetEnvironmentVariableA("OVERDUB_CONSOLE_TEST", NULL, 0)) { - ui_console_open(&globals.ui_manager.console); - } - - globals.ui_manager.main.selected = (globals.mod_manager.mod_order.want[0]); - - tmp_arena_t tmp = scratch_begin(NULL); - { - LOG_DEBUG("overlay: '%.*s'", STR_ARG(keybind_to_str(globals.mod_manager.cfg.overlay_toggle, tmp.arena))); - LOG_DEBUG("console: '%.*s'", STR_ARG(keybind_to_str(globals.ui_manager.console.cfg.toggle_bind, tmp.arena))); - } - scratch_end(tmp); - - if (GetEnvironmentVariableA("OVERDUB_CONSOLE_TEST", NULL, 0)) { - LOG_INFO("Wrapped selection test: this deliberately long console entry should wrap across multiple visual lines while remaining one logical string when selected and copied. Soft wrapping must not insert line breaks into the clipboard text, and dragging may continue into the next console entry."); - LOG_WARN("Second selectable console entry: drag here to verify that one persistent selection can span multiple wrapped widgets."); - } - - mod_manager_start_dlls(&globals.mod_manager); - globals.engine_inited = true; - - uint64_t frame_time_prev = time_now_us(); - int running = 1; - while (running) { - uint64_t frame_time_now = time_now_us(); - float delta = (float)(frame_time_now - frame_time_prev) / 1000000.0f; - - MSG msg; - nk_input_begin(ctx); - globals.ui_manager.input_begun = true; - globals.ui_manager.input_frame = globals.frame_counter; - - while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) { - if (msg.message == WM_QUIT) { - running = 0; - } - TranslateMessage(&msg); - DispatchMessageW(&msg); - } - nk_input_end(ctx); - globals.ui_manager.input_begun = false; - - if (keybind_is_pressed(keybind_parse(STR_LIT("Ctrl+C"), KEYBIND_NULL))) { - LOG_DEBUG("delta: %g\n\n\nTEST\nTEST", delta); - } - - if (delta > 0.00001f) { - float fps = 1.0f / delta; - if (globals.fps <= 0.0f) { - globals.fps = fps; - } else { - globals.fps += (fps - globals.fps) * 0.10f; - } - } - - mod_manager_dispatch_tick(&globals.mod_manager, delta); - - ui_manager_on_frame_end(&globals.ui_manager, g_width, g_height); - - if (text_profile) { - PROF_SCOPE_BEGIN("test_ui.text_rows", text_rows); - test_ui_text_profile(ctx, g_width, g_height); - PROF_SCOPE_END(text_rows); - } else if (text_selection_test) { - test_ui_text_selection(ctx, g_width, g_height); - } else { - test_ui_overview(ctx, g_width, g_height); - } - - ID3D11DeviceContext_ClearRenderTargetView(context, rt_view, &bg.r); - ID3D11DeviceContext_OMSetRenderTargets(context, 1, &rt_view, NULL); - PROF_SCOPE_BEGIN("test_ui.render", render); - nk_d3d11_render(context, NK_ANTI_ALIASING_ON); - PROF_SCOPE_END(render); - HRESULT hr = IDXGISwapChain_Present(swap_chain, 1, 0); - if (hr == DXGI_ERROR_DEVICE_RESET || hr == DXGI_ERROR_DEVICE_REMOVED) { - MessageBoxW(NULL, L"D3D11 device is lost or removed!", L"Error", 0); - break; - } else if (hr == DXGI_STATUS_OCCLUDED) { - Sleep(10); - } - ASSERT(SUCCEEDED(hr)); - - scratch_reset(); - if (text_profile && globals.frame_counter == 60) { - profiler_reset(); - } else if (text_profile && globals.frame_counter == 360) { - profiler_log_report(); - running = 0; - } - globals.frame_counter += 1; - input_key_clear_transient_state(); - - frame_time_prev = frame_time_now; - } - - ID3D11DeviceContext_ClearState(context); - nk_d3d11_shutdown(); - ID3D11RenderTargetView_Release(rt_view); - ID3D11DeviceContext_Release(context); - ID3D11Device_Release(device); - IDXGISwapChain_Release(swap_chain); - UnregisterClassW(wc.lpszClassName, wc.hInstance); - return 0; -} diff --git a/test/test_ui_overview.c b/test/test_ui_overview.c deleted file mode 100644 index d0692fe..0000000 --- a/test/test_ui_overview.c +++ /dev/null @@ -1,1522 +0,0 @@ -#include "vendor_nuklear.h" -#include "vendor_stb.h" - -#include /* INT_MAX */ -#include -#include /* struct tm, localtime */ - -int -test_ui_overview(struct nk_context *ctx, unsigned int viewport_width, unsigned int viewport_height) -{ - /* window flags */ - static nk_bool show_menu = nk_true; - static nk_flags window_flags = NK_WINDOW_TITLE | NK_WINDOW_BORDER | NK_WINDOW_SCALABLE | NK_WINDOW_MOVABLE | - NK_WINDOW_MINIMIZABLE | NK_WINDOW_SCROLL_AUTO_HIDE; - nk_flags actual_window_flags = 0; - - /* widget flags */ - static nk_bool disable_widgets = nk_false; - - /* popups */ - static enum nk_style_header_align header_align = NK_HEADER_RIGHT; - static nk_bool show_app_about = nk_false; - - /* window flags */ - ctx->style.window.header.align = header_align; - - actual_window_flags = window_flags; - if (!(actual_window_flags & NK_WINDOW_TITLE)) { - actual_window_flags &= ~(NK_WINDOW_MINIMIZABLE | NK_WINDOW_CLOSABLE); - } - - const char *name = "overview"; - struct nk_rect bounds = {0}; - struct nk_window *win = nk_window_find(ctx, name); - if (win) { - bounds = win->bounds; - } - - char title[256] = {0}; - stbsp_snprintf(title, sizeof(title), "Overview (%.1f, %.1f) %.1fx%.1f", bounds.x, bounds.y, bounds.w, bounds.h); - - if (nk_begin_titled(ctx, name, title, nk_rect(0, 0, viewport_width / 2.0f, (float)viewport_height), actual_window_flags)) { - if (show_menu) { - /* menubar */ - enum menu_states { MENU_DEFAULT, MENU_WINDOWS }; - static nk_size mprog = 60; - static int mslider = 10; - static nk_bool mcheck = nk_true; - nk_menubar_begin(ctx); - - /* menu #1 */ - nk_layout_row_begin(ctx, NK_STATIC, 25, 5); - nk_layout_row_push(ctx, 45); - if (nk_menu_begin_label(ctx, "MENU", NK_TEXT_LEFT, nk_vec2(120, 200))) { - static size_t prog = 40; - static int slider = 10; - static nk_bool check = nk_true; - nk_layout_row_dynamic(ctx, 25, 1); - if (nk_menu_item_label(ctx, "Hide", NK_TEXT_LEFT)) { - show_menu = nk_false; - } - if (nk_menu_item_label(ctx, "About", NK_TEXT_LEFT)) { - show_app_about = nk_true; - } - nk_progress(ctx, &prog, 100, NK_MODIFIABLE); - nk_slider_int(ctx, 0, &slider, 16, 1); - nk_checkbox_label(ctx, "check", &check); - nk_menu_end(ctx); - } - /* menu #2 */ - float advanced_width = nk_text_width(ctx, ctx->style.font, ctx->style.font_size, "ADVANCED", 8); - advanced_width += 2 * ctx->style.menu_button.padding.x + 2 * ctx->style.menu_button.border; - nk_layout_row_push(ctx, advanced_width); - if (nk_menu_begin_label(ctx, "ADVANCED", NK_TEXT_LEFT, nk_vec2(200, 600))) { - enum menu_state { MENU_NONE, MENU_FILE, MENU_EDIT, MENU_VIEW, MENU_CHART }; - static enum menu_state menu_state = MENU_NONE; - enum nk_collapse_states state; - - state = (menu_state == MENU_FILE) ? NK_MAXIMIZED : NK_MINIMIZED; - if (nk_tree_state_push(ctx, NK_TREE_TAB, "FILE", &state)) { - menu_state = MENU_FILE; - nk_menu_item_label(ctx, "New", NK_TEXT_LEFT); - nk_menu_item_label(ctx, "Open", NK_TEXT_LEFT); - nk_menu_item_label(ctx, "Save", NK_TEXT_LEFT); - nk_menu_item_label(ctx, "Close", NK_TEXT_LEFT); - nk_menu_item_label(ctx, "Exit", NK_TEXT_LEFT); - nk_tree_pop(ctx); - } else { - menu_state = (menu_state == MENU_FILE) ? MENU_NONE : menu_state; - } - - state = (menu_state == MENU_EDIT) ? NK_MAXIMIZED : NK_MINIMIZED; - if (nk_tree_state_push(ctx, NK_TREE_TAB, "EDIT", &state)) { - menu_state = MENU_EDIT; - nk_menu_item_label(ctx, "Copy", NK_TEXT_LEFT); - nk_menu_item_label(ctx, "Delete", NK_TEXT_LEFT); - nk_menu_item_label(ctx, "Cut", NK_TEXT_LEFT); - nk_menu_item_label(ctx, "Paste", NK_TEXT_LEFT); - nk_tree_pop(ctx); - } else { - menu_state = (menu_state == MENU_EDIT) ? MENU_NONE : menu_state; - } - - state = (menu_state == MENU_VIEW) ? NK_MAXIMIZED : NK_MINIMIZED; - if (nk_tree_state_push(ctx, NK_TREE_TAB, "VIEW", &state)) { - menu_state = MENU_VIEW; - nk_menu_item_label(ctx, "About", NK_TEXT_LEFT); - nk_menu_item_label(ctx, "Options", NK_TEXT_LEFT); - nk_menu_item_label(ctx, "Customize", NK_TEXT_LEFT); - nk_tree_pop(ctx); - } else { - menu_state = (menu_state == MENU_VIEW) ? MENU_NONE : menu_state; - } - - state = (menu_state == MENU_CHART) ? NK_MAXIMIZED : NK_MINIMIZED; - if (nk_tree_state_push(ctx, NK_TREE_TAB, "CHART", &state)) { - size_t i = 0; - const float values[] = {26.0f, 13.0f, 30.0f, 15.0f, 25.0f, 10.0f, 20.0f, 40.0f, 12.0f, 8.0f, 22.0f, 28.0f}; - menu_state = MENU_CHART; - nk_layout_row_dynamic(ctx, 150, 1); - nk_chart_begin(ctx, NK_CHART_COLUMN, NK_LEN(values), 0, 50); - for (i = 0; i < NK_LEN(values); ++i) { - nk_chart_push(ctx, values[i]); - } - nk_chart_end(ctx); - nk_tree_pop(ctx); - } else { - menu_state = (menu_state == MENU_CHART) ? MENU_NONE : menu_state; - } - nk_menu_end(ctx); - } - /* menu widgets */ - nk_layout_row_push(ctx, 70); - nk_progress(ctx, &mprog, 100, NK_MODIFIABLE); - nk_slider_int(ctx, 0, &mslider, 16, 1); - nk_checkbox_label(ctx, "check", &mcheck); - nk_menubar_end(ctx); - } - - if (show_app_about) { - /* about popup */ - static struct nk_rect s = {20, 100, 300, 190}; - if (nk_popup_begin(ctx, NK_POPUP_STATIC, "About", NK_WINDOW_CLOSABLE, s)) { - nk_layout_row_dynamic(ctx, 20, 1); - nk_label(ctx, "Nuklear", NK_TEXT_LEFT); - nk_label(ctx, "By Micha Mettke", NK_TEXT_LEFT); - nk_label(ctx, "nuklear is licensed under the public domain License.", NK_TEXT_LEFT); - nk_popup_end(ctx); - } else { - show_app_about = nk_false; - } - } - - /* window flags */ - if (nk_tree_push(ctx, NK_TREE_TAB, "Window", NK_MAXIMIZED)) { - nk_layout_row_dynamic(ctx, 30, 2); - nk_checkbox_label(ctx, "Menu", &show_menu); - nk_checkbox_flags_label(ctx, "Titlebar", &window_flags, NK_WINDOW_TITLE); - nk_checkbox_flags_label(ctx, "Border", &window_flags, NK_WINDOW_BORDER); - nk_checkbox_flags_label(ctx, "Resizable", &window_flags, NK_WINDOW_SCALABLE); - nk_checkbox_flags_label(ctx, "Movable", &window_flags, NK_WINDOW_MOVABLE); - nk_checkbox_flags_label(ctx, "No Scrollbar", &window_flags, NK_WINDOW_NO_SCROLLBAR); - nk_checkbox_flags_label(ctx, "Minimizable", &window_flags, NK_WINDOW_MINIMIZABLE); - nk_checkbox_flags_label(ctx, "Scale Left", &window_flags, NK_WINDOW_SCALE_LEFT); - nk_checkbox_label(ctx, "Disable widgets", &disable_widgets); - nk_tree_pop(ctx); - } - - if (disable_widgets) { - nk_widget_disable_begin(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Widgets", NK_MAXIMIZED)) { - enum options { A, B, C }; - static nk_bool checkbox_left_text_left; - static nk_bool checkbox_centered_text_right; - static nk_bool checkbox_right_text_right; - static nk_bool checkbox_right_text_left; - static int option_left; - static int option_right; - if (nk_tree_push(ctx, NK_TREE_NODE, "Text", NK_MAXIMIZED)) { - /* Text Widgets */ - nk_layout_row_dynamic(ctx, 20, 1); - nk_label(ctx, "Label aligned left", NK_TEXT_LEFT); - nk_label(ctx, "Label aligned centered", NK_TEXT_CENTERED); - nk_label(ctx, "Label aligned right", NK_TEXT_RIGHT); - nk_label_colored(ctx, "Blue text", NK_TEXT_LEFT, nk_rgb(0, 0, 255)); - nk_label_colored(ctx, "Yellow text", NK_TEXT_LEFT, nk_rgb(255, 255, 0)); - nk_text(ctx, "Text without /0", 15, NK_TEXT_RIGHT); - - nk_layout_row_static(ctx, 100, 200, 1); - nk_label_wrap(ctx, - "This is a very long line to hopefully get this text to be wrapped into multiple lines to show " - "line wrapping"); - nk_layout_row_dynamic(ctx, 100, 1); - nk_label_wrap(ctx, "This is another long text to show dynamic window changes on multiline text"); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_NODE, "Button", NK_MAXIMIZED)) { - /* Buttons Widgets */ - nk_layout_row_static(ctx, 30, 100, 3); - if (nk_button_label(ctx, "Button")) { - fprintf(stdout, "Button pressed!\n"); - } - nk_button_set_behavior(ctx, NK_BUTTON_REPEATER); - if (nk_button_label(ctx, "Repeater")) { - fprintf(stdout, "Repeater is being pressed!\n"); - } - nk_button_set_behavior(ctx, NK_BUTTON_DEFAULT); - nk_button_color(ctx, nk_rgb(0, 0, 255)); - - nk_layout_row_static(ctx, 25, 25, 8); - nk_button_symbol(ctx, NK_SYMBOL_CIRCLE_SOLID); - nk_button_symbol(ctx, NK_SYMBOL_CIRCLE_OUTLINE); - nk_button_symbol(ctx, NK_SYMBOL_RECT_SOLID); - nk_button_symbol(ctx, NK_SYMBOL_RECT_OUTLINE); - nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_UP); - nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_UP_OUTLINE); - nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_DOWN); - nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_DOWN_OUTLINE); - nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_LEFT); - nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_LEFT_OUTLINE); - nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_RIGHT); - nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_RIGHT_OUTLINE); - - nk_layout_row_static(ctx, 30, 100, 2); - nk_button_symbol_label(ctx, NK_SYMBOL_TRIANGLE_LEFT, "prev", NK_TEXT_RIGHT); - nk_button_symbol_label(ctx, NK_SYMBOL_TRIANGLE_RIGHT, "next", NK_TEXT_LEFT); - - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_NODE, "Basic", NK_MAXIMIZED)) { - /* Basic widgets */ - static int int_slider = 5; - static float float_slider = 2.5f; - static int int_knob = 5; - static float float_knob = 2.5f; - static nk_size prog_value = 40; - static float property_float = 2; - static int property_int = 10; - static int property_neg = 10; - - static float range_float_min = 0; - static float range_float_max = 100; - static float range_float_value = 50; - static int range_int_min = 0; - static int range_int_value = 2048; - static int range_int_max = 4096; - static const float ratio[] = {120, 150}; - static int range_int_value_hidden = 2048; - - nk_layout_row_dynamic(ctx, 0, 1); - nk_checkbox_label(ctx, "CheckLeft TextLeft", &checkbox_left_text_left); - nk_checkbox_label_align(ctx, - "CheckCenter TextRight", - &checkbox_centered_text_right, - NK_WIDGET_ALIGN_CENTERED | NK_WIDGET_ALIGN_MIDDLE, - NK_TEXT_RIGHT); - nk_checkbox_label_align(ctx, "CheckRight TextRight", &checkbox_right_text_right, NK_WIDGET_LEFT, NK_TEXT_RIGHT); - nk_checkbox_label_align(ctx, "CheckRight TextLeft", &checkbox_right_text_left, NK_WIDGET_RIGHT, NK_TEXT_LEFT); - - nk_layout_row_static(ctx, 30, 80, 3); - option_left = nk_option_label(ctx, "optionA", option_left == A) ? A : option_left; - option_left = nk_option_label(ctx, "optionB", option_left == B) ? B : option_left; - option_left = nk_option_label(ctx, "optionC", option_left == C) ? C : option_left; - - nk_layout_row_static(ctx, 30, 80, 3); - option_right = - nk_option_label_align(ctx, "optionA", option_right == A, NK_WIDGET_RIGHT, NK_TEXT_RIGHT) ? A : option_right; - option_right = - nk_option_label_align(ctx, "optionB", option_right == B, NK_WIDGET_RIGHT, NK_TEXT_RIGHT) ? B : option_right; - option_right = - nk_option_label_align(ctx, "optionC", option_right == C, NK_WIDGET_RIGHT, NK_TEXT_RIGHT) ? C : option_right; - - nk_layout_row(ctx, NK_STATIC, 30, 2, ratio); - nk_labelf(ctx, NK_TEXT_LEFT, "Slider int"); - nk_slider_int(ctx, 0, &int_slider, 10, 1); - - nk_label(ctx, "Slider float", NK_TEXT_LEFT); - nk_slider_float(ctx, 0, &float_slider, 5.0, 0.5f); - nk_labelf(ctx, NK_TEXT_LEFT, "Progressbar: %u", (int)prog_value); - nk_progress(ctx, &prog_value, 100, NK_MODIFIABLE); - - nk_layout_row(ctx, NK_STATIC, 40, 2, ratio); - nk_labelf(ctx, NK_TEXT_LEFT, "Knob int: %d", int_knob); - nk_knob_int(ctx, 0, &int_knob, 10, 1, NK_DOWN, 60.0f); - nk_labelf(ctx, NK_TEXT_LEFT, "Knob float: %.2f", float_knob); - nk_knob_float(ctx, 0, &float_knob, 5.0, 0.5f, NK_DOWN, 60.0f); - - nk_layout_row(ctx, NK_STATIC, 25, 2, ratio); - nk_label(ctx, "Property float:", NK_TEXT_LEFT); - nk_property_float(ctx, "Float:", 0, &property_float, 64.0f, 0.1f, 0.2f); - nk_label(ctx, "Property int:", NK_TEXT_LEFT); - nk_property_int(ctx, "Int:", 0, &property_int, 100, 1, 1); - nk_label(ctx, "Property neg:", NK_TEXT_LEFT); - nk_property_int(ctx, "Neg:", -10, &property_neg, 10, 1, 1); - - nk_layout_row_dynamic(ctx, 25, 1); - nk_label(ctx, "Range:", NK_TEXT_LEFT); - nk_layout_row_dynamic(ctx, 25, 3); - nk_property_float(ctx, "#min:", 0, &range_float_min, range_float_max, 1.0f, 0.2f); - nk_property_float(ctx, "#float:", range_float_min, &range_float_value, range_float_max, 1.0f, 0.2f); - nk_property_float(ctx, "#max:", range_float_min, &range_float_max, 100, 1.0f, 0.2f); - - nk_property_int(ctx, "#min:", INT_MIN, &range_int_min, range_int_max, 1, 10); - nk_property_int(ctx, "#neg:", range_int_min, &range_int_value, range_int_max, 1, 10); - nk_property_int(ctx, "#max:", range_int_min, &range_int_max, INT_MAX, 1, 10); - - nk_layout_row_dynamic(ctx, 0, 2); - nk_label(ctx, "Hidden Label:", NK_TEXT_LEFT); - nk_property_int(ctx, "##Hidden Label", range_int_min, &range_int_value_hidden, INT_MAX, 1, 10); - - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_NODE, "Inactive", NK_MAXIMIZED)) { - static nk_bool inactive = 1; - nk_layout_row_dynamic(ctx, 30, 1); - nk_checkbox_label(ctx, "Inactive", &inactive); - - nk_layout_row_static(ctx, 30, 80, 1); - if (inactive) { - nk_widget_disable_begin(ctx); - } - - if (nk_button_label(ctx, "button")) { - fprintf(stdout, "button pressed\n"); - } - - nk_widget_disable_end(ctx); - - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_NODE, "Selectable", NK_MAXIMIZED)) { - if (nk_tree_push(ctx, NK_TREE_NODE, "List", NK_MAXIMIZED)) { - static nk_bool selected[4] = {nk_false, nk_false, nk_true, nk_false}; - nk_layout_row_static(ctx, 18, 100, 1); - nk_selectable_label(ctx, "Selectable", NK_TEXT_LEFT, &selected[0]); - nk_selectable_label(ctx, "Selectable", NK_TEXT_LEFT, &selected[1]); - nk_label(ctx, "Not Selectable", NK_TEXT_LEFT); - nk_selectable_label(ctx, "Selectable", NK_TEXT_LEFT, &selected[2]); - nk_selectable_label(ctx, "Selectable", NK_TEXT_LEFT, &selected[3]); - nk_tree_pop(ctx); - } - if (nk_tree_push(ctx, NK_TREE_NODE, "Grid", NK_MAXIMIZED)) { - int i; - static nk_bool selected[16] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; - nk_layout_row_static(ctx, 50, 50, 4); - for (i = 0; i < 16; ++i) { - if (nk_selectable_label(ctx, "Z", NK_TEXT_CENTERED, &selected[i])) { - int x = (i % 4), y = i / 4; - if (x > 0) { - selected[i - 1] ^= 1; - } - if (x < 3) { - selected[i + 1] ^= 1; - } - if (y > 0) { - selected[i - 4] ^= 1; - } - if (y < 3) { - selected[i + 4] ^= 1; - } - } - } - nk_tree_pop(ctx); - } - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_NODE, "Combo", NK_MAXIMIZED)) { - /* Combobox Widgets - * In this library comboboxes are not limited to being a popup - * list of selectable text. Instead it is a abstract concept of - * having something that is *selected* or displayed, a popup window - * which opens if something needs to be modified and the content - * of the popup which causes the *selected* or displayed value to - * change or if wanted close the combobox. - * - * While strange at first handling comboboxes in a abstract way - * solves the problem of overloaded window content. For example - * changing a color value requires 4 value modifier (slider, property,...) - * for RGBA then you need a label and ways to display the current color. - * If you want to go fancy you even add rgb and hsv ratio boxes. - * While fine for one color if you have a lot of them it because - * tedious to look at and quite wasteful in space. You could add - * a popup which modifies the color but this does not solve the - * fact that it still requires a lot of cluttered space to do. - * - * In these kind of instance abstract comboboxes are quite handy. All - * value modifiers are hidden inside the combobox popup and only - * the color is shown if not open. This combines the clarity of the - * popup with the ease of use of just using the space for modifiers. - * - * Other instances are for example time and especially date picker, - * which only show the currently activated time/data and hide the - * selection logic inside the combobox popup. - */ - static float chart_selection = 8.0f; - static int current_weapon = 0; - static nk_bool check_values[5]; - static float position[3]; - static struct nk_color combo_color = {130, 50, 50, 255}; - static struct nk_colorf combo_color2 = {0.509f, 0.705f, 0.2f, 1.0f}; - static size_t prog_a = 20, prog_b = 40, prog_c = 10, prog_d = 90; - static const char *weapons[] = {"Fist", "Pistol", "Shotgun", "Plasma", "BFG"}; - - char buffer[64]; - size_t sum = 0; - - /* default combobox */ - nk_layout_row_static(ctx, 25, 200, 1); - current_weapon = nk_combo(ctx, weapons, NK_LEN(weapons), current_weapon, 25, nk_vec2(200, 200)); - - /* slider color combobox */ - if (nk_combo_begin_color(ctx, combo_color, nk_vec2(200, 200))) { - float ratios[] = {0.15f, 0.85f}; - nk_layout_row(ctx, NK_DYNAMIC, 30, 2, ratios); - nk_label(ctx, "R:", NK_TEXT_LEFT); - combo_color.r = (nk_byte)nk_slide_int(ctx, 0, combo_color.r, 255, 5); - nk_label(ctx, "G:", NK_TEXT_LEFT); - combo_color.g = (nk_byte)nk_slide_int(ctx, 0, combo_color.g, 255, 5); - nk_label(ctx, "B:", NK_TEXT_LEFT); - combo_color.b = (nk_byte)nk_slide_int(ctx, 0, combo_color.b, 255, 5); - nk_label(ctx, "A:", NK_TEXT_LEFT); - combo_color.a = (nk_byte)nk_slide_int(ctx, 0, combo_color.a, 255, 5); - nk_combo_end(ctx); - } - /* complex color combobox */ - if (nk_combo_begin_color(ctx, nk_rgb_cf(combo_color2), nk_vec2(200, 400))) { - enum color_mode { COL_RGB, COL_HSV }; - static int col_mode = COL_RGB; -#ifndef DEMO_DO_NOT_USE_COLOR_PICKER - nk_layout_row_dynamic(ctx, 120, 1); - combo_color2 = nk_color_picker(ctx, combo_color2, NK_RGBA); -#endif - - nk_layout_row_dynamic(ctx, 25, 2); - col_mode = nk_option_label(ctx, "RGB", col_mode == COL_RGB) ? COL_RGB : col_mode; - col_mode = nk_option_label(ctx, "HSV", col_mode == COL_HSV) ? COL_HSV : col_mode; - - nk_layout_row_dynamic(ctx, 25, 1); - if (col_mode == COL_RGB) { - combo_color2.r = nk_propertyf(ctx, "#R:", 0, combo_color2.r, 1.0f, 0.01f, 0.005f); - combo_color2.g = nk_propertyf(ctx, "#G:", 0, combo_color2.g, 1.0f, 0.01f, 0.005f); - combo_color2.b = nk_propertyf(ctx, "#B:", 0, combo_color2.b, 1.0f, 0.01f, 0.005f); - combo_color2.a = nk_propertyf(ctx, "#A:", 0, combo_color2.a, 1.0f, 0.01f, 0.005f); - } else { - float hsva[4]; - nk_colorf_hsva_fv(hsva, combo_color2); - hsva[0] = nk_propertyf(ctx, "#H:", 0, hsva[0], 1.0f, 0.01f, 0.05f); - hsva[1] = nk_propertyf(ctx, "#S:", 0, hsva[1], 1.0f, 0.01f, 0.05f); - hsva[2] = nk_propertyf(ctx, "#V:", 0, hsva[2], 1.0f, 0.01f, 0.05f); - hsva[3] = nk_propertyf(ctx, "#A:", 0, hsva[3], 1.0f, 0.01f, 0.05f); - combo_color2 = nk_hsva_colorfv(hsva); - } - nk_combo_end(ctx); - } - /* progressbar combobox */ - sum = prog_a + prog_b + prog_c + prog_d; - sprintf(buffer, "%llu", sum); - if (nk_combo_begin_label(ctx, buffer, nk_vec2(200, 200))) { - nk_layout_row_dynamic(ctx, 30, 1); - nk_progress(ctx, &prog_a, 100, NK_MODIFIABLE); - nk_progress(ctx, &prog_b, 100, NK_MODIFIABLE); - nk_progress(ctx, &prog_c, 100, NK_MODIFIABLE); - nk_progress(ctx, &prog_d, 100, NK_MODIFIABLE); - nk_combo_end(ctx); - } - - /* checkbox combobox */ - sum = (size_t)(check_values[0] + check_values[1] + check_values[2] + check_values[3] + check_values[4]); - sprintf(buffer, "%llu", sum); - if (nk_combo_begin_label(ctx, buffer, nk_vec2(200, 200))) { - nk_layout_row_dynamic(ctx, 30, 1); - nk_checkbox_label(ctx, weapons[0], &check_values[0]); - nk_checkbox_label(ctx, weapons[1], &check_values[1]); - nk_checkbox_label(ctx, weapons[2], &check_values[2]); - nk_checkbox_label(ctx, weapons[3], &check_values[3]); - nk_combo_end(ctx); - } - - /* complex text combobox */ - sprintf(buffer, "%.2f, %.2f, %.2f", position[0], position[1], position[2]); - if (nk_combo_begin_label(ctx, buffer, nk_vec2(200, 200))) { - nk_layout_row_dynamic(ctx, 25, 1); - nk_property_float(ctx, "#X:", -1024.0f, &position[0], 1024.0f, 1, 0.5f); - nk_property_float(ctx, "#Y:", -1024.0f, &position[1], 1024.0f, 1, 0.5f); - nk_property_float(ctx, "#Z:", -1024.0f, &position[2], 1024.0f, 1, 0.5f); - nk_combo_end(ctx); - } - - /* chart combobox */ - sprintf(buffer, "%.1f", chart_selection); - if (nk_combo_begin_label(ctx, buffer, nk_vec2(200, 250))) { - size_t i = 0; - static const float values[] = { - 26.0f, 13.0f, 30.0f, 15.0f, 25.0f, 10.0f, 20.0f, 40.0f, 12.0f, 8.0f, 22.0f, 28.0f, 5.0f}; - nk_layout_row_dynamic(ctx, 150, 1); - nk_chart_begin(ctx, NK_CHART_COLUMN, NK_LEN(values), 0, 50); - for (i = 0; i < NK_LEN(values); ++i) { - nk_flags res = nk_chart_push(ctx, values[i]); - if (res & NK_CHART_CLICKED) { - chart_selection = values[i]; - nk_combo_close(ctx); - } - } - nk_chart_end(ctx); - nk_combo_end(ctx); - } - - { - static int time_selected = 0; - static int date_selected = 0; - static struct tm sel_time; - static struct tm sel_date; - if (!time_selected || !date_selected) { - /* keep time and date updated if nothing is selected */ - time_t cur_time = time(0); - struct tm *n = localtime(&cur_time); - if (!time_selected) { - memcpy(&sel_time, n, sizeof(struct tm)); - } - if (!date_selected) { - memcpy(&sel_date, n, sizeof(struct tm)); - } - } - - /* time combobox */ - sprintf(buffer, "%02d:%02d:%02d", sel_time.tm_hour, sel_time.tm_min, sel_time.tm_sec); - if (nk_combo_begin_label(ctx, buffer, nk_vec2(200, 250))) { - time_selected = 1; - nk_layout_row_dynamic(ctx, 25, 1); - sel_time.tm_sec = nk_propertyi(ctx, "#S:", 0, sel_time.tm_sec, 60, 1, 1); - sel_time.tm_min = nk_propertyi(ctx, "#M:", 0, sel_time.tm_min, 60, 1, 1); - sel_time.tm_hour = nk_propertyi(ctx, "#H:", 0, sel_time.tm_hour, 23, 1, 1); - nk_combo_end(ctx); - } - - /* date combobox */ - sprintf(buffer, "%02d-%02d-%02d", sel_date.tm_mday, sel_date.tm_mon + 1, sel_date.tm_year + 1900); - if (nk_combo_begin_label(ctx, buffer, nk_vec2(350, 400))) { - int i = 0; - const char *month[] = {"January", - "February", - "March", - "April", - "May", - "June", - "July", - "August", - "September", - "October", - "November", - "December"}; - const char *week_days[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"}; - const int month_days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - int year = sel_date.tm_year + 1900; - int leap_year = (!(year % 4) && ((year % 100))) || !(year % 400); - int days = (sel_date.tm_mon == 1) ? month_days[sel_date.tm_mon] + leap_year : month_days[sel_date.tm_mon]; - - /* header with month and year */ - date_selected = 1; - nk_layout_row_begin(ctx, NK_DYNAMIC, 20, 3); - nk_layout_row_push(ctx, 0.05f); - if (nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_LEFT)) { - if (sel_date.tm_mon == 0) { - sel_date.tm_mon = 11; - sel_date.tm_year = NK_MAX(0, sel_date.tm_year - 1); - } else { - sel_date.tm_mon--; - } - } - nk_layout_row_push(ctx, 0.9f); - sprintf(buffer, "%s %d", month[sel_date.tm_mon], year); - nk_label(ctx, buffer, NK_TEXT_CENTERED); - nk_layout_row_push(ctx, 0.05f); - if (nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_RIGHT)) { - if (sel_date.tm_mon == 11) { - sel_date.tm_mon = 0; - sel_date.tm_year++; - } else { - sel_date.tm_mon++; - } - } - nk_layout_row_end(ctx); - - /* good old week day formula (double because precision) */ - { - int year_n = (sel_date.tm_mon < 2) ? year - 1 : year; - int y = year_n % 100; - int c = year_n / 100; - int y4 = (int)((float)y / 4); - int c4 = (int)((float)c / 4); - int m = (int)(2.6 * (double)(((sel_date.tm_mon + 10) % 12) + 1) - 0.2); - int week_day = (((1 + m + y + y4 + c4 - 2 * c) % 7) + 7) % 7; - - /* weekdays */ - nk_layout_row_dynamic(ctx, 35, 7); - for (i = 0; i < (int)NK_LEN(week_days); ++i) { - nk_label(ctx, week_days[i], NK_TEXT_CENTERED); - } - - /* days */ - if (week_day > 0) { - nk_spacing(ctx, week_day); - } - for (i = 1; i <= days; ++i) { - sprintf(buffer, "%d", i); - if (nk_button_label(ctx, buffer)) { - sel_date.tm_mday = i; - nk_combo_close(ctx); - } - } - } - nk_combo_end(ctx); - } - } - - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_NODE, "Input", NK_MAXIMIZED)) { - static const float ratio[] = {120, 150}; - static char field_buffer[64]; - static char field_w_overwrite_buf[64]; - static char text[9][64]; - static int text_len[9]; - static char box_buffer[512]; - static int field_len; - static int field_ow_len; - static int box_len; - nk_flags active; - nk_flags edit_flags; - - nk_layout_row(ctx, NK_STATIC, 25, 2, ratio); - nk_label(ctx, "Default:", NK_TEXT_LEFT); - - nk_edit_string(ctx, NK_EDIT_SIMPLE, text[0], &text_len[0], 64, nk_filter_default); - nk_label(ctx, "Int:", NK_TEXT_LEFT); - nk_edit_string(ctx, NK_EDIT_SIMPLE, text[1], &text_len[1], 64, nk_filter_decimal); - nk_label(ctx, "Float:", NK_TEXT_LEFT); - nk_edit_string(ctx, NK_EDIT_SIMPLE, text[2], &text_len[2], 64, nk_filter_float); - nk_label(ctx, "Hex:", NK_TEXT_LEFT); - nk_edit_string(ctx, NK_EDIT_SIMPLE, text[4], &text_len[4], 64, nk_filter_hex); - nk_label(ctx, "Octal:", NK_TEXT_LEFT); - nk_edit_string(ctx, NK_EDIT_SIMPLE, text[5], &text_len[5], 64, nk_filter_oct); - nk_label(ctx, "Binary:", NK_TEXT_LEFT); - nk_edit_string(ctx, NK_EDIT_SIMPLE, text[6], &text_len[6], 64, nk_filter_binary); - - nk_label(ctx, "Password:", NK_TEXT_LEFT); - { - int i = 0; - int old_len = text_len[8]; - char buffer[64]; - for (i = 0; i < text_len[8]; ++i) { - buffer[i] = '*'; - } - nk_edit_string(ctx, NK_EDIT_FIELD, buffer, &text_len[8], 64, nk_filter_default); - if (old_len < text_len[8]) { - memcpy(&text[8][old_len], &buffer[old_len], (nk_size)(text_len[8] - old_len)); - } - } - - nk_label(ctx, "Field:", NK_TEXT_LEFT); - nk_edit_string(ctx, NK_EDIT_FIELD, field_buffer, &field_len, 64, nk_filter_default); - - nk_label(ctx, "Field 2:", NK_TEXT_LEFT); - nk_edit_string( - ctx, NK_EDIT_SELECTABLE | NK_EDIT_CLIPBOARD, field_w_overwrite_buf, &field_ow_len, 64, nk_filter_default); - - nk_label(ctx, "Box:", NK_TEXT_LEFT); - nk_layout_row_static(ctx, 180, 278, 1); - nk_edit_string(ctx, NK_EDIT_BOX, box_buffer, &box_len, 512, nk_filter_default); - - nk_layout_row(ctx, NK_STATIC, 25, 2, ratio); - edit_flags = (nk_flags)NK_EDIT_FIELD | (nk_flags)NK_EDIT_SIG_ENTER; - active = nk_edit_string(ctx, edit_flags, text[7], &text_len[7], 64, nk_filter_ascii); - if (nk_button_label(ctx, "Submit") || (active & NK_EDIT_COMMITED)) { - text[7][text_len[7]] = '\n'; - text_len[7]++; - memcpy(&box_buffer[box_len], &text[7], (nk_size)text_len[7]); - box_len += text_len[7]; - text_len[7] = 0; - } - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_NODE, "Horizontal Rule", NK_MAXIMIZED)) { - nk_layout_row_dynamic(ctx, 12, 1); - nk_label(ctx, "Use this to subdivide spaces visually", NK_TEXT_LEFT); - nk_layout_row_dynamic(ctx, 4, 1); - nk_rule_horizontal(ctx, nk_white, nk_true); - nk_layout_row_dynamic(ctx, 75, 1); - nk_label_wrap(ctx, - "Best used in 'Card'-like layouts, with a bigger title font on top. Takes on the size of the " - "previous layout definition. Rounding optional."); - nk_tree_pop(ctx); - } - - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Chart", NK_MAXIMIZED)) { - /* Chart Widgets - * This library has two different rather simple charts. The line and the - * column chart. Both provide a simple way of visualizing values and - * have a retained mode and immediate mode API version. For the retain - * mode version `nk_plot` and `nk_plot_function` you either provide - * an array or a callback to call to handle drawing the graph. - * For the immediate mode version you start by calling `nk_chart_begin` - * and need to provide min and max values for scaling on the Y-axis. - * and then call `nk_chart_push` to push values into the chart. - * Finally `nk_chart_end` needs to be called to end the process. */ - float id = 0; - static int col_index = -1; - static int line_index = -1; - static nk_bool show_markers = nk_true; - float step = (2 * 3.141592654f) / 32; - - int i; - int index = -1; - - /* line chart */ - id = 0; - index = -1; - nk_layout_row_dynamic(ctx, 15, 1); - nk_checkbox_label(ctx, "Show markers", &show_markers); - nk_layout_row_dynamic(ctx, 100, 1); - ctx->style.chart.show_markers = show_markers; - if (nk_chart_begin(ctx, NK_CHART_LINES, 32, -1.0f, 1.0f)) { - for (i = 0; i < 32; ++i) { - nk_flags res = nk_chart_push(ctx, (float)NK_COS(id)); - if (res & NK_CHART_HOVERING) { - index = (int)i; - } - if (res & NK_CHART_CLICKED) { - line_index = (int)i; - } - id += step; - } - nk_chart_end(ctx); - } - - if (index != -1) { - nk_tooltipf(ctx, "Value: %.2f", (float)NK_COS((float)index * step)); - } - if (line_index != -1) { - nk_layout_row_dynamic(ctx, 20, 1); - nk_labelf(ctx, NK_TEXT_LEFT, "Selected value: %.2f", (float)NK_COS((float)index * step)); - } - - /* column chart */ - nk_layout_row_dynamic(ctx, 100, 1); - if (nk_chart_begin(ctx, NK_CHART_COLUMN, 32, 0.0f, 1.0f)) { - - for (i = 0, id = 0; i < 32; ++i) { - nk_flags res = nk_chart_push(ctx, (float)NK_ABS(NK_SIN(id))); - if (res & NK_CHART_HOVERING) { - index = (int)i; - } - if (res & NK_CHART_CLICKED) { - col_index = (int)i; - } - id += step; - } - nk_chart_end(ctx); - } - if (index != -1) { - nk_tooltipf(ctx, "Value: %.2f", (float)NK_ABS(NK_SIN(step * (float)index))); - } - if (col_index != -1) { - nk_layout_row_dynamic(ctx, 20, 1); - nk_labelf(ctx, NK_TEXT_LEFT, "Selected value: %.2f", (float)NK_ABS(NK_SIN(step * (float)col_index))); - } - nk_layout_row_dynamic(ctx, 20, 1); - - /* mixed chart */ - nk_layout_row_dynamic(ctx, 100, 1); - if (nk_chart_begin(ctx, NK_CHART_COLUMN, 32, 0.0f, 1.0f)) { - nk_chart_add_slot(ctx, NK_CHART_LINES, 32, -1.0f, 1.0f); - nk_chart_add_slot(ctx, NK_CHART_LINES, 32, -1.0f, 1.0f); - for (id = 0, i = 0; i < 32; ++i) { - nk_chart_push_slot(ctx, (float)NK_ABS(NK_SIN(id)), 0); - nk_chart_push_slot(ctx, (float)NK_COS(id), 1); - nk_chart_push_slot(ctx, (float)NK_SIN(id), 2); - id += step; - } - } - nk_chart_end(ctx); - - /* mixed colored chart */ - nk_layout_row_dynamic(ctx, 100, 1); - if (nk_chart_begin_colored(ctx, NK_CHART_LINES, nk_rgb(255, 0, 0), nk_rgb(150, 0, 0), 32, 0.0f, 1.0f)) { - nk_chart_add_slot_colored(ctx, NK_CHART_LINES, nk_rgb(0, 0, 255), nk_rgb(0, 0, 150), 32, -1.0f, 1.0f); - nk_chart_add_slot_colored(ctx, NK_CHART_LINES, nk_rgb(0, 255, 0), nk_rgb(0, 150, 0), 32, -1.0f, 1.0f); - for (id = 0, i = 0; i < 32; ++i) { - nk_chart_push_slot(ctx, (float)NK_ABS(NK_SIN(id)), 0); - nk_chart_push_slot(ctx, (float)NK_COS(id), 1); - nk_chart_push_slot(ctx, (float)NK_SIN(id), 2); - id += step; - } - } - nk_chart_end(ctx); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Popup", NK_MAXIMIZED)) { - static struct nk_color color = {255, 0, 0, 255}; - static nk_bool select[4]; - static nk_bool popup_active; - const struct nk_input *in = &ctx->input; - struct nk_rect bounds; - - /* menu contextual */ - nk_layout_row_static(ctx, 30, 160, 1); - bounds = nk_widget_bounds(ctx); - nk_label(ctx, "Right click me for menu", NK_TEXT_LEFT); - - if (nk_contextual_begin(ctx, 0, nk_vec2(100, 300), bounds)) { - static size_t prog = 40; - static int slider = 10; - - nk_layout_row_dynamic(ctx, 25, 1); - nk_checkbox_label(ctx, "Menu", &show_menu); - nk_progress(ctx, &prog, 100, NK_MODIFIABLE); - nk_slider_int(ctx, 0, &slider, 16, 1); - if (nk_contextual_item_label(ctx, "About", NK_TEXT_CENTERED)) { - show_app_about = nk_true; - } - nk_selectable_label(ctx, select[0] ? "Unselect" : "Select", NK_TEXT_LEFT, &select[0]); - nk_selectable_label(ctx, select[1] ? "Unselect" : "Select", NK_TEXT_LEFT, &select[1]); - nk_selectable_label(ctx, select[2] ? "Unselect" : "Select", NK_TEXT_LEFT, &select[2]); - nk_selectable_label(ctx, select[3] ? "Unselect" : "Select", NK_TEXT_LEFT, &select[3]); - nk_contextual_end(ctx); - } - - /* color contextual */ - nk_layout_row_begin(ctx, NK_STATIC, 30, 2); - nk_layout_row_push(ctx, 120); - nk_label(ctx, "Right Click here:", NK_TEXT_LEFT); - nk_layout_row_push(ctx, 50); - bounds = nk_widget_bounds(ctx); - nk_button_color(ctx, color); - nk_layout_row_end(ctx); - - if (nk_contextual_begin(ctx, 0, nk_vec2(350, 60), bounds)) { - nk_layout_row_dynamic(ctx, 30, 4); - color.r = (nk_byte)nk_propertyi(ctx, "#r", 0, color.r, 255, 1, 1); - color.g = (nk_byte)nk_propertyi(ctx, "#g", 0, color.g, 255, 1, 1); - color.b = (nk_byte)nk_propertyi(ctx, "#b", 0, color.b, 255, 1, 1); - color.a = (nk_byte)nk_propertyi(ctx, "#a", 0, color.a, 255, 1, 1); - nk_contextual_end(ctx); - } - - /* popup */ - nk_layout_row_begin(ctx, NK_STATIC, 30, 2); - nk_layout_row_push(ctx, 120); - nk_label(ctx, "Popup:", NK_TEXT_LEFT); - nk_layout_row_push(ctx, 50); - if (nk_button_label(ctx, "Popup")) { - popup_active = 1; - } - nk_layout_row_end(ctx); - - if (popup_active) { - static struct nk_rect s = {20, 100, 220, 90}; - if (nk_popup_begin(ctx, NK_POPUP_STATIC, "Error", 0, s)) { - nk_layout_row_dynamic(ctx, 25, 1); - nk_label(ctx, "A terrible error as occurred", NK_TEXT_LEFT); - nk_layout_row_dynamic(ctx, 25, 2); - if (nk_button_label(ctx, "OK")) { - popup_active = 0; - nk_popup_close(ctx); - } - if (nk_button_label(ctx, "Cancel")) { - popup_active = 0; - nk_popup_close(ctx); - } - nk_popup_end(ctx); - } else { - popup_active = nk_false; - } - } - - /* tooltips */ - nk_layout_row_static(ctx, 30, 400, 1); - bounds = nk_widget_bounds(ctx); - nk_label(ctx, "Hover for default tooltip", NK_TEXT_LEFT); - if (nk_input_is_mouse_hovering_rect(in, bounds)) { - nk_tooltip(ctx, "This is a default tooltip"); - } - bounds = nk_widget_bounds(ctx); - nk_label(ctx, "Hover for Gnome-like tooltip", NK_TEXT_LEFT); - if (nk_input_is_mouse_hovering_rect(in, bounds)) { - struct nk_vec2 offset = {0, -15}; - nk_tooltip_offset(ctx, "Gnome bottom centers plus a -y offset", NK_BOTTOM_CENTER, offset); - } - bounds = nk_widget_bounds(ctx); - nk_label(ctx, "Hover for a bottom left tooltip", NK_TEXT_LEFT); - if (nk_input_is_mouse_hovering_rect(in, bounds)) { - struct nk_vec2 offset = {0, 0}; - nk_tooltip_offset(ctx, "Bottom left positioning", NK_BOTTOM_LEFT, offset); - } - bounds = nk_widget_bounds(ctx); - nk_label(ctx, "Hover for MAGIC!", NK_TEXT_LEFT); - if (nk_input_is_mouse_hovering_rect(in, bounds)) { - static float accum_time_seconds = 0.0; - const float speed = 3.0, radius = 50.0; - struct nk_vec2 offset; - offset.x = radius * NK_COS(accum_time_seconds * speed); - offset.y = radius * NK_SIN(accum_time_seconds * speed); - nk_tooltip_offset(ctx, "WOW!", NK_MIDDLE_CENTER, offset); - accum_time_seconds += ctx->delta_time_seconds; - } - - /* editor for custom tooltip */ - { - static char text_buf[64] = {0}; - static int text_len = 0; - static int text_initialized = 0; - static struct nk_vec2 offset = {0}; - static const char *tooltip_positions[] = { - "TOP_LEFT", - "TOP_CENTER", - "TOP_RIGHT", - - "MIDDLE_LEFT", - "MIDDLE_CENTER", - "MIDDLE_RIGHT", - - "BOTTOM_LEFT", - "BOTTOM_CENTER", - "BOTTOM_RIGHT", - }; - int cur_pos = NK_TOP_LEFT; - - if (!text_initialized) { - const char text_default[] = "you can customize this!"; - NK_ASSERT(sizeof(text_default) < sizeof(text_buf)); - memcpy(text_buf, text_default, sizeof(text_default)); - text_len = sizeof(text_default) - 1; - text_initialized = 1; - } - bounds = nk_widget_bounds(ctx); - nk_label(ctx, "Hover for custom tooltip (you can customize it below)", NK_TEXT_LEFT); - if (nk_input_is_mouse_hovering_rect(in, bounds)) { - nk_tooltip_offset(ctx, text_buf, (enum nk_tooltip_pos)cur_pos, offset); - } - nk_layout_row_dynamic(ctx, 1, 1); - nk_rule_horizontal(ctx, nk_white, nk_true); - nk_layout_row_dynamic(ctx, 30, 2); - nk_label(ctx, "custom tooltip text:", NK_TEXT_LEFT); - nk_edit_string(ctx, NK_EDIT_FIELD, text_buf, &text_len, sizeof(text_buf), nk_filter_default); - text_buf[text_len] = '\0'; /* TODO: why nk_edit_string is NOT setting this on its own? */ - nk_layout_row_dynamic(ctx, 30, 1); - cur_pos = nk_combo(ctx, tooltip_positions, NK_LEN(tooltip_positions), cur_pos, 25, nk_vec2(200, 200)); - - nk_layout_row_dynamic(ctx, 30, 2); - nk_label(ctx, "custom tooltip offset", NK_TEXT_LEFT); - nk_property_float(ctx, "x", -100.0f, &offset.x, 100.0f, 5.0f, 0.5f); - nk_label(ctx, "custom tooltip offset", NK_TEXT_LEFT); - nk_property_float(ctx, "y", -100.0f, &offset.y, 100.0f, 5.0f, 0.5f); - } - - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Layout", NK_MAXIMIZED)) { - if (nk_tree_push(ctx, NK_TREE_NODE, "Widget", NK_MAXIMIZED)) { - float ratio_two[] = {0.2f, 0.6f, 0.2f}; - float width_two[] = {100, 200, 50}; - - nk_layout_row_dynamic(ctx, 30, 1); - nk_label(ctx, "Dynamic fixed column layout with generated position and size:", NK_TEXT_LEFT); - nk_layout_row_dynamic(ctx, 30, 3); - nk_button_label(ctx, "button"); - nk_button_label(ctx, "button"); - nk_button_label(ctx, "button"); - - nk_layout_row_dynamic(ctx, 30, 1); - nk_label(ctx, "static fixed column layout with generated position and size:", NK_TEXT_LEFT); - nk_layout_row_static(ctx, 30, 100, 3); - nk_button_label(ctx, "button"); - nk_button_label(ctx, "button"); - nk_button_label(ctx, "button"); - - nk_layout_row_dynamic(ctx, 30, 1); - nk_label( - ctx, "Dynamic array-based custom column layout with generated position and custom size:", NK_TEXT_LEFT); - nk_layout_row(ctx, NK_DYNAMIC, 30, 3, ratio_two); - nk_button_label(ctx, "button"); - nk_button_label(ctx, "button"); - nk_button_label(ctx, "button"); - - nk_layout_row_dynamic(ctx, 30, 1); - nk_label(ctx, "Static array-based custom column layout with generated position and custom size:", NK_TEXT_LEFT); - nk_layout_row(ctx, NK_STATIC, 30, 3, width_two); - nk_button_label(ctx, "button"); - nk_button_label(ctx, "button"); - nk_button_label(ctx, "button"); - - nk_layout_row_dynamic(ctx, 30, 1); - nk_label( - ctx, "Dynamic immediate mode custom column layout with generated position and custom size:", NK_TEXT_LEFT); - nk_layout_row_begin(ctx, NK_DYNAMIC, 30, 3); - nk_layout_row_push(ctx, 0.2f); - nk_button_label(ctx, "button"); - nk_layout_row_push(ctx, 0.6f); - nk_button_label(ctx, "button"); - nk_layout_row_push(ctx, 0.2f); - nk_button_label(ctx, "button"); - nk_layout_row_end(ctx); - - nk_layout_row_dynamic(ctx, 30, 1); - nk_label( - ctx, "Static immediate mode custom column layout with generated position and custom size:", NK_TEXT_LEFT); - nk_layout_row_begin(ctx, NK_STATIC, 30, 3); - nk_layout_row_push(ctx, 100); - nk_button_label(ctx, "button"); - nk_layout_row_push(ctx, 200); - nk_button_label(ctx, "button"); - nk_layout_row_push(ctx, 50); - nk_button_label(ctx, "button"); - nk_layout_row_end(ctx); - - nk_layout_row_dynamic(ctx, 30, 1); - nk_label(ctx, "Static free space with custom position and custom size:", NK_TEXT_LEFT); - nk_layout_space_begin(ctx, NK_STATIC, 60, 4); - nk_layout_space_push(ctx, nk_rect(100, 0, 100, 30)); - nk_button_label(ctx, "button"); - nk_layout_space_push(ctx, nk_rect(0, 15, 100, 30)); - nk_button_label(ctx, "button"); - nk_layout_space_push(ctx, nk_rect(200, 15, 100, 30)); - nk_button_label(ctx, "button"); - nk_layout_space_push(ctx, nk_rect(100, 30, 100, 30)); - nk_button_label(ctx, "button"); - nk_layout_space_end(ctx); - - nk_layout_row_dynamic(ctx, 30, 1); - nk_label(ctx, "Row template:", NK_TEXT_LEFT); - nk_layout_row_template_begin(ctx, 30); - nk_layout_row_template_push_dynamic(ctx); - nk_layout_row_template_push_variable(ctx, 80); - nk_layout_row_template_push_static(ctx, 80); - nk_layout_row_template_end(ctx); - nk_button_label(ctx, "button"); - nk_button_label(ctx, "button"); - nk_button_label(ctx, "button"); - - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_NODE, "Group", NK_MAXIMIZED)) { - static nk_bool group_titlebar = nk_false; - static nk_bool group_border = nk_true; - static nk_bool group_no_scrollbar = nk_false; - static int group_width = 320; - static int group_height = 200; - - nk_flags group_flags = 0; - if (group_border) { - group_flags |= NK_WINDOW_BORDER; - } - if (group_no_scrollbar) { - group_flags |= NK_WINDOW_NO_SCROLLBAR; - } - if (group_titlebar) { - group_flags |= NK_WINDOW_TITLE; - } - - nk_layout_row_dynamic(ctx, 30, 3); - nk_checkbox_label(ctx, "Titlebar", &group_titlebar); - nk_checkbox_label(ctx, "Border", &group_border); - nk_checkbox_label(ctx, "No Scrollbar", &group_no_scrollbar); - - nk_layout_row_begin(ctx, NK_STATIC, 22, 3); - nk_layout_row_push(ctx, 50); - nk_label(ctx, "size:", NK_TEXT_LEFT); - nk_layout_row_push(ctx, 130); - nk_property_int(ctx, "#Width:", 100, &group_width, 500, 10, 1); - nk_layout_row_push(ctx, 130); - nk_property_int(ctx, "#Height:", 100, &group_height, 500, 10, 1); - nk_layout_row_end(ctx); - - nk_layout_row_static(ctx, (float)group_height, group_width, 2); - if (nk_group_begin(ctx, "Group", group_flags)) { - int i = 0; - static nk_bool selected[16]; - nk_layout_row_static(ctx, 18, 100, 1); - for (i = 0; i < 16; ++i) { - nk_selectable_label(ctx, (selected[i]) ? "Selected" : "Unselected", NK_TEXT_CENTERED, &selected[i]); - } - nk_group_end(ctx); - } - nk_tree_pop(ctx); - } - if (nk_tree_push(ctx, NK_TREE_NODE, "Tree", NK_MAXIMIZED)) { - static nk_bool root_selected = 0; - nk_bool sel = root_selected; - if (nk_tree_element_push(ctx, NK_TREE_NODE, "Root", NK_MAXIMIZED, &sel)) { - static nk_bool selected[8]; - int i = 0; - nk_bool node_select = selected[0]; - if (sel != root_selected) { - root_selected = sel; - for (i = 0; i < 8; ++i) { - selected[i] = sel; - } - } - if (nk_tree_element_push(ctx, NK_TREE_NODE, "Node", NK_MAXIMIZED, &node_select)) { - int j = 0; - static nk_bool sel_nodes[4]; - if (node_select != selected[0]) { - selected[0] = node_select; - for (i = 0; i < 4; ++i) { - sel_nodes[i] = node_select; - } - } - nk_layout_row_static(ctx, 18, 100, 1); - for (j = 0; j < 4; ++j) { - nk_selectable_symbol_label( - ctx, NK_SYMBOL_CIRCLE_SOLID, (sel_nodes[j]) ? "Selected" : "Unselected", NK_TEXT_RIGHT, &sel_nodes[j]); - } - nk_tree_element_pop(ctx); - } - nk_layout_row_static(ctx, 18, 100, 1); - for (i = 1; i < 8; ++i) { - nk_selectable_symbol_label( - ctx, NK_SYMBOL_CIRCLE_SOLID, (selected[i]) ? "Selected" : "Unselected", NK_TEXT_RIGHT, &selected[i]); - } - nk_tree_element_pop(ctx); - } - nk_tree_pop(ctx); - } - if (nk_tree_push(ctx, NK_TREE_NODE, "Notebook", NK_MAXIMIZED)) { - static int current_tab = 0; - float step = (2 * 3.141592654f) / 32; - enum chart_type { CHART_LINE, CHART_HISTO, CHART_MIXED }; - const char *names[] = {"Lines", "Columns", "Mixed"}; - float id = 0; - int i; - - /* Header */ - nk_style_push_vec2(ctx, &ctx->style.window.spacing, nk_vec2(0, 0)); - nk_style_push_float(ctx, &ctx->style.button.rounding, 0); - nk_layout_row_begin(ctx, NK_STATIC, 20, 3); - for (i = 0; i < 3; ++i) { - /* make sure button perfectly fits text */ - const struct nk_user_font *f = ctx->style.font; - float text_width = nk_text_width(ctx, f, ctx->style.font_size, names[i], nk_strlen(names[i])); - float widget_width = text_width + 3 * ctx->style.button.padding.x; - nk_layout_row_push(ctx, widget_width); - if (current_tab == i) { - /* active tab gets highlighted */ - struct nk_style_item button_color = ctx->style.button.normal; - ctx->style.button.normal = ctx->style.button.active; - current_tab = nk_button_label(ctx, names[i]) ? i : current_tab; - ctx->style.button.normal = button_color; - } else { - current_tab = nk_button_label(ctx, names[i]) ? i : current_tab; - } - } - nk_style_pop_float(ctx); - - /* Body */ - nk_layout_row_dynamic(ctx, 140, 1); - if (nk_group_begin(ctx, "Notebook", NK_WINDOW_BORDER)) { - nk_style_pop_vec2(ctx); - switch (current_tab) { - default: - break; - case CHART_LINE: - nk_layout_row_dynamic(ctx, 100, 1); - if (nk_chart_begin_colored(ctx, NK_CHART_LINES, nk_rgb(255, 0, 0), nk_rgb(150, 0, 0), 32, 0.0f, 1.0f)) { - nk_chart_add_slot_colored(ctx, NK_CHART_LINES, nk_rgb(0, 0, 255), nk_rgb(0, 0, 150), 32, -1.0f, 1.0f); - for (i = 0, id = 0; i < 32; ++i) { - nk_chart_push_slot(ctx, (float)NK_ABS(NK_SIN(id)), 0); - nk_chart_push_slot(ctx, (float)NK_COS(id), 1); - id += step; - } - } - nk_chart_end(ctx); - break; - case CHART_HISTO: - nk_layout_row_dynamic(ctx, 100, 1); - if (nk_chart_begin_colored(ctx, NK_CHART_COLUMN, nk_rgb(255, 0, 0), nk_rgb(150, 0, 0), 32, 0.0f, 1.0f)) { - for (i = 0, id = 0; i < 32; ++i) { - nk_chart_push_slot(ctx, (float)NK_ABS(NK_SIN(id)), 0); - id += step; - } - } - nk_chart_end(ctx); - break; - case CHART_MIXED: - nk_layout_row_dynamic(ctx, 100, 1); - if (nk_chart_begin_colored(ctx, NK_CHART_LINES, nk_rgb(255, 0, 0), nk_rgb(150, 0, 0), 32, 0.0f, 1.0f)) { - nk_chart_add_slot_colored(ctx, NK_CHART_LINES, nk_rgb(0, 0, 255), nk_rgb(0, 0, 150), 32, -1.0f, 1.0f); - nk_chart_add_slot_colored(ctx, NK_CHART_COLUMN, nk_rgb(0, 255, 0), nk_rgb(0, 150, 0), 32, 0.0f, 1.0f); - for (i = 0, id = 0; i < 32; ++i) { - nk_chart_push_slot(ctx, (float)NK_ABS(NK_SIN(id)), 0); - nk_chart_push_slot(ctx, (float)NK_ABS(NK_COS(id)), 1); - nk_chart_push_slot(ctx, (float)NK_ABS(NK_SIN(id)), 2); - id += step; - } - } - nk_chart_end(ctx); - break; - } - nk_group_end(ctx); - } else { - nk_style_pop_vec2(ctx); - } - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_NODE, "Simple", NK_MAXIMIZED)) { - nk_layout_row_dynamic(ctx, 300, 2); - if (nk_group_begin(ctx, "Group_Without_Border", 0)) { - int i = 0; - char buffer[64]; - nk_layout_row_static(ctx, 18, 150, 1); - for (i = 0; i < 64; ++i) { - sprintf(buffer, "0x%02x", i); - nk_labelf(ctx, NK_TEXT_LEFT, "%s: scrollable region", buffer); - } - nk_group_end(ctx); - } - if (nk_group_begin(ctx, "Group_With_Border", NK_WINDOW_BORDER)) { - int i = 0; - char buffer[64]; - nk_layout_row_dynamic(ctx, 25, 2); - for (i = 0; i < 64; ++i) { - sprintf(buffer, "%08d", ((((i % 7) * 10) ^ 32)) + (64 + (i % 2) * 2)); - nk_button_label(ctx, buffer); - } - nk_group_end(ctx); - } - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_NODE, "Complex", NK_MAXIMIZED)) { - int i; - nk_layout_space_begin(ctx, NK_STATIC, 500, 64); - nk_layout_space_push(ctx, nk_rect(0, 0, 150, 500)); - if (nk_group_begin(ctx, "Group_left", NK_WINDOW_BORDER)) { - static nk_bool selected[32]; - nk_layout_row_static(ctx, 18, 100, 1); - for (i = 0; i < 32; ++i) { - nk_selectable_label(ctx, (selected[i]) ? "Selected" : "Unselected", NK_TEXT_CENTERED, &selected[i]); - } - nk_group_end(ctx); - } - - nk_layout_space_push(ctx, nk_rect(160, 0, 150, 240)); - if (nk_group_begin(ctx, "Group_top", NK_WINDOW_BORDER)) { - nk_layout_row_dynamic(ctx, 25, 1); - nk_button_label(ctx, "#FFAA"); - nk_button_label(ctx, "#FFBB"); - nk_button_label(ctx, "#FFCC"); - nk_button_label(ctx, "#FFDD"); - nk_button_label(ctx, "#FFEE"); - nk_button_label(ctx, "#FFFF"); - nk_group_end(ctx); - } - - nk_layout_space_push(ctx, nk_rect(160, 250, 150, 250)); - if (nk_group_begin(ctx, "Group_buttom", NK_WINDOW_BORDER)) { - nk_layout_row_dynamic(ctx, 25, 1); - nk_button_label(ctx, "#FFAA"); - nk_button_label(ctx, "#FFBB"); - nk_button_label(ctx, "#FFCC"); - nk_button_label(ctx, "#FFDD"); - nk_button_label(ctx, "#FFEE"); - nk_button_label(ctx, "#FFFF"); - nk_group_end(ctx); - } - - nk_layout_space_push(ctx, nk_rect(320, 0, 150, 150)); - if (nk_group_begin(ctx, "Group_right_top", NK_WINDOW_BORDER)) { - static nk_bool selected[4]; - nk_layout_row_static(ctx, 18, 100, 1); - for (i = 0; i < 4; ++i) { - nk_selectable_label(ctx, (selected[i]) ? "Selected" : "Unselected", NK_TEXT_CENTERED, &selected[i]); - } - nk_group_end(ctx); - } - - nk_layout_space_push(ctx, nk_rect(320, 160, 150, 150)); - if (nk_group_begin(ctx, "Group_right_center", NK_WINDOW_BORDER)) { - static nk_bool selected[4]; - nk_layout_row_static(ctx, 18, 100, 1); - for (i = 0; i < 4; ++i) { - nk_selectable_label(ctx, (selected[i]) ? "Selected" : "Unselected", NK_TEXT_CENTERED, &selected[i]); - } - nk_group_end(ctx); - } - - nk_layout_space_push(ctx, nk_rect(320, 320, 150, 150)); - if (nk_group_begin(ctx, "Group_right_bottom", NK_WINDOW_BORDER)) { - static nk_bool selected[4]; - nk_layout_row_static(ctx, 18, 100, 1); - for (i = 0; i < 4; ++i) { - nk_selectable_label(ctx, (selected[i]) ? "Selected" : "Unselected", NK_TEXT_CENTERED, &selected[i]); - } - nk_group_end(ctx); - } - nk_layout_space_end(ctx); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_NODE, "Splitter", NK_MAXIMIZED)) { - const struct nk_input *in = &ctx->input; - nk_layout_row_static(ctx, 20, 320, 1); - nk_label(ctx, "Use slider and spinner to change tile size", NK_TEXT_LEFT); - nk_label(ctx, "Drag the space between tiles to change tile ratio", NK_TEXT_LEFT); - - if (nk_tree_push(ctx, NK_TREE_NODE, "Vertical", NK_MAXIMIZED)) { - static float a = 100, b = 100, c = 100; - struct nk_rect bounds; - - float row_layout[5]; - row_layout[0] = a; - row_layout[1] = 8; - row_layout[2] = b; - row_layout[3] = 8; - row_layout[4] = c; - - /* header */ - nk_layout_row_static(ctx, 30, 100, 2); - nk_label(ctx, "left:", NK_TEXT_LEFT); - nk_slider_float(ctx, 10.0f, &a, 200.0f, 10.0f); - - nk_label(ctx, "middle:", NK_TEXT_LEFT); - nk_slider_float(ctx, 10.0f, &b, 200.0f, 10.0f); - - nk_label(ctx, "right:", NK_TEXT_LEFT); - nk_slider_float(ctx, 10.0f, &c, 200.0f, 10.0f); - - /* tiles */ - nk_layout_row(ctx, NK_STATIC, 200, 5, row_layout); - - /* left space */ - if (nk_group_begin(ctx, "left", NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_BORDER | NK_WINDOW_NO_SCROLLBAR)) { - nk_layout_row_dynamic(ctx, 25, 1); - nk_button_label(ctx, "#FFAA"); - nk_button_label(ctx, "#FFBB"); - nk_button_label(ctx, "#FFCC"); - nk_button_label(ctx, "#FFDD"); - nk_button_label(ctx, "#FFEE"); - nk_button_label(ctx, "#FFFF"); - nk_group_end(ctx); - } - - /* scaler */ - bounds = nk_widget_bounds(ctx); - nk_spacing(ctx, 1); - if ((nk_input_is_mouse_hovering_rect(in, bounds) || nk_input_is_mouse_prev_hovering_rect(in, bounds)) && - nk_input_is_mouse_down(in, NK_BUTTON_LEFT)) { - a = row_layout[0] + in->mouse.delta.x; - b = row_layout[2] - in->mouse.delta.x; - } - - /* middle space */ - if (nk_group_begin(ctx, "center", NK_WINDOW_BORDER | NK_WINDOW_NO_SCROLLBAR)) { - nk_layout_row_dynamic(ctx, 25, 1); - nk_button_label(ctx, "#FFAA"); - nk_button_label(ctx, "#FFBB"); - nk_button_label(ctx, "#FFCC"); - nk_button_label(ctx, "#FFDD"); - nk_button_label(ctx, "#FFEE"); - nk_button_label(ctx, "#FFFF"); - nk_group_end(ctx); - } - - /* scaler */ - bounds = nk_widget_bounds(ctx); - nk_spacing(ctx, 1); - if ((nk_input_is_mouse_hovering_rect(in, bounds) || nk_input_is_mouse_prev_hovering_rect(in, bounds)) && - nk_input_is_mouse_down(in, NK_BUTTON_LEFT)) { - b = (row_layout[2] + in->mouse.delta.x); - c = (row_layout[4] - in->mouse.delta.x); - } - - /* right space */ - if (nk_group_begin(ctx, "right", NK_WINDOW_BORDER | NK_WINDOW_NO_SCROLLBAR)) { - nk_layout_row_dynamic(ctx, 25, 1); - nk_button_label(ctx, "#FFAA"); - nk_button_label(ctx, "#FFBB"); - nk_button_label(ctx, "#FFCC"); - nk_button_label(ctx, "#FFDD"); - nk_button_label(ctx, "#FFEE"); - nk_button_label(ctx, "#FFFF"); - nk_group_end(ctx); - } - - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_NODE, "Horizontal", NK_MAXIMIZED)) { - static float a = 100, b = 100, c = 100; - struct nk_rect bounds; - - /* header */ - nk_layout_row_static(ctx, 30, 100, 2); - nk_label(ctx, "top:", NK_TEXT_LEFT); - nk_slider_float(ctx, 10.0f, &a, 200.0f, 10.0f); - - nk_label(ctx, "middle:", NK_TEXT_LEFT); - nk_slider_float(ctx, 10.0f, &b, 200.0f, 10.0f); - - nk_label(ctx, "bottom:", NK_TEXT_LEFT); - nk_slider_float(ctx, 10.0f, &c, 200.0f, 10.0f); - - /* top space */ - nk_layout_row_dynamic(ctx, a, 1); - if (nk_group_begin(ctx, "top", NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_BORDER)) { - nk_layout_row_dynamic(ctx, 25, 3); - nk_button_label(ctx, "#FFAA"); - nk_button_label(ctx, "#FFBB"); - nk_button_label(ctx, "#FFCC"); - nk_button_label(ctx, "#FFDD"); - nk_button_label(ctx, "#FFEE"); - nk_button_label(ctx, "#FFFF"); - nk_group_end(ctx); - } - - /* scaler */ - nk_layout_row_dynamic(ctx, 8, 1); - bounds = nk_widget_bounds(ctx); - nk_spacing(ctx, 1); - if ((nk_input_is_mouse_hovering_rect(in, bounds) || nk_input_is_mouse_prev_hovering_rect(in, bounds)) && - nk_input_is_mouse_down(in, NK_BUTTON_LEFT)) { - a = a + in->mouse.delta.y; - b = b - in->mouse.delta.y; - } - - /* middle space */ - nk_layout_row_dynamic(ctx, b, 1); - if (nk_group_begin(ctx, "middle", NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_BORDER)) { - nk_layout_row_dynamic(ctx, 25, 3); - nk_button_label(ctx, "#FFAA"); - nk_button_label(ctx, "#FFBB"); - nk_button_label(ctx, "#FFCC"); - nk_button_label(ctx, "#FFDD"); - nk_button_label(ctx, "#FFEE"); - nk_button_label(ctx, "#FFFF"); - nk_group_end(ctx); - } - - { - /* scaler */ - nk_layout_row_dynamic(ctx, 8, 1); - bounds = nk_widget_bounds(ctx); - if ((nk_input_is_mouse_hovering_rect(in, bounds) || nk_input_is_mouse_prev_hovering_rect(in, bounds)) && - nk_input_is_mouse_down(in, NK_BUTTON_LEFT)) { - b = b + in->mouse.delta.y; - c = c - in->mouse.delta.y; - } - } - - /* bottom space */ - nk_layout_row_dynamic(ctx, c, 1); - if (nk_group_begin(ctx, "bottom", NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_BORDER)) { - nk_layout_row_dynamic(ctx, 25, 3); - nk_button_label(ctx, "#FFAA"); - nk_button_label(ctx, "#FFBB"); - nk_button_label(ctx, "#FFCC"); - nk_button_label(ctx, "#FFDD"); - nk_button_label(ctx, "#FFEE"); - nk_button_label(ctx, "#FFFF"); - nk_group_end(ctx); - } - nk_tree_pop(ctx); - } - nk_tree_pop(ctx); - } - nk_tree_pop(ctx); - } - - /* Input */ - if (nk_tree_push(ctx, NK_TREE_TAB, "Input", NK_MAXIMIZED)) { - const struct nk_input *in = &ctx->input; - static const char *button_names[NK_BUTTON_MAX] = {"Left", "Middle", "Right", "Double Click", "X1", "X2"}; - int i; - - /* Mouse Buttons*/ - nk_layout_row_dynamic(ctx, 30, 1); - nk_label(ctx, "Mouse Buttons", NK_TEXT_LEFT); - nk_layout_row_dynamic(ctx, 20, 2); - for (i = 0; i < NK_BUTTON_MAX; i++) { - nk_label(ctx, button_names[i], NK_TEXT_LEFT); - if (nk_input_is_mouse_pressed(in, (enum nk_buttons)i)) { - nk_label(ctx, "Pressed", NK_TEXT_LEFT); - } else if (nk_input_is_mouse_down(in, (enum nk_buttons)i)) { - nk_label(ctx, "Down", NK_TEXT_LEFT); - } else if (nk_input_is_mouse_released(in, (enum nk_buttons)i)) { - nk_label(ctx, "Released", NK_TEXT_LEFT); - } else { - nk_label(ctx, "Up", NK_TEXT_LEFT); - } - } - - /* Mouse Wheel */ - nk_layout_row_dynamic(ctx, 30, 1); - nk_label(ctx, "Mouse Wheel", NK_TEXT_LEFT); - nk_layout_row_dynamic(ctx, 20, 2); - nk_labelf(ctx, NK_TEXT_LEFT, "X: %.2f", in->mouse.scroll_delta.x); - nk_labelf(ctx, NK_TEXT_LEFT, "Y: %.2f", in->mouse.scroll_delta.y); - nk_tree_pop(ctx); - } - - if (disable_widgets) { - nk_widget_disable_end(ctx); - } - } - nk_end(ctx); - return !nk_window_is_closed(ctx, "Overview"); -} diff --git a/test/test_ui_signatures.c b/test/test_ui_signatures.c deleted file mode 100644 index a4554c7..0000000 --- a/test/test_ui_signatures.c +++ /dev/null @@ -1,10 +0,0 @@ -#include "signatures.h" - -/* TestUI has no game process to scan, so engine entry points stay unavailable */ -#define UE_FUNC_NORMAL(NAME, RET, ...) \ - NAME##_fn_t NAME = NULL; -#define UE_FUNC_HOOKED(NAME, RET, ...) \ - NAME##_fn_t NAME = NULL; \ - NAME##_fn_t NAME##_real = NULL; - -#include "unreal_funcs.inc" diff --git a/test/test_ui_style_configurator.c b/test/test_ui_style_configurator.c deleted file mode 100644 index c2d7ca8..0000000 --- a/test/test_ui_style_configurator.c +++ /dev/null @@ -1,947 +0,0 @@ -#include "vendor_nuklear.h" -#include "vendor_stb.h" - -#include - -static const char *symbols[NK_SYMBOL_MAX] = { - "NONE", - "X", - "UNDERSCORE", - "CIRCLE_SOLID", - "CIRCLE_OUTLINE", - "RECT_SOLID", - "RECT_OUTLINE", - "TRIANGLE_UP", - "TRIANGLE_DOWN", - "TRIANGLE_LEFT", - "TRIANGLE_RIGHT", - "PLUS", - "MINUS", - "TRIANGLE_UP_OUTLINE", - "TRIANGLE_DOWN_OUTLINE", - "TRIANGLE_LEFT_OUTLINE", - "TRIANGLE_RIGHT_OUTLINE", -}; - -static int -style_rgba(struct nk_context *ctx, const char *name, struct nk_color *color) -{ - nk_label(ctx, name, NK_TEXT_LEFT); - if (nk_combo_begin_color(ctx, *color, nk_vec2(nk_widget_width(ctx), 400))) { - nk_layout_row_dynamic(ctx, 120, 1); - *color = nk_rgba_cf(nk_color_picker(ctx, nk_color_cf(*color), NK_RGBA)); - - nk_layout_row_dynamic(ctx, 25, 1); - color->r = nk_propertyi(ctx, "#R", 0, color->r, 255, 1, 1); - color->g = nk_propertyi(ctx, "#G", 0, color->g, 255, 1, 1); - color->b = nk_propertyi(ctx, "#B", 0, color->b, 255, 1, 1); - color->a = nk_propertyi(ctx, "#A", 0, color->a, 255, 1, 1); - - nk_combo_end(ctx); - return 1; - } - return 0; -} - -/* TODO style_style_item? how to handle images if at all? */ -static void -style_item_color(struct nk_context *ctx, const char *name, struct nk_style_item *item) -{ - style_rgba(ctx, name, &item->data.color); -} - -static void -style_vec2(struct nk_context *ctx, const char *name, struct nk_vec2 *vec) -{ - char buffer[64]; - nk_label(ctx, name, NK_TEXT_LEFT); - sprintf(buffer, "%.2f, %.2f", vec->x, vec->y); - if (nk_combo_begin_label(ctx, buffer, nk_vec2(200, 200))) { - nk_layout_row_dynamic(ctx, 25, 1); - nk_property_float(ctx, "#X:", -100.0f, &vec->x, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Y:", -100.0f, &vec->y, 100.0f, 1.0f, 0.5f); - nk_combo_end(ctx); - } -} - -/* style_general? pass array in instead of static? */ -static void -style_global_colors(struct nk_context *ctx, struct nk_color color_table[NK_COLOR_COUNT]) -{ - const char *color_labels[NK_COLOR_COUNT] = { - "COLOR_TEXT:", - "COLOR_WINDOW:", - "COLOR_HEADER:", - "COLOR_BORDER:", - "COLOR_BUTTON:", - "COLOR_BUTTON_HOVER:", - "COLOR_BUTTON_ACTIVE:", - "COLOR_TOGGLE:", - "COLOR_TOGGLE_HOVER:", - "COLOR_TOGGLE_CURSOR:", - "COLOR_SELECT:", - "COLOR_SELECT_ACTIVE:", - "COLOR_SLIDER:", - "COLOR_SLIDER_CURSOR:", - "COLOR_SLIDER_CURSOR_HOVER:", - "COLOR_SLIDER_CURSOR_ACTIVE:", - "COLOR_PROPERTY:", - "COLOR_EDIT:", - "COLOR_EDIT_CURSOR:", - "COLOR_COMBO:", - "COLOR_CHART:", - "COLOR_CHART_COLOR:", - "COLOR_CHART_COLOR_HIGHLIGHT:", - "COLOR_SCROLLBAR:", - "COLOR_SCROLLBAR_CURSOR:", - "COLOR_SCROLLBAR_CURSOR_HOVER:", - "COLOR_SCROLLBAR_CURSOR_ACTIVE:", - "COLOR_TAB_HEADER:", - "COLOR_KNOB:", - "COLOR_KNOB_CURSOR:", - "COLOR_KNOB_CURSOR_HOVER:", - "COLOR_KNOB_CURSOR_ACTIVE:", - }; - - int clicked = 0; - int i; - - nk_layout_row_dynamic(ctx, 30, 2); - for (i = 0; i < NK_COLOR_COUNT; ++i) { - clicked |= style_rgba(ctx, color_labels[i], &color_table[i]); - } - - if (clicked) { - nk_style_from_table(ctx, color_table); - } -} - -static void -style_text(struct nk_context *ctx, struct nk_style_text *out_style) -{ - struct nk_style_text text = *out_style; - - nk_layout_row_dynamic(ctx, 30, 2); - style_rgba(ctx, "Color:", &text.color); - - style_vec2(ctx, "Padding:", &text.padding); - nk_property_float(ctx, "#Color Factor:", 0.0f, &text.color_factor, 1.0f, 0.1f, 0.0025f); - nk_property_float(ctx, "#Disabled Factor:", 0.0f, &text.disabled_factor, 1.0f, 0.1f, 0.0025f); - - *out_style = text; -} - -static void -style_button(struct nk_context *ctx, - struct nk_style_button *out_style, - struct nk_style_button **duplicate_styles, - int n_dups) -{ - struct nk_style_button button = *out_style; - - nk_layout_row_dynamic(ctx, 30, 2); - style_item_color(ctx, "Normal:", &button.normal); - style_item_color(ctx, "Hover:", &button.hover); - style_item_color(ctx, "Active:", &button.active); - style_rgba(ctx, "Border:", &button.border_color); - - style_rgba(ctx, "Text Background:", &button.text_background); - style_rgba(ctx, "Text Normal:", &button.text_normal); - style_rgba(ctx, "Text Hover:", &button.text_hover); - style_rgba(ctx, "Text Active:", &button.text_active); - - style_vec2(ctx, "Padding:", &button.padding); - style_vec2(ctx, "Image Padding:", &button.image_padding); - style_vec2(ctx, "Touch Padding:", &button.touch_padding); - - { - const char *alignments[] = { - "LEFT", - "CENTERED", - "RIGHT", - "TOP LEFT", - "TOP CENTERED", - "TOP_RIGHT", - "BOTTOM LEFT", - "BOTTOM CENTERED", - "BOTTOM RIGHT", - }; - -#define TOP_LEFT NK_TEXT_ALIGN_TOP | NK_TEXT_ALIGN_LEFT -#define TOP_CENTER NK_TEXT_ALIGN_TOP | NK_TEXT_ALIGN_CENTERED -#define TOP_RIGHT NK_TEXT_ALIGN_TOP | NK_TEXT_ALIGN_RIGHT -#define BOTTOM_LEFT NK_TEXT_ALIGN_BOTTOM | NK_TEXT_ALIGN_LEFT -#define BOTTOM_CENTER NK_TEXT_ALIGN_BOTTOM | NK_TEXT_ALIGN_CENTERED -#define BOTTOM_RIGHT NK_TEXT_ALIGN_BOTTOM | NK_TEXT_ALIGN_RIGHT - - unsigned int aligns[] = { - NK_TEXT_LEFT, - NK_TEXT_CENTERED, - NK_TEXT_RIGHT, - TOP_LEFT, - TOP_CENTER, - TOP_RIGHT, - BOTTOM_LEFT, - BOTTOM_CENTER, - BOTTOM_RIGHT, - }; - - int cur_align = button.text_alignment - NK_TEXT_LEFT; - int i; - for (i = 0; i < (int)NK_LEN(aligns); ++i) { - if (button.text_alignment == aligns[i]) { - cur_align = i; - break; - } - } - nk_label(ctx, "Text Alignment:", NK_TEXT_LEFT); - cur_align = nk_combo(ctx, alignments, NK_LEN(alignments), cur_align, 25, nk_vec2(200, 200)); - button.text_alignment = aligns[cur_align]; - - nk_property_float(ctx, "#Border:", -100.0f, &button.border, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Rounding:", -100.0f, &button.rounding, 100.0f, 1.0f, 0.5f); - - nk_layout_row_dynamic(ctx, 30, 1); - nk_property_float(ctx, "#Color Factor Background:", 0.0f, &button.color_factor_background, 1.0f, 0.1f, 0.0025f); - nk_property_float(ctx, "#Color Factor Text:", 0.0f, &button.color_factor_text, 1.0f, 0.1f, 0.0025f); - nk_property_float(ctx, "#Disabled Factor:", 0.0f, &button.disabled_factor, 1.0f, 0.1f, 0.0025f); - - *out_style = button; - if (duplicate_styles) { - int i; - for (i = 0; i < n_dups; ++i) { - *duplicate_styles[i] = button; - } - } - } -} - -static void -style_toggle(struct nk_context *ctx, struct nk_style_toggle *out_style) -{ - struct nk_style_toggle toggle = *out_style; - - nk_layout_row_dynamic(ctx, 30, 2); - - style_item_color(ctx, "Normal:", &toggle.normal); - style_item_color(ctx, "Hover:", &toggle.hover); - style_item_color(ctx, "Active:", &toggle.active); - style_item_color(ctx, "Cursor Normal:", &toggle.cursor_normal); - style_item_color(ctx, "Cursor Hover:", &toggle.cursor_hover); - - style_rgba(ctx, "Border:", &toggle.border_color); - style_rgba(ctx, "Text Background:", &toggle.text_background); - style_rgba(ctx, "Text Normal:", &toggle.text_normal); - style_rgba(ctx, "Text Hover:", &toggle.text_hover); - style_rgba(ctx, "Text Active:", &toggle.text_active); - - style_vec2(ctx, "Padding:", &toggle.padding); - style_vec2(ctx, "Touch Padding:", &toggle.touch_padding); - - nk_property_float(ctx, "#Border:", -100.0f, &toggle.border, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Spacing:", -100.0f, &toggle.spacing, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Color Factor:", 0.0f, &toggle.color_factor, 1.0f, 0.1f, 0.0025f); - nk_property_float(ctx, "#Disabled Factor:", 0.0f, &toggle.disabled_factor, 1.0f, 0.1f, 0.0025f); - - *out_style = toggle; -} - -static void -style_selectable(struct nk_context *ctx, struct nk_style_selectable *out_style) -{ - struct nk_style_selectable select = *out_style; - - nk_layout_row_dynamic(ctx, 30, 2); - - style_item_color(ctx, "Normal:", &select.normal); - style_item_color(ctx, "Hover:", &select.hover); - style_item_color(ctx, "Pressed:", &select.pressed); - style_item_color(ctx, "Normal Active:", &select.normal_active); - style_item_color(ctx, "Hover Active:", &select.hover_active); - style_item_color(ctx, "Pressed Active:", &select.pressed_active); - - style_rgba(ctx, "Text Normal:", &select.text_normal); - style_rgba(ctx, "Text Hover:", &select.text_hover); - style_rgba(ctx, "Text Pressed:", &select.text_pressed); - style_rgba(ctx, "Text Normal Active:", &select.text_normal_active); - style_rgba(ctx, "Text Hover Active:", &select.text_hover_active); - style_rgba(ctx, "Text Pressed Active:", &select.text_pressed_active); - - style_vec2(ctx, "Padding:", &select.padding); - style_vec2(ctx, "Image Padding:", &select.image_padding); - style_vec2(ctx, "Touch Padding:", &select.touch_padding); - - nk_property_float(ctx, "#Rounding:", -100.0f, &select.rounding, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Color Factor:", 0.0f, &select.color_factor, 1.0f, 0.1f, 0.0025f); - nk_property_float(ctx, "#Disabled Factor:", 0.0f, &select.disabled_factor, 1.0f, 0.1f, 0.0025f); - - *out_style = select; -} - -static void -style_slider(struct nk_context *ctx, struct nk_style_slider *out_style) -{ - struct nk_style_slider slider = *out_style; - struct nk_style_button *dups[1]; - nk_bool show_buttons_b; - - nk_layout_row_dynamic(ctx, 30, 2); - - style_item_color(ctx, "Normal:", &slider.normal); - style_item_color(ctx, "Hover:", &slider.hover); - style_item_color(ctx, "Active:", &slider.active); - - style_rgba(ctx, "Bar Normal:", &slider.bar_normal); - style_rgba(ctx, "Bar Hover:", &slider.bar_hover); - style_rgba(ctx, "Bar Active:", &slider.bar_active); - style_rgba(ctx, "Bar Filled:", &slider.bar_filled); - - style_item_color(ctx, "Cursor Normal:", &slider.cursor_normal); - style_item_color(ctx, "Cursor Hover:", &slider.cursor_hover); - style_item_color(ctx, "Cursor Active:", &slider.cursor_active); - - style_vec2(ctx, "Cursor Size:", &slider.cursor_size); - style_vec2(ctx, "Padding:", &slider.padding); - style_vec2(ctx, "Spacing:", &slider.spacing); - - nk_property_float(ctx, "#Bar Height:", -100.0f, &slider.bar_height, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Rounding:", -100.0f, &slider.rounding, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Color Factor:", 0.0f, &slider.color_factor, 1.0f, 0.1f, 0.0025f); - nk_property_float(ctx, "#Disabled Factor:", 0.0f, &slider.disabled_factor, 1.0f, 0.1f, 0.0025f); - - nk_layout_row_dynamic(ctx, 30, 1); - show_buttons_b = (nk_bool)slider.show_buttons; - nk_checkbox_label(ctx, "Show Buttons", &show_buttons_b); - slider.show_buttons = (int)show_buttons_b; - - if (slider.show_buttons) { - nk_layout_row_dynamic(ctx, 30, 2); - nk_label(ctx, "Inc Symbol:", NK_TEXT_LEFT); - slider.inc_symbol = nk_combo(ctx, symbols, NK_SYMBOL_MAX, slider.inc_symbol, 25, nk_vec2(200, 200)); - nk_label(ctx, "Dec Symbol:", NK_TEXT_LEFT); - slider.dec_symbol = nk_combo(ctx, symbols, NK_SYMBOL_MAX, slider.dec_symbol, 25, nk_vec2(200, 200)); - - /* necessary or do tree's always take the whole width? */ - /* nk_layout_row_dynamic(ctx, 30, 1); */ - if (nk_tree_push(ctx, NK_TREE_TAB, "Slider Buttons", NK_MAXIMIZED)) { - dups[0] = &ctx->style.slider.dec_button; - style_button(ctx, &ctx->style.slider.inc_button, dups, 1); - nk_tree_pop(ctx); - } - } - - *out_style = slider; -} - -static void -style_knob(struct nk_context *ctx, struct nk_style_knob *out_style) -{ - struct nk_style_knob knob = *out_style; - - nk_layout_row_dynamic(ctx, 30, 2); - - /* background */ - style_item_color(ctx, "Normal:", &knob.normal); - style_item_color(ctx, "Hover:", &knob.hover); - style_item_color(ctx, "Active:", &knob.active); - style_rgba(ctx, "Border:", &knob.border_color); - - /* knob */ - style_rgba(ctx, "Knob Normal:", &knob.knob_normal); - style_rgba(ctx, "Knob Hover:", &knob.knob_hover); - style_rgba(ctx, "Knob Active:", &knob.knob_active); - style_rgba(ctx, "Knob Border:", &knob.knob_border_color); - - /* cursor */ - style_rgba(ctx, "Cursor Normal:", &knob.cursor_normal); - style_rgba(ctx, "Cursor Hover:", &knob.cursor_hover); - style_rgba(ctx, "Cursor Active:", &knob.cursor_active); - - /* properties */ - style_vec2(ctx, "Padding:", &knob.padding); - style_vec2(ctx, "Spacing:", &knob.spacing); - nk_property_float(ctx, "#Border:", -100.0f, &knob.border, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Knob Border:", -100.0f, &knob.knob_border, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Cursor Width:", -100.0f, &knob.cursor_width, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Color Factor:", 0.0f, &knob.color_factor, 1.0f, 0.1f, 0.0025f); - nk_property_float(ctx, "#Disabled Factor:", 0.0f, &knob.disabled_factor, 1.0f, 0.1f, 0.0025f); - - *out_style = knob; -} - -static void -style_progress(struct nk_context *ctx, struct nk_style_progress *out_style) -{ - struct nk_style_progress prog = *out_style; - - nk_layout_row_dynamic(ctx, 30, 2); - - style_item_color(ctx, "Normal:", &prog.normal); - style_item_color(ctx, "Hover:", &prog.hover); - style_item_color(ctx, "Active:", &prog.active); - style_item_color(ctx, "Cursor Normal:", &prog.cursor_normal); - style_item_color(ctx, "Cursor Hover:", &prog.cursor_hover); - style_item_color(ctx, "Cursor Active:", &prog.cursor_active); - - /* TODO rgba? */ - style_rgba(ctx, "Border Color:", &prog.border_color); - style_rgba(ctx, "Cursor Border Color:", &prog.cursor_border_color); - - style_vec2(ctx, "Padding:", &prog.padding); - - nk_property_float(ctx, "#Rounding:", -100.0f, &prog.rounding, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Border:", -100.0f, &prog.border, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Cursor Border:", -100.0f, &prog.cursor_border, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Cursor Rounding:", -100.0f, &prog.cursor_rounding, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Color Factor:", 0.0f, &prog.color_factor, 1.0f, 0.1f, 0.0025f); - nk_property_float(ctx, "#Disabled Factor:", 0.0f, &prog.disabled_factor, 1.0f, 0.1f, 0.0025f); - - *out_style = prog; -} - -static void -style_scrollbars(struct nk_context *ctx, - struct nk_style_scrollbar *out_style, - struct nk_style_scrollbar **duplicate_styles, - int n_dups) -{ - struct nk_style_scrollbar scroll = *out_style; - struct nk_style_button *dups[3]; - nk_bool show_buttons_b; - - nk_layout_row_dynamic(ctx, 30, 2); - - style_item_color(ctx, "Normal:", &scroll.normal); - style_item_color(ctx, "Hover:", &scroll.hover); - style_item_color(ctx, "Active:", &scroll.active); - style_item_color(ctx, "Cursor Normal:", &scroll.cursor_normal); - style_item_color(ctx, "Cursor Hover:", &scroll.cursor_hover); - style_item_color(ctx, "Cursor Active:", &scroll.cursor_active); - - /* TODO rgba? */ - style_rgba(ctx, "Border Color:", &scroll.border_color); - style_rgba(ctx, "Cursor Border Color:", &scroll.cursor_border_color); - - style_vec2(ctx, "Padding:", &scroll.padding); - - nk_property_float(ctx, "#Border:", -100.0f, &scroll.border, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Rounding:", -100.0f, &scroll.rounding, 100.0f, 1.0f, 0.5f); - - /* TODO naming inconsistency with style_scrollress? */ - nk_property_float(ctx, "#Cursor Border:", -100.0f, &scroll.border_cursor, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Cursor Rounding:", -100.0f, &scroll.rounding_cursor, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Color Factor:", 0.0f, &scroll.color_factor, 1.0f, 0.1f, 0.0025f); - nk_property_float(ctx, "#Disabled Factor:", 0.0f, &scroll.disabled_factor, 1.0f, 0.1f, 0.0025f); - - /* TODO what is wrong with scrollbar buttons? Also look into controlling the total width (and height) of scrollbars - */ - nk_layout_row_dynamic(ctx, 30, 1); - show_buttons_b = (nk_bool)scroll.show_buttons; - nk_checkbox_label(ctx, "Show Buttons", &show_buttons_b); - scroll.show_buttons = (int)show_buttons_b; - - if (scroll.show_buttons) { - nk_layout_row_dynamic(ctx, 30, 2); - nk_label(ctx, "Inc Symbol:", NK_TEXT_LEFT); - scroll.inc_symbol = nk_combo(ctx, symbols, NK_SYMBOL_MAX, scroll.inc_symbol, 25, nk_vec2(200, 200)); - nk_label(ctx, "Dec Symbol:", NK_TEXT_LEFT); - scroll.dec_symbol = nk_combo(ctx, symbols, NK_SYMBOL_MAX, scroll.dec_symbol, 25, nk_vec2(200, 200)); - - /* nk_layout_row_dynamic(ctx, 30, 1); */ - if (nk_tree_push(ctx, NK_TREE_TAB, "Scrollbar Buttons", NK_MAXIMIZED)) { - dups[0] = &ctx->style.scrollh.dec_button; - dups[1] = &ctx->style.scrollv.inc_button; - dups[2] = &ctx->style.scrollv.dec_button; - style_button(ctx, &ctx->style.scrollh.inc_button, dups, 3); - nk_tree_pop(ctx); - } - } - - *out_style = scroll; - if (duplicate_styles) { - int i; - for (i = 0; i < n_dups; ++i) { - *duplicate_styles[i] = scroll; - } - } -} - -static void -style_edit(struct nk_context *ctx, struct nk_style_edit *out_style) -{ - struct nk_style_edit edit = *out_style; - - nk_layout_row_dynamic(ctx, 30, 2); - - style_item_color(ctx, "Normal:", &edit.normal); - style_item_color(ctx, "Hover:", &edit.hover); - style_item_color(ctx, "Active:", &edit.active); - - style_rgba(ctx, "Cursor Normal:", &edit.cursor_normal); - style_rgba(ctx, "Cursor Hover:", &edit.cursor_hover); - style_rgba(ctx, "Cursor Text Normal:", &edit.cursor_text_normal); - style_rgba(ctx, "Cursor Text Hover:", &edit.cursor_text_hover); - style_rgba(ctx, "Border:", &edit.border_color); - style_rgba(ctx, "Text Normal:", &edit.text_normal); - style_rgba(ctx, "Text Hover:", &edit.text_hover); - style_rgba(ctx, "Text Active:", &edit.text_active); - style_rgba(ctx, "Selected Normal:", &edit.selected_normal); - style_rgba(ctx, "Selected Hover:", &edit.selected_hover); - style_rgba(ctx, "Selected Text Normal:", &edit.selected_text_normal); - style_rgba(ctx, "Selected Text Hover:", &edit.selected_text_hover); - - style_vec2(ctx, "Scrollbar Size:", &edit.scrollbar_size); - style_vec2(ctx, "Padding:", &edit.padding); - - nk_property_float(ctx, "#Border:", -100.0f, &edit.border, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Rounding:", -100.0f, &edit.rounding, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Cursor Size:", -100.0f, &edit.cursor_size, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Row Padding:", -100.0f, &edit.row_padding, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Color Factor:", 0.0f, &edit.color_factor, 1.0f, 0.1f, 0.0025f); - nk_property_float(ctx, "#Disabled Factor:", 0.0f, &edit.disabled_factor, 1.0f, 0.1f, 0.0025f); - - *out_style = edit; -} - -static void -style_property(struct nk_context *ctx, struct nk_style_property *out_style) -{ - struct nk_style_property property = *out_style; - struct nk_style_button *dups[1]; - - nk_layout_row_dynamic(ctx, 30, 2); - - style_item_color(ctx, "Normal:", &property.normal); - style_item_color(ctx, "Hover:", &property.hover); - style_item_color(ctx, "Active:", &property.active); - - style_rgba(ctx, "Border:", &property.border_color); - style_rgba(ctx, "Label Normal:", &property.label_normal); - style_rgba(ctx, "Label Hover:", &property.label_hover); - style_rgba(ctx, "Label Active:", &property.label_active); - - style_vec2(ctx, "Padding:", &property.padding); - - /* TODO check weird hover bug with properties, happens in overview basic section too */ - nk_property_float(ctx, "#Border:", -100.0f, &property.border, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Rounding:", -100.0f, &property.rounding, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Color Factor:", 0.0f, &property.color_factor, 1.0f, 0.1f, 0.0025f); - nk_property_float(ctx, "#Disabled Factor:", 0.0f, &property.disabled_factor, 1.0f, 0.1f, 0.0025f); - - /* there is no property.show_buttons, they're always there */ - - nk_label(ctx, "Left Symbol:", NK_TEXT_LEFT); - property.sym_left = nk_combo(ctx, symbols, NK_SYMBOL_MAX, property.sym_left, 25, nk_vec2(200, 200)); - nk_label(ctx, "Right Symbol:", NK_TEXT_LEFT); - property.sym_right = nk_combo(ctx, symbols, NK_SYMBOL_MAX, property.sym_right, 25, nk_vec2(200, 200)); - - if (nk_tree_push(ctx, NK_TREE_TAB, "Property Buttons", NK_MAXIMIZED)) { - dups[0] = &property.dec_button; - style_button(ctx, &property.inc_button, dups, 1); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Property Edit", NK_MAXIMIZED)) { - style_edit(ctx, &ctx->style.property.edit); - nk_tree_pop(ctx); - } - - *out_style = property; -} - -static void -style_chart(struct nk_context *ctx, struct nk_style_chart *out_style) -{ - struct nk_style_chart chart = *out_style; - - nk_layout_row_dynamic(ctx, 30, 2); - - style_item_color(ctx, "Background:", &chart.background); - - style_rgba(ctx, "Border:", &chart.border_color); - style_rgba(ctx, "Selected Color:", &chart.selected_color); - style_rgba(ctx, "Color:", &chart.color); - - style_vec2(ctx, "Padding:", &chart.padding); - - nk_property_float(ctx, "#Border:", -100.0f, &chart.border, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Rounding:", -100.0f, &chart.rounding, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Color Factor:", 0.0f, &chart.color_factor, 1.0f, 0.1f, 0.0025f); - nk_property_float(ctx, "#Disabled Factor:", 0.0f, &chart.disabled_factor, 1.0f, 0.1f, 0.0025f); - - *out_style = chart; -} - -static void -style_combo(struct nk_context *ctx, struct nk_style_combo *out_style) -{ - struct nk_style_combo combo = *out_style; - - nk_layout_row_dynamic(ctx, 30, 2); - - style_item_color(ctx, "Normal:", &combo.normal); - style_item_color(ctx, "Hover:", &combo.hover); - style_item_color(ctx, "Active:", &combo.active); - - style_rgba(ctx, "Border:", &combo.border_color); - style_rgba(ctx, "Label Normal:", &combo.label_normal); - style_rgba(ctx, "Label Hover:", &combo.label_hover); - style_rgba(ctx, "Label Active:", &combo.label_active); - - nk_label(ctx, "Normal Symbol:", NK_TEXT_LEFT); - combo.sym_normal = nk_combo(ctx, symbols, NK_SYMBOL_MAX, combo.sym_normal, 25, nk_vec2(200, 200)); - nk_label(ctx, "Hover Symbol:", NK_TEXT_LEFT); - combo.sym_hover = nk_combo(ctx, symbols, NK_SYMBOL_MAX, combo.sym_hover, 25, nk_vec2(200, 200)); - nk_label(ctx, "Active Symbol:", NK_TEXT_LEFT); - combo.sym_active = nk_combo(ctx, symbols, NK_SYMBOL_MAX, combo.sym_active, 25, nk_vec2(200, 200)); - - style_vec2(ctx, "Content Padding:", &combo.content_padding); - style_vec2(ctx, "Button Padding:", &combo.button_padding); - style_vec2(ctx, "Spacing:", &combo.spacing); - - nk_property_float(ctx, "#Border:", -100.0f, &combo.border, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Rounding:", -100.0f, &combo.rounding, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Color Factor:", 0.0f, &combo.color_factor, 1.0f, 0.1f, 0.0025f); - nk_property_float(ctx, "#Disabled Factor:", 0.0f, &combo.disabled_factor, 1.0f, 0.1f, 0.0025f); - - *out_style = combo; -} - -static void -style_tab(struct nk_context *ctx, struct nk_style_tab *out_style) -{ - struct nk_style_tab tab = *out_style; - - nk_layout_row_dynamic(ctx, 30, 2); - - style_item_color(ctx, "Background:", &tab.background); - - style_rgba(ctx, "Border:", &tab.border_color); - style_rgba(ctx, "Text:", &tab.text); - - /* - * FTR, I feel these fields are misnamed and should be sym_minimized and sym_maximized since they are - * what show in that state, not the button to push to get to that state - */ - nk_label(ctx, "Minimized Symbol:", NK_TEXT_LEFT); - tab.sym_minimize = nk_combo(ctx, symbols, NK_SYMBOL_MAX, tab.sym_minimize, 25, nk_vec2(200, 200)); - nk_label(ctx, "Maxmized Symbol:", NK_TEXT_LEFT); - tab.sym_maximize = nk_combo(ctx, symbols, NK_SYMBOL_MAX, tab.sym_maximize, 25, nk_vec2(200, 200)); - - style_vec2(ctx, "Padding:", &tab.padding); - style_vec2(ctx, "Spacing:", &tab.spacing); - - nk_property_float(ctx, "#Indent:", -100.0f, &tab.indent, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Border:", -100.0f, &tab.border, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Rounding:", -100.0f, &tab.rounding, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Color Factor:", 0.0f, &tab.color_factor, 1.0f, 0.1f, 0.0025f); - nk_property_float(ctx, "#Disabled Factor:", 0.0f, &tab.disabled_factor, 1.0f, 0.1f, 0.0025f); - - *out_style = tab; -} - -static void -style_window_header(struct nk_context *ctx, struct nk_style_window_header *out_style) -{ - struct nk_style_window_header header = *out_style; - struct nk_style_button *dups[1]; - - nk_layout_row_dynamic(ctx, 30, 2); - - style_item_color(ctx, "Normal:", &header.normal); - style_item_color(ctx, "Hover:", &header.hover); - style_item_color(ctx, "Active:", &header.active); - - style_rgba(ctx, "Label Normal:", &header.label_normal); - style_rgba(ctx, "Label Hover:", &header.label_hover); - style_rgba(ctx, "Label Active:", &header.label_active); - - style_vec2(ctx, "Label Padding:", &header.label_padding); - style_vec2(ctx, "Padding:", &header.padding); - style_vec2(ctx, "Spacing:", &header.spacing); - -#define NUM_ALIGNS 2 - { - const char *alignments[NUM_ALIGNS] = {"LEFT", "RIGHT"}; - - nk_layout_row_dynamic(ctx, 30, 2); - nk_label(ctx, "Button Alignment:", NK_TEXT_LEFT); - header.align = nk_combo(ctx, alignments, NUM_ALIGNS, header.align, 25, nk_vec2(200, 200)); - } -#undef NUM_ALIGNS - - nk_label(ctx, "Close Symbol:", NK_TEXT_LEFT); - header.close_symbol = nk_combo(ctx, symbols, NK_SYMBOL_MAX, header.close_symbol, 25, nk_vec2(200, 200)); - nk_label(ctx, "Minimize Symbol:", NK_TEXT_LEFT); - header.minimize_symbol = nk_combo(ctx, symbols, NK_SYMBOL_MAX, header.minimize_symbol, 25, nk_vec2(200, 200)); - nk_label(ctx, "Maximize Symbol:", NK_TEXT_LEFT); - header.maximize_symbol = nk_combo(ctx, symbols, NK_SYMBOL_MAX, header.maximize_symbol, 25, nk_vec2(200, 200)); - - /* necessary or do tree's always take the whole width? */ - /* nk_layout_row_dynamic(ctx, 30, 1); */ - if (nk_tree_push(ctx, NK_TREE_TAB, "Close and Minimize Button", NK_MAXIMIZED)) { - dups[0] = &header.minimize_button; - style_button(ctx, &header.close_button, dups, 1); - nk_tree_pop(ctx); - } - - *out_style = header; -} - -static void -style_window(struct nk_context *ctx, struct nk_style_window *out_style) -{ - static const char *tooltip_positions[] = { - "TOP_LEFT", - "TOP_CENTER", - "TOP_RIGHT", - - "MIDDLE_LEFT", - "MIDDLE_CENTER", - "MIDDLE_RIGHT", - - "BOTTOM_LEFT", - "BOTTOM_CENTER", - "BOTTOM_RIGHT", - }; - /*static int cur_tooltip_pos = NK_TOP_LEFT;*/ - - struct nk_style_window win = *out_style; - - nk_layout_row_dynamic(ctx, 30, 2); - - style_rgba(ctx, "Background:", &win.background); - - style_item_color(ctx, "Fixed Background:", &win.fixed_background); - - style_rgba(ctx, "Border:", &win.border_color); - style_rgba(ctx, "Popup Border:", &win.popup_border_color); - style_rgba(ctx, "Combo Border:", &win.combo_border_color); - style_rgba(ctx, "Contextual Border:", &win.contextual_border_color); - style_rgba(ctx, "Menu Border:", &win.menu_border_color); - style_rgba(ctx, "Group Border:", &win.group_border_color); - style_rgba(ctx, "Tooltip Border:", &win.tooltip_border_color); - - style_item_color(ctx, "Scaler:", &win.scaler); - - style_vec2(ctx, "Spacing:", &win.spacing); - style_vec2(ctx, "Scrollbar Size:", &win.scrollbar_size); - style_vec2(ctx, "Min Size:", &win.min_size); - style_vec2(ctx, "Padding:", &win.padding); - style_vec2(ctx, "Group Padding:", &win.group_padding); - style_vec2(ctx, "Popup Padding:", &win.popup_padding); - style_vec2(ctx, "Combo Padding:", &win.combo_padding); - style_vec2(ctx, "Contextual Padding:", &win.contextual_padding); - style_vec2(ctx, "Menu Padding:", &win.menu_padding); - style_vec2(ctx, "Tooltip Padding:", &win.tooltip_padding); - - nk_label(ctx, "Tooltip Origin", NK_TEXT_LEFT); - win.tooltip_origin = - nk_combo(ctx, tooltip_positions, NK_LEN(tooltip_positions), win.tooltip_origin, 25, nk_vec2(200, 200)); - style_vec2(ctx, "Tooltip offset:", &win.tooltip_offset); - - nk_property_float(ctx, "#Rounding:", -100.0f, &win.rounding, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Combo Border:", -100.0f, &win.combo_border, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Contextual Border:", -100.0f, &win.contextual_border, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Menu Border:", -100.0f, &win.menu_border, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Group Border:", -100.0f, &win.group_border, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Tooltip Border:", -100.0f, &win.tooltip_border, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Popup Border:", -100.0f, &win.popup_border, 100.0f, 1.0f, 0.5f); - nk_property_float(ctx, "#Border:", -100.0f, &win.border, 100.0f, 1.0f, 0.5f); - - nk_layout_row_dynamic(ctx, 30, 1); - nk_property_float(ctx, "#Min Row Height Padding:", -100.0f, &win.min_row_height_padding, 100.0f, 1.0f, 0.5f); - - if (nk_tree_push(ctx, NK_TREE_TAB, "Window Header", NK_MAXIMIZED)) { - style_window_header(ctx, &win.header); - nk_tree_pop(ctx); - } - - *out_style = win; -} - -int -test_ui_style_configurator(struct nk_context *ctx, - struct nk_color color_table[NK_COLOR_COUNT], - unsigned int viewport_width, - unsigned int viewport_height) -{ - /* window flags */ - int border = nk_true; - int resize = nk_true; - int movable = nk_true; - int no_scrollbar = nk_false; - int scale_left = nk_false; - nk_flags window_flags = 0; - int minimizable = nk_true; - struct nk_style *style = NULL; - struct nk_style_button *dups[1]; - - /* window flags */ - window_flags = 0; - if (border) { - window_flags |= NK_WINDOW_BORDER; - } - - if (resize) { - window_flags |= NK_WINDOW_SCALABLE; - } - - if (movable) { - window_flags |= NK_WINDOW_MOVABLE; - } - - if (no_scrollbar) { - window_flags |= NK_WINDOW_NO_SCROLLBAR; - } - - if (scale_left) { - window_flags |= NK_WINDOW_SCALE_LEFT; - } - - if (minimizable) { - window_flags |= NK_WINDOW_MINIMIZABLE; - } - - style = &ctx->style; - - const char *name = "configurator"; - struct nk_rect bounds = {0}; - struct nk_window *win = nk_window_find(ctx, name); - if (win) { - bounds = win->bounds; - } - - char title[256] = {0}; - stbsp_snprintf(title, sizeof(title), "Configurator (%.1f, %.1f) %.1fx%.1f", bounds.x, bounds.y, bounds.w, bounds.h); - - if (nk_begin_titled( - ctx, name, title, nk_rect(viewport_width / 2.0f, 0, viewport_width / 2.0f, (float)viewport_height), window_flags)) { - if (nk_tree_push(ctx, NK_TREE_TAB, "Global Colors", NK_MAXIMIZED)) { - style_global_colors(ctx, color_table); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Text", NK_MAXIMIZED)) { - style_text(ctx, &style->text); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Button", NK_MAXIMIZED)) { - style_button(ctx, &style->button, NULL, 0); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Contextual Button", NK_MAXIMIZED)) { - style_button(ctx, &style->contextual_button, NULL, 0); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Menu Button", NK_MAXIMIZED)) { - style_button(ctx, &style->menu_button, NULL, 0); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Combo Buttons", NK_MAXIMIZED)) { - style_button(ctx, &style->combo.button, NULL, 0); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Tab Min/Max Buttons", NK_MAXIMIZED)) { - dups[0] = &style->tab.tab_maximize_button; - style_button(ctx, &style->tab.tab_minimize_button, dups, 1); - nk_tree_pop(ctx); - } - if (nk_tree_push(ctx, NK_TREE_TAB, "Node Min/Max Buttons", NK_MAXIMIZED)) { - dups[0] = &style->tab.node_maximize_button; - style_button(ctx, &style->tab.node_minimize_button, dups, 1); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Window Header Close Buttons", NK_MAXIMIZED)) { - style_button(ctx, &style->window.header.close_button, NULL, 0); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Window Header Minimize Buttons", NK_MAXIMIZED)) { - style_button(ctx, &style->window.header.minimize_button, NULL, 0); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Checkbox", NK_MAXIMIZED)) { - style_toggle(ctx, &style->checkbox); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Option", NK_MAXIMIZED)) { - style_toggle(ctx, &style->option); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Selectable", NK_MAXIMIZED)) { - style_selectable(ctx, &style->selectable); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Slider", NK_MAXIMIZED)) { - style_slider(ctx, &style->slider); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Knob", NK_MAXIMIZED)) { - style_knob(ctx, &style->knob); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Progress", NK_MAXIMIZED)) { - style_progress(ctx, &style->progress); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Scrollbars", NK_MAXIMIZED)) { - struct nk_style_scrollbar *dups[1]; - dups[0] = &style->scrollv; - style_scrollbars(ctx, &style->scrollh, dups, 1); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Edit", NK_MAXIMIZED)) { - style_edit(ctx, &style->edit); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Property", NK_MAXIMIZED)) { - style_property(ctx, &style->property); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Chart", NK_MAXIMIZED)) { - style_chart(ctx, &style->chart); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Combo", NK_MAXIMIZED)) { - style_combo(ctx, &style->combo); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Tab", NK_MAXIMIZED)) { - style_tab(ctx, &style->tab); - nk_tree_pop(ctx); - } - - if (nk_tree_push(ctx, NK_TREE_TAB, "Window", NK_MAXIMIZED)) { - style_window(ctx, &style->window); - nk_tree_pop(ctx); - } - - nk_layout_row_dynamic(ctx, 30, 1); - if (nk_button_label(ctx, "Reset all styles to defaults")) { - memcpy(color_table, nk_default_color_style, sizeof(nk_default_color_style)); - nk_style_default(ctx); - } - } - - nk_end(ctx); - return !nk_window_is_closed(ctx, "Configurator"); -} diff --git a/vendor/lua/src/luaconf.h b/vendor/lua/src/luaconf.h index 33bb580..0d8f68e 100644 --- a/vendor/lua/src/luaconf.h +++ b/vendor/lua/src/luaconf.h @@ -284,7 +284,11 @@ ** the libraries, you may want to use the following definition (define ** LUA_BUILD_AS_DLL to get it). */ -#if defined(LUA_BUILD_AS_DLL) /* { */ +#if defined(OVERDUB_BUILD_DLL) /* { */ + +#define LUA_API __declspec(dllexport) + +#elif defined(LUA_BUILD_AS_DLL) /* }{ */ #if defined(LUA_CORE) || defined(LUA_LIB) /* { */ #define LUA_API __declspec(dllexport) @@ -799,4 +803,3 @@ #endif - diff --git a/vendor/minhook/src/buffer.c b/vendor/minhook/src/buffer.c index 940df65..0ef74e4 100644 --- a/vendor/minhook/src/buffer.c +++ b/vendor/minhook/src/buffer.c @@ -1,4 +1,4 @@ -/* +/* * MinHook - The Minimalistic API Hooking Library for x64/x86 * Copyright (C) 2009-2017 Tsuda Kageyu. * All rights reserved. diff --git a/vendor/minhook/src/buffer.h b/vendor/minhook/src/buffer.h index 204d551..c6f6991 100644 --- a/vendor/minhook/src/buffer.h +++ b/vendor/minhook/src/buffer.h @@ -1,4 +1,4 @@ -/* +/* * MinHook - The Minimalistic API Hooking Library for x64/x86 * Copyright (C) 2009-2017 Tsuda Kageyu. * All rights reserved. diff --git a/vendor/minhook/src/hde/hde32.c b/vendor/minhook/src/hde/hde32.c index eb6af9b..e8af7df 100644 --- a/vendor/minhook/src/hde/hde32.c +++ b/vendor/minhook/src/hde/hde32.c @@ -1,4 +1,4 @@ -/* +/* * Hacker Disassembler Engine 32 C * Copyright (c) 2008-2009, Vyacheslav Patkov. * All rights reserved. diff --git a/vendor/minhook/src/hde/hde32.h b/vendor/minhook/src/hde/hde32.h index 1112450..de28c68 100644 --- a/vendor/minhook/src/hde/hde32.h +++ b/vendor/minhook/src/hde/hde32.h @@ -1,4 +1,4 @@ -/* +/* * Hacker Disassembler Engine 32 * Copyright (c) 2006-2009, Vyacheslav Patkov. * All rights reserved. diff --git a/vendor/minhook/src/hde/hde64.c b/vendor/minhook/src/hde/hde64.c index 75dc0cb..d0b0d79 100644 --- a/vendor/minhook/src/hde/hde64.c +++ b/vendor/minhook/src/hde/hde64.c @@ -1,4 +1,4 @@ -/* +/* * Hacker Disassembler Engine 64 C * Copyright (c) 2008-2009, Vyacheslav Patkov. * All rights reserved. diff --git a/vendor/minhook/src/hde/hde64.h b/vendor/minhook/src/hde/hde64.h index ecbf4df..ecd7281 100644 --- a/vendor/minhook/src/hde/hde64.h +++ b/vendor/minhook/src/hde/hde64.h @@ -1,4 +1,4 @@ -/* +/* * Hacker Disassembler Engine 64 * Copyright (c) 2008-2009, Vyacheslav Patkov. * All rights reserved. diff --git a/vendor/minhook/src/hde/pstdint.h b/vendor/minhook/src/hde/pstdint.h index 84d82a0..c998529 100644 --- a/vendor/minhook/src/hde/pstdint.h +++ b/vendor/minhook/src/hde/pstdint.h @@ -1,4 +1,4 @@ -/* +/* * MinHook - The Minimalistic API Hooking Library for x64/x86 * Copyright (C) 2009-2017 Tsuda Kageyu. All rights reserved. * diff --git a/vendor/minhook/src/hde/table32.h b/vendor/minhook/src/hde/table32.h index 7b3e12e..e1e1de6 100644 --- a/vendor/minhook/src/hde/table32.h +++ b/vendor/minhook/src/hde/table32.h @@ -1,4 +1,4 @@ -/* +/* * Hacker Disassembler Engine 32 C * Copyright (c) 2008-2009, Vyacheslav Patkov. * All rights reserved. diff --git a/vendor/minhook/src/hde/table64.h b/vendor/minhook/src/hde/table64.h index 01d4541..144f290 100644 --- a/vendor/minhook/src/hde/table64.h +++ b/vendor/minhook/src/hde/table64.h @@ -1,4 +1,4 @@ -/* +/* * Hacker Disassembler Engine 64 C * Copyright (c) 2008-2009, Vyacheslav Patkov. * All rights reserved. diff --git a/vendor/minhook/src/hook.c b/vendor/minhook/src/hook.c index eb7f354..247f3f9 100644 --- a/vendor/minhook/src/hook.c +++ b/vendor/minhook/src/hook.c @@ -1,4 +1,4 @@ -/* +/* * MinHook - The Minimalistic API Hooking Library for x64/x86 * Copyright (C) 2009-2017 Tsuda Kageyu. * All rights reserved. diff --git a/vendor/minhook/src/trampoline.c b/vendor/minhook/src/trampoline.c index d4d6f99..49682dc 100644 --- a/vendor/minhook/src/trampoline.c +++ b/vendor/minhook/src/trampoline.c @@ -1,4 +1,4 @@ -/* +/* * MinHook - The Minimalistic API Hooking Library for x64/x86 * Copyright (C) 2009-2017 Tsuda Kageyu. * All rights reserved. diff --git a/vendor/minhook/src/trampoline.h b/vendor/minhook/src/trampoline.h index bdffdac..62e8718 100644 --- a/vendor/minhook/src/trampoline.h +++ b/vendor/minhook/src/trampoline.h @@ -1,4 +1,4 @@ -/* +/* * MinHook - The Minimalistic API Hooking Library for x64/x86 * Copyright (C) 2009-2017 Tsuda Kageyu. * All rights reserved.