From 1e4b5ca759e89fc0eb41751c40837f580d805f46 Mon Sep 17 00:00:00 2001 From: rez Date: Sun, 22 Jul 2012 01:16:07 +0000 Subject: [PATCH] new font / blur+chromatic aberration boosted on screen corners / various optimization in postfx --- neercs/neercs.cpp | 16 ++-- neercs/video/blurh.lolfx | 28 +++---- neercs/video/blurv.lolfx | 28 +++---- neercs/video/postfx.lolfx | 20 ++--- neercs/video/remanency.lolfx | 2 +- neercs/video/render.cpp | 75 ++++++++++--------- neercs/video/resource/charset_p0t-noodle.png | Bin 0 -> 4098 bytes neercs/video/text-render.cpp | 5 +- 8 files changed, 90 insertions(+), 84 deletions(-) create mode 100755 neercs/video/resource/charset_p0t-noodle.png diff --git a/neercs/neercs.cpp b/neercs/neercs.cpp index 3fd2679..51331a2 100644 --- a/neercs/neercs.cpp +++ b/neercs/neercs.cpp @@ -78,7 +78,7 @@ void Neercs::TickGame(float seconds) m_time += seconds; - /* draw something */ + /* draw something awesome */ int bg_color = 0x222; int w = caca_get_canvas_width(m_caca); int h = caca_get_canvas_height(m_caca); @@ -86,7 +86,7 @@ void Neercs::TickGame(float seconds) caca_set_color_argb(m_caca, 0xfff, bg_color); caca_clear_canvas(m_caca); - caca_set_color_argb(m_caca, 0xa46, bg_color); + caca_set_color_argb(m_caca, 0x545, bg_color); for(int i = 0; i < h; i++) { float a = M_PI / 180 * i * 16 + m_time * 4; @@ -105,20 +105,18 @@ void Neercs::TickGame(float seconds) caca_draw_line(m_caca, i, y - 1, i, y + 1,'%'); } -/* - __ _________ ______ ______ ______ ______ - / \/ / __ Y __ Y __ Y ___// ___/ +/* __ _________ ______ ______ ______ ______ + / \/ / __ > __ > __ > ___// ___/ \x0a9 / / ____/ ____/ __ < <____\___ \ -/__/\__/\_______________/ \________________\ -*/ +/__/\__/\_______________/ \________________\ */ int logo_x = (w - 46) / 2; - int logo_y = h / 2 - 2; + int logo_y = h / 2 - 2;// + h / 4 * lol::cos(m_time * 2); caca_set_color_argb(m_caca, hex_color(0.5f + 0.5f * lol::cos(m_time * 3 ), 0.5f, 0.5f + 0.25f * lol::sin(m_time * 3 )), bg_color); caca_put_str(m_caca, logo_x + 3, logo_y ,"__ _________ ______ ______ ______ ______"); caca_set_color_argb(m_caca, hex_color(0.5f + 0.5f * lol::cos(m_time * 3 + M_PI / 4 * 1), 0.5f, 0.5f + 0.25f * lol::sin(m_time * 3 + M_PI / 4 * 1)), bg_color); - caca_put_str(m_caca, logo_x + 2, logo_y + 1, "/ \\/ / __ Y __ Y __ Y ___// ___/"); + caca_put_str(m_caca, logo_x + 2, logo_y + 1, "/ \\/ / __ > __ > __ > ___// ___/"); caca_set_color_argb(m_caca, hex_color(0.5f + 0.5f * lol::cos(m_time * 3 + M_PI / 4 * 2), 0.5f, 0.5f + 0.25f * lol::sin(m_time * 3 + M_PI / 4 * 2)), bg_color); caca_put_str(m_caca, logo_x + 1, logo_y + 2, "/ / ____/ ____/ __ < <____\\___ \\"); caca_set_color_argb(m_caca, hex_color(0.5f + 0.5f * lol::cos(m_time * 3 + M_PI / 4 * 3), 0.5f, 0.5f + 0.25f * lol::sin(m_time * 3 + M_PI / 4 * 3)), bg_color); diff --git a/neercs/video/blurh.lolfx b/neercs/video/blurh.lolfx index 258530c..adb051d 100644 --- a/neercs/video/blurh.lolfx +++ b/neercs/video/blurh.lolfx @@ -14,23 +14,25 @@ void main() uniform sampler2D texture; uniform vec2 screen_size; -uniform float time; -uniform float value; +uniform float blur; +uniform float deform; -float blur=value; +const float PI=3.14159265358979323846; void main(void) { vec4 total=vec4(0.0); vec2 p=gl_TexCoord[0].xy/screen_size; - total+=texture2D(texture,vec2(p.x-blur*4.0,p.y))*0.04; - total+=texture2D(texture,vec2(p.x-blur*3.0,p.y))*0.08; - total+=texture2D(texture,vec2(p.x-blur*2.0,p.y))*0.12; - total+=texture2D(texture,vec2(p.x-blur ,p.y))*0.16; - total+=texture2D(texture,vec2(p.x ,p.y))*0.20; - total+=texture2D(texture,vec2(p.x+blur ,p.y))*0.16; - total+=texture2D(texture,vec2(p.x+blur*2.0,p.y))*0.12; - total+=texture2D(texture,vec2(p.x+blur*3.0,p.y))*0.08; - total+=texture2D(texture,vec2(p.x+blur*4.0,p.y))*0.04; + float mask=2.0-p.x*(6.0-p.x*6.0)*p.y*(6.0-p.y*6.0); + float b=blur+deform*mask; + total+=texture2D(texture,vec2(p.x-b*4.0,p.y))*0.04; + total+=texture2D(texture,vec2(p.x-b*3.0,p.y))*0.08; + total+=texture2D(texture,vec2(p.x-b*2.0,p.y))*0.12; + total+=texture2D(texture,vec2(p.x-b ,p.y))*0.16; + total+=texture2D(texture,vec2(p.x ,p.y))*0.20; + total+=texture2D(texture,vec2(p.x+b ,p.y))*0.16; + total+=texture2D(texture,vec2(p.x+b*2.0,p.y))*0.12; + total+=texture2D(texture,vec2(p.x+b*3.0,p.y))*0.08; + total+=texture2D(texture,vec2(p.x+b*4.0,p.y))*0.04; gl_FragColor=total; - } + } \ No newline at end of file diff --git a/neercs/video/blurv.lolfx b/neercs/video/blurv.lolfx index f5189d0..e471145 100644 --- a/neercs/video/blurv.lolfx +++ b/neercs/video/blurv.lolfx @@ -14,23 +14,25 @@ void main() uniform sampler2D texture; uniform vec2 screen_size; -uniform float time; -uniform float value; +uniform float blur; +uniform float deform; -float blur=value; +const float PI=3.14159265358979323846; void main(void) { vec4 total=vec4(0.0); vec2 p=gl_TexCoord[0].xy/screen_size; - total+=texture2D(texture,vec2(p.x,p.y-blur*4.0))*0.04; - total+=texture2D(texture,vec2(p.x,p.y-blur*3.0))*0.08; - total+=texture2D(texture,vec2(p.x,p.y-blur*2.0))*0.12; - total+=texture2D(texture,vec2(p.x,p.y-blur ))*0.16; - total+=texture2D(texture,vec2(p.x,p.y ))*0.20; - total+=texture2D(texture,vec2(p.x,p.y+blur ))*0.16; - total+=texture2D(texture,vec2(p.x,p.y+blur*2.0))*0.12; - total+=texture2D(texture,vec2(p.x,p.y+blur*3.0))*0.08; - total+=texture2D(texture,vec2(p.x,p.y+blur*4.0))*0.04; + float mask=2.0-p.x*(6.0-p.x*6.0)*p.y*(6.0-p.y*6.0); + float b=blur+deform*mask; + total+=texture2D(texture,vec2(p.x,p.y-b*4.0))*0.04; + total+=texture2D(texture,vec2(p.x,p.y-b*3.0))*0.08; + total+=texture2D(texture,vec2(p.x,p.y-b*2.0))*0.12; + total+=texture2D(texture,vec2(p.x,p.y-b ))*0.16; + total+=texture2D(texture,vec2(p.x,p.y ))*0.20; + total+=texture2D(texture,vec2(p.x,p.y+b ))*0.16; + total+=texture2D(texture,vec2(p.x,p.y+b*2.0))*0.12; + total+=texture2D(texture,vec2(p.x,p.y+b*3.0))*0.08; + total+=texture2D(texture,vec2(p.x,p.y+b*4.0))*0.04; gl_FragColor=total; - } + } \ No newline at end of file diff --git a/neercs/video/postfx.lolfx b/neercs/video/postfx.lolfx index 5ff1710..4a5155d 100644 --- a/neercs/video/postfx.lolfx +++ b/neercs/video/postfx.lolfx @@ -16,17 +16,18 @@ uniform sampler2D texture; uniform vec2 screen_size; uniform float time; uniform float flash; -uniform float value; +uniform float noise; +uniform float aberration; uniform float deform; uniform bool scanline; uniform float sync; const float PI=3.14159265358979323846; -float lens=deform+sync*0.0625; vec2 zoom(in vec2 p,in float radius) { - float zoom=1.5-(radius*cos(p.x*lens)+radius*cos(p.y*lens)); + float d=deform+sync*0.0625; + float zoom=1.5-(radius*cos(p.x*d)+radius*cos(p.y*d)); return p*zoom-0.5; } @@ -53,14 +54,14 @@ void main(void) vec2 z =zoom(p,0.5250); vec2 z1=zoom(p,0.5225); vec2 z2=zoom(p,0.5275); - float g=(2.0-cos(lens*0.5+z.x*lens)-cos(lens*0.5+z.y*lens))*32.0; + float mask=q.x*(6.0-q.x*6.0)*q.y*(6.0-q.y*6.0); float rnd1=rand(vec2(p.x+time,p.y-time)); float rnd2=rand(vec2(p.x-time,p.y+time)); - float d1=rnd1*value/float(screen_size.x); - float d2=rnd2*value/float(screen_size.y); + float d1=rnd1*noise/float(screen_size.x); + float d2=rnd2*noise/float(screen_size.y); - vec3 source;//=get_color(texture,z); + vec3 source; source.x=get_color(texture,vec2(z.x+d1,z.y)).x; source.y=get_color(texture,vec2(z.x+d1,z.y)).y; source.z=get_color(texture,vec2(z.x+d1,z.y)).z; @@ -68,7 +69,7 @@ void main(void) vec3 glass1=get_color(texture,z1); vec3 glass2=get_color(texture,z2); - float v=value/float(screen_size.x)*g; + float v=aberration/float(screen_size.x)+aberration/float(screen_size.x)*(2.0-mask); vec3 noise; noise.x=get_color(texture,vec2(z.x+d1-v,z.y+d2)).x; @@ -90,8 +91,7 @@ void main(void) color*=0.675; } color=vec3(color.x*0.875,color.y*1.0,color.z*0.75); - color*=q.x*(6.0-q.x*6.0)*q.y*(6.0-q.y*6.0); // vignetting - //color*=2.0*letterbox(z,-0.75,0.125)*2.0; // vignetting + color*=mask; // vignetting color*=letterbox(z,-0.75,0.95); // letterbox gl_FragColor=vec4(color,1.0); } \ No newline at end of file diff --git a/neercs/video/remanency.lolfx b/neercs/video/remanency.lolfx index 4ea79c2..394573a 100644 --- a/neercs/video/remanency.lolfx +++ b/neercs/video/remanency.lolfx @@ -15,7 +15,7 @@ void main() uniform sampler2D texture; uniform sampler2D texture_buffer; uniform vec2 screen_size; -uniform float time; +uniform float screen_color; uniform float value1; uniform float value2; diff --git a/neercs/video/render.cpp b/neercs/video/render.cpp index 740d66d..0b6e9f2 100644 --- a/neercs/video/render.cpp +++ b/neercs/video/render.cpp @@ -84,7 +84,7 @@ float beat_speed = 2.0f; // speed /* window variable */ ivec2 border; // border width /* text variable */ -ivec2 ratio_2d(2,4); // 2d ratio +ivec2 ratio_2d(2,3); // 2d ratio ivec2 map_size(256,256); // texture map size ivec2 font_size(8,8); // font size ivec2 canvas_char(0,0); // canvas char number @@ -99,8 +99,10 @@ float glow_mix_ratio2 = 0.5f; // source mixing ratio float radial_value1 = 2.0f; float radial_value2 = 0.8f; float radial_color = 0; // color -bool postfx_scanline = true; float postfx_deform = 0.625f; // deformation ratio +float postfx_noise = 4.0f; // noise +float postfx_aberration = 3.0f; // chromatic aberration +bool postfx_scanline = true; // scanline Shader *shader_simple; Shader *shader_blur_h, *shader_blur_v; @@ -109,16 +111,16 @@ Shader *shader_remanency, *shader_glow, *shader_radial, *shader_postfx; ShaderUniform shader_simple_texture; ShaderUniform shader_blur_h_texture, shader_blur_h_screen_size, - shader_blur_h_time, - shader_blur_h_value; + shader_blur_h_blur, + shader_blur_h_deform; ShaderUniform shader_blur_v_texture, shader_blur_v_screen_size, - shader_blur_v_time, - shader_blur_v_value; + shader_blur_v_blur, + shader_blur_v_deform; ShaderUniform shader_remanency_texture, shader_remanency_texture_buffer, shader_remanency_screen_size, - shader_remanency_time, + shader_remanency_screen_color, shader_remanency_value1, shader_remanency_value2; ShaderUniform shader_glow_texture, @@ -138,10 +140,11 @@ ShaderUniform shader_postfx_texture, shader_postfx_texture_2d, shader_postfx_screen_size, shader_postfx_time, - shader_postfx_flash, - shader_postfx_value, shader_postfx_deform, + shader_postfx_noise, + shader_postfx_aberration, shader_postfx_scanline, + shader_postfx_flash, shader_postfx_sync; FrameBuffer *fbo_back, *fbo_front, *fbo_buffer; @@ -195,20 +198,20 @@ int Render::InitDraw(void) shader_blur_h = Shader::Create(lolfx_blurh); shader_blur_h_texture = shader_blur_h->GetUniformLocation("texture"); shader_blur_h_screen_size = shader_blur_h->GetUniformLocation("screen_size"); - shader_blur_h_time = shader_blur_h->GetUniformLocation("time"); - shader_blur_h_value = shader_blur_h->GetUniformLocation("value"); + shader_blur_h_blur = shader_blur_h->GetUniformLocation("blur"); + shader_blur_h_deform = shader_blur_h->GetUniformLocation("deform"); // shader blur vertical shader_blur_v = Shader::Create(lolfx_blurv); shader_blur_v_texture = shader_blur_v->GetUniformLocation("texture"); shader_blur_v_screen_size = shader_blur_v->GetUniformLocation("screen_size"); - shader_blur_v_time = shader_blur_v->GetUniformLocation("time"); - shader_blur_v_value = shader_blur_v->GetUniformLocation("value"); + shader_blur_v_blur = shader_blur_v->GetUniformLocation("blur"); + shader_blur_v_deform = shader_blur_v->GetUniformLocation("deform"); // shader remanency shader_remanency = Shader::Create(lolfx_remanency); shader_remanency_texture = shader_remanency->GetUniformLocation("texture"); shader_remanency_texture_buffer = shader_remanency->GetUniformLocation("texture_buffer"); shader_remanency_screen_size = shader_remanency->GetUniformLocation("screen_size"); - shader_remanency_time = shader_remanency->GetUniformLocation("time"); + shader_remanency_screen_color = shader_remanency->GetUniformLocation("screen_color"); shader_remanency_value1 = shader_remanency->GetUniformLocation("value1"); shader_remanency_value2 = shader_remanency->GetUniformLocation("value2"); // shader glow @@ -234,10 +237,11 @@ int Render::InitDraw(void) shader_postfx_texture_2d = shader_postfx->GetUniformLocation("texture_2d"); shader_postfx_screen_size = shader_postfx->GetUniformLocation("screen_size"); shader_postfx_time = shader_postfx->GetUniformLocation("time"); - shader_postfx_flash = shader_postfx->GetUniformLocation("flash"); - shader_postfx_value = shader_postfx->GetUniformLocation("value"); shader_postfx_deform = shader_postfx->GetUniformLocation("deform"); + shader_postfx_noise = shader_postfx->GetUniformLocation("noise"); + shader_postfx_aberration = shader_postfx->GetUniformLocation("aberration"); shader_postfx_scanline = shader_postfx->GetUniformLocation("scanline"); + shader_postfx_flash = shader_postfx->GetUniformLocation("flash"); shader_postfx_sync = shader_postfx->GetUniformLocation("sync"); return true; @@ -265,8 +269,8 @@ Render::Render(caca_canvas_t *caca) m_pause(false), m_polygon(true), m_shader(true), - m_shader_blur(true), m_shader_remanency(true), + m_shader_blur(true), m_shader_glow(true), m_shader_fx(true), m_shader_postfx(true), @@ -432,7 +436,7 @@ void Render::Draw3D() shader_remanency->SetTexture(shader_remanency_texture, fbo_back->GetTexture(), 0); shader_remanency->SetTexture(shader_remanency_texture_buffer, fbo_buffer->GetTexture(), 1); shader_remanency->SetUniform(shader_remanency_screen_size, vec2(1.0f)); - shader_remanency->SetUniform(shader_remanency_time, fx_angle); + shader_remanency->SetUniform(shader_remanency_screen_color, screen_color); shader_remanency->SetUniform(shader_remanency_value1, 0.25f); shader_remanency->SetUniform(shader_remanency_value2, 0.75f); fs_quad(); @@ -448,9 +452,9 @@ void Render::Draw3D() shader_remanency->SetTexture(shader_remanency_texture, fbo_front->GetTexture(), 0); shader_remanency->SetTexture(shader_remanency_texture_buffer, fbo_buffer->GetTexture(), 1); shader_remanency->SetUniform(shader_remanency_screen_size, vec2(1.0f)); - shader_remanency->SetUniform(shader_remanency_time, fx_angle); - shader_remanency->SetUniform(shader_remanency_value1, 0.25f); - shader_remanency->SetUniform(shader_remanency_value2, 0.75f); + shader_remanency->SetUniform(shader_remanency_screen_color, screen_color); + shader_remanency->SetUniform(shader_remanency_value1, 0.75f); + shader_remanency->SetUniform(shader_remanency_value2, 0.25f); fs_quad(); shader_remanency->Unbind(); fbo_ping->Unbind(); @@ -467,8 +471,8 @@ void Render::Draw3D() shader_blur_h->Bind(); shader_blur_h->SetTexture(shader_blur_h_texture, fbo_back->GetTexture(), 0); shader_blur_h->SetUniform(shader_blur_h_screen_size, vec2(1.0f)); - shader_blur_h->SetUniform(shader_blur_h_time, fx_angle); - shader_blur_h->SetUniform(shader_blur_h_value, 0.375f/screen_size.x); + shader_blur_h->SetUniform(shader_blur_h_blur, 0.25f / screen_size.x); + shader_blur_h->SetUniform(shader_blur_h_deform, 0.375f / screen_size.x); fs_quad(); shader_blur_h->Unbind(); fbo_ping->Unbind(); @@ -477,8 +481,8 @@ void Render::Draw3D() shader_blur_v->Bind(); shader_blur_v->SetTexture(shader_blur_v_texture, fbo_ping->GetTexture(), 0); shader_blur_v->SetUniform(shader_blur_v_screen_size, vec2(1.0f)); - shader_blur_v->SetUniform(shader_blur_v_time, fx_angle); - shader_blur_v->SetUniform(shader_blur_v_value, 0.375f/screen_size.y); + shader_blur_v->SetUniform(shader_blur_v_blur, 0.25f / screen_size.y); + shader_blur_v->SetUniform(shader_blur_v_deform, 0.375f / screen_size.y); fs_quad(); shader_blur_v->Unbind(); } @@ -497,8 +501,8 @@ void Render::Draw3D() shader_blur_h->Bind(); shader_blur_h->SetTexture(shader_blur_h_texture, fbo_ping->GetTexture(), 0); shader_blur_h->SetUniform(shader_blur_h_screen_size, vec2(1.0f / glow_fbo_size)); - shader_blur_h->SetUniform(shader_blur_h_time, fx_angle); - shader_blur_h->SetUniform(shader_blur_h_value, 2.5f / screen_size.x); + shader_blur_h->SetUniform(shader_blur_h_blur, 2.5f / screen_size.x); + shader_blur_h->SetUniform(shader_blur_h_deform, 0.5f / screen_size.x); fs_quad(); shader_blur_h->Unbind(); fbo_blur_h->Unbind(); @@ -507,8 +511,8 @@ void Render::Draw3D() shader_blur_v->Bind(); shader_blur_v->SetTexture(shader_blur_v_texture, fbo_blur_h->GetTexture(), 0); shader_blur_v->SetUniform(shader_blur_v_screen_size, vec2(1.0f / glow_fbo_size)); - shader_blur_v->SetUniform(shader_blur_v_time, fx_angle); - shader_blur_v->SetUniform(shader_blur_h_value, 2.5f / screen_size.y); + shader_blur_v->SetUniform(shader_blur_v_blur, 2.5f / screen_size.y); + shader_blur_v->SetUniform(shader_blur_v_deform, 0.5f / screen_size.y); fs_quad(); shader_blur_v->Unbind(); fbo_blur_v->Unbind(); @@ -517,8 +521,8 @@ void Render::Draw3D() shader_blur_h->Bind(); shader_blur_h->SetTexture(shader_blur_h_texture, fbo_blur_v->GetTexture(), 0); shader_blur_h->SetUniform(shader_blur_h_screen_size, vec2(1.0f / glow_fbo_size)); - shader_blur_h->SetUniform(shader_blur_h_time, fx_angle); - shader_blur_h->SetUniform(shader_blur_h_value, 1.0f / screen_size.x); + shader_blur_h->SetUniform(shader_blur_h_blur, 1.0f / screen_size.x); + shader_blur_h->SetUniform(shader_blur_h_deform, 0.5f / screen_size.x); fs_quad(); shader_blur_h->Unbind(); fbo_blur_h->Unbind(); @@ -527,8 +531,8 @@ void Render::Draw3D() shader_blur_v->Bind(); shader_blur_v->SetTexture(shader_blur_v_texture, fbo_blur_h->GetTexture(), 0); shader_blur_v->SetUniform(shader_blur_v_screen_size, vec2(1.0f / glow_fbo_size)); - shader_blur_v->SetUniform(shader_blur_v_time, fx_angle); - shader_blur_v->SetUniform(shader_blur_h_value, 1.0f / screen_size.y); + shader_blur_v->SetUniform(shader_blur_v_blur, 1.0f / screen_size.y); + shader_blur_h->SetUniform(shader_blur_v_deform, 0.5f / screen_size.y); fs_quad(); shader_blur_v->Unbind(); fbo_blur_v->Unbind(); @@ -559,10 +563,11 @@ void Render::Draw3D() shader_postfx->SetTexture(shader_postfx_texture, fbo_pong->GetTexture(), 0); shader_postfx->SetUniform(shader_postfx_screen_size, (vec2)screen_size); shader_postfx->SetUniform(shader_postfx_time, fx_angle); - shader_postfx->SetUniform(shader_postfx_flash, flash_value); - shader_postfx->SetUniform(shader_postfx_value, 4.0f); shader_postfx->SetUniform(shader_postfx_deform, postfx_deform); + shader_postfx->SetUniform(shader_postfx_noise, postfx_noise); + shader_postfx->SetUniform(shader_postfx_aberration, postfx_aberration); shader_postfx->SetUniform(shader_postfx_scanline, postfx_scanline); + shader_postfx->SetUniform(shader_postfx_flash, flash_value); shader_postfx->SetUniform(shader_postfx_sync, (float)fabs(beat_value*cosf((main_angle-beat_angle)*8.0f))); fs_quad(); shader_postfx->Unbind(); diff --git a/neercs/video/resource/charset_p0t-noodle.png b/neercs/video/resource/charset_p0t-noodle.png new file mode 100755 index 0000000000000000000000000000000000000000..72862f3f03745864a26940358b6d583e4541e53f GIT binary patch literal 4098 zcmeHKYg-f77T%MD$q)ibFouMSxp7G)(12)D3Yb7h0;ml+s7Ngh5d^ukgi{oO)=5Gj zVo;z+kp6tsYAheOh~J5w(hsJ)9l?!}(O_%bv-sz4lt~ zTJO6iyEW@nzLY=;0Khj*tQlWgU9DwZe&s8%7_{`g))~*Gh zIt&2Z48X!7T<-!<84bX_cL0e07=VEHw#|-40zd?sHCd^Pi_qld^%8-*#5cnb^$pz0i$$ys5;e(1Z> zF<({6Eni$gAknu1o|L{%xZuZ-Nf`No?)M%sO;_iQPgVv*yO0_C>>jd59?yJ^vn~%T9$LO@&obS!t^*xSnP z0dDYr3rQGnWD_U}!=p&$&#)3e^?z|X(Qj3*B{avl{x{wO&xvjWnV9PpS_Ps=XvU2c z$oLpt)SZ^}UD?%^fJP_NpL;e~+T_kV^;CyZaFD!ws%88&#Zqhfir!~_D{(eMZvBFJ z;f&FiPep4cFMQ%jV&>A!YN+4aVw;ut@tQaXb+ID~-AuxJAL-_h`7qPQ6EpX-FOmECQ^~746wYsw0<38XA zX$f*L-uJECu?_t_le_xEd#;J#hY*Q=4an9poHylvioeK7u`$nnr^=!PZJ{F&B*!Cq z^{4wHfvXsqWD$hQi!1ylpycz=timnZ$lYWhOo&*a_XV@frt7BmaFhYx&H7O%7wte+ z;ud&2Qje2>l8;T<#<>Ze-0c;d=EyjG@Fo1Pe+um|I6H$eVB=&As-qHb=tcLHdf}d1 zbZ#xQl@P!u|9r6AaW`>t;9ZSp-1HRWDu;^c87Hl2TVB20oUxX9+x3VhfoEQvR{R-P zeaX7%R$dkJ$KY99{?*pYk&Q+IKkQfM#eO5UE3 z_x@hCj;X!RDS|$;KgEyr7CNFE&ht(^(Xjh1zdFbWqztd1ETI4-To>FiOg{MF;J5p7 zH|S#73G3!o{@^eN*wlA$sD6 z&UqBQw0T-HuR~x-TL>=IxfbtQ^Jy0cQ9iP#XlXt`9BCu_!D3ASM;BM8*bmWE-@ZFN zUMFuSK#x%^y$~U zD+G=~R?TDO^w_Xwf$vd2o;LO#$xmBW-|knw;ih5#kZTQ)L!7TN~6uWpO{mIucP_HGK&td59k#S zdG}F9XK~xNXYu|3wC$KG{6(No4p#Fsyg=74VB_p_o z>?2n`JzYIJ#z1%Ba1Z~`j^|TLdY{yv@DCPPz9$@v_d40d37+E1fG;6}Du!8?Mk;13 zAl+bzwCI?fPJ^v8!8LGwxS7a?J$W=vS+VTf8%nL!pKjNN^w7RJk6oa7w$-Vu2Q&4o z%rlI&XQRS3cU?XZapH(jag{3Ct7_7%2^4yDAL%lB0fdxs@t3u%+PLD_@U{x9!G#lW zAc*kl&PTNWaOiv>B!U%yZsDaLuznQ2Ih@Lb?u(XNPX1)=Ybj~!@u=Cq82C+9o=$dX zu5t^z{9eiiQbwZYA(}#mld`pj&2fD|751>tnEBozpC_&HX0ODOVI5{}CJ)SBPB*+C zLZxDF4o}7k#(c^zOMVvq#wB^UFCq%2DT!5`sXL?znitHC*I>%1E>?R@Fd;T%Hmd4G|_beRC91? zvRPxH9bxCilZ}gz+E#r;b1@JkymInDJT$gX{%jTR$zzgC}0fu2O=Bf9bz z{YtN75Q*s*&RLgbIyv0IG;HUPRi!l*VZJPg(wrFIRMd0rxAL9TUCABnXN+f>5@LR; znJ0#mhcbbqyjJ7WqU;}I=5iZ6?HzO@KlF&auC)fcoUI*uQS8A$g+W?zMu(v=uuOj- zvIt|AsWRl|;YAx{@#{)eDGUEZR$7B2hv;<=$(}C+Vs3N{N