diff options
32 files changed, 4230 insertions, 1032 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 2a779fc..ff47cea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,6 +109,9 @@ set(GPU_SOURCES ) set(3D_SOURCES src/3d/renderer.cc + src/3d/renderer_sdf.cc + src/3d/renderer_mesh.cc + src/3d/renderer_skybox.cc src/3d/visual_debug.cc src/3d/bvh.cc src/3d/physics.cc @@ -372,6 +375,10 @@ if(DEMO_BUILD_TESTS) add_demo_executable(test_3d_physics src/tests/test_3d_physics.cc ${PLATFORM_SOURCES} ${GENERATED_TIMELINE_CC} ${GEN_DEMO_CC} ${GENERATED_MUSIC_DATA_CC}) target_link_libraries(test_3d_physics PRIVATE 3d gpu audio procedural util ${DEMO_LIBS}) add_dependencies(test_3d_physics generate_timeline generate_demo_assets generate_tracker_music) + + add_demo_executable(test_mesh src/tests/test_mesh.cc ${PLATFORM_SOURCES} ${GENERATED_TIMELINE_CC} ${GEN_DEMO_CC} ${GENERATED_MUSIC_DATA_CC}) + target_link_libraries(test_mesh PRIVATE 3d gpu audio procedural util ${DEMO_LIBS}) + add_dependencies(test_mesh generate_timeline generate_demo_assets generate_tracker_music) endif() #-- - Extra Tools -- - @@ -395,4 +402,4 @@ add_custom_target(final add_custom_target(pack_source COMMAND tar -czf demo_all.tgz --exclude=.git --exclude=build* --exclude=.gemini* --exclude=*.tgz --exclude=*.zip --exclude=.DS_Store . WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} -) +)
\ No newline at end of file diff --git a/PROJECT_CONTEXT.md b/PROJECT_CONTEXT.md index 520e733..e176179 100644 --- a/PROJECT_CONTEXT.md +++ b/PROJECT_CONTEXT.md @@ -33,7 +33,7 @@ Style: ### Recently Completed #### Milestone: Audio Playback Stability & Debug Infrastructure (February 4, 2026) -- **Core Audio Backend Optimization**: Resolved critical audio playback issues (stop-and-go, glitches, eventual silence) caused by timing mismatches in miniaudio's Core Audio backend. Root cause: Core Audio optimized for 44.1kHz with 10ms periods, but our 32kHz system expected uniform ~13.78ms callbacks, causing resampling jitter. Fix: Added `allowNominalSampleRateChange = TRUE` to force OS-level 32kHz native playback and `performanceProfile = conservative` for larger buffers (4096 frames = 128ms). Result: Stable ~128ms callbacks with <1ms jitter, zero underruns during variable tempo (1.0x → 2.0x). +- **Core Audio Backend Optimization**: Resolved critical audio playback issues (stop-and-go, glitches, eventual silence) caused by timing mismatches in miniaudio's Core Audio backend. Root cause: Core Audio optimized for 44.1kHz with 10ms periods, but our 32kHz system expected uniform ~13.78ms callbacks, causing resampling jitter. Fix: Added `allowNominalSampleRateChange = TRUE` to force OS-level 32kHz native and `performanceProfile = conservative` for larger buffers (4096 frames = 128ms). Result: Stable ~128ms callbacks with <1ms jitter, zero underruns during variable tempo (1.0x → 2.0x). - **Ring Buffer Capacity Tuning**: Increased ring buffer from 200ms to 400ms (25,600 samples) to handle tempo scaling headroom. Added comprehensive bounds checking with abort() on violations to catch buffer corruption early. Fixed critical bug: tempo-scaled rendering wasn't scaling dt when pre-filling buffer (`audio_render_ahead(g_music_time, dt * g_tempo_scale)`). Buffer now maintains 400ms fullness throughout playback, including 2.0x tempo acceleration. @@ -78,6 +78,7 @@ Style: - **Tight Ray Bounds (Task 21.2)**: Implemented local-space ray-box intersection to optimize SDF raymarching. - **High-DPI Fix**: Resolved viewport "squishing" via dynamic resolution uniforms and explicit viewports. - **Unified 3D Shadows**: Implemented robust SDF shadows across all objects using `inv_model` transforms. +- **test_mesh tool**: Implemented a standalone `test_mesh` tool for visualizing OBJ files with debug normal display. --- ## Next Up @@ -88,7 +89,6 @@ Style: - **Task #18: 3D System Enhancements** - [ ] **Task #18.0: Basic OBJ Asset Pipeline**: Implement `ASSET_MESH` type, `asset_packer` OBJ support, and `Renderer3D` mesh rendering. - - [ ] **Task #36: Blender Exporter**: Create script to export scenes to internal binary format. - [ ] **Task #37: Asset Ingestion**: Update `asset_packer` to handle the new 3D binary format. - [ ] **Task #38: Runtime Loader**: Implement a minimal C++ parser to load the scene data into the ECS/Renderer. @@ -102,12 +102,13 @@ Style: --- ## Future Goals +- **Task #36: Blender Exporter**: Create script to export scenes to internal binary format. (Deprioritized) - **Task #5: Implement Spectrogram Editor** - [ ] Develop a web-based tool (`tools/editor`) for creating and editing `.spec` files visually. - **Task #21: Shader Optimization** - [ ] Use macros or code generation to factorize common WGSL code (normals, bump, lighting). - [ ] Implement Tri-planar mapping for better procedural textures. -- **Task #18-B: GPU BVH & Shadows**: Optimize scene queries with a GPU-based BVH. +- [ ] **Task #18-B: GPU BVH & Shadows**: Optimize scene queries with a GPU-based BVH. - **Phase 2: Advanced Size Optimization** - [ ] **Task #22: Windows Native Platform**: Replace GLFW with minimal native Windows API. - [ ] **Task #28: Spectrogram Quantization**: Quantize spectrograms to logarithmic frequency and uint16_t. @@ -18,8 +18,8 @@ This file tracks prioritized tasks with detailed attack plans. - [x] **Integration & Visualization**: Added `velocity`, `mass`, `is_static` to `Object3D`. Integrated physics loop into `test_3d_render.cc` and added BVH wireframe visualization to `VisualDebug`. - [x] **Audio Playback Debugging & Core Audio Optimization**: - - [x] **Core Audio Timing Fix**: Resolved stop-and-go audio glitches caused by timing mismatch. Core Audio optimized for 44.1kHz (10ms periods), but 32kHz system expected ~13.78ms callbacks. Added `allowNominalSampleRateChange = TRUE` to force OS-level 32kHz native and `performanceProfile = conservative` for 4096-frame buffers (128ms). Result: Stable ~128ms callbacks, <1ms jitter, zero underruns. - - [x] **Ring Buffer Capacity**: Increased from 200ms to 400ms (25,600 samples) for tempo scaling headroom. Added bounds checking with abort() on violations. + - [x] **Core Audio Timing Fix**: Resolved stop-and-go audio glitches caused by timing mismatch. Core Audio optimized for 44.1kHz (10ms periods), but our 32kHz system expected uniform ~13.78ms callbacks, causing resampling jitter. Fix: Added `allowNominalSampleRateChange = TRUE` to force OS-level 32kHz native and `performanceProfile = conservative` for 4096-frame buffers (128ms). Result: Stable ~128ms callbacks, <1ms jitter, zero underruns. + - [x] **Ring Buffer Capacity**: Increased from 200ms to 400ms (25,600 samples) to handle tempo scaling headroom. Added comprehensive bounds checking with abort() on violations. - [x] **Tempo-Scaled Buffer Fill**: Fixed critical bug where buffer pre-fill didn't scale dt by tempo (`audio_render_ahead(g_music_time, dt * g_tempo_scale)`). Buffer now maintains 400ms fullness during 2.0x acceleration. - [x] **Extensive Diagnostics**: Added high-resolution timing tracking (clock_gettime), callback interval measurement, buffer level monitoring, underrun detection. All under conditional compilation for future debugging. @@ -86,7 +86,7 @@ This file tracks prioritized tasks with detailed attack plans. - [x] **Task #51.1: Audio Backend Abstraction**: - [x] **Interface Created**: Defined `AudioBackend` interface in `src/audio/audio_backend.h` with hooks for voice triggering and frame rendering. - - [x] **Production Backend**: Moved miniaudio implementation to `MiniaudioBackend` class, maintaining backward compatibility. + - [x] **Production Backend**: Moved miniaudio implementation from `audio.cc` to `MiniaudioBackend` class, maintaining backward compatibility. - [x] **Audio Refactoring**: Updated `audio.cc` to use backend abstraction with automatic fallback to `MiniaudioBackend`. - [x] **Event Hooks**: Added time tracking to `synth.cc` with `on_voice_triggered()` callbacks (guarded by `!STRIP_ALL`). - [x] **Verification Test**: Created `test_audio_backend.cc` to verify backend injection and event recording work correctly. @@ -116,7 +116,7 @@ This file tracks prioritized tasks with detailed attack plans. - [x] **Documentation:** Updated `doc/HOWTO.md` with usage instructions. - [x] **Skybox & Two-pass Rendering Stability**: - [x] **Fixed Two-pass Rendering:** Implemented mandatory clear operations for color and depth when the skybox is absent, preventing black screens and depth validation errors. - - [x] **Implemented Rotating Skybox:** Added `inv_view_proj` to `GlobalUniforms` and updated the skybox shader to perform world-space ray unprojection, enabling correct rotation with the camera. + - [x] **Implemented Rotating Skybox:** Added `inv_view_proj` to `GlobalUniforms` and updated the skybox shader to perform world-space ray unprojection (`inv_view_proj`), enabling correct rotation with the camera. - [x] **Enhanced Procedural Noise:** Implemented a multi-octave Value Noise generator for higher-quality skybox textures. - [x] **Scene Integrity:** Restored proper object indexing and removed redundant geometry, ensuring the floor grid and objects render correctly. @@ -137,20 +137,39 @@ This file tracks prioritized tasks with detailed attack plans. - **Result**: Fully functional timeline editor ready for production use. Phase 1.1 complete (basic editing, snap-to-beat, waveform). Phase 1.2 (Add Effect button) and Phase 2.5 (music.track visualization) documented in ROADMAP.md. - **Files**: `tools/timeline_editor/index.html` (~1200 lines), `README.md`, `ROADMAP.md` (3 phases, 117-161 hour estimate). +## Critical Fixes + +- [ ] **Task A: Fix Test Mesh** + - [ ] Investigate and fix bad bounding box (clipping at the bottom) for `dodecahedron.obj`. + - [ ] Investigate and fix strange normals for `dodecahedron.obj`. + - [ ] Fix incorrect shadows on the floor plane. + +- [ ] **Task B: Move platform-specific conditional code into a single header location** + - [ ] Abstract out `#if defined(DEMO_CROSS_COMPILE_WIN32)` statements from core `.cc` and `.h` sources. + - [ ] Centralize platform-specific code and `#ifdef`s into `platform.h` or equivalent. + - [ ] Address `str_view()` calls that cause compilation breaks. + +- [ ] **Task C: Minimal Builds with dependency graph** + - [ ] Investigate solutions for faster, minimal recompilation (dependency graph). + - [ ] Plan CMake configuration modifications. + - [ ] Implement the solution. + - [ ] Ensure Gemini/Claude are aware of and use the dependency graph. + ## Priority 2: 3D System Enhancements (Task #18) **Goal:** Establish a pipeline for importing complex 3D scenes to replace hardcoded geometry. -- [ ] **Task #18.0: Basic OBJ Asset Pipeline** (New) - - [ ] Define `ASSET_MESH` type in `asset_manager`. - - [ ] Update `asset_packer` to parse simple `.obj` files (positions, normals, UVs) and serialize them. - - [ ] Update `Renderer3D` to handle `ObjectType::MESH` in the rasterization path. -- [ ] **Task #36: Blender Exporter:** Create a Python script (`tools/blender_export.py`) to export meshes/cameras/lights to a binary asset format. +- [x] **Task #18.0: Basic OBJ Asset Pipeline** (New) + - [x] Define `ASSET_MESH` type in `asset_manager`. + - [x] Update `asset_packer` to parse simple `.obj` files (positions, normals, UVs) and serialize them. + - [x] Update `Renderer3D` to handle `ObjectType::MESH` in the rasterization path. +- [ ] **Task #36: Blender Exporter:** Create a Python script (`tools/blender_export.py`) to export meshes/cameras/lights to a binary asset format. (Deprioritized) - [ ] **Task #37: Asset Ingestion:** Update `asset_packer` to handle the new 3D binary format. - [ ] **Task #38: Runtime Loader:** Implement a minimal C++ parser to load the scene data into the ECS/Renderer. -- [ ] **Task #18-B: GPU BVH & Shadows** (Optimization) - - [ ] **Upload BVH:** Create a storage buffer for `BVHNode` data and upload the CPU-built BVH every frame in `Renderer3D`. - - [ ] **Shader Traversal:** Implement stack-based BVH traversal in `scene_query.wgsl` to replace the linear loop in `map_scene`. - - [ ] **Shadow Optimization:** Use the BVH traversal for `calc_shadow` to skip occluded objects efficiently. +- [x] **Task #18-B: GPU BVH & Shadows** (Optimization) + - [x] **Upload BVH:** Create a storage buffer for `BVHNode` data and upload the CPU-built BVH every frame in `Renderer3D`. + - [x] **Shader Traversal:** Implement stack-based BVH traversal in `scene_query.wgsl` to replace the linear loop in `map_scene`. + - [x] **Shadow Optimization:** Use the BVH traversal for `calc_shadow` to skip occluded objects efficiently. + - [x] **Compile-Time Switch:** Implemented dual-pipeline architecture (BVH vs Linear) using `ShaderComposer` substitution to avoid runtime branching cost. ## Priority 3: WGSL Modularization (Task #50) [RECURRENT] @@ -175,6 +194,21 @@ This file tracks prioritized tasks with detailed attack plans. - [ ] **Task #35: CRT Replacement**: investigation and implementation of CRT-free entry point. +## Future Goals & Ideas (Untriaged) + +- [ ] **Task #52: Procedural SDF Font**: Minimal bezier/spline set for [A-Z, 0-9] and SDF rendering. +- [ ] **Task #53: Particles Shader Polish**: Improve visual quality of particles. +- [ ] **Task #55: SDF Random Planes Intersection**: Implement `sdPolyhedron` (crystal/gem shapes) via plane intersection. +- [ ] **Task #54: Tracy Integration**: Integrate Tracy debugger for performance profiling. +- [ ] **Task #58: Advanced Shader Factorization**: Further factorize WGSL code into smaller, reusable snippets. +- [ ] **Task #59: Comprehensive RNG Library**: Add WGSL snippets for float/vec2/vec3 noise (Perlin, Gyroid, etc.) and random number generators. +- [ ] **Task #60: OOP Refactoring**: Investigate if more C++ code can be made object-oriented without size penalty (vs functional style). +- [ ] **Task #61: GPU Procedural Generation**: Implement system to generate procedural data (textures, geometry) on GPU and read back to CPU. +- [ ] **Task #62: Physics Engine Enhancements (PBD & Rotation)**: + - [ ] **Task #62.1: Quaternion Rotation**: Implement quaternion-based rotation for `Object3D` and incorporate angular momentum into physics. + - [ ] **Task #62.2: Position Based Dynamics (PBD)**: Refactor solver to re-evaluate velocity after resolving all collisions and constraints. +- [ ] **Task #63: Refactor large files**: Split `src/3d/renderer.cc` (currently > 500 lines) into sub-functionalities. + --- ## Task #51: Tracker Timing Verification - Detailed Attack Plan @@ -426,4 +460,4 @@ tools/timeline_editor/ --- -## Future Goals +## Future Goals
\ No newline at end of file diff --git a/assets/final/demo_assets.txt b/assets/final/demo_assets.txt index c38da51..d5ce9b4 100644 --- a/assets/final/demo_assets.txt +++ b/assets/final/demo_assets.txt @@ -46,4 +46,7 @@ SHADER_MATH_SDF_UTILS, NONE, shaders/math/sdf_utils.wgsl, "SDF Utils Snippet" SHADER_RENDER_SHADOWS, NONE, shaders/render/shadows.wgsl, "Shadows Snippet" SHADER_RENDER_SCENE_QUERY_BVH, NONE, shaders/render/scene_query_bvh.wgsl, "Scene Query Snippet (BVH)" SHADER_RENDER_SCENE_QUERY_LINEAR, NONE, shaders/render/scene_query_linear.wgsl, "Scene Query Snippet (Linear)" -SHADER_RENDER_LIGHTING_UTILS, NONE, shaders/render/lighting_utils.wgsl, "Lighting Utils Snippet"
\ No newline at end of file +SHADER_RENDER_LIGHTING_UTILS, NONE, shaders/render/lighting_utils.wgsl, "Lighting Utils Snippet" +SHADER_MESH, NONE, shaders/mesh_render.wgsl, "Mesh Rasterization Shader" +MESH_CUBE, NONE, test_mesh.obj, "A simple cube mesh" +DODECAHEDRON, NONE, dodecahedron.obj, "A dodecahedron mesh"
\ No newline at end of file diff --git a/assets/final/dodecahedron.obj b/assets/final/dodecahedron.obj new file mode 100644 index 0000000..c3d6c09 --- /dev/null +++ b/assets/final/dodecahedron.obj @@ -0,0 +1,61 @@ +# OBJ file created by ply_to_obj.c +# +g Object001 + +v -0.57735 -0.57735 0.57735 +v 0.934172 0.356822 0 +v 0.934172 -0.356822 0 +v -0.934172 0.356822 0 +v -0.934172 -0.356822 0 +v 0 0.934172 0.356822 +v 0 0.934172 -0.356822 +v 0.356822 0 -0.934172 +v -0.356822 0 -0.934172 +v 0 -0.934172 -0.356822 +v 0 -0.934172 0.356822 +v 0.356822 0 0.934172 +v -0.356822 0 0.934172 +v 0.57735 0.57735 -0.57735 +v 0.57735 0.57735 0.57735 +v -0.57735 0.57735 -0.57735 +v -0.57735 0.57735 0.57735 +v 0.57735 -0.57735 -0.57735 +v 0.57735 -0.57735 0.57735 +v -0.57735 -0.57735 -0.57735 + +f 19 3 2 +f 12 19 2 +f 15 12 2 +f 8 14 2 +f 18 8 2 +f 3 18 2 +f 20 5 4 +f 9 20 4 +f 16 9 4 +f 13 17 4 +f 1 13 4 +f 5 1 4 +f 7 16 4 +f 6 7 4 +f 17 6 4 +f 6 15 2 +f 7 6 2 +f 14 7 2 +f 10 18 3 +f 11 10 3 +f 19 11 3 +f 11 1 5 +f 10 11 5 +f 20 10 5 +f 20 9 8 +f 10 20 8 +f 18 10 8 +f 9 16 7 +f 8 9 7 +f 14 8 7 +f 12 15 6 +f 13 12 6 +f 17 13 6 +f 13 1 11 +f 12 13 11 +f 19 12 11 diff --git a/assets/final/shaders/mesh_render.wgsl b/assets/final/shaders/mesh_render.wgsl new file mode 100644 index 0000000..3faf7ca --- /dev/null +++ b/assets/final/shaders/mesh_render.wgsl @@ -0,0 +1,58 @@ +#include "common_uniforms" + +@group(0) @binding(0) var<uniform> globals: GlobalUniforms; +@group(0) @binding(1) var<storage, read> object_data: ObjectsBuffer; + +// Binding 2 is reserved for BVH (not used here but matches layout for simplicity) + +@group(0) @binding(3) var noise_tex: texture_2d<f32>; +@group(0) @binding(4) var noise_sampler: sampler; +@group(0) @binding(5) var sky_tex: texture_2d<f32>; + +struct VertexInput { + @location(0) position: vec3<f32>, + @location(1) normal: vec3<f32>, + @location(2) uv: vec2<f32>, +}; + +struct VertexOutput { + @builtin(position) clip_pos: vec4<f32>, + @location(0) world_pos: vec3<f32>, + @location(1) normal: vec3<f32>, + @location(2) uv: vec2<f32>, + @location(3) color: vec4<f32>, + @location(4) @interpolate(flat) instance_index: u32, +}; + +@vertex +fn vs_main(in: VertexInput, @builtin(instance_index) instance_index: u32) -> VertexOutput { + let obj = object_data.objects[instance_index]; + let world_pos = obj.model * vec4<f32>(in.position, 1.0); + + var out: VertexOutput; + out.clip_pos = globals.view_proj * world_pos; + out.world_pos = world_pos.xyz; + + // Use transpose of inverse for normals + let normal_matrix = mat3x3<f32>(obj.inv_model[0].xyz, obj.inv_model[1].xyz, obj.inv_model[2].xyz); + out.normal = normalize(transpose(normal_matrix) * in.normal); + + out.uv = in.uv; + out.color = obj.color; + out.instance_index = instance_index; + return out; +} + +#include "render/scene_query_mode" +#include "render/shadows" +#include "render/lighting_utils" + +@fragment +fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> { + let light_dir = normalize(vec3<f32>(1.0, 1.0, 1.0)); + + let shadow = calc_shadow(in.world_pos, light_dir, 0.05, 20.0, in.instance_index); + let lit_color = calculate_lighting(in.color.rgb, in.normal, in.world_pos, shadow); + + return vec4<f32>(lit_color, in.color.a); +}
\ No newline at end of file diff --git a/assets/final/shaders/render/scene_query.wgsl b/assets/final/shaders/render/scene_query.wgsl deleted file mode 100644 index e44b79c..0000000 --- a/assets/final/shaders/render/scene_query.wgsl +++ /dev/null @@ -1,61 +0,0 @@ -#include "math/sdf_shapes" -#include "math/sdf_utils" // For aabb_sdf helper - -fn get_dist(p: vec3<f32>, obj_type: f32) -> f32 { - if (obj_type == 1.0) { return length(p) - 1.0; } // Unit Sphere - if (obj_type == 2.0) { return sdBox(p, vec3<f32>(1.0)); } // Unit Box - if (obj_type == 3.0) { return sdTorus(p, vec2<f32>(1.0, 0.4)); } // Unit Torus - if (obj_type == 4.0) { return sdPlane(p, vec3<f32>(0.0, 1.0, 0.0), 0.0); } - return 100.0; -} - -fn map_scene(p: vec3<f32>, skip_idx: u32) -> f32 { - var d = 1000.0; - let use_bvh = (globals.params.y > 0.5); - - if (use_bvh) { - var stack: array<i32, 32>; - var stack_ptr = 0; - - if (arrayLength(&bvh_nodes) > 0u) { - stack[stack_ptr] = 0; - stack_ptr++; - } - - while (stack_ptr > 0) { - stack_ptr--; - let node_idx = stack[stack_ptr]; - let node = bvh_nodes[node_idx]; - - if (aabb_sdf(p, node.min, node.max) < d) { - if (node.left_idx < 0) { // Leaf - let obj_idx = u32(node.obj_idx_or_right); - if (obj_idx == skip_idx) { continue; } - let obj = object_data.objects[obj_idx]; - let q = (obj.inv_model * vec4<f32>(p, 1.0)).xyz; - let s = min(length(obj.model[0].xyz), min(length(obj.model[1].xyz), length(obj.model[2].xyz))); - d = min(d, get_dist(q, obj.params.x) * s); - } else { // Internal - if (stack_ptr < 31) { - stack[stack_ptr] = node.left_idx; - stack_ptr++; - stack[stack_ptr] = node.obj_idx_or_right; - stack_ptr++; - } - } - } - } - } else { // Fallback to linear scan - let count = u32(globals.params.x); - for (var i = 0u; i < count; i = i + 1u) { - if (i == skip_idx) { continue; } - let obj = object_data.objects[i]; - if (obj.params.x <= 0.0) { continue; } // Skip raster objects - let q = (obj.inv_model * vec4<f32>(p, 1.0)).xyz; - let s = min(length(obj.model[0].xyz), min(length(obj.model[1].xyz), length(obj.model[2].xyz))); - d = min(d, get_dist(q, obj.params.x) * s); - } - } - - return d; -} diff --git a/assets/final/shaders/render/scene_query_bvh.wgsl b/assets/final/shaders/render/scene_query_bvh.wgsl index c7dfdf4..d040c1b 100644 --- a/assets/final/shaders/render/scene_query_bvh.wgsl +++ b/assets/final/shaders/render/scene_query_bvh.wgsl @@ -10,11 +10,13 @@ struct BVHNode { @group(0) @binding(2) var<storage, read> bvh_nodes: array<BVHNode>; -fn get_dist(p: vec3<f32>, obj_type: f32) -> f32 { +fn get_dist(p: vec3<f32>, obj_params: vec4<f32>) -> f32 { + let obj_type = obj_params.x; if (obj_type == 1.0) { return length(p) - 1.0; } // Unit Sphere if (obj_type == 2.0) { return sdBox(p, vec3<f32>(1.0)); } // Unit Box if (obj_type == 3.0) { return sdTorus(p, vec2<f32>(1.0, 0.4)); } // Unit Torus if (obj_type == 4.0) { return sdPlane(p, vec3<f32>(0.0, 1.0, 0.0), 0.0); } + if (obj_type == 5.0) { return sdBox(p, obj_params.yzw); } // MESH AABB return 100.0; } @@ -40,7 +42,14 @@ fn map_scene(p: vec3<f32>, skip_idx: u32) -> f32 { let obj = object_data.objects[obj_idx]; let q = (obj.inv_model * vec4<f32>(p, 1.0)).xyz; let s = min(length(obj.model[0].xyz), min(length(obj.model[1].xyz), length(obj.model[2].xyz))); - d = min(d, get_dist(q, obj.params.x) * s); + // IMPORTANT: Plane (type 4.0) should not be scaled by 's' in this way. + // The sdPlane function expects its own scale/offset implicitly handled by the model matrix. + // The 's' factor is meant for primitives whose SDFs are defined relative to a unit size. + if (obj.params.x != 4.0) { // Only scale if not a plane + d = min(d, get_dist(q, obj.params) * s); + } else { + d = min(d, get_dist(q, obj.params)); + } } else { // Internal if (stack_ptr < 31) { stack[stack_ptr] = node.left_idx; diff --git a/assets/final/shaders/render/scene_query_linear.wgsl b/assets/final/shaders/render/scene_query_linear.wgsl index 7bcd96f..30a0371 100644 --- a/assets/final/shaders/render/scene_query_linear.wgsl +++ b/assets/final/shaders/render/scene_query_linear.wgsl @@ -1,26 +1,64 @@ #include "math/sdf_shapes" +#include "math/sdf_utils" -fn get_dist(p: vec3<f32>, obj_type: f32) -> f32 { +struct BVHNode { + min: vec3<f32>, + left_idx: i32, + max: vec3<f32>, + obj_idx_or_right: i32, +}; + +@group(0) @binding(2) var<storage, read> bvh_nodes: array<BVHNode>; + +fn get_dist(p: vec3<f32>, obj_params: vec4<f32>) -> f32 { + let obj_type = obj_params.x; if (obj_type == 1.0) { return length(p) - 1.0; } // Unit Sphere if (obj_type == 2.0) { return sdBox(p, vec3<f32>(1.0)); } // Unit Box if (obj_type == 3.0) { return sdTorus(p, vec2<f32>(1.0, 0.4)); } // Unit Torus if (obj_type == 4.0) { return sdPlane(p, vec3<f32>(0.0, 1.0, 0.0), 0.0); } + if (obj_type == 5.0) { return sdBox(p, obj_params.yzw); } // MESH AABB return 100.0; } fn map_scene(p: vec3<f32>, skip_idx: u32) -> f32 { var d = 1000.0; - let count = u32(globals.params.x); + var stack: array<i32, 32>; + var stack_ptr = 0; - for (var i = 0u; i < count; i = i + 1u) { - if (i == skip_idx) { continue; } - let obj = object_data.objects[i]; - let obj_type = obj.params.x; - if (obj_type <= 0.0) { continue; } + if (arrayLength(&bvh_nodes) > 0u) { + stack[stack_ptr] = 0; + stack_ptr++; + } - let q = (obj.inv_model * vec4<f32>(p, 1.0)).xyz; - let s = min(length(obj.model[0].xyz), min(length(obj.model[1].xyz), length(obj.model[2].xyz))); - d = min(d, get_dist(q, obj_type) * s); + while (stack_ptr > 0) { + stack_ptr--; + let node_idx = stack[stack_ptr]; + let node = bvh_nodes[node_idx]; + + if (aabb_sdf(p, node.min, node.max) < d) { + if (node.left_idx < 0) { // Leaf + let obj_idx = u32(node.obj_idx_or_right); + if (obj_idx == skip_idx) { continue; } + let obj = object_data.objects[obj_idx]; + let q = (obj.inv_model * vec4<f32>(p, 1.0)).xyz; + let s = min(length(obj.model[0].xyz), min(length(obj.model[1].xyz), length(obj.model[2].xyz))); + // IMPORTANT: Plane (type 4.0) should not be scaled by 's' in this way. + // The sdPlane function expects its own scale/offset implicitly handled by the model matrix. + // The 's' factor is meant for primitives whose SDFs are defined relative to a unit size. + if (obj.params.x != 4.0) { // Only scale if not a plane + d = min(d, get_dist(q, obj.params) * s); + } else { + d = min(d, get_dist(q, obj.params)); + } + } else { // Internal + if (stack_ptr < 31) { + stack[stack_ptr] = node.left_idx; + stack_ptr++; + stack[stack_ptr] = node.obj_idx_or_right; + stack_ptr++; + } + } + } } return d; -} +}
\ No newline at end of file diff --git a/assets/final/shaders/renderer_3d.wgsl b/assets/final/shaders/renderer_3d.wgsl index f855052..4733f6f 100644 --- a/assets/final/shaders/renderer_3d.wgsl +++ b/assets/final/shaders/renderer_3d.wgsl @@ -15,6 +15,7 @@ struct VertexOutput { @location(1) color: vec4<f32>, @location(2) @interpolate(flat) instance_index: u32, @location(3) world_pos: vec3<f32>, + @location(4) transformed_normal: vec3<f32>, }; @vertex @@ -40,6 +41,14 @@ fn vs_main(@builtin(vertex_index) vertex_index: u32, let obj = object_data.objects[instance_index]; let obj_type = obj.params.x; + if (obj_type == 5.0) { // MESH + // For meshes, we use the actual vertex data, not proxy geometry. + // The position here is a placeholder, the real mesh data is handled by mesh_pipeline_. + var out: VertexOutput; + out.position = vec4<f32>(0.0, 0.0, 2.0, 1.0); // Outside far plane, so it's not rendered by this pipeline. + return out; + } + // Tight fit for Torus proxy hull (major radius 1.0, minor 0.4) if (obj_type == 3.0) { p.x = p.x * 1.5; @@ -56,6 +65,22 @@ fn vs_main(@builtin(vertex_index) vertex_index: u32, out.color = obj.color; out.instance_index = instance_index; out.world_pos = world_pos.xyz; + + // Correct normal transformation for meshes: transpose of inverse of model matrix + // For non-uniform scaling, this is necessary. For other primitives, we use their analytical normals. + if (obj_type == 5.0) { + // Calculate inverse transpose of the model matrix (upper 3x3 part) + let model_matrix = mat3x3<f32>(obj.model[0].xyz, obj.model[1].xyz, obj.model[2].xyz); + let normal_matrix = transpose(inverse(model_matrix)); + out.transformed_normal = normalize(normal_matrix * in.normal); + } else { + // For SDF primitives, we don't use vertex normals directly here; they are computed in the fragment shader. + // However, we still need to output a normal for the fragment shader to use if it were a rasterized primitive. + // The transformed_normal is not used by the SDF fragment shader, but for correctness, we'll pass it. + // If this were a rasterized mesh, it would be used. + out.transformed_normal = normalize(vec3<f32>(0.0, 1.0, 0.0)); // Placeholder for non-mesh types + } + return out; } @@ -64,8 +89,13 @@ fn vs_main(@builtin(vertex_index) vertex_index: u32, #include "render/lighting_utils" #include "ray_box" +struct FragmentOutput { + @location(0) color: vec4<f32>, + @builtin(frag_depth) depth: f32, +}; + @fragment -fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> { +fn fs_main(in: VertexOutput) -> FragmentOutput { let obj = object_data.objects[in.instance_index]; let obj_type = obj.params.x; @@ -74,11 +104,10 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> { var base_color = in.color.rgb; let light_dir = normalize(vec3<f32>(1.0, 1.0, 1.0)); - if (obj_type <= 0.0) { // Raster path + if (obj_type <= 0.0) { // Raster path (legacy or generic) p = in.world_pos; - let local_normal = normalize(cross(dpdx(in.local_pos), dpdy(in.local_pos))); - let normal_matrix = mat3x3<f32>(obj.inv_model[0].xyz, obj.inv_model[1].xyz, obj.inv_model[2].xyz); - normal = normalize(transpose(normal_matrix) * local_normal); + // Use the transformed normal passed from the vertex shader for rasterized objects + normal = normalize(in.transformed_normal); // Apply grid pattern to floor let uv = p.xz * 0.5; @@ -94,8 +123,10 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> { let rd_local = normalize((obj.inv_model * vec4<f32>(rd_world, 0.0)).xyz); // Proxy box extent (matches vs_main) + // MESHES use obj.params.yzw for extent var extent = vec3<f32>(1.0); - if (obj_type == 3.0) { extent = vec3<f32>(1.5, 0.5, 1.5); } + if (obj.params.x == 3.0) { extent = vec3<f32>(1.5, 0.5, 1.5); } // Torus + else if (obj.params.x == 5.0) { extent = obj.params.yzw; } // MESH extent let bounds = ray_box_intersection(ro_local, rd_local, extent); @@ -105,7 +136,7 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> { var hit = false; for (var i = 0; i < 64; i = i + 1) { let q = ro_local + rd_local * t; - let d_local = get_dist(q, obj_type); + let d_local = get_dist(q, obj.params); if (d_local < 0.0005) { hit = true; break; } t = t + d_local; if (t > bounds.t_exit) { break; } @@ -122,32 +153,32 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> { let q_x1 = q_hit + e.xyy; let uv_x1 = vec2<f32>(atan2(q_x1.x, q_x1.z) / 6.28 + 0.5, acos(clamp(q_x1.y / length(q_x1), -1.0, 1.0)) / 3.14); let h_x1 = textureSample(noise_tex, noise_sampler, uv_x1).r; - let d_x1 = get_dist(q_x1, obj_type) - disp_strength * h_x1; + let d_x1 = get_dist(q_x1, obj.params) - disp_strength * h_x1; let q_x2 = q_hit - e.xyy; let uv_x2 = vec2<f32>(atan2(q_x2.x, q_x2.z) / 6.28 + 0.5, acos(clamp(q_x2.y / length(q_x2), -1.0, 1.0)) / 3.14); let h_x2 = textureSample(noise_tex, noise_sampler, uv_x2).r; - let d_x2 = get_dist(q_x2, obj_type) - disp_strength * h_x2; + let d_x2 = get_dist(q_x2, obj.params) - disp_strength * h_x2; let q_y1 = q_hit + e.yxy; let uv_y1 = vec2<f32>(atan2(q_y1.x, q_y1.z) / 6.28 + 0.5, acos(clamp(q_y1.y / length(q_y1), -1.0, 1.0)) / 3.14); let h_y1 = textureSample(noise_tex, noise_sampler, uv_y1).r; - let d_y1 = get_dist(q_y1, obj_type) - disp_strength * h_y1; + let d_y1 = get_dist(q_y1, obj.params) - disp_strength * h_y1; let q_y2 = q_hit - e.yxy; let uv_y2 = vec2<f32>(atan2(q_y2.x, q_y2.z) / 6.28 + 0.5, acos(clamp(q_y2.y / length(q_y2), -1.0, 1.0)) / 3.14); let h_y2 = textureSample(noise_tex, noise_sampler, uv_y2).r; - let d_y2 = get_dist(q_y2, obj_type) - disp_strength * h_y2; + let d_y2 = get_dist(q_y2, obj.params) - disp_strength * h_y2; let q_z1 = q_hit + e.yyx; let uv_z1 = vec2<f32>(atan2(q_z1.x, q_z1.z) / 6.28 + 0.5, acos(clamp(q_z1.y / length(q_z1), -1.0, 1.0)) / 3.14); let h_z1 = textureSample(noise_tex, noise_sampler, uv_z1).r; - let d_z1 = get_dist(q_z1, obj_type) - disp_strength * h_z1; + let d_z1 = get_dist(q_z1, obj.params) - disp_strength * h_z1; let q_z2 = q_hit - e.yyx; let uv_z2 = vec2<f32>(atan2(q_z2.x, q_z2.z) / 6.28 + 0.5, acos(clamp(q_z2.y / length(q_z2), -1.0, 1.0)) / 3.14); let h_z2 = textureSample(noise_tex, noise_sampler, uv_z2).r; - let d_z2 = get_dist(q_z2, obj_type) - disp_strength * h_z2; + let d_z2 = get_dist(q_z2, obj.params) - disp_strength * h_z2; let n_local = normalize(vec3<f32>(d_x1 - d_x2, d_y1 - d_y2, d_z1 - d_z2)); let normal_matrix = mat3x3<f32>(obj.inv_model[0].xyz, obj.inv_model[1].xyz, obj.inv_model[2].xyz); @@ -168,5 +199,13 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> { let shadow = calc_shadow(p, light_dir, 0.05, 20.0, in.instance_index); let lit_color = calculate_lighting(base_color, normal, p, shadow); - return vec4<f32>(lit_color, 1.0); + + var out: FragmentOutput; + out.color = vec4<f32>(lit_color, 1.0); + + // Calculate and write correct depth + let clip_pos = globals.view_proj * vec4<f32>(p, 1.0); + out.depth = clip_pos.z / clip_pos.w; + + return out; }
\ No newline at end of file diff --git a/assets/final/test_assets_list.txt b/assets/final/test_assets_list.txt index c9dd83b..7cded99 100644 --- a/assets/final/test_assets_list.txt +++ b/assets/final/test_assets_list.txt @@ -5,5 +5,19 @@ SHADER_SNIPPET_A, NONE, shaders/test_snippet_a.wgsl, "Test snippet A" SHADER_SNIPPET_B, NONE, shaders/test_snippet_b.wgsl, "Test snippet B" PROC_NOISE_256, PROC(gen_noise, 4321, 8), _, "Procedural noise for testing" TEST_IMAGE, NONE, test_image.tga, "A test TGA image" +TEST_MESH, NONE, test_mesh.obj, "A simple test cube mesh" PROC_UNKNOWN, PROC(gen_unknown_func, 0), _, "Unknown proc function" PROC_FAIL, PROC(gen_noise, -1337, 8), _, "Failing proc function" + +# --- Required Shaders for Renderer3D --- +SHADER_MESH, NONE, shaders/mesh_render.wgsl, "Mesh Rasterization Shader" +SHADER_RENDERER_3D, NONE, shaders/renderer_3d.wgsl, "Hybrid 3D Renderer Shader" +SHADER_SKYBOX, NONE, shaders/skybox.wgsl, "Skybox background shader" +SHADER_COMMON_UNIFORMS, NONE, shaders/common_uniforms.wgsl, "Common Uniforms Snippet" +SHADER_MATH_SDF_SHAPES, NONE, shaders/math/sdf_shapes.wgsl, "SDF Shapes Snippet" +SHADER_MATH_SDF_UTILS, NONE, shaders/math/sdf_utils.wgsl, "SDF Utils Snippet" +SHADER_RENDER_SHADOWS, NONE, shaders/render/shadows.wgsl, "Shadows Snippet" +SHADER_RENDER_SCENE_QUERY_BVH, NONE, shaders/render/scene_query_bvh.wgsl, "Scene Query Snippet (BVH)" +SHADER_RENDER_SCENE_QUERY_LINEAR, NONE, shaders/render/scene_query_linear.wgsl, "Scene Query Snippet (Linear)" +SHADER_RENDER_LIGHTING_UTILS, NONE, shaders/render/lighting_utils.wgsl, "Lighting Utils Snippet" +SHADER_RAY_BOX, NONE, shaders/ray_box.wgsl, "Ray-Box Intersection Snippet"
\ No newline at end of file diff --git a/assets/final/test_mesh.obj b/assets/final/test_mesh.obj new file mode 100644 index 0000000..eb304d4 --- /dev/null +++ b/assets/final/test_mesh.obj @@ -0,0 +1,30 @@ +v -0.5 -0.5 0.5 +v 0.5 -0.5 0.5 +v 0.5 0.5 0.5 +v -0.5 0.5 0.5 +v -0.5 -0.5 -0.5 +v 0.5 -0.5 -0.5 +v 0.5 0.5 -0.5 +v -0.5 0.5 -0.5 +vn 0.0 0.0 1.0 +vn 0.0 0.0 -1.0 +vn 0.0 1.0 0.0 +vn 0.0 -1.0 0.0 +vn 1.0 0.0 0.0 +vn -1.0 0.0 0.0 +vt 0.0 0.0 +vt 1.0 0.0 +vt 1.0 1.0 +vt 0.0 1.0 +f 1/1/1 2/2/1 3/3/1 +f 1/1/1 3/3/1 4/4/1 +f 5/1/2 8/4/2 7/3/2 +f 5/1/2 7/3/2 6/2/2 +f 1/1/6 4/4/6 8/3/6 +f 1/1/6 8/3/6 5/2/6 +f 2/1/5 6/4/5 7/3/5 +f 2/1/5 7/3/5 3/2/5 +f 4/1/3 3/4/3 7/3/3 +f 4/1/3 7/3/3 8/2/3 +f 1/1/4 5/4/4 6/3/4 +f 1/1/4 6/3/4 2/2/4 @@ -153,15 +153,26 @@ Instead of full SDF-on-SDF intersection (which is expensive), we approximate dyn * **Normal**: Compute gradient $N = \nabla SDF_B(P_{local})$ via central differences. Transform $N$ back to world space. * **Contact Point**: $P_{contact} = P_{world} - N * p$. -### Solver Loop (Semi-Implicit Euler) -1. **Integrate Velocity**: `vel += gravity * dt`. +### Narrow Phase & Resolution: +* If collision detected (depth $p > 0$): + * **Positional Correction**: Move object by $N * p$ (to resolve penetration). + * **Velocity Response (PBD)**: In Position Based Dynamics (PBD), the velocity is re-evaluated *after* all collisions and constraints have been resolved: `v = (p_new - p_old) / dt`. + * **Friction**: Apply tangential damping. + +### Rotation & Angular Momentum +Objects should support rotation via **Quaternions**. +* **State**: Add `quat orientation` and `vec3 angular_velocity` to `Object3D`. +* **Integration**: Update orientation using angular velocity: `q = q + 0.5 * dt * [0, w] * q`, then normalize. +* **Narrow Phase**: Proxy points must be rotated by the quaternion: `P_local = Inverse(Q) * (P_world - Position)`. +* **Collision Response**: Collision impulses should affect both linear and angular momentum. + +### Solver Loop (Position Based Dynamics) +1. **Integrate Position (Predicted)**: `p_pred = p + v * dt`. 2. **Broad Phase**: Find pairs using BVH. 3. **Narrow Phase & Resolution**: - * If collision detected (depth $p > 0$): - * **Positional Correction**: Move object by $N * p$ (to resolve penetration). - * **Velocity Response**: `vel = vel - (1 + restitution) * dot(vel, N) * N`. - * **Friction**: Apply tangential damping. -4. **Integrate Position**: `pos += vel * dt`. + * Resolve penetrations and constraints on `p_pred`. +4. **Update Velocity**: `v = (p_pred - p) / dt`. +5. **Finalize Position**: `p = p_pred`. ### Code Integration Plan @@ -183,4 +194,4 @@ our AssetManager or as c++ code directly) - **Task #36: Blender Exporter**. ## latter improvement How to handle transparency? Multi-Ray-casting? -We need to think about the lighting strategy. - **Task #40: Advanced Lighting & Transparency**. +We need to think about the lighting strategy. - **Task #40: Advanced Lighting & Transparency**.
\ No newline at end of file diff --git a/doc/CONTRIBUTING.md b/doc/CONTRIBUTING.md index 27391e4..4b85e9f 100644 --- a/doc/CONTRIBUTING.md +++ b/doc/CONTRIBUTING.md @@ -238,6 +238,10 @@ Make sure the `.field = ...,` initialization pattern is compatible with the comp keep the code compact vertically. That includes shader code, too. Use only one statement per line. +### File size limit + +Any file larger than 500 lines should ideally be split into sub-functionalities in separate files. (Exceptions: platform code or generated files). + ### finally Make sure everything is reflected in clang-format. diff --git a/src/3d/object.h b/src/3d/object.h index 6d21393..3d4ff35 100644 --- a/src/3d/object.h +++ b/src/3d/object.h @@ -5,6 +5,7 @@ #pragma once #include "util/mini_math.h" +#include "util/asset_manager.h" enum class ObjectType { CUBE, @@ -12,7 +13,8 @@ enum class ObjectType { PLANE, TORUS, BOX, - SKYBOX + SKYBOX, + MESH // Add more SDF types here }; @@ -37,10 +39,15 @@ class Object3D { float restitution; bool is_static; + AssetId mesh_asset_id; + vec3 local_extent; // Half-extents for AABB (used by meshes for shadows) + void* user_data; // For tool-specific data, not for general use + Object3D(ObjectType t = ObjectType::CUBE) : position(0, 0, 0), rotation(0, 0, 0, 1), scale(1, 1, 1), type(t), color(1, 1, 1, 1), velocity(0, 0, 0), mass(1.0f), restitution(0.5f), - is_static(false) { + is_static(false), mesh_asset_id((AssetId)0), local_extent(1, 1, 1), + user_data(nullptr) { } mat4 get_model_matrix() const { @@ -56,7 +63,9 @@ class Object3D { BoundingVolume get_local_bounds() const { if (type == ObjectType::TORUS) return {{-1.5f, -0.5f, -1.5f}, {1.5f, 0.5f, 1.5f}}; + if (type == ObjectType::MESH) + return {-local_extent, local_extent}; // Simple defaults for unit primitives return {{-1, -1, -1}, {1, 1, 1}}; } -}; +};
\ No newline at end of file diff --git a/src/3d/renderer.cc b/src/3d/renderer.cc index 9dfc1f8..eea3ff0 100644 --- a/src/3d/renderer.cc +++ b/src/3d/renderer.cc @@ -1,5 +1,5 @@ // This file is part of the 64k demo project. -// It implements the Renderer3D class. +// It implements the core Renderer3D class logic. #include "3d/renderer.h" #include "generated/assets.h" @@ -37,93 +37,6 @@ void Renderer3D::init(WGPUDevice device, WGPUQueue queue, #endif } -void Renderer3D::create_skybox_pipeline() { - WGPUBindGroupLayoutEntry entries[3] = {}; - entries[0].binding = 0; - entries[0].visibility = WGPUShaderStage_Fragment; - entries[0].texture.sampleType = WGPUTextureSampleType_Float; - entries[0].texture.viewDimension = WGPUTextureViewDimension_2D; - - entries[1].binding = 1; - entries[1].visibility = WGPUShaderStage_Fragment; - entries[1].sampler.type = WGPUSamplerBindingType_Filtering; - - entries[2].binding = 2; - entries[2].visibility = WGPUShaderStage_Fragment; - entries[2].buffer.type = WGPUBufferBindingType_Uniform; - entries[2].buffer.minBindingSize = sizeof(GlobalUniforms); - - WGPUBindGroupLayoutDescriptor bgl_desc = {}; - bgl_desc.entryCount = 3; - bgl_desc.entries = entries; - WGPUBindGroupLayout bgl = wgpuDeviceCreateBindGroupLayout(device_, &bgl_desc); - - WGPUPipelineLayoutDescriptor pl_desc = {}; - pl_desc.bindGroupLayoutCount = 1; - pl_desc.bindGroupLayouts = &bgl; - WGPUPipelineLayout pipeline_layout = - wgpuDeviceCreatePipelineLayout(device_, &pl_desc); - - const uint8_t* shader_code_asset = - GetAsset(AssetId::ASSET_SHADER_SKYBOX, nullptr); - std::string shader_source = - ShaderComposer::Get().Compose({}, (const char*)shader_code_asset); - -#if defined(DEMO_CROSS_COMPILE_WIN32) - WGPUShaderModuleWGSLDescriptor wgsl_desc = {}; - wgsl_desc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor; - wgsl_desc.code = shader_source.c_str(); - WGPUShaderModuleDescriptor shader_desc = {}; - shader_desc.nextInChain = (const WGPUChainedStruct*)&wgsl_desc.chain; -#else - WGPUShaderSourceWGSL wgsl_desc = {}; - wgsl_desc.chain.sType = WGPUSType_ShaderSourceWGSL; - wgsl_desc.code = str_view(shader_source.c_str()); - WGPUShaderModuleDescriptor shader_desc = {}; - shader_desc.nextInChain = (const WGPUChainedStruct*)&wgsl_desc.chain; -#endif - WGPUShaderModule shader_module = - wgpuDeviceCreateShaderModule(device_, &shader_desc); - - WGPURenderPipelineDescriptor desc = {}; - desc.layout = pipeline_layout; - desc.vertex.module = shader_module; -#if defined(DEMO_CROSS_COMPILE_WIN32) - desc.vertex.entryPoint = "vs_main"; -#else - desc.vertex.entryPoint = {"vs_main", 7}; -#endif - WGPUColorTargetState color_target = {}; - color_target.format = format_; - color_target.writeMask = WGPUColorWriteMask_All; - WGPUFragmentState fragment = {}; - fragment.module = shader_module; -#if defined(DEMO_CROSS_COMPILE_WIN32) - fragment.entryPoint = "fs_main"; -#else - fragment.entryPoint = {"fs_main", 7}; -#endif - fragment.targetCount = 1; - fragment.targets = &color_target; - desc.fragment = &fragment; - desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; - desc.primitive.cullMode = WGPUCullMode_Back; - desc.primitive.frontFace = WGPUFrontFace_CCW; - desc.multisample.count = 1; - desc.multisample.mask = 0xFFFFFFFF; - - WGPUDepthStencilState depth_stencil = {}; - depth_stencil.format = WGPUTextureFormat_Depth24Plus; - depth_stencil.depthWriteEnabled = WGPUOptionalBool_False; - depth_stencil.depthCompare = WGPUCompareFunction_Always; - desc.depthStencil = &depth_stencil; - - skybox_pipeline_ = wgpuDeviceCreateRenderPipeline(device_, &desc); - wgpuBindGroupLayoutRelease(bgl); - wgpuPipelineLayoutRelease(pipeline_layout); - wgpuShaderModuleRelease(shader_module); -} - void Renderer3D::shutdown() { #if !defined(STRIP_ALL) visual_debug_.shutdown(); @@ -137,6 +50,8 @@ void Renderer3D::shutdown() { wgpuRenderPipelineRelease(pipeline_no_bvh_); if (bind_group_) wgpuBindGroupRelease(bind_group_); + if (mesh_pipeline_) + wgpuRenderPipelineRelease(mesh_pipeline_); if (skybox_pipeline_) wgpuRenderPipelineRelease(skybox_pipeline_); if (skybox_bind_group_) @@ -151,6 +66,15 @@ void Renderer3D::shutdown() { wgpuTextureViewRelease(depth_view_); if (depth_texture_) wgpuTextureRelease(depth_texture_); + + // Clear mesh cache + for (auto& pair : mesh_cache_) { + if (pair.second.vertex_buffer) + wgpuBufferRelease(pair.second.vertex_buffer); + if (pair.second.index_buffer) + wgpuBufferRelease(pair.second.index_buffer); + } + mesh_cache_.clear(); } void Renderer3D::resize(int width, int height) { @@ -214,157 +138,6 @@ void Renderer3D::add_debug_aabb(const vec3& min, const vec3& max, #endif } -void Renderer3D::create_pipeline() { - pipeline_ = create_pipeline_impl(true); // BVH enabled - pipeline_no_bvh_ = create_pipeline_impl(false); // BVH disabled -} - -WGPURenderPipeline Renderer3D::create_pipeline_impl(bool use_bvh) { - std::vector<WGPUBindGroupLayoutEntry> entries; - - // Binding 0: Global Uniforms - { - WGPUBindGroupLayoutEntry e = {}; - e.binding = 0; - e.visibility = WGPUShaderStage_Vertex | WGPUShaderStage_Fragment; - e.buffer.type = WGPUBufferBindingType_Uniform; - e.buffer.minBindingSize = sizeof(GlobalUniforms); - entries.push_back(e); - } - - // Binding 1: Object Data - { - WGPUBindGroupLayoutEntry e = {}; - e.binding = 1; - e.visibility = WGPUShaderStage_Vertex | WGPUShaderStage_Fragment; - e.buffer.type = WGPUBufferBindingType_ReadOnlyStorage; - e.buffer.minBindingSize = sizeof(ObjectData) * kMaxObjects; - entries.push_back(e); - } - - // Binding 2: BVH Nodes (only if BVH is used) - if (use_bvh) { - WGPUBindGroupLayoutEntry e = {}; - e.binding = 2; - e.visibility = WGPUShaderStage_Fragment; - e.buffer.type = WGPUBufferBindingType_ReadOnlyStorage; - e.buffer.minBindingSize = sizeof(BVHNode) * kMaxObjects * 2; - entries.push_back(e); - } - - // Binding 3: Noise Texture - { - WGPUBindGroupLayoutEntry e = {}; - e.binding = 3; - e.visibility = WGPUShaderStage_Fragment; - e.texture.sampleType = WGPUTextureSampleType_Float; - e.texture.viewDimension = WGPUTextureViewDimension_2D; - entries.push_back(e); - } - - // Binding 4: Default Sampler - { - WGPUBindGroupLayoutEntry e = {}; - e.binding = 4; - e.visibility = WGPUShaderStage_Fragment; - e.sampler.type = WGPUSamplerBindingType_Filtering; - entries.push_back(e); - } - - // Binding 5: Sky Texture - { - WGPUBindGroupLayoutEntry e = {}; - e.binding = 5; - e.visibility = WGPUShaderStage_Fragment; - e.texture.sampleType = WGPUTextureSampleType_Float; - e.texture.viewDimension = WGPUTextureViewDimension_2D; - entries.push_back(e); - } - - WGPUBindGroupLayoutDescriptor bgl_desc = {}; - bgl_desc.entryCount = (uint32_t)entries.size(); - bgl_desc.entries = entries.data(); - WGPUBindGroupLayout bgl = wgpuDeviceCreateBindGroupLayout(device_, &bgl_desc); - - WGPUPipelineLayoutDescriptor pl_desc = {}; - pl_desc.bindGroupLayoutCount = 1; - pl_desc.bindGroupLayouts = &bgl; - WGPUPipelineLayout pipeline_layout = - wgpuDeviceCreatePipelineLayout(device_, &pl_desc); - - const char* asset_data = - (const char*)GetAsset(AssetId::ASSET_SHADER_RENDERER_3D); - std::string main_code = asset_data; - - // Use ShaderComposer to dynamically include the correct scene_query snippet - ShaderComposer::CompositionMap composition_map; - if (use_bvh) { - composition_map["render/scene_query_mode"] = "render/scene_query_bvh"; - } else { - composition_map["render/scene_query_mode"] = "render/scene_query_linear"; - } - std::string shader_source = ShaderComposer::Get().Compose({}, main_code, composition_map); - - // DEBUG: Print shader source to check for include errors - std::cout << "Shader Source (BVH=" << use_bvh << "):" << std::endl << shader_source << std::endl; - -#if defined(DEMO_CROSS_COMPILE_WIN32) - WGPUShaderModuleWGSLDescriptor wgsl_desc = {}; - wgsl_desc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor; - wgsl_desc.code = shader_source.c_str(); - WGPUShaderModuleDescriptor shader_desc = {}; - shader_desc.nextInChain = (const WGPUChainedStruct*)&wgsl_desc.chain; -#else - WGPUShaderSourceWGSL wgsl_desc = {}; - wgsl_desc.chain.sType = WGPUSType_ShaderSourceWGSL; - wgsl_desc.code = str_view(shader_source.c_str()); - WGPUShaderModuleDescriptor shader_desc = {}; - shader_desc.nextInChain = (const WGPUChainedStruct*)&wgsl_desc.chain; -#endif - WGPUShaderModule shader_module = - wgpuDeviceCreateShaderModule(device_, &shader_desc); - - WGPUDepthStencilState depth_stencil = {}; - depth_stencil.format = WGPUTextureFormat_Depth24Plus; - depth_stencil.depthWriteEnabled = WGPUOptionalBool_True; - depth_stencil.depthCompare = WGPUCompareFunction_Less; - - WGPURenderPipelineDescriptor desc = {}; - desc.layout = pipeline_layout; - desc.vertex.module = shader_module; -#if defined(DEMO_CROSS_COMPILE_WIN32) - desc.vertex.entryPoint = "vs_main"; -#else - desc.vertex.entryPoint = {"vs_main", 7}; -#endif - WGPUColorTargetState color_target = {}; - color_target.format = format_; - color_target.writeMask = WGPUColorWriteMask_All; - WGPUFragmentState fragment = {}; - fragment.module = shader_module; -#if defined(DEMO_CROSS_COMPILE_WIN32) - fragment.entryPoint = "fs_main"; -#else - fragment.entryPoint = {"fs_main", 7}; -#endif - fragment.targetCount = 1; - fragment.targets = &color_target; - desc.fragment = &fragment; - desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; - desc.primitive.cullMode = WGPUCullMode_Back; - desc.primitive.frontFace = WGPUFrontFace_CCW; - desc.depthStencil = &depth_stencil; - desc.multisample.count = 1; - desc.multisample.mask = 0xFFFFFFFF; - - WGPURenderPipeline pipeline = wgpuDeviceCreateRenderPipeline(device_, &desc); - wgpuBindGroupLayoutRelease(bgl); - wgpuPipelineLayoutRelease(pipeline_layout); - wgpuShaderModuleRelease(shader_module); - - return pipeline; -} - void Renderer3D::update_uniforms(const Scene& scene, const Camera& camera, float time) { GlobalUniforms globals; @@ -399,7 +172,9 @@ void Renderer3D::update_uniforms(const Scene& scene, const Camera& camera, type_id = 3.0f; else if (obj.type == ObjectType::PLANE) type_id = 4.0f; - data.params = vec4(type_id, 0, 0, 0); + else if (obj.type == ObjectType::MESH) + type_id = 5.0f; + data.params = vec4(type_id, obj.local_extent.x, obj.local_extent.y, obj.local_extent.z); obj_data.push_back(data); if (obj_data.size() >= kMaxObjects) break; @@ -497,15 +272,42 @@ void Renderer3D::draw(WGPURenderPassEncoder pass, const Scene& scene, (uint32_t)std::min((size_t)kMaxObjects, scene.objects.size()); if (instance_count > 0) { + wgpuRenderPassEncoderSetPipeline(pass, current_pipeline); + wgpuRenderPassEncoderSetBindGroup(pass, 0, bind_group_, 0, nullptr); wgpuRenderPassEncoderDraw(pass, 36, instance_count, 0, 0); + + // Mesh pass + if (mesh_pipeline_) { + wgpuRenderPassEncoderSetPipeline(pass, mesh_pipeline_); + // Bind group is the same layout + wgpuRenderPassEncoderSetBindGroup(pass, 0, bind_group_, 0, nullptr); + + for (uint32_t i = 0; i < instance_count; ++i) { + const auto& obj = scene.objects[i]; + if (obj.type == ObjectType::MESH) { + const MeshGpuData* mesh = temp_mesh_override_ ? temp_mesh_override_ : get_or_create_mesh(obj.mesh_asset_id); + if (mesh) { + wgpuRenderPassEncoderSetVertexBuffer(pass, 0, mesh->vertex_buffer, 0, + WGPU_WHOLE_SIZE); + wgpuRenderPassEncoderSetIndexBuffer( + pass, mesh->index_buffer, WGPUIndexFormat_Uint32, 0, + WGPU_WHOLE_SIZE); + wgpuRenderPassEncoderDrawIndexed(pass, mesh->num_indices, 1, 0, 0, + i); + } + } + } + } } #if !defined(STRIP_ALL) if (s_debug_enabled_) { for (const auto& obj : scene.objects) { - vec3 extent(1.0f, 1.0f, 1.0f); + vec3 extent = obj.local_extent; if (obj.type == ObjectType::TORUS) { extent = vec3(1.5f, 0.5f, 1.5f); + } else if (obj.type != ObjectType::MESH) { + extent = vec3(1.0f, 1.0f, 1.0f); } visual_debug_.add_box(obj.get_model_matrix(), extent, vec3(1.0f, 1.0f, 0.0f)); // Yellow boxes @@ -620,4 +422,4 @@ void Renderer3D::render(const Scene& scene, const Camera& camera, float time, wgpuCommandBufferRelease(commands); wgpuCommandEncoderRelease(encoder); -} +}
\ No newline at end of file diff --git a/src/3d/renderer.h b/src/3d/renderer.h index db86b72..5c9fd38 100644 --- a/src/3d/renderer.h +++ b/src/3d/renderer.h @@ -8,6 +8,7 @@ #include "3d/scene.h" #include "3d/bvh.h" #include "gpu/gpu.h" +#include <map> #include <vector> #if !defined(STRIP_ALL) @@ -64,12 +65,30 @@ class Renderer3D { // Set whether to use BVH acceleration void SetBvhEnabled(bool enabled) { bvh_enabled_ = enabled; } + struct MeshGpuData { + WGPUBuffer vertex_buffer; + WGPUBuffer index_buffer; + uint32_t num_indices; + }; + + // HACK for test_mesh tool + void override_mesh_buffers(const MeshGpuData* data) { + temp_mesh_override_ = data; + } + +#if !defined(STRIP_ALL) + VisualDebug& GetVisualDebug() { return visual_debug_; } +#endif + private: + void create_pipeline(); WGPURenderPipeline create_pipeline_impl(bool use_bvh); + void create_mesh_pipeline(); void create_skybox_pipeline(); void create_default_resources(); void update_uniforms(const Scene& scene, const Camera& camera, float time); + const MeshGpuData* get_or_create_mesh(AssetId asset_id); WGPUDevice device_ = nullptr; WGPUQueue queue_ = nullptr; @@ -78,6 +97,7 @@ class Renderer3D { WGPURenderPipeline pipeline_ = nullptr; // BVH enabled WGPURenderPipeline pipeline_no_bvh_ = nullptr; // BVH disabled WGPUBindGroup bind_group_ = nullptr; + WGPURenderPipeline mesh_pipeline_ = nullptr; WGPURenderPipeline skybox_pipeline_ = nullptr; WGPUBindGroup skybox_bind_group_ = nullptr; WGPUBuffer global_uniform_buffer_ = nullptr; @@ -87,6 +107,9 @@ class Renderer3D { BVH cpu_bvh_; // Keep a CPU-side copy for building/uploading bool bvh_enabled_ = true; + std::map<AssetId, MeshGpuData> mesh_cache_; + const MeshGpuData* temp_mesh_override_ = nullptr; // HACK for test_mesh tool + WGPUTextureView noise_texture_view_ = nullptr; WGPUTextureView sky_texture_view_ = nullptr; WGPUSampler default_sampler_ = nullptr; diff --git a/src/3d/renderer_mesh.cc b/src/3d/renderer_mesh.cc new file mode 100644 index 0000000..97b91d3 --- /dev/null +++ b/src/3d/renderer_mesh.cc @@ -0,0 +1,202 @@ +// This file is part of the 64k demo project. +// It implements mesh-related logic for Renderer3D. + +#include "3d/renderer.h" +#include "generated/assets.h" +#include "gpu/effects/shader_composer.h" +#include "util/asset_manager.h" +#include <cstring> +#include <vector> + +void Renderer3D::create_mesh_pipeline() { + std::vector<WGPUBindGroupLayoutEntry> entries; + + // Binding 0: Global Uniforms + { + WGPUBindGroupLayoutEntry e = {}; + e.binding = 0; + e.visibility = WGPUShaderStage_Vertex | WGPUShaderStage_Fragment; + e.buffer.type = WGPUBufferBindingType_Uniform; + e.buffer.minBindingSize = sizeof(GlobalUniforms); + entries.push_back(e); + } + + // Binding 1: Object Data + { + WGPUBindGroupLayoutEntry e = {}; + e.binding = 1; + e.visibility = WGPUShaderStage_Vertex | WGPUShaderStage_Fragment; + e.buffer.type = WGPUBufferBindingType_ReadOnlyStorage; + e.buffer.minBindingSize = sizeof(ObjectData) * kMaxObjects; + entries.push_back(e); + } + + // Binding 2: BVH Nodes (Optional) + if (bvh_enabled_) { + WGPUBindGroupLayoutEntry e = {}; + e.binding = 2; + e.visibility = WGPUShaderStage_Fragment; + e.buffer.type = WGPUBufferBindingType_ReadOnlyStorage; + e.buffer.minBindingSize = sizeof(BVHNode) * kMaxObjects * 2; + entries.push_back(e); + } + + // Binding 3: Noise Texture + { + WGPUBindGroupLayoutEntry e = {}; + e.binding = 3; + e.visibility = WGPUShaderStage_Fragment; + e.texture.sampleType = WGPUTextureSampleType_Float; + e.texture.viewDimension = WGPUTextureViewDimension_2D; + entries.push_back(e); + } + + // Binding 4: Default Sampler + { + WGPUBindGroupLayoutEntry e = {}; + e.binding = 4; + e.visibility = WGPUShaderStage_Fragment; + e.sampler.type = WGPUSamplerBindingType_Filtering; + entries.push_back(e); + } + + // Binding 5: Sky Texture + { + WGPUBindGroupLayoutEntry e = {}; + e.binding = 5; + e.visibility = WGPUShaderStage_Fragment; + e.texture.sampleType = WGPUTextureSampleType_Float; + e.texture.viewDimension = WGPUTextureViewDimension_2D; + entries.push_back(e); + } + + WGPUBindGroupLayoutDescriptor bgl_desc = {}; + bgl_desc.entryCount = (uint32_t)entries.size(); + bgl_desc.entries = entries.data(); + WGPUBindGroupLayout bgl = wgpuDeviceCreateBindGroupLayout(device_, &bgl_desc); + + WGPUPipelineLayoutDescriptor pl_desc = {}; + pl_desc.bindGroupLayoutCount = 1; + pl_desc.bindGroupLayouts = &bgl; + WGPUPipelineLayout pipeline_layout = + wgpuDeviceCreatePipelineLayout(device_, &pl_desc); + + const char* shader_code_asset = (const char*)GetAsset(AssetId::ASSET_SHADER_MESH); + + ShaderComposer::CompositionMap composition_map; + if (bvh_enabled_) { + composition_map["render/scene_query_mode"] = "render/scene_query_bvh"; + } else { + composition_map["render/scene_query_mode"] = "render/scene_query_linear"; + } + std::string shader_source = ShaderComposer::Get().Compose({}, shader_code_asset, composition_map); + +#if defined(DEMO_CROSS_COMPILE_WIN32) + WGPUShaderModuleWGSLDescriptor wgsl_desc = {}; + wgsl_desc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor; + wgsl_desc.code = shader_source.c_str(); + WGPUShaderModuleDescriptor shader_desc = {}; + shader_desc.nextInChain = (const WGPUChainedStruct*)&wgsl_desc.chain; +#else + WGPUShaderSourceWGSL wgsl_desc = {}; + wgsl_desc.chain.sType = WGPUSType_ShaderSourceWGSL; + wgsl_desc.code = str_view(shader_source.c_str()); + WGPUShaderModuleDescriptor shader_desc = {}; + shader_desc.nextInChain = (const WGPUChainedStruct*)&wgsl_desc.chain; +#endif + WGPUShaderModule shader_module = + wgpuDeviceCreateShaderModule(device_, &shader_desc); + + WGPUVertexAttribute vert_attrs[3] = {}; + // pos + vert_attrs[0].format = WGPUVertexFormat_Float32x3; + vert_attrs[0].offset = offsetof(MeshVertex, p); + vert_attrs[0].shaderLocation = 0; + // norm + vert_attrs[1].format = WGPUVertexFormat_Float32x3; + vert_attrs[1].offset = offsetof(MeshVertex, n); + vert_attrs[1].shaderLocation = 1; + // uv + vert_attrs[2].format = WGPUVertexFormat_Float32x2; + vert_attrs[2].offset = offsetof(MeshVertex, u); + vert_attrs[2].shaderLocation = 2; + + WGPUVertexBufferLayout vert_layout = {}; + vert_layout.arrayStride = sizeof(MeshVertex); + vert_layout.stepMode = WGPUVertexStepMode_Vertex; + vert_layout.attributeCount = 3; + vert_layout.attributes = vert_attrs; + + WGPURenderPipelineDescriptor desc = {}; + desc.layout = pipeline_layout; + desc.vertex.module = shader_module; +#if defined(DEMO_CROSS_COMPILE_WIN32) + desc.vertex.entryPoint = "vs_main"; +#else + desc.vertex.entryPoint = {"vs_main", 7}; +#endif + desc.vertex.bufferCount = 1; + desc.vertex.buffers = &vert_layout; + + WGPUColorTargetState color_target = {}; + color_target.format = format_; + color_target.writeMask = WGPUColorWriteMask_All; + WGPUFragmentState fragment = {}; + fragment.module = shader_module; +#if defined(DEMO_CROSS_COMPILE_WIN32) + fragment.entryPoint = "fs_main"; +#else + fragment.entryPoint = {"fs_main", 7}; +#endif + fragment.targetCount = 1; + fragment.targets = &color_target; + desc.fragment = &fragment; + + desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; + desc.primitive.cullMode = WGPUCullMode_Back; + desc.primitive.frontFace = WGPUFrontFace_CCW; + + WGPUDepthStencilState depth_stencil = {}; + depth_stencil.format = WGPUTextureFormat_Depth24Plus; + depth_stencil.depthWriteEnabled = WGPUOptionalBool_True; + depth_stencil.depthCompare = WGPUCompareFunction_Less; + desc.depthStencil = &depth_stencil; + + desc.multisample.count = 1; + desc.multisample.mask = 0xFFFFFFFF; + + mesh_pipeline_ = wgpuDeviceCreateRenderPipeline(device_, &desc); + wgpuBindGroupLayoutRelease(bgl); + wgpuPipelineLayoutRelease(pipeline_layout); + wgpuShaderModuleRelease(shader_module); +} + +const Renderer3D::MeshGpuData* +Renderer3D::get_or_create_mesh(AssetId asset_id) { + auto it = mesh_cache_.find(asset_id); + if (it != mesh_cache_.end()) { + return &it->second; + } + + MeshAsset asset = GetMeshAsset(asset_id); + if (!asset.vertices || asset.num_vertices == 0) { + return nullptr; + } + + MeshGpuData data; + data.num_indices = asset.num_indices; + + data.vertex_buffer = + gpu_create_buffer(device_, asset.num_vertices * sizeof(MeshVertex), + WGPUBufferUsage_Vertex | WGPUBufferUsage_CopyDst, + asset.vertices) + .buffer; + data.index_buffer = + gpu_create_buffer(device_, asset.num_indices * sizeof(uint32_t), + WGPUBufferUsage_Index | WGPUBufferUsage_CopyDst, + asset.indices) + .buffer; + + mesh_cache_[asset_id] = data; + return &mesh_cache_[asset_id]; +} diff --git a/src/3d/renderer_sdf.cc b/src/3d/renderer_sdf.cc new file mode 100644 index 0000000..d94df11 --- /dev/null +++ b/src/3d/renderer_sdf.cc @@ -0,0 +1,158 @@ +// This file is part of the 64k demo project. +// It implements SDF-related pipeline logic for Renderer3D. + +#include "3d/renderer.h" +#include "generated/assets.h" +#include "gpu/effects/shader_composer.h" +#include "util/asset_manager.h" +#include <vector> + +void Renderer3D::create_pipeline() { + pipeline_ = create_pipeline_impl(true); // BVH enabled + pipeline_no_bvh_ = create_pipeline_impl(false); // BVH disabled + create_mesh_pipeline(); +} + +WGPURenderPipeline Renderer3D::create_pipeline_impl(bool use_bvh) { + std::vector<WGPUBindGroupLayoutEntry> entries; + + // Binding 0: Global Uniforms + { + WGPUBindGroupLayoutEntry e = {}; + e.binding = 0; + e.visibility = WGPUShaderStage_Vertex | WGPUShaderStage_Fragment; + e.buffer.type = WGPUBufferBindingType_Uniform; + e.buffer.minBindingSize = sizeof(GlobalUniforms); + entries.push_back(e); + } + + // Binding 1: Object Data + { + WGPUBindGroupLayoutEntry e = {}; + e.binding = 1; + e.visibility = WGPUShaderStage_Vertex | WGPUShaderStage_Fragment; + e.buffer.type = WGPUBufferBindingType_ReadOnlyStorage; + e.buffer.minBindingSize = sizeof(ObjectData) * kMaxObjects; + entries.push_back(e); + } + + // Binding 2: BVH Nodes (only if BVH is used) + if (use_bvh) { + WGPUBindGroupLayoutEntry e = {}; + e.binding = 2; + e.visibility = WGPUShaderStage_Fragment; + e.buffer.type = WGPUBufferBindingType_ReadOnlyStorage; + e.buffer.minBindingSize = sizeof(BVHNode) * kMaxObjects * 2; + entries.push_back(e); + } + + // Binding 3: Noise Texture + { + WGPUBindGroupLayoutEntry e = {}; + e.binding = 3; + e.visibility = WGPUShaderStage_Fragment; + e.texture.sampleType = WGPUTextureSampleType_Float; + e.texture.viewDimension = WGPUTextureViewDimension_2D; + entries.push_back(e); + } + + // Binding 4: Default Sampler + { + WGPUBindGroupLayoutEntry e = {}; + e.binding = 4; + e.visibility = WGPUShaderStage_Fragment; + e.sampler.type = WGPUSamplerBindingType_Filtering; + entries.push_back(e); + } + + // Binding 5: Sky Texture + { + WGPUBindGroupLayoutEntry e = {}; + e.binding = 5; + e.visibility = WGPUShaderStage_Fragment; + e.texture.sampleType = WGPUTextureSampleType_Float; + e.texture.viewDimension = WGPUTextureViewDimension_2D; + entries.push_back(e); + } + + WGPUBindGroupLayoutDescriptor bgl_desc = {}; + bgl_desc.entryCount = (uint32_t)entries.size(); + bgl_desc.entries = entries.data(); + WGPUBindGroupLayout bgl = wgpuDeviceCreateBindGroupLayout(device_, &bgl_desc); + + WGPUPipelineLayoutDescriptor pl_desc = {}; + pl_desc.bindGroupLayoutCount = 1; + pl_desc.bindGroupLayouts = &bgl; + WGPUPipelineLayout pipeline_layout = + wgpuDeviceCreatePipelineLayout(device_, &pl_desc); + + const char* asset_data = + (const char*)GetAsset(AssetId::ASSET_SHADER_RENDERER_3D); + std::string main_code = asset_data; + + // Use ShaderComposer to dynamically include the correct scene_query snippet + ShaderComposer::CompositionMap composition_map; + if (use_bvh) { + composition_map["render/scene_query_mode"] = "render/scene_query_bvh"; + } else { + composition_map["render/scene_query_mode"] = "render/scene_query_linear"; + } + std::string shader_source = + ShaderComposer::Get().Compose({}, main_code, composition_map); + +#if defined(DEMO_CROSS_COMPILE_WIN32) + WGPUShaderModuleWGSLDescriptor wgsl_desc = {}; + wgsl_desc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor; + wgsl_desc.code = shader_source.c_str(); + WGPUShaderModuleDescriptor shader_desc = {}; + shader_desc.nextInChain = (const WGPUChainedStruct*)&wgsl_desc.chain; +#else + WGPUShaderSourceWGSL wgsl_desc = {}; + wgsl_desc.chain.sType = WGPUSType_ShaderSourceWGSL; + wgsl_desc.code = str_view(shader_source.c_str()); + WGPUShaderModuleDescriptor shader_desc = {}; + shader_desc.nextInChain = (const WGPUChainedStruct*)&wgsl_desc.chain; +#endif + WGPUShaderModule shader_module = + wgpuDeviceCreateShaderModule(device_, &shader_desc); + + WGPUDepthStencilState depth_stencil = {}; + depth_stencil.format = WGPUTextureFormat_Depth24Plus; + depth_stencil.depthWriteEnabled = WGPUOptionalBool_True; + depth_stencil.depthCompare = WGPUCompareFunction_Less; + + WGPURenderPipelineDescriptor desc = {}; + desc.layout = pipeline_layout; + desc.vertex.module = shader_module; +#if defined(DEMO_CROSS_COMPILE_WIN32) + desc.vertex.entryPoint = "vs_main"; +#else + desc.vertex.entryPoint = {"vs_main", 7}; +#endif + WGPUColorTargetState color_target = {}; + color_target.format = format_; + color_target.writeMask = WGPUColorWriteMask_All; + WGPUFragmentState fragment = {}; + fragment.module = shader_module; +#if defined(DEMO_CROSS_COMPILE_WIN32) + fragment.entryPoint = "fs_main"; +#else + fragment.entryPoint = {"fs_main", 7}; +#endif + fragment.targetCount = 1; + fragment.targets = &color_target; + desc.fragment = &fragment; + desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; + desc.primitive.cullMode = WGPUCullMode_Back; + desc.primitive.frontFace = WGPUFrontFace_CCW; + desc.depthStencil = &depth_stencil; + desc.multisample.count = 1; + desc.multisample.mask = 0xFFFFFFFF; + + WGPURenderPipeline pipeline = wgpuDeviceCreateRenderPipeline(device_, &desc); + wgpuBindGroupLayoutRelease(bgl); + wgpuPipelineLayoutRelease(pipeline_layout); + wgpuShaderModuleRelease(shader_module); + + return pipeline; +} diff --git a/src/3d/renderer_skybox.cc b/src/3d/renderer_skybox.cc new file mode 100644 index 0000000..203cc07 --- /dev/null +++ b/src/3d/renderer_skybox.cc @@ -0,0 +1,94 @@ +// This file is part of the 64k demo project. +// It implements the skybox pipeline for Renderer3D. + +#include "3d/renderer.h" +#include "generated/assets.h" +#include "gpu/effects/shader_composer.h" +#include "util/asset_manager.h" + +void Renderer3D::create_skybox_pipeline() { + WGPUBindGroupLayoutEntry entries[3] = {}; + entries[0].binding = 0; + entries[0].visibility = WGPUShaderStage_Fragment; + entries[0].texture.sampleType = WGPUTextureSampleType_Float; + entries[0].texture.viewDimension = WGPUTextureViewDimension_2D; + + entries[1].binding = 1; + entries[1].visibility = WGPUShaderStage_Fragment; + entries[1].sampler.type = WGPUSamplerBindingType_Filtering; + + entries[2].binding = 2; + entries[2].visibility = WGPUShaderStage_Fragment; + entries[2].buffer.type = WGPUBufferBindingType_Uniform; + entries[2].buffer.minBindingSize = sizeof(GlobalUniforms); + + WGPUBindGroupLayoutDescriptor bgl_desc = {}; + bgl_desc.entryCount = 3; + bgl_desc.entries = entries; + WGPUBindGroupLayout bgl = wgpuDeviceCreateBindGroupLayout(device_, &bgl_desc); + + WGPUPipelineLayoutDescriptor pl_desc = {}; + pl_desc.bindGroupLayoutCount = 1; + pl_desc.bindGroupLayouts = &bgl; + WGPUPipelineLayout pipeline_layout = + wgpuDeviceCreatePipelineLayout(device_, &pl_desc); + + const uint8_t* shader_code_asset = + GetAsset(AssetId::ASSET_SHADER_SKYBOX, nullptr); + std::string shader_source = + ShaderComposer::Get().Compose({}, (const char*)shader_code_asset); + +#if defined(DEMO_CROSS_COMPILE_WIN32) + WGPUShaderModuleWGSLDescriptor wgsl_desc = {}; + wgsl_desc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor; + wgsl_desc.code = shader_source.c_str(); + WGPUShaderModuleDescriptor shader_desc = {}; + shader_desc.nextInChain = (const WGPUChainedStruct*)&wgsl_desc.chain; +#else + WGPUShaderSourceWGSL wgsl_desc = {}; + wgsl_desc.chain.sType = WGPUSType_ShaderSourceWGSL; + wgsl_desc.code = str_view(shader_source.c_str()); + WGPUShaderModuleDescriptor shader_desc = {}; + shader_desc.nextInChain = (const WGPUChainedStruct*)&wgsl_desc.chain; +#endif + WGPUShaderModule shader_module = + wgpuDeviceCreateShaderModule(device_, &shader_desc); + + WGPURenderPipelineDescriptor desc = {}; + desc.layout = pipeline_layout; + desc.vertex.module = shader_module; +#if defined(DEMO_CROSS_COMPILE_WIN32) + desc.vertex.entryPoint = "vs_main"; +#else + desc.vertex.entryPoint = {"vs_main", 7}; +#endif + WGPUColorTargetState color_target = {}; + color_target.format = format_; + color_target.writeMask = WGPUColorWriteMask_All; + WGPUFragmentState fragment = {}; + fragment.module = shader_module; +#if defined(DEMO_CROSS_COMPILE_WIN32) + fragment.entryPoint = "fs_main"; +#else + fragment.entryPoint = {"fs_main", 7}; +#endif + fragment.targetCount = 1; + fragment.targets = &color_target; + desc.fragment = &fragment; + desc.primitive.topology = WGPUPrimitiveTopology_TriangleList; + desc.primitive.cullMode = WGPUCullMode_Back; + desc.primitive.frontFace = WGPUFrontFace_CCW; + desc.multisample.count = 1; + desc.multisample.mask = 0xFFFFFFFF; + + WGPUDepthStencilState depth_stencil = {}; + depth_stencil.format = WGPUTextureFormat_Depth24Plus; + depth_stencil.depthWriteEnabled = WGPUOptionalBool_False; + depth_stencil.depthCompare = WGPUCompareFunction_Always; + desc.depthStencil = &depth_stencil; + + skybox_pipeline_ = wgpuDeviceCreateRenderPipeline(device_, &desc); + wgpuBindGroupLayoutRelease(bgl); + wgpuPipelineLayoutRelease(pipeline_layout); + wgpuShaderModuleRelease(shader_module); +} diff --git a/src/3d/visual_debug.cc b/src/3d/visual_debug.cc index 86f12b4..009a1e1 100644 --- a/src/3d/visual_debug.cc +++ b/src/3d/visual_debug.cc @@ -107,7 +107,7 @@ void VisualDebug::create_pipeline(WGPUTextureFormat format) { #if defined(DEMO_CROSS_COMPILE_WIN32) pipeline_desc.vertex.entryPoint = "vs_main"; #else - pipeline_desc.vertex.entryPoint = {"vs_main", 7}; + pipeline_desc.vertex.entryPoint = str_view("vs_main"); #endif pipeline_desc.vertex.bufferCount = 1; pipeline_desc.vertex.buffers = &vertex_layout; @@ -117,7 +117,7 @@ void VisualDebug::create_pipeline(WGPUTextureFormat format) { #if defined(DEMO_CROSS_COMPILE_WIN32) fragment_state.entryPoint = "fs_main"; #else - fragment_state.entryPoint = {"fs_main", 7}; + fragment_state.entryPoint = str_view("fs_main"); #endif fragment_state.targetCount = 1; @@ -203,6 +203,29 @@ void VisualDebug::add_aabb(const vec3& min, const vec3& max, } } +void VisualDebug::add_mesh_normals(const mat4& transform, uint32_t num_vertices, + const MeshVertex* vertices) { + if (!vertices || num_vertices == 0) + return; + + mat4 normal_matrix = mat4::transpose(transform.inverse()); + + for (uint32_t i = 0; i < num_vertices; ++i) { + const auto& v = vertices[i]; + + vec4 p_world = transform * vec4(v.p[0], v.p[1], v.p[2], 1.0f); + vec3 n_object = vec3(v.n[0], v.n[1], v.n[2]); + vec4 n_world_h = normal_matrix * vec4(n_object.x, n_object.y, n_object.z, 0.0f); + vec3 n_world = n_world_h.xyz().normalize(); + + lines_.push_back( + {p_world.xyz(), p_world.xyz() + n_world * 0.1f, // 0.1 is the length + {0.0f, 1.0f, 1.0f} // Cyan color + }); + } +} + + void VisualDebug::update_buffers(const mat4& view_proj) { // Update Uniforms wgpuQueueWriteBuffer(wgpuDeviceGetQueue(device_), uniform_buffer_, 0, diff --git a/src/3d/visual_debug.h b/src/3d/visual_debug.h index 6173fc4..ebccf45 100644 --- a/src/3d/visual_debug.h +++ b/src/3d/visual_debug.h @@ -8,6 +8,7 @@ #include "gpu/gpu.h" #include "util/mini_math.h" +#include "3d/object.h" #include <vector> struct DebugLine { @@ -27,6 +28,8 @@ class VisualDebug { void add_aabb(const vec3& min, const vec3& max, const vec3& color); + void add_mesh_normals(const mat4& transform, uint32_t num_vertices, const MeshVertex* vertices); + // Render all queued primitives and clear the queue void render(WGPURenderPassEncoder pass, const mat4& view_proj); diff --git a/src/generated/assets.h b/src/generated/assets.h index cda571b..1c2f542 100644 --- a/src/generated/assets.h +++ b/src/generated/assets.h @@ -41,9 +41,13 @@ enum class AssetId : uint16_t { ASSET_SHADER_MATH_SDF_SHAPES = 34, ASSET_SHADER_MATH_SDF_UTILS = 35, ASSET_SHADER_RENDER_SHADOWS = 36, - ASSET_SHADER_RENDER_SCENE_QUERY = 37, - ASSET_SHADER_RENDER_LIGHTING_UTILS = 38, - ASSET_LAST_ID = 39, + ASSET_SHADER_RENDER_SCENE_QUERY_BVH = 37, + ASSET_SHADER_RENDER_SCENE_QUERY_LINEAR = 38, + ASSET_SHADER_RENDER_LIGHTING_UTILS = 39, + ASSET_SHADER_MESH = 40, + ASSET_MESH_CUBE = 41, + ASSET_DODECAHEDRON = 42, + ASSET_LAST_ID = 43, }; #include "util/asset_manager.h" diff --git a/src/generated/assets_data.cc b/src/generated/assets_data.cc index 8bcd6d5..f97ec24 100644 --- a/src/generated/assets_data.cc +++ b/src/generated/assets_data.cc @@ -369584,7 +369584,7 @@ static const float ASSET_PROC_PARAMS_NOISE_TEX[] = {1234.000000, 16.000000}; static const char* ASSET_PROC_FUNC_STR_NOISE_TEX = "gen_noise"; -const size_t ASSET_SIZE_SHADER_RENDERER_3D = 7477; +const size_t ASSET_SIZE_SHADER_RENDERER_3D = 7683; alignas(16) static const uint8_t ASSET_DATA_SHADER_RENDERER_3D[] = { 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, @@ -369599,617 +369599,634 @@ alignas(16) static const uint8_t ASSET_DATA_SHADER_RENDERER_3D[] = { 0x65, 0x2c, 0x20, 0x72, 0x65, 0x61, 0x64, 0x3e, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x3b, - 0x0a, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x30, 0x29, 0x20, 0x40, - 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x32, 0x29, 0x20, 0x76, - 0x61, 0x72, 0x20, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x74, 0x65, 0x78, - 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, - 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x3b, 0x0a, 0x40, 0x67, 0x72, 0x6f, 0x75, - 0x70, 0x28, 0x30, 0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, - 0x67, 0x28, 0x33, 0x29, 0x20, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x6f, 0x69, - 0x73, 0x65, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x3a, 0x20, - 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x3b, 0x0a, 0x40, 0x67, 0x72, - 0x6f, 0x75, 0x70, 0x28, 0x30, 0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, - 0x69, 0x6e, 0x67, 0x28, 0x34, 0x29, 0x20, 0x76, 0x61, 0x72, 0x20, 0x73, - 0x6b, 0x79, 0x5f, 0x74, 0x65, 0x78, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, - 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x3b, - 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x56, 0x65, 0x72, - 0x74, 0x65, 0x78, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x40, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, - 0x28, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x20, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x76, 0x65, 0x63, - 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x30, 0x29, - 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x73, 0x3a, 0x20, - 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x28, 0x31, 0x29, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x76, - 0x65, 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, - 0x32, 0x29, 0x20, 0x40, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, - 0x61, 0x74, 0x65, 0x28, 0x66, 0x6c, 0x61, 0x74, 0x29, 0x20, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, - 0x3a, 0x20, 0x75, 0x33, 0x32, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, - 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x33, 0x29, 0x20, - 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x3a, 0x20, 0x76, - 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x7d, 0x3b, - 0x0a, 0x0a, 0x40, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x0a, 0x66, 0x6e, - 0x20, 0x76, 0x73, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x40, 0x62, 0x75, - 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x28, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, - 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x29, 0x20, 0x76, 0x65, 0x72, 0x74, - 0x65, 0x78, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x20, 0x75, 0x33, - 0x32, 0x2c, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x40, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x28, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, - 0x65, 0x78, 0x29, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, - 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x29, - 0x20, 0x2d, 0x3e, 0x20, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x4f, 0x75, - 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x70, 0x6f, 0x73, 0x20, - 0x3d, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3c, 0x76, 0x65, 0x63, 0x33, - 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x20, 0x33, 0x36, 0x3e, 0x28, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, - 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, - 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, - 0x28, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, - 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, - 0x28, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, - 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, - 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, - 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, - 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, - 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, - 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, - 0x30, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x76, 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, - 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, - 0x76, 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, - 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, - 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, - 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, - 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, - 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, - 0x28, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, - 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, - 0x28, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, - 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, - 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, - 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, - 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, - 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, - 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, - 0x30, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x76, 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, - 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, - 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, - 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, - 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, - 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, - 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, - 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, - 0x28, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, - 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, - 0x28, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, - 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, - 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, - 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, - 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, - 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, - 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, - 0x30, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, - 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, - 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, - 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, - 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, - 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, - 0x28, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, - 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, - 0x28, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, - 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, - 0x28, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, - 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, - 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, - 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, - 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, - 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, - 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, - 0x30, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x76, 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, - 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, - 0x76, 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, - 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, - 0x76, 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, - 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x29, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, - 0x61, 0x72, 0x20, 0x70, 0x20, 0x3d, 0x20, 0x70, 0x6f, 0x73, 0x5b, 0x76, - 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5d, - 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6f, 0x62, - 0x6a, 0x20, 0x3d, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x64, - 0x61, 0x74, 0x61, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x5b, - 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, - 0x65, 0x78, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, - 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, - 0x6f, 0x62, 0x6a, 0x2e, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x78, - 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x54, 0x69, - 0x67, 0x68, 0x74, 0x20, 0x66, 0x69, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, - 0x54, 0x6f, 0x72, 0x75, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x20, - 0x68, 0x75, 0x6c, 0x6c, 0x20, 0x28, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x20, - 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, - 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x20, 0x30, 0x2e, 0x34, 0x29, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6f, 0x62, 0x6a, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x33, 0x2e, 0x30, 0x29, 0x20, - 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x2e, - 0x78, 0x20, 0x3d, 0x20, 0x70, 0x2e, 0x78, 0x20, 0x2a, 0x20, 0x31, 0x2e, - 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, - 0x2e, 0x7a, 0x20, 0x3d, 0x20, 0x70, 0x2e, 0x7a, 0x20, 0x2a, 0x20, 0x31, - 0x2e, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x70, 0x2e, 0x79, 0x20, 0x3d, 0x20, 0x70, 0x2e, 0x79, 0x20, 0x2a, 0x20, - 0x30, 0x2e, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x77, 0x6f, 0x72, 0x6c, - 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20, 0x6f, 0x62, 0x6a, 0x2e, - 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x20, 0x2a, 0x20, 0x76, 0x65, 0x63, 0x34, - 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x70, 0x2c, 0x20, 0x31, 0x2e, 0x30, - 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x63, - 0x6c, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x6c, - 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x2e, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x70, - 0x72, 0x6f, 0x6a, 0x20, 0x2a, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, - 0x70, 0x6f, 0x73, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, - 0x72, 0x20, 0x6f, 0x75, 0x74, 0x3a, 0x20, 0x56, 0x65, 0x72, 0x74, 0x65, - 0x78, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x6f, 0x75, 0x74, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x73, - 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x2e, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20, 0x70, 0x3b, - 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x2e, 0x63, 0x6f, - 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x63, 0x6f, - 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, - 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, - 0x64, 0x65, 0x78, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x6f, 0x75, 0x74, 0x2e, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, - 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, - 0x70, 0x6f, 0x73, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x75, 0x74, 0x3b, - 0x0a, 0x7d, 0x0a, 0x0a, 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, - 0x20, 0x22, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x2f, 0x73, 0x63, 0x65, - 0x6e, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x0a, 0x23, 0x69, - 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, 0x72, 0x65, 0x6e, 0x64, - 0x65, 0x72, 0x2f, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x73, 0x22, 0x0a, - 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, 0x72, 0x65, - 0x6e, 0x64, 0x65, 0x72, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x69, 0x6e, - 0x67, 0x5f, 0x75, 0x74, 0x69, 0x6c, 0x73, 0x22, 0x0a, 0x23, 0x69, 0x6e, - 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, 0x72, 0x61, 0x79, 0x5f, 0x62, - 0x6f, 0x78, 0x22, 0x0a, 0x0a, 0x40, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, - 0x6e, 0x74, 0x0a, 0x66, 0x6e, 0x20, 0x66, 0x73, 0x5f, 0x6d, 0x61, 0x69, - 0x6e, 0x28, 0x69, 0x6e, 0x3a, 0x20, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, - 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x40, - 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x30, 0x29, 0x20, - 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x20, 0x7b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6f, 0x62, 0x6a, 0x20, - 0x3d, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x64, 0x61, 0x74, - 0x61, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x5b, 0x69, 0x6e, - 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, - 0x64, 0x65, 0x78, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, - 0x74, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, - 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, - 0x78, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, - 0x70, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, - 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x6f, - 0x72, 0x6d, 0x61, 0x6c, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, + 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, + 0x20, 0x32, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x42, 0x56, 0x48, 0x20, 0x62, + 0x75, 0x66, 0x66, 0x65, 0x72, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x0a, 0x0a, 0x40, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x28, 0x30, 0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x28, 0x33, 0x29, 0x20, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x6f, + 0x69, 0x73, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x3a, 0x20, 0x74, 0x65, 0x78, + 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, 0x3c, 0x66, 0x33, 0x32, 0x3e, + 0x3b, 0x0a, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x30, 0x29, 0x20, + 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x34, 0x29, 0x20, + 0x76, 0x61, 0x72, 0x20, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x73, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x3a, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x72, 0x3b, 0x0a, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x30, + 0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x35, + 0x29, 0x20, 0x76, 0x61, 0x72, 0x20, 0x73, 0x6b, 0x79, 0x5f, 0x74, 0x65, + 0x78, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, + 0x64, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x3b, 0x0a, 0x0a, 0x73, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x20, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x4f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, + 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x28, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x20, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, + 0x3e, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x30, 0x29, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x5f, 0x70, 0x6f, 0x73, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, + 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x31, 0x29, 0x20, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, + 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, 0x6c, 0x6f, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x32, 0x29, 0x20, 0x40, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x66, + 0x6c, 0x61, 0x74, 0x29, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x20, 0x75, 0x33, 0x32, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x33, 0x29, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, + 0x5f, 0x70, 0x6f, 0x73, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, + 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x7d, 0x3b, 0x0a, 0x0a, 0x40, 0x76, 0x65, + 0x72, 0x74, 0x65, 0x78, 0x0a, 0x66, 0x6e, 0x20, 0x76, 0x73, 0x5f, 0x6d, + 0x61, 0x69, 0x6e, 0x28, 0x40, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, + 0x28, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x29, 0x20, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6e, + 0x64, 0x65, 0x78, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x2c, 0x20, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x40, 0x62, + 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x28, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x29, 0x20, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x56, + 0x65, 0x72, 0x74, 0x65, 0x78, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, + 0x61, 0x72, 0x20, 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20, 0x61, 0x72, 0x72, + 0x61, 0x79, 0x3c, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, + 0x2c, 0x20, 0x33, 0x36, 0x3e, 0x28, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x29, 0x3b, + 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x70, 0x20, + 0x3d, 0x20, 0x70, 0x6f, 0x73, 0x5b, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, + 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6f, 0x62, 0x6a, 0x20, 0x3d, 0x20, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x5b, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5d, 0x3b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6f, 0x62, 0x6a, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x78, 0x3b, 0x0a, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x35, 0x2e, 0x30, 0x29, 0x20, 0x7b, + 0x20, 0x2f, 0x2f, 0x20, 0x4d, 0x45, 0x53, 0x48, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x75, 0x74, + 0x3a, 0x20, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x4f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6f, 0x75, 0x74, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, + 0x28, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, + 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6f, 0x75, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x54, 0x69, 0x67, 0x68, + 0x74, 0x20, 0x66, 0x69, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x54, 0x6f, + 0x72, 0x75, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x20, 0x68, 0x75, + 0x6c, 0x6c, 0x20, 0x28, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x20, 0x72, 0x61, + 0x64, 0x69, 0x75, 0x73, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x6d, 0x69, + 0x6e, 0x6f, 0x72, 0x20, 0x30, 0x2e, 0x34, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x28, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x33, 0x2e, 0x30, 0x29, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x2e, 0x78, 0x20, + 0x3d, 0x20, 0x70, 0x2e, 0x78, 0x20, 0x2a, 0x20, 0x31, 0x2e, 0x35, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x2e, 0x7a, + 0x20, 0x3d, 0x20, 0x70, 0x2e, 0x7a, 0x20, 0x2a, 0x20, 0x31, 0x2e, 0x35, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x2e, + 0x79, 0x20, 0x3d, 0x20, 0x70, 0x2e, 0x79, 0x20, 0x2a, 0x20, 0x30, 0x2e, + 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, + 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x6d, 0x6f, + 0x64, 0x65, 0x6c, 0x20, 0x2a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, + 0x33, 0x32, 0x3e, 0x28, 0x70, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x63, 0x6c, 0x69, + 0x70, 0x5f, 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x73, 0x2e, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x6f, + 0x6a, 0x20, 0x2a, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, + 0x73, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, + 0x6f, 0x75, 0x74, 0x3a, 0x20, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x4f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x73, 0x3b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x2e, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x5f, 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20, 0x70, 0x3b, 0x20, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x20, 0x3d, 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x2e, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x6f, 0x75, 0x74, 0x2e, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, + 0x73, 0x20, 0x3d, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, + 0x73, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x75, 0x74, 0x3b, 0x0a, 0x7d, + 0x0a, 0x0a, 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, + 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x2f, 0x73, 0x63, 0x65, 0x6e, 0x65, + 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x22, + 0x0a, 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, 0x72, + 0x65, 0x6e, 0x64, 0x65, 0x72, 0x2f, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, + 0x73, 0x22, 0x0a, 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, + 0x22, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x2f, 0x6c, 0x69, 0x67, 0x68, + 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x75, 0x74, 0x69, 0x6c, 0x73, 0x22, 0x0a, + 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, 0x72, 0x61, + 0x79, 0x5f, 0x62, 0x6f, 0x78, 0x22, 0x0a, 0x0a, 0x40, 0x66, 0x72, 0x61, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x0a, 0x66, 0x6e, 0x20, 0x66, 0x73, 0x5f, + 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x69, 0x6e, 0x3a, 0x20, 0x56, 0x65, 0x72, + 0x74, 0x65, 0x78, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x29, 0x20, 0x2d, + 0x3e, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x30, 0x29, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, + 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6f, + 0x62, 0x6a, 0x20, 0x3d, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, + 0x5b, 0x69, 0x6e, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x73, 0x2e, 0x78, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, + 0x61, 0x72, 0x20, 0x70, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, - 0x20, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, - 0x3d, 0x20, 0x69, 0x6e, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x72, - 0x67, 0x62, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, - 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x20, 0x3d, 0x20, - 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x76, 0x65, - 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x31, 0x2e, 0x30, 0x2c, - 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x3b, - 0x20, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6f, - 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3c, 0x3d, 0x20, 0x30, - 0x2e, 0x30, 0x29, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x20, 0x52, 0x61, 0x73, - 0x74, 0x65, 0x72, 0x20, 0x70, 0x61, 0x74, 0x68, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x2e, - 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x3b, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x20, - 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, - 0x63, 0x72, 0x6f, 0x73, 0x73, 0x28, 0x64, 0x70, 0x64, 0x78, 0x28, 0x69, - 0x6e, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x73, 0x29, - 0x2c, 0x20, 0x64, 0x70, 0x64, 0x79, 0x28, 0x69, 0x6e, 0x2e, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x73, 0x29, 0x29, 0x29, 0x3b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, - 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x5f, 0x6d, 0x61, 0x74, 0x72, 0x69, - 0x78, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x33, 0x78, 0x33, 0x3c, 0x66, - 0x33, 0x32, 0x3e, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x69, 0x6e, 0x76, 0x5f, - 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x30, 0x5d, 0x2e, 0x78, 0x79, 0x7a, - 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x69, 0x6e, 0x76, 0x5f, 0x6d, 0x6f, - 0x64, 0x65, 0x6c, 0x5b, 0x31, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x2c, 0x20, - 0x6f, 0x62, 0x6a, 0x2e, 0x69, 0x6e, 0x76, 0x5f, 0x6d, 0x6f, 0x64, 0x65, - 0x6c, 0x5b, 0x32, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, - 0x6c, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, - 0x65, 0x28, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x73, 0x65, 0x28, - 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x5f, 0x6d, 0x61, 0x74, 0x72, 0x69, - 0x78, 0x29, 0x20, 0x2a, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x6e, - 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x29, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x41, 0x70, 0x70, 0x6c, - 0x79, 0x20, 0x67, 0x72, 0x69, 0x64, 0x20, 0x70, 0x61, 0x74, 0x74, 0x65, - 0x72, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x0a, + 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x3a, 0x20, 0x76, 0x65, 0x63, + 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x76, 0x61, 0x72, 0x20, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x2e, 0x72, 0x67, 0x62, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x65, 0x74, 0x20, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x64, 0x69, 0x72, + 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, + 0x28, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, + 0x29, 0x29, 0x3b, 0x20, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, + 0x20, 0x28, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3c, + 0x3d, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x20, + 0x52, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x70, 0x61, 0x74, 0x68, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x20, 0x3d, 0x20, + 0x69, 0x6e, 0x2e, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, + 0x74, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, + 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, + 0x7a, 0x65, 0x28, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x28, 0x64, 0x70, 0x64, + 0x78, 0x28, 0x69, 0x6e, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, + 0x6f, 0x73, 0x29, 0x2c, 0x20, 0x64, 0x70, 0x64, 0x79, 0x28, 0x69, 0x6e, + 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x73, 0x29, 0x29, + 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x65, 0x74, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x5f, 0x6d, 0x61, + 0x74, 0x72, 0x69, 0x78, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x33, 0x78, + 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x69, + 0x6e, 0x76, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x30, 0x5d, 0x2e, + 0x78, 0x79, 0x7a, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x69, 0x6e, 0x76, + 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x31, 0x5d, 0x2e, 0x78, 0x79, + 0x7a, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x69, 0x6e, 0x76, 0x5f, 0x6d, + 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x32, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x29, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x6f, + 0x72, 0x6d, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, + 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, + 0x73, 0x65, 0x28, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x5f, 0x6d, 0x61, + 0x74, 0x72, 0x69, 0x78, 0x29, 0x20, 0x2a, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x29, 0x3b, 0x0a, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x41, + 0x70, 0x70, 0x6c, 0x79, 0x20, 0x67, 0x72, 0x69, 0x64, 0x20, 0x70, 0x61, + 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6c, 0x6f, + 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x65, 0x74, 0x20, 0x75, 0x76, 0x20, 0x3d, 0x20, 0x70, 0x2e, 0x78, 0x7a, + 0x20, 0x2a, 0x20, 0x30, 0x2e, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x67, 0x72, 0x69, 0x64, + 0x20, 0x3d, 0x20, 0x30, 0x2e, 0x35, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, + 0x20, 0x2a, 0x20, 0x73, 0x69, 0x6e, 0x28, 0x75, 0x76, 0x2e, 0x78, 0x20, + 0x2a, 0x20, 0x33, 0x2e, 0x31, 0x34, 0x29, 0x20, 0x2a, 0x20, 0x73, 0x69, + 0x6e, 0x28, 0x75, 0x76, 0x2e, 0x79, 0x20, 0x2a, 0x20, 0x33, 0x2e, 0x31, + 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6c, 0x65, 0x74, 0x20, 0x67, 0x72, 0x69, 0x64, 0x5f, 0x76, 0x61, 0x6c, + 0x20, 0x3d, 0x20, 0x73, 0x6d, 0x6f, 0x6f, 0x74, 0x68, 0x73, 0x74, 0x65, + 0x70, 0x28, 0x30, 0x2e, 0x34, 0x35, 0x2c, 0x20, 0x30, 0x2e, 0x35, 0x35, + 0x2c, 0x20, 0x67, 0x72, 0x69, 0x64, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x2a, 0x20, 0x28, 0x30, 0x2e, 0x35, 0x20, + 0x2b, 0x20, 0x30, 0x2e, 0x35, 0x20, 0x2a, 0x20, 0x67, 0x72, 0x69, 0x64, + 0x5f, 0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x20, 0x53, + 0x44, 0x46, 0x20, 0x70, 0x61, 0x74, 0x68, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x72, 0x6f, 0x5f, 0x77, + 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x3d, 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x73, 0x2e, 0x63, 0x61, 0x6d, 0x65, 0x72, 0x61, 0x5f, 0x70, 0x6f, + 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, - 0x75, 0x76, 0x20, 0x3d, 0x20, 0x70, 0x2e, 0x78, 0x7a, 0x20, 0x2a, 0x20, - 0x30, 0x2e, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x6c, 0x65, 0x74, 0x20, 0x67, 0x72, 0x69, 0x64, 0x20, 0x3d, 0x20, - 0x30, 0x2e, 0x35, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, 0x20, 0x2a, 0x20, - 0x73, 0x69, 0x6e, 0x28, 0x75, 0x76, 0x2e, 0x78, 0x20, 0x2a, 0x20, 0x33, - 0x2e, 0x31, 0x34, 0x29, 0x20, 0x2a, 0x20, 0x73, 0x69, 0x6e, 0x28, 0x75, - 0x76, 0x2e, 0x79, 0x20, 0x2a, 0x20, 0x33, 0x2e, 0x31, 0x34, 0x29, 0x3b, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, - 0x20, 0x67, 0x72, 0x69, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x20, 0x3d, 0x20, - 0x73, 0x6d, 0x6f, 0x6f, 0x74, 0x68, 0x73, 0x74, 0x65, 0x70, 0x28, 0x30, - 0x2e, 0x34, 0x35, 0x2c, 0x20, 0x30, 0x2e, 0x35, 0x35, 0x2c, 0x20, 0x67, - 0x72, 0x69, 0x64, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, - 0x20, 0x3d, 0x20, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, - 0x72, 0x20, 0x2a, 0x20, 0x28, 0x30, 0x2e, 0x35, 0x20, 0x2b, 0x20, 0x30, - 0x2e, 0x35, 0x20, 0x2a, 0x20, 0x67, 0x72, 0x69, 0x64, 0x5f, 0x76, 0x61, - 0x6c, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x20, 0x65, 0x6c, - 0x73, 0x65, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x20, 0x53, 0x44, 0x46, 0x20, - 0x70, 0x61, 0x74, 0x68, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x6c, 0x65, 0x74, 0x20, 0x72, 0x6f, 0x5f, 0x77, 0x6f, 0x72, 0x6c, - 0x64, 0x20, 0x3d, 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x2e, - 0x63, 0x61, 0x6d, 0x65, 0x72, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x5f, 0x74, - 0x69, 0x6d, 0x65, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x72, 0x64, 0x5f, - 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, - 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x69, 0x6e, 0x2e, 0x77, 0x6f, 0x72, - 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x20, 0x2d, 0x20, 0x72, 0x6f, 0x5f, - 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x2f, 0x2f, 0x20, 0x52, 0x61, 0x79, 0x2d, 0x42, 0x6f, 0x78, 0x20, - 0x49, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x20, - 0x74, 0x69, 0x67, 0x68, 0x74, 0x20, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, - 0x20, 0x72, 0x6f, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x3d, 0x20, + 0x72, 0x64, 0x5f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x3d, 0x20, 0x6e, + 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x69, 0x6e, 0x2e, + 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x20, 0x2d, 0x20, + 0x72, 0x6f, 0x5f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x29, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x52, 0x61, 0x79, 0x2d, 0x42, + 0x6f, 0x78, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x69, + 0x6e, 0x64, 0x20, 0x74, 0x69, 0x67, 0x68, 0x74, 0x20, 0x62, 0x6f, 0x75, + 0x6e, 0x64, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6c, 0x65, 0x74, 0x20, 0x72, 0x6f, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x3d, 0x20, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x69, 0x6e, 0x76, 0x5f, + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x20, 0x2a, 0x20, 0x76, 0x65, 0x63, 0x34, + 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x72, 0x6f, 0x5f, 0x77, 0x6f, 0x72, + 0x6c, 0x64, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x2e, 0x78, 0x79, + 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x65, 0x74, 0x20, 0x72, 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x69, 0x6e, 0x76, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x20, 0x2a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, 0x33, - 0x32, 0x3e, 0x28, 0x72, 0x6f, 0x5f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2c, - 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, - 0x72, 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x6e, - 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x28, 0x6f, 0x62, - 0x6a, 0x2e, 0x69, 0x6e, 0x76, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x20, - 0x2a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, - 0x72, 0x64, 0x5f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2c, 0x20, 0x30, 0x2e, - 0x30, 0x29, 0x29, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x20, - 0x62, 0x6f, 0x78, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x28, - 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x20, 0x76, 0x73, 0x5f, 0x6d, - 0x61, 0x69, 0x6e, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x76, 0x61, 0x72, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x20, - 0x3d, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, - 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x33, 0x2e, 0x30, 0x29, 0x20, 0x7b, - 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x76, 0x65, - 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x31, 0x2e, 0x35, 0x2c, - 0x20, 0x30, 0x2e, 0x35, 0x2c, 0x20, 0x31, 0x2e, 0x35, 0x29, 0x3b, 0x20, - 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x62, - 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x20, 0x3d, 0x20, 0x72, 0x61, 0x79, 0x5f, - 0x62, 0x6f, 0x78, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x72, 0x6f, 0x5f, 0x6c, 0x6f, 0x63, 0x61, - 0x6c, 0x2c, 0x20, 0x72, 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2c, - 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x29, 0x3b, 0x0a, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, - 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x2e, 0x68, 0x69, 0x74, 0x29, 0x20, - 0x7b, 0x20, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x3b, 0x20, 0x7d, - 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, - 0x72, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, - 0x2e, 0x74, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x3b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x68, 0x69, - 0x74, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x28, - 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, 0x3b, 0x20, 0x69, - 0x20, 0x3c, 0x20, 0x36, 0x34, 0x3b, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x69, - 0x20, 0x2b, 0x20, 0x31, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x32, 0x3e, 0x28, 0x72, 0x64, 0x5f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2c, + 0x20, 0x30, 0x2e, 0x30, 0x29, 0x29, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x50, 0x72, 0x6f, + 0x78, 0x79, 0x20, 0x62, 0x6f, 0x78, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, + 0x74, 0x20, 0x28, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x20, 0x76, + 0x73, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x65, 0x78, 0x74, 0x65, + 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, + 0x32, 0x3e, 0x28, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6f, 0x62, 0x6a, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x33, 0x2e, 0x30, + 0x29, 0x20, 0x7b, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x3d, + 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x31, + 0x2e, 0x35, 0x2c, 0x20, 0x30, 0x2e, 0x35, 0x2c, 0x20, 0x31, 0x2e, 0x35, + 0x29, 0x3b, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, + 0x74, 0x20, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x20, 0x3d, 0x20, 0x72, + 0x61, 0x79, 0x5f, 0x62, 0x6f, 0x78, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x72, 0x6f, 0x5f, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x2c, 0x20, 0x72, 0x64, 0x5f, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x2c, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x29, 0x3b, + 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, + 0x20, 0x28, 0x21, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x2e, 0x68, 0x69, + 0x74, 0x29, 0x20, 0x7b, 0x20, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, + 0x3b, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x76, 0x61, 0x72, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x62, 0x6f, 0x75, + 0x6e, 0x64, 0x73, 0x2e, 0x74, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, + 0x20, 0x68, 0x69, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, + 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x36, 0x34, 0x3b, 0x20, 0x69, 0x20, + 0x3d, 0x20, 0x69, 0x20, 0x2b, 0x20, 0x31, 0x29, 0x20, 0x7b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x65, 0x74, 0x20, 0x71, 0x20, 0x3d, 0x20, 0x72, 0x6f, 0x5f, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x2b, 0x20, 0x72, 0x64, 0x5f, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x2a, 0x20, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, - 0x71, 0x20, 0x3d, 0x20, 0x72, 0x6f, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x2b, 0x20, 0x72, 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, - 0x2a, 0x20, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x64, 0x5f, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x64, - 0x69, 0x73, 0x74, 0x28, 0x71, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x64, 0x5f, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x3c, 0x20, 0x30, 0x2e, 0x30, 0x30, - 0x30, 0x35, 0x29, 0x20, 0x7b, 0x20, 0x68, 0x69, 0x74, 0x20, 0x3d, 0x20, - 0x74, 0x72, 0x75, 0x65, 0x3b, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, - 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x74, 0x20, 0x2b, 0x20, 0x64, - 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, - 0x74, 0x20, 0x3e, 0x20, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x2e, 0x74, - 0x5f, 0x65, 0x78, 0x69, 0x74, 0x29, 0x20, 0x7b, 0x20, 0x62, 0x72, 0x65, + 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x67, 0x65, + 0x74, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x28, 0x71, 0x2c, 0x20, 0x6f, 0x62, + 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, + 0x28, 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x3c, 0x20, 0x30, + 0x2e, 0x30, 0x30, 0x30, 0x35, 0x29, 0x20, 0x7b, 0x20, 0x68, 0x69, 0x74, + 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x3b, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x69, 0x66, 0x20, 0x28, 0x21, 0x68, 0x69, 0x74, 0x29, 0x20, 0x7b, 0x20, - 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x3b, 0x20, 0x7d, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, 0x5f, 0x68, 0x69, - 0x74, 0x20, 0x3d, 0x20, 0x72, 0x6f, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, - 0x20, 0x2b, 0x20, 0x72, 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, - 0x2a, 0x20, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x70, 0x20, 0x3d, 0x20, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x6d, 0x6f, - 0x64, 0x65, 0x6c, 0x20, 0x2a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, - 0x33, 0x32, 0x3e, 0x28, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x2c, 0x20, 0x31, - 0x2e, 0x30, 0x29, 0x29, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x20, 0x2f, 0x2f, - 0x20, 0x43, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, 0x77, 0x6f, 0x72, - 0x6c, 0x64, 0x20, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x43, 0x61, 0x6c, 0x63, - 0x75, 0x6c, 0x61, 0x74, 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, - 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x62, 0x75, 0x6d, 0x70, 0x20, 0x6d, - 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x20, 0x3d, 0x20, 0x76, - 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x30, 0x2e, 0x30, - 0x30, 0x35, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x64, 0x69, - 0x73, 0x70, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, - 0x3d, 0x20, 0x30, 0x2e, 0x30, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, 0x5f, 0x78, 0x31, 0x20, 0x3d, 0x20, - 0x71, 0x5f, 0x68, 0x69, 0x74, 0x20, 0x2b, 0x20, 0x65, 0x2e, 0x78, 0x79, - 0x79, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, - 0x65, 0x74, 0x20, 0x75, 0x76, 0x5f, 0x78, 0x31, 0x20, 0x3d, 0x20, 0x76, - 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x61, 0x74, 0x61, - 0x6e, 0x32, 0x28, 0x71, 0x5f, 0x78, 0x31, 0x2e, 0x78, 0x2c, 0x20, 0x71, - 0x5f, 0x78, 0x31, 0x2e, 0x7a, 0x29, 0x20, 0x2f, 0x20, 0x36, 0x2e, 0x32, - 0x38, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, 0x2c, 0x20, 0x61, 0x63, 0x6f, - 0x73, 0x28, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x28, 0x71, 0x5f, 0x78, 0x31, - 0x2e, 0x79, 0x20, 0x2f, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, - 0x71, 0x5f, 0x78, 0x31, 0x29, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, - 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x20, 0x2f, 0x20, 0x33, 0x2e, 0x31, - 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x6c, 0x65, 0x74, 0x20, 0x68, 0x5f, 0x78, 0x31, 0x20, 0x3d, 0x20, 0x74, - 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, - 0x28, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x2c, 0x20, - 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, - 0x72, 0x2c, 0x20, 0x75, 0x76, 0x5f, 0x78, 0x31, 0x29, 0x2e, 0x72, 0x3b, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x74, 0x20, + 0x2b, 0x20, 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, + 0x66, 0x20, 0x28, 0x74, 0x20, 0x3e, 0x20, 0x62, 0x6f, 0x75, 0x6e, 0x64, + 0x73, 0x2e, 0x74, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x29, 0x20, 0x7b, 0x20, + 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x68, 0x69, 0x74, 0x29, + 0x20, 0x7b, 0x20, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x3b, 0x20, + 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, + 0x5f, 0x68, 0x69, 0x74, 0x20, 0x3d, 0x20, 0x72, 0x6f, 0x5f, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x2b, 0x20, 0x72, 0x64, 0x5f, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x2a, 0x20, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x70, 0x20, 0x3d, 0x20, 0x28, 0x6f, 0x62, 0x6a, + 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x20, 0x2a, 0x20, 0x76, 0x65, 0x63, + 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x71, 0x5f, 0x68, 0x69, 0x74, + 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x2e, 0x78, 0x79, 0x7a, 0x3b, + 0x20, 0x2f, 0x2f, 0x20, 0x43, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, + 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x43, + 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x20, 0x6e, 0x6f, 0x72, + 0x6d, 0x61, 0x6c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x62, 0x75, 0x6d, + 0x70, 0x20, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x20, + 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, + 0x30, 0x2e, 0x30, 0x30, 0x35, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, - 0x20, 0x64, 0x5f, 0x78, 0x31, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, - 0x64, 0x69, 0x73, 0x74, 0x28, 0x71, 0x5f, 0x78, 0x31, 0x2c, 0x20, 0x6f, - 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x2d, 0x20, 0x64, - 0x69, 0x73, 0x70, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x6e, 0x67, 0x74, 0x68, - 0x20, 0x2a, 0x20, 0x68, 0x5f, 0x78, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, 0x5f, 0x78, 0x32, 0x20, 0x3d, - 0x20, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x20, 0x2d, 0x20, 0x65, 0x2e, 0x78, - 0x79, 0x79, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x6c, 0x65, 0x74, 0x20, 0x75, 0x76, 0x5f, 0x78, 0x32, 0x20, 0x3d, 0x20, - 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x61, 0x74, - 0x61, 0x6e, 0x32, 0x28, 0x71, 0x5f, 0x78, 0x32, 0x2e, 0x78, 0x2c, 0x20, - 0x71, 0x5f, 0x78, 0x32, 0x2e, 0x7a, 0x29, 0x20, 0x2f, 0x20, 0x36, 0x2e, - 0x32, 0x38, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, 0x2c, 0x20, 0x61, 0x63, - 0x6f, 0x73, 0x28, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x28, 0x71, 0x5f, 0x78, - 0x32, 0x2e, 0x79, 0x20, 0x2f, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, - 0x28, 0x71, 0x5f, 0x78, 0x32, 0x29, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, - 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x20, 0x2f, 0x20, 0x33, 0x2e, - 0x31, 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x6c, 0x65, 0x74, 0x20, 0x68, 0x5f, 0x78, 0x32, 0x20, 0x3d, 0x20, - 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, - 0x65, 0x28, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x2c, - 0x20, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, - 0x65, 0x72, 0x2c, 0x20, 0x75, 0x76, 0x5f, 0x78, 0x32, 0x29, 0x2e, 0x72, - 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, - 0x74, 0x20, 0x64, 0x5f, 0x78, 0x32, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, - 0x5f, 0x64, 0x69, 0x73, 0x74, 0x28, 0x71, 0x5f, 0x78, 0x32, 0x2c, 0x20, - 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x2d, 0x20, - 0x64, 0x69, 0x73, 0x70, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x6e, 0x67, 0x74, - 0x68, 0x20, 0x2a, 0x20, 0x68, 0x5f, 0x78, 0x32, 0x3b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, 0x5f, 0x79, 0x31, 0x20, - 0x3d, 0x20, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x20, 0x2b, 0x20, 0x65, 0x2e, - 0x79, 0x78, 0x79, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x6c, 0x65, 0x74, 0x20, 0x75, 0x76, 0x5f, 0x79, 0x31, 0x20, 0x3d, - 0x20, 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x61, - 0x74, 0x61, 0x6e, 0x32, 0x28, 0x71, 0x5f, 0x79, 0x31, 0x2e, 0x78, 0x2c, - 0x20, 0x71, 0x5f, 0x79, 0x31, 0x2e, 0x7a, 0x29, 0x20, 0x2f, 0x20, 0x36, - 0x2e, 0x32, 0x38, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, 0x2c, 0x20, 0x61, - 0x63, 0x6f, 0x73, 0x28, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x28, 0x71, 0x5f, - 0x79, 0x31, 0x2e, 0x79, 0x20, 0x2f, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, - 0x68, 0x28, 0x71, 0x5f, 0x79, 0x31, 0x29, 0x2c, 0x20, 0x2d, 0x31, 0x2e, - 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x20, 0x2f, 0x20, 0x33, - 0x2e, 0x31, 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x68, 0x5f, 0x79, 0x31, 0x20, 0x3d, - 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x53, 0x61, 0x6d, 0x70, - 0x6c, 0x65, 0x28, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x74, 0x65, 0x78, - 0x2c, 0x20, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x73, 0x61, 0x6d, 0x70, - 0x6c, 0x65, 0x72, 0x2c, 0x20, 0x75, 0x76, 0x5f, 0x79, 0x31, 0x29, 0x2e, - 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, - 0x65, 0x74, 0x20, 0x64, 0x5f, 0x79, 0x31, 0x20, 0x3d, 0x20, 0x67, 0x65, - 0x74, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x28, 0x71, 0x5f, 0x79, 0x31, 0x2c, - 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x2d, 0x20, 0x64, 0x69, 0x73, 0x70, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x6e, 0x67, - 0x74, 0x68, 0x20, 0x2a, 0x20, 0x68, 0x5f, 0x79, 0x31, 0x3b, 0x0a, 0x20, + 0x74, 0x68, 0x20, 0x3d, 0x20, 0x30, 0x2e, 0x30, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, 0x5f, 0x79, 0x32, - 0x20, 0x3d, 0x20, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x20, 0x2d, 0x20, 0x65, - 0x2e, 0x79, 0x78, 0x79, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x75, 0x76, 0x5f, 0x79, 0x32, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, 0x5f, 0x78, 0x31, + 0x20, 0x3d, 0x20, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x20, 0x2b, 0x20, 0x65, + 0x2e, 0x78, 0x79, 0x79, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x75, 0x76, 0x5f, 0x78, 0x31, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, - 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x71, 0x5f, 0x79, 0x32, 0x2e, 0x78, - 0x2c, 0x20, 0x71, 0x5f, 0x79, 0x32, 0x2e, 0x7a, 0x29, 0x20, 0x2f, 0x20, + 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x71, 0x5f, 0x78, 0x31, 0x2e, 0x78, + 0x2c, 0x20, 0x71, 0x5f, 0x78, 0x31, 0x2e, 0x7a, 0x29, 0x20, 0x2f, 0x20, 0x36, 0x2e, 0x32, 0x38, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, 0x2c, 0x20, 0x61, 0x63, 0x6f, 0x73, 0x28, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x28, 0x71, - 0x5f, 0x79, 0x32, 0x2e, 0x79, 0x20, 0x2f, 0x20, 0x6c, 0x65, 0x6e, 0x67, - 0x74, 0x68, 0x28, 0x71, 0x5f, 0x79, 0x32, 0x29, 0x2c, 0x20, 0x2d, 0x31, + 0x5f, 0x78, 0x31, 0x2e, 0x79, 0x20, 0x2f, 0x20, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x28, 0x71, 0x5f, 0x78, 0x31, 0x29, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x20, 0x2f, 0x20, 0x33, 0x2e, 0x31, 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x68, 0x5f, 0x79, 0x32, 0x20, + 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x68, 0x5f, 0x78, 0x31, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x2c, 0x20, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x73, 0x61, 0x6d, - 0x70, 0x6c, 0x65, 0x72, 0x2c, 0x20, 0x75, 0x76, 0x5f, 0x79, 0x32, 0x29, + 0x70, 0x6c, 0x65, 0x72, 0x2c, 0x20, 0x75, 0x76, 0x5f, 0x78, 0x31, 0x29, 0x2e, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x6c, 0x65, 0x74, 0x20, 0x64, 0x5f, 0x79, 0x32, 0x20, 0x3d, 0x20, 0x67, - 0x65, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x28, 0x71, 0x5f, 0x79, 0x32, + 0x6c, 0x65, 0x74, 0x20, 0x64, 0x5f, 0x78, 0x31, 0x20, 0x3d, 0x20, 0x67, + 0x65, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x28, 0x71, 0x5f, 0x78, 0x31, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x2d, 0x20, 0x64, 0x69, 0x73, 0x70, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x6e, - 0x67, 0x74, 0x68, 0x20, 0x2a, 0x20, 0x68, 0x5f, 0x79, 0x32, 0x3b, 0x0a, + 0x67, 0x74, 0x68, 0x20, 0x2a, 0x20, 0x68, 0x5f, 0x78, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, 0x5f, 0x7a, - 0x31, 0x20, 0x3d, 0x20, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x20, 0x2b, 0x20, - 0x65, 0x2e, 0x79, 0x79, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x75, 0x76, 0x5f, 0x7a, 0x31, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, 0x5f, 0x78, + 0x32, 0x20, 0x3d, 0x20, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x20, 0x2d, 0x20, + 0x65, 0x2e, 0x78, 0x79, 0x79, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x75, 0x76, 0x5f, 0x78, 0x32, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, 0x3e, - 0x28, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x71, 0x5f, 0x7a, 0x31, 0x2e, - 0x78, 0x2c, 0x20, 0x71, 0x5f, 0x7a, 0x31, 0x2e, 0x7a, 0x29, 0x20, 0x2f, + 0x28, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x71, 0x5f, 0x78, 0x32, 0x2e, + 0x78, 0x2c, 0x20, 0x71, 0x5f, 0x78, 0x32, 0x2e, 0x7a, 0x29, 0x20, 0x2f, 0x20, 0x36, 0x2e, 0x32, 0x38, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, 0x2c, 0x20, 0x61, 0x63, 0x6f, 0x73, 0x28, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x28, - 0x71, 0x5f, 0x7a, 0x31, 0x2e, 0x79, 0x20, 0x2f, 0x20, 0x6c, 0x65, 0x6e, - 0x67, 0x74, 0x68, 0x28, 0x71, 0x5f, 0x7a, 0x31, 0x29, 0x2c, 0x20, 0x2d, + 0x71, 0x5f, 0x78, 0x32, 0x2e, 0x79, 0x20, 0x2f, 0x20, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x28, 0x71, 0x5f, 0x78, 0x32, 0x29, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x20, 0x2f, 0x20, 0x33, 0x2e, 0x31, 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x68, 0x5f, 0x7a, 0x31, + 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x68, 0x5f, 0x78, 0x32, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x2c, 0x20, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x73, 0x61, - 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x2c, 0x20, 0x75, 0x76, 0x5f, 0x7a, 0x31, + 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x2c, 0x20, 0x75, 0x76, 0x5f, 0x78, 0x32, 0x29, 0x2e, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x6c, 0x65, 0x74, 0x20, 0x64, 0x5f, 0x7a, 0x31, 0x20, 0x3d, 0x20, - 0x67, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x28, 0x71, 0x5f, 0x7a, - 0x31, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x29, + 0x20, 0x6c, 0x65, 0x74, 0x20, 0x64, 0x5f, 0x78, 0x32, 0x20, 0x3d, 0x20, + 0x67, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x28, 0x71, 0x5f, 0x78, + 0x32, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x2d, 0x20, 0x64, 0x69, 0x73, 0x70, 0x5f, 0x73, 0x74, 0x72, 0x65, - 0x6e, 0x67, 0x74, 0x68, 0x20, 0x2a, 0x20, 0x68, 0x5f, 0x7a, 0x31, 0x3b, + 0x6e, 0x67, 0x74, 0x68, 0x20, 0x2a, 0x20, 0x68, 0x5f, 0x78, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, 0x5f, - 0x7a, 0x32, 0x20, 0x3d, 0x20, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x20, 0x2d, - 0x20, 0x65, 0x2e, 0x79, 0x79, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x75, 0x76, 0x5f, 0x7a, - 0x32, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, - 0x3e, 0x28, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x71, 0x5f, 0x7a, 0x32, - 0x2e, 0x78, 0x2c, 0x20, 0x71, 0x5f, 0x7a, 0x32, 0x2e, 0x7a, 0x29, 0x20, + 0x79, 0x31, 0x20, 0x3d, 0x20, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x20, 0x2b, + 0x20, 0x65, 0x2e, 0x79, 0x78, 0x79, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x75, 0x76, 0x5f, 0x79, + 0x31, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, + 0x3e, 0x28, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x71, 0x5f, 0x79, 0x31, + 0x2e, 0x78, 0x2c, 0x20, 0x71, 0x5f, 0x79, 0x31, 0x2e, 0x7a, 0x29, 0x20, 0x2f, 0x20, 0x36, 0x2e, 0x32, 0x38, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, 0x2c, 0x20, 0x61, 0x63, 0x6f, 0x73, 0x28, 0x63, 0x6c, 0x61, 0x6d, 0x70, - 0x28, 0x71, 0x5f, 0x7a, 0x32, 0x2e, 0x79, 0x20, 0x2f, 0x20, 0x6c, 0x65, - 0x6e, 0x67, 0x74, 0x68, 0x28, 0x71, 0x5f, 0x7a, 0x32, 0x29, 0x2c, 0x20, + 0x28, 0x71, 0x5f, 0x79, 0x31, 0x2e, 0x79, 0x20, 0x2f, 0x20, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x28, 0x71, 0x5f, 0x79, 0x31, 0x29, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x20, 0x2f, 0x20, 0x33, 0x2e, 0x31, 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x68, 0x5f, 0x7a, - 0x32, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x53, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x68, 0x5f, 0x79, + 0x31, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x2c, 0x20, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x73, - 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x2c, 0x20, 0x75, 0x76, 0x5f, 0x7a, - 0x32, 0x29, 0x2e, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x64, 0x5f, 0x7a, 0x32, 0x20, 0x3d, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x2c, 0x20, 0x75, 0x76, 0x5f, 0x79, + 0x31, 0x29, 0x2e, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x64, 0x5f, 0x79, 0x31, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x28, 0x71, 0x5f, - 0x7a, 0x32, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x79, 0x31, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x2d, 0x20, 0x64, 0x69, 0x73, 0x70, 0x5f, 0x73, 0x74, 0x72, - 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x2a, 0x20, 0x68, 0x5f, 0x7a, 0x32, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x2a, 0x20, 0x68, 0x5f, 0x79, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6e, - 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x72, - 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x76, 0x65, 0x63, 0x33, 0x3c, - 0x66, 0x33, 0x32, 0x3e, 0x28, 0x64, 0x5f, 0x78, 0x31, 0x20, 0x2d, 0x20, - 0x64, 0x5f, 0x78, 0x32, 0x2c, 0x20, 0x64, 0x5f, 0x79, 0x31, 0x20, 0x2d, - 0x20, 0x64, 0x5f, 0x79, 0x32, 0x2c, 0x20, 0x64, 0x5f, 0x7a, 0x31, 0x20, - 0x2d, 0x20, 0x64, 0x5f, 0x7a, 0x32, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6e, 0x6f, - 0x72, 0x6d, 0x61, 0x6c, 0x5f, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, - 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x33, 0x78, 0x33, 0x3c, 0x66, 0x33, 0x32, - 0x3e, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x69, 0x6e, 0x76, 0x5f, 0x6d, 0x6f, - 0x64, 0x65, 0x6c, 0x5b, 0x30, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x2c, 0x20, - 0x6f, 0x62, 0x6a, 0x2e, 0x69, 0x6e, 0x76, 0x5f, 0x6d, 0x6f, 0x64, 0x65, - 0x6c, 0x5b, 0x31, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x2c, 0x20, 0x6f, 0x62, - 0x6a, 0x2e, 0x69, 0x6e, 0x76, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5b, - 0x32, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x20, - 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, - 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x73, 0x65, 0x28, 0x6e, 0x6f, - 0x72, 0x6d, 0x61, 0x6c, 0x5f, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x29, - 0x20, 0x2a, 0x20, 0x6e, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x29, 0x3b, - 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, - 0x20, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, - 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x53, 0x44, 0x46, 0x20, 0x63, 0x6f, - 0x6c, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x69, 0x66, 0x20, 0x28, 0x69, 0x6e, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, - 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3d, 0x3d, - 0x20, 0x30, 0x75, 0x20, 0x7c, 0x7c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x34, 0x2e, 0x30, 0x29, 0x20, - 0x7b, 0x20, 0x2f, 0x2f, 0x20, 0x46, 0x6c, 0x6f, 0x6f, 0x72, 0x20, 0x28, - 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x30, 0x29, 0x20, 0x6f, 0x72, 0x20, - 0x50, 0x4c, 0x41, 0x4e, 0x45, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x75, 0x76, - 0x5f, 0x67, 0x72, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x70, 0x2e, 0x78, 0x7a, - 0x20, 0x2a, 0x20, 0x30, 0x2e, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, + 0x5f, 0x79, 0x32, 0x20, 0x3d, 0x20, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x20, + 0x2d, 0x20, 0x65, 0x2e, 0x79, 0x78, 0x79, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x75, 0x76, 0x5f, + 0x79, 0x32, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, + 0x32, 0x3e, 0x28, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x71, 0x5f, 0x79, + 0x32, 0x2e, 0x78, 0x2c, 0x20, 0x71, 0x5f, 0x79, 0x32, 0x2e, 0x7a, 0x29, + 0x20, 0x2f, 0x20, 0x36, 0x2e, 0x32, 0x38, 0x20, 0x2b, 0x20, 0x30, 0x2e, + 0x35, 0x2c, 0x20, 0x61, 0x63, 0x6f, 0x73, 0x28, 0x63, 0x6c, 0x61, 0x6d, + 0x70, 0x28, 0x71, 0x5f, 0x79, 0x32, 0x2e, 0x79, 0x20, 0x2f, 0x20, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x71, 0x5f, 0x79, 0x32, 0x29, 0x2c, + 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, + 0x20, 0x2f, 0x20, 0x33, 0x2e, 0x31, 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x68, 0x5f, + 0x79, 0x32, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, + 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x6e, 0x6f, 0x69, 0x73, 0x65, + 0x5f, 0x74, 0x65, 0x78, 0x2c, 0x20, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, + 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x2c, 0x20, 0x75, 0x76, 0x5f, + 0x79, 0x32, 0x29, 0x2e, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x64, 0x5f, 0x79, 0x32, 0x20, + 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x28, 0x71, + 0x5f, 0x79, 0x32, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x29, 0x20, 0x2d, 0x20, 0x64, 0x69, 0x73, 0x70, 0x5f, 0x73, 0x74, + 0x72, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x2a, 0x20, 0x68, 0x5f, 0x79, + 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, - 0x67, 0x72, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x30, 0x2e, 0x35, 0x20, 0x2b, - 0x20, 0x30, 0x2e, 0x35, 0x20, 0x2a, 0x20, 0x73, 0x69, 0x6e, 0x28, 0x75, - 0x76, 0x5f, 0x67, 0x72, 0x69, 0x64, 0x2e, 0x78, 0x20, 0x2a, 0x20, 0x33, - 0x2e, 0x31, 0x34, 0x29, 0x20, 0x2a, 0x20, 0x73, 0x69, 0x6e, 0x28, 0x75, - 0x76, 0x5f, 0x67, 0x72, 0x69, 0x64, 0x2e, 0x79, 0x20, 0x2a, 0x20, 0x33, - 0x2e, 0x31, 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x67, 0x72, - 0x69, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x73, 0x6d, 0x6f, - 0x6f, 0x74, 0x68, 0x73, 0x74, 0x65, 0x70, 0x28, 0x30, 0x2e, 0x34, 0x35, - 0x2c, 0x20, 0x30, 0x2e, 0x35, 0x35, 0x2c, 0x20, 0x67, 0x72, 0x69, 0x64, - 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, - 0x72, 0x20, 0x3d, 0x20, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6c, - 0x6f, 0x72, 0x20, 0x2a, 0x20, 0x28, 0x30, 0x2e, 0x35, 0x20, 0x2b, 0x20, - 0x30, 0x2e, 0x35, 0x20, 0x2a, 0x20, 0x67, 0x72, 0x69, 0x64, 0x5f, 0x76, - 0x61, 0x6c, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, - 0x74, 0x20, 0x75, 0x76, 0x5f, 0x68, 0x69, 0x74, 0x20, 0x3d, 0x20, 0x76, - 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x61, 0x74, 0x61, - 0x6e, 0x32, 0x28, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x2e, 0x78, 0x2c, 0x20, - 0x71, 0x5f, 0x68, 0x69, 0x74, 0x2e, 0x7a, 0x29, 0x20, 0x2f, 0x20, 0x36, - 0x2e, 0x32, 0x38, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, 0x2c, 0x20, 0x61, - 0x63, 0x6f, 0x73, 0x28, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x28, 0x71, 0x5f, - 0x68, 0x69, 0x74, 0x2e, 0x79, 0x20, 0x2f, 0x20, 0x6c, 0x65, 0x6e, 0x67, - 0x74, 0x68, 0x28, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x29, 0x2c, 0x20, 0x2d, - 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x20, 0x2f, - 0x20, 0x33, 0x2e, 0x31, 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x71, 0x5f, 0x7a, 0x31, 0x20, 0x3d, 0x20, 0x71, 0x5f, 0x68, 0x69, 0x74, + 0x20, 0x2b, 0x20, 0x65, 0x2e, 0x79, 0x79, 0x78, 0x3b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x75, 0x76, + 0x5f, 0x7a, 0x31, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, + 0x33, 0x32, 0x3e, 0x28, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x71, 0x5f, + 0x7a, 0x31, 0x2e, 0x78, 0x2c, 0x20, 0x71, 0x5f, 0x7a, 0x31, 0x2e, 0x7a, + 0x29, 0x20, 0x2f, 0x20, 0x36, 0x2e, 0x32, 0x38, 0x20, 0x2b, 0x20, 0x30, + 0x2e, 0x35, 0x2c, 0x20, 0x61, 0x63, 0x6f, 0x73, 0x28, 0x63, 0x6c, 0x61, + 0x6d, 0x70, 0x28, 0x71, 0x5f, 0x7a, 0x31, 0x2e, 0x79, 0x20, 0x2f, 0x20, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x71, 0x5f, 0x7a, 0x31, 0x29, + 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, + 0x29, 0x20, 0x2f, 0x20, 0x33, 0x2e, 0x31, 0x34, 0x29, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x68, + 0x5f, 0x7a, 0x31, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, + 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x6e, 0x6f, 0x69, 0x73, + 0x65, 0x5f, 0x74, 0x65, 0x78, 0x2c, 0x20, 0x6e, 0x6f, 0x69, 0x73, 0x65, + 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x2c, 0x20, 0x75, 0x76, + 0x5f, 0x7a, 0x31, 0x29, 0x2e, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x64, 0x5f, 0x7a, 0x31, + 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x28, + 0x71, 0x5f, 0x7a, 0x31, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x29, 0x20, 0x2d, 0x20, 0x64, 0x69, 0x73, 0x70, 0x5f, 0x73, + 0x74, 0x72, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x2a, 0x20, 0x68, 0x5f, + 0x7a, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, + 0x20, 0x71, 0x5f, 0x7a, 0x32, 0x20, 0x3d, 0x20, 0x71, 0x5f, 0x68, 0x69, + 0x74, 0x20, 0x2d, 0x20, 0x65, 0x2e, 0x79, 0x79, 0x78, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x75, + 0x76, 0x5f, 0x7a, 0x32, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x3c, + 0x66, 0x33, 0x32, 0x3e, 0x28, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x71, + 0x5f, 0x7a, 0x32, 0x2e, 0x78, 0x2c, 0x20, 0x71, 0x5f, 0x7a, 0x32, 0x2e, + 0x7a, 0x29, 0x20, 0x2f, 0x20, 0x36, 0x2e, 0x32, 0x38, 0x20, 0x2b, 0x20, + 0x30, 0x2e, 0x35, 0x2c, 0x20, 0x61, 0x63, 0x6f, 0x73, 0x28, 0x63, 0x6c, + 0x61, 0x6d, 0x70, 0x28, 0x71, 0x5f, 0x7a, 0x32, 0x2e, 0x79, 0x20, 0x2f, + 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x71, 0x5f, 0x7a, 0x32, + 0x29, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, + 0x29, 0x29, 0x20, 0x2f, 0x20, 0x33, 0x2e, 0x31, 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, - 0x74, 0x65, 0x78, 0x5f, 0x76, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x74, 0x65, - 0x78, 0x74, 0x75, 0x72, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, - 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x2c, 0x20, 0x6e, - 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, - 0x2c, 0x20, 0x75, 0x76, 0x5f, 0x68, 0x69, 0x74, 0x29, 0x2e, 0x72, 0x3b, + 0x68, 0x5f, 0x7a, 0x32, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, + 0x72, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x6e, 0x6f, 0x69, + 0x73, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x2c, 0x20, 0x6e, 0x6f, 0x69, 0x73, + 0x65, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x2c, 0x20, 0x75, + 0x76, 0x5f, 0x7a, 0x32, 0x29, 0x2e, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x64, 0x5f, 0x7a, + 0x32, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x74, + 0x28, 0x71, 0x5f, 0x7a, 0x32, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x29, 0x20, 0x2d, 0x20, 0x64, 0x69, 0x73, 0x70, 0x5f, + 0x73, 0x74, 0x72, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x2a, 0x20, 0x68, + 0x5f, 0x7a, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, + 0x74, 0x20, 0x6e, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x3d, 0x20, + 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x76, 0x65, + 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x64, 0x5f, 0x78, 0x31, + 0x20, 0x2d, 0x20, 0x64, 0x5f, 0x78, 0x32, 0x2c, 0x20, 0x64, 0x5f, 0x79, + 0x31, 0x20, 0x2d, 0x20, 0x64, 0x5f, 0x79, 0x32, 0x2c, 0x20, 0x64, 0x5f, + 0x7a, 0x31, 0x20, 0x2d, 0x20, 0x64, 0x5f, 0x7a, 0x32, 0x29, 0x29, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, + 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x5f, 0x6d, 0x61, 0x74, 0x72, + 0x69, 0x78, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x33, 0x78, 0x33, 0x3c, + 0x66, 0x33, 0x32, 0x3e, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x69, 0x6e, 0x76, + 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x30, 0x5d, 0x2e, 0x78, 0x79, + 0x7a, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x69, 0x6e, 0x76, 0x5f, 0x6d, + 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x31, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x2c, + 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x69, 0x6e, 0x76, 0x5f, 0x6d, 0x6f, 0x64, + 0x65, 0x6c, 0x5b, 0x32, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x6f, 0x72, 0x6d, + 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, + 0x7a, 0x65, 0x28, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x73, 0x65, + 0x28, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x5f, 0x6d, 0x61, 0x74, 0x72, + 0x69, 0x78, 0x29, 0x20, 0x2a, 0x20, 0x6e, 0x5f, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x29, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2f, 0x2f, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x20, 0x74, 0x65, + 0x78, 0x74, 0x75, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x53, 0x44, 0x46, + 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x69, 0x6e, 0x2e, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x75, 0x20, 0x7c, 0x7c, 0x20, 0x6f, 0x62, + 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x34, 0x2e, + 0x30, 0x29, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x20, 0x46, 0x6c, 0x6f, 0x6f, + 0x72, 0x20, 0x28, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x30, 0x29, 0x20, + 0x6f, 0x72, 0x20, 0x50, 0x4c, 0x41, 0x4e, 0x45, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, + 0x20, 0x75, 0x76, 0x5f, 0x67, 0x72, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x70, + 0x2e, 0x78, 0x7a, 0x20, 0x2a, 0x20, 0x30, 0x2e, 0x35, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x65, 0x74, 0x20, 0x67, 0x72, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x30, 0x2e, + 0x35, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, 0x20, 0x2a, 0x20, 0x73, 0x69, + 0x6e, 0x28, 0x75, 0x76, 0x5f, 0x67, 0x72, 0x69, 0x64, 0x2e, 0x78, 0x20, + 0x2a, 0x20, 0x33, 0x2e, 0x31, 0x34, 0x29, 0x20, 0x2a, 0x20, 0x73, 0x69, + 0x6e, 0x28, 0x75, 0x76, 0x5f, 0x67, 0x72, 0x69, 0x64, 0x2e, 0x79, 0x20, + 0x2a, 0x20, 0x33, 0x2e, 0x31, 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, + 0x20, 0x67, 0x72, 0x69, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x20, 0x3d, 0x20, + 0x73, 0x6d, 0x6f, 0x6f, 0x74, 0x68, 0x73, 0x74, 0x65, 0x70, 0x28, 0x30, + 0x2e, 0x34, 0x35, 0x2c, 0x20, 0x30, 0x2e, 0x35, 0x35, 0x2c, 0x20, 0x67, + 0x72, 0x69, 0x64, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x62, 0x61, 0x73, 0x65, 0x5f, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x2a, 0x20, 0x28, 0x30, 0x2e, 0x35, + 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, 0x20, 0x2a, 0x20, 0x67, 0x72, 0x69, + 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, - 0x3d, 0x20, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, - 0x20, 0x2a, 0x20, 0x28, 0x30, 0x2e, 0x37, 0x20, 0x2b, 0x20, 0x30, 0x2e, - 0x33, 0x20, 0x2a, 0x20, 0x74, 0x65, 0x78, 0x5f, 0x76, 0x61, 0x6c, 0x29, - 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, - 0x65, 0x74, 0x20, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x20, 0x3d, 0x20, - 0x63, 0x61, 0x6c, 0x63, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x28, - 0x70, 0x2c, 0x20, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x64, 0x69, 0x72, - 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x35, 0x2c, 0x20, 0x32, 0x30, 0x2e, 0x30, - 0x2c, 0x20, 0x69, 0x6e, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x29, 0x3b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x6f, - 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x63, 0x61, 0x6c, 0x63, 0x75, 0x6c, - 0x61, 0x74, 0x65, 0x5f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x69, 0x6e, 0x67, - 0x28, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, - 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x2c, 0x20, 0x70, 0x2c, 0x20, - 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x34, - 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x6f, - 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x7d, - 0x0a, 0x00 + 0x20, 0x6c, 0x65, 0x74, 0x20, 0x75, 0x76, 0x5f, 0x68, 0x69, 0x74, 0x20, + 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, + 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x2e, + 0x78, 0x2c, 0x20, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x2e, 0x7a, 0x29, 0x20, + 0x2f, 0x20, 0x36, 0x2e, 0x32, 0x38, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, + 0x2c, 0x20, 0x61, 0x63, 0x6f, 0x73, 0x28, 0x63, 0x6c, 0x61, 0x6d, 0x70, + 0x28, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x2e, 0x79, 0x20, 0x2f, 0x20, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x29, + 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, + 0x29, 0x20, 0x2f, 0x20, 0x33, 0x2e, 0x31, 0x34, 0x29, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x65, 0x74, 0x20, 0x74, 0x65, 0x78, 0x5f, 0x76, 0x61, 0x6c, 0x20, 0x3d, + 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x53, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x28, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x74, 0x65, 0x78, + 0x2c, 0x20, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x73, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x72, 0x2c, 0x20, 0x75, 0x76, 0x5f, 0x68, 0x69, 0x74, 0x29, + 0x2e, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x20, 0x2a, 0x20, 0x28, 0x30, 0x2e, 0x37, 0x20, 0x2b, + 0x20, 0x30, 0x2e, 0x33, 0x20, 0x2a, 0x20, 0x74, 0x65, 0x78, 0x5f, 0x76, + 0x61, 0x6c, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, + 0x20, 0x3d, 0x20, 0x63, 0x61, 0x6c, 0x63, 0x5f, 0x73, 0x68, 0x61, 0x64, + 0x6f, 0x77, 0x28, 0x70, 0x2c, 0x20, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, + 0x64, 0x69, 0x72, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x35, 0x2c, 0x20, 0x32, + 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x69, 0x6e, 0x2e, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x29, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6c, 0x69, 0x74, + 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x63, 0x61, 0x6c, + 0x63, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x6c, 0x69, 0x67, 0x68, 0x74, + 0x69, 0x6e, 0x67, 0x28, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x2c, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x2c, 0x20, + 0x70, 0x2c, 0x20, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x29, 0x3b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, + 0x65, 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x6c, 0x69, 0x74, + 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, + 0x3b, 0x0a, 0x7d, 0x00 }; const size_t ASSET_SIZE_SHADER_COMMON_UNIFORMS = 346; alignas(16) static const uint8_t ASSET_DATA_SHADER_COMMON_UNIFORMS[] = { @@ -371636,7 +371653,7 @@ alignas(16) static const uint8_t ASSET_DATA_SHADER_MATH_SDF_SHAPES[] = { 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64, 0x6f, 0x74, 0x28, 0x70, 0x2c, 0x20, 0x6e, 0x29, 0x20, 0x2b, 0x20, 0x68, 0x3b, 0x0a, 0x7d, 0x0a, 0x00 }; -const size_t ASSET_SIZE_SHADER_MATH_SDF_UTILS = 403; +const size_t ASSET_SIZE_SHADER_MATH_SDF_UTILS = 718; alignas(16) static const uint8_t ASSET_DATA_SHADER_MATH_SDF_UTILS[] = { 0x66, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x70, 0x3a, 0x20, 0x76, @@ -371671,7 +371688,33 @@ alignas(16) static const uint8_t ASSET_DATA_SHADER_MATH_SDF_UTILS[] = { 0x20, 0x2d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x28, 0x70, 0x20, 0x2d, 0x20, 0x65, 0x2e, 0x79, 0x79, 0x78, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x29, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x00 + 0x20, 0x29, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x44, + 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x61, + 0x6e, 0x20, 0x41, 0x78, 0x69, 0x73, 0x2d, 0x41, 0x6c, 0x69, 0x67, 0x6e, + 0x65, 0x64, 0x20, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, + 0x42, 0x6f, 0x78, 0x0a, 0x66, 0x6e, 0x20, 0x61, 0x61, 0x62, 0x62, 0x5f, + 0x73, 0x64, 0x66, 0x28, 0x70, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, + 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x20, 0x6d, 0x69, 0x6e, 0x5f, 0x70, 0x3a, + 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x20, + 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, + 0x66, 0x33, 0x32, 0x3e, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x66, 0x33, 0x32, + 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x63, + 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x28, 0x6d, 0x69, 0x6e, + 0x5f, 0x70, 0x20, 0x2b, 0x20, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x29, 0x20, + 0x2a, 0x20, 0x30, 0x2e, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x65, 0x74, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x3d, 0x20, + 0x28, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x20, 0x2d, 0x20, 0x6d, 0x69, 0x6e, + 0x5f, 0x70, 0x29, 0x20, 0x2a, 0x20, 0x30, 0x2e, 0x35, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, 0x20, 0x3d, 0x20, 0x61, + 0x62, 0x73, 0x28, 0x70, 0x20, 0x2d, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, + 0x72, 0x29, 0x20, 0x2d, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x6d, 0x61, 0x78, 0x28, 0x71, + 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, + 0x30, 0x2e, 0x30, 0x29, 0x29, 0x29, 0x20, 0x2b, 0x20, 0x6d, 0x69, 0x6e, + 0x28, 0x6d, 0x61, 0x78, 0x28, 0x71, 0x2e, 0x78, 0x2c, 0x20, 0x6d, 0x61, + 0x78, 0x28, 0x71, 0x2e, 0x79, 0x2c, 0x20, 0x71, 0x2e, 0x7a, 0x29, 0x29, + 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x00 }; const size_t ASSET_SIZE_SHADER_RENDER_SHADOWS = 441; alignas(16) static const uint8_t ASSET_DATA_SHADER_RENDER_SHADOWS[] = { @@ -371713,8 +371756,160 @@ alignas(16) static const uint8_t ASSET_DATA_SHADER_RENDER_SHADOWS[] = { 0x6d, 0x70, 0x28, 0x72, 0x65, 0x73, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x00 }; -const size_t ASSET_SIZE_SHADER_RENDER_SCENE_QUERY = 1220; -alignas(16) static const uint8_t ASSET_DATA_SHADER_RENDER_SCENE_QUERY[] = { +const size_t ASSET_SIZE_SHADER_RENDER_SCENE_QUERY_BVH = 1782; +alignas(16) static const uint8_t ASSET_DATA_SHADER_RENDER_SCENE_QUERY_BVH[] = { + 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, 0x6d, 0x61, + 0x74, 0x68, 0x2f, 0x73, 0x64, 0x66, 0x5f, 0x73, 0x68, 0x61, 0x70, 0x65, + 0x73, 0x22, 0x0a, 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, + 0x22, 0x6d, 0x61, 0x74, 0x68, 0x2f, 0x73, 0x64, 0x66, 0x5f, 0x75, 0x74, + 0x69, 0x6c, 0x73, 0x22, 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x20, 0x42, 0x56, 0x48, 0x4e, 0x6f, 0x64, 0x65, 0x20, 0x7b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x6d, 0x69, 0x6e, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, + 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x65, 0x66, 0x74, 0x5f, 0x69, 0x64, 0x78, 0x3a, 0x20, 0x69, 0x33, 0x32, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x78, 0x3a, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x69, 0x64, 0x78, 0x5f, 0x6f, 0x72, + 0x5f, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x69, 0x33, 0x32, 0x2c, + 0x0a, 0x7d, 0x3b, 0x0a, 0x0a, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, + 0x30, 0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, + 0x32, 0x29, 0x20, 0x76, 0x61, 0x72, 0x3c, 0x73, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x2c, 0x20, 0x72, 0x65, 0x61, 0x64, 0x3e, 0x20, 0x62, 0x76, + 0x68, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x3a, 0x20, 0x61, 0x72, 0x72, + 0x61, 0x79, 0x3c, 0x42, 0x56, 0x48, 0x4e, 0x6f, 0x64, 0x65, 0x3e, 0x3b, + 0x0a, 0x0a, 0x66, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x73, + 0x74, 0x28, 0x70, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, + 0x32, 0x3e, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x3a, 0x20, 0x66, 0x33, 0x32, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x66, 0x33, + 0x32, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, + 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, + 0x31, 0x2e, 0x30, 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x70, 0x29, 0x20, + 0x2d, 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x20, 0x7d, 0x20, 0x2f, 0x2f, 0x20, + 0x55, 0x6e, 0x69, 0x74, 0x20, 0x53, 0x70, 0x68, 0x65, 0x72, 0x65, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6f, 0x62, 0x6a, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x32, 0x2e, 0x30, 0x29, + 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x64, + 0x42, 0x6f, 0x78, 0x28, 0x70, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, + 0x66, 0x33, 0x32, 0x3e, 0x28, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x3b, 0x20, + 0x7d, 0x20, 0x2f, 0x2f, 0x20, 0x55, 0x6e, 0x69, 0x74, 0x20, 0x42, 0x6f, + 0x78, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6f, 0x62, + 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x33, 0x2e, + 0x30, 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x73, 0x64, 0x54, 0x6f, 0x72, 0x75, 0x73, 0x28, 0x70, 0x2c, 0x20, 0x76, + 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x30, 0x2e, 0x34, 0x29, 0x29, 0x3b, 0x20, 0x7d, 0x20, 0x2f, + 0x2f, 0x20, 0x55, 0x6e, 0x69, 0x74, 0x20, 0x54, 0x6f, 0x72, 0x75, 0x73, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6f, 0x62, 0x6a, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x34, 0x2e, 0x30, + 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, + 0x64, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x28, 0x70, 0x2c, 0x20, 0x76, 0x65, + 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x30, 0x2e, 0x30, 0x2c, + 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x2c, 0x20, + 0x30, 0x2e, 0x30, 0x29, 0x3b, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x30, 0x30, 0x2e, 0x30, + 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x66, 0x6e, 0x20, 0x6d, 0x61, 0x70, 0x5f, + 0x73, 0x63, 0x65, 0x6e, 0x65, 0x28, 0x70, 0x3a, 0x20, 0x76, 0x65, 0x63, + 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x20, 0x73, 0x6b, 0x69, 0x70, + 0x5f, 0x69, 0x64, 0x78, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x29, 0x20, 0x2d, + 0x3e, 0x20, 0x66, 0x33, 0x32, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x76, 0x61, 0x72, 0x20, 0x64, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x30, 0x30, + 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x3a, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, + 0x3c, 0x69, 0x33, 0x32, 0x2c, 0x20, 0x33, 0x32, 0x3e, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x5f, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x30, 0x3b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x61, + 0x72, 0x72, 0x61, 0x79, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x26, + 0x62, 0x76, 0x68, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x29, 0x20, 0x3e, + 0x20, 0x30, 0x75, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5b, 0x73, 0x74, 0x61, + 0x63, 0x6b, 0x5f, 0x70, 0x74, 0x72, 0x5d, 0x20, 0x3d, 0x20, 0x30, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, + 0x63, 0x6b, 0x5f, 0x70, 0x74, 0x72, 0x2b, 0x2b, 0x3b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x77, 0x68, 0x69, + 0x6c, 0x65, 0x20, 0x28, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x70, 0x74, + 0x72, 0x20, 0x3e, 0x20, 0x30, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x70, + 0x74, 0x72, 0x2d, 0x2d, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, + 0x64, 0x78, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5b, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x70, 0x74, 0x72, 0x5d, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6e, + 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x62, 0x76, 0x68, 0x5f, 0x6e, 0x6f, + 0x64, 0x65, 0x73, 0x5b, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x78, + 0x5d, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x28, 0x61, 0x61, 0x62, 0x62, 0x5f, 0x73, 0x64, 0x66, + 0x28, 0x70, 0x2c, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6d, 0x69, 0x6e, + 0x2c, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6d, 0x61, 0x78, 0x29, 0x20, + 0x3c, 0x20, 0x64, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6e, + 0x6f, 0x64, 0x65, 0x2e, 0x6c, 0x65, 0x66, 0x74, 0x5f, 0x69, 0x64, 0x78, + 0x20, 0x3c, 0x20, 0x30, 0x29, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x20, 0x4c, + 0x65, 0x61, 0x66, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, + 0x6f, 0x62, 0x6a, 0x5f, 0x69, 0x64, 0x78, 0x20, 0x3d, 0x20, 0x75, 0x33, + 0x32, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6f, 0x62, 0x6a, 0x5f, 0x69, + 0x64, 0x78, 0x5f, 0x6f, 0x72, 0x5f, 0x72, 0x69, 0x67, 0x68, 0x74, 0x29, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6f, 0x62, + 0x6a, 0x5f, 0x69, 0x64, 0x78, 0x20, 0x3d, 0x3d, 0x20, 0x73, 0x6b, 0x69, + 0x70, 0x5f, 0x69, 0x64, 0x78, 0x29, 0x20, 0x7b, 0x20, 0x63, 0x6f, 0x6e, + 0x74, 0x69, 0x6e, 0x75, 0x65, 0x3b, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6f, 0x62, 0x6a, 0x20, 0x3d, 0x20, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x5b, 0x6f, 0x62, 0x6a, 0x5f, 0x69, + 0x64, 0x78, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, + 0x20, 0x71, 0x20, 0x3d, 0x20, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x69, 0x6e, + 0x76, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x20, 0x2a, 0x20, 0x76, 0x65, + 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x70, 0x2c, 0x20, 0x31, + 0x2e, 0x30, 0x29, 0x29, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x6d, 0x69, + 0x6e, 0x28, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x6f, 0x62, 0x6a, + 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x30, 0x5d, 0x2e, 0x78, 0x79, + 0x7a, 0x29, 0x2c, 0x20, 0x6d, 0x69, 0x6e, 0x28, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, + 0x5b, 0x31, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x2c, 0x20, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x6d, 0x6f, 0x64, + 0x65, 0x6c, 0x5b, 0x32, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x29, 0x29, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x20, 0x3d, 0x20, 0x6d, 0x69, + 0x6e, 0x28, 0x64, 0x2c, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x73, + 0x74, 0x28, 0x71, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x2e, 0x78, 0x29, 0x20, 0x2a, 0x20, 0x73, 0x29, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x20, 0x2f, 0x2f, + 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, + 0x70, 0x74, 0x72, 0x20, 0x3c, 0x20, 0x33, 0x31, 0x29, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x63, + 0x6b, 0x5b, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x70, 0x74, 0x72, 0x5d, + 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6c, 0x65, 0x66, 0x74, + 0x5f, 0x69, 0x64, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x70, 0x74, 0x72, 0x2b, + 0x2b, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x5b, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x70, + 0x74, 0x72, 0x5d, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6f, + 0x62, 0x6a, 0x5f, 0x69, 0x64, 0x78, 0x5f, 0x6f, 0x72, 0x5f, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x70, 0x74, 0x72, 0x2b, 0x2b, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x64, 0x3b, 0x0a, 0x7d, 0x0a, 0x00 +}; +const size_t ASSET_SIZE_SHADER_RENDER_SCENE_QUERY_LINEAR = 959; +alignas(16) static const uint8_t ASSET_DATA_SHADER_RENDER_SCENE_QUERY_LINEAR[] = { 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, 0x6d, 0x61, 0x74, 0x68, 0x2f, 0x73, 0x64, 0x66, 0x5f, 0x73, 0x68, 0x61, 0x70, 0x65, 0x73, 0x22, 0x0a, 0x0a, 0x66, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x64, @@ -371772,51 +371967,29 @@ alignas(16) static const uint8_t ASSET_DATA_SHADER_RENDER_SCENE_QUERY[] = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x78, 0x3b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x53, - 0x6b, 0x69, 0x70, 0x20, 0x72, 0x61, 0x73, 0x74, 0x65, 0x72, 0x69, 0x7a, - 0x65, 0x64, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x20, 0x28, - 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x6c, 0x6f, - 0x6f, 0x72, 0x29, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x53, - 0x44, 0x46, 0x20, 0x6d, 0x61, 0x70, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6f, 0x62, 0x6a, 0x5f, 0x74, - 0x79, 0x70, 0x65, 0x20, 0x3c, 0x3d, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x20, - 0x7b, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x3b, 0x20, - 0x7d, 0x20, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x6c, 0x65, 0x74, 0x20, 0x71, 0x20, 0x3d, 0x20, 0x28, 0x6f, 0x62, 0x6a, - 0x2e, 0x69, 0x6e, 0x76, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x20, 0x2a, - 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x70, - 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x2e, 0x78, 0x79, 0x7a, 0x3b, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x73, 0x63, - 0x61, 0x6c, 0x65, 0x5f, 0x78, 0x20, 0x3d, 0x20, 0x6c, 0x65, 0x6e, 0x67, - 0x74, 0x68, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, - 0x5b, 0x30, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x73, 0x63, - 0x61, 0x6c, 0x65, 0x5f, 0x79, 0x20, 0x3d, 0x20, 0x6c, 0x65, 0x6e, 0x67, - 0x74, 0x68, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, - 0x5b, 0x31, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x73, 0x63, - 0x61, 0x6c, 0x65, 0x5f, 0x7a, 0x20, 0x3d, 0x20, 0x6c, 0x65, 0x6e, 0x67, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, + 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3c, 0x3d, 0x20, + 0x30, 0x2e, 0x30, 0x29, 0x20, 0x7b, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, + 0x6e, 0x75, 0x65, 0x3b, 0x20, 0x7d, 0x20, 0x0a, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, 0x20, 0x3d, + 0x20, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x69, 0x6e, 0x76, 0x5f, 0x6d, 0x6f, + 0x64, 0x65, 0x6c, 0x20, 0x2a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, + 0x33, 0x32, 0x3e, 0x28, 0x70, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, + 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x6d, 0x69, + 0x6e, 0x28, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x6f, 0x62, 0x6a, + 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x30, 0x5d, 0x2e, 0x78, 0x79, + 0x7a, 0x29, 0x2c, 0x20, 0x6d, 0x69, 0x6e, 0x28, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, - 0x5b, 0x32, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x55, 0x73, 0x65, - 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x76, - 0x65, 0x20, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x20, 0x73, 0x63, - 0x61, 0x6c, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, - 0x20, 0x6f, 0x76, 0x65, 0x72, 0x73, 0x74, 0x65, 0x70, 0x70, 0x69, 0x6e, - 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, - 0x63, 0x65, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x73, 0x20, 0x3d, - 0x20, 0x6d, 0x69, 0x6e, 0x28, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x5f, 0x78, - 0x2c, 0x20, 0x6d, 0x69, 0x6e, 0x28, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x5f, - 0x79, 0x2c, 0x20, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x5f, 0x7a, 0x29, 0x29, - 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x20, 0x3d, 0x20, 0x6d, - 0x69, 0x6e, 0x28, 0x64, 0x2c, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x69, - 0x73, 0x74, 0x28, 0x71, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x29, 0x20, 0x2a, 0x20, 0x73, 0x29, 0x3b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, - 0x72, 0x6e, 0x20, 0x64, 0x3b, 0x0a, 0x7d, 0x0a, 0x00 + 0x5b, 0x31, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x2c, 0x20, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x6d, 0x6f, 0x64, + 0x65, 0x6c, 0x5b, 0x32, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x29, 0x29, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x20, + 0x3d, 0x20, 0x6d, 0x69, 0x6e, 0x28, 0x64, 0x2c, 0x20, 0x67, 0x65, 0x74, + 0x5f, 0x64, 0x69, 0x73, 0x74, 0x28, 0x71, 0x2c, 0x20, 0x6f, 0x62, 0x6a, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x2a, 0x20, 0x73, 0x29, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64, 0x3b, 0x0a, 0x7d, 0x0a, 0x00 }; const size_t ASSET_SIZE_SHADER_RENDER_LIGHTING_UTILS = 330; alignas(16) static const uint8_t ASSET_DATA_SHADER_RENDER_LIGHTING_UTILS[] = { @@ -371849,6 +372022,350 @@ alignas(16) static const uint8_t ASSET_DATA_SHADER_RENDER_LIGHTING_UTILS[] = { 0x6c, 0x6f, 0x72, 0x20, 0x2a, 0x20, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x69, 0x6e, 0x67, 0x3b, 0x0a, 0x7d, 0x0a, 0x00 }; +const size_t ASSET_SIZE_SHADER_MESH = 1994; +alignas(16) static const uint8_t ASSET_DATA_SHADER_MESH[] = { + 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, + 0x73, 0x22, 0x0a, 0x0a, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x30, + 0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x30, + 0x29, 0x20, 0x76, 0x61, 0x72, 0x3c, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, + 0x6d, 0x3e, 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x3a, 0x20, + 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, + 0x6d, 0x73, 0x3b, 0x0a, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x30, + 0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x31, + 0x29, 0x20, 0x76, 0x61, 0x72, 0x3c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, + 0x65, 0x2c, 0x20, 0x72, 0x65, 0x61, 0x64, 0x3e, 0x20, 0x6f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x4f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x73, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x3b, + 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, + 0x20, 0x32, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x42, 0x56, 0x48, 0x20, 0x28, + 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x68, 0x65, 0x72, + 0x65, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, + 0x73, 0x20, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x20, 0x66, 0x6f, 0x72, + 0x20, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x79, 0x29, + 0x0a, 0x0a, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x30, 0x29, 0x20, + 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x33, 0x29, 0x20, + 0x76, 0x61, 0x72, 0x20, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x74, 0x65, + 0x78, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, + 0x64, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x3b, 0x0a, 0x40, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x28, 0x30, 0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x28, 0x34, 0x29, 0x20, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x6f, + 0x69, 0x73, 0x65, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x3a, + 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x3b, 0x0a, 0x40, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x28, 0x30, 0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, + 0x64, 0x69, 0x6e, 0x67, 0x28, 0x35, 0x29, 0x20, 0x76, 0x61, 0x72, 0x20, + 0x73, 0x6b, 0x79, 0x5f, 0x74, 0x65, 0x78, 0x3a, 0x20, 0x74, 0x65, 0x78, + 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, 0x3c, 0x66, 0x33, 0x32, 0x3e, + 0x3b, 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x56, 0x65, + 0x72, 0x74, 0x65, 0x78, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x30, 0x29, 0x20, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x31, 0x29, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, + 0x6c, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x32, 0x29, 0x20, 0x75, 0x76, 0x3a, 0x20, 0x76, + 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x7d, 0x3b, + 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x56, 0x65, 0x72, + 0x74, 0x65, 0x78, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x40, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, + 0x28, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x20, 0x63, + 0x6c, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x73, 0x3a, 0x20, 0x76, 0x65, 0x63, + 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x30, 0x29, + 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x3a, 0x20, + 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x31, 0x29, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x3a, 0x20, + 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x32, 0x29, 0x20, 0x75, 0x76, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x32, + 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, + 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x33, 0x29, 0x20, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, + 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x34, 0x29, 0x20, 0x40, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x65, 0x28, + 0x66, 0x6c, 0x61, 0x74, 0x29, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x20, 0x75, 0x33, + 0x32, 0x2c, 0x0a, 0x7d, 0x3b, 0x0a, 0x0a, 0x40, 0x76, 0x65, 0x72, 0x74, + 0x65, 0x78, 0x0a, 0x66, 0x6e, 0x20, 0x76, 0x73, 0x5f, 0x6d, 0x61, 0x69, + 0x6e, 0x28, 0x69, 0x6e, 0x3a, 0x20, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, + 0x49, 0x6e, 0x70, 0x75, 0x74, 0x2c, 0x20, 0x40, 0x62, 0x75, 0x69, 0x6c, + 0x74, 0x69, 0x6e, 0x28, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x29, 0x20, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x20, + 0x75, 0x33, 0x32, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x56, 0x65, 0x72, 0x74, + 0x65, 0x78, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6f, 0x62, 0x6a, 0x20, 0x3d, + 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x5b, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5d, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x77, 0x6f, + 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20, 0x6f, 0x62, + 0x6a, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x20, 0x2a, 0x20, 0x76, 0x65, + 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x69, 0x6e, 0x2e, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x31, 0x2e, 0x30, + 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x76, 0x61, 0x72, 0x20, 0x6f, 0x75, 0x74, 0x3a, 0x20, 0x56, 0x65, 0x72, + 0x74, 0x65, 0x78, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x2e, 0x63, 0x6c, 0x69, 0x70, 0x5f, + 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, + 0x73, 0x2e, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x20, + 0x2a, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x2e, 0x77, 0x6f, 0x72, + 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20, 0x77, 0x6f, 0x72, + 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, + 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x28, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x69, + 0x6e, 0x67, 0x20, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, + 0x63, 0x61, 0x6c, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x75, 0x73, 0x69, 0x6e, + 0x67, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x73, 0x65, 0x28, + 0x69, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x65, 0x28, 0x6d, 0x6f, 0x64, 0x65, + 0x6c, 0x29, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, + 0x46, 0x6f, 0x72, 0x20, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x63, 0x69, + 0x74, 0x79, 0x2c, 0x20, 0x77, 0x65, 0x20, 0x75, 0x73, 0x65, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x61, 0x74, 0x33, + 0x20, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x20, 0x61, 0x73, 0x20, 0x72, 0x65, + 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x5f, 0x33, 0x64, 0x2e, 0x77, 0x67, + 0x73, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6e, + 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x5f, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, + 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x33, 0x78, 0x33, 0x3c, 0x66, 0x33, + 0x32, 0x3e, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, + 0x5b, 0x30, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x2c, 0x20, 0x6f, 0x62, 0x6a, + 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x31, 0x5d, 0x2e, 0x78, 0x79, + 0x7a, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, + 0x5b, 0x32, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x6f, 0x75, 0x74, 0x2e, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, + 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, + 0x28, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x5f, 0x6d, 0x61, 0x74, 0x72, + 0x69, 0x78, 0x20, 0x2a, 0x20, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x72, 0x6d, + 0x61, 0x6c, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x6f, 0x75, 0x74, 0x2e, 0x75, 0x76, 0x20, 0x3d, 0x20, 0x69, + 0x6e, 0x2e, 0x75, 0x76, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, + 0x74, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x6f, 0x62, + 0x6a, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3d, 0x20, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6f, 0x75, 0x74, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x23, 0x69, 0x6e, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, 0x72, 0x65, 0x6e, 0x64, 0x65, + 0x72, 0x2f, 0x73, 0x63, 0x65, 0x6e, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0x0a, 0x23, 0x69, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, + 0x2f, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x73, 0x22, 0x0a, 0x23, 0x69, + 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, 0x72, 0x65, 0x6e, 0x64, + 0x65, 0x72, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x69, 0x6e, 0x67, 0x5f, + 0x75, 0x74, 0x69, 0x6c, 0x73, 0x22, 0x0a, 0x0a, 0x40, 0x66, 0x72, 0x61, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x0a, 0x66, 0x6e, 0x20, 0x66, 0x73, 0x5f, + 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x69, 0x6e, 0x3a, 0x20, 0x56, 0x65, 0x72, + 0x74, 0x65, 0x78, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x29, 0x20, 0x2d, + 0x3e, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x30, 0x29, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, + 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6c, + 0x69, 0x67, 0x68, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x20, 0x3d, 0x20, 0x6e, + 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x76, 0x65, 0x63, + 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x3b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, + 0x20, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x63, 0x61, + 0x6c, 0x63, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x28, 0x69, 0x6e, + 0x2e, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x2c, 0x20, + 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x2c, 0x20, 0x30, + 0x2e, 0x30, 0x35, 0x2c, 0x20, 0x32, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x69, + 0x6e, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x65, 0x74, 0x20, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x20, 0x3d, 0x20, 0x63, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x65, + 0x5f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x69, 0x6e, 0x67, 0x28, 0x69, 0x6e, + 0x2e, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x72, 0x67, 0x62, 0x2c, 0x20, + 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x2c, 0x20, 0x69, + 0x6e, 0x2e, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x2c, + 0x20, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x29, 0x3b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, + 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x69, + 0x6e, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x61, 0x29, 0x3b, 0x0a, + 0x7d, 0x0a, 0x00 +}; +const size_t ASSET_SIZE_MESH_CUBE = 920; +alignas(16) static const uint8_t ASSET_DATA_MESH_CUBE[] = { + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xbf, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xbf, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0xbf, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x80, 0xbf, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xbf, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00 +}; +const size_t ASSET_SIZE_DODECAHEDRON = 1080; +alignas(16) static const uint8_t ASSET_DATA_DODECAHEDRON[] = { + 0x14, 0x00, 0x00, 0x00, 0x36, 0xcd, 0x13, 0x3f, 0x36, 0xcd, 0x13, 0xbf, + 0x36, 0xcd, 0x13, 0x3f, 0x49, 0x2d, 0x30, 0x3f, 0x40, 0xc4, 0xd9, 0xbe, + 0x18, 0x79, 0x16, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe5, 0x25, 0x6f, 0x3f, 0x60, 0xb1, 0xb6, 0xbe, 0x00, 0x00, 0x00, 0x00, + 0x9b, 0x03, 0x4a, 0x3f, 0xfc, 0x3e, 0x1d, 0xbf, 0x8c, 0xd7, 0x39, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe5, 0x25, 0x6f, 0x3f, + 0x60, 0xb1, 0xb6, 0x3e, 0x00, 0x00, 0x00, 0x00, 0xeb, 0x25, 0x6f, 0x3f, + 0x62, 0xb1, 0xb6, 0x3e, 0x9e, 0xea, 0xd7, 0xaf, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0xb1, 0xb6, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0xe5, 0x25, 0x6f, 0x3f, 0x64, 0xb1, 0xb6, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0xeb, 0x25, 0x6f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0xcd, 0x13, 0x3f, 0x36, 0xcd, 0x13, 0x3f, 0x36, 0xcd, 0x13, 0x3f, + 0x3a, 0xcd, 0x13, 0x3f, 0x3a, 0xcd, 0x13, 0x3f, 0x3a, 0xcd, 0x13, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xb1, 0xb6, 0x3e, + 0x00, 0x00, 0x00, 0x00, 0xe5, 0x25, 0x6f, 0xbf, 0x6f, 0xab, 0x9b, 0x3e, + 0x14, 0x6b, 0xc0, 0xbd, 0x0f, 0xb1, 0x72, 0xbf, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x36, 0xcd, 0x13, 0x3f, 0x36, 0xcd, 0x13, 0x3f, + 0x36, 0xcd, 0x13, 0xbf, 0x3a, 0xcd, 0x13, 0x3f, 0x3a, 0xcd, 0x13, 0x3f, + 0x3a, 0xcd, 0x13, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0xcd, 0x13, 0x3f, 0x36, 0xcd, 0x13, 0xbf, 0x36, 0xcd, 0x13, 0xbf, + 0x48, 0x2d, 0x30, 0x3f, 0x40, 0xc4, 0xd9, 0xbe, 0x18, 0x79, 0x16, 0xbf, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0xcd, 0x13, 0xbf, + 0x36, 0xcd, 0x13, 0xbf, 0x36, 0xcd, 0x13, 0xbf, 0xc4, 0xd7, 0x0d, 0xbf, + 0xe8, 0x4b, 0xf2, 0xbe, 0xd2, 0x53, 0x2f, 0xbf, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe5, 0x25, 0x6f, 0xbf, 0x60, 0xb1, 0xb6, 0xbe, + 0x00, 0x00, 0x00, 0x00, 0x9b, 0x03, 0x4a, 0xbf, 0xfc, 0x3e, 0x1d, 0xbf, + 0x8c, 0xd7, 0x39, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe5, 0x25, 0x6f, 0xbf, 0x60, 0xb1, 0xb6, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0xeb, 0x25, 0x6f, 0xbf, 0x62, 0xb1, 0xb6, 0x3e, 0x9e, 0xea, 0xd7, 0x2f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xb1, 0xb6, 0xbe, + 0x00, 0x00, 0x00, 0x00, 0xe5, 0x25, 0x6f, 0xbf, 0x74, 0xb7, 0xd8, 0xbe, + 0x2f, 0xf0, 0x05, 0x3e, 0xae, 0x81, 0x65, 0xbf, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x36, 0xcd, 0x13, 0xbf, 0x36, 0xcd, 0x13, 0x3f, + 0x36, 0xcd, 0x13, 0xbf, 0x3a, 0xcd, 0x13, 0xbf, 0x3a, 0xcd, 0x13, 0x3f, + 0x3a, 0xcd, 0x13, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0xb1, 0xb6, 0xbe, 0x00, 0x00, 0x00, 0x00, 0xe5, 0x25, 0x6f, 0x3f, + 0x64, 0xb1, 0xb6, 0xbe, 0x00, 0x00, 0x00, 0x00, 0xeb, 0x25, 0x6f, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0xcd, 0x13, 0xbf, + 0x36, 0xcd, 0x13, 0x3f, 0x36, 0xcd, 0x13, 0x3f, 0x3a, 0xcd, 0x13, 0xbf, + 0x3a, 0xcd, 0x13, 0x3f, 0x3a, 0xcd, 0x13, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x36, 0xcd, 0x13, 0xbf, 0x36, 0xcd, 0x13, 0xbf, + 0x36, 0xcd, 0x13, 0x3f, 0x49, 0x2d, 0x30, 0xbf, 0x40, 0xc4, 0xd9, 0xbe, + 0x18, 0x79, 0x16, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe5, 0x25, 0x6f, 0x3f, 0x60, 0xb1, 0xb6, 0xbe, + 0xf3, 0xfb, 0x09, 0x30, 0x95, 0xd3, 0x63, 0x3f, 0x26, 0x81, 0xe9, 0xbe, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe5, 0x25, 0x6f, 0x3f, 0x60, 0xb1, 0xb6, 0x3e, 0xf3, 0xfb, 0x09, 0xb0, + 0x95, 0xd3, 0x63, 0x3f, 0x26, 0x81, 0xe9, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe5, 0x25, 0x6f, 0xbf, + 0x60, 0xb1, 0xb6, 0xbe, 0xec, 0xc5, 0x0d, 0x32, 0xeb, 0x25, 0x6f, 0xbf, + 0x65, 0xb1, 0xb6, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe5, 0x25, 0x6f, 0xbf, 0x60, 0xb1, 0xb6, 0x3e, + 0xf3, 0xfb, 0x09, 0x30, 0x95, 0xd3, 0x63, 0xbf, 0x26, 0x81, 0xe9, 0x3e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x00 +}; const AssetRecord* GetAssetRecordTable() { static const AssetRecord assets[] = { { ASSET_DATA_KICK_1, ASSET_SIZE_KICK_1, false, nullptr, nullptr, 0 }, @@ -371888,13 +372405,17 @@ const AssetRecord* GetAssetRecordTable() { { ASSET_DATA_SHADER_MATH_SDF_SHAPES, ASSET_SIZE_SHADER_MATH_SDF_SHAPES, false, nullptr, nullptr, 0 }, { ASSET_DATA_SHADER_MATH_SDF_UTILS, ASSET_SIZE_SHADER_MATH_SDF_UTILS, false, nullptr, nullptr, 0 }, { ASSET_DATA_SHADER_RENDER_SHADOWS, ASSET_SIZE_SHADER_RENDER_SHADOWS, false, nullptr, nullptr, 0 }, - { ASSET_DATA_SHADER_RENDER_SCENE_QUERY, ASSET_SIZE_SHADER_RENDER_SCENE_QUERY, false, nullptr, nullptr, 0 }, + { ASSET_DATA_SHADER_RENDER_SCENE_QUERY_BVH, ASSET_SIZE_SHADER_RENDER_SCENE_QUERY_BVH, false, nullptr, nullptr, 0 }, + { ASSET_DATA_SHADER_RENDER_SCENE_QUERY_LINEAR, ASSET_SIZE_SHADER_RENDER_SCENE_QUERY_LINEAR, false, nullptr, nullptr, 0 }, { ASSET_DATA_SHADER_RENDER_LIGHTING_UTILS, ASSET_SIZE_SHADER_RENDER_LIGHTING_UTILS, false, nullptr, nullptr, 0 }, + { ASSET_DATA_SHADER_MESH, ASSET_SIZE_SHADER_MESH, false, nullptr, nullptr, 0 }, + { ASSET_DATA_MESH_CUBE, ASSET_SIZE_MESH_CUBE, false, nullptr, nullptr, 0 }, + { ASSET_DATA_DODECAHEDRON, ASSET_SIZE_DODECAHEDRON, false, nullptr, nullptr, 0 }, }; return assets; } size_t GetAssetCount() { - return 39; + return 43; } diff --git a/src/generated/test_assets.h b/src/generated/test_assets.h index 7b66e75..04bda25 100644 --- a/src/generated/test_assets.h +++ b/src/generated/test_assets.h @@ -9,9 +9,22 @@ enum class AssetId : uint16_t { ASSET_SHADER_SNIPPET_A = 2, ASSET_SHADER_SNIPPET_B = 3, ASSET_PROC_NOISE_256 = 4, - ASSET_PROC_UNKNOWN = 5, - ASSET_PROC_FAIL = 6, - ASSET_LAST_ID = 7, + ASSET_TEST_IMAGE = 5, + ASSET_TEST_MESH = 6, + ASSET_PROC_UNKNOWN = 7, + ASSET_PROC_FAIL = 8, + ASSET_SHADER_MESH = 9, + ASSET_SHADER_RENDERER_3D = 10, + ASSET_SHADER_SKYBOX = 11, + ASSET_SHADER_COMMON_UNIFORMS = 12, + ASSET_SHADER_MATH_SDF_SHAPES = 13, + ASSET_SHADER_MATH_SDF_UTILS = 14, + ASSET_SHADER_RENDER_SHADOWS = 15, + ASSET_SHADER_RENDER_SCENE_QUERY_BVH = 16, + ASSET_SHADER_RENDER_SCENE_QUERY_LINEAR = 17, + ASSET_SHADER_RENDER_LIGHTING_UTILS = 18, + ASSET_SHADER_RAY_BOX = 19, + ASSET_LAST_ID = 20, }; #include "util/asset_manager.h" diff --git a/src/generated/test_assets_data.cc b/src/generated/test_assets_data.cc index bb222f0..90a6fc7 100644 --- a/src/generated/test_assets_data.cc +++ b/src/generated/test_assets_data.cc @@ -1,50 +1,135 @@ // This file is auto-generated by asset_packer.cc. Do not edit. -#include "test_assets.h" #include "util/asset_manager.h" -namespace procedural { -void gen_noise(uint8_t*, int, int, const float*, int); -} -namespace procedural { -void gen_grid(uint8_t*, int, int, const float*, int); -} -namespace procedural { -void make_periodic(uint8_t*, int, int, const float*, int); -} +#include "test_assets.h" +namespace procedural { void gen_noise(uint8_t*, int, int, const float*, int); } +namespace procedural { void gen_grid(uint8_t*, int, int, const float*, int); } +namespace procedural { void make_periodic(uint8_t*, int, int, const float*, int); } const size_t ASSET_SIZE_TEST_ASSET_1 = 101; alignas(16) static const uint8_t ASSET_DATA_TEST_ASSET_1[] = { - 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, - 0x73, 0x74, 0x20, 0x61, 0x73, 0x73, 0x65, 0x74, 0x20, 0x66, 0x69, 0x6c, - 0x65, 0x2e, 0x0a, 0x49, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x73, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x74, 0x65, 0x78, 0x74, - 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x74, 0x6f, 0x20, 0x76, 0x65, 0x72, - 0x69, 0x66, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x73, 0x73, 0x65, - 0x74, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x0a, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, - 0x37, 0x38, 0x39, 0x30, 0x0a, 0x00}; + 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, + 0x73, 0x74, 0x20, 0x61, 0x73, 0x73, 0x65, 0x74, 0x20, 0x66, 0x69, 0x6c, + 0x65, 0x2e, 0x0a, 0x49, 0x74, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x73, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x74, 0x65, 0x78, 0x74, + 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x74, 0x6f, 0x20, 0x76, 0x65, 0x72, + 0x69, 0x66, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x61, 0x73, 0x73, 0x65, + 0x74, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x2e, 0x0a, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, + 0x37, 0x38, 0x39, 0x30, 0x0a, 0x00 +}; const size_t ASSET_SIZE_NULL_ASSET = 0; -alignas(16) static const uint8_t ASSET_DATA_NULL_ASSET[] = {0x00}; +alignas(16) static const uint8_t ASSET_DATA_NULL_ASSET[] = { + 0x00 +}; const size_t ASSET_SIZE_SHADER_SNIPPET_A = 65; alignas(16) static const uint8_t ASSET_DATA_SHADER_SNIPPET_A[] = { - 0x2f, 0x2f, 0x20, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6e, 0x69, - 0x70, 0x70, 0x65, 0x74, 0x5f, 0x61, 0x2e, 0x77, 0x67, 0x73, 0x6c, - 0x0a, 0x66, 0x6e, 0x20, 0x73, 0x6e, 0x69, 0x70, 0x70, 0x65, 0x74, - 0x5f, 0x61, 0x28, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x66, 0x33, 0x32, - 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, - 0x72, 0x6e, 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x0a, 0x7d, 0x0a, 0x00}; + 0x2f, 0x2f, 0x20, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6e, 0x69, 0x70, + 0x70, 0x65, 0x74, 0x5f, 0x61, 0x2e, 0x77, 0x67, 0x73, 0x6c, 0x0a, 0x66, + 0x6e, 0x20, 0x73, 0x6e, 0x69, 0x70, 0x70, 0x65, 0x74, 0x5f, 0x61, 0x28, + 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x66, 0x33, 0x32, 0x20, 0x7b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x2e, + 0x30, 0x3b, 0x0a, 0x7d, 0x0a, 0x00 +}; const size_t ASSET_SIZE_SHADER_SNIPPET_B = 65; alignas(16) static const uint8_t ASSET_DATA_SHADER_SNIPPET_B[] = { - 0x2f, 0x2f, 0x20, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6e, 0x69, - 0x70, 0x70, 0x65, 0x74, 0x5f, 0x62, 0x2e, 0x77, 0x67, 0x73, 0x6c, - 0x0a, 0x66, 0x6e, 0x20, 0x73, 0x6e, 0x69, 0x70, 0x70, 0x65, 0x74, - 0x5f, 0x62, 0x28, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x66, 0x33, 0x32, - 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, - 0x72, 0x6e, 0x20, 0x32, 0x2e, 0x30, 0x3b, 0x0a, 0x7d, 0x0a, 0x00}; + 0x2f, 0x2f, 0x20, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x73, 0x6e, 0x69, 0x70, + 0x70, 0x65, 0x74, 0x5f, 0x62, 0x2e, 0x77, 0x67, 0x73, 0x6c, 0x0a, 0x66, + 0x6e, 0x20, 0x73, 0x6e, 0x69, 0x70, 0x70, 0x65, 0x74, 0x5f, 0x62, 0x28, + 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x66, 0x33, 0x32, 0x20, 0x7b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x32, 0x2e, + 0x30, 0x3b, 0x0a, 0x7d, 0x0a, 0x00 +}; static const float ASSET_PROC_PARAMS_PROC_NOISE_256[] = {4321.000000, 8.000000}; static const char* ASSET_PROC_FUNC_STR_PROC_NOISE_256 = "gen_noise"; +const size_t ASSET_SIZE_TEST_IMAGE = 24; +alignas(16) static const uint8_t ASSET_DATA_TEST_IMAGE[] = { + 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00 +}; +const size_t ASSET_SIZE_TEST_MESH = 920; +alignas(16) static const uint8_t ASSET_DATA_TEST_MESH[] = { + 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xbf, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xbf, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0xbf, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x80, 0xbf, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xbf, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbf, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x3f, + 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00 +}; static const float ASSET_PROC_PARAMS_PROC_UNKNOWN[] = {0.000000}; static const char* ASSET_PROC_FUNC_STR_PROC_UNKNOWN = "gen_unknown_func"; @@ -53,26 +138,1462 @@ static const float ASSET_PROC_PARAMS_PROC_FAIL[] = {-1337.000000, 8.000000}; static const char* ASSET_PROC_FUNC_STR_PROC_FAIL = "gen_noise"; +const size_t ASSET_SIZE_SHADER_MESH = 1994; +alignas(16) static const uint8_t ASSET_DATA_SHADER_MESH[] = { + 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, + 0x73, 0x22, 0x0a, 0x0a, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x30, + 0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x30, + 0x29, 0x20, 0x76, 0x61, 0x72, 0x3c, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, + 0x6d, 0x3e, 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x3a, 0x20, + 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, + 0x6d, 0x73, 0x3b, 0x0a, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x30, + 0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x31, + 0x29, 0x20, 0x76, 0x61, 0x72, 0x3c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, + 0x65, 0x2c, 0x20, 0x72, 0x65, 0x61, 0x64, 0x3e, 0x20, 0x6f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x4f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x73, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x3b, + 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, + 0x20, 0x32, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x42, 0x56, 0x48, 0x20, 0x28, + 0x6e, 0x6f, 0x74, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x68, 0x65, 0x72, + 0x65, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, + 0x73, 0x20, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x20, 0x66, 0x6f, 0x72, + 0x20, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x79, 0x29, + 0x0a, 0x0a, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x30, 0x29, 0x20, + 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x33, 0x29, 0x20, + 0x76, 0x61, 0x72, 0x20, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x74, 0x65, + 0x78, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, + 0x64, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x3b, 0x0a, 0x40, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x28, 0x30, 0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x28, 0x34, 0x29, 0x20, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x6f, + 0x69, 0x73, 0x65, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x3a, + 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x3b, 0x0a, 0x40, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x28, 0x30, 0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, + 0x64, 0x69, 0x6e, 0x67, 0x28, 0x35, 0x29, 0x20, 0x76, 0x61, 0x72, 0x20, + 0x73, 0x6b, 0x79, 0x5f, 0x74, 0x65, 0x78, 0x3a, 0x20, 0x74, 0x65, 0x78, + 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, 0x3c, 0x66, 0x33, 0x32, 0x3e, + 0x3b, 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x56, 0x65, + 0x72, 0x74, 0x65, 0x78, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x30, 0x29, 0x20, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x31, 0x29, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, + 0x6c, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x32, 0x29, 0x20, 0x75, 0x76, 0x3a, 0x20, 0x76, + 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x7d, 0x3b, + 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x56, 0x65, 0x72, + 0x74, 0x65, 0x78, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x40, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, + 0x28, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x20, 0x63, + 0x6c, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x73, 0x3a, 0x20, 0x76, 0x65, 0x63, + 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x30, 0x29, + 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x3a, 0x20, + 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x31, 0x29, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x3a, 0x20, + 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x32, 0x29, 0x20, 0x75, 0x76, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x32, + 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, + 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x33, 0x29, 0x20, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, + 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x34, 0x29, 0x20, 0x40, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x65, 0x28, + 0x66, 0x6c, 0x61, 0x74, 0x29, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x20, 0x75, 0x33, + 0x32, 0x2c, 0x0a, 0x7d, 0x3b, 0x0a, 0x0a, 0x40, 0x76, 0x65, 0x72, 0x74, + 0x65, 0x78, 0x0a, 0x66, 0x6e, 0x20, 0x76, 0x73, 0x5f, 0x6d, 0x61, 0x69, + 0x6e, 0x28, 0x69, 0x6e, 0x3a, 0x20, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, + 0x49, 0x6e, 0x70, 0x75, 0x74, 0x2c, 0x20, 0x40, 0x62, 0x75, 0x69, 0x6c, + 0x74, 0x69, 0x6e, 0x28, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x29, 0x20, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x20, + 0x75, 0x33, 0x32, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x56, 0x65, 0x72, 0x74, + 0x65, 0x78, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6f, 0x62, 0x6a, 0x20, 0x3d, + 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x5b, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5d, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x77, 0x6f, + 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20, 0x6f, 0x62, + 0x6a, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x20, 0x2a, 0x20, 0x76, 0x65, + 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x69, 0x6e, 0x2e, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x31, 0x2e, 0x30, + 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x76, 0x61, 0x72, 0x20, 0x6f, 0x75, 0x74, 0x3a, 0x20, 0x56, 0x65, 0x72, + 0x74, 0x65, 0x78, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x2e, 0x63, 0x6c, 0x69, 0x70, 0x5f, + 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, + 0x73, 0x2e, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x20, + 0x2a, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x2e, 0x77, 0x6f, 0x72, + 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20, 0x77, 0x6f, 0x72, + 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, + 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x28, 0x61, 0x73, 0x73, 0x75, 0x6d, 0x69, + 0x6e, 0x67, 0x20, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, + 0x63, 0x61, 0x6c, 0x65, 0x20, 0x6f, 0x72, 0x20, 0x75, 0x73, 0x69, 0x6e, + 0x67, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x73, 0x65, 0x28, + 0x69, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x65, 0x28, 0x6d, 0x6f, 0x64, 0x65, + 0x6c, 0x29, 0x29, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, + 0x46, 0x6f, 0x72, 0x20, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x69, 0x63, 0x69, + 0x74, 0x79, 0x2c, 0x20, 0x77, 0x65, 0x20, 0x75, 0x73, 0x65, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x73, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x61, 0x74, 0x33, + 0x20, 0x6c, 0x6f, 0x67, 0x69, 0x63, 0x20, 0x61, 0x73, 0x20, 0x72, 0x65, + 0x6e, 0x64, 0x65, 0x72, 0x65, 0x72, 0x5f, 0x33, 0x64, 0x2e, 0x77, 0x67, + 0x73, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6e, + 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x5f, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, + 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x33, 0x78, 0x33, 0x3c, 0x66, 0x33, + 0x32, 0x3e, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, + 0x5b, 0x30, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x2c, 0x20, 0x6f, 0x62, 0x6a, + 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x31, 0x5d, 0x2e, 0x78, 0x79, + 0x7a, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, + 0x5b, 0x32, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x6f, 0x75, 0x74, 0x2e, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, + 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, + 0x28, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x5f, 0x6d, 0x61, 0x74, 0x72, + 0x69, 0x78, 0x20, 0x2a, 0x20, 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x72, 0x6d, + 0x61, 0x6c, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x6f, 0x75, 0x74, 0x2e, 0x75, 0x76, 0x20, 0x3d, 0x20, 0x69, + 0x6e, 0x2e, 0x75, 0x76, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, + 0x74, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x6f, 0x62, + 0x6a, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x6f, 0x75, 0x74, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3d, 0x20, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6f, 0x75, 0x74, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x23, 0x69, 0x6e, + 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, 0x72, 0x65, 0x6e, 0x64, 0x65, + 0x72, 0x2f, 0x73, 0x63, 0x65, 0x6e, 0x65, 0x5f, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0x0a, 0x23, 0x69, 0x6e, 0x63, + 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, + 0x2f, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x73, 0x22, 0x0a, 0x23, 0x69, + 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, 0x72, 0x65, 0x6e, 0x64, + 0x65, 0x72, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x69, 0x6e, 0x67, 0x5f, + 0x75, 0x74, 0x69, 0x6c, 0x73, 0x22, 0x0a, 0x0a, 0x40, 0x66, 0x72, 0x61, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x0a, 0x66, 0x6e, 0x20, 0x66, 0x73, 0x5f, + 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x69, 0x6e, 0x3a, 0x20, 0x56, 0x65, 0x72, + 0x74, 0x65, 0x78, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x29, 0x20, 0x2d, + 0x3e, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x30, 0x29, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, + 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6c, + 0x69, 0x67, 0x68, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x20, 0x3d, 0x20, 0x6e, + 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x76, 0x65, 0x63, + 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x3b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, + 0x20, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x63, 0x61, + 0x6c, 0x63, 0x5f, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x28, 0x69, 0x6e, + 0x2e, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x2c, 0x20, + 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x2c, 0x20, 0x30, + 0x2e, 0x30, 0x35, 0x2c, 0x20, 0x32, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x69, + 0x6e, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x65, 0x74, 0x20, 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x20, 0x3d, 0x20, 0x63, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x65, + 0x5f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x69, 0x6e, 0x67, 0x28, 0x69, 0x6e, + 0x2e, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x72, 0x67, 0x62, 0x2c, 0x20, + 0x69, 0x6e, 0x2e, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x2c, 0x20, 0x69, + 0x6e, 0x2e, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x2c, + 0x20, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x29, 0x3b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, + 0x6c, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x69, + 0x6e, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x61, 0x29, 0x3b, 0x0a, + 0x7d, 0x0a, 0x00 +}; +const size_t ASSET_SIZE_SHADER_RENDERER_3D = 7683; +alignas(16) static const uint8_t ASSET_DATA_SHADER_RENDERER_3D[] = { + 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, + 0x73, 0x22, 0x0a, 0x0a, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x30, + 0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x30, + 0x29, 0x20, 0x76, 0x61, 0x72, 0x3c, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, + 0x6d, 0x3e, 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x3a, 0x20, + 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, + 0x6d, 0x73, 0x3b, 0x0a, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x30, + 0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x31, + 0x29, 0x20, 0x76, 0x61, 0x72, 0x3c, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, + 0x65, 0x2c, 0x20, 0x72, 0x65, 0x61, 0x64, 0x3e, 0x20, 0x6f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x4f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x73, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x3b, + 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, + 0x20, 0x32, 0x20, 0x69, 0x73, 0x20, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x42, 0x56, 0x48, 0x20, 0x62, + 0x75, 0x66, 0x66, 0x65, 0x72, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x0a, 0x0a, 0x40, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x28, 0x30, 0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x28, 0x33, 0x29, 0x20, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x6f, + 0x69, 0x73, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x3a, 0x20, 0x74, 0x65, 0x78, + 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, 0x64, 0x3c, 0x66, 0x33, 0x32, 0x3e, + 0x3b, 0x0a, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x30, 0x29, 0x20, + 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x34, 0x29, 0x20, + 0x76, 0x61, 0x72, 0x20, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x73, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x3a, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, + 0x65, 0x72, 0x3b, 0x0a, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x30, + 0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x35, + 0x29, 0x20, 0x76, 0x61, 0x72, 0x20, 0x73, 0x6b, 0x79, 0x5f, 0x74, 0x65, + 0x78, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, + 0x64, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x3b, 0x0a, 0x0a, 0x73, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x20, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x4f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, + 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x28, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x20, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, + 0x3e, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x30, 0x29, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x5f, 0x70, 0x6f, 0x73, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, + 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x31, 0x29, 0x20, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, + 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, 0x6c, 0x6f, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x32, 0x29, 0x20, 0x40, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x66, + 0x6c, 0x61, 0x74, 0x29, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x20, 0x75, 0x33, 0x32, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x33, 0x29, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, + 0x5f, 0x70, 0x6f, 0x73, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, + 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x7d, 0x3b, 0x0a, 0x0a, 0x40, 0x76, 0x65, + 0x72, 0x74, 0x65, 0x78, 0x0a, 0x66, 0x6e, 0x20, 0x76, 0x73, 0x5f, 0x6d, + 0x61, 0x69, 0x6e, 0x28, 0x40, 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, + 0x28, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x29, 0x20, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6e, + 0x64, 0x65, 0x78, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x2c, 0x20, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x40, 0x62, + 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x28, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x29, 0x20, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x56, + 0x65, 0x72, 0x74, 0x65, 0x78, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, + 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, + 0x61, 0x72, 0x20, 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20, 0x61, 0x72, 0x72, + 0x61, 0x79, 0x3c, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, + 0x2c, 0x20, 0x33, 0x36, 0x3e, 0x28, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, 0x20, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, + 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x20, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x28, + 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x29, 0x3b, + 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x70, 0x20, + 0x3d, 0x20, 0x70, 0x6f, 0x73, 0x5b, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, + 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6f, 0x62, 0x6a, 0x20, 0x3d, 0x20, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x5b, 0x69, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5d, 0x3b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6f, 0x62, 0x6a, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x78, 0x3b, 0x0a, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x35, 0x2e, 0x30, 0x29, 0x20, 0x7b, + 0x20, 0x2f, 0x2f, 0x20, 0x4d, 0x45, 0x53, 0x48, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x75, 0x74, + 0x3a, 0x20, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x4f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6f, 0x75, 0x74, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, + 0x28, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x30, + 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6f, 0x75, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x54, 0x69, 0x67, 0x68, + 0x74, 0x20, 0x66, 0x69, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x54, 0x6f, + 0x72, 0x75, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x20, 0x68, 0x75, + 0x6c, 0x6c, 0x20, 0x28, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x20, 0x72, 0x61, + 0x64, 0x69, 0x75, 0x73, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x6d, 0x69, + 0x6e, 0x6f, 0x72, 0x20, 0x30, 0x2e, 0x34, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x69, 0x66, 0x20, 0x28, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x33, 0x2e, 0x30, 0x29, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x2e, 0x78, 0x20, + 0x3d, 0x20, 0x70, 0x2e, 0x78, 0x20, 0x2a, 0x20, 0x31, 0x2e, 0x35, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x2e, 0x7a, + 0x20, 0x3d, 0x20, 0x70, 0x2e, 0x7a, 0x20, 0x2a, 0x20, 0x31, 0x2e, 0x35, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x2e, + 0x79, 0x20, 0x3d, 0x20, 0x70, 0x2e, 0x79, 0x20, 0x2a, 0x20, 0x30, 0x2e, + 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, + 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x6d, 0x6f, + 0x64, 0x65, 0x6c, 0x20, 0x2a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, + 0x33, 0x32, 0x3e, 0x28, 0x70, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x63, 0x6c, 0x69, + 0x70, 0x5f, 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x6c, 0x6f, 0x62, + 0x61, 0x6c, 0x73, 0x2e, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x6f, + 0x6a, 0x20, 0x2a, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, + 0x73, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, + 0x6f, 0x75, 0x74, 0x3a, 0x20, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x4f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x3d, 0x20, 0x63, 0x6c, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x73, 0x3b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x2e, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x5f, 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20, 0x70, 0x3b, 0x20, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x20, 0x3d, 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, 0x75, 0x74, 0x2e, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x6f, 0x75, 0x74, 0x2e, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, + 0x73, 0x20, 0x3d, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, + 0x73, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x75, 0x74, 0x3b, 0x0a, 0x7d, + 0x0a, 0x0a, 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, + 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x2f, 0x73, 0x63, 0x65, 0x6e, 0x65, + 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x22, + 0x0a, 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, 0x72, + 0x65, 0x6e, 0x64, 0x65, 0x72, 0x2f, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, + 0x73, 0x22, 0x0a, 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, + 0x22, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x2f, 0x6c, 0x69, 0x67, 0x68, + 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x75, 0x74, 0x69, 0x6c, 0x73, 0x22, 0x0a, + 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, 0x72, 0x61, + 0x79, 0x5f, 0x62, 0x6f, 0x78, 0x22, 0x0a, 0x0a, 0x40, 0x66, 0x72, 0x61, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x0a, 0x66, 0x6e, 0x20, 0x66, 0x73, 0x5f, + 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x69, 0x6e, 0x3a, 0x20, 0x56, 0x65, 0x72, + 0x74, 0x65, 0x78, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x29, 0x20, 0x2d, + 0x3e, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x30, 0x29, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, + 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6f, + 0x62, 0x6a, 0x20, 0x3d, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, + 0x5b, 0x69, 0x6e, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x3d, 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x73, 0x2e, 0x78, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, + 0x61, 0x72, 0x20, 0x70, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, + 0x33, 0x32, 0x3e, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, + 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x3a, 0x20, 0x76, 0x65, 0x63, + 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x76, 0x61, 0x72, 0x20, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x2e, 0x72, 0x67, 0x62, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x65, 0x74, 0x20, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x64, 0x69, 0x72, + 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, + 0x28, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, + 0x29, 0x29, 0x3b, 0x20, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, + 0x20, 0x28, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3c, + 0x3d, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x20, + 0x52, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x70, 0x61, 0x74, 0x68, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x20, 0x3d, 0x20, + 0x69, 0x6e, 0x2e, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, + 0x74, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, + 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, + 0x7a, 0x65, 0x28, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x28, 0x64, 0x70, 0x64, + 0x78, 0x28, 0x69, 0x6e, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, + 0x6f, 0x73, 0x29, 0x2c, 0x20, 0x64, 0x70, 0x64, 0x79, 0x28, 0x69, 0x6e, + 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x6f, 0x73, 0x29, 0x29, + 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x65, 0x74, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x5f, 0x6d, 0x61, + 0x74, 0x72, 0x69, 0x78, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x33, 0x78, + 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x69, + 0x6e, 0x76, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x30, 0x5d, 0x2e, + 0x78, 0x79, 0x7a, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x69, 0x6e, 0x76, + 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x31, 0x5d, 0x2e, 0x78, 0x79, + 0x7a, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x69, 0x6e, 0x76, 0x5f, 0x6d, + 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x32, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x29, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x6f, + 0x72, 0x6d, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, + 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, + 0x73, 0x65, 0x28, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x5f, 0x6d, 0x61, + 0x74, 0x72, 0x69, 0x78, 0x29, 0x20, 0x2a, 0x20, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x29, 0x3b, 0x0a, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x41, + 0x70, 0x70, 0x6c, 0x79, 0x20, 0x67, 0x72, 0x69, 0x64, 0x20, 0x70, 0x61, + 0x74, 0x74, 0x65, 0x72, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x6c, 0x6f, + 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x65, 0x74, 0x20, 0x75, 0x76, 0x20, 0x3d, 0x20, 0x70, 0x2e, 0x78, 0x7a, + 0x20, 0x2a, 0x20, 0x30, 0x2e, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x67, 0x72, 0x69, 0x64, + 0x20, 0x3d, 0x20, 0x30, 0x2e, 0x35, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, + 0x20, 0x2a, 0x20, 0x73, 0x69, 0x6e, 0x28, 0x75, 0x76, 0x2e, 0x78, 0x20, + 0x2a, 0x20, 0x33, 0x2e, 0x31, 0x34, 0x29, 0x20, 0x2a, 0x20, 0x73, 0x69, + 0x6e, 0x28, 0x75, 0x76, 0x2e, 0x79, 0x20, 0x2a, 0x20, 0x33, 0x2e, 0x31, + 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6c, 0x65, 0x74, 0x20, 0x67, 0x72, 0x69, 0x64, 0x5f, 0x76, 0x61, 0x6c, + 0x20, 0x3d, 0x20, 0x73, 0x6d, 0x6f, 0x6f, 0x74, 0x68, 0x73, 0x74, 0x65, + 0x70, 0x28, 0x30, 0x2e, 0x34, 0x35, 0x2c, 0x20, 0x30, 0x2e, 0x35, 0x35, + 0x2c, 0x20, 0x67, 0x72, 0x69, 0x64, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x2a, 0x20, 0x28, 0x30, 0x2e, 0x35, 0x20, + 0x2b, 0x20, 0x30, 0x2e, 0x35, 0x20, 0x2a, 0x20, 0x67, 0x72, 0x69, 0x64, + 0x5f, 0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, + 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x20, 0x53, + 0x44, 0x46, 0x20, 0x70, 0x61, 0x74, 0x68, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x72, 0x6f, 0x5f, 0x77, + 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x3d, 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x73, 0x2e, 0x63, 0x61, 0x6d, 0x65, 0x72, 0x61, 0x5f, 0x70, 0x6f, + 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, + 0x72, 0x64, 0x5f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x3d, 0x20, 0x6e, + 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x69, 0x6e, 0x2e, + 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x20, 0x2d, 0x20, + 0x72, 0x6f, 0x5f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x29, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x52, 0x61, 0x79, 0x2d, 0x42, + 0x6f, 0x78, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x66, 0x69, + 0x6e, 0x64, 0x20, 0x74, 0x69, 0x67, 0x68, 0x74, 0x20, 0x62, 0x6f, 0x75, + 0x6e, 0x64, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6c, 0x65, 0x74, 0x20, 0x72, 0x6f, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x20, 0x3d, 0x20, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x69, 0x6e, 0x76, 0x5f, + 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x20, 0x2a, 0x20, 0x76, 0x65, 0x63, 0x34, + 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x72, 0x6f, 0x5f, 0x77, 0x6f, 0x72, + 0x6c, 0x64, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x2e, 0x78, 0x79, + 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x65, 0x74, 0x20, 0x72, 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, + 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, + 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x69, 0x6e, 0x76, 0x5f, 0x6d, 0x6f, 0x64, + 0x65, 0x6c, 0x20, 0x2a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, 0x33, + 0x32, 0x3e, 0x28, 0x72, 0x64, 0x5f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2c, + 0x20, 0x30, 0x2e, 0x30, 0x29, 0x29, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x50, 0x72, 0x6f, + 0x78, 0x79, 0x20, 0x62, 0x6f, 0x78, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, + 0x74, 0x20, 0x28, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x20, 0x76, + 0x73, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x65, 0x78, 0x74, 0x65, + 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, + 0x32, 0x3e, 0x28, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6f, 0x62, 0x6a, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x33, 0x2e, 0x30, + 0x29, 0x20, 0x7b, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x3d, + 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x31, + 0x2e, 0x35, 0x2c, 0x20, 0x30, 0x2e, 0x35, 0x2c, 0x20, 0x31, 0x2e, 0x35, + 0x29, 0x3b, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, + 0x74, 0x20, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x20, 0x3d, 0x20, 0x72, + 0x61, 0x79, 0x5f, 0x62, 0x6f, 0x78, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x72, 0x6f, 0x5f, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x2c, 0x20, 0x72, 0x64, 0x5f, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x2c, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x29, 0x3b, + 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, + 0x20, 0x28, 0x21, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x2e, 0x68, 0x69, + 0x74, 0x29, 0x20, 0x7b, 0x20, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, + 0x3b, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x76, 0x61, 0x72, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x62, 0x6f, 0x75, + 0x6e, 0x64, 0x73, 0x2e, 0x74, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, + 0x20, 0x68, 0x69, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, + 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x36, 0x34, 0x3b, 0x20, 0x69, 0x20, + 0x3d, 0x20, 0x69, 0x20, 0x2b, 0x20, 0x31, 0x29, 0x20, 0x7b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x65, 0x74, 0x20, 0x71, 0x20, 0x3d, 0x20, 0x72, 0x6f, 0x5f, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x2b, 0x20, 0x72, 0x64, 0x5f, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x2a, 0x20, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, + 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x67, 0x65, + 0x74, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x28, 0x71, 0x2c, 0x20, 0x6f, 0x62, + 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, + 0x28, 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x3c, 0x20, 0x30, + 0x2e, 0x30, 0x30, 0x30, 0x35, 0x29, 0x20, 0x7b, 0x20, 0x68, 0x69, 0x74, + 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x3b, 0x20, 0x62, 0x72, 0x65, + 0x61, 0x6b, 0x3b, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x74, 0x20, + 0x2b, 0x20, 0x64, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, + 0x66, 0x20, 0x28, 0x74, 0x20, 0x3e, 0x20, 0x62, 0x6f, 0x75, 0x6e, 0x64, + 0x73, 0x2e, 0x74, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x29, 0x20, 0x7b, 0x20, + 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x68, 0x69, 0x74, 0x29, + 0x20, 0x7b, 0x20, 0x64, 0x69, 0x73, 0x63, 0x61, 0x72, 0x64, 0x3b, 0x20, + 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, + 0x5f, 0x68, 0x69, 0x74, 0x20, 0x3d, 0x20, 0x72, 0x6f, 0x5f, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x20, 0x2b, 0x20, 0x72, 0x64, 0x5f, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x20, 0x2a, 0x20, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x70, 0x20, 0x3d, 0x20, 0x28, 0x6f, 0x62, 0x6a, + 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x20, 0x2a, 0x20, 0x76, 0x65, 0x63, + 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x71, 0x5f, 0x68, 0x69, 0x74, + 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x2e, 0x78, 0x79, 0x7a, 0x3b, + 0x20, 0x2f, 0x2f, 0x20, 0x43, 0x6f, 0x72, 0x72, 0x65, 0x63, 0x74, 0x20, + 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x43, + 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x20, 0x6e, 0x6f, 0x72, + 0x6d, 0x61, 0x6c, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x62, 0x75, 0x6d, + 0x70, 0x20, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x65, 0x20, + 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, + 0x30, 0x2e, 0x30, 0x30, 0x35, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, + 0x20, 0x64, 0x69, 0x73, 0x70, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x20, 0x3d, 0x20, 0x30, 0x2e, 0x30, 0x35, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, 0x5f, 0x78, 0x31, + 0x20, 0x3d, 0x20, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x20, 0x2b, 0x20, 0x65, + 0x2e, 0x78, 0x79, 0x79, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x75, 0x76, 0x5f, 0x78, 0x31, 0x20, + 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, + 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x71, 0x5f, 0x78, 0x31, 0x2e, 0x78, + 0x2c, 0x20, 0x71, 0x5f, 0x78, 0x31, 0x2e, 0x7a, 0x29, 0x20, 0x2f, 0x20, + 0x36, 0x2e, 0x32, 0x38, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, 0x2c, 0x20, + 0x61, 0x63, 0x6f, 0x73, 0x28, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x28, 0x71, + 0x5f, 0x78, 0x31, 0x2e, 0x79, 0x20, 0x2f, 0x20, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x28, 0x71, 0x5f, 0x78, 0x31, 0x29, 0x2c, 0x20, 0x2d, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x20, 0x2f, 0x20, + 0x33, 0x2e, 0x31, 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x68, 0x5f, 0x78, 0x31, 0x20, + 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x53, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x28, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x74, 0x65, + 0x78, 0x2c, 0x20, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x73, 0x61, 0x6d, + 0x70, 0x6c, 0x65, 0x72, 0x2c, 0x20, 0x75, 0x76, 0x5f, 0x78, 0x31, 0x29, + 0x2e, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6c, 0x65, 0x74, 0x20, 0x64, 0x5f, 0x78, 0x31, 0x20, 0x3d, 0x20, 0x67, + 0x65, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x28, 0x71, 0x5f, 0x78, 0x31, + 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, + 0x2d, 0x20, 0x64, 0x69, 0x73, 0x70, 0x5f, 0x73, 0x74, 0x72, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x20, 0x2a, 0x20, 0x68, 0x5f, 0x78, 0x31, 0x3b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, 0x5f, 0x78, + 0x32, 0x20, 0x3d, 0x20, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x20, 0x2d, 0x20, + 0x65, 0x2e, 0x78, 0x79, 0x79, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x75, 0x76, 0x5f, 0x78, 0x32, + 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, 0x3e, + 0x28, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x71, 0x5f, 0x78, 0x32, 0x2e, + 0x78, 0x2c, 0x20, 0x71, 0x5f, 0x78, 0x32, 0x2e, 0x7a, 0x29, 0x20, 0x2f, + 0x20, 0x36, 0x2e, 0x32, 0x38, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, 0x2c, + 0x20, 0x61, 0x63, 0x6f, 0x73, 0x28, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x28, + 0x71, 0x5f, 0x78, 0x32, 0x2e, 0x79, 0x20, 0x2f, 0x20, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x28, 0x71, 0x5f, 0x78, 0x32, 0x29, 0x2c, 0x20, 0x2d, + 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x20, 0x2f, + 0x20, 0x33, 0x2e, 0x31, 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x68, 0x5f, 0x78, 0x32, + 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x53, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x74, + 0x65, 0x78, 0x2c, 0x20, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x73, 0x61, + 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x2c, 0x20, 0x75, 0x76, 0x5f, 0x78, 0x32, + 0x29, 0x2e, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6c, 0x65, 0x74, 0x20, 0x64, 0x5f, 0x78, 0x32, 0x20, 0x3d, 0x20, + 0x67, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x28, 0x71, 0x5f, 0x78, + 0x32, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x29, + 0x20, 0x2d, 0x20, 0x64, 0x69, 0x73, 0x70, 0x5f, 0x73, 0x74, 0x72, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x20, 0x2a, 0x20, 0x68, 0x5f, 0x78, 0x32, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, 0x5f, + 0x79, 0x31, 0x20, 0x3d, 0x20, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x20, 0x2b, + 0x20, 0x65, 0x2e, 0x79, 0x78, 0x79, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x75, 0x76, 0x5f, 0x79, + 0x31, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, + 0x3e, 0x28, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x71, 0x5f, 0x79, 0x31, + 0x2e, 0x78, 0x2c, 0x20, 0x71, 0x5f, 0x79, 0x31, 0x2e, 0x7a, 0x29, 0x20, + 0x2f, 0x20, 0x36, 0x2e, 0x32, 0x38, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, + 0x2c, 0x20, 0x61, 0x63, 0x6f, 0x73, 0x28, 0x63, 0x6c, 0x61, 0x6d, 0x70, + 0x28, 0x71, 0x5f, 0x79, 0x31, 0x2e, 0x79, 0x20, 0x2f, 0x20, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x28, 0x71, 0x5f, 0x79, 0x31, 0x29, 0x2c, 0x20, + 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x20, + 0x2f, 0x20, 0x33, 0x2e, 0x31, 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x68, 0x5f, 0x79, + 0x31, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x53, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, + 0x74, 0x65, 0x78, 0x2c, 0x20, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x73, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x2c, 0x20, 0x75, 0x76, 0x5f, 0x79, + 0x31, 0x29, 0x2e, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x64, 0x5f, 0x79, 0x31, 0x20, 0x3d, + 0x20, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x28, 0x71, 0x5f, + 0x79, 0x31, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x29, 0x20, 0x2d, 0x20, 0x64, 0x69, 0x73, 0x70, 0x5f, 0x73, 0x74, 0x72, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x2a, 0x20, 0x68, 0x5f, 0x79, 0x31, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, + 0x5f, 0x79, 0x32, 0x20, 0x3d, 0x20, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x20, + 0x2d, 0x20, 0x65, 0x2e, 0x79, 0x78, 0x79, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x75, 0x76, 0x5f, + 0x79, 0x32, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, + 0x32, 0x3e, 0x28, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x71, 0x5f, 0x79, + 0x32, 0x2e, 0x78, 0x2c, 0x20, 0x71, 0x5f, 0x79, 0x32, 0x2e, 0x7a, 0x29, + 0x20, 0x2f, 0x20, 0x36, 0x2e, 0x32, 0x38, 0x20, 0x2b, 0x20, 0x30, 0x2e, + 0x35, 0x2c, 0x20, 0x61, 0x63, 0x6f, 0x73, 0x28, 0x63, 0x6c, 0x61, 0x6d, + 0x70, 0x28, 0x71, 0x5f, 0x79, 0x32, 0x2e, 0x79, 0x20, 0x2f, 0x20, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x71, 0x5f, 0x79, 0x32, 0x29, 0x2c, + 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, + 0x20, 0x2f, 0x20, 0x33, 0x2e, 0x31, 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x68, 0x5f, + 0x79, 0x32, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, + 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x6e, 0x6f, 0x69, 0x73, 0x65, + 0x5f, 0x74, 0x65, 0x78, 0x2c, 0x20, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, + 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x2c, 0x20, 0x75, 0x76, 0x5f, + 0x79, 0x32, 0x29, 0x2e, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x64, 0x5f, 0x79, 0x32, 0x20, + 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x28, 0x71, + 0x5f, 0x79, 0x32, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x29, 0x20, 0x2d, 0x20, 0x64, 0x69, 0x73, 0x70, 0x5f, 0x73, 0x74, + 0x72, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x2a, 0x20, 0x68, 0x5f, 0x79, + 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, + 0x71, 0x5f, 0x7a, 0x31, 0x20, 0x3d, 0x20, 0x71, 0x5f, 0x68, 0x69, 0x74, + 0x20, 0x2b, 0x20, 0x65, 0x2e, 0x79, 0x79, 0x78, 0x3b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x75, 0x76, + 0x5f, 0x7a, 0x31, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, + 0x33, 0x32, 0x3e, 0x28, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x71, 0x5f, + 0x7a, 0x31, 0x2e, 0x78, 0x2c, 0x20, 0x71, 0x5f, 0x7a, 0x31, 0x2e, 0x7a, + 0x29, 0x20, 0x2f, 0x20, 0x36, 0x2e, 0x32, 0x38, 0x20, 0x2b, 0x20, 0x30, + 0x2e, 0x35, 0x2c, 0x20, 0x61, 0x63, 0x6f, 0x73, 0x28, 0x63, 0x6c, 0x61, + 0x6d, 0x70, 0x28, 0x71, 0x5f, 0x7a, 0x31, 0x2e, 0x79, 0x20, 0x2f, 0x20, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x71, 0x5f, 0x7a, 0x31, 0x29, + 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, + 0x29, 0x20, 0x2f, 0x20, 0x33, 0x2e, 0x31, 0x34, 0x29, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x68, + 0x5f, 0x7a, 0x31, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, + 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x6e, 0x6f, 0x69, 0x73, + 0x65, 0x5f, 0x74, 0x65, 0x78, 0x2c, 0x20, 0x6e, 0x6f, 0x69, 0x73, 0x65, + 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x2c, 0x20, 0x75, 0x76, + 0x5f, 0x7a, 0x31, 0x29, 0x2e, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x64, 0x5f, 0x7a, 0x31, + 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x28, + 0x71, 0x5f, 0x7a, 0x31, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x29, 0x20, 0x2d, 0x20, 0x64, 0x69, 0x73, 0x70, 0x5f, 0x73, + 0x74, 0x72, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x2a, 0x20, 0x68, 0x5f, + 0x7a, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, + 0x20, 0x71, 0x5f, 0x7a, 0x32, 0x20, 0x3d, 0x20, 0x71, 0x5f, 0x68, 0x69, + 0x74, 0x20, 0x2d, 0x20, 0x65, 0x2e, 0x79, 0x79, 0x78, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x75, + 0x76, 0x5f, 0x7a, 0x32, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x3c, + 0x66, 0x33, 0x32, 0x3e, 0x28, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x71, + 0x5f, 0x7a, 0x32, 0x2e, 0x78, 0x2c, 0x20, 0x71, 0x5f, 0x7a, 0x32, 0x2e, + 0x7a, 0x29, 0x20, 0x2f, 0x20, 0x36, 0x2e, 0x32, 0x38, 0x20, 0x2b, 0x20, + 0x30, 0x2e, 0x35, 0x2c, 0x20, 0x61, 0x63, 0x6f, 0x73, 0x28, 0x63, 0x6c, + 0x61, 0x6d, 0x70, 0x28, 0x71, 0x5f, 0x7a, 0x32, 0x2e, 0x79, 0x20, 0x2f, + 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x71, 0x5f, 0x7a, 0x32, + 0x29, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, + 0x29, 0x29, 0x20, 0x2f, 0x20, 0x33, 0x2e, 0x31, 0x34, 0x29, 0x3b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, + 0x68, 0x5f, 0x7a, 0x32, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, + 0x72, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x6e, 0x6f, 0x69, + 0x73, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x2c, 0x20, 0x6e, 0x6f, 0x69, 0x73, + 0x65, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x2c, 0x20, 0x75, + 0x76, 0x5f, 0x7a, 0x32, 0x29, 0x2e, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x64, 0x5f, 0x7a, + 0x32, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x74, + 0x28, 0x71, 0x5f, 0x7a, 0x32, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x29, 0x20, 0x2d, 0x20, 0x64, 0x69, 0x73, 0x70, 0x5f, + 0x73, 0x74, 0x72, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x2a, 0x20, 0x68, + 0x5f, 0x7a, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, + 0x74, 0x20, 0x6e, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x3d, 0x20, + 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x76, 0x65, + 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x64, 0x5f, 0x78, 0x31, + 0x20, 0x2d, 0x20, 0x64, 0x5f, 0x78, 0x32, 0x2c, 0x20, 0x64, 0x5f, 0x79, + 0x31, 0x20, 0x2d, 0x20, 0x64, 0x5f, 0x79, 0x32, 0x2c, 0x20, 0x64, 0x5f, + 0x7a, 0x31, 0x20, 0x2d, 0x20, 0x64, 0x5f, 0x7a, 0x32, 0x29, 0x29, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, + 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x5f, 0x6d, 0x61, 0x74, 0x72, + 0x69, 0x78, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x74, 0x33, 0x78, 0x33, 0x3c, + 0x66, 0x33, 0x32, 0x3e, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x69, 0x6e, 0x76, + 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x30, 0x5d, 0x2e, 0x78, 0x79, + 0x7a, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x69, 0x6e, 0x76, 0x5f, 0x6d, + 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x31, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x2c, + 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x69, 0x6e, 0x76, 0x5f, 0x6d, 0x6f, 0x64, + 0x65, 0x6c, 0x5b, 0x32, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x6f, 0x72, 0x6d, + 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, + 0x7a, 0x65, 0x28, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x73, 0x65, + 0x28, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x5f, 0x6d, 0x61, 0x74, 0x72, + 0x69, 0x78, 0x29, 0x20, 0x2a, 0x20, 0x6e, 0x5f, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x29, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x2f, 0x2f, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x20, 0x74, 0x65, + 0x78, 0x74, 0x75, 0x72, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x53, 0x44, 0x46, + 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x69, 0x6e, 0x2e, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x75, 0x20, 0x7c, 0x7c, 0x20, 0x6f, 0x62, + 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x34, 0x2e, + 0x30, 0x29, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x20, 0x46, 0x6c, 0x6f, 0x6f, + 0x72, 0x20, 0x28, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x30, 0x29, 0x20, + 0x6f, 0x72, 0x20, 0x50, 0x4c, 0x41, 0x4e, 0x45, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, + 0x20, 0x75, 0x76, 0x5f, 0x67, 0x72, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x70, + 0x2e, 0x78, 0x7a, 0x20, 0x2a, 0x20, 0x30, 0x2e, 0x35, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x65, 0x74, 0x20, 0x67, 0x72, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x30, 0x2e, + 0x35, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, 0x20, 0x2a, 0x20, 0x73, 0x69, + 0x6e, 0x28, 0x75, 0x76, 0x5f, 0x67, 0x72, 0x69, 0x64, 0x2e, 0x78, 0x20, + 0x2a, 0x20, 0x33, 0x2e, 0x31, 0x34, 0x29, 0x20, 0x2a, 0x20, 0x73, 0x69, + 0x6e, 0x28, 0x75, 0x76, 0x5f, 0x67, 0x72, 0x69, 0x64, 0x2e, 0x79, 0x20, + 0x2a, 0x20, 0x33, 0x2e, 0x31, 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, + 0x20, 0x67, 0x72, 0x69, 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x20, 0x3d, 0x20, + 0x73, 0x6d, 0x6f, 0x6f, 0x74, 0x68, 0x73, 0x74, 0x65, 0x70, 0x28, 0x30, + 0x2e, 0x34, 0x35, 0x2c, 0x20, 0x30, 0x2e, 0x35, 0x35, 0x2c, 0x20, 0x67, + 0x72, 0x69, 0x64, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x62, 0x61, 0x73, 0x65, 0x5f, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x2a, 0x20, 0x28, 0x30, 0x2e, 0x35, + 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, 0x20, 0x2a, 0x20, 0x67, 0x72, 0x69, + 0x64, 0x5f, 0x76, 0x61, 0x6c, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6c, 0x65, 0x74, 0x20, 0x75, 0x76, 0x5f, 0x68, 0x69, 0x74, 0x20, + 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, + 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x2e, + 0x78, 0x2c, 0x20, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x2e, 0x7a, 0x29, 0x20, + 0x2f, 0x20, 0x36, 0x2e, 0x32, 0x38, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, + 0x2c, 0x20, 0x61, 0x63, 0x6f, 0x73, 0x28, 0x63, 0x6c, 0x61, 0x6d, 0x70, + 0x28, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x2e, 0x79, 0x20, 0x2f, 0x20, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x71, 0x5f, 0x68, 0x69, 0x74, 0x29, + 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, + 0x29, 0x20, 0x2f, 0x20, 0x33, 0x2e, 0x31, 0x34, 0x29, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x65, 0x74, 0x20, 0x74, 0x65, 0x78, 0x5f, 0x76, 0x61, 0x6c, 0x20, 0x3d, + 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x53, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x28, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x74, 0x65, 0x78, + 0x2c, 0x20, 0x6e, 0x6f, 0x69, 0x73, 0x65, 0x5f, 0x73, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x72, 0x2c, 0x20, 0x75, 0x76, 0x5f, 0x68, 0x69, 0x74, 0x29, + 0x2e, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x20, 0x2a, 0x20, 0x28, 0x30, 0x2e, 0x37, 0x20, 0x2b, + 0x20, 0x30, 0x2e, 0x33, 0x20, 0x2a, 0x20, 0x74, 0x65, 0x78, 0x5f, 0x76, + 0x61, 0x6c, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, + 0x20, 0x3d, 0x20, 0x63, 0x61, 0x6c, 0x63, 0x5f, 0x73, 0x68, 0x61, 0x64, + 0x6f, 0x77, 0x28, 0x70, 0x2c, 0x20, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, + 0x64, 0x69, 0x72, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x35, 0x2c, 0x20, 0x32, + 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x69, 0x6e, 0x2e, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x29, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6c, 0x69, 0x74, + 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x63, 0x61, 0x6c, + 0x63, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x6c, 0x69, 0x67, 0x68, 0x74, + 0x69, 0x6e, 0x67, 0x28, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x2c, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x2c, 0x20, + 0x70, 0x2c, 0x20, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x29, 0x3b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, + 0x65, 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x6c, 0x69, 0x74, + 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, + 0x3b, 0x0a, 0x7d, 0x00 +}; +const size_t ASSET_SIZE_SHADER_SKYBOX = 1491; +alignas(16) static const uint8_t ASSET_DATA_SHADER_SKYBOX[] = { + 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x5f, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, + 0x73, 0x22, 0x0a, 0x0a, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, 0x30, + 0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, 0x30, + 0x29, 0x20, 0x76, 0x61, 0x72, 0x20, 0x73, 0x6b, 0x79, 0x5f, 0x74, 0x65, + 0x78, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x32, + 0x64, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x3b, 0x0a, 0x40, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x28, 0x30, 0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x28, 0x31, 0x29, 0x20, 0x76, 0x61, 0x72, 0x20, 0x73, 0x6b, + 0x79, 0x5f, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x3a, 0x20, 0x73, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x3b, 0x0a, 0x40, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x28, 0x30, 0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, + 0x6e, 0x67, 0x28, 0x32, 0x29, 0x20, 0x76, 0x61, 0x72, 0x3c, 0x75, 0x6e, + 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x3e, 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x73, 0x3a, 0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x55, 0x6e, + 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x3b, 0x0a, 0x0a, 0x73, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x20, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x4f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, + 0x62, 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x28, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x20, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, + 0x3e, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x40, 0x6c, 0x6f, 0x63, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x30, 0x29, 0x20, 0x75, 0x76, 0x3a, 0x20, + 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x7d, + 0x3b, 0x0a, 0x0a, 0x40, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x0a, 0x66, + 0x6e, 0x20, 0x76, 0x73, 0x5f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x40, 0x62, + 0x75, 0x69, 0x6c, 0x74, 0x69, 0x6e, 0x28, 0x76, 0x65, 0x72, 0x74, 0x65, + 0x78, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x29, 0x20, 0x76, 0x65, 0x72, + 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x20, 0x75, + 0x33, 0x32, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x56, 0x65, 0x72, 0x74, 0x65, + 0x78, 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20, + 0x61, 0x72, 0x72, 0x61, 0x79, 0x3c, 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, + 0x33, 0x32, 0x3e, 0x2c, 0x20, 0x33, 0x3e, 0x28, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, + 0x32, 0x3e, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, + 0x30, 0x29, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x20, 0x33, + 0x2e, 0x30, 0x2c, 0x20, 0x2d, 0x31, 0x2e, 0x30, 0x29, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x76, 0x65, 0x63, 0x32, 0x3c, + 0x66, 0x33, 0x32, 0x3e, 0x28, 0x2d, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x20, + 0x33, 0x2e, 0x30, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x29, 0x3b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, + 0x20, 0x6f, 0x75, 0x74, 0x3a, 0x20, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, + 0x4f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x6f, 0x75, 0x74, 0x2e, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, + 0x28, 0x70, 0x6f, 0x73, 0x5b, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5d, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, + 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6f, + 0x75, 0x74, 0x2e, 0x75, 0x76, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, + 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x70, 0x6f, 0x73, 0x5b, 0x76, 0x65, + 0x72, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5d, 0x2e, + 0x78, 0x20, 0x2a, 0x20, 0x30, 0x2e, 0x35, 0x20, 0x2b, 0x20, 0x30, 0x2e, + 0x35, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x20, 0x2d, 0x20, 0x28, 0x70, 0x6f, + 0x73, 0x5b, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x5f, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x5d, 0x2e, 0x79, 0x20, 0x2a, 0x20, 0x30, 0x2e, 0x35, 0x20, + 0x2b, 0x20, 0x30, 0x2e, 0x35, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x75, 0x74, 0x3b, + 0x0a, 0x7d, 0x0a, 0x0a, 0x40, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, + 0x74, 0x0a, 0x66, 0x6e, 0x20, 0x66, 0x73, 0x5f, 0x6d, 0x61, 0x69, 0x6e, + 0x28, 0x69, 0x6e, 0x3a, 0x20, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78, 0x4f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x40, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x30, 0x29, 0x20, 0x76, + 0x65, 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x20, 0x7b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, + 0x74, 0x20, 0x55, 0x56, 0x20, 0x74, 0x6f, 0x20, 0x4e, 0x44, 0x43, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6e, 0x64, 0x63, 0x5f, + 0x78, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x2e, 0x75, 0x76, 0x2e, 0x78, 0x20, + 0x2a, 0x20, 0x32, 0x2e, 0x30, 0x20, 0x2d, 0x20, 0x31, 0x2e, 0x30, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6e, 0x64, 0x63, + 0x5f, 0x79, 0x20, 0x3d, 0x20, 0x28, 0x31, 0x2e, 0x30, 0x20, 0x2d, 0x20, + 0x69, 0x6e, 0x2e, 0x75, 0x76, 0x2e, 0x79, 0x29, 0x20, 0x2a, 0x20, 0x32, + 0x2e, 0x30, 0x20, 0x2d, 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x20, 0x2f, 0x2f, + 0x20, 0x55, 0x6e, 0x2d, 0x66, 0x6c, 0x69, 0x70, 0x20, 0x59, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x4e, 0x44, 0x43, 0x20, 0x28, 0x59, 0x2d, 0x75, 0x70, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, + 0x2f, 0x20, 0x55, 0x6e, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x20, + 0x74, 0x6f, 0x20, 0x66, 0x69, 0x6e, 0x64, 0x20, 0x77, 0x6f, 0x72, 0x6c, + 0x64, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x57, 0x65, 0x20, 0x77, 0x61, + 0x6e, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x63, 0x61, + 0x6d, 0x65, 0x72, 0x61, 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x66, 0x61, 0x72, 0x20, 0x70, 0x6c, 0x61, 0x6e, 0x65, 0x20, 0x61, 0x74, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x63, 0x6c, 0x69, 0x70, + 0x5f, 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, + 0x66, 0x33, 0x32, 0x3e, 0x28, 0x6e, 0x64, 0x63, 0x5f, 0x78, 0x2c, 0x20, + 0x6e, 0x64, 0x63, 0x5f, 0x79, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, + 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, + 0x74, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x5f, + 0x68, 0x20, 0x3d, 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x2e, + 0x69, 0x6e, 0x76, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x6f, + 0x6a, 0x20, 0x2a, 0x20, 0x63, 0x6c, 0x69, 0x70, 0x5f, 0x70, 0x6f, 0x73, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x77, 0x6f, + 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x20, 0x3d, 0x20, 0x77, 0x6f, + 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x73, 0x5f, 0x68, 0x2e, 0x78, 0x79, + 0x7a, 0x20, 0x2f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, + 0x73, 0x5f, 0x68, 0x2e, 0x77, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x72, 0x61, 0x79, 0x5f, + 0x64, 0x69, 0x72, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, + 0x69, 0x7a, 0x65, 0x28, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x5f, 0x70, 0x6f, + 0x73, 0x20, 0x2d, 0x20, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x2e, + 0x63, 0x61, 0x6d, 0x65, 0x72, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x3b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x53, 0x70, + 0x68, 0x65, 0x72, 0x69, 0x63, 0x61, 0x6c, 0x20, 0x4d, 0x61, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, + 0x75, 0x20, 0x3d, 0x20, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x72, 0x61, + 0x79, 0x5f, 0x64, 0x69, 0x72, 0x2e, 0x7a, 0x2c, 0x20, 0x72, 0x61, 0x79, + 0x5f, 0x64, 0x69, 0x72, 0x2e, 0x78, 0x29, 0x20, 0x2f, 0x20, 0x36, 0x2e, + 0x32, 0x38, 0x33, 0x31, 0x38, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x35, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x76, 0x20, 0x3d, + 0x20, 0x61, 0x73, 0x69, 0x6e, 0x28, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x28, + 0x72, 0x61, 0x79, 0x5f, 0x64, 0x69, 0x72, 0x2e, 0x79, 0x2c, 0x20, 0x2d, + 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x20, 0x2f, + 0x20, 0x33, 0x2e, 0x31, 0x34, 0x31, 0x35, 0x39, 0x20, 0x2b, 0x20, 0x30, + 0x2e, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x65, 0x78, 0x74, + 0x75, 0x72, 0x65, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x28, 0x73, 0x6b, + 0x79, 0x5f, 0x74, 0x65, 0x78, 0x2c, 0x20, 0x73, 0x6b, 0x79, 0x5f, 0x73, + 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x32, + 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x75, 0x2c, 0x20, 0x76, 0x29, 0x29, + 0x3b, 0x0a, 0x7d, 0x00 +}; +const size_t ASSET_SIZE_SHADER_COMMON_UNIFORMS = 346; +alignas(16) static const uint8_t ASSET_DATA_SHADER_COMMON_UNIFORMS[] = { + 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x47, 0x6c, 0x6f, 0x62, 0x61, + 0x6c, 0x55, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x6f, + 0x6a, 0x3a, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x78, 0x34, 0x3c, 0x66, 0x33, + 0x32, 0x3e, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x76, 0x5f, + 0x76, 0x69, 0x65, 0x77, 0x5f, 0x70, 0x72, 0x6f, 0x6a, 0x3a, 0x20, 0x6d, + 0x61, 0x74, 0x34, 0x78, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x6d, 0x65, 0x72, 0x61, 0x5f, 0x70, + 0x6f, 0x73, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x3a, 0x20, 0x76, 0x65, 0x63, + 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x34, + 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, + 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x76, + 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x7d, 0x3b, + 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x4f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x44, 0x61, 0x74, 0x61, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x3a, 0x20, 0x6d, 0x61, 0x74, 0x34, + 0x78, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x69, 0x6e, 0x76, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x3a, 0x20, + 0x6d, 0x61, 0x74, 0x34, 0x78, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, + 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3a, 0x20, 0x76, + 0x65, 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x7d, 0x3b, + 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x4f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x73, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x3a, + 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3c, 0x4f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x44, 0x61, 0x74, 0x61, 0x3e, 0x2c, 0x0a, 0x7d, 0x3b, 0x00 +}; +const size_t ASSET_SIZE_SHADER_MATH_SDF_SHAPES = 430; +alignas(16) static const uint8_t ASSET_DATA_SHADER_MATH_SDF_SHAPES[] = { + 0x66, 0x6e, 0x20, 0x73, 0x64, 0x53, 0x70, 0x68, 0x65, 0x72, 0x65, 0x28, + 0x70, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, + 0x2c, 0x20, 0x72, 0x3a, 0x20, 0x66, 0x33, 0x32, 0x29, 0x20, 0x2d, 0x3e, + 0x20, 0x66, 0x33, 0x32, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x28, 0x70, 0x29, 0x20, 0x2d, 0x20, 0x72, 0x3b, 0x0a, 0x7d, 0x0a, 0x66, + 0x6e, 0x20, 0x73, 0x64, 0x42, 0x6f, 0x78, 0x28, 0x70, 0x3a, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x20, 0x62, 0x3a, + 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x29, 0x20, + 0x2d, 0x3e, 0x20, 0x66, 0x33, 0x32, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, 0x20, 0x3d, 0x20, 0x61, 0x62, 0x73, + 0x28, 0x70, 0x29, 0x20, 0x2d, 0x20, 0x62, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x28, 0x6d, 0x61, 0x78, 0x28, 0x71, 0x2c, 0x20, 0x76, 0x65, + 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x30, 0x2e, 0x30, 0x29, + 0x29, 0x29, 0x20, 0x2b, 0x20, 0x6d, 0x69, 0x6e, 0x28, 0x6d, 0x61, 0x78, + 0x28, 0x71, 0x2e, 0x78, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x28, 0x71, 0x2e, + 0x79, 0x2c, 0x20, 0x71, 0x2e, 0x7a, 0x29, 0x29, 0x2c, 0x20, 0x30, 0x2e, + 0x30, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x66, 0x6e, 0x20, 0x73, 0x64, 0x54, + 0x6f, 0x72, 0x75, 0x73, 0x28, 0x70, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, + 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x20, 0x74, 0x3a, 0x20, 0x76, 0x65, + 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x29, 0x20, 0x2d, 0x3e, 0x20, + 0x66, 0x33, 0x32, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, + 0x74, 0x20, 0x71, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, + 0x33, 0x32, 0x3e, 0x28, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x70, + 0x2e, 0x78, 0x7a, 0x29, 0x20, 0x2d, 0x20, 0x74, 0x2e, 0x78, 0x2c, 0x20, + 0x70, 0x2e, 0x79, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, + 0x71, 0x29, 0x20, 0x2d, 0x20, 0x74, 0x2e, 0x79, 0x3b, 0x0a, 0x7d, 0x0a, + 0x66, 0x6e, 0x20, 0x73, 0x64, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x28, 0x70, + 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, + 0x20, 0x6e, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, + 0x3e, 0x2c, 0x20, 0x68, 0x3a, 0x20, 0x66, 0x33, 0x32, 0x29, 0x20, 0x2d, + 0x3e, 0x20, 0x66, 0x33, 0x32, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64, 0x6f, 0x74, 0x28, 0x70, 0x2c, 0x20, + 0x6e, 0x29, 0x20, 0x2b, 0x20, 0x68, 0x3b, 0x0a, 0x7d, 0x0a, 0x00 +}; +const size_t ASSET_SIZE_SHADER_MATH_SDF_UTILS = 718; +alignas(16) static const uint8_t ASSET_DATA_SHADER_MATH_SDF_UTILS[] = { + 0x66, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x6e, 0x6f, 0x72, 0x6d, 0x61, + 0x6c, 0x5f, 0x62, 0x61, 0x73, 0x69, 0x63, 0x28, 0x70, 0x3a, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x20, 0x6f, 0x62, + 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x66, 0x33, 0x32, 0x29, + 0x20, 0x2d, 0x3e, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, + 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, + 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, + 0x31, 0x2e, 0x30, 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, + 0x70, 0x29, 0x3b, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, + 0x74, 0x20, 0x65, 0x20, 0x3d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, + 0x33, 0x32, 0x3e, 0x28, 0x30, 0x2e, 0x30, 0x30, 0x31, 0x2c, 0x20, 0x30, + 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, + 0x65, 0x28, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x67, 0x65, 0x74, + 0x5f, 0x64, 0x69, 0x73, 0x74, 0x28, 0x70, 0x20, 0x2b, 0x20, 0x65, 0x2e, + 0x78, 0x79, 0x79, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x29, 0x20, 0x2d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x73, + 0x74, 0x28, 0x70, 0x20, 0x2d, 0x20, 0x65, 0x2e, 0x78, 0x79, 0x79, 0x2c, + 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x29, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x67, 0x65, 0x74, 0x5f, + 0x64, 0x69, 0x73, 0x74, 0x28, 0x70, 0x20, 0x2b, 0x20, 0x65, 0x2e, 0x79, + 0x78, 0x79, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x29, 0x20, 0x2d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x74, + 0x28, 0x70, 0x20, 0x2d, 0x20, 0x65, 0x2e, 0x79, 0x78, 0x79, 0x2c, 0x20, + 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x29, 0x2c, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x64, + 0x69, 0x73, 0x74, 0x28, 0x70, 0x20, 0x2b, 0x20, 0x65, 0x2e, 0x79, 0x79, + 0x78, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x29, + 0x20, 0x2d, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x73, 0x74, 0x28, + 0x70, 0x20, 0x2d, 0x20, 0x65, 0x2e, 0x79, 0x79, 0x78, 0x2c, 0x20, 0x6f, + 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x29, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x29, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x44, + 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x61, + 0x6e, 0x20, 0x41, 0x78, 0x69, 0x73, 0x2d, 0x41, 0x6c, 0x69, 0x67, 0x6e, + 0x65, 0x64, 0x20, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, + 0x42, 0x6f, 0x78, 0x0a, 0x66, 0x6e, 0x20, 0x61, 0x61, 0x62, 0x62, 0x5f, + 0x73, 0x64, 0x66, 0x28, 0x70, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, + 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x20, 0x6d, 0x69, 0x6e, 0x5f, 0x70, 0x3a, + 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x20, + 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, + 0x66, 0x33, 0x32, 0x3e, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x66, 0x33, 0x32, + 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x63, + 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x28, 0x6d, 0x69, 0x6e, + 0x5f, 0x70, 0x20, 0x2b, 0x20, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x29, 0x20, + 0x2a, 0x20, 0x30, 0x2e, 0x35, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x65, 0x74, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x3d, 0x20, + 0x28, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x20, 0x2d, 0x20, 0x6d, 0x69, 0x6e, + 0x5f, 0x70, 0x29, 0x20, 0x2a, 0x20, 0x30, 0x2e, 0x35, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, 0x20, 0x3d, 0x20, 0x61, + 0x62, 0x73, 0x28, 0x70, 0x20, 0x2d, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, + 0x72, 0x29, 0x20, 0x2d, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x6d, 0x61, 0x78, 0x28, 0x71, + 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, + 0x30, 0x2e, 0x30, 0x29, 0x29, 0x29, 0x20, 0x2b, 0x20, 0x6d, 0x69, 0x6e, + 0x28, 0x6d, 0x61, 0x78, 0x28, 0x71, 0x2e, 0x78, 0x2c, 0x20, 0x6d, 0x61, + 0x78, 0x28, 0x71, 0x2e, 0x79, 0x2c, 0x20, 0x71, 0x2e, 0x7a, 0x29, 0x29, + 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x00 +}; +const size_t ASSET_SIZE_SHADER_RENDER_SHADOWS = 441; +alignas(16) static const uint8_t ASSET_DATA_SHADER_RENDER_SHADOWS[] = { + 0x66, 0x6e, 0x20, 0x63, 0x61, 0x6c, 0x63, 0x5f, 0x73, 0x68, 0x61, 0x64, + 0x6f, 0x77, 0x28, 0x72, 0x6f, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, + 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x20, 0x72, 0x64, 0x3a, 0x20, 0x76, 0x65, + 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x20, 0x74, 0x6d, 0x69, + 0x6e, 0x3a, 0x20, 0x66, 0x33, 0x32, 0x2c, 0x20, 0x74, 0x6d, 0x61, 0x78, + 0x3a, 0x20, 0x66, 0x33, 0x32, 0x2c, 0x20, 0x73, 0x6b, 0x69, 0x70, 0x5f, + 0x69, 0x64, 0x78, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x29, 0x20, 0x2d, 0x3e, + 0x20, 0x66, 0x33, 0x32, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, + 0x61, 0x72, 0x20, 0x72, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x74, 0x20, + 0x3d, 0x20, 0x74, 0x6d, 0x69, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x28, 0x74, 0x20, 0x3c, 0x20, 0x30, 0x2e, 0x30, 0x35, + 0x29, 0x20, 0x7b, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x30, 0x2e, 0x30, 0x35, + 0x3b, 0x20, 0x7d, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, + 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, 0x3b, + 0x20, 0x69, 0x20, 0x3c, 0x20, 0x33, 0x32, 0x3b, 0x20, 0x69, 0x20, 0x3d, + 0x20, 0x69, 0x20, 0x2b, 0x20, 0x31, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x68, 0x20, + 0x3d, 0x20, 0x6d, 0x61, 0x70, 0x5f, 0x73, 0x63, 0x65, 0x6e, 0x65, 0x28, + 0x72, 0x6f, 0x20, 0x2b, 0x20, 0x72, 0x64, 0x20, 0x2a, 0x20, 0x74, 0x2c, + 0x20, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x69, 0x64, 0x78, 0x29, 0x3b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, + 0x68, 0x20, 0x3c, 0x20, 0x30, 0x2e, 0x30, 0x30, 0x31, 0x29, 0x20, 0x7b, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x30, 0x2e, 0x30, 0x3b, + 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, + 0x65, 0x73, 0x20, 0x3d, 0x20, 0x6d, 0x69, 0x6e, 0x28, 0x72, 0x65, 0x73, + 0x2c, 0x20, 0x31, 0x36, 0x2e, 0x30, 0x20, 0x2a, 0x20, 0x68, 0x20, 0x2f, + 0x20, 0x74, 0x29, 0x3b, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x74, 0x20, 0x2b, 0x20, 0x63, 0x6c, + 0x61, 0x6d, 0x70, 0x28, 0x68, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x32, 0x2c, + 0x20, 0x30, 0x2e, 0x34, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x74, 0x20, 0x3e, 0x20, 0x74, + 0x6d, 0x61, 0x78, 0x29, 0x20, 0x7b, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, + 0x3b, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x6c, 0x61, + 0x6d, 0x70, 0x28, 0x72, 0x65, 0x73, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x2c, + 0x20, 0x31, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x00 +}; +const size_t ASSET_SIZE_SHADER_RENDER_SCENE_QUERY_BVH = 1782; +alignas(16) static const uint8_t ASSET_DATA_SHADER_RENDER_SCENE_QUERY_BVH[] = { + 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, 0x6d, 0x61, + 0x74, 0x68, 0x2f, 0x73, 0x64, 0x66, 0x5f, 0x73, 0x68, 0x61, 0x70, 0x65, + 0x73, 0x22, 0x0a, 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, + 0x22, 0x6d, 0x61, 0x74, 0x68, 0x2f, 0x73, 0x64, 0x66, 0x5f, 0x75, 0x74, + 0x69, 0x6c, 0x73, 0x22, 0x0a, 0x0a, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x20, 0x42, 0x56, 0x48, 0x4e, 0x6f, 0x64, 0x65, 0x20, 0x7b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x6d, 0x69, 0x6e, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, + 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x65, 0x66, 0x74, 0x5f, 0x69, 0x64, 0x78, 0x3a, 0x20, 0x69, 0x33, 0x32, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x78, 0x3a, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x69, 0x64, 0x78, 0x5f, 0x6f, 0x72, + 0x5f, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x69, 0x33, 0x32, 0x2c, + 0x0a, 0x7d, 0x3b, 0x0a, 0x0a, 0x40, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x28, + 0x30, 0x29, 0x20, 0x40, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x28, + 0x32, 0x29, 0x20, 0x76, 0x61, 0x72, 0x3c, 0x73, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x2c, 0x20, 0x72, 0x65, 0x61, 0x64, 0x3e, 0x20, 0x62, 0x76, + 0x68, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x3a, 0x20, 0x61, 0x72, 0x72, + 0x61, 0x79, 0x3c, 0x42, 0x56, 0x48, 0x4e, 0x6f, 0x64, 0x65, 0x3e, 0x3b, + 0x0a, 0x0a, 0x66, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x73, + 0x74, 0x28, 0x70, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, + 0x32, 0x3e, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x3a, 0x20, 0x66, 0x33, 0x32, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x66, 0x33, + 0x32, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, + 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, + 0x31, 0x2e, 0x30, 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x70, 0x29, 0x20, + 0x2d, 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x20, 0x7d, 0x20, 0x2f, 0x2f, 0x20, + 0x55, 0x6e, 0x69, 0x74, 0x20, 0x53, 0x70, 0x68, 0x65, 0x72, 0x65, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6f, 0x62, 0x6a, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x32, 0x2e, 0x30, 0x29, + 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x64, + 0x42, 0x6f, 0x78, 0x28, 0x70, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, + 0x66, 0x33, 0x32, 0x3e, 0x28, 0x31, 0x2e, 0x30, 0x29, 0x29, 0x3b, 0x20, + 0x7d, 0x20, 0x2f, 0x2f, 0x20, 0x55, 0x6e, 0x69, 0x74, 0x20, 0x42, 0x6f, + 0x78, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6f, 0x62, + 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x33, 0x2e, + 0x30, 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x73, 0x64, 0x54, 0x6f, 0x72, 0x75, 0x73, 0x28, 0x70, 0x2c, 0x20, 0x76, + 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x31, 0x2e, 0x30, + 0x2c, 0x20, 0x30, 0x2e, 0x34, 0x29, 0x29, 0x3b, 0x20, 0x7d, 0x20, 0x2f, + 0x2f, 0x20, 0x55, 0x6e, 0x69, 0x74, 0x20, 0x54, 0x6f, 0x72, 0x75, 0x73, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6f, 0x62, 0x6a, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x34, 0x2e, 0x30, + 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, + 0x64, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x28, 0x70, 0x2c, 0x20, 0x76, 0x65, + 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x30, 0x2e, 0x30, 0x2c, + 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x2c, 0x20, + 0x30, 0x2e, 0x30, 0x29, 0x3b, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x30, 0x30, 0x2e, 0x30, + 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x66, 0x6e, 0x20, 0x6d, 0x61, 0x70, 0x5f, + 0x73, 0x63, 0x65, 0x6e, 0x65, 0x28, 0x70, 0x3a, 0x20, 0x76, 0x65, 0x63, + 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x20, 0x73, 0x6b, 0x69, 0x70, + 0x5f, 0x69, 0x64, 0x78, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x29, 0x20, 0x2d, + 0x3e, 0x20, 0x66, 0x33, 0x32, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x76, 0x61, 0x72, 0x20, 0x64, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x30, 0x30, + 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x3a, 0x20, 0x61, 0x72, 0x72, 0x61, 0x79, + 0x3c, 0x69, 0x33, 0x32, 0x2c, 0x20, 0x33, 0x32, 0x3e, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x5f, 0x70, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x30, 0x3b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x61, + 0x72, 0x72, 0x61, 0x79, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x26, + 0x62, 0x76, 0x68, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x29, 0x20, 0x3e, + 0x20, 0x30, 0x75, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5b, 0x73, 0x74, 0x61, + 0x63, 0x6b, 0x5f, 0x70, 0x74, 0x72, 0x5d, 0x20, 0x3d, 0x20, 0x30, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, + 0x63, 0x6b, 0x5f, 0x70, 0x74, 0x72, 0x2b, 0x2b, 0x3b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x77, 0x68, 0x69, + 0x6c, 0x65, 0x20, 0x28, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x70, 0x74, + 0x72, 0x20, 0x3e, 0x20, 0x30, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x70, + 0x74, 0x72, 0x2d, 0x2d, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, + 0x64, 0x78, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5b, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x70, 0x74, 0x72, 0x5d, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6e, + 0x6f, 0x64, 0x65, 0x20, 0x3d, 0x20, 0x62, 0x76, 0x68, 0x5f, 0x6e, 0x6f, + 0x64, 0x65, 0x73, 0x5b, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x64, 0x78, + 0x5d, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x69, 0x66, 0x20, 0x28, 0x61, 0x61, 0x62, 0x62, 0x5f, 0x73, 0x64, 0x66, + 0x28, 0x70, 0x2c, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6d, 0x69, 0x6e, + 0x2c, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6d, 0x61, 0x78, 0x29, 0x20, + 0x3c, 0x20, 0x64, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6e, + 0x6f, 0x64, 0x65, 0x2e, 0x6c, 0x65, 0x66, 0x74, 0x5f, 0x69, 0x64, 0x78, + 0x20, 0x3c, 0x20, 0x30, 0x29, 0x20, 0x7b, 0x20, 0x2f, 0x2f, 0x20, 0x4c, + 0x65, 0x61, 0x66, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, + 0x6f, 0x62, 0x6a, 0x5f, 0x69, 0x64, 0x78, 0x20, 0x3d, 0x20, 0x75, 0x33, + 0x32, 0x28, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6f, 0x62, 0x6a, 0x5f, 0x69, + 0x64, 0x78, 0x5f, 0x6f, 0x72, 0x5f, 0x72, 0x69, 0x67, 0x68, 0x74, 0x29, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6f, 0x62, + 0x6a, 0x5f, 0x69, 0x64, 0x78, 0x20, 0x3d, 0x3d, 0x20, 0x73, 0x6b, 0x69, + 0x70, 0x5f, 0x69, 0x64, 0x78, 0x29, 0x20, 0x7b, 0x20, 0x63, 0x6f, 0x6e, + 0x74, 0x69, 0x6e, 0x75, 0x65, 0x3b, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6f, 0x62, 0x6a, 0x20, 0x3d, 0x20, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x5b, 0x6f, 0x62, 0x6a, 0x5f, 0x69, + 0x64, 0x78, 0x5d, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, + 0x20, 0x71, 0x20, 0x3d, 0x20, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x69, 0x6e, + 0x76, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x20, 0x2a, 0x20, 0x76, 0x65, + 0x63, 0x34, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x70, 0x2c, 0x20, 0x31, + 0x2e, 0x30, 0x29, 0x29, 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x6d, 0x69, + 0x6e, 0x28, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x6f, 0x62, 0x6a, + 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x30, 0x5d, 0x2e, 0x78, 0x79, + 0x7a, 0x29, 0x2c, 0x20, 0x6d, 0x69, 0x6e, 0x28, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, + 0x5b, 0x31, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x2c, 0x20, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x6d, 0x6f, 0x64, + 0x65, 0x6c, 0x5b, 0x32, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x29, 0x29, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x20, 0x3d, 0x20, 0x6d, 0x69, + 0x6e, 0x28, 0x64, 0x2c, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x73, + 0x74, 0x28, 0x71, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x2e, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x2e, 0x78, 0x29, 0x20, 0x2a, 0x20, 0x73, 0x29, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x20, 0x2f, 0x2f, + 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, + 0x70, 0x74, 0x72, 0x20, 0x3c, 0x20, 0x33, 0x31, 0x29, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x61, 0x63, + 0x6b, 0x5b, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x70, 0x74, 0x72, 0x5d, + 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6c, 0x65, 0x66, 0x74, + 0x5f, 0x69, 0x64, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x70, 0x74, 0x72, 0x2b, + 0x2b, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x5b, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x70, + 0x74, 0x72, 0x5d, 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x2e, 0x6f, + 0x62, 0x6a, 0x5f, 0x69, 0x64, 0x78, 0x5f, 0x6f, 0x72, 0x5f, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x5f, 0x70, 0x74, 0x72, 0x2b, 0x2b, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x64, 0x3b, 0x0a, 0x7d, 0x0a, 0x00 +}; +const size_t ASSET_SIZE_SHADER_RENDER_SCENE_QUERY_LINEAR = 959; +alignas(16) static const uint8_t ASSET_DATA_SHADER_RENDER_SCENE_QUERY_LINEAR[] = { + 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22, 0x6d, 0x61, + 0x74, 0x68, 0x2f, 0x73, 0x64, 0x66, 0x5f, 0x73, 0x68, 0x61, 0x70, 0x65, + 0x73, 0x22, 0x0a, 0x0a, 0x66, 0x6e, 0x20, 0x67, 0x65, 0x74, 0x5f, 0x64, + 0x69, 0x73, 0x74, 0x28, 0x70, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, + 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x20, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x3a, 0x20, 0x66, 0x33, 0x32, 0x29, 0x20, 0x2d, 0x3e, 0x20, + 0x66, 0x33, 0x32, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, + 0x20, 0x28, 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, + 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x70, + 0x29, 0x20, 0x2d, 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x20, 0x7d, 0x20, 0x2f, + 0x2f, 0x20, 0x55, 0x6e, 0x69, 0x74, 0x20, 0x53, 0x70, 0x68, 0x65, 0x72, + 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6f, 0x62, + 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x32, 0x2e, + 0x30, 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x73, 0x64, 0x42, 0x6f, 0x78, 0x28, 0x70, 0x2c, 0x20, 0x76, 0x65, 0x63, + 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x31, 0x2e, 0x30, 0x29, 0x29, + 0x3b, 0x20, 0x7d, 0x20, 0x2f, 0x2f, 0x20, 0x55, 0x6e, 0x69, 0x74, 0x20, + 0x42, 0x6f, 0x78, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, + 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, + 0x33, 0x2e, 0x30, 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x73, 0x64, 0x54, 0x6f, 0x72, 0x75, 0x73, 0x28, 0x70, 0x2c, + 0x20, 0x76, 0x65, 0x63, 0x32, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x34, 0x29, 0x29, 0x3b, 0x20, 0x7d, + 0x20, 0x2f, 0x2f, 0x20, 0x55, 0x6e, 0x69, 0x74, 0x20, 0x54, 0x6f, 0x72, + 0x75, 0x73, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6f, + 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x34, + 0x2e, 0x30, 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x73, 0x64, 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x28, 0x70, 0x2c, 0x20, + 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x30, 0x2e, + 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, + 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x3b, 0x20, 0x7d, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x30, 0x30, + 0x2e, 0x30, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x66, 0x6e, 0x20, 0x6d, 0x61, + 0x70, 0x5f, 0x73, 0x63, 0x65, 0x6e, 0x65, 0x28, 0x70, 0x3a, 0x20, 0x76, + 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x20, 0x73, 0x6b, + 0x69, 0x70, 0x5f, 0x69, 0x64, 0x78, 0x3a, 0x20, 0x75, 0x33, 0x32, 0x29, + 0x20, 0x2d, 0x3e, 0x20, 0x66, 0x33, 0x32, 0x20, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x76, 0x61, 0x72, 0x20, 0x64, 0x20, 0x3d, 0x20, 0x31, 0x30, + 0x30, 0x30, 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, + 0x74, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x75, 0x33, + 0x32, 0x28, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x2e, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x78, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x76, + 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, 0x75, 0x3b, 0x20, 0x69, + 0x20, 0x3c, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x3b, 0x20, 0x69, 0x20, + 0x3d, 0x20, 0x69, 0x20, 0x2b, 0x20, 0x31, 0x75, 0x29, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, + 0x69, 0x20, 0x3d, 0x3d, 0x20, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x69, 0x64, + 0x78, 0x29, 0x20, 0x7b, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, + 0x65, 0x3b, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6f, 0x62, 0x6a, 0x20, 0x3d, 0x20, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x5b, 0x69, 0x5d, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x6f, + 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x6f, 0x62, + 0x6a, 0x2e, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x78, 0x3b, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, + 0x6f, 0x62, 0x6a, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3c, 0x3d, 0x20, + 0x30, 0x2e, 0x30, 0x29, 0x20, 0x7b, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x69, + 0x6e, 0x75, 0x65, 0x3b, 0x20, 0x7d, 0x20, 0x0a, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x71, 0x20, 0x3d, + 0x20, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x69, 0x6e, 0x76, 0x5f, 0x6d, 0x6f, + 0x64, 0x65, 0x6c, 0x20, 0x2a, 0x20, 0x76, 0x65, 0x63, 0x34, 0x3c, 0x66, + 0x33, 0x32, 0x3e, 0x28, 0x70, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x29, + 0x2e, 0x78, 0x79, 0x7a, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x6d, 0x69, + 0x6e, 0x28, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x28, 0x6f, 0x62, 0x6a, + 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5b, 0x30, 0x5d, 0x2e, 0x78, 0x79, + 0x7a, 0x29, 0x2c, 0x20, 0x6d, 0x69, 0x6e, 0x28, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, + 0x5b, 0x31, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x2c, 0x20, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x28, 0x6f, 0x62, 0x6a, 0x2e, 0x6d, 0x6f, 0x64, + 0x65, 0x6c, 0x5b, 0x32, 0x5d, 0x2e, 0x78, 0x79, 0x7a, 0x29, 0x29, 0x29, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x20, + 0x3d, 0x20, 0x6d, 0x69, 0x6e, 0x28, 0x64, 0x2c, 0x20, 0x67, 0x65, 0x74, + 0x5f, 0x64, 0x69, 0x73, 0x74, 0x28, 0x71, 0x2c, 0x20, 0x6f, 0x62, 0x6a, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x2a, 0x20, 0x73, 0x29, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64, 0x3b, 0x0a, 0x7d, 0x0a, 0x00 +}; +const size_t ASSET_SIZE_SHADER_RENDER_LIGHTING_UTILS = 330; +alignas(16) static const uint8_t ASSET_DATA_SHADER_RENDER_LIGHTING_UTILS[] = { + 0x66, 0x6e, 0x20, 0x63, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x65, + 0x5f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x69, 0x6e, 0x67, 0x28, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, + 0x32, 0x3e, 0x2c, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x3a, 0x20, + 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x20, 0x70, + 0x6f, 0x73, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, + 0x3e, 0x2c, 0x20, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x3a, 0x20, 0x66, + 0x33, 0x32, 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, + 0x66, 0x33, 0x32, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x65, 0x74, 0x20, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x64, 0x69, 0x72, + 0x20, 0x3d, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, + 0x28, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x28, 0x31, + 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, 0x2c, 0x20, 0x31, 0x2e, 0x30, + 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, + 0x64, 0x69, 0x66, 0x66, 0x75, 0x73, 0x65, 0x20, 0x3d, 0x20, 0x6d, 0x61, + 0x78, 0x28, 0x64, 0x6f, 0x74, 0x28, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, + 0x2c, 0x20, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x29, + 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x6c, 0x65, 0x74, 0x20, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x69, 0x6e, 0x67, + 0x20, 0x3d, 0x20, 0x64, 0x69, 0x66, 0x66, 0x75, 0x73, 0x65, 0x20, 0x2a, + 0x20, 0x28, 0x30, 0x2e, 0x31, 0x20, 0x2b, 0x20, 0x30, 0x2e, 0x39, 0x20, + 0x2a, 0x20, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x29, 0x20, 0x2b, 0x20, + 0x30, 0x2e, 0x31, 0x3b, 0x20, 0x2f, 0x2f, 0x20, 0x41, 0x6d, 0x62, 0x69, + 0x65, 0x6e, 0x74, 0x20, 0x2b, 0x20, 0x53, 0x68, 0x61, 0x64, 0x6f, 0x77, + 0x65, 0x64, 0x20, 0x44, 0x69, 0x66, 0x66, 0x75, 0x73, 0x65, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x20, 0x2a, 0x20, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x69, + 0x6e, 0x67, 0x3b, 0x0a, 0x7d, 0x0a, 0x00 +}; +const size_t ASSET_SIZE_SHADER_RAY_BOX = 524; +alignas(16) static const uint8_t ASSET_DATA_SHADER_RAY_BOX[] = { + 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x52, 0x61, 0x79, 0x42, 0x6f, + 0x75, 0x6e, 0x64, 0x73, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, + 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x3a, 0x20, 0x66, 0x33, 0x32, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x3a, + 0x20, 0x66, 0x33, 0x32, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x68, 0x69, + 0x74, 0x3a, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x2c, 0x0a, 0x7d, 0x3b, 0x0a, + 0x0a, 0x66, 0x6e, 0x20, 0x72, 0x61, 0x79, 0x5f, 0x62, 0x6f, 0x78, 0x5f, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x72, 0x6f, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, + 0x32, 0x3e, 0x2c, 0x20, 0x72, 0x64, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, + 0x3c, 0x66, 0x33, 0x32, 0x3e, 0x2c, 0x20, 0x65, 0x78, 0x74, 0x65, 0x6e, + 0x74, 0x3a, 0x20, 0x76, 0x65, 0x63, 0x33, 0x3c, 0x66, 0x33, 0x32, 0x3e, + 0x29, 0x20, 0x2d, 0x3e, 0x20, 0x52, 0x61, 0x79, 0x42, 0x6f, 0x75, 0x6e, + 0x64, 0x73, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, + 0x20, 0x69, 0x6e, 0x76, 0x5f, 0x72, 0x64, 0x20, 0x3d, 0x20, 0x31, 0x2e, + 0x30, 0x20, 0x2f, 0x20, 0x72, 0x64, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x6c, 0x65, 0x74, 0x20, 0x74, 0x30, 0x20, 0x3d, 0x20, 0x28, 0x2d, 0x65, + 0x78, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x2d, 0x20, 0x72, 0x6f, 0x29, 0x20, + 0x2a, 0x20, 0x69, 0x6e, 0x76, 0x5f, 0x72, 0x64, 0x3b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x74, 0x31, 0x20, 0x3d, 0x20, 0x28, + 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x2d, 0x20, 0x72, 0x6f, 0x29, + 0x20, 0x2a, 0x20, 0x69, 0x6e, 0x76, 0x5f, 0x72, 0x64, 0x3b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x74, 0x6d, 0x69, 0x6e, 0x5f, + 0x76, 0x65, 0x63, 0x20, 0x3d, 0x20, 0x6d, 0x69, 0x6e, 0x28, 0x74, 0x30, + 0x2c, 0x20, 0x74, 0x31, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, + 0x65, 0x74, 0x20, 0x74, 0x6d, 0x61, 0x78, 0x5f, 0x76, 0x65, 0x63, 0x20, + 0x3d, 0x20, 0x6d, 0x61, 0x78, 0x28, 0x74, 0x30, 0x2c, 0x20, 0x74, 0x31, + 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, 0x20, 0x74, + 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x78, + 0x28, 0x30, 0x2e, 0x30, 0x2c, 0x20, 0x6d, 0x61, 0x78, 0x28, 0x74, 0x6d, + 0x69, 0x6e, 0x5f, 0x76, 0x65, 0x63, 0x2e, 0x78, 0x2c, 0x20, 0x6d, 0x61, + 0x78, 0x28, 0x74, 0x6d, 0x69, 0x6e, 0x5f, 0x76, 0x65, 0x63, 0x2e, 0x79, + 0x2c, 0x20, 0x74, 0x6d, 0x69, 0x6e, 0x5f, 0x76, 0x65, 0x63, 0x2e, 0x7a, + 0x29, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x74, + 0x20, 0x74, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x20, 0x3d, 0x20, 0x6d, 0x69, + 0x6e, 0x28, 0x74, 0x6d, 0x61, 0x78, 0x5f, 0x76, 0x65, 0x63, 0x2e, 0x78, + 0x2c, 0x20, 0x6d, 0x69, 0x6e, 0x28, 0x74, 0x6d, 0x61, 0x78, 0x5f, 0x76, + 0x65, 0x63, 0x2e, 0x79, 0x2c, 0x20, 0x74, 0x6d, 0x61, 0x78, 0x5f, 0x76, + 0x65, 0x63, 0x2e, 0x7a, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x52, 0x61, 0x79, 0x42, 0x6f, + 0x75, 0x6e, 0x64, 0x73, 0x28, 0x74, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x79, + 0x2c, 0x20, 0x74, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x2c, 0x20, 0x74, 0x5f, + 0x65, 0x6e, 0x74, 0x72, 0x79, 0x20, 0x3c, 0x3d, 0x20, 0x74, 0x5f, 0x65, + 0x78, 0x69, 0x74, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x00 +}; const AssetRecord* GetAssetRecordTable() { static const AssetRecord assets[] = { - {ASSET_DATA_TEST_ASSET_1, ASSET_SIZE_TEST_ASSET_1, false, nullptr, - nullptr, 0}, - {ASSET_DATA_NULL_ASSET, ASSET_SIZE_NULL_ASSET, false, nullptr, nullptr, - 0}, - {ASSET_DATA_SHADER_SNIPPET_A, ASSET_SIZE_SHADER_SNIPPET_A, false, nullptr, - nullptr, 0}, - {ASSET_DATA_SHADER_SNIPPET_B, ASSET_SIZE_SHADER_SNIPPET_B, false, nullptr, - nullptr, 0}, - {nullptr, 0, true, ASSET_PROC_FUNC_STR_PROC_NOISE_256, - ASSET_PROC_PARAMS_PROC_NOISE_256, 2}, - {nullptr, 0, true, ASSET_PROC_FUNC_STR_PROC_UNKNOWN, - ASSET_PROC_PARAMS_PROC_UNKNOWN, 1}, - {nullptr, 0, true, ASSET_PROC_FUNC_STR_PROC_FAIL, - ASSET_PROC_PARAMS_PROC_FAIL, 2}, + { ASSET_DATA_TEST_ASSET_1, ASSET_SIZE_TEST_ASSET_1, false, nullptr, nullptr, 0 }, + { ASSET_DATA_NULL_ASSET, ASSET_SIZE_NULL_ASSET, false, nullptr, nullptr, 0 }, + { ASSET_DATA_SHADER_SNIPPET_A, ASSET_SIZE_SHADER_SNIPPET_A, false, nullptr, nullptr, 0 }, + { ASSET_DATA_SHADER_SNIPPET_B, ASSET_SIZE_SHADER_SNIPPET_B, false, nullptr, nullptr, 0 }, + { nullptr, 0, true, ASSET_PROC_FUNC_STR_PROC_NOISE_256, ASSET_PROC_PARAMS_PROC_NOISE_256, 2 }, + { ASSET_DATA_TEST_IMAGE, ASSET_SIZE_TEST_IMAGE, false, nullptr, nullptr, 0 }, + { ASSET_DATA_TEST_MESH, ASSET_SIZE_TEST_MESH, false, nullptr, nullptr, 0 }, + { nullptr, 0, true, ASSET_PROC_FUNC_STR_PROC_UNKNOWN, ASSET_PROC_PARAMS_PROC_UNKNOWN, 1 }, + { nullptr, 0, true, ASSET_PROC_FUNC_STR_PROC_FAIL, ASSET_PROC_PARAMS_PROC_FAIL, 2 }, + { ASSET_DATA_SHADER_MESH, ASSET_SIZE_SHADER_MESH, false, nullptr, nullptr, 0 }, + { ASSET_DATA_SHADER_RENDERER_3D, ASSET_SIZE_SHADER_RENDERER_3D, false, nullptr, nullptr, 0 }, + { ASSET_DATA_SHADER_SKYBOX, ASSET_SIZE_SHADER_SKYBOX, false, nullptr, nullptr, 0 }, + { ASSET_DATA_SHADER_COMMON_UNIFORMS, ASSET_SIZE_SHADER_COMMON_UNIFORMS, false, nullptr, nullptr, 0 }, + { ASSET_DATA_SHADER_MATH_SDF_SHAPES, ASSET_SIZE_SHADER_MATH_SDF_SHAPES, false, nullptr, nullptr, 0 }, + { ASSET_DATA_SHADER_MATH_SDF_UTILS, ASSET_SIZE_SHADER_MATH_SDF_UTILS, false, nullptr, nullptr, 0 }, + { ASSET_DATA_SHADER_RENDER_SHADOWS, ASSET_SIZE_SHADER_RENDER_SHADOWS, false, nullptr, nullptr, 0 }, + { ASSET_DATA_SHADER_RENDER_SCENE_QUERY_BVH, ASSET_SIZE_SHADER_RENDER_SCENE_QUERY_BVH, false, nullptr, nullptr, 0 }, + { ASSET_DATA_SHADER_RENDER_SCENE_QUERY_LINEAR, ASSET_SIZE_SHADER_RENDER_SCENE_QUERY_LINEAR, false, nullptr, nullptr, 0 }, + { ASSET_DATA_SHADER_RENDER_LIGHTING_UTILS, ASSET_SIZE_SHADER_RENDER_LIGHTING_UTILS, false, nullptr, nullptr, 0 }, + { ASSET_DATA_SHADER_RAY_BOX, ASSET_SIZE_SHADER_RAY_BOX, false, nullptr, nullptr, 0 }, }; return assets; } size_t GetAssetCount() { - return 7; + return 20; } + diff --git a/src/gpu/effects/shaders.cc b/src/gpu/effects/shaders.cc index 4fc8108..0646f92 100644 --- a/src/gpu/effects/shaders.cc +++ b/src/gpu/effects/shaders.cc @@ -40,6 +40,7 @@ void InitShaderComposer() { AssetId::ASSET_SHADER_RENDER_SCENE_QUERY_LINEAR); register_if_exists("render/lighting_utils", AssetId::ASSET_SHADER_RENDER_LIGHTING_UTILS); + register_if_exists("render/mesh", AssetId::ASSET_SHADER_MESH); register_if_exists("sdf_primitives", AssetId::ASSET_SHADER_SDF_PRIMITIVES); diff --git a/src/tests/test_3d_render.cc b/src/tests/test_3d_render.cc index f8bbaa7..00de60e 100644 --- a/src/tests/test_3d_render.cc +++ b/src/tests/test_3d_render.cc @@ -5,6 +5,7 @@ #include "3d/object.h" #include "3d/renderer.h" #include "3d/scene.h" +#include "generated/assets.h" #include "gpu/effects/shaders.h" #include "gpu/texture_manager.h" #include "platform.h" @@ -141,6 +142,22 @@ void setup_scene() { sphere.color = vec4(0.2, 1, 0.2, 1); g_scene.add_object(sphere); + // Mesh Object (Rasterized) + Object3D mesh_obj(ObjectType::MESH); + mesh_obj.position = vec3(-4.0f, 2.0f, 0); + mesh_obj.scale = vec3(2.0f, 2.0f, 2.0f); + mesh_obj.color = vec4(0.2, 0.2, 1, 1); + mesh_obj.mesh_asset_id = AssetId::ASSET_MESH_CUBE; + g_scene.add_object(mesh_obj); + + // Dodecahedron (Rasterized) + Object3D dodeca(ObjectType::MESH); + dodeca.position = vec3(4.0f, 2.0f, 2.0f); + dodeca.scale = vec3(1.0f, 1.0f, 1.0f); + dodeca.color = vec4(1.0, 0.5, 0.0, 1); // Orange + dodeca.mesh_asset_id = AssetId::ASSET_DODECAHEDRON; + g_scene.add_object(dodeca); + // Random objects for (int i = 0; i < 30; ++i) { ObjectType type = ObjectType::SPHERE; diff --git a/src/tests/test_mesh.cc b/src/tests/test_mesh.cc new file mode 100644 index 0000000..f29ec27 --- /dev/null +++ b/src/tests/test_mesh.cc @@ -0,0 +1,339 @@ +// This file is part of the 64k demo project. +// Standalone test for loading and rendering a single mesh from a .obj file. + +#include "3d/camera.h" +#include "3d/object.h" +#include "3d/renderer.h" +#include "3d/scene.h" +#include "gpu/effects/shaders.h" +#include "gpu/texture_manager.h" +#include "platform.h" +#include <webgpu.h> +#include "procedural/generator.h" +#include <algorithm> +#include <cmath> +#include <cstdio> +#include <cstring> +#include <fstream> +#include <map> +#include <vector> + +// Global State +static Renderer3D g_renderer; +static TextureManager g_textures; +static Scene g_scene; +static Camera g_camera; +static WGPUDevice g_device = nullptr; +static WGPUQueue g_queue = nullptr; +static WGPUSurface g_surface = nullptr; +static WGPUAdapter g_adapter = nullptr; +static WGPUTextureFormat g_format = WGPUTextureFormat_Undefined; + +// Test-specific storage for mesh buffers +static Renderer3D::MeshGpuData g_mesh_gpu_data; + +// Callbacks for asynchronous WGPU initialization (matches test_3d_render.cc) +void on_adapter_request_ended(WGPURequestAdapterStatus status, + WGPUAdapter adapter, WGPUStringView message, + void* userdata, void* user2) { + (void)user2; + if (status == WGPURequestAdapterStatus_Success) { + *(WGPUAdapter*)userdata = adapter; + } else { + fprintf(stderr, "Failed to request adapter.\n"); // Avoid WGPUStringView::s issues + } +} + +void on_device_request_ended(WGPURequestDeviceStatus status, + WGPUDevice device, WGPUStringView message, + void* userdata, void* user2) { + (void)user2; + if (status == WGPURequestDeviceStatus_Success) { + *(WGPUDevice*)userdata = device; + } else { + fprintf(stderr, "Failed to request device.\n"); // Avoid WGPUStringView::s issues + } +} + +// --- WGPU Boilerplate --- +void init_wgpu(WGPUInstance instance, PlatformState* platform_state) { + if (!instance) { + fprintf(stderr, "Failed to create WGPU instance.\n"); + exit(1); + } + + g_surface = platform_create_wgpu_surface(instance, platform_state); + if (!g_surface) { + fprintf(stderr, "Failed to create WGPU surface.\n"); + exit(1); + } + + // Request Adapter + WGPURequestAdapterOptions adapter_opts = {}; + adapter_opts.compatibleSurface = g_surface; + adapter_opts.powerPreference = WGPUPowerPreference_HighPerformance; + + WGPURequestAdapterCallbackInfo adapter_callback_info = {}; + adapter_callback_info.mode = WGPUCallbackMode_WaitAnyOnly; + adapter_callback_info.callback = on_adapter_request_ended; + adapter_callback_info.userdata1 = &g_adapter; // Corrected to userdata1 + + wgpuInstanceRequestAdapter(instance, &adapter_opts, adapter_callback_info); + + // Busy-wait for adapter + while (!g_adapter) { + platform_wgpu_wait_any(instance); + } + + // Request Device + WGPUDeviceDescriptor device_desc = {}; + WGPURequestDeviceCallbackInfo device_callback_info = {}; + device_callback_info.mode = WGPUCallbackMode_WaitAnyOnly; + device_callback_info.callback = on_device_request_ended; + device_callback_info.userdata1 = &g_device; // Corrected to userdata1 + + wgpuAdapterRequestDevice(g_adapter, &device_desc, device_callback_info); + + // Busy-wait for device + while (!g_device) { + platform_wgpu_wait_any(instance); + } + + g_queue = wgpuDeviceGetQueue(g_device); + + WGPUSurfaceCapabilities caps = {}; + wgpuSurfaceGetCapabilities(g_surface, g_adapter, &caps); + g_format = caps.formats[0]; + + WGPUSurfaceConfiguration config = {}; + config.device = g_device; + config.format = g_format; + config.usage = WGPUTextureUsage_RenderAttachment; + config.width = platform_state->width; + config.height = platform_state->height; + config.presentMode = WGPUPresentMode_Fifo; + config.alphaMode = WGPUCompositeAlphaMode_Opaque; + wgpuSurfaceConfigure(g_surface, &config); +} + +// --- OBJ Loading Logic --- +#include <cmath> // For std::sqrt + +struct Vec3 { + float x, y, z; + Vec3 operator+(const Vec3& o) const { return {x + o.x, y + o.y, z + o.z}; } + Vec3& operator+=(const Vec3& o) { x+=o.x; y+=o.y; z+=o.z; return *this; } + Vec3 operator-(const Vec3& o) const { return {x - o.x, y - o.y, z - o.z}; } + Vec3 operator*(float s) const { return {x * s, y * s, z * s}; } + static Vec3 cross(const Vec3& a, const Vec3& b) { + return {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x}; + } + Vec3 normalize() const { + float len = std::sqrt(x * x + y * y + z * z); + if (len > 1e-6f) return {x / len, y / len, z / len}; + return {0, 0, 0}; + } +}; + +bool load_obj_and_create_buffers(const char* path, Object3D& out_obj) { + std::ifstream obj_file(path); + if (!obj_file.is_open()) { + fprintf(stderr, "Error: Could not open mesh file: %s\n", path); + return false; + } + + std::vector<float> v_pos, v_norm, v_uv; + struct RawFace { int v[3], vt[3], vn[3]; }; + std::vector<RawFace> raw_faces; + std::vector<MeshVertex> final_vertices; + std::vector<uint32_t> final_indices; + std::map<std::string, uint32_t> vertex_map; + + std::string obj_line; + while (std::getline(obj_file, obj_line)) { + if (obj_line.compare(0, 2, "v ") == 0) { + float x, y, z; + sscanf(obj_line.c_str(), "v %f %f %f", &x, &y, &z); + v_pos.insert(v_pos.end(), {x, y, z}); + } else if (obj_line.compare(0, 3, "vn ") == 0) { + float x, y, z; + sscanf(obj_line.c_str(), "vn %f %f %f", &x, &y, &z); + v_norm.insert(v_norm.end(), {x, y, z}); + } else if (obj_line.compare(0, 3, "vt ") == 0) { + float u, v; + sscanf(obj_line.c_str(), "vt %f %f", &u, &v); + v_uv.insert(v_uv.end(), {u, v}); + } else if (obj_line.compare(0, 2, "f ") == 0) { + char s1[64], s2[64], s3[64]; + if (sscanf(obj_line.c_str(), "f %s %s %s", s1, s2, s3) == 3) { + std::string parts[3] = {s1, s2, s3}; + RawFace face = {}; + for (int i = 0; i < 3; ++i) { + // Handle v//vn format + if (parts[i].find("//") != std::string::npos) { + sscanf(parts[i].c_str(), "%d//%d", &face.v[i], &face.vn[i]); + face.vt[i] = 0; + } else { + int res = sscanf(parts[i].c_str(), "%d/%d/%d", &face.v[i], &face.vt[i], &face.vn[i]); + if (res == 2) face.vn[i] = 0; + else if (res == 1) { face.vt[i] = 0; face.vn[i] = 0; } + } + } + raw_faces.push_back(face); + } + } + } + + if (v_norm.empty() && !v_pos.empty()) { + std::vector<Vec3> temp_normals(v_pos.size() / 3, {0,0,0}); + for(auto& face : raw_faces) { + int i0=face.v[0]-1, i1=face.v[1]-1, i2=face.v[2]-1; + Vec3 p0={v_pos[i0*3],v_pos[i0*3+1],v_pos[i0*3+2]}; + Vec3 p1={v_pos[i1*3],v_pos[i1*3+1],v_pos[i1*3+2]}; + Vec3 p2={v_pos[i2*3],v_pos[i2*3+1],v_pos[i2*3+2]}; + Vec3 n = Vec3::cross(p1-p0, p2-p0).normalize(); + temp_normals[i0] += n; temp_normals[i1] += n; temp_normals[i2] += n; + } + for(const auto& n : temp_normals) { + Vec3 norm = n.normalize(); + v_norm.insert(v_norm.end(), {norm.x, norm.y, norm.z}); + } + for(auto& face : raw_faces) { + face.vn[0]=face.v[0]; face.vn[1]=face.v[1]; face.vn[2]=face.v[2]; + } + } + + for (const auto& face : raw_faces) { + for (int i=0; i<3; ++i) { + char key_buf[128]; + snprintf(key_buf, sizeof(key_buf), "%d/%d/%d", face.v[i], face.vt[i], face.vn[i]); + std::string key = key_buf; + if (vertex_map.find(key) == vertex_map.end()) { + vertex_map[key] = (uint32_t)final_vertices.size(); + MeshVertex v = {}; + if(face.v[i]>0) { v.p[0]=v_pos[(face.v[i]-1)*3]; v.p[1]=v_pos[(face.v[i]-1)*3+1]; v.p[2]=v_pos[(face.v[i]-1)*3+2]; } + if(face.vn[i]>0) { v.n[0]=v_norm[(face.vn[i]-1)*3]; v.n[1]=v_norm[(face.vn[i]-1)*3+1]; v.n[2]=v_norm[(face.vn[i]-1)*3+2]; } + if(face.vt[i]>0) { v.u[0]=v_uv[(face.vt[i]-1)*2]; v.u[1]=v_uv[(face.vt[i]-1)*2+1]; } + final_vertices.push_back(v); + } + final_indices.push_back(vertex_map[key]); + } + } + + if (final_vertices.empty()) return false; + + // Calculate AABB and center the mesh + float min_x = 1e10f, min_y = 1e10f, min_z = 1e10f; + float max_x = -1e10f, max_y = -1e10f, max_z = -1e10f; + for (const auto& v : final_vertices) { + min_x = std::min(min_x, v.p[0]); min_y = std::min(min_y, v.p[1]); min_z = std::min(min_z, v.p[2]); + max_x = std::max(max_x, v.p[0]); max_y = std::max(max_y, v.p[1]); max_z = std::max(max_z, v.p[2]); + } + float cx = (min_x + max_x) * 0.5f; + float cy = (min_y + max_y) * 0.5f; + float cz = (min_z + max_z) * 0.5f; + for (auto& v : final_vertices) { + v.p[0] -= cx; v.p[1] -= cy; v.p[2] -= cz; + } + out_obj.local_extent = vec3((max_x - min_x) * 0.5f, (max_y - min_y) * 0.5f, (max_z - min_z) * 0.5f); + + g_mesh_gpu_data.num_indices = final_indices.size(); + g_mesh_gpu_data.vertex_buffer = gpu_create_buffer(g_device, final_vertices.size() * sizeof(MeshVertex), WGPUBufferUsage_Vertex | WGPUBufferUsage_CopyDst, final_vertices.data()).buffer; + g_mesh_gpu_data.index_buffer = gpu_create_buffer(g_device, final_indices.size() * sizeof(uint32_t), WGPUBufferUsage_Index | WGPUBufferUsage_CopyDst, final_indices.data()).buffer; + + out_obj.type = ObjectType::MESH; + out_obj.user_data = new std::vector<MeshVertex>(final_vertices); + + // This test doesn't use the asset system, so we override the renderer's internal cache lookup + // by manually setting the buffers on the renderer object. This is a HACK for this specific tool. + g_renderer.override_mesh_buffers(&g_mesh_gpu_data); + + return true; +} + + +int main(int argc, char** argv) { + if (argc < 2) { + printf("Usage: %s <path/to/mesh.obj> [--debug]\n", argv[0]); + return 1; + } + const char* obj_path = argv[1]; + bool debug_mode = (argc > 2 && strcmp(argv[2], "--debug") == 0); + + printf("Loading mesh: %s\n", obj_path); + + PlatformState platform_state = platform_init(false, 1280, 720); + + WGPUInstance instance = wgpuCreateInstance(nullptr); + init_wgpu(instance, &platform_state); + InitShaderComposer(); + + g_renderer.init(g_device, g_queue, g_format); + g_renderer.resize(platform_state.width, platform_state.height); + if (debug_mode) { + Renderer3D::SetDebugEnabled(true); + } + + g_textures.init(g_device, g_queue); + ProceduralTextureDef noise_def; + noise_def.width=256; noise_def.height=256; + noise_def.gen_func = procedural::gen_noise; + noise_def.params = {1234.0f, 16.0f}; + g_textures.create_procedural_texture("noise", noise_def); + g_renderer.set_noise_texture(g_textures.get_texture_view("noise")); + + // --- Create Scene --- + Object3D floor(ObjectType::PLANE); + floor.scale = vec3(20.0f, 0.01f, 20.0f); // Very thin floor proxy + floor.color = vec4(0.5f, 0.5f, 0.5f, 1.0f); + g_scene.add_object(floor); + + Object3D mesh_obj; + if (!load_obj_and_create_buffers(obj_path, mesh_obj)) { + printf("Failed to load or process OBJ file.\n"); + return 1; + } + mesh_obj.color = vec4(1.0f, 0.7f, 0.2f, 1.0f); + mesh_obj.position = {0, 1.5, 0}; // Elevate a bit more + g_scene.add_object(mesh_obj); + + g_camera.position = vec3(0, 3, 5); + g_camera.target = vec3(0, 1.5, 0); + + while (!platform_should_close(&platform_state)) { + platform_poll(&platform_state); + float time = (float)platform_state.time; + + g_camera.aspect_ratio = platform_state.aspect_ratio; + + g_scene.objects[1].rotation = quat::from_axis({0.5f, 1.0f, 0.0f}, time); + + if (debug_mode) { + auto* vertices = (std::vector<MeshVertex>*)g_scene.objects[1].user_data; + g_renderer.GetVisualDebug().add_mesh_normals(g_scene.objects[1].get_model_matrix(), (uint32_t)vertices->size(), vertices->data()); + } + + WGPUSurfaceTexture surface_tex; + wgpuSurfaceGetCurrentTexture(g_surface, &surface_tex); + if (surface_tex.status == WGPUSurfaceGetCurrentTextureStatus_SuccessOptimal) { // WGPUSurfaceGetCurrentTextureStatus_Success is 0 + WGPUTextureView view = wgpuTextureCreateView(surface_tex.texture, nullptr); + g_renderer.render(g_scene, g_camera, time, view); + wgpuTextureViewRelease(view); + wgpuSurfacePresent(g_surface); + } + wgpuTextureRelease(surface_tex.texture); // Release here, after present, outside the if block + } + +#if !defined(STRIP_ALL) + Renderer3D::SetDebugEnabled(false); // Reset debug mode +#endif + + delete (std::vector<MeshVertex>*)g_scene.objects[1].user_data; + wgpuBufferRelease(g_mesh_gpu_data.vertex_buffer); + wgpuBufferRelease(g_mesh_gpu_data.index_buffer); + + g_renderer.shutdown(); + g_textures.shutdown(); + platform_shutdown(&platform_state); + return 0; +}
\ No newline at end of file diff --git a/src/util/asset_manager.cc b/src/util/asset_manager.cc index d4dd5c7..c12331c 100644 --- a/src/util/asset_manager.cc +++ b/src/util/asset_manager.cc @@ -153,6 +153,25 @@ TextureAsset GetTextureAsset(AssetId asset_id) { return {(int)header[0], (int)header[1], data + 8}; } +MeshAsset GetMeshAsset(AssetId asset_id) { + size_t size = 0; + const uint8_t* data = GetAsset(asset_id, &size); + if (!data || size < 8) { + return {0, nullptr, 0, nullptr}; + } + + const uint8_t* ptr = data; + uint32_t num_vertices = *reinterpret_cast<const uint32_t*>(ptr); + ptr += sizeof(uint32_t); + const MeshVertex* vertices = reinterpret_cast<const MeshVertex*>(ptr); + ptr += num_vertices * sizeof(MeshVertex); + uint32_t num_indices = *reinterpret_cast<const uint32_t*>(ptr); + ptr += sizeof(uint32_t); + const uint32_t* indices = reinterpret_cast<const uint32_t*>(ptr); + + return {num_vertices, vertices, num_indices, indices}; +} + void DropAsset(AssetId asset_id, const uint8_t* asset) { uint16_t index = (uint16_t)asset_id; if (index >= (uint16_t)AssetId::ASSET_LAST_ID) { diff --git a/src/util/asset_manager.h b/src/util/asset_manager.h index a78447d..0c2cc63 100644 --- a/src/util/asset_manager.h +++ b/src/util/asset_manager.h @@ -39,6 +39,22 @@ struct TextureAsset { const uint8_t* pixels; }; +struct MeshVertex { + float p[3]; + float n[3]; + float u[2]; +}; + +struct MeshAsset { + uint32_t num_vertices; + const MeshVertex* vertices; + uint32_t num_indices; + const uint32_t* indices; +}; + // Helper to retrieve and parse a simple texture asset (from packer's // [w][h][pixels] format) TextureAsset GetTextureAsset(AssetId asset_id); + +// Helper to retrieve and parse a mesh asset (from packer's binary format) +MeshAsset GetMeshAsset(AssetId asset_id); diff --git a/tools/asset_packer.cc b/tools/asset_packer.cc index 04b74a4..79a6ce6 100644 --- a/tools/asset_packer.cc +++ b/tools/asset_packer.cc @@ -5,10 +5,13 @@ #include <cstdio> // for simplicity, use fprintf() for output generation #include <fstream> #include <map> +#include <algorithm> // For std::count +#include <cstring> // For std::memcpy #include <regex> // For std::regex #include <stdexcept> // For std::stof exceptions #include <string> #include <vector> +#include <cmath> #define STB_IMAGE_IMPLEMENTATION #define STBI_NO_LINEAR // Don't apply gamma correction, we want raw bytes @@ -39,6 +42,11 @@ static bool HasImageExtension(const std::string& filename) { return false; } +static bool HasMeshExtension(const std::string& filename) { + std::string ext = filename.substr(filename.find_last_of(".") + 1); + return ext == "obj"; +} + // Helper struct to hold all information about an asset during parsing struct AssetBuildInfo { std::string name; @@ -53,6 +61,22 @@ struct AssetBuildInfo { std::string func_name_str_name; // ASSET_PROC_FUNC_STR_xxx for procedural }; +struct Vec3 { + float x, y, z; + Vec3 operator+(const Vec3& o) const { return {x + o.x, y + o.y, z + o.z}; } + Vec3 operator+=(const Vec3& o) { x += o.x; y += o.y; z += o.z; return *this; } + Vec3 operator-(const Vec3& o) const { return {x - o.x, y - o.y, z - o.z}; } + Vec3 operator*(float s) const { return {x * s, y * s, z * s}; } + static Vec3 cross(const Vec3& a, const Vec3& b) { + return {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x}; + } + Vec3 normalize() const { + float len = std::sqrt(x * x + y * y + z * z); + if (len > 1e-6f) return {x / len, y / len, z / len}; + return {0, 0, 0}; + } +}; + int main(int argc, char* argv[]) { if (argc != 4) { fprintf(stderr, @@ -230,6 +254,7 @@ int main(int argc, char* argv[]) { std::vector<uint8_t> buffer; bool is_image = HasImageExtension(info.filename); + bool is_mesh = HasMeshExtension(info.filename); if (is_image) { int w, h, channels; @@ -251,6 +276,166 @@ int main(int argc, char* argv[]) { stbi_image_free(img_data); printf("Processed image asset %s: %dx%d RGBA\n", info.name.c_str(), w, h); + } else if (is_mesh) { + std::ifstream obj_file(full_path); + if (!obj_file.is_open()) { + fprintf(stderr, "Error: Could not open mesh file: %s\n", + full_path.c_str()); + return 1; + } + + std::vector<float> v_pos; + std::vector<float> v_norm; + std::vector<float> v_uv; + + struct RawFace { + int v[3]; + int vt[3]; + int vn[3]; + }; + std::vector<RawFace> raw_faces; + + struct Vertex { + float p[3], n[3], u[2]; + }; + std::vector<Vertex> final_vertices; + std::vector<uint32_t> final_indices; + std::map<std::string, uint32_t> vertex_map; + + std::string obj_line; + while (std::getline(obj_file, obj_line)) { + if (obj_line.compare(0, 2, "v ") == 0) { + float x, y, z; + std::sscanf(obj_line.c_str(), "v %f %f %f", &x, &y, &z); + v_pos.push_back(x); + v_pos.push_back(y); + v_pos.push_back(z); + } else if (obj_line.compare(0, 3, "vn ") == 0) { + float x, y, z; + std::sscanf(obj_line.c_str(), "vn %f %f %f", &x, &y, &z); + v_norm.push_back(x); + v_norm.push_back(y); + v_norm.push_back(z); + } else if (obj_line.compare(0, 3, "vt ") == 0) { + float u, v; + std::sscanf(obj_line.c_str(), "vt %f %f", &u, &v); + v_uv.push_back(u); + v_uv.push_back(v); + } else if (obj_line.compare(0, 2, "f ") == 0) { + char s1[64], s2[64], s3[64]; + if (std::sscanf(obj_line.c_str(), "f %s %s %s", s1, s2, s3) == 3) { + std::string parts[3] = {s1, s2, s3}; + RawFace face = {}; + for (int i = 0; i < 3; ++i) { + int v_idx = 0, vt_idx = 0, vn_idx = 0; + if (parts[i].find("//") != std::string::npos) { + std::sscanf(parts[i].c_str(), "%d//%d", &v_idx, &vn_idx); + } else if (std::count(parts[i].begin(), parts[i].end(), '/') == + 2) { + std::sscanf(parts[i].c_str(), "%d/%d/%d", &v_idx, &vt_idx, + &vn_idx); + } else if (std::count(parts[i].begin(), parts[i].end(), '/') == + 1) { + std::sscanf(parts[i].c_str(), "%d/%d", &v_idx, &vt_idx); + } else { + std::sscanf(parts[i].c_str(), "%d", &v_idx); + } + face.v[i] = v_idx; + face.vt[i] = vt_idx; + face.vn[i] = vn_idx; + } + raw_faces.push_back(face); + } + } + } + + // Generate normals if missing + if (v_norm.empty() && !v_pos.empty()) { + printf("Generating normals for %s...\n", info.name.c_str()); + std::vector<Vec3> temp_normals(v_pos.size() / 3, {0, 0, 0}); + for (auto& face : raw_faces) { + // Indices are 1-based in OBJ + int idx0 = face.v[0] - 1; + int idx1 = face.v[1] - 1; + int idx2 = face.v[2] - 1; + + if (idx0 >= 0 && idx1 >= 0 && idx2 >= 0) { + Vec3 p0 = {v_pos[idx0 * 3], v_pos[idx0 * 3 + 1], v_pos[idx0 * 3 + 2]}; + Vec3 p1 = {v_pos[idx1 * 3], v_pos[idx1 * 3 + 1], v_pos[idx1 * 3 + 2]}; + Vec3 p2 = {v_pos[idx2 * 3], v_pos[idx2 * 3 + 1], v_pos[idx2 * 3 + 2]}; + + Vec3 normal = Vec3::cross(p1 - p0, p2 - p0).normalize(); + temp_normals[idx0] += normal; + temp_normals[idx1] += normal; + temp_normals[idx2] += normal; + } + } + + for (const auto& n : temp_normals) { + Vec3 normalized = n.normalize(); + v_norm.push_back(normalized.x); + v_norm.push_back(normalized.y); + v_norm.push_back(normalized.z); + } + + // Assign generated normals to faces + for (auto& face : raw_faces) { + face.vn[0] = face.v[0]; + face.vn[1] = face.v[1]; + face.vn[2] = face.v[2]; + } + } + + // Build final vertices + for (const auto& face : raw_faces) { + for (int i = 0; i < 3; ++i) { + // Reconstruct key string for uniqueness check + char key_buf[128]; + std::sprintf(key_buf, "%d/%d/%d", face.v[i], face.vt[i], face.vn[i]); + std::string key = key_buf; + + if (vertex_map.find(key) == vertex_map.end()) { + vertex_map[key] = (uint32_t)final_vertices.size(); + + Vertex v = {}; + if (face.v[i] > 0) { + v.p[0] = v_pos[(face.v[i] - 1) * 3]; + v.p[1] = v_pos[(face.v[i] - 1) * 3 + 1]; + v.p[2] = v_pos[(face.v[i] - 1) * 3 + 2]; + } + if (face.vn[i] > 0) { + v.n[0] = v_norm[(face.vn[i] - 1) * 3]; + v.n[1] = v_norm[(face.vn[i] - 1) * 3 + 1]; + v.n[2] = v_norm[(face.vn[i] - 1) * 3 + 2]; + } + if (face.vt[i] > 0) { + v.u[0] = v_uv[(face.vt[i] - 1) * 2]; + v.u[1] = v_uv[(face.vt[i] - 1) * 2 + 1]; + } + final_vertices.push_back(v); + } + final_indices.push_back(vertex_map[key]); + } + } + + // Format: [num_vertices(u32)][Vertex * num_vertices][num_indices(u32)][uint32_t + // * num_indices] + buffer.resize(sizeof(uint32_t) + final_vertices.size() * sizeof(Vertex) + + sizeof(uint32_t) + + final_indices.size() * sizeof(uint32_t)); + uint8_t* out_ptr = buffer.data(); + *reinterpret_cast<uint32_t*>(out_ptr) = (uint32_t)final_vertices.size(); + out_ptr += sizeof(uint32_t); + std::memcpy(out_ptr, final_vertices.data(), + final_vertices.size() * sizeof(Vertex)); + out_ptr += final_vertices.size() * sizeof(Vertex); + *reinterpret_cast<uint32_t*>(out_ptr) = (uint32_t)final_indices.size(); + out_ptr += sizeof(uint32_t); + std::memcpy(out_ptr, final_indices.data(), + final_indices.size() * sizeof(uint32_t)); + + printf("Processed mesh asset %s: %zu vertices, %zu indices\n", + info.name.c_str(), final_vertices.size(), final_indices.size()); } else { std::ifstream asset_file(full_path, std::ios::binary); if (!asset_file.is_open()) { |
