From b33f9d5515c636a9913d0159a94e91117530a50f Mon Sep 17 00:00:00 2001 From: Zsolt Zitting Date: Mon, 26 Jun 2023 11:40:28 -0700 Subject: [PATCH] initial code, no input from IO board for some reason --- .gitignore | 398 +++++++++++++++++++++++++++++++ WACCALauncher_VS.sln | 31 +++ WACCALauncher_VS.vcxproj | 165 +++++++++++++ WACCALauncher_VS.vcxproj.filters | 9 + main.c | 103 ++++++++ packages.config | 4 + res/funny.ttf | Bin 0 -> 12900 bytes 7 files changed, 710 insertions(+) create mode 100644 .gitignore create mode 100644 WACCALauncher_VS.sln create mode 100644 WACCALauncher_VS.vcxproj create mode 100644 WACCALauncher_VS.vcxproj.filters create mode 100644 main.c create mode 100644 packages.config create mode 100644 res/funny.ttf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8dd4607 --- /dev/null +++ b/.gitignore @@ -0,0 +1,398 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.tlog +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio 6 auto-generated project file (contains which files were open etc.) +*.vbp + +# Visual Studio 6 workspace and project file (working project files containing files to include in project) +*.dsw +*.dsp + +# Visual Studio 6 technical files +*.ncb +*.aps + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# Visual Studio History (VSHistory) files +.vshistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd + +# VS Code files for those working on multiple tools +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +# Windows Installer files from build outputs +*.cab +*.msi +*.msix +*.msm +*.msp + +# JetBrains Rider +*.sln.iml \ No newline at end of file diff --git a/WACCALauncher_VS.sln b/WACCALauncher_VS.sln new file mode 100644 index 0000000..fac7509 --- /dev/null +++ b/WACCALauncher_VS.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.33414.496 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WACCALauncher_VS", "WACCALauncher_VS.vcxproj", "{A34920BA-9FB8-49FF-A507-33178A503E5E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A34920BA-9FB8-49FF-A507-33178A503E5E}.Debug|x64.ActiveCfg = Debug|x64 + {A34920BA-9FB8-49FF-A507-33178A503E5E}.Debug|x64.Build.0 = Debug|x64 + {A34920BA-9FB8-49FF-A507-33178A503E5E}.Debug|x86.ActiveCfg = Debug|Win32 + {A34920BA-9FB8-49FF-A507-33178A503E5E}.Debug|x86.Build.0 = Debug|Win32 + {A34920BA-9FB8-49FF-A507-33178A503E5E}.Release|x64.ActiveCfg = Release|x64 + {A34920BA-9FB8-49FF-A507-33178A503E5E}.Release|x64.Build.0 = Release|x64 + {A34920BA-9FB8-49FF-A507-33178A503E5E}.Release|x86.ActiveCfg = Release|Win32 + {A34920BA-9FB8-49FF-A507-33178A503E5E}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E747FB65-2044-4297-8AB1-1720216207F5} + EndGlobalSection +EndGlobal diff --git a/WACCALauncher_VS.vcxproj b/WACCALauncher_VS.vcxproj new file mode 100644 index 0000000..83dadee --- /dev/null +++ b/WACCALauncher_VS.vcxproj @@ -0,0 +1,165 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + 16.0 + Win32Proj + {a34920ba-9fb8-49ff-a507-33178a503e5e} + WACCALauncherVS + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + StaticMonolithRelease + + + StaticMonolithRelease + + + StaticMonolithRelease + + + StaticMonolithRelease + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + CompileAsC + false + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + CompileAsC + false + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + CompileAsC + false + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + CompileAsC + false + + + Console + true + true + true + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/WACCALauncher_VS.vcxproj.filters b/WACCALauncher_VS.vcxproj.filters new file mode 100644 index 0000000..506dc35 --- /dev/null +++ b/WACCALauncher_VS.vcxproj.filters @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/main.c b/main.c new file mode 100644 index 0000000..79988be --- /dev/null +++ b/main.c @@ -0,0 +1,103 @@ +#include "raylib.h" + +bool prefix(const char* pre, const char* str) +{ + return strncmp(pre, str, strlen(pre)) == 0; +} + +typedef enum { + TEST_BUTTON = GAMEPAD_BUTTON_RIGHT_FACE_DOWN, + SERVICE_BUTTON = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT, + VOLUME_UP = GAMEPAD_BUTTON_LEFT_FACE_UP, + VOLUME_DOWN = GAMEPAD_BUTTON_LEFT_FACE_DOWN +} IOButtons; + +int main(void) +{ + SetTraceLogLevel(LOG_ALL); + + const int windowSize = 1080; + int monitorIndex = 0; + bool ioBoard = false; + + InitWindow(windowSize, windowSize, "WACCA Launcher"); + + for (int i = 0; i < GetMonitorCount(); i++) { + Vector2 size = { GetMonitorWidth(i), GetMonitorHeight(i) }; + if (size.x < size.y) { // vertical monitor that is at least + monitorIndex = i; + TraceLog(LOG_DEBUG, "Monitor %i passed check", i); + } + else TraceLog(LOG_DEBUG, "Monitor %i failed check", i); + } + + // TODO: for some reason this doesn't work + SetGamepadMappings("0300bd19a30c00002100000000000000,I/O CONTROL BD;15257 ;01;91;3EEE;6679B;00;GOUT=14_ADIN=8,E_ROTIN=4_COININ=2_SWIN=2,E_UQ1=41,6;,a:b9,b:b6,dpup:b1,dpdown:b0,platform:Windows,"); + + Vector2 screen = GetMonitorPosition(monitorIndex); + SetWindowPosition(screen.x, screen.y + 362); // TODO: hardcoded offset won't work on non-1080p displays. + SetWindowState(FLAG_WINDOW_UNDECORATED); + + Font fontTtf = LoadFontEx("res/funny.ttf", 30, 0, 250); + + SetTargetFPS(60); + + int cursor = 0; + + // Main loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + if (IsGamepadAvailable(0)) { +#if _DEBUG + ioBoard = prefix("Logitech", GetGamepadName(0)); +#else + ioBoard = prefix("I/O CONTROL BD", GetGamepadName(0)); +#endif + + if (IsGamepadButtonPressed(0, VOLUME_UP)) cursor++; + if (IsGamepadButtonPressed(0, VOLUME_DOWN)) cursor--; + } + else ioBoard = false; + + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(BLACK); + + Vector2 textBounds = MeasureTextEx(fontTtf, "LAUNCHER SETTINGS", (float)fontTtf.baseSize, 0.1f); + DrawTextEx(fontTtf, "LAUNCHER SETTINGS", (Vector2) { 540 - (textBounds.x / 2), 126 }, (float)fontTtf.baseSize, 0.1f, WHITE); + DrawText(TextFormat("Monitor position: %03i, %03i (%i)", screen.x, screen.y, GetMonitorCount()), 10, 40, 20, LIGHTGRAY); + DrawText(TextFormat("IO Board detected: %c", ioBoard ? 'Y' : 'N'), 10, 540, 20, GREEN); + DrawText(TextFormat("Buttons Pressed: %s, %s, %s, %s (%d)", + IsGamepadButtonDown(0, TEST_BUTTON) ? "TEST" : "test", + IsGamepadButtonDown(0, SERVICE_BUTTON) ? "SERVICE" : "service", + IsGamepadButtonDown(0, VOLUME_UP) ? "UP" : "up", + IsGamepadButtonDown(0, VOLUME_DOWN) ? "DOWN" : "down", + cursor + ), 10, 570, 20, ORANGE); + + + if (IsGamepadAvailable(0)) { + if (GetGamepadButtonPressed() != GAMEPAD_BUTTON_UNKNOWN) DrawText(TextFormat("DETECTED BUTTON: %i", GetGamepadButtonPressed()), 100, 500, 20, RED); + else DrawText("DETECTED BUTTON: NONE", 100, 500, 20, GRAY); + } + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + + UnloadFont(fontTtf); + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} \ No newline at end of file diff --git a/packages.config b/packages.config new file mode 100644 index 0000000..848f370 --- /dev/null +++ b/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/res/funny.ttf b/res/funny.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f667cac7c05e021acfdc215eac084465492b5c95 GIT binary patch literal 12900 zcmc(GX?PsfmFT@yy?3kkeXZ{5eOE7P?P|4FOSX2|l2-{!vTTekWFu^O#Wr9o1_ICI zWq=7L3Hg8tOq-AaLm-4T6PB=Km?V=t2)rb~%QDG8CLh?PcW!k{mI*KUzV|2Hs;;}9 zd$xPdxu;49BZRc@BS1`h`_P($`}g%BR5=E%_Kw!JcI1N+s_cXxbMIgxwdIu``~V?* zAJo@wy=r{M^2c?rB1An0ZR@wr?PZXg+K-Uj4*efZ&1}1B?#Wi@6EFyg*lpu`W)>F_ z4e;{NFWI(p|J2ZqnS%%^UPj2(IXyW(K{var09F+GtEQnrxE22r>Jw1+PG7ZmpXNVSF>eH9&pHJs32g)C6Y0WKNnTZ=p>jUGjvs0+$UnBhV7a5VvBFVu`k z0jpG?5PAc8{ip}Mg(9d0Rr9^0fNLYV2MwVCbRGqu?1Mfpx*5iGp*mzja#+m`qu)SJ z!EEvYo#HQhnX^Ms1Fj=G=yf&RWxO;ffE+@b(IL=61Z5A3qOrxr#rGE9U3_Qp?ebjc zA|EW`1y?E)Uh(|mtEC@+Pa}a)B$h~Ja?rsFrAn>Q>huPq$!xLO><*`kaeG*=&mRbe z!jWh!o=8@v(wS^kuDYhSuD+oWHRYQNEwIZvI#+dduU^yB+t)uZI5fO=-N@+r4Ma!( z?w@?q$nenMK!0Cv&zjZUU8_1f+S^)N3eEYZ#)kU3+M4QIRW=ciMT35ym-V>JdW~9D zA(u%dVv$flQy4|t*!D4|=pQQz{A_1ujMUk2Xc%A7Fji!ssr~XXMTX29hpx*;=3(U2 zXGZ2rBlF86v6`tz^|2_^#xliMT3O~XyuN<~$~U#LqfGI)e0dFD7Wnx}1ytN_n8CD} zr(2mK9%I^y?Q_!$ZDXymC_X2bwXiLdvRD+IlgXhdhf*=f&YZ)+M$8weU|a1u*oPHl z*&^+08=oll^^df*+T89@z74hTu!^FVqL_!pY%c=N=nKrb=+g_QA5)_%#v+Odc4B)cTY*C0B^nwj=3AkVA1^br?OZYe!gyL^o z7@3$Vy2fl1pr2FBh|OKhj{^Hf*^$XnA|+N`47~%(!3PA$&jQ*$GkR$-kX;n}B+Lk9 zqeqFfpn++JAGS~r9qOW}R3#EE)H5U4hL(oGD&-NRbQv6|(7u*Vm<)HA+R|xrgL3nq zzk-sjL;#>slq};U03?K$a4N0y|3s}cnjjQn+9q39Ab1&2sPG7up?yA{6yZgg8GwR> zh_jQ>5Q|b!W}sVAq<~JoiAd4R6j2{D!cMZIEa*_aZ-fYk@S2xz_aNKdzkY<5c3De? zE~}OLtC#!Ar6Sb=3fLaug-T?~*E{(7a<%g_-K&Wo@IToMnKbOZR2iK3Bhp31-IW%&P!i7;735E?A09LS#nIOzLI6A#B zHcC_*8G(`Thl`kPL`8~iJclWfq9|i03q?6wAni@0y{XhLBJEpm>ei5} zt8>ED32p7I6RuWhYiZWF3UH~y%3*m}HY^T{hH)4TOT&_3I!u8_dJLm)8L<#QhQHYT zn0RrZyC~_~Fmev#n@6v|=_XWgbQc|iBgM0h(eC0=C?LlJ`qdAVR5T?Nc6f)xv@!hn8 zhly-BO|!Z*{lLyscmAgD$UO9=xmU;q@}iJ_@g@8Y^=D*5E`&@uR?OzuY?{B);&cu! z1Iu4D-2UJic5ZTYkLbEbjhifM&6_M81NznhJ2PY$&VKO02eWtXc@93acg=o)|NAb0 zPotW}Df~lv79>K9o7LQ7aax>rY{Ulh?O~R}ae+2i z)fV@6)&<4Ay+V!T7OPeGzB*dpm#rFZipVB^p{&dLs|CgY`+cyevtC&S;t|C4LrX7C55K+0;Y4BBkLN~1LuFmby-+XAxDEIth;Sxjm%ZyfwP4>@C?(%+7e!a!;E)hwKHl9$144{ zxL%|nCI}-x=(v;De_s3j6KBqpv>y6iT0D;5qPN3o5eds0m==NHv?jbRnsdr!&Rpzp zNB8QELk%Zyn2*QzUw^7`lH*RF<`$<2Y$wbQmFAnOwAl<5NSD>t*|EC2<8UnJl*ygB z=%Fc$PoKurWaFvp_s8S&H=JxJ;kMX=o#;B?J~F|sB)C0X+Kd=Zn-Ae{V?XK3W!;7* zJonJPeXwSH@d@;EG*56gdHgF?@&;d8X=b!q#-vo5n6~Pm-eXm%tRB6dwW|2_RItB) zNjv%Va2l)dw%y!6Wa+^R4-#Hc$h-Jm{2CqR^&X&KuJM7-==LYggGsGEIoQ-RnAB^N zgUt-95zuO{oAGLBp_XkfTyu8w=-vC;+xOi)y7}xig~N3lcBQMX-cVaRvOSr;;Em60g3IC(s9Bf@* z8SGy_RTpYd3QrJx60rB51s;Hea!y#Gw4oyycC3nDBX%nj{3I(>nz=|Z5#zwz#CT3i>?BVDfAsLc{gTYZH}JJ|~ub%5Tz z26hATC?=g4b|BsRpMS=uKFm_D32)qZQAYfkcku}r69<18f$R~&LS8j;!12$aY0Dok@EI?P(rsY-qhd zl+@W>3boTzA<;3{#ypKfDZT$o#|t~UgOT(F zPv6GwLtnr32(05oefTX*?6w%_0NoJ6<;0J1oe*qVrl8JRS$|JXa{Sfyyz^MY=e~I=Z2Sgbt7ciEM3#i6Q>!zZ3OT5IX>qTOX)KXi?tX&^X z>BGjFJsWHM4c&fGO6RsHvwp4HqRO6q1_(f(P0bt{r>>_s)T&yB0TrIu1Hj3V3)G z3qUwfjs{4p5nrd)%jgQJUL%uwq~2uCw*3&BUtg78ldz#2($j0JTneQ|Mr#5MQA0~tmo4nn8klH2wD!b?{{4MHtt)CBVOVLR zs#2!0##&Z0EPrmIkQVm-yI}vskn4p=2;yK}T1UqrCZbi~Hz(a^+=tG7@$B=oL?RN= z7>ng{p=odSyWb_Q6hE%3s;jSL1>)9`QTuVi;~d!Pp8z~HWPZV>nlxqe#(NDB%iA@7 z1RKixFoHF?M>oxgH5P5M@|wN6%4}^oQCZudbA^n#3_Wnwj3JQ-sq8zN4lLjcbq#gN z_qaVRLxGI5f_snHuGHe=_$fL98E+)KBraH#gw~ftRh7d}Rd~F9P4jr3VGCmou2zGo z(cw+IRccS#<7;9pAPrID-mgteeQmbEpuWvzs~p}_=-4|Lb9q63Gr*_Ufi4L$EK?<7 zbIU$clR10f*um>m=8#jPc7`o!h&A4P^A|7AyF2#|4DIb?F5biMlMdj|x53sz9@?Y< z4`TpF2F|Pl@A~lBXFtr){qt`g;Qn}kAG;RT{64HHT{(6wp8fr^&jR#=Kbq&R<;Qto zZ@owdA!Cj(9AY#p`QW5VjDT2`1h3%Y@$k?KQg^JH$#1H61Uk0Xt5~;P>S%Iyc2qcG zE`>>}z}~&wBaU>y)HHj~)~oNmG9!{#h)-KwU;lFZHA8W^t{h{f0l)77en5**!@?Kb zGJJ9CnL~%p9LnOGxmkLUE8@O#eDf%bZ-DU-=Yd{m9=%~X9>b_}@kzV`_yX2!DHeet z<$c(x59!o)z2XK(WwX~-V;hmHl%DD^wdUeCd$u)N6u=;&3ta&J9e@uGOGxwRK%}X| z8}6K&`_hT~9?IhHbJc**NxYAn=fDM%IfTbAz#Kj%BVonb8$JZIE=CTQ`jsHBUjbf~ z1g1X&?k-!814^NoX6ZN`Fxat3Zy*Ovos%X(8x-($Dh#0wEr1V>PbMgl2#z?a$@ENu z7Kz0)Ef$NZ#7sJaCzL^RawcYC<%&d2V@+JajpMs@0~-c(!QBVzRTOs@-Oo)Jy862f z#?}2@I(*lKe+HbBfb(;JvxDFSNI)P?s3jOcXip@t_I9C4DTi~FNU&$u?IPt;Ig4LZ z)-~m%l4N0xm)i);=v3F%r=^leLr(nHRNte57yZ{ zdWlHOI-RUmB++{c4Of44a`LOQ4Gpv8es#lqxc{2&&b@=t=-}SY?rZwPz-S891E1dl zKC9qK5N|b{lmmnK!9eIPZL<2;Q{8EcCDol8US)C{Wpbn2*ae#=*10i3CpUK|xX1Am z)=<`FO$RN!-|;N&;b}1vzatDl$g(oj7l}=D8jg4?W36;5hgZ3b)|GVmBKeCG4ux2( z_qkj?y;y4S*~Rot{i2n`9et|mG~PHFI5yUG?NBT>bZyt_1H*9=W&(XpW!=<(M+K?z zyQO@-7VGF`3JrMOuH^jdnXZIUU`$4jzioCKWDw&Uda`(qTc8I+g`tSJrlZXOPcJ{P z_+th`*lqYzNmpwYpMji%AD-QzCBszCHe6;8$(hvzKYZ2!ydKF*q<^LNIkW~()I`z^ z)^v9=JYe)UyA6yl-6|!Nh>Kslu5FuxYx*zqYUl1c+a6@#|}|jF5cVP-rfpx zjR60D0epDK3Zm7SU_;XXa`xDOT0L;=EZNw%Scxgk^*v}~7L_t%`{#Dy70*Z!;fc9VErv$VBP8)FEuxwkE!LL5AO=YttE=3P; z!R~``LruQTgMZ8gO$~*D-P(}PJMfP$JjBz;=bvD0VmsxS)zN8^u+rfzlatroedFQ2 zzQZ@(oy7(2Df}${BKJG2Rh-k&vdf>jw<&awNvTx8$iWxf(8n;fRB5PUIowJVKWd9 zSdMc^uo*CrUAT1W6Ny{qLaAhX!eolKC(>a>*zS!=buN=5D9_S|x%=5@->yRbs{Xjw z_;|#>Wo@7(W%ne37uB#v5$J_ehwyS@m*b%lbw#GdlUtwnc$-JFj=am=WO5}Kb)nwT z?D6O;V!gWxgzYz4895@~}pf#p^B{!zYp+d#WX{c8fnk)=5HK_dI0*I>0|% zMhS5Y?xkoZ2L_HmN8|e)eaWhUoWq>z$)>wgX6_v@Ty`ZJh?s`44D6WErI%Ayy_s;X ze)n)X*uA4UB)3;bZ9*OJSC=}7^ ztxBuUBoFxPGPyWxQCj2@`3NPX6%`7BR6_|UN+@(dBBf!Z#_r5^hJ!6yecI-(Q%haJ zggLpk*;gU)T8}G*%C=yULCey-l zJBZDo&^-Wekj{ey$k~{v<w?*AQ0F!) z35+4`0K}tt@Ij#VcsXd`0g(JJ@kfxp!5XdGtWufXT5ncmW`1afY}-*bzo~{gMIh=u zunrIN!j;$@rKI zH4?E&IH{D-6$=B83nxn8MkmJ@N2LpZ;y4rqLud8 z0x7P)VUP7LlRYTsPSD5nm+Ue3H3~0VgB{GqlwYYpdViZdBB4m(E75#OJ+-~x%q&()+JO3;ms%3 zuA{P4txg9S*b}r=Yu9sd+QFy?Z0z1t3WIf+-TMNv<9n8<%%}N z!>vgR*>mLl_8h*6`WIq%g=EL^F-Dq%6-!TE@bUOS13Nl;VE66{gIy`A5Y<-%I%=`v zx?=IVkIXKu7{ksYu<91SgCC`Yf#FojtO}Bb4mp7!SV4V2@WxdDWAUoc%M*0(-L9d@%zDsaQA8>I$cDI zH(Y$4%#*{s4`6-by=bs$#PXNI%cW!DrSQ^eh2RpC2-AA?`t1xkJ3>?m?_@F443wdZ zgqY0s^;ztY1kyQ^yC%Vix%a4A?q4N=%9Ku*PWnZ-mU}_qNoGx^Ou{S1xf1>sunYeI z_>(vj;wOkRA&CWXX5ZSiU$}GO_?k7x7w*hF{x}X`-2)GBzvX@cxVzzO@oT_62pK<~ zUl0#NU`+fLp}q>}hm<=Ff8cZi35DF@mC-6y1$FjBvq&hE(gLYaC~7@X71jBidRpa8 z)CD9u8OPB9izHeZlTr!p1EWbF*Xt8{vkB{;_)`AxwsuKob)}ht^{at*PXNw*+^QpS zE1fn}|LAc%{N}H-Tk!PWjoj^fVcZ*wSL0XV4Nk&i4>_4u^;m)+C6{<%@s#i}Eu&F(?Mt`;G9@&?Li4z>{*^eS zF5z~|Ut(|>f@DpEthf=dDt#K!;c^*+-}*(lOd&BYy<re2ltiB zLZrkul*=N-;IEX+Qbgg`%jF7q)A`@|GMoX?LHu#KjFFYvQ!c|=)Gg&QJfEQME|&!` z=J|3N)}nqUi6Z_FD+K#rNX|xxSrw2*M^;AN(fI)+(myg{F z@LaqH-l}CFj%$NiolxsVtKsT^H-8yu>4l7PAG}@5z{s8OWuU$Ua}QseM0+6TJd5Vw zcY?er+_HOS|Lpc{(|egzva&M94EDAU6`FgxnW46p&Ys@Yy&a=WOYcBmoN3;yKdnRY+CMRJ2ASwVlF*J-?0kv^-CAtQP*bT^30SOHBqQSyYY`C?1{K{*#?QW?` zGSEa4-`im1PM9$Z)yZww>>P(eC7_gsS9aUcI)F9^rO$^OBXBF@={oYVa@`8xF|ywO z7fK{L9s-0*D4_PCAqEyeeCw9KhQ`p)mcKv%Z~(!q0-hv6l;oQxkE>R%YE7n6sWcS- zu0mhQqEl}qA6Y4_&&uZWWwK%xFN?nl@iVL?%=tX-kXUHxGX({_R9U`nf<_8P(O@Y= zkRyNPxG=iGP7tz~LhQ zi9qNUl<#G_e>(UN{|POZ|E~a6qs5CH%%b1t_Q5ZtOg_UU0sM!-Tlgb-hWw`i{XRVd zIPF{H0OKhriIJH4J=I1132<$PtAqa?09weNDc}w8ox#7yGeBDh^bY{FgsK6cm()n9 z^xFYtGNNm_mG4>n1P#FDM}v4h3h>uDWWWjFcM`q