diff --git a/android/framework/decode/CMakeLists.txt b/android/framework/decode/CMakeLists.txt index d7052f26b..466129085 100644 --- a/android/framework/decode/CMakeLists.txt +++ b/android/framework/decode/CMakeLists.txt @@ -53,6 +53,9 @@ target_sources(gfxrecon_decode ${GFXRECON_SOURCE_DIR}/framework/decode/vulkan_decoder_base.cpp ${GFXRECON_SOURCE_DIR}/framework/decode/vulkan_default_allocator.h ${GFXRECON_SOURCE_DIR}/framework/decode/vulkan_default_allocator.cpp + ${GFXRECON_SOURCE_DIR}/framework/decode/vulkan_address_replacer.h + ${GFXRECON_SOURCE_DIR}/framework/decode/vulkan_address_replacer.cpp + ${GFXRECON_SOURCE_DIR}/framework/decode/vulkan_address_replacer_shaders.h ${GFXRECON_SOURCE_DIR}/framework/decode/vulkan_device_address_tracker.h ${GFXRECON_SOURCE_DIR}/framework/decode/vulkan_device_address_tracker.cpp ${GFXRECON_SOURCE_DIR}/framework/decode/vulkan_captured_swapchain.h diff --git a/android/layer/build.gradle b/android/layer/build.gradle index 6d440621d..8e0f24168 100644 --- a/android/layer/build.gradle +++ b/android/layer/build.gradle @@ -24,7 +24,7 @@ android { } externalNativeBuild { cmake { - cppFlags "-fexceptions", "-std=c++14", "-Wno-nullability-completeness" + cppFlags "-fexceptions", "-std=c++17", "-Wno-nullability-completeness" arguments "-DANDROID_TOOLCHAIN=clang", "-DANDROID_STL=c++_static" } } diff --git a/android/tools/replay/build.gradle b/android/tools/replay/build.gradle index bdd8887f5..73b66dfe8 100644 --- a/android/tools/replay/build.gradle +++ b/android/tools/replay/build.gradle @@ -25,7 +25,7 @@ android { } externalNativeBuild { cmake { - cppFlags "-fexceptions", "-std=c++14", "-Wno-nullability-completeness" + cppFlags "-fexceptions", "-std=c++17", "-Wno-nullability-completeness" arguments "-DANDROID_TOOLCHAIN=clang", "-DANDROID_STL=c++_static" } } diff --git a/framework/decode/CMakeLists.txt b/framework/decode/CMakeLists.txt index 29a910fc3..75e6f8d65 100644 --- a/framework/decode/CMakeLists.txt +++ b/framework/decode/CMakeLists.txt @@ -149,6 +149,9 @@ target_sources(gfxrecon_decode ${CMAKE_CURRENT_LIST_DIR}/vulkan_decoder_base.cpp ${CMAKE_CURRENT_LIST_DIR}/vulkan_default_allocator.h ${CMAKE_CURRENT_LIST_DIR}/vulkan_default_allocator.cpp + ${CMAKE_CURRENT_LIST_DIR}/vulkan_address_replacer.h + ${CMAKE_CURRENT_LIST_DIR}/vulkan_address_replacer.cpp + ${CMAKE_CURRENT_LIST_DIR}/vulkan_address_replacer_shaders.h ${CMAKE_CURRENT_LIST_DIR}/vulkan_device_address_tracker.h ${CMAKE_CURRENT_LIST_DIR}/vulkan_device_address_tracker.cpp ${CMAKE_CURRENT_LIST_DIR}/vulkan_captured_swapchain.h diff --git a/framework/decode/vulkan_address_replacer.cpp b/framework/decode/vulkan_address_replacer.cpp new file mode 100644 index 000000000..c9e80b566 --- /dev/null +++ b/framework/decode/vulkan_address_replacer.cpp @@ -0,0 +1,749 @@ +/* +** Copyright (c) 2024 LunarG, Inc. +** +** 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. +*/ + +#include "decode/vulkan_address_replacer.h" +#include "decode/vulkan_address_replacer_shaders.h" +#include "util/logging.h" + +GFXRECON_BEGIN_NAMESPACE(gfxrecon) +GFXRECON_BEGIN_NAMESPACE(decode) + +inline uint32_t aligned_size(uint32_t size, uint32_t alignment) +{ + return (size + alignment - 1) & ~(alignment - 1); +} + +inline uint32_t div_up(uint32_t nom, uint32_t denom) +{ + GFXRECON_ASSERT(denom > 0) + return (nom + denom - 1) / denom; +} + +uint32_t get_memory_type_index(const VkPhysicalDeviceMemoryProperties& memory_properties, + uint32_t type_bits, + VkMemoryPropertyFlags property_flags) +{ + uint32_t memory_type_index = std::numeric_limits::max(); + + for (uint32_t i = 0; i < memory_properties.memoryTypeCount; ++i) + { + if ((type_bits & (1 << i)) && + ((memory_properties.memoryTypes[i].propertyFlags & property_flags) == property_flags)) + { + memory_type_index = i; + break; + } + } + + return memory_type_index; +} + +//! 16 bytes +struct hashmap_t +{ + VkDeviceAddress storage; + uint32_t size; + uint32_t capacity; +}; + +struct replacer_params_t +{ + hashmap_t hashmap; + + // input-/output-arrays can be identical when sbt-alignments/strides match + VkDeviceAddress input_handles, output_handles; + uint32_t num_handles; +}; + +decode::VulkanAddressReplacer::buffer_context_t::~buffer_context_t() +{ + if (resource_allocator != nullptr) + { + if (buffer != VK_NULL_HANDLE) + { + resource_allocator->DestroyBufferDirect(buffer, nullptr, allocator_data); + } + if (device_memory != VK_NULL_HANDLE) + { + resource_allocator->FreeMemoryDirect(device_memory, nullptr, memory_data); + } + } +} + +VulkanAddressReplacer::VulkanAddressReplacer(const VulkanDeviceInfo* device_info, + const encode::VulkanDeviceTable* device_table, + const decode::CommonObjectInfoTable& object_table) : + device_table_(device_table) +{ + GFXRECON_ASSERT(device_info != nullptr && device_table != nullptr) + + const VulkanPhysicalDeviceInfo* physical_device_info = object_table.GetVkPhysicalDeviceInfo(device_info->parent_id); + device_ = device_info->handle; + resource_allocator_ = device_info->allocator.get(); + get_device_address_fn_ = physical_device_info->parent_api_version >= VK_API_VERSION_1_2 + ? device_table->GetBufferDeviceAddress + : device_table->GetBufferDeviceAddressKHR; + + if (physical_device_info != nullptr && physical_device_info->capture_raytracing_properties && + physical_device_info->replay_device_info->raytracing_properties) + { + capture_ray_properties_ = *physical_device_info->capture_raytracing_properties; + replay_ray_properties_ = *physical_device_info->replay_device_info->raytracing_properties; + + if (capture_ray_properties_.shaderGroupHandleSize != replay_ray_properties_.shaderGroupHandleSize || + capture_ray_properties_.shaderGroupHandleAlignment != replay_ray_properties_.shaderGroupHandleAlignment || + capture_ray_properties_.shaderGroupBaseAlignment != replay_ray_properties_.shaderGroupBaseAlignment) + { + valid_sbt_alignment_ = false; + } + + GFXRECON_ASSERT(physical_device_info->replay_device_info != nullptr); + GFXRECON_ASSERT(physical_device_info->replay_device_info->memory_properties.has_value()); + memory_properties_ = *physical_device_info->replay_device_info->memory_properties; + } +} + +VulkanAddressReplacer::VulkanAddressReplacer(VulkanAddressReplacer&& other) noexcept : VulkanAddressReplacer() +{ + swap(*this, other); +} + +VulkanAddressReplacer::~VulkanAddressReplacer() +{ + if (pipeline_bda_ != VK_NULL_HANDLE) + { + device_table_->DestroyPipeline(device_, pipeline_bda_, nullptr); + } + if (pipeline_sbt_ != VK_NULL_HANDLE) + { + device_table_->DestroyPipeline(device_, pipeline_sbt_, nullptr); + } + if (pipeline_layout_ != VK_NULL_HANDLE) + { + device_table_->DestroyPipelineLayout(device_, pipeline_layout_, nullptr); + } +} + +void VulkanAddressReplacer::ProcessCmdTraceRays( + const VulkanCommandBufferInfo* command_buffer_info, + VkStridedDeviceAddressRegionKHR* raygen_sbt, + VkStridedDeviceAddressRegionKHR* miss_sbt, + VkStridedDeviceAddressRegionKHR* hit_sbt, + VkStridedDeviceAddressRegionKHR* callable_sbt, + const decode::VulkanDeviceAddressTracker& address_tracker, + const std::unordered_map& group_handle_map) +{ + GFXRECON_ASSERT(device_table_ != nullptr); + + // NOTE: we expect this map to be populated here, but not for older captures (before #1844) using trimming. + if (group_handle_map.empty()) + { + // the capture appears to be older and is missing information we require here -> bail out + return; + } + + // figure out if the captured group-handles are valid for replay + bool valid_group_handles = true; + + for (const auto& [lhs, rhs] : group_handle_map) + { + if (lhs != rhs) + { + valid_group_handles = false; + break; + } + } + + // TODO: testing only -> remove when closing issue #1526 + // valid_sbt_alignment_ = false; + // valid_group_handles = false; + + if (!valid_sbt_alignment_ || !valid_group_handles) + { + if (pipeline_sbt_ == VK_NULL_HANDLE) + { + init_pipeline(); + } + std::unordered_set buffer_set; + + auto address_remap = [&address_tracker, &buffer_set](VkStridedDeviceAddressRegionKHR* address_region) { + if (address_region->size > 0) + { + auto buffer_info = address_tracker.GetBufferByCaptureDeviceAddress(address_region->deviceAddress); + GFXRECON_ASSERT(buffer_info != nullptr); + + if (buffer_info->replay_address != 0) + { + // keep track of used handles + buffer_set.insert(buffer_info->handle); + + uint64_t offset = address_region->deviceAddress - buffer_info->capture_address; + + // in-place address-remap + address_region->deviceAddress = buffer_info->replay_address + offset; + } + else + { + GFXRECON_LOG_WARNING_ONCE( + "VulkanAddressReplacer::ProcessCmdTraceRays: missing buffer_info->replay_address, remap failed") + } + } + }; + + // in-place remap: capture-addresses -> replay-addresses + address_remap(raygen_sbt); + address_remap(miss_sbt); + address_remap(hit_sbt); + address_remap(callable_sbt); + + // prepare linear hashmap + hashmap_sbt_.clear(); + + for (const auto& [lhs, rhs] : group_handle_map) + { + hashmap_sbt_.put(lhs, rhs); + } + + if (!create_buffer(hashmap_sbt_.get_storage(nullptr), pipeline_context_sbt_.hashmap_storage)) + { + GFXRECON_LOG_ERROR("VulkanAddressReplacer: hashmap-storage-buffer creation failed"); + } + hashmap_sbt_.get_storage(pipeline_context_sbt_.hashmap_storage.mapped_data); + + // input-handles + constexpr uint32_t max_num_handles = 4; + if (!create_buffer(max_num_handles * sizeof(VkDeviceAddress), pipeline_context_sbt_.input_handle_buffer)) + { + GFXRECON_LOG_ERROR("VulkanAddressReplacer: input-handle-buffer creation failed"); + } + auto input_addresses = + reinterpret_cast(pipeline_context_sbt_.input_handle_buffer.mapped_data); + uint32_t num_addresses = 0; + + for (const auto& region : { raygen_sbt, miss_sbt, hit_sbt, callable_sbt }) + { + if (region != nullptr && region->size) + { + input_addresses[num_addresses++] = region->deviceAddress; + } + } + + replacer_params_t replacer_params = {}; + replacer_params.hashmap.storage = pipeline_context_sbt_.hashmap_storage.device_address; + replacer_params.hashmap.size = hashmap_sbt_.size(); + replacer_params.hashmap.capacity = hashmap_sbt_.capacity(); + + replacer_params.input_handles = pipeline_context_sbt_.input_handle_buffer.device_address; + replacer_params.num_handles = num_addresses; + + if (valid_sbt_alignment_) + { + // rewrite group-handles in-place + replacer_params.output_handles = replacer_params.input_handles; + + // pre memory-barrier + for (const auto& buf : buffer_set) + { + barrier(command_buffer_info->handle, + buf, + VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR, + VK_ACCESS_SHADER_READ_BIT, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_ACCESS_SHADER_WRITE_BIT); + } + } + else + { + // output-handles + if (!create_buffer(max_num_handles * sizeof(VkDeviceAddress), pipeline_context_sbt_.output_handle_buffer)) + { + GFXRECON_LOG_ERROR("VulkanAddressReplacer: input-handle-buffer creation failed"); + } + // output to shadow-sbt-buffer + replacer_params.output_handles = pipeline_context_sbt_.output_handle_buffer.device_address; + + // find/create shadow-SBT-buffer + uint32_t sbt_offset = 0; + auto& shadow_buf_context = shadow_sbt_map_[command_buffer_info->handle]; + + const uint32_t handle_size_aligned = aligned_size(replay_ray_properties_.shaderGroupHandleSize, + replay_ray_properties_.shaderGroupHandleAlignment); + + for (auto& region : { raygen_sbt, miss_sbt, hit_sbt, callable_sbt }) + { + if (region != nullptr) + { + uint32_t num_handles_limit = region->size / region->stride; + uint32_t group_size = aligned_size(num_handles_limit * handle_size_aligned, + replay_ray_properties_.shaderGroupBaseAlignment); + sbt_offset += group_size; + + // adjust group-size + region->size = group_size; + region->stride = handle_size_aligned; + } + } + // raygen: stride == size + raygen_sbt->size = raygen_sbt->stride = replay_ray_properties_.shaderGroupBaseAlignment; + + if (!create_buffer(sbt_offset, shadow_buf_context, VK_BUFFER_USAGE_SHADER_BINDING_TABLE_BIT_KHR)) + { + GFXRECON_LOG_ERROR("VulkanAddressReplacer: shadow shader-binding-table creation failed"); + } + + auto output_addresses = + reinterpret_cast(pipeline_context_sbt_.output_handle_buffer.mapped_data); + uint32_t out_index = 0; + sbt_offset = 0; + for (auto& region : { raygen_sbt, miss_sbt, hit_sbt, callable_sbt }) + { + if (region != nullptr) + { + // assign shadow-sbt-address + region->deviceAddress = shadow_buf_context.device_address + sbt_offset; + sbt_offset += region->size; + output_addresses[out_index++] = region->deviceAddress; + } + } + } + + device_table_->CmdBindPipeline(command_buffer_info->handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_sbt_); + + // NOTE: using push-constants here requires us to re-establish the previous data, if any + device_table_->CmdPushConstants(command_buffer_info->handle, + pipeline_layout_, + VK_SHADER_STAGE_COMPUTE_BIT, + 0, + sizeof(replacer_params_t), + &replacer_params); + // run a single workgroup + constexpr uint32_t wg_size = 32; + device_table_->CmdDispatch(command_buffer_info->handle, div_up(replacer_params.num_handles, wg_size), 1, 1); + + // post memory-barrier + for (const auto& buf : buffer_set) + { + barrier(command_buffer_info->handle, + buf, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_ACCESS_SHADER_WRITE_BIT, + VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, + VK_ACCESS_SHADER_READ_BIT); + } + + // set previous push-constant data + if (!command_buffer_info->push_constant_data.empty()) + { + device_table_->CmdPushConstants(command_buffer_info->handle, + command_buffer_info->push_constant_pipeline_layout, + command_buffer_info->push_constant_stage_flags, + 0, + command_buffer_info->push_constant_data.size(), + command_buffer_info->push_constant_data.data()); + } + } // !valid_sbt_alignment_ || !valid_group_handles +} + +void VulkanAddressReplacer::ProcessCmdBuildAccelerationStructuresKHR( + const VulkanCommandBufferInfo* command_buffer_info, + uint32_t info_count, + VkAccelerationStructureBuildGeometryInfoKHR* build_geometry_infos, + VkAccelerationStructureBuildRangeInfoKHR** build_range_infos, + const VulkanDeviceAddressTracker& address_tracker) +{ + GFXRECON_ASSERT(device_table_ != nullptr); + + // TODO: testing only -> remove when closing issue #1526 + constexpr bool force_replace = false; + + std::unordered_set buffer_set; + auto address_remap = [&address_tracker, &buffer_set](VkDeviceAddress& capture_address) { + auto buffer_info = address_tracker.GetBufferByCaptureDeviceAddress(capture_address); + + if (buffer_info != nullptr && buffer_info->replay_address != 0) + { + // keep track of used handles + buffer_set.insert(buffer_info->handle); + + uint64_t offset = capture_address - buffer_info->capture_address; + + // in-place address-remap via const-cast + capture_address = buffer_info->replay_address + offset; + } + else + { + GFXRECON_LOG_WARNING( + "ProcessCmdBuildAccelerationStructuresKHR: missing buffer_info->replay_address, remap failed"); + } + }; + + std::vector addresses_to_replace; + + for (uint32_t i = 0; i < info_count; ++i) + { + auto& build_geometry_info = build_geometry_infos[i]; + auto range_info = build_range_infos[i]; + + // check/correct scratch-address + address_remap(build_geometry_info.scratchData.deviceAddress); + + for (uint32_t j = 0; j < build_geometry_info.geometryCount; ++j) + { + auto geometry = const_cast(build_geometry_info.pGeometries != nullptr + ? build_geometry_info.pGeometries + j + : build_geometry_info.ppGeometries[j]); + switch (geometry->geometryType) + { + case VK_GEOMETRY_TYPE_TRIANGLES_KHR: + { + auto& triangles = geometry->geometry.triangles; + address_remap(triangles.vertexData.deviceAddress); + address_remap(triangles.indexData.deviceAddress); + break; + } + case VK_GEOMETRY_TYPE_AABBS_KHR: + { + auto& aabbs = geometry->geometry.aabbs; + address_remap(aabbs.data.deviceAddress); + break; + } + case VK_GEOMETRY_TYPE_INSTANCES_KHR: + { + auto& instances = geometry->geometry.instances; + address_remap(instances.data.deviceAddress); + + // replace VkAccelerationStructureInstanceKHR::accelerationStructureReference inside buffer + for (uint32_t k = 0; k < range_info->primitiveCount; ++k) + { + VkDeviceAddress accel_structure_reference = + instances.data.deviceAddress + k * sizeof(VkAccelerationStructureInstanceKHR) + + offsetof(VkAccelerationStructureInstanceKHR, accelerationStructureReference); + addresses_to_replace.push_back(accel_structure_reference); + } + break; + } + default: + GFXRECON_LOG_ERROR( + "OverrideCmdBuildAccelerationStructuresKHR: unhandled case in switch-statement: %d", + geometry->geometryType); + break; + } + } + } + + if (!addresses_to_replace.empty()) + { + // prepare linear hashmap + hashmap_bda_.clear(); + auto acceleration_structure_map = address_tracker.GetAccelerationStructureDeviceAddressMap(); + for (const auto& [capture_address, replay_address] : acceleration_structure_map) + { + if (force_replace || capture_address != replay_address) + { + // store addresses we will need to replace + hashmap_bda_.put(capture_address, replay_address); + } + } + + if (!hashmap_bda_.empty()) + { + if (pipeline_bda_ == VK_NULL_HANDLE) + { + init_pipeline(); + } + + if (!create_buffer(hashmap_bda_.get_storage(nullptr), pipeline_context_bda_.hashmap_storage)) + { + GFXRECON_LOG_ERROR("VulkanAddressReplacer: hashmap-storage-buffer creation failed"); + } + hashmap_bda_.get_storage(pipeline_context_bda_.hashmap_storage.mapped_data); + + uint32_t num_bytes = addresses_to_replace.size() * sizeof(VkDeviceAddress); + + if (!create_buffer(num_bytes, pipeline_context_bda_.input_handle_buffer)) + { + GFXRECON_LOG_ERROR("VulkanAddressReplacer: input-handle-buffer creation failed"); + } + memcpy(pipeline_context_bda_.input_handle_buffer.mapped_data, addresses_to_replace.data(), num_bytes); + + replacer_params_t replacer_params = {}; + replacer_params.hashmap.storage = pipeline_context_bda_.hashmap_storage.device_address; + replacer_params.hashmap.size = hashmap_bda_.size(); + replacer_params.hashmap.capacity = hashmap_bda_.capacity(); + + // in-place + replacer_params.input_handles = pipeline_context_bda_.input_handle_buffer.device_address; + replacer_params.output_handles = pipeline_context_bda_.input_handle_buffer.device_address; + + replacer_params.num_handles = addresses_to_replace.size(); + + device_table_->CmdBindPipeline(command_buffer_info->handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline_bda_); + + // NOTE: using push-constants here requires us to re-establish the previous data, if any + device_table_->CmdPushConstants(command_buffer_info->handle, + pipeline_layout_, + VK_SHADER_STAGE_COMPUTE_BIT, + 0, + sizeof(replacer_params_t), + &replacer_params); + // run a single workgroup + constexpr uint32_t wg_size = 32; + device_table_->CmdDispatch(command_buffer_info->handle, div_up(replacer_params.num_handles, wg_size), 1, 1); + + // post memory-barrier + for (const auto& buf : buffer_set) + { + barrier(command_buffer_info->handle, + buf, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_ACCESS_SHADER_WRITE_BIT, + VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, + VK_ACCESS_SHADER_READ_BIT); + } + + // set previous push-constant data + if (!command_buffer_info->push_constant_data.empty()) + { + device_table_->CmdPushConstants(command_buffer_info->handle, + command_buffer_info->push_constant_pipeline_layout, + command_buffer_info->push_constant_stage_flags, + 0, + command_buffer_info->push_constant_data.size(), + command_buffer_info->push_constant_data.data()); + } + } + } +} + +void VulkanAddressReplacer::init_pipeline() +{ + if (pipeline_sbt_ != VK_NULL_HANDLE) + { + return; + } + VkPushConstantRange push_constant_range = {}; + push_constant_range.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT; + push_constant_range.offset = 0; + push_constant_range.size = sizeof(replacer_params_t); + + VkPipelineLayoutCreateInfo pipeline_layout_info = {}; + pipeline_layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; + pipeline_layout_info.pNext = nullptr; + pipeline_layout_info.flags = 0; + pipeline_layout_info.setLayoutCount = 0; + pipeline_layout_info.pSetLayouts = nullptr; + pipeline_layout_info.pushConstantRangeCount = 1; + pipeline_layout_info.pPushConstantRanges = &push_constant_range; + + VkResult result = device_table_->CreatePipelineLayout(device_, &pipeline_layout_info, nullptr, &pipeline_layout_); + + if (result != VK_SUCCESS) + { + GFXRECON_LOG_FATAL("VulkanAddressReplacer: failed in vkCreatePipelineLayout"); + } + + auto create_pipeline = [this](VkPipelineLayout layout, const auto& spirv, VkPipeline& out_pipeline) -> VkResult { + VkShaderModule compute_module = VK_NULL_HANDLE; + VkShaderModuleCreateInfo shader_module_create_info = {}; + shader_module_create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + shader_module_create_info.pNext = VK_NULL_HANDLE; + shader_module_create_info.flags = 0; + shader_module_create_info.codeSize = spirv.size(); + shader_module_create_info.pCode = reinterpret_cast(spirv.data()); + + VkResult result = + device_table_->CreateShaderModule(device_, &shader_module_create_info, nullptr, &compute_module); + + if (result != VK_SUCCESS) + { + GFXRECON_LOG_FATAL("VulkanAddressReplacer: failed in vkCreateShaderModule"); + return result; + } + VkPipelineShaderStageCreateInfo stage_info = {}; + stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + stage_info.pNext = nullptr; + stage_info.flags = 0; + stage_info.stage = VK_SHADER_STAGE_COMPUTE_BIT; + stage_info.module = compute_module; + stage_info.pName = "main"; + stage_info.pSpecializationInfo = nullptr; + + VkComputePipelineCreateInfo pipeline_create_info = {}; + pipeline_create_info.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; + pipeline_create_info.layout = layout; + pipeline_create_info.stage = stage_info; + + result = device_table_->CreateComputePipelines( + device_, VK_NULL_HANDLE, 1, &pipeline_create_info, VK_NULL_HANDLE, &out_pipeline); + + if (result != VK_SUCCESS) + { + GFXRECON_LOG_ERROR("VulkanAddressReplacer: pipeline creation failed"); + } + + if (compute_module != VK_NULL_HANDLE) + { + device_table_->DestroyShaderModule(device_, compute_module, nullptr); + } + return result; + }; + + // create SBT pipeline + create_pipeline(pipeline_layout_, g_replacer_sbt_comp, pipeline_sbt_); + + // create BDA pipeline + create_pipeline(pipeline_layout_, g_replacer_bda_comp, pipeline_bda_); +} + +bool VulkanAddressReplacer::create_buffer(size_t num_bytes, + VulkanAddressReplacer::buffer_context_t& buffer_context, + uint32_t usage_flags) +{ + // nothing to do + if (num_bytes <= buffer_context.num_bytes) + { + return true; + } + + // free previous resources + buffer_context = {}; + buffer_context.resource_allocator = resource_allocator_; + buffer_context.num_bytes = num_bytes; + + VkBufferCreateInfo buffer_create_info = {}; + buffer_create_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + buffer_create_info.usage = + VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | usage_flags; + buffer_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + buffer_create_info.queueFamilyIndexCount = 0; + buffer_create_info.size = num_bytes; + + VkResult result = resource_allocator_->CreateBufferDirect( + &buffer_create_info, nullptr, &buffer_context.buffer, &buffer_context.allocator_data); + if (result != VK_SUCCESS) + { + return false; + } + + VkMemoryRequirements memory_requirements; + device_table_->GetBufferMemoryRequirements(device_, buffer_context.buffer, &memory_requirements); + + uint32_t memory_type_index = + get_memory_type_index(memory_properties_, + memory_requirements.memoryTypeBits, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT); + + if (memory_type_index == std::numeric_limits::max()) + { + /* fallback to coherent */ + memory_type_index = + get_memory_type_index(memory_properties_, + memory_requirements.memoryTypeBits, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + } + + GFXRECON_ASSERT(memory_type_index != std::numeric_limits::max()); + + VkMemoryAllocateInfo alloc_info = {}; + alloc_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + alloc_info.allocationSize = memory_requirements.size; + alloc_info.memoryTypeIndex = memory_type_index; + + VkMemoryAllocateFlagsInfo alloc_flags_info = {}; + alloc_flags_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO; + alloc_flags_info.flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT; + alloc_info.pNext = &alloc_flags_info; + + result = resource_allocator_->AllocateMemoryDirect( + &alloc_info, nullptr, &buffer_context.device_memory, &buffer_context.memory_data); + + if (result != VK_SUCCESS) + { + return false; + } + + VkMemoryPropertyFlags memory_flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; + result = resource_allocator_->BindBufferMemory(buffer_context.buffer, + buffer_context.device_memory, + 0, + buffer_context.allocator_data, + buffer_context.memory_data, + &memory_flags); + if (result != VK_SUCCESS) + { + return false; + } + + // get device-address + VkBufferDeviceAddressInfo address_info = {}; + address_info.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO; + address_info.buffer = buffer_context.buffer; + buffer_context.device_address = get_device_address_fn_(device_, &address_info); + + // map buffer + result = resource_allocator_->MapResourceMemoryDirect( + VK_WHOLE_SIZE, 0, &buffer_context.mapped_data, buffer_context.allocator_data); + return result == VK_SUCCESS; +} + +void VulkanAddressReplacer::barrier(VkCommandBuffer command_buffer, + VkBuffer buffer, + VkPipelineStageFlags src_stage, + VkAccessFlags src_access, + VkPipelineStageFlags dst_stage, + VkAccessFlags dst_access) +{ + VkBufferMemoryBarrier barrier = {}; + barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; + barrier.buffer = buffer; + barrier.offset = 0; + barrier.size = VK_WHOLE_SIZE; + barrier.srcQueueFamilyIndex = barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + barrier.srcAccessMask = src_access; + barrier.dstAccessMask = dst_access; + + device_table_->CmdPipelineBarrier( + command_buffer, src_stage, dst_stage, VkDependencyFlags(0), 0, nullptr, 1, &barrier, 0, nullptr); +} + +void swap(VulkanAddressReplacer& lhs, VulkanAddressReplacer& rhs) noexcept +{ + std::swap(lhs.device_table_, rhs.device_table_); + std::swap(lhs.memory_properties_, rhs.memory_properties_); + std::swap(lhs.capture_ray_properties_, rhs.capture_ray_properties_); + std::swap(lhs.replay_ray_properties_, rhs.replay_ray_properties_); + std::swap(lhs.valid_sbt_alignment_, rhs.valid_sbt_alignment_); + std::swap(lhs.device_, rhs.device_); + std::swap(lhs.get_device_address_fn_, rhs.get_device_address_fn_); + std::swap(lhs.resource_allocator_, rhs.resource_allocator_); + std::swap(lhs.pipeline_layout_, rhs.pipeline_layout_); + std::swap(lhs.pipeline_sbt_, rhs.pipeline_sbt_); + std::swap(lhs.pipeline_bda_, rhs.pipeline_bda_); + std::swap(lhs.pipeline_context_sbt_, rhs.pipeline_context_sbt_); + std::swap(lhs.pipeline_context_bda_, rhs.pipeline_context_bda_); + std::swap(lhs.hashmap_sbt_, rhs.hashmap_sbt_); + std::swap(lhs.hashmap_bda_, rhs.hashmap_bda_); + std::swap(lhs.shadow_sbt_map_, rhs.shadow_sbt_map_); +} + +GFXRECON_END_NAMESPACE(decode) +GFXRECON_END_NAMESPACE(gfxrecon) diff --git a/framework/decode/vulkan_address_replacer.h b/framework/decode/vulkan_address_replacer.h new file mode 100644 index 000000000..bdcd978c2 --- /dev/null +++ b/framework/decode/vulkan_address_replacer.h @@ -0,0 +1,162 @@ +/* +** Copyright (c) 2024 LunarG, Inc. +** +** 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. +*/ + +#ifndef GFXRECON_GRAPHICS_VULKAN_ADDRESS_REPLACER_H +#define GFXRECON_GRAPHICS_VULKAN_ADDRESS_REPLACER_H + +#include "util/linear_hashmap.h" +#include "decode/common_object_info_table.h" +#include "decode/vulkan_device_address_tracker.h" +#include "graphics/vulkan_shader_group_handle.h" +#include "format/platform_types.h" + +GFXRECON_BEGIN_NAMESPACE(gfxrecon) +GFXRECON_BEGIN_NAMESPACE(decode) + +class VulkanAddressReplacer +{ + public: + VulkanAddressReplacer() = default; + + VulkanAddressReplacer(const VulkanDeviceInfo* device_info, + const encode::VulkanDeviceTable* device_table, + const decode::CommonObjectInfoTable& object_table); + + //! prevent copying + VulkanAddressReplacer(const VulkanAddressReplacer&) = delete; + + //! allow moving + VulkanAddressReplacer(VulkanAddressReplacer&& other) noexcept; + + ~VulkanAddressReplacer(); + + /** + * @brief ProcessCmdTraceRays will check and potentially correct input-parameters to 'VkCmdTraceRays', + * like buffer-device-addresses and shader-group-handles. + * + * Depending on capture- and replay-device-properties one of the following strategies will be used: + * + * if the shader-binding-table (SBT) layout is compatible and group-handles are also valid: + * - happy day, nothing to do! + * + * if the shader-binding-table (SBT) layout is compatible, but group-handles are invalid: + * - Apply in-place correction of group-handles contained in SBT + * + * if the shader-binding-table (SBT) layout is not compatible: + * - Create a shadow-SBT matching the replay-device's layout, map/copy group-handles to that, adjust input-addresses + * + * @param command_buffer_info a provided VulkanCommandBufferInfo + * @param raygen_sbt ray-generation sbt + * @param miss_sbt ray-miss sbt + * @param hit_sbt ray-hit sbt + * @param callable_sbt ray-callable sbt + * @param address_tracker const reference to a VulkanDeviceAddressTracker, used for mapping device-addresses + * @param group_handle_map a map from capture- to replay-time group-handles + */ + void ProcessCmdTraceRays( + const VulkanCommandBufferInfo* command_buffer_info, + VkStridedDeviceAddressRegionKHR* raygen_sbt, + VkStridedDeviceAddressRegionKHR* miss_sbt, + VkStridedDeviceAddressRegionKHR* hit_sbt, + VkStridedDeviceAddressRegionKHR* callable_sbt, + const decode::VulkanDeviceAddressTracker& address_tracker, + const std::unordered_map& group_handle_map); + + /** + * @brief ProcessCmdBuildAccelerationStructuresKHR will check + * and potentially correct input-parameters to 'VkCmdBuildAccelerationStructuresKHR' + * + * @param command_buffer_info a provided VulkanCommandBufferInfo + * @param info_count number of elements in 'build_geometry_infos' + * @param build_geometry_infos provided array of VkAccelerationStructureBuildGeometryInfoKHR + * @param build_range_infos provided array of VkAccelerationStructureBuildRangeInfoKHR* + * @param address_tracker const reference to a VulkanDeviceAddressTracker, used for mapping device-addresses + */ + void ProcessCmdBuildAccelerationStructuresKHR(const VulkanCommandBufferInfo* command_buffer_info, + uint32_t info_count, + VkAccelerationStructureBuildGeometryInfoKHR* build_geometry_infos, + VkAccelerationStructureBuildRangeInfoKHR** build_range_infos, + const decode::VulkanDeviceAddressTracker& address_tracker); + + friend void swap(VulkanAddressReplacer& lhs, VulkanAddressReplacer& rhs) noexcept; + + private: + struct buffer_context_t + { + decode::VulkanResourceAllocator* resource_allocator = nullptr; + uint32_t num_bytes = 0; + VkDeviceMemory device_memory = VK_NULL_HANDLE; + VkBuffer buffer = VK_NULL_HANDLE; + decode::VulkanResourceAllocator::ResourceData allocator_data{}; + decode::VulkanResourceAllocator::MemoryData memory_data{}; + VkDeviceAddress device_address = 0; + void* mapped_data = nullptr; + ~buffer_context_t(); + }; + + struct pipeline_context_t + { + buffer_context_t input_handle_buffer = {}; + buffer_context_t output_handle_buffer = {}; + buffer_context_t hashmap_storage = {}; + }; + + void init_pipeline(); + + bool create_buffer(size_t num_bytes, buffer_context_t& buffer_context, uint32_t usage_flags = 0); + + void barrier(VkCommandBuffer command_buffer, + VkBuffer buffer, + VkPipelineStageFlags src_stage, + VkAccessFlags src_access, + VkPipelineStageFlags dst_stage, + VkAccessFlags dst_access); + + const encode::VulkanDeviceTable* device_table_ = nullptr; + VkPhysicalDeviceMemoryProperties memory_properties_ = {}; + VkPhysicalDeviceRayTracingPipelinePropertiesKHR capture_ray_properties_{}, replay_ray_properties_{}; + bool valid_sbt_alignment_ = true; + + VkDevice device_ = VK_NULL_HANDLE; + PFN_vkGetBufferDeviceAddress get_device_address_fn_ = nullptr; + decode::VulkanResourceAllocator* resource_allocator_ = nullptr; + + // common layout used for all pipelines + VkPipelineLayout pipeline_layout_ = VK_NULL_HANDLE; + + // pipeline dealing with shader-binding-table (SBT), replacing group-handles + VkPipeline pipeline_sbt_ = VK_NULL_HANDLE; + + // pipeline dealing with buffer-device-addresses (BDA), replacing addresses + VkPipeline pipeline_bda_ = VK_NULL_HANDLE; + + pipeline_context_t pipeline_context_sbt_; + pipeline_context_t pipeline_context_bda_; + + util::linear_hashmap hashmap_sbt_; + util::linear_hashmap hashmap_bda_; + std::unordered_map shadow_sbt_map_; +}; +GFXRECON_END_NAMESPACE(decode) +GFXRECON_END_NAMESPACE(gfxrecon) + +#endif // GFXRECON_GRAPHICS_VULKAN_ADDRESS_REPLACER_H diff --git a/framework/decode/vulkan_address_replacer_shaders.h b/framework/decode/vulkan_address_replacer_shaders.h new file mode 100644 index 000000000..5c6771c22 --- /dev/null +++ b/framework/decode/vulkan_address_replacer_shaders.h @@ -0,0 +1,1088 @@ +/* +** Copyright (c) 2024 LunarG, Inc. +** +** 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. +*/ + +#ifndef GFXRECON_DECODE_VULKAN_ADDRESS_REPLACER_SHADERS_H +#define GFXRECON_DECODE_VULKAN_ADDRESS_REPLACER_SHADERS_H + +#include + +GFXRECON_BEGIN_NAMESPACE(gfxrecon) +GFXRECON_BEGIN_NAMESPACE(decode) + +// g_replacer_sbt_comp: original GLSL source +#if 0 +// replacer_sbt.comp + +#version 460 +#extension GL_EXT_buffer_reference2 : require +#extension GL_GOOGLE_include_directive : require + +/// -> hash.glsl +uint murmur_32_scramble(uint k) +{ + k *= 0xcc9e2d51; + k = (k << 15) | (k >> 17); + k *= 0x1b873593; + return k; +} + +//! condensed version of murmur3_32 for arrays of uint32_t +#define DEFINE_MURMUR3_32(LEN) \ + uint murmur3_32(const uint key[LEN], uint seed) \ + { \ + uint h = seed; \ + for (uint i = 0; i < LEN; ++i) \ + { \ + h ^= murmur_32_scramble(key[i]); \ + h = (h << 13) | (h >> 19); \ + h = h * 5 + 0xe6546b64; \ + } \ + h ^= LEN << 2; \ + h ^= h >> 16; \ + h *= 0x85ebca6b; \ + h ^= h >> 13; \ + h *= 0xc2b2ae35; \ + h ^= h >> 16; \ + return h; \ + } \ +/// hash.glsl + +DEFINE_MURMUR3_32(8); + +// 32-byte wide opaque handle +struct shader_group_handle_t +{ + uint data[8]; +}; +const shader_group_handle_t k_null_handle = shader_group_handle_t(uint[](0, 0, 0, 0, 0, 0, 0, 0)); + +bool equal(const shader_group_handle_t lhs, const shader_group_handle_t rhs) +{ + for(uint i = 0; i < 8; ++i) + { + if(lhs.data[i] != rhs.data[i]) + { + return false; + } + } + return true; +} + +bool is_null(const shader_group_handle_t h){ return equal(h, k_null_handle); } + +struct hashmap_item_t +{ + shader_group_handle_t key; + shader_group_handle_t value; +}; +layout(buffer_reference, std430) buffer readonly HashMapStorage{ hashmap_item_t v[]; }; + +//! 16 bytes +struct hashmap_t +{ + HashMapStorage storage; + uint size; + uint capacity; +}; + +uint hash(const shader_group_handle_t group_handle) +{ + return murmur3_32(group_handle.data, 0); +} + +shader_group_handle_t get(const hashmap_t hashmap, const shader_group_handle_t key) +{ + if(is_null(key) || hashmap.capacity == 0) { return k_null_handle; } + + for(uint idx = hash(key);; idx++) + { + idx &= hashmap.capacity - 1; + const hashmap_item_t item = hashmap.storage.v[idx]; + if(is_null(item.key)) { return k_null_handle; } + else if(equal(key, item.key) && !is_null(item.value)) { return item.value; } + } +} + +layout(buffer_reference, std430) buffer GroupHandlePtr{ shader_group_handle_t group_handle; }; + +layout(buffer_reference, std430) buffer readonly AddressArray{ GroupHandlePtr v[]; }; + +struct replacer_params_t +{ + hashmap_t shader_group_handle_map; + + // input-/output-arrays can be identical when sbt-alignments/strides match + AddressArray input_handles, output_handles; + uint num_handles; +}; + +layout(push_constant, std430) uniform pc +{ + replacer_params_t params; +}; + +layout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in; + +void main() +{ + uint gid = gl_GlobalInvocationID.x; + if(gid >= params.num_handles){ return; } + + // hashmap lookup + shader_group_handle_t result = get(params.shader_group_handle_map, params.input_handles.v[gid].group_handle); + + if(!is_null(result)) + { + // write remapped value to output-array + params.output_handles.v[gid].group_handle = result; + } +} +#endif // g_replacer_sbt_comp: original GLSL source + +// g_replacer_bda_comp: original GLSL source +#if 0 +#version 460 +#extension GL_EXT_buffer_reference2 : require +#extension GL_GOOGLE_include_directive : require + +/// -> hash.glsl +uint murmur_32_scramble(uint k) +{ + k *= 0xcc9e2d51; + k = (k << 15) | (k >> 17); + k *= 0x1b873593; + return k; +} + +//! condensed version of murmur3_32 for arrays of uint32_t +#define DEFINE_MURMUR3_32(LEN) \ + uint murmur3_32(const uint key[LEN], uint seed) \ + { \ + uint h = seed; \ + for (uint i = 0; i < LEN; ++i) \ + { \ + h ^= murmur_32_scramble(key[i]); \ + h = (h << 13) | (h >> 19); \ + h = h * 5 + 0xe6546b64; \ + } \ + h ^= LEN << 2; \ + h ^= h >> 16; \ + h *= 0x85ebca6b; \ + h ^= h >> 13; \ + h *= 0xc2b2ae35; \ + h ^= h >> 16; \ + return h; \ + } \ +/// hash.glsl + +DEFINE_MURMUR3_32(2); + +// 32-byte wide opaque handle +struct buffer_device_address_t +{ + uint data[2]; +}; +const buffer_device_address_t k_null_handle = buffer_device_address_t(uint[](0, 0)); + +bool equal(const buffer_device_address_t lhs, const buffer_device_address_t rhs) +{ + for(uint i = 0; i < 2; ++i) + { + if(lhs.data[i] != rhs.data[i]) + { + return false; + } + } + return true; +} + +bool is_null(const buffer_device_address_t h){ return equal(h, k_null_handle); } + +struct hashmap_item_t +{ + buffer_device_address_t key; + buffer_device_address_t value; +}; +layout(buffer_reference, std430) buffer readonly HashMapStorage{ hashmap_item_t v[]; }; + +//! 16 bytes +struct hashmap_t +{ + HashMapStorage storage; + uint size; + uint capacity; +}; + +uint hash(const buffer_device_address_t device_address) +{ + return murmur3_32(device_address.data, 0); +} + +buffer_device_address_t get(const hashmap_t hashmap, const buffer_device_address_t key) +{ + if(is_null(key) || hashmap.capacity == 0) { return k_null_handle; } + + for(uint idx = hash(key);; idx++) + { + idx &= hashmap.capacity - 1; + const hashmap_item_t item = hashmap.storage.v[idx]; + if(is_null(item.key)) { return k_null_handle; } + else if(equal(key, item.key) && !is_null(item.value)) { return item.value; } + } +} + +layout(buffer_reference, std430) buffer BufferDeviceAddressPtr{ buffer_device_address_t buffer_device_address; }; + +layout(buffer_reference, std430) buffer readonly AddressArray{ BufferDeviceAddressPtr v[]; }; + +struct replacer_params_t +{ + hashmap_t buffer_device_address_map; + + // input-/output-arrays 'can' be identical + AddressArray input_handles, output_handles; + uint num_handles; +}; + +layout(push_constant, std430) uniform pc +{ + replacer_params_t params; +}; + +layout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in; + +void main() +{ + uint gid = gl_GlobalInvocationID.x; + if(gid >= params.num_handles){ return; } + + // hashmap lookup + buffer_device_address_t result = get(params.buffer_device_address_map, + params.input_handles.v[gid].buffer_device_address); + + if(!is_null(result)) + { + // write remapped value to output-array + params.output_handles.v[gid].buffer_device_address = result; + } +} +#endif // g_replacer_bda_comp + +static const std::array g_replacer_sbt_comp = { + 0x03, 0x02, 0x23, 0x07, 0x00, 0x05, 0x01, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x1a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0xb6, 0x14, 0x00, 0x00, 0x11, 0x00, + 0x02, 0x00, 0xe3, 0x14, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4c, 0x53, 0x4c, 0x2e, + 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0xe4, 0x14, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, + 0x6e, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00, 0x10, 0x00, 0x06, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xcc, 0x01, 0x00, 0x00, 0x04, 0x00, 0x07, 0x00, 0x47, 0x4c, 0x5f, 0x45, + 0x58, 0x54, 0x5f, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x00, 0x04, 0x00, 0x08, 0x00, 0x47, 0x4c, 0x5f, 0x45, 0x58, 0x54, 0x5f, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x32, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x47, + 0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x63, 0x70, 0x70, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x5f, + 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x04, 0x00, 0x08, + 0x00, 0x47, 0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, + 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, + 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x6d, 0x75, 0x72, 0x6d, + 0x75, 0x72, 0x5f, 0x33, 0x32, 0x5f, 0x73, 0x63, 0x72, 0x61, 0x6d, 0x62, 0x6c, 0x65, 0x28, 0x75, 0x31, 0x3b, 0x00, + 0x00, 0x05, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x6d, 0x75, 0x72, 0x6d, 0x75, 0x72, 0x33, 0x5f, 0x33, 0x32, 0x28, 0x75, 0x31, 0x5b, 0x38, 0x5d, 0x3b, + 0x75, 0x31, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x6b, 0x65, 0x79, 0x00, + 0x05, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x73, 0x65, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08, + 0x00, 0x13, 0x00, 0x00, 0x00, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x68, + 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x16, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x65, 0x71, 0x75, 0x61, 0x6c, 0x28, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2d, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, + 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x5f, 0x74, 0x2d, 0x75, 0x31, 0x5b, + 0x38, 0x5d, 0x31, 0x3b, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2d, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x5f, 0x74, 0x2d, 0x75, 0x31, 0x5b, 0x38, 0x5d, + 0x31, 0x3b, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x16, 0x00, 0x00, 0x00, 0x6c, 0x68, 0x73, 0x00, 0x05, 0x00, 0x03, + 0x00, 0x17, 0x00, 0x00, 0x00, 0x72, 0x68, 0x73, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x69, 0x73, + 0x5f, 0x6e, 0x75, 0x6c, 0x6c, 0x28, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2d, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, + 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x5f, 0x74, 0x2d, 0x75, 0x31, 0x5b, + 0x38, 0x5d, 0x31, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x0d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x68, 0x61, 0x73, 0x68, 0x28, 0x73, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x2d, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x68, 0x61, 0x6e, 0x64, + 0x6c, 0x65, 0x5f, 0x74, 0x2d, 0x75, 0x31, 0x5b, 0x38, 0x5d, 0x31, 0x3b, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x05, 0x00, 0x23, 0x00, 0x00, 0x00, 0x68, 0x61, 0x73, 0x68, 0x6d, 0x61, 0x70, 0x5f, 0x74, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x00, 0x06, 0x00, 0x05, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x73, 0x69, 0x7a, 0x65, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x23, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x63, 0x61, 0x70, + 0x61, 0x63, 0x69, 0x74, 0x79, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00, 0x25, 0x00, 0x00, 0x00, 0x73, 0x68, + 0x61, 0x64, 0x65, 0x72, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x5f, 0x74, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x26, 0x00, 0x00, 0x00, 0x68, 0x61, 0x73, 0x68, 0x6d, 0x61, 0x70, + 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x74, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x6b, 0x65, 0x79, 0x00, 0x06, 0x00, 0x05, 0x00, 0x26, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x28, 0x00, 0x00, 0x00, 0x48, 0x61, 0x73, 0x68, + 0x4d, 0x61, 0x70, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x05, 0x00, 0x13, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x67, 0x65, + 0x74, 0x28, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2d, 0x68, 0x61, 0x73, 0x68, 0x6d, 0x61, 0x70, 0x5f, 0x74, 0x2d, + 0x31, 0x2d, 0x75, 0x31, 0x2d, 0x75, 0x31, 0x31, 0x3b, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2d, 0x73, 0x68, 0x61, + 0x64, 0x65, 0x72, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x5f, 0x74, 0x2d, + 0x75, 0x31, 0x5b, 0x38, 0x5d, 0x31, 0x3b, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x68, 0x61, + 0x73, 0x68, 0x6d, 0x61, 0x70, 0x00, 0x05, 0x00, 0x03, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x6b, 0x65, 0x79, 0x00, 0x05, + 0x00, 0x03, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x41, 0x00, 0x00, 0x00, + 0x69, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x05, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x61, 0x62, 0x6c, 0x65, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x86, + 0x00, 0x00, 0x00, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, + 0x8a, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, + 0x00, 0x9d, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0xac, 0x00, + 0x00, 0x00, 0x69, 0x64, 0x78, 0x00, 0x05, 0x00, 0x06, 0x00, 0xb7, 0x00, 0x00, 0x00, 0x68, 0x61, 0x73, 0x68, 0x6d, + 0x61, 0x70, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x74, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00, 0xb7, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6b, 0x65, 0x79, 0x00, 0x06, 0x00, 0x05, 0x00, 0xb7, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x69, 0x74, + 0x65, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0xd9, 0x00, 0x00, 0x00, 0x67, 0x69, 0x64, 0x00, 0x05, + 0x00, 0x08, 0x00, 0xdc, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x49, 0x6e, 0x76, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0xe1, 0x00, 0x00, + 0x00, 0x68, 0x61, 0x73, 0x68, 0x6d, 0x61, 0x70, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0xe1, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x00, 0x06, 0x00, 0x05, 0x00, 0xe1, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x73, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, + 0xe1, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x00, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x07, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x72, 0x5f, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x06, 0x00, 0x09, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x68, 0x61, 0x6e, + 0x64, 0x6c, 0x65, 0x5f, 0x6d, 0x61, 0x70, 0x00, 0x06, 0x00, 0x07, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x00, 0x00, 0x00, 0x06, 0x00, + 0x07, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x68, 0x61, + 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x6e, 0x75, 0x6d, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x00, 0x05, 0x00, 0x06, 0x00, 0xe6, 0x00, 0x00, + 0x00, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x41, 0x72, 0x72, 0x61, 0x79, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, + 0x04, 0x00, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00, 0xe8, + 0x00, 0x00, 0x00, 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x68, 0x61, 0x6e, + 0x64, 0x6c, 0x65, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0xe9, 0x00, 0x00, 0x00, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x50, 0x74, 0x72, 0x00, 0x00, 0x06, 0x00, 0x07, 0x00, 0xe9, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0xeb, 0x00, 0x00, 0x00, 0x70, 0x63, 0x00, 0x00, 0x06, 0x00, 0x05, + 0x00, 0xeb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x00, 0x00, 0x05, 0x00, + 0x03, 0x00, 0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0xf6, 0x00, 0x00, 0x00, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x05, 0x01, 0x00, 0x00, 0x61, 0x72, 0x67, 0x00, + 0x05, 0x00, 0x03, 0x00, 0x08, 0x01, 0x00, 0x00, 0x61, 0x72, 0x67, 0x00, 0x47, 0x00, 0x04, 0x00, 0x24, 0x00, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x26, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x27, 0x00, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x28, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x48, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x48, + 0x00, 0x05, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x04, 0x00, 0xdc, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, + 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, + 0x05, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x48, + 0x00, 0x05, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x05, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x00, 0x05, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xe5, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x47, 0x00, 0x03, 0x00, 0xe6, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x04, 0x00, 0xe6, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xe7, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0xe9, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xea, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x03, 0x00, 0xeb, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0xeb, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x05, 0x01, + 0x00, 0x00, 0xec, 0x14, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x19, 0x01, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x19, + 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x21, 0x00, + 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x21, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, + 0x00, 0x0d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x03, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0d, 0x00, + 0x00, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x00, 0x00, 0x21, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x21, 0x00, 0x04, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x21, 0x00, 0x04, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, + 0x00, 0x13, 0x00, 0x00, 0x00, 0x27, 0x00, 0x03, 0x00, 0x22, 0x00, 0x00, 0x00, 0xe5, 0x14, 0x00, 0x00, 0x1e, 0x00, + 0x05, 0x00, 0x23, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1c, + 0x00, 0x04, 0x00, 0x24, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x03, 0x00, + 0x25, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x04, 0x00, 0x26, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, + 0x00, 0x25, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x03, 0x00, 0x27, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x1e, 0x00, + 0x03, 0x00, 0x28, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x22, 0x00, 0x00, 0x00, 0xe5, + 0x14, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x21, 0x00, 0x05, 0x00, 0x29, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, + 0x00, 0x51, 0x2d, 0x9e, 0xcc, 0x15, 0x00, 0x04, 0x00, 0x32, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x32, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x2b, + 0x00, 0x04, 0x00, 0x32, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x93, 0x35, 0x87, 0x1b, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, + 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x32, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x0d, + 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x32, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x64, 0x6b, 0x54, 0xe6, 0x2b, 0x00, 0x04, 0x00, 0x32, 0x00, + 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x62, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x32, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x6b, 0xca, 0xeb, + 0x85, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x35, 0xae, 0xb2, 0xc2, 0x2b, 0x00, + 0x04, 0x00, 0x32, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x85, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x03, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x90, 0x00, 0x00, 0x00, 0x29, 0x00, 0x03, 0x00, 0x14, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x0b, + 0x00, 0x0d, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x42, 0x00, + 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x42, + 0x00, 0x00, 0x00, 0x2c, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x32, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, + 0x00, 0x06, 0x00, 0x00, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x04, 0x00, 0xb7, 0x00, + 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x00, 0xb7, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xbc, 0x00, 0x00, 0x00, 0xe5, 0x14, 0x00, 0x00, + 0x26, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0xda, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x04, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, 0x3b, 0x00, + 0x04, 0x00, 0xdb, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xdd, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x05, 0x00, 0xe1, 0x00, 0x00, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x27, 0x00, 0x03, 0x00, 0xe2, 0x00, 0x00, + 0x00, 0xe5, 0x14, 0x00, 0x00, 0x1e, 0x00, 0x06, 0x00, 0xe3, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0xe2, 0x00, + 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x27, 0x00, 0x03, 0x00, 0xe4, 0x00, 0x00, 0x00, 0xe5, + 0x14, 0x00, 0x00, 0x1d, 0x00, 0x03, 0x00, 0xe5, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x03, 0x00, + 0xe6, 0x00, 0x00, 0x00, 0xe5, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, + 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x03, 0x00, 0xe8, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x1e, 0x00, + 0x03, 0x00, 0xe9, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xe4, 0x00, 0x00, 0x00, 0xe5, + 0x14, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x03, 0x00, 0xea, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0xe2, 0x00, 0x00, 0x00, 0xe5, 0x14, 0x00, 0x00, 0xe6, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x03, + 0x00, 0xeb, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xec, 0x00, 0x00, 0x00, 0x09, 0x00, + 0x00, 0x00, 0xeb, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0xec, 0x00, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x32, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0xef, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, + 0x00, 0xf7, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xfa, 0x00, + 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xe5, + 0x14, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x01, 0x01, 0x00, 0x00, 0xe5, 0x14, 0x00, 0x00, + 0xe8, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x04, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, + 0x00, 0x2c, 0x00, 0x06, 0x00, 0xda, 0x00, 0x00, 0x00, 0x19, 0x01, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0xb3, 0x00, + 0x00, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0xd9, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x85, 0x00, 0x00, + 0x00, 0xf6, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x04, 0x01, 0x00, 0x00, 0x05, 0x01, + 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x85, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0xdd, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xdf, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00, + 0x00, 0x3e, 0x00, 0x03, 0x00, 0xd9, 0x00, 0x00, 0x00, 0xdf, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, + 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xd9, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0xef, 0x00, 0x00, 0x00, 0xf0, + 0x00, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xae, 0x00, 0x05, 0x00, 0x14, 0x00, 0x00, + 0x00, 0xf2, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0xf4, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0xf2, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0x00, 0xf4, + 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xf3, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0xf4, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0xf7, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xed, 0x00, 0x00, + 0x00, 0x83, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0xe1, 0x00, 0x00, 0x00, 0xf9, 0x00, + 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0xfa, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x00, 0x00, 0xed, + 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0xe2, 0x00, 0x00, 0x00, + 0xfc, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, + 0x00, 0xd9, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xfc, 0x00, + 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x06, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x01, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x06, + 0x00, 0xe8, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x90, 0x01, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x06, 0x01, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0x3e, + 0x00, 0x03, 0x00, 0x05, 0x01, 0x00, 0x00, 0x06, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x07, 0x01, 0x00, 0x00, 0x05, 0x01, 0x00, 0x00, 0x90, 0x01, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0x09, 0x01, 0x00, + 0x00, 0x03, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x08, 0x01, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0x3d, 0x00, + 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x39, 0x00, 0x06, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x07, 0x01, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0xf6, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x0c, 0x01, 0x00, 0x00, 0xf6, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0d, 0x01, + 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0xa8, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0e, + 0x01, 0x00, 0x00, 0x0d, 0x01, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfa, 0x00, 0x04, 0x00, 0x0e, 0x01, 0x00, 0x00, 0x0f, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, + 0x00, 0x0f, 0x01, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0xed, 0x00, + 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x12, + 0x01, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, + 0xd9, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x12, 0x01, 0x00, + 0x00, 0x83, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x06, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x15, 0x01, + 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x16, 0x01, 0x00, 0x00, 0xf6, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x01, 0x01, 0x00, 0x00, + 0x17, 0x01, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x90, 0x01, 0x04, 0x00, 0xe8, 0x00, 0x00, + 0x00, 0x18, 0x01, 0x00, 0x00, 0x16, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x05, 0x00, 0x17, 0x01, 0x00, 0x00, 0x18, 0x01, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x10, 0x01, 0x00, 0x00, 0xf8, + 0x00, 0x02, 0x00, 0x10, 0x01, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00, 0x36, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x3d, 0x00, + 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x84, 0x00, 0x05, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, + 0x00, 0x09, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x31, 0x00, + 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x00, 0x00, 0xc2, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, + 0x00, 0x37, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x3d, 0x00, + 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x84, 0x00, 0x05, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, + 0x00, 0x09, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0x00, 0x36, 0x00, + 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x37, + 0x00, 0x03, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x12, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, + 0x00, 0x3f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x41, 0x00, + 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, + 0x00, 0x3f, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x41, 0x00, 0x00, 0x00, 0x42, 0x00, + 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x43, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x43, 0x00, 0x00, 0x00, 0xf6, + 0x00, 0x04, 0x00, 0x45, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, + 0x47, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x47, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, + 0x00, 0x48, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x05, 0x00, 0x14, 0x00, 0x00, 0x00, 0x49, 0x00, + 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x49, 0x00, 0x00, 0x00, 0x44, + 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x44, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x4d, 0x00, 0x00, + 0x00, 0x0f, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x4d, 0x00, + 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x4e, + 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x05, 0x00, 0x06, 0x00, + 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, + 0x3f, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, + 0x00, 0x54, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x3f, 0x00, + 0x00, 0x00, 0xc2, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x57, + 0x00, 0x00, 0x00, 0xc5, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, + 0x58, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x84, 0x00, 0x05, 0x00, 0x06, 0x00, + 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x3f, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x46, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, + 0x00, 0x46, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x41, 0x00, + 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x60, + 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x41, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, + 0x43, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x45, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, + 0x00, 0x63, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x64, 0x00, + 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x64, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, + 0xc2, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, + 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xc6, 0x00, + 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x3e, + 0x00, 0x03, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x6b, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x84, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, + 0x00, 0x6b, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x6c, 0x00, + 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xc2, + 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x05, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x3e, 0x00, + 0x03, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x72, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x84, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, + 0x72, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, + 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xc2, 0x00, + 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, + 0x00, 0x3f, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x78, 0x00, + 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, 0x78, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0x00, 0x36, + 0x00, 0x05, 0x00, 0x14, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x37, 0x00, 0x03, 0x00, 0x13, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x17, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x19, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x85, 0x00, 0x00, 0x00, 0x86, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x85, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, + 0x00, 0x7c, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x7c, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x04, 0x00, 0x7e, 0x00, + 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, 0xf8, + 0x00, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, + 0x7b, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x05, 0x00, 0x14, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, + 0x00, 0x0c, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x82, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x7e, 0x00, + 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x84, + 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x86, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x06, 0x00, 0x07, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, + 0x00, 0x84, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x87, 0x00, + 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x3e, + 0x00, 0x03, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x8b, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0xab, 0x00, 0x05, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0x8f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, + 0x8f, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x8e, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, 0x90, 0x00, 0x00, + 0x00, 0xf8, 0x00, 0x02, 0x00, 0x8f, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xf8, 0x00, + 0x02, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x7b, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, + 0x00, 0x7c, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x7e, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, 0x94, 0x00, + 0x00, 0x00, 0x38, 0x00, 0x01, 0x00, 0x36, 0x00, 0x05, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00, 0x13, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x39, 0x00, 0x06, 0x00, 0x14, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, + 0x00, 0x18, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, 0x99, 0x00, + 0x00, 0x00, 0x38, 0x00, 0x01, 0x00, 0x36, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00, 0x13, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0x21, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x9d, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x1f, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x39, + 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, + 0x9d, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0x00, 0x36, 0x00, 0x05, + 0x00, 0x13, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x37, 0x00, + 0x03, 0x00, 0x23, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00, 0x13, 0x00, 0x00, 0x00, 0x2b, + 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0xac, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0xb8, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, 0x14, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x1c, 0x00, + 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, 0xa1, + 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, + 0xa2, 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xa3, 0x00, 0x00, + 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0xaa, 0x00, 0x05, 0x00, 0x14, 0x00, 0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00, 0x42, + 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0xa4, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xa4, 0x00, 0x00, 0x00, + 0xf5, 0x00, 0x07, 0x00, 0x14, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, + 0x00, 0xa7, 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0xa8, 0x00, 0x00, 0x00, 0xa9, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xf8, + 0x00, 0x02, 0x00, 0xa9, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, 0x98, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0xaa, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, + 0x00, 0x2b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xac, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, 0x00, 0xf9, 0x00, + 0x02, 0x00, 0xae, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xae, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x04, 0x00, 0xb0, + 0x00, 0x00, 0x00, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0xaf, 0x00, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0xaf, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb2, 0x00, 0x00, + 0x00, 0x2a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x82, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb4, 0x00, + 0x00, 0x00, 0xb2, 0x00, 0x00, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb5, + 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, + 0xb5, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xac, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00, + 0x00, 0x51, 0x00, 0x05, 0x00, 0x22, 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0x41, + 0x00, 0x06, 0x00, 0xbc, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, + 0xbb, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x06, 0x00, 0x26, 0x00, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x90, 0x01, 0x04, 0x00, 0xb7, 0x00, 0x00, 0x00, 0xbf, 0x00, + 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xb9, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x41, + 0x00, 0x05, 0x00, 0x85, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, + 0x00, 0x14, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0xf7, 0x00, + 0x03, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0xc2, 0x00, 0x00, 0x00, 0xc3, + 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xc3, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, + 0x98, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x85, 0x00, 0x00, + 0x00, 0xc7, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x13, 0x00, + 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x39, 0x00, 0x06, 0x00, 0x14, 0x00, 0x00, 0x00, 0xc9, + 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, + 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0xc9, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00, + 0x00, 0xcb, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xca, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x85, 0x00, + 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x13, + 0x00, 0x00, 0x00, 0xcd, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, 0x14, 0x00, 0x00, 0x00, + 0xce, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0xcd, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, + 0x00, 0xcf, 0x00, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0xcb, 0x00, 0x00, 0x00, 0xf8, 0x00, + 0x02, 0x00, 0xcb, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x07, 0x00, 0x14, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0xc9, + 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, + 0xd2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0xd0, 0x00, 0x00, 0x00, 0xd1, 0x00, 0x00, + 0x00, 0xd2, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xd1, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x85, 0x00, + 0x00, 0x00, 0xd3, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x13, + 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0xd3, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, 0xd4, 0x00, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0xd2, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0xc4, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, + 0x00, 0xc4, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0xb1, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xb1, 0x00, + 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0x80, + 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xd7, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0xac, 0x00, 0x00, 0x00, 0xd7, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0xae, 0x00, 0x00, + 0x00, 0xf8, 0x00, 0x02, 0x00, 0xb0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00 +}; + +const std::array g_replacer_bda_comp = { + 0x03, 0x02, 0x23, 0x07, 0x00, 0x05, 0x01, 0x00, 0x0b, 0x00, 0x08, 0x00, 0x1b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0xb6, 0x14, 0x00, 0x00, 0x11, 0x00, + 0x02, 0x00, 0xe3, 0x14, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4c, 0x53, 0x4c, 0x2e, + 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0xe4, 0x14, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, + 0x6e, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00, 0x10, 0x00, 0x06, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, + 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xcc, 0x01, 0x00, 0x00, 0x04, 0x00, 0x07, 0x00, 0x47, 0x4c, 0x5f, 0x45, + 0x58, 0x54, 0x5f, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x00, 0x04, 0x00, 0x08, 0x00, 0x47, 0x4c, 0x5f, 0x45, 0x58, 0x54, 0x5f, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x32, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x47, + 0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x63, 0x70, 0x70, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x5f, + 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x00, 0x04, 0x00, 0x08, + 0x00, 0x47, 0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, + 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, + 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x6d, 0x75, 0x72, 0x6d, + 0x75, 0x72, 0x5f, 0x33, 0x32, 0x5f, 0x73, 0x63, 0x72, 0x61, 0x6d, 0x62, 0x6c, 0x65, 0x28, 0x75, 0x31, 0x3b, 0x00, + 0x00, 0x05, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00, 0x11, 0x00, + 0x00, 0x00, 0x6d, 0x75, 0x72, 0x6d, 0x75, 0x72, 0x33, 0x5f, 0x33, 0x32, 0x28, 0x75, 0x31, 0x5b, 0x32, 0x5d, 0x3b, + 0x75, 0x31, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x6b, 0x65, 0x79, 0x00, + 0x05, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x73, 0x65, 0x65, 0x64, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08, + 0x00, 0x13, 0x00, 0x00, 0x00, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x00, 0x06, 0x00, 0x05, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x17, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x65, 0x71, 0x75, 0x61, 0x6c, 0x28, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2d, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, + 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x2d, 0x75, + 0x31, 0x5b, 0x32, 0x5d, 0x31, 0x3b, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2d, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, + 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x2d, 0x75, + 0x31, 0x5b, 0x32, 0x5d, 0x31, 0x3b, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x16, 0x00, 0x00, 0x00, 0x6c, 0x68, 0x73, + 0x00, 0x05, 0x00, 0x03, 0x00, 0x17, 0x00, 0x00, 0x00, 0x72, 0x68, 0x73, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x1c, 0x00, + 0x00, 0x00, 0x69, 0x73, 0x5f, 0x6e, 0x75, 0x6c, 0x6c, 0x28, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2d, 0x62, 0x75, + 0x66, 0x66, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x5f, 0x74, 0x2d, 0x75, 0x31, 0x5b, 0x32, 0x5d, 0x31, 0x3b, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x1b, 0x00, 0x00, + 0x00, 0x68, 0x00, 0x00, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x20, 0x00, 0x00, 0x00, 0x68, 0x61, 0x73, 0x68, 0x28, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x2d, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x2d, 0x75, 0x31, 0x5b, 0x32, 0x5d, 0x31, 0x3b, 0x00, + 0x05, 0x00, 0x06, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x23, 0x00, 0x00, 0x00, 0x68, 0x61, 0x73, 0x68, 0x6d, 0x61, + 0x70, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x00, 0x06, 0x00, 0x05, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x73, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x23, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00, 0x25, 0x00, + 0x00, 0x00, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x00, 0x06, 0x00, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x26, 0x00, 0x00, 0x00, 0x68, 0x61, 0x73, + 0x68, 0x6d, 0x61, 0x70, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x74, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00, 0x26, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x65, 0x79, 0x00, 0x06, 0x00, 0x05, 0x00, 0x26, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x48, 0x61, 0x73, 0x68, 0x4d, 0x61, 0x70, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x00, 0x00, 0x06, 0x00, 0x04, + 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x05, 0x00, 0x14, 0x00, 0x2c, 0x00, + 0x00, 0x00, 0x67, 0x65, 0x74, 0x28, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2d, 0x68, 0x61, 0x73, 0x68, 0x6d, 0x61, + 0x70, 0x5f, 0x74, 0x2d, 0x31, 0x2d, 0x75, 0x31, 0x2d, 0x75, 0x31, 0x31, 0x3b, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x2d, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x5f, 0x74, 0x2d, 0x75, 0x31, 0x5b, 0x32, 0x5d, 0x31, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, + 0x04, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x68, 0x61, 0x73, 0x68, 0x6d, 0x61, 0x70, 0x00, 0x05, 0x00, 0x03, 0x00, 0x2b, + 0x00, 0x00, 0x00, 0x6b, 0x65, 0x79, 0x00, 0x05, 0x00, 0x03, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x03, 0x00, 0x41, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x4b, 0x00, 0x00, + 0x00, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x69, 0x6e, + 0x64, 0x65, 0x78, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x69, + 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x86, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x61, 0x62, 0x6c, + 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x61, 0x62, + 0x6c, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0xac, 0x00, 0x00, 0x00, 0x69, 0x64, 0x78, 0x00, 0x05, 0x00, 0x06, 0x00, 0xb7, + 0x00, 0x00, 0x00, 0x68, 0x61, 0x73, 0x68, 0x6d, 0x61, 0x70, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x74, 0x00, 0x00, + 0x06, 0x00, 0x04, 0x00, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x65, 0x79, 0x00, 0x06, 0x00, 0x05, + 0x00, 0xb7, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, + 0x04, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x69, 0x74, 0x65, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0xd9, + 0x00, 0x00, 0x00, 0x67, 0x69, 0x64, 0x00, 0x05, 0x00, 0x08, 0x00, 0xdc, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x47, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x49, 0x6e, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x00, 0x00, + 0x00, 0x05, 0x00, 0x05, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x68, 0x61, 0x73, 0x68, 0x6d, 0x61, 0x70, 0x5f, 0x74, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x00, 0x06, 0x00, 0x05, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x73, 0x69, 0x7a, 0x65, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x63, 0x61, 0x70, + 0x61, 0x63, 0x69, 0x74, 0x79, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x07, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x72, 0x65, + 0x70, 0x6c, 0x61, 0x63, 0x65, 0x72, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x5f, 0x74, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x0a, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x6d, 0x61, 0x70, 0x00, 0x00, + 0x00, 0x06, 0x00, 0x07, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, + 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x00, 0x00, 0x00, 0x06, 0x00, 0x07, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x00, 0x00, + 0x06, 0x00, 0x06, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x6e, 0x75, 0x6d, 0x5f, 0x68, 0x61, 0x6e, + 0x64, 0x6c, 0x65, 0x73, 0x00, 0x05, 0x00, 0x06, 0x00, 0xe6, 0x00, 0x00, 0x00, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x41, 0x72, 0x72, 0x61, 0x79, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x04, 0x00, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x62, 0x75, 0x66, 0x66, + 0x65, 0x72, 0x5f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x5f, 0x74, + 0x00, 0x06, 0x00, 0x05, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x08, 0x00, 0xe9, 0x00, 0x00, 0x00, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x44, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x50, 0x74, 0x72, 0x00, 0x00, 0x06, 0x00, 0x09, 0x00, + 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0xeb, 0x00, + 0x00, 0x00, 0x70, 0x63, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0xeb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0xed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x04, 0x00, 0xf6, 0x00, 0x00, 0x00, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x00, 0x00, 0x05, 0x00, 0x03, + 0x00, 0x05, 0x01, 0x00, 0x00, 0x61, 0x72, 0x67, 0x00, 0x05, 0x00, 0x03, 0x00, 0x08, 0x01, 0x00, 0x00, 0x61, 0x72, + 0x67, 0x00, 0x47, 0x00, 0x04, 0x00, 0x24, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x48, + 0x00, 0x05, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x05, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x00, 0x05, 0x00, 0x26, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x27, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x47, + 0x00, 0x03, 0x00, 0x28, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x04, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xdc, 0x00, 0x00, 0x00, 0x0b, 0x00, + 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x23, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0xe3, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0xe3, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xe5, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0xe6, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0x48, 0x00, 0x04, 0x00, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x05, 0x00, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x47, 0x00, 0x04, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x48, 0x00, + 0x05, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, + 0x00, 0x03, 0x00, 0xe9, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0xe9, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xea, 0x00, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0xeb, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0xeb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x05, 0x01, 0x00, 0x00, 0xec, 0x14, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, + 0x1a, 0x01, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, 0x06, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x21, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x1c, 0x00, 0x04, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x21, 0x00, + 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x1e, + 0x00, 0x03, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x21, 0x00, 0x04, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x21, 0x00, + 0x04, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x27, 0x00, 0x03, 0x00, 0x22, + 0x00, 0x00, 0x00, 0xe5, 0x14, 0x00, 0x00, 0x1e, 0x00, 0x05, 0x00, 0x23, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x24, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, + 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x03, 0x00, 0x25, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x1e, 0x00, + 0x04, 0x00, 0x26, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x03, 0x00, 0x27, + 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x03, 0x00, 0x28, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x22, 0x00, 0x00, 0x00, 0xe5, 0x14, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x21, 0x00, 0x05, + 0x00, 0x29, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x2b, 0x00, + 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x51, 0x2d, 0x9e, 0xcc, 0x15, 0x00, 0x04, 0x00, 0x32, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x32, 0x00, 0x00, 0x00, + 0x33, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x32, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, + 0x00, 0x11, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x93, 0x35, + 0x87, 0x1b, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x04, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, + 0x32, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x32, 0x00, 0x00, + 0x00, 0x57, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5b, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x64, + 0x6b, 0x54, 0xe6, 0x2b, 0x00, 0x04, 0x00, 0x32, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, + 0x00, 0x32, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, + 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x6b, 0xca, 0xeb, 0x85, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x71, + 0x00, 0x00, 0x00, 0x35, 0xae, 0xb2, 0xc2, 0x2b, 0x00, 0x04, 0x00, 0x32, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x85, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, + 0x00, 0x2a, 0x00, 0x03, 0x00, 0x14, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x29, 0x00, 0x03, 0x00, 0x14, 0x00, + 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, 0x42, + 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, + 0x97, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x32, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1e, 0x00, + 0x04, 0x00, 0xb7, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xb8, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xb7, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xbc, 0x00, 0x00, 0x00, + 0xe5, 0x14, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0xda, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, + 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xdb, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xda, 0x00, + 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0xdb, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x04, 0x00, 0xdd, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x05, 0x00, + 0xe1, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x27, 0x00, 0x03, + 0x00, 0xe2, 0x00, 0x00, 0x00, 0xe5, 0x14, 0x00, 0x00, 0x1e, 0x00, 0x06, 0x00, 0xe3, 0x00, 0x00, 0x00, 0xe1, 0x00, + 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x27, 0x00, 0x03, 0x00, 0xe4, + 0x00, 0x00, 0x00, 0xe5, 0x14, 0x00, 0x00, 0x1d, 0x00, 0x03, 0x00, 0xe5, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x03, 0x00, 0xe6, 0x00, 0x00, 0x00, 0xe5, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0xe7, 0x00, 0x00, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x03, 0x00, 0xe8, 0x00, 0x00, 0x00, 0xe7, 0x00, + 0x00, 0x00, 0x1e, 0x00, 0x03, 0x00, 0xe9, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xe4, + 0x00, 0x00, 0x00, 0xe5, 0x14, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x03, 0x00, 0xea, 0x00, 0x00, 0x00, + 0xe4, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xe2, 0x00, 0x00, 0x00, 0xe5, 0x14, 0x00, 0x00, 0xe6, 0x00, 0x00, + 0x00, 0x1e, 0x00, 0x03, 0x00, 0xeb, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xec, 0x00, + 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xeb, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0xec, 0x00, 0x00, 0x00, 0xed, + 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x32, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xef, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x04, 0x00, 0xf7, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x04, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0xfe, + 0x00, 0x00, 0x00, 0xe5, 0x14, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x01, 0x01, 0x00, 0x00, + 0xe5, 0x14, 0x00, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x04, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, + 0x00, 0x23, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x19, 0x01, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x2c, 0x00, 0x06, 0x00, 0xda, 0x00, 0x00, 0x00, 0x1a, 0x01, 0x00, 0x00, 0x19, 0x01, 0x00, 0x00, 0xb3, + 0x00, 0x00, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, + 0x00, 0x07, 0x00, 0x00, 0x00, 0xd9, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x85, 0x00, + 0x00, 0x00, 0xf6, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x04, 0x01, 0x00, 0x00, 0x05, + 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x85, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0xdd, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, + 0x00, 0x42, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xdf, 0x00, 0x00, 0x00, 0xde, 0x00, + 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xd9, 0x00, 0x00, 0x00, 0xdf, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, + 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xd9, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0xef, 0x00, 0x00, 0x00, + 0xf0, 0x00, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, + 0x00, 0x06, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xae, 0x00, 0x05, 0x00, 0x14, 0x00, + 0x00, 0x00, 0xf2, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0xf4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0xf2, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0x00, + 0xf4, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xf3, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0xf8, 0x00, 0x02, + 0x00, 0xf4, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0xf7, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xed, 0x00, + 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0xe1, 0x00, 0x00, 0x00, 0xf9, + 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0xfa, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x00, 0x00, + 0xed, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0xe2, 0x00, 0x00, + 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xfd, 0x00, + 0x00, 0x00, 0xd9, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xfc, + 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x06, 0x00, 0xe4, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, + 0x00, 0x01, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x3d, 0x00, + 0x06, 0x00, 0xe8, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x90, 0x01, 0x04, 0x00, 0x23, 0x00, 0x00, 0x00, 0x06, 0x01, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x05, 0x01, 0x00, 0x00, 0x06, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x23, 0x00, 0x00, + 0x00, 0x07, 0x01, 0x00, 0x00, 0x05, 0x01, 0x00, 0x00, 0x90, 0x01, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0x09, 0x01, + 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x08, 0x01, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0x3d, + 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x39, 0x00, 0x06, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x07, 0x01, 0x00, 0x00, 0x0a, 0x01, 0x00, + 0x00, 0x3e, 0x00, 0x03, 0x00, 0xf6, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x13, 0x00, + 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0xf6, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0d, + 0x01, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0xa8, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x0e, 0x01, 0x00, 0x00, 0x0d, 0x01, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xfa, 0x00, 0x04, 0x00, 0x0e, 0x01, 0x00, 0x00, 0x0f, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0xf8, 0x00, + 0x02, 0x00, 0x0f, 0x01, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0xfa, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0xed, + 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0xe2, 0x00, 0x00, 0x00, + 0x12, 0x01, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, + 0x00, 0xd9, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x12, 0x01, + 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x06, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x15, + 0x01, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x16, 0x01, 0x00, 0x00, 0xf6, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x01, 0x01, 0x00, + 0x00, 0x17, 0x01, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x90, 0x01, 0x04, 0x00, 0xe8, 0x00, + 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x16, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x05, 0x00, 0x17, 0x01, 0x00, 0x00, 0x18, + 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x10, 0x01, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0x10, 0x01, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00, 0x36, 0x00, 0x05, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x37, 0x00, + 0x03, 0x00, 0x07, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x84, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, + 0x00, 0x09, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x31, 0x00, + 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x31, + 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, + 0x00, 0x36, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x34, 0x00, + 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x3d, + 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x84, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, + 0x00, 0x09, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3c, 0x00, + 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0x00, 0x36, + 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x37, 0x00, 0x03, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00, 0x07, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x12, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, + 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x41, + 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, + 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x3e, 0x00, + 0x03, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x41, 0x00, 0x00, 0x00, 0x42, + 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x43, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x43, 0x00, 0x00, 0x00, + 0xf6, 0x00, 0x04, 0x00, 0x45, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, + 0x00, 0x47, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x47, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, + 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x05, 0x00, 0x14, 0x00, 0x00, 0x00, 0x49, + 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x49, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x44, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x4d, 0x00, + 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x4d, + 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, + 0x4e, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x3d, 0x00, + 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x05, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x3f, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, + 0x00, 0x3f, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x53, 0x00, + 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0xc2, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, + 0x57, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, + 0x00, 0x58, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x3d, 0x00, + 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x84, 0x00, 0x05, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, + 0x00, 0x3f, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x46, 0x00, 0x00, 0x00, 0xf8, 0x00, + 0x02, 0x00, 0x46, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x41, + 0x00, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x41, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, + 0x00, 0x43, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x45, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, + 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x64, + 0x00, 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x3f, 0x00, 0x00, 0x00, + 0x64, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, + 0x00, 0xc2, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x00, 0x66, 0x00, + 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xc6, + 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, + 0x00, 0x6b, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x84, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x6c, 0x00, + 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x6c, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, + 0xc2, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, + 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xc6, 0x00, + 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x3e, + 0x00, 0x03, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x72, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x84, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, + 0x00, 0x72, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x73, 0x00, + 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xc2, + 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x05, + 0x00, 0x06, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x3e, 0x00, + 0x03, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x78, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, 0x78, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0x00, + 0x36, 0x00, 0x05, 0x00, 0x14, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, + 0x00, 0x37, 0x00, 0x03, 0x00, 0x13, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00, 0x13, 0x00, + 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x19, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x07, + 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x85, 0x00, 0x00, 0x00, + 0x86, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x85, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, + 0x00, 0x07, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0xf9, 0x00, + 0x02, 0x00, 0x7c, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x7c, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x04, 0x00, 0x7e, + 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, + 0x00, 0x7b, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x05, 0x00, 0x14, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, 0x81, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x82, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x7e, + 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x84, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x86, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, + 0x00, 0x41, 0x00, 0x06, 0x00, 0x07, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x83, 0x00, + 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x87, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x41, 0x00, 0x06, 0x00, 0x07, 0x00, 0x00, + 0x00, 0x8b, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x3d, 0x00, + 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0xab, 0x00, 0x05, 0x00, 0x14, + 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, + 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, + 0x00, 0x8f, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x8e, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, 0x90, 0x00, + 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x8f, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xf8, + 0x00, 0x02, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, + 0x7b, 0x00, 0x00, 0x00, 0x80, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, + 0x00, 0x60, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0xf9, 0x00, + 0x02, 0x00, 0x7c, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x7e, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, 0x94, + 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0x00, 0x36, 0x00, 0x05, 0x00, 0x14, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00, 0x13, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, + 0x00, 0xf8, 0x00, 0x02, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x39, 0x00, 0x06, 0x00, 0x14, 0x00, 0x00, 0x00, 0x99, 0x00, + 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, 0x99, + 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0x00, 0x36, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00, 0x13, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, + 0x00, 0xf8, 0x00, 0x02, 0x00, 0x21, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x9d, 0x00, + 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x1f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, + 0x39, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, + 0x00, 0x9d, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0x00, 0x36, 0x00, + 0x05, 0x00, 0x13, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x37, + 0x00, 0x03, 0x00, 0x23, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, + 0x00, 0xac, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0xb8, 0x00, 0x00, 0x00, 0xb9, 0x00, + 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, 0x14, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x1c, + 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x04, 0x00, 0x14, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, + 0xa1, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, + 0x00, 0xa2, 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xa3, 0x00, + 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x02, + 0x00, 0x00, 0x00, 0xaa, 0x00, 0x05, 0x00, 0x14, 0x00, 0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00, + 0x42, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0xa4, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xa4, 0x00, 0x00, + 0x00, 0xf5, 0x00, 0x07, 0x00, 0x14, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x2d, 0x00, + 0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0xa8, 0x00, 0x00, 0x00, 0xa9, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0xa9, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, 0x98, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, + 0x00, 0xaa, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, 0x00, 0x20, 0x00, + 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xac, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, 0x00, 0xf9, + 0x00, 0x02, 0x00, 0xae, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xae, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x04, 0x00, + 0xb0, 0x00, 0x00, 0x00, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0xaf, 0x00, 0x00, + 0x00, 0xf8, 0x00, 0x02, 0x00, 0xaf, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb2, 0x00, + 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x82, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb4, + 0x00, 0x00, 0x00, 0xb2, 0x00, 0x00, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0xb5, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00, + 0x00, 0xb5, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xac, 0x00, 0x00, 0x00, 0xb6, 0x00, + 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x22, 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x06, 0x00, 0xbc, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, + 0x00, 0xbb, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x06, 0x00, 0x26, 0x00, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00, 0xbd, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x90, 0x01, 0x04, 0x00, 0xb7, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xb9, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x85, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, + 0x00, 0x3d, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x39, 0x00, + 0x05, 0x00, 0x14, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0xf7, + 0x00, 0x03, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0xc2, 0x00, 0x00, 0x00, + 0xc3, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xc3, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, + 0x00, 0x98, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x85, 0x00, + 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x13, + 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x39, 0x00, 0x06, 0x00, 0x14, 0x00, 0x00, 0x00, + 0xc9, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, + 0x00, 0xcb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0xc9, 0x00, 0x00, 0x00, 0xca, 0x00, + 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xca, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x85, + 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x13, 0x00, 0x00, 0x00, 0xcd, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, 0x14, 0x00, 0x00, + 0x00, 0xce, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0xcd, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x04, 0x00, 0x14, 0x00, + 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0xcb, 0x00, 0x00, 0x00, 0xf8, + 0x00, 0x02, 0x00, 0xcb, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x07, 0x00, 0x14, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, + 0xc9, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, + 0x00, 0xd2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0xd0, 0x00, 0x00, 0x00, 0xd1, 0x00, + 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xd1, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x85, + 0x00, 0x00, 0x00, 0xd3, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x13, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0xd3, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, 0xd4, 0x00, 0x00, + 0x00, 0xf8, 0x00, 0x02, 0x00, 0xd2, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0xc4, 0x00, 0x00, 0x00, 0xf8, 0x00, + 0x02, 0x00, 0xc4, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0xb1, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xb1, + 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, + 0x80, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xd7, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, + 0x00, 0x3e, 0x00, 0x03, 0x00, 0xac, 0x00, 0x00, 0x00, 0xd7, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0xae, 0x00, + 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xb0, 0x00, 0x00, 0x00, 0xff, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00 +}; + +GFXRECON_END_NAMESPACE(decode) +GFXRECON_END_NAMESPACE(gfxrecon) + +#endif // GFXRECON_DECODE_VULKAN_ADDRESS_REPLACER_SHADERS_H diff --git a/framework/decode/vulkan_device_address_tracker.cpp b/framework/decode/vulkan_device_address_tracker.cpp index 043982b81..bab13b599 100644 --- a/framework/decode/vulkan_device_address_tracker.cpp +++ b/framework/decode/vulkan_device_address_tracker.cpp @@ -123,6 +123,22 @@ VulkanDeviceAddressTracker::GetAccelerationStructureByCaptureDeviceAddress(VkDev } return nullptr; } +std::unordered_map +VulkanDeviceAddressTracker::GetAccelerationStructureDeviceAddressMap() const +{ + std::unordered_map ret; + for (const auto& [address, handleId] : _acceleration_structure_capture_addresses) + { + const VulkanAccelerationStructureKHRInfo* acceleration_structure_info = + _object_info_table.GetVkAccelerationStructureKHRInfo(handleId); + + if (acceleration_structure_info != nullptr && acceleration_structure_info->replay_address != 0) + { + ret[address] = acceleration_structure_info->replay_address; + } + } + return ret; +} GFXRECON_END_NAMESPACE(decode) GFXRECON_END_NAMESPACE(gfxrecon) \ No newline at end of file diff --git a/framework/decode/vulkan_device_address_tracker.h b/framework/decode/vulkan_device_address_tracker.h index ab7d069fe..c73857a4a 100644 --- a/framework/decode/vulkan_device_address_tracker.h +++ b/framework/decode/vulkan_device_address_tracker.h @@ -90,6 +90,13 @@ class VulkanDeviceAddressTracker [[nodiscard]] const VulkanAccelerationStructureKHRInfo* GetAccelerationStructureByCaptureDeviceAddress(VkDeviceAddress capture_address) const; + /** + * @brief Create and return a lookup-table containing all internally stored acceleration-structure addresses. + * + * @return a lookup-table for acceleration-structure addresses. + */ + [[nodiscard]] std::unordered_map GetAccelerationStructureDeviceAddressMap() const; + private: //! use a sorted (BST-based) map using buffer_address_map_t = std::map; diff --git a/framework/decode/vulkan_object_info.h b/framework/decode/vulkan_object_info.h index 4b537cf7d..f6c8a8180 100644 --- a/framework/decode/vulkan_object_info.h +++ b/framework/decode/vulkan_object_info.h @@ -280,11 +280,8 @@ struct VulkanPhysicalDeviceInfo : public VulkanObjectInfo std::string capture_device_name; VkPhysicalDeviceMemoryProperties capture_memory_properties{}; - // capture raytracing shader-binding-table properties - // extracted from VkPhysicalDeviceRayTracingPipelinePropertiesKHR - uint32_t shaderGroupHandleSize = 0; - uint32_t shaderGroupBaseAlignment = 0; - uint32_t shaderGroupHandleAlignment = 0; + // capture raytracing (shader-binding-table) properties + std::optional capture_raytracing_properties = {}; // Closest matching replay device. VulkanReplayDeviceInfo* replay_device_info{ nullptr }; @@ -623,6 +620,9 @@ struct VulkanCommandBufferInfo : public VulkanPoolObjectInfo std::vector frame_buffer_ids; std::unordered_map image_layout_barriers; format::HandleId bound_pipeline_id = format::kNullHandleId; + std::vector push_constant_data; + VkShaderStageFlags push_constant_stage_flags = 0; + VkPipelineLayout push_constant_pipeline_layout = VK_NULL_HANDLE; }; struct VulkanRenderPassInfo : public VulkanObjectInfo diff --git a/framework/decode/vulkan_rebind_allocator.cpp b/framework/decode/vulkan_rebind_allocator.cpp index 38e64ac06..96fcca471 100644 --- a/framework/decode/vulkan_rebind_allocator.cpp +++ b/framework/decode/vulkan_rebind_allocator.cpp @@ -67,16 +67,14 @@ GFXRECON_BEGIN_NAMESPACE(gfxrecon) GFXRECON_BEGIN_NAMESPACE(decode) -const format::HandleId kPlaceholderHandleId = static_cast(~0); -const uintptr_t kPlaceholderAddress = static_cast(~0); +constexpr format::HandleId kPlaceholderHandleId = static_cast(~0ul); +constexpr uintptr_t kPlaceholderAddress = static_cast(~0ul); VulkanRebindAllocator::VulkanRebindAllocator() : device_(VK_NULL_HANDLE), allocator_(VK_NULL_HANDLE), vma_functions_{}, capture_device_type_(VK_PHYSICAL_DEVICE_TYPE_OTHER), capture_memory_properties_{}, replay_memory_properties_{} {} -VulkanRebindAllocator::~VulkanRebindAllocator() {} - VkResult VulkanRebindAllocator::Initialize(uint32_t api_version, VkInstance instance, VkPhysicalDevice physical_device, @@ -200,6 +198,16 @@ VkResult VulkanRebindAllocator::Initialize(uint32_t { create_info.flags |= VMA_ALLOCATOR_CREATE_AMD_DEVICE_COHERENT_MEMORY_BIT; } + else if (entry == VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME) + { + create_info.flags |= VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT; + } + } + + if (api_version >= VK_API_VERSION_1_2) + { + // when core (1.2+), use the feature unconditionally + create_info.flags |= VMA_ALLOCATOR_CREATE_BUFFER_DEVICE_ADDRESS_BIT; } if (have_memory_reqs2 && have_dedicated_allocation) diff --git a/framework/decode/vulkan_rebind_allocator.h b/framework/decode/vulkan_rebind_allocator.h index 1c0549c36..cb5eac68a 100644 --- a/framework/decode/vulkan_rebind_allocator.h +++ b/framework/decode/vulkan_rebind_allocator.h @@ -42,7 +42,7 @@ class VulkanRebindAllocator : public VulkanResourceAllocator public: VulkanRebindAllocator(); - virtual ~VulkanRebindAllocator() override; + ~VulkanRebindAllocator() override = default; virtual VkResult Initialize(uint32_t api_version, VkInstance instance, @@ -435,17 +435,17 @@ class VulkanRebindAllocator : public VulkanResourceAllocator const VkPhysicalDeviceMemoryProperties& device_memory_properties); private: - VkDevice device_; + VkDevice device_ = VK_NULL_HANDLE; VmaAllocator allocator_; Functions functions_; VmaVulkanFunctions vma_functions_; VkPhysicalDeviceType capture_device_type_; VkPhysicalDeviceMemoryProperties capture_memory_properties_; VkPhysicalDeviceMemoryProperties replay_memory_properties_; - VkCommandBuffer cmd_buffer_; - VkCommandPool cmd_pool_; - VkQueue staging_queue_; - uint32_t staging_queue_family_; + VkCommandBuffer cmd_buffer_ = VK_NULL_HANDLE; + VkCommandPool cmd_pool_ = VK_NULL_HANDLE; + VkQueue staging_queue_ = VK_NULL_HANDLE; + uint32_t staging_queue_family_{}; }; GFXRECON_END_NAMESPACE(decode) diff --git a/framework/decode/vulkan_replay_consumer_base.cpp b/framework/decode/vulkan_replay_consumer_base.cpp index 738982005..863ddbce5 100644 --- a/framework/decode/vulkan_replay_consumer_base.cpp +++ b/framework/decode/vulkan_replay_consumer_base.cpp @@ -30,6 +30,7 @@ #include "decode/vulkan_object_info.h" #include "decode/vulkan_virtual_swapchain.h" #include "decode/vulkan_offscreen_swapchain.h" +#include "decode/vulkan_address_replacer.h" #include "decode/vulkan_enum_util.h" #include "decode/vulkan_feature_util.h" #include "decode/vulkan_object_cleanup_util.h" @@ -229,6 +230,9 @@ VulkanReplayConsumerBase::~VulkanReplayConsumerBase() // Idle all devices before destroying other resources. WaitDevicesIdle(); + // free replacer internal vulkan-resources + _device_address_replacers.clear(); + // Cleanup screenshot resources before destroying device. object_info_table_->VisitVkDeviceInfo([this](const VulkanDeviceInfo* info) { assert(info != nullptr); @@ -1350,9 +1354,7 @@ void VulkanReplayConsumerBase::SetPhysicalDeviceProperties(VulkanPhysicalDeviceI if (auto ray_capture_props = graphics::vulkan_struct_get_pnext(capture_properties)) { - physical_device_info->shaderGroupBaseAlignment = ray_capture_props->shaderGroupBaseAlignment; - physical_device_info->shaderGroupHandleAlignment = ray_capture_props->shaderGroupHandleAlignment; - physical_device_info->shaderGroupHandleSize = ray_capture_props->shaderGroupHandleSize; + physical_device_info->capture_raytracing_properties = *ray_capture_props; } if (auto ray_replay_props = @@ -4581,30 +4583,6 @@ VkResult VulkanReplayConsumerBase::OverrideBindBufferMemory(PFN_vkBindBufferMemo allocator->ReportBindBufferIncompatibility( buffer_info->handle, buffer_info->allocator_data, memory_info->allocator_data); } - - if (result == VK_SUCCESS && !allocator->SupportsOpaqueDeviceAddresses()) - { - // TODO: this might be not necessary - // On fast-forwarded traces buffer device addresses might be missing (no GetBufferDeviceAddress calls) - // Fill out this data based on original memory device address and binding offset - auto entry = device_info->opaque_addresses.find(memory_info->capture_id); - if (entry != device_info->opaque_addresses.end()) - { - uint64_t memory_device_address = entry->second; - uint64_t original_buffer_address = memory_device_address + memoryOffset; - VkBufferDeviceAddressInfo info = {}; - info.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO; - info.pNext = nullptr; - info.buffer = buffer_info->handle; - - buffer_info->capture_address = original_buffer_address; - buffer_info->replay_address = - GetDeviceTable(device_info->handle)->GetBufferDeviceAddress(device_info->handle, &info); - - // track buffer-addresses - GetDeviceAddressTracker(device_info->handle).TrackBuffer(buffer_info); - } - } return result; } @@ -5014,7 +4992,7 @@ void VulkanReplayConsumerBase::OverrideDestroyBuffer( allocator->DestroyBuffer(buffer, GetAllocationCallbacks(pAllocator), allocator_data); // remove from device-address tracking - GetDeviceAddressTracker(device_info->handle).RemoveBuffer(buffer_info); + GetDeviceAddressTracker(device_info).RemoveBuffer(buffer_info); } VkResult @@ -7688,7 +7666,7 @@ void VulkanReplayConsumerBase::OverrideDestroyAccelerationStructureKHR( acceleration_structure = acceleration_structure_info->handle; // remove from address-tracking - GetDeviceAddressTracker(device_info->handle).RemoveAccelerationStructure(acceleration_structure_info); + GetDeviceAddressTracker(device_info).RemoveAccelerationStructure(acceleration_structure_info); } func(device_info->handle, acceleration_structure, GetAllocationCallbacks(pAllocator)); } @@ -7701,65 +7679,19 @@ void VulkanReplayConsumerBase::OverrideCmdBuildAccelerationStructuresKHR( StructPointerDecoder* ppBuildRangeInfos) { VulkanDeviceInfo* device_info = object_info_table_->GetVkDeviceInfo(command_buffer_info->parent_id); - VkCommandBuffer command_buffer = command_buffer_info->handle; + VkCommandBuffer command_buffer = command_buffer_info->handle; VkAccelerationStructureBuildGeometryInfoKHR* build_geometry_infos = pInfos->GetPointer(); VkAccelerationStructureBuildRangeInfoKHR** build_range_infos = ppBuildRangeInfos->GetPointer(); - auto& address_tracker = GetDeviceAddressTracker(device_info->handle); - - auto address_remap = [&address_tracker](VkDeviceAddress& capture_address) { - auto buffer_info = address_tracker.GetBufferByCaptureDeviceAddress(capture_address); - - // TODO: we 'should' find that buffer here, check what's missing - if (buffer_info != nullptr && buffer_info->replay_address != 0) - { - uint64_t offset = capture_address - buffer_info->capture_address; - - // in-place address-remap via const-cast - capture_address = buffer_info->replay_address + offset; - } - }; - - for (uint32_t i = 0; i < infoCount; ++i) + if (!device_info->allocator->SupportsOpaqueDeviceAddresses()) { - auto& build_geometry_info = build_geometry_infos[i]; + auto& address_tracker = GetDeviceAddressTracker(device_info); + auto& address_replacer = GetDeviceAddressReplacer(device_info); - for (uint32_t j = 0; j < build_geometry_info.geometryCount; ++j) - { - auto geometry = const_cast(build_geometry_info.pGeometries != nullptr - ? build_geometry_info.pGeometries + j - : build_geometry_info.ppGeometries[j]); - switch (geometry->geometryType) - { - case VK_GEOMETRY_TYPE_TRIANGLES_KHR: - { - auto& triangles = geometry->geometry.triangles; - address_remap(triangles.vertexData.deviceAddress); - address_remap(triangles.indexData.deviceAddress); - break; - } - case VK_GEOMETRY_TYPE_AABBS_KHR: - { - auto& aabbs = geometry->geometry.aabbs; - address_remap(aabbs.data.deviceAddress); - break; - } - case VK_GEOMETRY_TYPE_INSTANCES_KHR: - { - auto& instances = geometry->geometry.instances; - address_remap(instances.data.deviceAddress); - // TODO: replace VkAccelerationStructureInstanceKHR::accelerationStructureReference inside buffer - // (issue #1526) - break; - } - default: - GFXRECON_LOG_ERROR( - "OverrideCmdBuildAccelerationStructuresKHR: unhandled case in switch-statement: %d", - geometry->geometryType); - break; - } - } + address_replacer.ProcessCmdBuildAccelerationStructuresKHR( + command_buffer_info, infoCount, build_geometry_infos, build_range_infos, address_tracker); } + func(command_buffer, infoCount, build_geometry_infos, build_range_infos); } @@ -7842,7 +7774,8 @@ VkResult VulkanReplayConsumerBase::OverrideCreateRayTracingPipelinesKHR( &pPipelines->GetPointer()[createInfoCount]); } - // NOTE: this is basically never true and does not look like it's going to change soon + // NOTE: this is almost never true, even on newest desktop-drivers + // TODO: consider removing all of the feature_rayTracingPipelineShaderGroupHandleCaptureReplay logic here if (device_info->property_feature_info.feature_rayTracingPipelineShaderGroupHandleCaptureReplay) { // Modify pipeline create infos with capture replay flag and data. @@ -8119,14 +8052,14 @@ VkDeviceAddress VulkanReplayConsumerBase::OverrideGetBufferDeviceAddress( } // keep track of old/new addresses in any case - format::HandleId buffer = pInfo->GetMetaStructPointer()->buffer; + format::HandleId buffer = pInfo->GetMetaStructPointer()->buffer; VulkanBufferInfo* buffer_info = GetObjectInfoTable().GetVkBufferInfo(buffer); GFXRECON_ASSERT(buffer_info != nullptr); buffer_info->capture_address = original_result; buffer_info->replay_address = replay_device_address; // track device-addresses - GetDeviceAddressTracker(device).TrackBuffer(buffer_info); + GetDeviceAddressTracker(device_info).TrackBuffer(buffer_info); return replay_device_address; } @@ -8138,13 +8071,6 @@ void VulkanReplayConsumerBase::OverrideGetAccelerationStructureDeviceAddressKHR( { assert((device_info != nullptr) && (pInfo != nullptr) && !pInfo->IsNull() && (pInfo->GetPointer() != nullptr)); - if (!device_info->property_feature_info.feature_accelerationStructureCaptureReplay) - { - GFXRECON_LOG_WARNING_ONCE("The captured application used vkGetAccelerationStructureDeviceAddressKHR, which may " - "require the accelerationStructureCaptureReplay feature for accurate capture and " - "replay. The replay device does not support this feature, so replay may fail."); - } - VkDevice device = device_info->handle; const VkAccelerationStructureDeviceAddressInfoKHR* address_info = pInfo->GetPointer(); @@ -8157,15 +8083,9 @@ void VulkanReplayConsumerBase::OverrideGetAccelerationStructureDeviceAddressKHR( acceleration_structure_info->replay_address = replay_address; // track device-address - GetDeviceAddressTracker(device).TrackAccelerationStructure(acceleration_structure_info); + GetDeviceAddressTracker(device_info).TrackAccelerationStructure(acceleration_structure_info); - if (!device_info->allocator->SupportsOpaqueDeviceAddresses()) - { - GFXRECON_LOG_WARNING_ONCE( - "The captured application used vkGetAccelerationStructureDeviceAddressKHR. The specified replay option '-m " - "rebind' may not support the replay of captured device addresses, so replay may fail."); - } - else + if (device_info->allocator->SupportsOpaqueDeviceAddresses()) { // opaque addresses should match GFXRECON_ASSERT(original_result == replay_address); @@ -8196,7 +8116,7 @@ VulkanReplayConsumerBase::OverrideGetRayTracingShaderGroupHandlesKHR(PFN_vkGetRa auto physical_device_info = GetObjectInfoTable().GetVkPhysicalDeviceInfo(device_info->parent_id); // in practice: always 32 bytes - uint32_t capture_handle_size = physical_device_info->shaderGroupHandleSize; + uint32_t capture_handle_size = physical_device_info->capture_raytracing_properties->shaderGroupHandleSize; uint32_t replay_handle_size = physical_device_info->replay_device_info->raytracing_properties->shaderGroupHandleSize; @@ -8257,6 +8177,9 @@ void VulkanReplayConsumerBase::ClearCommandBufferInfo(VulkanCommandBufferInfo* c command_buffer_info->is_frame_boundary = false; command_buffer_info->frame_buffer_ids.clear(); command_buffer_info->bound_pipeline_id = format::kNullHandleId; + command_buffer_info->push_constant_data.clear(); + command_buffer_info->push_constant_stage_flags = 0; + command_buffer_info->push_constant_pipeline_layout = VK_NULL_HANDLE; } VkResult VulkanReplayConsumerBase::OverrideBeginCommandBuffer( @@ -8401,6 +8324,32 @@ void VulkanReplayConsumerBase::OverrideCmdBindPipeline(PFN_vkCmdBindPipeline func(command_buffer, pipelineBindPoint, pipeline); } +void VulkanReplayConsumerBase::OverrideCmdPushConstants(PFN_vkCmdPushConstants func, + VulkanCommandBufferInfo* command_buffer_info, + VulkanObjectInfo* pipeline_layout_info, + VkShaderStageFlags stage_flags, + uint32_t offset, + uint32_t size, + PointerDecoder* data_decoder) +{ + VkCommandBuffer command_buffer = VK_NULL_HANDLE; + VkPipelineLayout pipeline_layout = VK_NULL_HANDLE; + const void* data = data_decoder->GetPointer(); + + if (command_buffer_info != nullptr && pipeline_layout_info != nullptr) + { + command_buffer = command_buffer_info->handle; + pipeline_layout = pipeline_layout_info->handle; + + // keep track of current push-constants + command_buffer_info->push_constant_stage_flags = stage_flags; + command_buffer_info->push_constant_pipeline_layout = pipeline_layout; + command_buffer_info->push_constant_data.resize(offset + size, 0); + memcpy(command_buffer_info->push_constant_data.data() + offset, data, size); + } + func(command_buffer, pipeline_layout, stage_flags, offset, size, data); +} + void VulkanReplayConsumerBase::OverrideCmdBeginRenderPass( PFN_vkCmdBeginRenderPass func, VulkanCommandBufferInfo* command_buffer_info, @@ -8507,97 +8456,27 @@ void VulkanReplayConsumerBase::OverrideCmdTraceRaysKHR( { if (command_buffer_info != nullptr) { - VkCommandBuffer commandBuffer = command_buffer_info->handle; + const VulkanDeviceInfo* device_info = GetObjectInfoTable().GetVkDeviceInfo(command_buffer_info->parent_id); + VkCommandBuffer commandBuffer = command_buffer_info->handle; VkStridedDeviceAddressRegionKHR* in_pRaygenShaderBindingTable = pRaygenShaderBindingTable->GetPointer(); VkStridedDeviceAddressRegionKHR* in_pMissShaderBindingTable = pMissShaderBindingTable->GetPointer(); VkStridedDeviceAddressRegionKHR* in_pHitShaderBindingTable = pHitShaderBindingTable->GetPointer(); VkStridedDeviceAddressRegionKHR* in_pCallableShaderBindingTable = pCallableShaderBindingTable->GetPointer(); // identify buffer(s) by their device-address - const VulkanDeviceInfo* device_info = GetObjectInfoTable().GetVkDeviceInfo(command_buffer_info->parent_id); - const auto& address_tracker = GetDeviceAddressTracker(device_info->handle); - - auto address_remap = [&address_tracker](VkStridedDeviceAddressRegionKHR* address_region) { - if (address_region->size > 0) - { - auto buffer_info = address_tracker.GetBufferByCaptureDeviceAddress(address_region->deviceAddress); - GFXRECON_ASSERT(buffer_info != nullptr); - - if (buffer_info->replay_address != 0) - { - uint64_t offset = address_region->deviceAddress - buffer_info->capture_address; - - // in-place address-remap - address_region->deviceAddress = buffer_info->replay_address + offset; - } - else - { - GFXRECON_LOG_WARNING_ONCE( - "OverrideCmdTraceRaysKHR: missing buffer_info->replay_address, remap failed") - } - } - }; + const auto& address_tracker = GetDeviceAddressTracker(device_info); + auto& address_replacer = GetDeviceAddressReplacer(device_info); auto bound_pipeline = GetObjectInfoTable().GetVkPipelineInfo(command_buffer_info->bound_pipeline_id); GFXRECON_ASSERT(bound_pipeline != nullptr) - // NOTE: expect this map to be populated here, but not for older captures using trimming. - auto& shader_group_handles = bound_pipeline->shader_group_handle_map; - - // figure out if the captured group-handles are valid for replay - bool valid_group_handles = !shader_group_handles.empty(); - bool valid_sbt_alignment = true; - - const VulkanPhysicalDeviceInfo* physical_device_info = - GetObjectInfoTable().GetVkPhysicalDeviceInfo(device_info->parent_id); - - if (physical_device_info != nullptr && physical_device_info->replay_device_info->raytracing_properties) - { - const auto& replay_props = *physical_device_info->replay_device_info->raytracing_properties; - - if (physical_device_info->shaderGroupHandleSize != replay_props.shaderGroupHandleSize || - physical_device_info->shaderGroupHandleAlignment != replay_props.shaderGroupHandleAlignment || - physical_device_info->shaderGroupBaseAlignment != replay_props.shaderGroupBaseAlignment) - { - valid_sbt_alignment = false; - } - } - - for (const auto& [lhs, rhs] : shader_group_handles) - { - if (lhs != rhs) - { - valid_group_handles = false; - break; - } - } - - if (!(valid_group_handles && valid_sbt_alignment)) - { - if (!valid_sbt_alignment) - { - // TODO: remove TODO/warning when issue #1526 is solved - GFXRECON_LOG_WARNING_ONCE("OverrideCmdTraceRaysKHR: invalid shader-binding-table (handle-size and/or " - "alignments mismatch) -> TODO: run SBT re-assembly"); - - // TODO: create shadow-SBT-buffer, remap addresses to that - } - else - { - // in-place remap: capture-addresses -> replay-addresses - address_remap(in_pRaygenShaderBindingTable); - address_remap(in_pMissShaderBindingTable); - address_remap(in_pHitShaderBindingTable); - address_remap(in_pCallableShaderBindingTable); - } - - // TODO: run sbt-handle replacer. (create linear hashmap (x), [create shadow-buffer], run compute-shader) - util::linear_hashmap hashmap; - for (const auto& [lhs, rhs] : shader_group_handles) - { - hashmap.put(lhs, rhs); - } - } + address_replacer.ProcessCmdTraceRays(command_buffer_info, + in_pRaygenShaderBindingTable, + in_pMissShaderBindingTable, + in_pHitShaderBindingTable, + in_pCallableShaderBindingTable, + address_tracker, + bound_pipeline->shader_group_handle_map); func(commandBuffer, in_pRaygenShaderBindingTable, @@ -9372,13 +9251,29 @@ void VulkanReplayConsumerBase::UpdateDescriptorSetInfoWithTemplate( } } -VulkanDeviceAddressTracker& VulkanReplayConsumerBase::GetDeviceAddressTracker(VkDevice device) +VulkanDeviceAddressTracker& +VulkanReplayConsumerBase::GetDeviceAddressTracker(const decode::VulkanDeviceInfo* device_info) { - auto it = _device_address_trackers.find(device); + auto it = _device_address_trackers.find(device_info); if (it == _device_address_trackers.end()) { auto [new_it, success] = - _device_address_trackers.insert({ device, VulkanDeviceAddressTracker(*object_info_table_) }); + _device_address_trackers.insert({ device_info, VulkanDeviceAddressTracker(*object_info_table_) }); + GFXRECON_ASSERT(success); + return new_it->second; + } + return it->second; +} + +VulkanAddressReplacer& VulkanReplayConsumerBase::GetDeviceAddressReplacer(const decode::VulkanDeviceInfo* device_info) +{ + auto it = _device_address_replacers.find(device_info); + if (it == _device_address_replacers.end()) + { + auto [new_it, success] = _device_address_replacers.insert( + { device_info, + VulkanAddressReplacer(device_info, GetDeviceTable(device_info->handle), *object_info_table_) }); + GFXRECON_ASSERT(success); return new_it->second; } return it->second; diff --git a/framework/decode/vulkan_replay_consumer_base.h b/framework/decode/vulkan_replay_consumer_base.h index eca6c61c8..b87778a35 100644 --- a/framework/decode/vulkan_replay_consumer_base.h +++ b/framework/decode/vulkan_replay_consumer_base.h @@ -30,6 +30,7 @@ #include "decode/screenshot_handler.h" #include "decode/swapchain_image_tracker.h" #include "decode/vulkan_device_address_tracker.h" +#include "decode/vulkan_address_replacer.h" #include "decode/vulkan_handle_mapping_util.h" #include "decode/vulkan_object_info.h" #include "decode/common_object_info_table.h" @@ -1274,6 +1275,14 @@ class VulkanReplayConsumerBase : public VulkanConsumer VkPipelineBindPoint pipelineBindPoint, VulkanPipelineInfo* pipeline_info); + void OverrideCmdPushConstants(PFN_vkCmdPushConstants func, + VulkanCommandBufferInfo* command_buffer_info, + VulkanObjectInfo* pipeline_layout_info, + VkShaderStageFlags stage_flags, + uint32_t offset, + uint32_t size, + PointerDecoder* data_decoder); + void OverrideCmdBeginRenderPass(PFN_vkCmdBeginRenderPass func, VulkanCommandBufferInfo* command_buffer_info, StructPointerDecoder* render_pass_begin_info_decoder, @@ -1524,7 +1533,8 @@ class VulkanReplayConsumerBase : public VulkanConsumer const VulkanDescriptorUpdateTemplateInfo* template_info, const DescriptorUpdateTemplateDecoder* decoder) const; - VulkanDeviceAddressTracker& GetDeviceAddressTracker(VkDevice device); + decode::VulkanDeviceAddressTracker& GetDeviceAddressTracker(const decode::VulkanDeviceInfo* device_info); + decode::VulkanAddressReplacer& GetDeviceAddressReplacer(const decode::VulkanDeviceInfo* device_info); [[nodiscard]] std::vector> ReplaceShaders(uint32_t create_info_count, VkGraphicsPipelineCreateInfo* create_infos, @@ -1581,7 +1591,8 @@ class VulkanReplayConsumerBase : public VulkanConsumer std::string screenshot_file_prefix_; graphics::FpsInfo* fps_info_; - std::unordered_map _device_address_trackers; + std::unordered_map _device_address_trackers; + std::unordered_map _device_address_replacers; util::ThreadPool main_thread_queue_; util::ThreadPool background_queue_; diff --git a/framework/generated/generated_vulkan_replay_consumer.cpp b/framework/generated/generated_vulkan_replay_consumer.cpp index 4f776e73b..b9e9825ca 100644 --- a/framework/generated/generated_vulkan_replay_consumer.cpp +++ b/framework/generated/generated_vulkan_replay_consumer.cpp @@ -2224,15 +2224,14 @@ void VulkanReplayConsumer::Process_vkCmdPushConstants( uint32_t size, PointerDecoder* pValues) { - VkCommandBuffer in_commandBuffer = MapHandle(commandBuffer, &CommonObjectInfoTable::GetVkCommandBufferInfo); - VkPipelineLayout in_layout = MapHandle(layout, &CommonObjectInfoTable::GetVkPipelineLayoutInfo); - const void* in_pValues = pValues->GetPointer(); + auto in_commandBuffer = GetObjectInfoTable().GetVkCommandBufferInfo(commandBuffer); + auto in_layout = GetObjectInfoTable().GetVkPipelineLayoutInfo(layout); - GetDeviceTable(in_commandBuffer)->CmdPushConstants(in_commandBuffer, in_layout, stageFlags, offset, size, in_pValues); + OverrideCmdPushConstants(GetDeviceTable(in_commandBuffer->handle)->CmdPushConstants, in_commandBuffer, in_layout, stageFlags, offset, size, pValues); if (options_.dumping_resources) { - resource_dumper_->Process_vkCmdPushConstants(call_info, GetDeviceTable(in_commandBuffer)->CmdPushConstants, in_commandBuffer, in_layout, stageFlags, offset, size, in_pValues); + resource_dumper_->Process_vkCmdPushConstants(call_info, GetDeviceTable(in_commandBuffer->handle)->CmdPushConstants, in_commandBuffer->handle, in_layout->handle, stageFlags, offset, size, pValues); } } diff --git a/framework/generated/vulkan_generators/replay_overrides.json b/framework/generated/vulkan_generators/replay_overrides.json index a0da0740f..b08c47bcd 100644 --- a/framework/generated/vulkan_generators/replay_overrides.json +++ b/framework/generated/vulkan_generators/replay_overrides.json @@ -128,6 +128,7 @@ "vkCmdBuildAccelerationStructuresKHR": "OverrideCmdBuildAccelerationStructuresKHR", "vkCmdCopyAccelerationStructureKHR" : "OverrideCmdCopyAccelerationStructureKHR", "vkCmdWriteAccelerationStructuresPropertiesKHR" : "OverrideCmdWriteAccelerationStructuresPropertiesKHR", - "vkCmdBindPipeline" : "OverrideCmdBindPipeline" + "vkCmdBindPipeline" : "OverrideCmdBindPipeline", + "vkCmdPushConstants" : "OverrideCmdPushConstants" } } diff --git a/framework/util/linear_hashmap.h b/framework/util/linear_hashmap.h index 3f8be53e9..ccb319b2f 100644 --- a/framework/util/linear_hashmap.h +++ b/framework/util/linear_hashmap.h @@ -25,6 +25,7 @@ #include "util/defines.h" #include "util/hash.h" +#include #include #include #include @@ -75,7 +76,7 @@ class linear_hashmap linear_hashmap() = default; linear_hashmap(const linear_hashmap&) = delete; - linear_hashmap(linear_hashmap& other) : linear_hashmap() { swap(*this, other); }; + linear_hashmap(linear_hashmap&& other) noexcept : linear_hashmap() { swap(*this, other); }; linear_hashmap& operator=(linear_hashmap other) { swap(*this, other);