diff --git a/config/assets.yaml b/config/assets.yaml index a6d54c8..b79ec4f 100644 --- a/config/assets.yaml +++ b/config/assets.yaml @@ -91,7 +91,11 @@ assets: required: false absolute: true - type: DATA - path: ${SYSTEM_FOLDER}/postfx.yaml + path: ${SYSTEM_FOLDER}/shaders/postfx.yaml + required: false + absolute: true + - type: DATA + path: ${SYSTEM_FOLDER}/shaders/crtpi.yaml required: false absolute: true diff --git a/data/shaders/crtpi.glsl b/data/shaders/crtpi.glsl new file mode 100644 index 0000000..cd63e80 --- /dev/null +++ b/data/shaders/crtpi.glsl @@ -0,0 +1,157 @@ +#version 330 core + +// Configuración +#define SCANLINES +#define MULTISAMPLE +#define GAMMA +//#define FAKE_GAMMA +//#define CURVATURE +//#define SHARPER +#define MASK_TYPE 2 + +#define CURVATURE_X 0.05 +#define CURVATURE_Y 0.1 +#define MASK_BRIGHTNESS 0.80 +#define SCANLINE_WEIGHT 6.0 +#define SCANLINE_GAP_BRIGHTNESS 0.12 +#define BLOOM_FACTOR 3.5 +#define INPUT_GAMMA 2.4 +#define OUTPUT_GAMMA 2.2 + +// Inputs desde vertex shader +in vec2 vTexCoord; +in float vFilterWidth; +#if defined(CURVATURE) +in vec2 vScreenScale; +#endif + +// Output +out vec4 FragColor; + +// Uniforms +uniform sampler2D Texture; +uniform vec2 TextureSize; + +#if defined(CURVATURE) +vec2 Distort(vec2 coord) +{ + vec2 CURVATURE_DISTORTION = vec2(CURVATURE_X, CURVATURE_Y); + vec2 barrelScale = 1.0 - (0.23 * CURVATURE_DISTORTION); + coord *= vScreenScale; + coord -= vec2(0.5); + float rsq = coord.x * coord.x + coord.y * coord.y; + coord += coord * (CURVATURE_DISTORTION * rsq); + coord *= barrelScale; + if (abs(coord.x) >= 0.5 || abs(coord.y) >= 0.5) + coord = vec2(-1.0); + else + { + coord += vec2(0.5); + coord /= vScreenScale; + } + return coord; +} +#endif + +float CalcScanLineWeight(float dist) +{ + return max(1.0 - dist * dist * SCANLINE_WEIGHT, SCANLINE_GAP_BRIGHTNESS); +} + +float CalcScanLine(float dy) +{ + float scanLineWeight = CalcScanLineWeight(dy); +#if defined(MULTISAMPLE) + scanLineWeight += CalcScanLineWeight(dy - vFilterWidth); + scanLineWeight += CalcScanLineWeight(dy + vFilterWidth); + scanLineWeight *= 0.3333333; +#endif + return scanLineWeight; +} + +void main() +{ +#if defined(CURVATURE) + vec2 texcoord = Distort(vTexCoord); + if (texcoord.x < 0.0) { + FragColor = vec4(0.0); + return; + } +#else + vec2 texcoord = vTexCoord; +#endif + + vec2 texcoordInPixels = texcoord * TextureSize; + +#if defined(SHARPER) + vec2 tempCoord = floor(texcoordInPixels) + 0.5; + vec2 coord = tempCoord / TextureSize; + vec2 deltas = texcoordInPixels - tempCoord; + float scanLineWeight = CalcScanLine(deltas.y); + vec2 signs = sign(deltas); + deltas.x *= 2.0; + deltas = deltas * deltas; + deltas.y = deltas.y * deltas.y; + deltas.x *= 0.5; + deltas.y *= 8.0; + deltas /= TextureSize; + deltas *= signs; + vec2 tc = coord + deltas; +#else + float tempY = floor(texcoordInPixels.y) + 0.5; + float yCoord = tempY / TextureSize.y; + float dy = texcoordInPixels.y - tempY; + float scanLineWeight = CalcScanLine(dy); + float signY = sign(dy); + dy = dy * dy; + dy = dy * dy; + dy *= 8.0; + dy /= TextureSize.y; + dy *= signY; + vec2 tc = vec2(texcoord.x, yCoord + dy); +#endif + + vec3 colour = texture(Texture, tc).rgb; + +#if defined(SCANLINES) +#if defined(GAMMA) +#if defined(FAKE_GAMMA) + colour = colour * colour; +#else + colour = pow(colour, vec3(INPUT_GAMMA)); +#endif +#endif + scanLineWeight *= BLOOM_FACTOR; + colour *= scanLineWeight; + +#if defined(GAMMA) +#if defined(FAKE_GAMMA) + colour = sqrt(colour); +#else + colour = pow(colour, vec3(1.0 / OUTPUT_GAMMA)); +#endif +#endif +#endif + +#if MASK_TYPE == 0 + FragColor = vec4(colour, 1.0); +#elif MASK_TYPE == 1 + float whichMask = fract(gl_FragCoord.x * 0.5); + vec3 mask; + if (whichMask < 0.5) + mask = vec3(MASK_BRIGHTNESS, 1.0, MASK_BRIGHTNESS); + else + mask = vec3(1.0, MASK_BRIGHTNESS, 1.0); + FragColor = vec4(colour * mask, 1.0); +#elif MASK_TYPE == 2 + float whichMask = fract(gl_FragCoord.x * 0.3333333); + vec3 mask = vec3(MASK_BRIGHTNESS, MASK_BRIGHTNESS, MASK_BRIGHTNESS); + if (whichMask < 0.3333333) + mask.x = 1.0; + else if (whichMask < 0.6666666) + mask.y = 1.0; + else + mask.z = 1.0; + FragColor = vec4(colour * mask, 1.0); +#endif +} diff --git a/data/shaders/crtpi.vert b/data/shaders/crtpi.vert new file mode 100644 index 0000000..66102c6 --- /dev/null +++ b/data/shaders/crtpi.vert @@ -0,0 +1,48 @@ +#version 330 core + +// Configuración +#define SCANLINES +#define MULTISAMPLE +#define GAMMA +//#define FAKE_GAMMA +//#define CURVATURE +//#define SHARPER +#define MASK_TYPE 2 + +#define CURVATURE_X 0.05 +#define CURVATURE_Y 0.1 +#define MASK_BRIGHTNESS 0.80 +#define SCANLINE_WEIGHT 6.0 +#define SCANLINE_GAP_BRIGHTNESS 0.12 +#define BLOOM_FACTOR 3.5 +#define INPUT_GAMMA 2.4 +#define OUTPUT_GAMMA 2.2 + +// Inputs (desde VAO) +layout(location = 0) in vec2 aPosition; +layout(location = 1) in vec2 aTexCoord; + +// Outputs al fragment shader +out vec2 vTexCoord; +out float vFilterWidth; +#if defined(CURVATURE) +out vec2 vScreenScale; +#endif + +// Uniforms +uniform vec2 TextureSize; + +void main() +{ +#if defined(CURVATURE) + vScreenScale = vec2(1.0, 1.0); +#endif + // Calcula filterWidth dinámicamente basándose en la altura de la textura + vFilterWidth = (768.0 / TextureSize.y) / 3.0; + + // Pasar coordenadas de textura (invertir Y para SDL) + vTexCoord = vec2(aTexCoord.x, 1.0 - aTexCoord.y) * 1.0001; + + // Posición del vértice (ya en espacio de clip [-1, 1]) + gl_Position = vec4(aPosition, 0.0, 1.0); +} diff --git a/data/shaders/crtpi_frag.glsl b/data/shaders/crtpi_frag.glsl new file mode 100644 index 0000000..48f0fa3 --- /dev/null +++ b/data/shaders/crtpi_frag.glsl @@ -0,0 +1,152 @@ +#version 450 + +// Vulkan GLSL fragment shader — CRT-Pi PostFX +// Algoritmo de scanlines continuas con pesos gaussianos, bloom y máscara de fósforo. +// Basado en el shader CRT-Pi original (GLSL 3.3), portado a GLSL 4.50 con parámetros uniformes. +// +// Compile: glslc -fshader-stage=frag --target-env=vulkan1.0 crtpi_frag.glsl -o crtpi_frag.spv +// xxd -i crtpi_frag.spv > ../../source/core/rendering/sdl3gpu/crtpi_frag_spv.h + +layout(location = 0) in vec2 v_uv; +layout(location = 0) out vec4 out_color; + +layout(set = 2, binding = 0) uniform sampler2D Texture; + +layout(set = 3, binding = 0) uniform CrtPiBlock { + // vec4 #0 + float scanline_weight; // Ajuste gaussiano de scanlines (default 6.0) + float scanline_gap_brightness; // Brillo mínimo entre scanlines (default 0.12) + float bloom_factor; // Factor de brillo en zonas iluminadas (default 3.5) + float input_gamma; // Gamma de entrada — linealización (default 2.4) + // vec4 #1 + float output_gamma; // Gamma de salida — codificación (default 2.2) + float mask_brightness; // Brillo sub-píxeles de la máscara (default 0.80) + float curvature_x; // Distorsión barrel eje X (default 0.05) + float curvature_y; // Distorsión barrel eje Y (default 0.10) + // vec4 #2 + int mask_type; // 0=ninguna, 1=verde/magenta, 2=RGB fósforo + int enable_scanlines; // 0 = off, 1 = on + int enable_multisample; // 0 = off, 1 = on (antialiasing analítico de scanlines) + int enable_gamma; // 0 = off, 1 = on + // vec4 #3 + int enable_curvature; // 0 = off, 1 = on + int enable_sharper; // 0 = off, 1 = on + float texture_width; // Ancho del canvas lógico en píxeles + float texture_height; // Alto del canvas lógico en píxeles +} u; + +// Distorsión barrel CRT +vec2 distort(vec2 coord, vec2 screen_scale) { + vec2 curvature = vec2(u.curvature_x, u.curvature_y); + vec2 barrel_scale = 1.0 - (0.23 * curvature); + coord *= screen_scale; + coord -= vec2(0.5); + float rsq = coord.x * coord.x + coord.y * coord.y; + coord += coord * (curvature * rsq); + coord *= barrel_scale; + if (abs(coord.x) >= 0.5 || abs(coord.y) >= 0.5) { + return vec2(-1.0); // fuera de pantalla + } + coord += vec2(0.5); + coord /= screen_scale; + return coord; +} + +float calcScanLineWeight(float dist) { + return max(1.0 - dist * dist * u.scanline_weight, u.scanline_gap_brightness); +} + +float calcScanLine(float dy, float filter_width) { + float weight = calcScanLineWeight(dy); + if (u.enable_multisample != 0) { + weight += calcScanLineWeight(dy - filter_width); + weight += calcScanLineWeight(dy + filter_width); + weight *= 0.3333333; + } + return weight; +} + +void main() { + vec2 tex_size = vec2(u.texture_width, u.texture_height); + + // filterWidth: equivalente al original (768.0 / TextureSize.y) / 3.0 + float filter_width = (768.0 / u.texture_height) / 3.0; + + vec2 texcoord = v_uv; + + // Curvatura barrel opcional + if (u.enable_curvature != 0) { + texcoord = distort(texcoord, vec2(1.0, 1.0)); + if (texcoord.x < 0.0) { + out_color = vec4(0.0, 0.0, 0.0, 1.0); + return; + } + } + + vec2 texcoord_in_pixels = texcoord * tex_size; + vec2 tc; + float scan_line_weight; + + if (u.enable_sharper != 0) { + // Modo SHARPER: filtrado bicúbico-like con subpixel sharpen + vec2 temp_coord = floor(texcoord_in_pixels) + 0.5; + tc = temp_coord / tex_size; + vec2 deltas = texcoord_in_pixels - temp_coord; + scan_line_weight = calcScanLine(deltas.y, filter_width); + vec2 signs = sign(deltas); + deltas.x *= 2.0; + deltas = deltas * deltas; + deltas.y = deltas.y * deltas.y; + deltas.x *= 0.5; + deltas.y *= 8.0; + deltas /= tex_size; + deltas *= signs; + tc = tc + deltas; + } else { + // Modo estándar + float temp_y = floor(texcoord_in_pixels.y) + 0.5; + float y_coord = temp_y / tex_size.y; + float dy = texcoord_in_pixels.y - temp_y; + scan_line_weight = calcScanLine(dy, filter_width); + float sign_y = sign(dy); + dy = dy * dy; + dy = dy * dy; + dy *= 8.0; + dy /= tex_size.y; + dy *= sign_y; + tc = vec2(texcoord.x, y_coord + dy); + } + + vec3 colour = texture(Texture, tc).rgb; + + if (u.enable_scanlines != 0) { + if (u.enable_gamma != 0) { + colour = pow(colour, vec3(u.input_gamma)); + } + colour *= scan_line_weight * u.bloom_factor; + if (u.enable_gamma != 0) { + colour = pow(colour, vec3(1.0 / u.output_gamma)); + } + } + + // Máscara de fósforo + if (u.mask_type == 1) { + float which_mask = fract(gl_FragCoord.x * 0.5); + vec3 mask = (which_mask < 0.5) + ? vec3(u.mask_brightness, 1.0, u.mask_brightness) + : vec3(1.0, u.mask_brightness, 1.0); + colour *= mask; + } else if (u.mask_type == 2) { + float which_mask = fract(gl_FragCoord.x * 0.3333333); + vec3 mask = vec3(u.mask_brightness); + if (which_mask < 0.3333333) + mask.x = 1.0; + else if (which_mask < 0.6666666) + mask.y = 1.0; + else + mask.z = 1.0; + colour *= mask; + } + + out_color = vec4(colour, 1.0); +} diff --git a/data/shaders/crtpi_frag.spv b/data/shaders/crtpi_frag.spv new file mode 100644 index 0000000..6440efe Binary files /dev/null and b/data/shaders/crtpi_frag.spv differ diff --git a/source/core/rendering/screen.cpp b/source/core/rendering/screen.cpp index 6e65f26..63cbb80 100644 --- a/source/core/rendering/screen.cpp +++ b/source/core/rendering/screen.cpp @@ -555,6 +555,54 @@ void Screen::applyCurrentPostFXPreset() { // NOLINT(readability-convert-member- } } +// Aplica los parámetros del preset CrtPi actual al backend de shaders +void Screen::applyCurrentCrtPiPreset() { // NOLINT(readability-convert-member-functions-to-static) + if (shader_backend_ && !Options::crtpi_presets.empty()) { + const auto& p = Options::crtpi_presets[static_cast(Options::current_crtpi_preset)]; + Rendering::CrtPiParams params{ + .scanline_weight = p.scanline_weight, + .scanline_gap_brightness = p.scanline_gap_brightness, + .bloom_factor = p.bloom_factor, + .input_gamma = p.input_gamma, + .output_gamma = p.output_gamma, + .mask_brightness = p.mask_brightness, + .curvature_x = p.curvature_x, + .curvature_y = p.curvature_y, + .mask_type = p.mask_type, + .enable_scanlines = p.enable_scanlines, + .enable_multisample = p.enable_multisample, + .enable_gamma = p.enable_gamma, + .enable_curvature = p.enable_curvature, + .enable_sharper = p.enable_sharper, + }; + shader_backend_->setCrtPiParams(params); + } +} + +// Cambia el shader de post-procesado activo y aplica el preset correspondiente +void Screen::setActiveShader(Rendering::ShaderType type) { + Options::current_shader = type; + if (!shader_backend_) { return; } + shader_backend_->setActiveShader(type); + if (type == Rendering::ShaderType::CRTPI) { + applyCurrentCrtPiPreset(); + } else { + if (Options::video.postfx) { + applyCurrentPostFXPreset(); + } else { + shader_backend_->setPostFXParams(Rendering::PostFXParams{}); + } + } +} + +// Cicla al siguiente shader disponible (preparado para futura UI) +void Screen::nextShader() { + const Rendering::ShaderType NEXT = (Options::current_shader == Rendering::ShaderType::POSTFX) + ? Rendering::ShaderType::CRTPI + : Rendering::ShaderType::POSTFX; + setActiveShader(NEXT); +} + // Inicializa los shaders // El device GPU se crea siempre (independientemente de postfx) para evitar // conflictos SDL_Renderer/SDL_GPU al hacer toggle F4 en Windows/Vulkan. @@ -580,6 +628,12 @@ void Screen::initShaders() { // Pass-through: todos los efectos a 0, el shader solo copia la textura shader_backend_->setPostFXParams(Rendering::PostFXParams{}); } + + // Restaurar el shader activo guardado en config (y sus parámetros CrtPi si aplica) + shader_backend_->setActiveShader(Options::current_shader); + if (Options::current_shader == Rendering::ShaderType::CRTPI) { + applyCurrentCrtPiPreset(); + } } // Obtiene información sobre la pantalla diff --git a/source/core/rendering/screen.hpp b/source/core/rendering/screen.hpp index 72b1e06..72ed229 100644 --- a/source/core/rendering/screen.hpp +++ b/source/core/rendering/screen.hpp @@ -9,12 +9,10 @@ #include // Para std::pair #include // Para vector +#include "core/rendering/shader_backend.hpp" // Para Rendering::ShaderType, ShaderBackend #include "utils/utils.hpp" // Para Color class Surface; class Text; -namespace Rendering { - class ShaderBackend; -} class Screen { public: @@ -60,8 +58,10 @@ class Screen { void togglePostFX(); // Cambia el estado del PostFX void toggleSupersampling(); // Activa/desactiva el supersampling global void reloadPostFX(); // Recarga el shader del preset actual sin toggle - void setLinearUpscale(bool linear); // Upscale NEAREST (false) o LINEAR (true) en el paso SS - void setDownscaleAlgo(int algo); // 0=bilinear legacy, 1=Lanczos2, 2=Lanczos3 + void setLinearUpscale(bool linear); // Upscale NEAREST (false) o LINEAR (true) en el paso SS + void setDownscaleAlgo(int algo); // 0=bilinear legacy, 1=Lanczos2, 2=Lanczos3 + void setActiveShader(Rendering::ShaderType type); // Cambia el shader de post-procesado activo + void nextShader(); // Cicla al siguiente shader disponible (para futura UI) // Surfaces y notificaciones void setRendererSurface(const std::shared_ptr& surface = nullptr); // Establece el renderizador para las surfaces @@ -124,7 +124,8 @@ class Screen { void renderOverlays(); // Renderiza todos los overlays auto findPalette(const std::string& name) -> size_t; // Localiza la paleta dentro del vector de paletas void initShaders(); // Inicializa los shaders - void applyCurrentPostFXPreset(); // Aplica los parámetros del preset actual al backend + void applyCurrentPostFXPreset(); // Aplica los parámetros del preset PostFX actual al backend + void applyCurrentCrtPiPreset(); // Aplica los parámetros del preset CrtPi actual al backend void getDisplayInfo(); // Obtiene información sobre la pantalla auto initSDLVideo() -> bool; // Arranca SDL VIDEO y crea la ventana void createText(); // Crea el objeto de texto diff --git a/source/core/rendering/sdl3gpu/crtpi_frag_spv.h b/source/core/rendering/sdl3gpu/crtpi_frag_spv.h new file mode 100644 index 0000000..83e6465 --- /dev/null +++ b/source/core/rendering/sdl3gpu/crtpi_frag_spv.h @@ -0,0 +1,870 @@ +#pragma once +#include +#include + +static const uint8_t kcrtpi_frag_spv[] = { + 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x0b, 0x00, 0x0d, 0x00, + 0xa2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0xa4, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x62, 0x01, 0x00, 0x00, + 0x10, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc2, 0x01, 0x00, 0x00, + 0x04, 0x00, 0x0a, 0x00, 0x47, 0x4c, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c, + 0x45, 0x5f, 0x63, 0x70, 0x70, 0x5f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x5f, + 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x47, 0x4c, 0x5f, 0x47, + 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, + 0x65, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x00, + 0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x64, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, 0x28, 0x76, 0x66, 0x32, 0x3b, + 0x76, 0x66, 0x32, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x06, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x73, 0x63, 0x72, 0x65, + 0x65, 0x6e, 0x5f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x08, 0x00, 0x11, 0x00, 0x00, 0x00, 0x63, 0x61, 0x6c, 0x63, + 0x53, 0x63, 0x61, 0x6e, 0x4c, 0x69, 0x6e, 0x65, 0x57, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x28, 0x66, 0x31, 0x3b, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x64, 0x69, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x07, 0x00, 0x16, 0x00, 0x00, 0x00, 0x63, 0x61, 0x6c, 0x63, + 0x53, 0x63, 0x61, 0x6e, 0x4c, 0x69, 0x6e, 0x65, 0x28, 0x66, 0x31, 0x3b, + 0x66, 0x31, 0x3b, 0x00, 0x05, 0x00, 0x03, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x64, 0x79, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x63, 0x75, 0x72, 0x76, 0x61, 0x74, 0x75, 0x72, 0x65, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x43, 0x72, 0x74, 0x50, + 0x69, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x00, 0x00, 0x06, 0x00, 0x07, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x63, 0x61, 0x6e, + 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x00, + 0x06, 0x00, 0x09, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x73, 0x63, 0x61, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x67, 0x61, 0x70, + 0x5f, 0x62, 0x72, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x00, + 0x06, 0x00, 0x07, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x62, 0x6c, 0x6f, 0x6f, 0x6d, 0x5f, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x67, 0x61, + 0x6d, 0x6d, 0x61, 0x00, 0x06, 0x00, 0x07, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x67, + 0x61, 0x6d, 0x6d, 0x61, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x07, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x73, 0x6b, + 0x5f, 0x62, 0x72, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x65, 0x73, 0x73, 0x00, + 0x06, 0x00, 0x06, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x63, 0x75, 0x72, 0x76, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x78, 0x00, + 0x06, 0x00, 0x06, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x63, 0x75, 0x72, 0x76, 0x61, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x79, 0x00, + 0x06, 0x00, 0x06, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x6d, 0x61, 0x73, 0x6b, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x08, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x63, 0x61, 0x6e, 0x6c, + 0x69, 0x6e, 0x65, 0x73, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x65, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x5f, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x73, 0x61, 0x6d, 0x70, + 0x6c, 0x65, 0x00, 0x00, 0x06, 0x00, 0x07, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x67, + 0x61, 0x6d, 0x6d, 0x61, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x08, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x65, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x5f, 0x63, 0x75, 0x72, 0x76, 0x61, 0x74, 0x75, 0x72, 0x65, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x07, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, + 0x68, 0x61, 0x72, 0x70, 0x65, 0x72, 0x00, 0x00, 0x06, 0x00, 0x07, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x74, + 0x75, 0x72, 0x65, 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x07, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, + 0x74, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x5f, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x75, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x25, 0x00, 0x00, 0x00, + 0x62, 0x61, 0x72, 0x72, 0x65, 0x6c, 0x5f, 0x73, 0x63, 0x61, 0x6c, 0x65, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x33, 0x00, 0x00, 0x00, + 0x72, 0x73, 0x71, 0x00, 0x05, 0x00, 0x04, 0x00, 0x74, 0x00, 0x00, 0x00, + 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, + 0x75, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x04, 0x00, 0x82, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x89, 0x00, 0x00, 0x00, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, + 0x93, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x5f, 0x73, 0x69, 0x7a, 0x65, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x9b, 0x00, 0x00, 0x00, + 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0xa2, 0x00, 0x00, 0x00, + 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x04, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x76, 0x5f, 0x75, 0x76, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0xad, 0x00, 0x00, 0x00, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, + 0xaf, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x05, 0x00, 0xb9, 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x5f, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x07, 0x00, + 0xbc, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, + 0x5f, 0x69, 0x6e, 0x5f, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x73, 0x00, 0x00, + 0x05, 0x00, 0x05, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x74, 0x65, 0x6d, 0x70, + 0x5f, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, + 0xcb, 0x00, 0x00, 0x00, 0x74, 0x63, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, + 0xcf, 0x00, 0x00, 0x00, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x73, 0x00, 0x00, + 0x05, 0x00, 0x07, 0x00, 0xd3, 0x00, 0x00, 0x00, 0x73, 0x63, 0x61, 0x6e, + 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0xd4, 0x00, 0x00, 0x00, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, + 0xd7, 0x00, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x04, 0x00, 0xda, 0x00, 0x00, 0x00, 0x73, 0x69, 0x67, 0x6e, + 0x73, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0xfe, 0x00, 0x00, 0x00, + 0x74, 0x65, 0x6d, 0x70, 0x5f, 0x79, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, + 0x03, 0x01, 0x00, 0x00, 0x79, 0x5f, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x00, + 0x05, 0x00, 0x03, 0x00, 0x08, 0x01, 0x00, 0x00, 0x64, 0x79, 0x00, 0x00, + 0x05, 0x00, 0x04, 0x00, 0x0d, 0x01, 0x00, 0x00, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x0f, 0x01, 0x00, 0x00, + 0x70, 0x61, 0x72, 0x61, 0x6d, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, + 0x12, 0x01, 0x00, 0x00, 0x73, 0x69, 0x67, 0x6e, 0x5f, 0x79, 0x00, 0x00, + 0x05, 0x00, 0x04, 0x00, 0x2c, 0x01, 0x00, 0x00, 0x63, 0x6f, 0x6c, 0x6f, + 0x75, 0x72, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x30, 0x01, 0x00, 0x00, + 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x00, 0x05, 0x00, 0x05, 0x00, + 0x60, 0x01, 0x00, 0x00, 0x77, 0x68, 0x69, 0x63, 0x68, 0x5f, 0x6d, 0x61, + 0x73, 0x6b, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x62, 0x01, 0x00, 0x00, + 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f, 0x72, 0x64, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x68, 0x01, 0x00, 0x00, + 0x6d, 0x61, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, + 0x82, 0x01, 0x00, 0x00, 0x77, 0x68, 0x69, 0x63, 0x68, 0x5f, 0x6d, 0x61, + 0x73, 0x6b, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00, 0x87, 0x01, 0x00, 0x00, + 0x6d, 0x61, 0x73, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x3c, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x04, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0xb9, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, + 0x30, 0x01, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x04, 0x00, 0x30, 0x01, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x62, 0x01, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x21, 0x00, 0x05, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x15, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x12, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x1b, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x1b, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x3f, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x27, 0x00, 0x00, 0x00, 0x1f, 0x85, 0x6b, 0x3e, 0x2b, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0x2c, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x2f, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x34, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00, + 0x4c, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x5b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xbf, 0x2c, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x5b, 0x00, 0x00, 0x00, + 0x5b, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x79, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x3e, + 0x2b, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x97, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x44, + 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x40, 0x20, 0x00, 0x04, 0x00, 0xa3, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0xa3, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0xac, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb3, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0xb7, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0xb8, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb7, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0xb8, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x07, 0x00, 0xb7, 0x00, 0x00, 0x00, + 0xba, 0x00, 0x00, 0x00, 0xb3, 0x00, 0x00, 0x00, 0xb3, 0x00, 0x00, 0x00, + 0xb3, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0x00, 0x04, 0x00, + 0x2a, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x2b, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x2a, 0x01, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00, 0x2d, 0x01, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x03, 0x00, 0x2e, 0x01, 0x00, 0x00, + 0x2d, 0x01, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x2f, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x2e, 0x01, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x2f, 0x01, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x35, 0x01, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x3b, 0x01, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x42, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x48, 0x01, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x54, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x61, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xb7, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x61, 0x01, 0x00, 0x00, + 0x62, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x63, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x6e, 0x01, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x92, 0x01, 0x00, 0x00, 0xaa, 0xaa, 0x2a, 0x3f, 0x2b, 0x00, 0x04, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x98, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x93, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, + 0xad, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x08, 0x00, 0x00, 0x00, 0xaf, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, + 0xc6, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x08, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0xd3, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xd7, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, + 0xda, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x08, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x0d, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x01, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x12, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x2b, 0x01, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x60, 0x01, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x2b, 0x01, 0x00, 0x00, + 0x68, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x2b, 0x01, 0x00, 0x00, 0x6b, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x82, 0x01, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x2b, 0x01, 0x00, 0x00, + 0x87, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x94, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x96, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x97, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x99, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x50, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, + 0x99, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x93, 0x00, 0x00, 0x00, + 0x9a, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x9d, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x97, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, + 0x9d, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x9f, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, + 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, + 0x9f, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x9b, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0xa2, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x79, 0x00, 0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, + 0xab, 0x00, 0x05, 0x00, 0x4c, 0x00, 0x00, 0x00, 0xa9, 0x00, 0x00, 0x00, + 0xa8, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, + 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, + 0xa9, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xab, 0x00, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0xae, 0x00, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0xad, 0x00, 0x00, 0x00, 0xae, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0xaf, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, + 0x39, 0x00, 0x06, 0x00, 0x07, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, 0x00, 0xaf, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0xa2, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xb1, 0x00, 0x00, 0x00, + 0xa2, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0xb2, 0x00, 0x00, 0x00, 0xb1, 0x00, 0x00, 0x00, + 0xb8, 0x00, 0x05, 0x00, 0x4c, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, + 0xb2, 0x00, 0x00, 0x00, 0xb3, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, + 0xb6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, + 0xb4, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0xb5, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0xb9, 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0xb6, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, + 0xab, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xab, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00, 0x00, + 0xa2, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0xbe, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00, 0x00, + 0xbe, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xbc, 0x00, 0x00, 0x00, + 0xbf, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x79, 0x00, 0x00, 0x00, + 0xc1, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, + 0xc1, 0x00, 0x00, 0x00, 0xab, 0x00, 0x05, 0x00, 0x4c, 0x00, 0x00, 0x00, + 0xc3, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, + 0xf7, 0x00, 0x03, 0x00, 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfa, 0x00, 0x04, 0x00, 0xc3, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, + 0xfd, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xc4, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, + 0xbc, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x07, 0x00, 0x00, 0x00, + 0xc8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0xc7, 0x00, 0x00, 0x00, 0x50, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0xc9, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, + 0x81, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00, 0x00, + 0xc8, 0x00, 0x00, 0x00, 0xc9, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0xc6, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xcd, 0x00, 0x00, 0x00, + 0x93, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0xce, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x00, 0xcd, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0xcb, 0x00, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, + 0xbc, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0xd1, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0xd2, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, + 0xd1, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xcf, 0x00, 0x00, 0x00, + 0xd2, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0xd5, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, + 0xd5, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xd4, 0x00, 0x00, 0x00, + 0xd6, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0xd8, 0x00, 0x00, 0x00, 0x9b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0xd7, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00, 0x39, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x00, 0x00, 0xd9, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, + 0xd4, 0x00, 0x00, 0x00, 0xd7, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0xd3, 0x00, 0x00, 0x00, 0xd9, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x06, 0x00, 0x07, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0xda, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00, 0x00, + 0xcf, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0xdf, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00, 0x00, + 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, + 0xdf, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, + 0x35, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xe1, 0x00, 0x00, 0x00, + 0xe0, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0xe2, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, + 0x85, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, + 0xe2, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0xcf, 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0xe5, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0xe6, 0x00, 0x00, 0x00, 0xe5, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0xe8, 0x00, 0x00, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x00, 0xe6, 0x00, 0x00, 0x00, + 0xe8, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0xea, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0xea, 0x00, 0x00, 0x00, 0xe9, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xeb, 0x00, 0x00, 0x00, + 0xcf, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00, 0xeb, 0x00, 0x00, 0x00, + 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0xed, 0x00, 0x00, 0x00, + 0xec, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, + 0x35, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xee, 0x00, 0x00, 0x00, + 0xed, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0xf0, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, + 0xf0, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0xf2, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xf3, 0x00, 0x00, 0x00, + 0xcf, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0xf3, 0x00, 0x00, 0x00, 0xf2, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x00, + 0xcf, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0xf6, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0xcf, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x00, 0x00, + 0xda, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0xf8, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, + 0xf7, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xcf, 0x00, 0x00, 0x00, + 0xf9, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0xfa, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0x00, + 0x81, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, + 0xfa, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0xcb, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, + 0xc5, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xfd, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0xbc, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, + 0x01, 0x01, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0xfe, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x05, 0x01, 0x00, 0x00, + 0x93, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x06, 0x01, 0x00, 0x00, 0x05, 0x01, 0x00, 0x00, + 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x01, 0x00, 0x00, + 0x04, 0x01, 0x00, 0x00, 0x06, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x03, 0x01, 0x00, 0x00, 0x07, 0x01, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x0a, 0x01, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, + 0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, + 0x0a, 0x01, 0x00, 0x00, 0x0b, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x08, 0x01, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x0e, 0x01, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x0d, 0x01, 0x00, 0x00, 0x0e, 0x01, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, + 0x9b, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x0f, 0x01, 0x00, 0x00, + 0x10, 0x01, 0x00, 0x00, 0x39, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x11, 0x01, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x0d, 0x01, 0x00, 0x00, + 0x0f, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xd3, 0x00, 0x00, 0x00, + 0x11, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x13, 0x01, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x12, 0x01, 0x00, 0x00, 0x14, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16, 0x01, 0x00, 0x00, + 0x08, 0x01, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x17, 0x01, 0x00, 0x00, 0x15, 0x01, 0x00, 0x00, 0x16, 0x01, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x08, 0x01, 0x00, 0x00, 0x17, 0x01, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, + 0x08, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x19, 0x01, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x1a, 0x01, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, + 0x19, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x08, 0x01, 0x00, 0x00, + 0x1a, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x1b, 0x01, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x00, 0x00, 0x1b, 0x01, 0x00, 0x00, + 0xef, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x08, 0x01, 0x00, 0x00, + 0x1c, 0x01, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x1d, 0x01, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x1e, 0x01, 0x00, 0x00, + 0x1d, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x1f, 0x01, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x1f, 0x01, 0x00, 0x00, + 0x1e, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x08, 0x01, 0x00, 0x00, + 0x20, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x21, 0x01, 0x00, 0x00, 0x12, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x22, 0x01, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, + 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x23, 0x01, 0x00, 0x00, + 0x22, 0x01, 0x00, 0x00, 0x21, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x08, 0x01, 0x00, 0x00, 0x23, 0x01, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x24, 0x01, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x00, + 0x35, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x25, 0x01, 0x00, 0x00, 0x24, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x26, 0x01, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x27, 0x01, 0x00, 0x00, + 0x08, 0x01, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x28, 0x01, 0x00, 0x00, 0x26, 0x01, 0x00, 0x00, 0x27, 0x01, 0x00, 0x00, + 0x50, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x29, 0x01, 0x00, 0x00, + 0x25, 0x01, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0xcb, 0x00, 0x00, 0x00, 0x29, 0x01, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, + 0xc5, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xc5, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x2e, 0x01, 0x00, 0x00, 0x31, 0x01, 0x00, 0x00, + 0x30, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x32, 0x01, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00, 0x57, 0x00, 0x05, 0x00, + 0xb7, 0x00, 0x00, 0x00, 0x33, 0x01, 0x00, 0x00, 0x31, 0x01, 0x00, 0x00, + 0x32, 0x01, 0x00, 0x00, 0x4f, 0x00, 0x08, 0x00, 0x2a, 0x01, 0x00, 0x00, + 0x34, 0x01, 0x00, 0x00, 0x33, 0x01, 0x00, 0x00, 0x33, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x2c, 0x01, 0x00, 0x00, 0x34, 0x01, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x79, 0x00, 0x00, 0x00, 0x36, 0x01, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x35, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x37, 0x01, 0x00, 0x00, 0x36, 0x01, 0x00, 0x00, + 0xab, 0x00, 0x05, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, + 0x37, 0x01, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, + 0x3a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, + 0x38, 0x01, 0x00, 0x00, 0x39, 0x01, 0x00, 0x00, 0x3a, 0x01, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0x39, 0x01, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x79, 0x00, 0x00, 0x00, 0x3c, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x3b, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x3d, 0x01, 0x00, 0x00, 0x3c, 0x01, 0x00, 0x00, 0xab, 0x00, 0x05, 0x00, + 0x4c, 0x00, 0x00, 0x00, 0x3e, 0x01, 0x00, 0x00, 0x3d, 0x01, 0x00, 0x00, + 0x69, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0x40, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x3e, 0x01, 0x00, 0x00, + 0x3f, 0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0x3f, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x2a, 0x01, 0x00, 0x00, + 0x41, 0x01, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x43, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x42, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x44, 0x01, 0x00, 0x00, 0x43, 0x01, 0x00, 0x00, 0x50, 0x00, 0x06, 0x00, + 0x2a, 0x01, 0x00, 0x00, 0x45, 0x01, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00, + 0x44, 0x01, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x07, 0x00, + 0x2a, 0x01, 0x00, 0x00, 0x46, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x1a, 0x00, 0x00, 0x00, 0x41, 0x01, 0x00, 0x00, 0x45, 0x01, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x2c, 0x01, 0x00, 0x00, 0x46, 0x01, 0x00, 0x00, + 0xf9, 0x00, 0x02, 0x00, 0x40, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0x40, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x47, 0x01, 0x00, 0x00, 0xd3, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x49, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x48, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x4a, 0x01, 0x00, 0x00, 0x49, 0x01, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x4b, 0x01, 0x00, 0x00, 0x47, 0x01, 0x00, 0x00, + 0x4a, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x2a, 0x01, 0x00, 0x00, + 0x4c, 0x01, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, 0x8e, 0x00, 0x05, 0x00, + 0x2a, 0x01, 0x00, 0x00, 0x4d, 0x01, 0x00, 0x00, 0x4c, 0x01, 0x00, 0x00, + 0x4b, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x2c, 0x01, 0x00, 0x00, + 0x4d, 0x01, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x79, 0x00, 0x00, 0x00, + 0x4e, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x3b, 0x01, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, 0x4f, 0x01, 0x00, 0x00, + 0x4e, 0x01, 0x00, 0x00, 0xab, 0x00, 0x05, 0x00, 0x4c, 0x00, 0x00, 0x00, + 0x50, 0x01, 0x00, 0x00, 0x4f, 0x01, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, + 0xf7, 0x00, 0x03, 0x00, 0x52, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfa, 0x00, 0x04, 0x00, 0x50, 0x01, 0x00, 0x00, 0x51, 0x01, 0x00, 0x00, + 0x52, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x51, 0x01, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x2a, 0x01, 0x00, 0x00, 0x53, 0x01, 0x00, 0x00, + 0x2c, 0x01, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x55, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x54, 0x01, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x56, 0x01, 0x00, 0x00, + 0x55, 0x01, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x57, 0x01, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x56, 0x01, 0x00, 0x00, + 0x50, 0x00, 0x06, 0x00, 0x2a, 0x01, 0x00, 0x00, 0x58, 0x01, 0x00, 0x00, + 0x57, 0x01, 0x00, 0x00, 0x57, 0x01, 0x00, 0x00, 0x57, 0x01, 0x00, 0x00, + 0x0c, 0x00, 0x07, 0x00, 0x2a, 0x01, 0x00, 0x00, 0x59, 0x01, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x53, 0x01, 0x00, 0x00, + 0x58, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x2c, 0x01, 0x00, 0x00, + 0x59, 0x01, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x52, 0x01, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0x52, 0x01, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, + 0x3a, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x3a, 0x01, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x79, 0x00, 0x00, 0x00, 0x5b, 0x01, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x00, 0x00, 0x5b, 0x01, 0x00, 0x00, + 0xaa, 0x00, 0x05, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x5d, 0x01, 0x00, 0x00, + 0x5c, 0x01, 0x00, 0x00, 0x6e, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, + 0x5f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, + 0x5d, 0x01, 0x00, 0x00, 0x5e, 0x01, 0x00, 0x00, 0x7c, 0x01, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0x5e, 0x01, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x63, 0x01, 0x00, 0x00, 0x64, 0x01, 0x00, 0x00, 0x62, 0x01, 0x00, 0x00, + 0x35, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x65, 0x01, 0x00, 0x00, 0x64, 0x01, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x66, 0x01, 0x00, 0x00, 0x65, 0x01, 0x00, 0x00, + 0x2f, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x67, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x66, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x60, 0x01, 0x00, 0x00, + 0x67, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x69, 0x01, 0x00, 0x00, 0x60, 0x01, 0x00, 0x00, 0xb8, 0x00, 0x05, 0x00, + 0x4c, 0x00, 0x00, 0x00, 0x6a, 0x01, 0x00, 0x00, 0x69, 0x01, 0x00, 0x00, + 0x2f, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0x6d, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x6a, 0x01, 0x00, 0x00, + 0x6c, 0x01, 0x00, 0x00, 0x74, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0x6c, 0x01, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x6f, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x6e, 0x01, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x70, 0x01, 0x00, 0x00, + 0x6f, 0x01, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x71, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x6e, 0x01, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x72, 0x01, 0x00, 0x00, + 0x71, 0x01, 0x00, 0x00, 0x50, 0x00, 0x06, 0x00, 0x2a, 0x01, 0x00, 0x00, + 0x73, 0x01, 0x00, 0x00, 0x70, 0x01, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, + 0x72, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x6b, 0x01, 0x00, 0x00, + 0x73, 0x01, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x6d, 0x01, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0x74, 0x01, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x75, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x6e, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x76, 0x01, 0x00, 0x00, 0x75, 0x01, 0x00, 0x00, 0x50, 0x00, 0x06, 0x00, + 0x2a, 0x01, 0x00, 0x00, 0x77, 0x01, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, + 0x76, 0x01, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x6b, 0x01, 0x00, 0x00, 0x77, 0x01, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, + 0x6d, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x6d, 0x01, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x2a, 0x01, 0x00, 0x00, 0x78, 0x01, 0x00, 0x00, + 0x6b, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x68, 0x01, 0x00, 0x00, + 0x78, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x2a, 0x01, 0x00, 0x00, + 0x79, 0x01, 0x00, 0x00, 0x68, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x2a, 0x01, 0x00, 0x00, 0x7a, 0x01, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, + 0x85, 0x00, 0x05, 0x00, 0x2a, 0x01, 0x00, 0x00, 0x7b, 0x01, 0x00, 0x00, + 0x7a, 0x01, 0x00, 0x00, 0x79, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x2c, 0x01, 0x00, 0x00, 0x7b, 0x01, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, + 0x5f, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x7c, 0x01, 0x00, 0x00, + 0x41, 0x00, 0x05, 0x00, 0x79, 0x00, 0x00, 0x00, 0x7d, 0x01, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x5a, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x7e, 0x01, 0x00, 0x00, 0x7d, 0x01, 0x00, 0x00, + 0xaa, 0x00, 0x05, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x7f, 0x01, 0x00, 0x00, + 0x7e, 0x01, 0x00, 0x00, 0x48, 0x01, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, + 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, + 0x7f, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x81, 0x01, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0x80, 0x01, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x63, 0x01, 0x00, 0x00, 0x83, 0x01, 0x00, 0x00, 0x62, 0x01, 0x00, 0x00, + 0x35, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x84, 0x01, 0x00, 0x00, 0x83, 0x01, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x85, 0x01, 0x00, 0x00, 0x84, 0x01, 0x00, 0x00, + 0x8d, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x86, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x85, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x82, 0x01, 0x00, 0x00, + 0x86, 0x01, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x88, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x6e, 0x01, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x89, 0x01, 0x00, 0x00, + 0x88, 0x01, 0x00, 0x00, 0x50, 0x00, 0x06, 0x00, 0x2a, 0x01, 0x00, 0x00, + 0x8a, 0x01, 0x00, 0x00, 0x89, 0x01, 0x00, 0x00, 0x89, 0x01, 0x00, 0x00, + 0x89, 0x01, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x87, 0x01, 0x00, 0x00, + 0x8a, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x8b, 0x01, 0x00, 0x00, 0x82, 0x01, 0x00, 0x00, 0xb8, 0x00, 0x05, 0x00, + 0x4c, 0x00, 0x00, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x8b, 0x01, 0x00, 0x00, + 0x8d, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0x8e, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x8c, 0x01, 0x00, 0x00, + 0x8d, 0x01, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0x8d, 0x01, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x8f, 0x01, 0x00, 0x00, 0x87, 0x01, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x8f, 0x01, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, + 0xf9, 0x00, 0x02, 0x00, 0x8e, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0x90, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x91, 0x01, 0x00, 0x00, 0x82, 0x01, 0x00, 0x00, 0xb8, 0x00, 0x05, 0x00, + 0x4c, 0x00, 0x00, 0x00, 0x93, 0x01, 0x00, 0x00, 0x91, 0x01, 0x00, 0x00, + 0x92, 0x01, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0x95, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x93, 0x01, 0x00, 0x00, + 0x94, 0x01, 0x00, 0x00, 0x97, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0x94, 0x01, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x96, 0x01, 0x00, 0x00, 0x87, 0x01, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x96, 0x01, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, + 0xf9, 0x00, 0x02, 0x00, 0x95, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0x97, 0x01, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x99, 0x01, 0x00, 0x00, 0x87, 0x01, 0x00, 0x00, 0x98, 0x01, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x99, 0x01, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, + 0xf9, 0x00, 0x02, 0x00, 0x95, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0x95, 0x01, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x8e, 0x01, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0x8e, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x2a, 0x01, 0x00, 0x00, 0x9a, 0x01, 0x00, 0x00, 0x87, 0x01, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x2a, 0x01, 0x00, 0x00, 0x9b, 0x01, 0x00, 0x00, + 0x2c, 0x01, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x2a, 0x01, 0x00, 0x00, + 0x9c, 0x01, 0x00, 0x00, 0x9b, 0x01, 0x00, 0x00, 0x9a, 0x01, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x2c, 0x01, 0x00, 0x00, 0x9c, 0x01, 0x00, 0x00, + 0xf9, 0x00, 0x02, 0x00, 0x81, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0x81, 0x01, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x5f, 0x01, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x2a, 0x01, 0x00, 0x00, 0x9d, 0x01, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x00, + 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x9e, 0x01, 0x00, 0x00, + 0x9d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x9f, 0x01, 0x00, 0x00, 0x9d, 0x01, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0xa0, 0x01, 0x00, 0x00, 0x9d, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x07, 0x00, 0xb7, 0x00, 0x00, 0x00, 0xa1, 0x01, 0x00, 0x00, + 0x9e, 0x01, 0x00, 0x00, 0x9f, 0x01, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, + 0x26, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0xb9, 0x00, 0x00, 0x00, + 0xa1, 0x01, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00, + 0x36, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x1f, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x22, 0x00, 0x00, 0x00, 0x50, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x18, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x29, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, + 0x26, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x83, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, + 0x29, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x25, 0x00, 0x00, 0x00, + 0x2b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x85, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, + 0x2d, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x83, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, + 0x31, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x35, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x37, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x35, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x39, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, + 0x39, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x3c, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, + 0x3c, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, + 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, + 0x3a, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x33, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x44, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x46, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, + 0x25, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x4a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, + 0x49, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x4b, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x4d, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, + 0x4d, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x4f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x4e, 0x00, 0x00, 0x00, 0xbe, 0x00, 0x05, 0x00, 0x4c, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, + 0xa8, 0x00, 0x04, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0x53, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x51, 0x00, 0x00, 0x00, + 0x52, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0x52, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x54, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, + 0x54, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x56, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x55, 0x00, 0x00, 0x00, 0xbe, 0x00, 0x05, 0x00, 0x4c, 0x00, 0x00, 0x00, + 0x57, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, + 0xf9, 0x00, 0x02, 0x00, 0x53, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0x53, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x07, 0x00, 0x4c, 0x00, 0x00, 0x00, + 0x58, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x57, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, + 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, + 0x58, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0x59, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, + 0x5c, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x5a, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x5f, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x61, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x88, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x61, 0x00, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x62, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x63, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x02, 0x00, + 0x63, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0x00, 0x36, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x67, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00, + 0x67, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x6a, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x69, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, + 0x6a, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x6c, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x6b, 0x00, 0x00, 0x00, + 0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, + 0x26, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x6e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x07, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0xfe, 0x00, 0x02, 0x00, 0x71, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0x00, + 0x36, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x37, 0x00, 0x03, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0x17, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x89, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x75, 0x00, 0x00, 0x00, 0x76, 0x00, 0x00, 0x00, + 0x39, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, + 0x79, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x78, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x7b, 0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0xab, 0x00, 0x05, 0x00, + 0x4c, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, + 0x69, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x03, 0x00, 0x7e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfa, 0x00, 0x04, 0x00, 0x7c, 0x00, 0x00, 0x00, + 0x7d, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, + 0x7d, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x7f, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x83, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, + 0x7f, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x82, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x82, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x84, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, + 0x83, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x74, 0x00, 0x00, 0x00, + 0x85, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x86, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x81, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, + 0x86, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, + 0x89, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x39, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x89, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x8b, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, + 0x8a, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x74, 0x00, 0x00, 0x00, + 0x8c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x8e, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x85, 0x00, 0x05, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, + 0x8d, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x03, 0x00, 0x74, 0x00, 0x00, 0x00, + 0x8f, 0x00, 0x00, 0x00, 0xf9, 0x00, 0x02, 0x00, 0x7e, 0x00, 0x00, 0x00, + 0xf8, 0x00, 0x02, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, + 0xfe, 0x00, 0x02, 0x00, 0x90, 0x00, 0x00, 0x00, 0x38, 0x00, 0x01, 0x00 +}; +static const size_t kcrtpi_frag_spv_size = 10356; diff --git a/source/core/rendering/sdl3gpu/sdl3gpu_shader.cpp b/source/core/rendering/sdl3gpu/sdl3gpu_shader.cpp index 2dbb0bf..ca99909 100644 --- a/source/core/rendering/sdl3gpu/sdl3gpu_shader.cpp +++ b/source/core/rendering/sdl3gpu/sdl3gpu_shader.cpp @@ -7,6 +7,7 @@ #include // memcpy, strlen #ifndef __APPLE__ +#include "core/rendering/sdl3gpu/crtpi_frag_spv.h" #include "core/rendering/sdl3gpu/downscale_frag_spv.h" #include "core/rendering/sdl3gpu/postfx_frag_spv.h" #include "core/rendering/sdl3gpu/postfx_vert_spv.h" @@ -228,6 +229,136 @@ fragment float4 downscale_fs(VertOut in [[stage_in]], return (weight_sum > 0.0f) ? (color / weight_sum) : float4(0.0f, 0.0f, 0.0f, 1.0f); } )"; +static const char* CRTPI_FRAG_MSL = R"( +#include +using namespace metal; + +struct PostVOut { + float4 pos [[position]]; + float2 uv; +}; + +struct CrtPiUniforms { + // vec4 #0 + float scanline_weight; + float scanline_gap_brightness; + float bloom_factor; + float input_gamma; + // vec4 #1 + float output_gamma; + float mask_brightness; + float curvature_x; + float curvature_y; + // vec4 #2 + int mask_type; + int enable_scanlines; + int enable_multisample; + int enable_gamma; + // vec4 #3 + int enable_curvature; + int enable_sharper; + float texture_width; + float texture_height; +}; + +static float2 crtpi_distort(float2 coord, float2 screen_scale, float cx, float cy) { + float2 curvature = float2(cx, cy); + float2 barrel_scale = 1.0f - (0.23f * curvature); + coord *= screen_scale; + coord -= 0.5f; + float rsq = coord.x * coord.x + coord.y * coord.y; + coord += coord * (curvature * rsq); + coord *= barrel_scale; + if (abs(coord.x) >= 0.5f || abs(coord.y) >= 0.5f) { return float2(-1.0f); } + coord += 0.5f; + coord /= screen_scale; + return coord; +} + +static float crtpi_scan_weight(float dist, float sw, float gap) { + return max(1.0f - dist * dist * sw, gap); +} + +static float crtpi_scan_line(float dy, float filter_w, float sw, float gap, bool ms) { + float w = crtpi_scan_weight(dy, sw, gap); + if (ms) { + w += crtpi_scan_weight(dy - filter_w, sw, gap); + w += crtpi_scan_weight(dy + filter_w, sw, gap); + w *= 0.3333333f; + } + return w; +} + +fragment float4 crtpi_fs(PostVOut in [[stage_in]], + texture2d tex [[texture(0)]], + sampler samp [[sampler(0)]], + constant CrtPiUniforms& u [[buffer(0)]]) { + float2 tex_size = float2(u.texture_width, u.texture_height); + float filter_width = (768.0f / u.texture_height) / 3.0f; + float2 texcoord = in.uv; + + if (u.enable_curvature != 0) { + texcoord = crtpi_distort(texcoord, float2(1.0f, 1.0f), u.curvature_x, u.curvature_y); + if (texcoord.x < 0.0f) { return float4(0.0f, 0.0f, 0.0f, 1.0f); } + } + + float2 coord_in_pixels = texcoord * tex_size; + float2 tc; + float scan_weight; + + if (u.enable_sharper != 0) { + float2 temp = floor(coord_in_pixels) + 0.5f; + tc = temp / tex_size; + float2 deltas = coord_in_pixels - temp; + scan_weight = crtpi_scan_line(deltas.y, filter_width, u.scanline_weight, u.scanline_gap_brightness, u.enable_multisample != 0); + float2 signs = sign(deltas); + deltas.x *= 2.0f; + deltas = deltas * deltas; + deltas.y = deltas.y * deltas.y; + deltas.x *= 0.5f; + deltas.y *= 8.0f; + deltas /= tex_size; + deltas *= signs; + tc = tc + deltas; + } else { + float temp_y = floor(coord_in_pixels.y) + 0.5f; + float y_coord = temp_y / tex_size.y; + float dy = coord_in_pixels.y - temp_y; + scan_weight = crtpi_scan_line(dy, filter_width, u.scanline_weight, u.scanline_gap_brightness, u.enable_multisample != 0); + float sign_y = sign(dy); + dy = dy * dy; + dy = dy * dy; + dy *= 8.0f; + dy /= tex_size.y; + dy *= sign_y; + tc = float2(texcoord.x, y_coord + dy); + } + + float3 colour = tex.sample(samp, tc).rgb; + + if (u.enable_scanlines != 0) { + if (u.enable_gamma != 0) { colour = pow(colour, float3(u.input_gamma)); } + colour *= scan_weight * u.bloom_factor; + if (u.enable_gamma != 0) { colour = pow(colour, float3(1.0f / u.output_gamma)); } + } + + if (u.mask_type == 1) { + float wm = fract(in.pos.x * 0.5f); + float3 mask = (wm < 0.5f) ? float3(u.mask_brightness, 1.0f, u.mask_brightness) + : float3(1.0f, u.mask_brightness, 1.0f); + colour *= mask; + } else if (u.mask_type == 2) { + float wm = fract(in.pos.x * 0.3333333f); + float3 mask = float3(u.mask_brightness); + if (wm < 0.3333333f) mask.x = 1.0f; + else if (wm < 0.6666666f) mask.y = 1.0f; + else mask.z = 1.0f; + colour *= mask; + } + + return float4(colour, 1.0f); +} +)"; // NOLINTEND(readability-identifier-naming) #endif // __APPLE__ @@ -379,6 +510,14 @@ namespace Rendering { return false; } + // ---------------------------------------------------------------- + // 7. Create CrtPi graphics pipeline + // ---------------------------------------------------------------- + if (!createCrtPiPipeline()) { + cleanup(); + return false; + } + is_initialized_ = true; SDL_Log("SDL3GPUShader: initialized OK — game %dx%d, oversample %d", game_width_, game_height_, oversample_); return true; @@ -552,6 +691,61 @@ namespace Rendering { return true; } + // --------------------------------------------------------------------------- + // createCrtPiPipeline — pipeline dedicado para el shader CRT-Pi. + // Usa el mismo vertex shader que postfx (fullscreen-triangle genérico). + // El fragment shader es específico para el algoritmo CRT-Pi. + // Sin supersampling ni Lanczos: va siempre directo al swapchain. + // --------------------------------------------------------------------------- + auto SDL3GPUShader::createCrtPiPipeline() -> bool { + const SDL_GPUTextureFormat SWAPCHAIN_FMT = SDL_GetGPUSwapchainTextureFormat(device_, window_); + +#ifdef __APPLE__ + SDL_GPUShader* vert = createShaderMSL(device_, POSTFX_VERT_MSL, "postfx_vs", SDL_GPU_SHADERSTAGE_VERTEX, 0, 0); + SDL_GPUShader* frag = createShaderMSL(device_, CRTPI_FRAG_MSL, "crtpi_fs", SDL_GPU_SHADERSTAGE_FRAGMENT, 1, 1); +#else + SDL_GPUShader* vert = createShaderSPIRV(device_, kpostfx_vert_spv, kpostfx_vert_spv_size, "main", SDL_GPU_SHADERSTAGE_VERTEX, 0, 0); + SDL_GPUShader* frag = createShaderSPIRV(device_, kcrtpi_frag_spv, kcrtpi_frag_spv_size, "main", SDL_GPU_SHADERSTAGE_FRAGMENT, 1, 1); +#endif + + if ((vert == nullptr) || (frag == nullptr)) { + SDL_Log("SDL3GPUShader: failed to compile CrtPi shaders"); + if (vert != nullptr) { SDL_ReleaseGPUShader(device_, vert); } + if (frag != nullptr) { SDL_ReleaseGPUShader(device_, frag); } + return false; + } + + SDL_GPUColorTargetBlendState no_blend = {}; + no_blend.enable_blend = false; + no_blend.enable_color_write_mask = false; + + SDL_GPUColorTargetDescription color_target = {}; + color_target.format = SWAPCHAIN_FMT; + color_target.blend_state = no_blend; + + SDL_GPUVertexInputState no_input = {}; + + SDL_GPUGraphicsPipelineCreateInfo pipe_info = {}; + pipe_info.vertex_shader = vert; + pipe_info.fragment_shader = frag; + pipe_info.vertex_input_state = no_input; + pipe_info.primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST; + pipe_info.target_info.num_color_targets = 1; + pipe_info.target_info.color_target_descriptions = &color_target; + + crtpi_pipeline_ = SDL_CreateGPUGraphicsPipeline(device_, &pipe_info); + + SDL_ReleaseGPUShader(device_, vert); + SDL_ReleaseGPUShader(device_, frag); + + if (crtpi_pipeline_ == nullptr) { + SDL_Log("SDL3GPUShader: CrtPi pipeline creation failed: %s", SDL_GetError()); + return false; + } + + return true; + } + // --------------------------------------------------------------------------- // uploadPixels — copies ARGB8888 CPU pixels into the GPU transfer buffer. // Con supersampling (oversample_ > 1) expande cada pixel del juego a un bloque @@ -681,6 +875,38 @@ namespace Rendering { ? static_cast(ss_factor_) : 1.0F; + // ---- Path CrtPi: directo scene_texture_ → swapchain, sin SS ni Lanczos ---- + if (active_shader_ == ShaderType::CRTPI && crtpi_pipeline_ != nullptr) { + SDL_GPUColorTargetInfo color_target = {}; + color_target.texture = swapchain; + color_target.load_op = SDL_GPU_LOADOP_CLEAR; + color_target.store_op = SDL_GPU_STOREOP_STORE; + color_target.clear_color = {.r = 0.0F, .g = 0.0F, .b = 0.0F, .a = 1.0F}; + + SDL_GPURenderPass* pass = SDL_BeginGPURenderPass(cmd, &color_target, 1, nullptr); + if (pass != nullptr) { + SDL_BindGPUGraphicsPipeline(pass, crtpi_pipeline_); + SDL_GPUViewport vp = {.x = vx, .y = vy, .w = vw, .h = vh, .min_depth = 0.0F, .max_depth = 1.0F}; + SDL_SetGPUViewport(pass, &vp); + + SDL_GPUTextureSamplerBinding binding = {}; + binding.texture = scene_texture_; + binding.sampler = sampler_; // NEAREST: el shader CrtPi hace su propio filtrado analítico + SDL_BindGPUFragmentSamplers(pass, 0, &binding, 1); + + // Inyectar texture_width/height antes del push + crtpi_uniforms_.texture_width = static_cast(game_width_); + crtpi_uniforms_.texture_height = static_cast(game_height_); + SDL_PushGPUFragmentUniformData(cmd, 0, &crtpi_uniforms_, sizeof(CrtPiUniforms)); + + SDL_DrawGPUPrimitives(pass, 3, 1, 0, 0); + SDL_EndGPURenderPass(pass); + } + + SDL_SubmitGPUCommandBuffer(cmd); + return; + } + // ---- Determinar si usar el path Lanczos (SS activo + algo seleccionado) ---- const bool USE_LANCZOS = (oversample_ > 1 && downscale_algo_ > 0 && scaled_texture_ != nullptr && postfx_texture_ != nullptr && postfx_offscreen_pipeline_ != nullptr && downscale_pipeline_ != nullptr); @@ -776,6 +1002,10 @@ namespace Rendering { SDL_ReleaseGPUGraphicsPipeline(device_, pipeline_); pipeline_ = nullptr; } + if (crtpi_pipeline_ != nullptr) { + SDL_ReleaseGPUGraphicsPipeline(device_, crtpi_pipeline_); + crtpi_pipeline_ = nullptr; + } if (postfx_offscreen_pipeline_ != nullptr) { SDL_ReleaseGPUGraphicsPipeline(device_, postfx_offscreen_pipeline_); postfx_offscreen_pipeline_ = nullptr; @@ -892,6 +1122,28 @@ namespace Rendering { uniforms_.scanline_strength = p.scanlines; } + void SDL3GPUShader::setCrtPiParams(const CrtPiParams& p) { + crtpi_uniforms_.scanline_weight = p.scanline_weight; + crtpi_uniforms_.scanline_gap_brightness = p.scanline_gap_brightness; + crtpi_uniforms_.bloom_factor = p.bloom_factor; + crtpi_uniforms_.input_gamma = p.input_gamma; + crtpi_uniforms_.output_gamma = p.output_gamma; + crtpi_uniforms_.mask_brightness = p.mask_brightness; + crtpi_uniforms_.curvature_x = p.curvature_x; + crtpi_uniforms_.curvature_y = p.curvature_y; + crtpi_uniforms_.mask_type = p.mask_type; + crtpi_uniforms_.enable_scanlines = p.enable_scanlines ? 1 : 0; + crtpi_uniforms_.enable_multisample = p.enable_multisample ? 1 : 0; + crtpi_uniforms_.enable_gamma = p.enable_gamma ? 1 : 0; + crtpi_uniforms_.enable_curvature = p.enable_curvature ? 1 : 0; + crtpi_uniforms_.enable_sharper = p.enable_sharper ? 1 : 0; + // texture_width/height se inyectan en render() cada frame + } + + void SDL3GPUShader::setActiveShader(ShaderType type) { + active_shader_ = type; + } + void SDL3GPUShader::setVSync(bool vsync) { vsync_ = vsync; if (device_ != nullptr && window_ != nullptr) { diff --git a/source/core/rendering/sdl3gpu/sdl3gpu_shader.hpp b/source/core/rendering/sdl3gpu/sdl3gpu_shader.hpp index 52326ac..d4b5587 100644 --- a/source/core/rendering/sdl3gpu/sdl3gpu_shader.hpp +++ b/source/core/rendering/sdl3gpu/sdl3gpu_shader.hpp @@ -23,6 +23,32 @@ struct PostFXUniforms { float flicker; // 0 = off, 1 = phosphor flicker ~50 Hz — keep struct at 48 bytes (3 × 16) }; +// CrtPi uniforms pushed to fragment stage each frame. +// Must match the MSL struct and GLSL uniform block layout. +// 14 fields (8 floats + 6 ints) + 2 floats (texture size) = 16 fields = 64 bytes — 4 × 16-byte alignment. +struct CrtPiUniforms { + // vec4 #0 + float scanline_weight; // Ajuste gaussiano (default 6.0) + float scanline_gap_brightness; // Brillo mínimo entre scanlines (default 0.12) + float bloom_factor; // Factor brillo zonas iluminadas (default 3.5) + float input_gamma; // Gamma de entrada (default 2.4) + // vec4 #1 + float output_gamma; // Gamma de salida (default 2.2) + float mask_brightness; // Brillo sub-píxeles máscara (default 0.80) + float curvature_x; // Distorsión barrel X (default 0.05) + float curvature_y; // Distorsión barrel Y (default 0.10) + // vec4 #2 + int mask_type; // 0=ninguna, 1=verde/magenta, 2=RGB fósforo + int enable_scanlines; // 0 = off, 1 = on + int enable_multisample; // 0 = off, 1 = on (antialiasing analítico) + int enable_gamma; // 0 = off, 1 = on + // vec4 #3 + int enable_curvature; // 0 = off, 1 = on + int enable_sharper; // 0 = off, 1 = on + float texture_width; // Ancho del canvas en píxeles (inyectado en render) + float texture_height; // Alto del canvas en píxeles (inyectado en render) +}; + // Downscale uniforms pushed to the Lanczos downscale fragment stage. // 1 int + 3 floats = 16 bytes — meets Metal/Vulkan alignment. struct DownscaleUniforms { @@ -85,6 +111,15 @@ namespace Rendering { // Devuelve las dimensiones de la textura de supersampling (0,0 si SS desactivado) [[nodiscard]] auto getSsTextureSize() const -> std::pair override; + // Selecciona el shader de post-procesado activo (POSTFX o CRTPI) + void setActiveShader(ShaderType type) override; + + // Actualiza los parámetros del shader CRT-Pi + void setCrtPiParams(const CrtPiParams& p) override; + + // Devuelve el shader activo + [[nodiscard]] auto getActiveShader() const -> ShaderType override { return active_shader_; } + private: static auto createShaderMSL(SDL_GPUDevice* device, const char* msl_source, @@ -102,6 +137,7 @@ namespace Rendering { Uint32 num_uniform_buffers) -> SDL_GPUShader*; auto createPipeline() -> bool; + auto createCrtPiPipeline() -> bool; // Pipeline dedicado para el shader CrtPi auto reinitTexturesAndBuffer() -> bool; // Recrea scene_texture_ y upload_buffer_ auto recreateScaledTexture(int factor) -> bool; // Recrea scaled_texture_ para factor dado static auto calcSsFactor(float zoom) -> int; // Primer múltiplo de 3 >= zoom (mín 3) @@ -109,6 +145,7 @@ namespace Rendering { SDL_Window* window_ = nullptr; SDL_GPUDevice* device_ = nullptr; SDL_GPUGraphicsPipeline* pipeline_ = nullptr; // PostFX pass (→ swapchain o → postfx_texture_) + SDL_GPUGraphicsPipeline* crtpi_pipeline_ = nullptr; // CrtPi pass (→ swapchain directo, sin SS) SDL_GPUGraphicsPipeline* postfx_offscreen_pipeline_ = nullptr; // PostFX → postfx_texture_ (B8G8R8A8, solo con Lanczos) SDL_GPUGraphicsPipeline* upscale_pipeline_ = nullptr; // Upscale pass (solo con SS) SDL_GPUGraphicsPipeline* downscale_pipeline_ = nullptr; // Lanczos downscale (solo con SS + algo > 0) @@ -120,6 +157,8 @@ namespace Rendering { SDL_GPUSampler* linear_sampler_ = nullptr; // LINEAR PostFXUniforms uniforms_{.vignette_strength = 0.6F, .chroma_strength = 0.15F, .scanline_strength = 0.7F, .screen_height = 192.0F, .pixel_scale = 1.0F, .oversample = 1.0F}; + CrtPiUniforms crtpi_uniforms_{.scanline_weight = 6.0F, .scanline_gap_brightness = 0.12F, .bloom_factor = 3.5F, .input_gamma = 2.4F, .output_gamma = 2.2F, .mask_brightness = 0.80F, .curvature_x = 0.05F, .curvature_y = 0.10F, .mask_type = 2, .enable_scanlines = 1, .enable_multisample = 1, .enable_gamma = 1}; + ShaderType active_shader_ = ShaderType::POSTFX; // Shader de post-procesado activo int game_width_ = 0; // Dimensiones originales del canvas int game_height_ = 0; diff --git a/source/core/rendering/shader_backend.hpp b/source/core/rendering/shader_backend.hpp index e42f955..3a6468c 100644 --- a/source/core/rendering/shader_backend.hpp +++ b/source/core/rendering/shader_backend.hpp @@ -7,6 +7,9 @@ namespace Rendering { + /** @brief Identificador del shader de post-procesado activo */ + enum class ShaderType { POSTFX, CRTPI }; + /** * @brief Parámetros de intensidad de los efectos PostFX * Definido a nivel de namespace para facilitar el uso desde subclases y screen.cpp @@ -22,6 +25,27 @@ namespace Rendering { float flicker = 0.0F; // Parpadeo de fósforo CRT ~50 Hz }; + /** + * @brief Parámetros del shader CRT-Pi (algoritmo de scanlines continuas) + * Diferente al PostFX: usa pesos gaussianos por distancia subpixel y bloom. + */ + struct CrtPiParams { + float scanline_weight{6.0F}; // Ajuste gaussiano (mayor = scanlines más estrechas) + float scanline_gap_brightness{0.12F}; // Brillo mínimo en las ranuras entre scanlines + float bloom_factor{3.5F}; // Factor de brillo para zonas iluminadas + float input_gamma{2.4F}; // Gamma de entrada (linealización) + float output_gamma{2.2F}; // Gamma de salida (codificación) + float mask_brightness{0.80F}; // Sub-píxeles tenues en la máscara de fósforo + float curvature_x{0.05F}; // Distorsión barrel eje X + float curvature_y{0.10F}; // Distorsión barrel eje Y + int mask_type{2}; // 0=ninguna, 1=verde/magenta, 2=RGB fósforo + bool enable_scanlines{true}; // Activar efecto de scanlines + bool enable_multisample{true}; // Antialiasing analítico de scanlines + bool enable_gamma{true}; // Corrección gamma + bool enable_curvature{false}; // Distorsión barrel CRT + bool enable_sharper{false}; // Submuestreo más nítido (modo SHARPER) + }; + /** * @brief Interfaz abstracta para backends de renderizado con shaders * @@ -129,6 +153,22 @@ namespace Rendering { * Vacío = selección automática de SDL. Implementado en SDL3GPUShader. */ virtual void setPreferredDriver(const std::string& /*driver*/) {} + + /** + * @brief Selecciona el shader de post-procesado activo (POSTFX o CRTPI). + * Debe llamarse antes de render(). No recrea pipelines. + */ + virtual void setActiveShader(ShaderType /*type*/) {} + + /** + * @brief Establece los parámetros del shader CRT-Pi. + */ + virtual void setCrtPiParams(const CrtPiParams& /*p*/) {} + + /** + * @brief Devuelve el shader de post-procesado activo. + */ + [[nodiscard]] virtual auto getActiveShader() const -> ShaderType { return ShaderType::POSTFX; } }; } // namespace Rendering diff --git a/source/core/system/director.cpp b/source/core/system/director.cpp index 6dfcc47..11889e5 100644 --- a/source/core/system/director.cpp +++ b/source/core/system/director.cpp @@ -129,6 +129,10 @@ Director::Director(std::vector const& args) { Options::setPostFXFile(Resource::List::get()->get("postfx.yaml")); // NOLINT(readability-static-accessed-through-instance) Options::loadPostFXFromFile(); + // Configura la ruta y carga los presets del shader CrtPi + Options::setCrtPiFile(Resource::List::get()->get("crtpi.yaml")); // NOLINT(readability-static-accessed-through-instance) + Options::loadCrtPiFromFile(); + // En mode quiosc, forçar pantalla completa independentment de la configuració if (Options::kiosk.enabled) { Options::video.fullscreen = true; diff --git a/source/game/options.cpp b/source/game/options.cpp index 1554088..7ab8f70 100644 --- a/source/game/options.cpp +++ b/source/game/options.cpp @@ -2,6 +2,7 @@ #include +#include // Para create_directories #include // Para ifstream, ofstream #include // Para cout, cerr #include // Para string @@ -364,6 +365,23 @@ namespace Options { } } + if (vid.contains("current_crtpi_preset")) { + try { + current_crtpi_preset = vid["current_crtpi_preset"].get_value(); + } catch (...) { + current_crtpi_preset = 0; + } + } + + if (vid.contains("current_shader")) { + try { + const std::string s = vid["current_shader"].get_value(); + current_shader = (s == "crtpi") ? Rendering::ShaderType::CRTPI : Rendering::ShaderType::POSTFX; + } catch (...) { + current_shader = Rendering::ShaderType::POSTFX; + } + } + if (vid.contains("vertical_sync")) { try { video.vertical_sync = vid["vertical_sync"].get_value(); @@ -722,6 +740,8 @@ namespace Options { file << " postfx: " << (video.postfx ? "true" : "false") << "\n"; file << " supersampling: " << (video.supersampling ? "true" : "false") << "\n"; file << " current_postfx_preset: " << current_postfx_preset << "\n"; + file << " current_crtpi_preset: " << current_crtpi_preset << "\n"; + file << " current_shader: " << (current_shader == Rendering::ShaderType::CRTPI ? "crtpi" : "postfx") << "\n"; file << " vertical_sync: " << (video.vertical_sync ? "true" : "false") << "\n"; file << " integer_scale: " << (video.integer_scale ? "true" : "false") << "\n"; file << " keep_aspect: " << (video.keep_aspect ? "true" : "false") << "\n"; @@ -951,4 +971,188 @@ namespace Options { return true; } + void setCrtPiFile(const std::string& path) { + crtpi_file_path = path; + } + + // Carga los presets del shader CrtPi desde el fichero. Crea defaults si no existe. + auto loadCrtPiFromFile() -> bool { + crtpi_presets.clear(); + + std::ifstream file(crtpi_file_path); + if (!file.good()) { + if (console) { + std::cout << "CrtPi file not found, creating default: " << crtpi_file_path << '\n'; + } + // Crear directorio padre si no existe + const std::filesystem::path p(crtpi_file_path); + if (p.has_parent_path()) { + std::error_code ec; + std::filesystem::create_directories(p.parent_path(), ec); + } + // Escribir defaults + std::ofstream out(crtpi_file_path); + if (!out.is_open()) { + if (console) { + std::cerr << "Error: Cannot create CrtPi file: " << crtpi_file_path << '\n'; + } + // Cargar defaults en memoria aunque no se pueda escribir + crtpi_presets.push_back({"DEFAULT", 6.0F, 0.12F, 3.5F, 2.4F, 2.2F, 0.80F, 0.05F, 0.10F, 2, true, true, true, false, false}); + crtpi_presets.push_back({"CURVED", 6.0F, 0.12F, 3.5F, 2.4F, 2.2F, 0.80F, 0.05F, 0.10F, 2, true, true, true, true, false}); + crtpi_presets.push_back({"SHARP", 6.0F, 0.12F, 3.5F, 2.4F, 2.2F, 0.80F, 0.05F, 0.10F, 2, true, false, true, false, true}); + crtpi_presets.push_back({"MINIMAL", 8.0F, 0.05F, 2.0F, 2.4F, 2.2F, 1.00F, 0.0F, 0.0F, 0, true, false, false, false, false}); + current_crtpi_preset = 0; + return true; + } + out << "# JailDoctor's Dilemma - CrtPi Shader Presets\n"; + out << "# scanline_weight: ajuste gaussiano (mayor = scanlines mas estrechas, default 6.0)\n"; + out << "# scanline_gap_brightness: brillo minimo entre scanlines (0.0-1.0, default 0.12)\n"; + out << "# bloom_factor: factor de brillo para zonas iluminadas (default 3.5)\n"; + out << "# input_gamma: gamma de entrada - linealizacion (default 2.4)\n"; + out << "# output_gamma: gamma de salida - codificacion (default 2.2)\n"; + out << "# mask_brightness: brillo sub-pixeles de la mascara de fosforo (default 0.80)\n"; + out << "# curvature_x/y: distorsion barrel CRT (0.0 = plana)\n"; + out << "# mask_type: 0=ninguna, 1=verde/magenta, 2=RGB fosforo\n"; + out << "# enable_scanlines/multisample/gamma/curvature/sharper: true/false\n"; + out << "\n"; + out << "presets:\n"; + out << " - name: \"DEFAULT\"\n"; + out << " scanline_weight: 6.0\n"; + out << " scanline_gap_brightness: 0.12\n"; + out << " bloom_factor: 3.5\n"; + out << " input_gamma: 2.4\n"; + out << " output_gamma: 2.2\n"; + out << " mask_brightness: 0.80\n"; + out << " curvature_x: 0.05\n"; + out << " curvature_y: 0.10\n"; + out << " mask_type: 2\n"; + out << " enable_scanlines: true\n"; + out << " enable_multisample: true\n"; + out << " enable_gamma: true\n"; + out << " enable_curvature: false\n"; + out << " enable_sharper: false\n"; + out << " - name: \"CURVED\"\n"; + out << " scanline_weight: 6.0\n"; + out << " scanline_gap_brightness: 0.12\n"; + out << " bloom_factor: 3.5\n"; + out << " input_gamma: 2.4\n"; + out << " output_gamma: 2.2\n"; + out << " mask_brightness: 0.80\n"; + out << " curvature_x: 0.05\n"; + out << " curvature_y: 0.10\n"; + out << " mask_type: 2\n"; + out << " enable_scanlines: true\n"; + out << " enable_multisample: true\n"; + out << " enable_gamma: true\n"; + out << " enable_curvature: true\n"; + out << " enable_sharper: false\n"; + out << " - name: \"SHARP\"\n"; + out << " scanline_weight: 6.0\n"; + out << " scanline_gap_brightness: 0.12\n"; + out << " bloom_factor: 3.5\n"; + out << " input_gamma: 2.4\n"; + out << " output_gamma: 2.2\n"; + out << " mask_brightness: 0.80\n"; + out << " curvature_x: 0.05\n"; + out << " curvature_y: 0.10\n"; + out << " mask_type: 2\n"; + out << " enable_scanlines: true\n"; + out << " enable_multisample: false\n"; + out << " enable_gamma: true\n"; + out << " enable_curvature: false\n"; + out << " enable_sharper: true\n"; + out << " - name: \"MINIMAL\"\n"; + out << " scanline_weight: 8.0\n"; + out << " scanline_gap_brightness: 0.05\n"; + out << " bloom_factor: 2.0\n"; + out << " input_gamma: 2.4\n"; + out << " output_gamma: 2.2\n"; + out << " mask_brightness: 1.00\n"; + out << " curvature_x: 0.0\n"; + out << " curvature_y: 0.0\n"; + out << " mask_type: 0\n"; + out << " enable_scanlines: true\n"; + out << " enable_multisample: false\n"; + out << " enable_gamma: false\n"; + out << " enable_curvature: false\n"; + out << " enable_sharper: false\n"; + out.close(); + if (console) { + std::cout << "CrtPi file created with defaults: " << crtpi_file_path << '\n'; + } + crtpi_presets.push_back({"DEFAULT", 6.0F, 0.12F, 3.5F, 2.4F, 2.2F, 0.80F, 0.05F, 0.10F, 2, true, true, true, false, false}); + crtpi_presets.push_back({"CURVED", 6.0F, 0.12F, 3.5F, 2.4F, 2.2F, 0.80F, 0.05F, 0.10F, 2, true, true, true, true, false}); + crtpi_presets.push_back({"SHARP", 6.0F, 0.12F, 3.5F, 2.4F, 2.2F, 0.80F, 0.05F, 0.10F, 2, true, false, true, false, true}); + crtpi_presets.push_back({"MINIMAL", 8.0F, 0.05F, 2.0F, 2.4F, 2.2F, 1.00F, 0.0F, 0.0F, 0, true, false, false, false, false}); + current_crtpi_preset = 0; + return true; + } + + std::string content((std::istreambuf_iterator(file)), std::istreambuf_iterator()); + file.close(); + + try { + auto yaml = fkyaml::node::deserialize(content); + + if (yaml.contains("presets")) { + const auto& presets = yaml["presets"]; + for (const auto& p : presets) { + CrtPiPreset preset; + if (p.contains("name")) { + preset.name = p["name"].get_value(); + } + parseFloatField(p, "scanline_weight", preset.scanline_weight); + parseFloatField(p, "scanline_gap_brightness", preset.scanline_gap_brightness); + parseFloatField(p, "bloom_factor", preset.bloom_factor); + parseFloatField(p, "input_gamma", preset.input_gamma); + parseFloatField(p, "output_gamma", preset.output_gamma); + parseFloatField(p, "mask_brightness", preset.mask_brightness); + parseFloatField(p, "curvature_x", preset.curvature_x); + parseFloatField(p, "curvature_y", preset.curvature_y); + if (p.contains("mask_type")) { + try { preset.mask_type = p["mask_type"].get_value(); } catch (...) {} + } + if (p.contains("enable_scanlines")) { + try { preset.enable_scanlines = p["enable_scanlines"].get_value(); } catch (...) {} + } + if (p.contains("enable_multisample")) { + try { preset.enable_multisample = p["enable_multisample"].get_value(); } catch (...) {} + } + if (p.contains("enable_gamma")) { + try { preset.enable_gamma = p["enable_gamma"].get_value(); } catch (...) {} + } + if (p.contains("enable_curvature")) { + try { preset.enable_curvature = p["enable_curvature"].get_value(); } catch (...) {} + } + if (p.contains("enable_sharper")) { + try { preset.enable_sharper = p["enable_sharper"].get_value(); } catch (...) {} + } + crtpi_presets.push_back(preset); + } + } + + if (!crtpi_presets.empty()) { + current_crtpi_preset = std::clamp( + current_crtpi_preset, 0, static_cast(crtpi_presets.size()) - 1); + } else { + current_crtpi_preset = 0; + } + + if (console) { + std::cout << "CrtPi file loaded: " << crtpi_presets.size() << " preset(s)\n"; + } + return true; + + } catch (const fkyaml::exception& e) { + if (console) { + std::cerr << "Error parsing CrtPi YAML: " << e.what() << '\n'; + } + // Cargar defaults en memoria en caso de error + crtpi_presets.clear(); + crtpi_presets.push_back({"DEFAULT", 6.0F, 0.12F, 3.5F, 2.4F, 2.2F, 0.80F, 0.05F, 0.10F, 2, true, true, true, false, false}); + current_crtpi_preset = 0; + return false; + } + } + } // namespace Options diff --git a/source/game/options.hpp b/source/game/options.hpp index 9369bb0..f96816d 100644 --- a/source/game/options.hpp +++ b/source/game/options.hpp @@ -7,7 +7,8 @@ #include #include // Para vector -#include "core/rendering/screen.hpp" // Para Screen::Filter +#include "core/rendering/screen.hpp" // Para Screen::Filter +#include "core/rendering/shader_backend.hpp" // Para Rendering::ShaderType #include "game/defaults.hpp" #include "utils/defines.hpp" // Para WINDOW_CAPTION #include "utils/utils.hpp" // Para Color, Palette @@ -131,6 +132,25 @@ namespace Options { float flicker{0.0F}; // Parpadeo de fósforo CRT ~50 Hz (0.0 = off, 1.0 = máximo) }; + // Estructura para un preset del shader CRT-Pi + struct CrtPiPreset { + std::string name; + float scanline_weight{6.0F}; // Ajuste gaussiano (mayor = scanlines más estrechas) + float scanline_gap_brightness{0.12F}; // Brillo mínimo en las ranuras entre scanlines + float bloom_factor{3.5F}; // Factor de brillo para zonas iluminadas + float input_gamma{2.4F}; // Gamma de entrada (linealización) + float output_gamma{2.2F}; // Gamma de salida (codificación) + float mask_brightness{0.80F}; // Brillo sub-píxeles en la máscara de fósforo + float curvature_x{0.05F}; // Distorsión barrel eje X + float curvature_y{0.10F}; // Distorsión barrel eje Y + int mask_type{2}; // 0=ninguna, 1=verde/magenta, 2=RGB fósforo + bool enable_scanlines{true}; // Activar efecto de scanlines + bool enable_multisample{true}; // Antialiasing analítico de scanlines + bool enable_gamma{true}; // Corrección gamma + bool enable_curvature{false}; // Distorsión barrel CRT + bool enable_sharper{false}; // Submuestreo más nítido (modo SHARPER) + }; + // --- Variables globales --- inline std::string version{}; // Versión del fichero de configuración. Sirve para saber si las opciones son compatibles inline bool console{false}; // Indica si ha de mostrar información por la consola de texto @@ -155,13 +175,23 @@ namespace Options { inline int current_postfx_preset{0}; // Índice del preset de PostFX actual inline std::string postfx_file_path{}; // Ruta del fichero postfx.yaml + // --- Variables CrtPi --- + inline std::vector crtpi_presets{}; // Lista de presets del shader CRT-Pi + inline int current_crtpi_preset{0}; // Índice del preset CRT-Pi actual + inline std::string crtpi_file_path{}; // Ruta del fichero crtpi.yaml + + // --- Shader activo --- + inline Rendering::ShaderType current_shader{Rendering::ShaderType::POSTFX}; // Shader de post-procesado activo + // --- Funciones públicas --- void init(); // Crea e inicializa las opciones del programa void setConfigFile(const std::string& path); // Establece la ruta del fichero de configuración auto loadFromFile() -> bool; // Carga las opciones desde el fichero configurado auto saveToFile() -> bool; // Guarda las opciones al fichero configurado - void setPostFXFile(const std::string& path); // Establece la ruta del fichero de PostFX - auto loadPostFXFromFile() -> bool; // Carga los presets de PostFX desde el fichero - auto savePostFXToFile() -> bool; // Guarda los presets de PostFX por defecto + void setPostFXFile(const std::string& path); // Establece la ruta del fichero de PostFX + auto loadPostFXFromFile() -> bool; // Carga los presets de PostFX desde el fichero + auto savePostFXToFile() -> bool; // Guarda los presets de PostFX por defecto + void setCrtPiFile(const std::string& path); // Establece la ruta del fichero de CrtPi + auto loadCrtPiFromFile() -> bool; // Carga los presets de CrtPi desde el fichero (crea defaults si no existe) } // namespace Options \ No newline at end of file