From 1204ac0319d93a8ee3f75a7aed5cc643af875a9d Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 16 Dec 2023 11:44:41 +0100 Subject: [PATCH] Remove Console and ASP.NET examples, simplify README.md Simplified README.md by removing in-depth Console and ASP.NET Core examples, as well as mentions about building from source, serving overall clarity and readability. Added descriptions for coded and visual workflow design possibilities. --- README.md | 556 +----------------- .../http-send-email-workflow-designer.png | Bin 0 -> 36304 bytes 2 files changed, 13 insertions(+), 543 deletions(-) create mode 100644 design/screenshots/http-send-email-workflow-designer.png diff --git a/README.md b/README.md index 39992cf56..bc849fdd6 100644 --- a/README.md +++ b/README.md @@ -38,10 +38,6 @@ docker run -t -i -e ASPNETCORE_ENVIRONMENT='Development' -e HTTP_PORTS=8080 -p 1 - [Features](#features) - [Roadmap](#roadmap) - [Use Cases](#use-cases) -- [Console Example](#console-example) -- [ASP.NET Example](#aspnet-example) -- [Elsa Server + Elsa Studio](#elsa-server--elsa-studio) -- [Building from Source](#building-from-source) ## Documentation @@ -99,143 +95,12 @@ Elsa can be used in a variety of scenarios, including: - Scheduled workflows such as sending daily reports. - Event-driven workflows such as sending welcome emails when a user signs up. -## Console Example +## Programmatic Workflows -Let's explore a simple example demonstrating how to create and run a workflow in a console application. In this example, we'll create a workflow that writes "Hello World!" to the console. - -First, create a new console application and add the following NuGet packages: - -```shell -dotnet new console -n "ElsaConsole" -f net8.0 -cd ElsaConsole -dotnet add package Elsa -``` - -Open Program.cs and replace its contents with the following code: +Elsa allows you to define workflows in code using C#. The following example shows how to receive HTTP requests and send an email in response: ```csharp -using Elsa.Extensions; -using Elsa.Workflows.Core.Activities; -using Elsa.Workflows.Core.Contracts; -using Microsoft.Extensions.DependencyInjection; - -// Set up the service container. -var services = new ServiceCollection(); - -// Add Elsa services. -services.AddElsa(); - -// Build the service container. -var serviceProvider = services.BuildServiceProvider(); - -// Create a workflow. -var workflow = new WriteLine("Hello World!"); - -// Resolve a workflow runner to run the workflow. -var workflowRunner = serviceProvider.GetRequiredService(); - -// Run the workflow. -await workflowRunner.RunAsync(workflow); -``` - -Run the application using the following command: - -```shell -dotnet run -``` - -The application should output the following text: - -```shell -Hello World! -``` - -You can also create more complex workflows. For example, the following demonstrates how to create a workflow that writes two messages to the console: - -```csharp -var workflow = new Sequence -{ - Activities = - { - new WriteLine("Hello World!"), - new WriteLine("Goodbye cruel world...") - } -}; -``` - -Which will output the following text: - -```shell -Hello World! -Goodbye cruel world... -``` - -# ASP.NET Example - -When working with workflows that involve timers, messages and other events, running a simple Console application is not enough. -In this case, we need a proper host that can run the workflows in the background and handle events. - -ASP.NET Core is a great host for this purpose. The following example demonstrates how to create a simple ASP.NET Core application that acts as a workflow server. - -First, create a new ASP.NET Core application and add the following NuGet packages: - -```shell -dotnet new web -n "ElsaWeb" -f net8.0 -cd ElsaWeb -dotnet add package Elsa --prerelease -dotnet add package Elsa.Http --prerelease -``` - -```csharp -using Elsa.Extensions; - -var builder = WebApplication.CreateBuilder(args); -var services = builder.Services; - -// Add Elsa services. -services.AddElsa(elsa => elsa - - // Add workflows from this program. - .AddWorkflowsFrom() - - // Enable Elsa HTTP module for HTTP related activities. - .UseHttp() -); - -// Configure ASP.NET's middleware pipeline. -var app = builder.Build(); - -if (app.Environment.IsDevelopment()) - app.UseDeveloperExceptionPage(); - -// Add Elsa HTTP middleware to handle requests mapped to HTTP Endpoint activities. -app.UseWorkflows(); - -// Start accepting requests. -app.Run(); -``` - -The above example demonstrates how to: - -- Add workflows from the current program. -- Enable the HTTP module to handle HTTP related activities. - -Next, let's define a workflow that handles HTTP requests. - -### HTTP Workflow - -Create a new file called `HelloWorldHttpWorkflow.cs` and add the following code: - -```csharp -using System.Net; -using Elsa.Http; -using Elsa.Workflows.Core; -using Elsa.Workflows.Core.Activities; -using Elsa.Workflows.Core.Contracts; - -namespace ElsaWeb; - -public class HelloWorldHttpWorkflow : WorkflowBase +public class SendEmailWorkflow : WorkflowBase { protected override void Build(IWorkflowBuilder builder) { @@ -245,14 +110,16 @@ public class HelloWorldHttpWorkflow : WorkflowBase { new HttpEndpoint { - Path = new("/hello-world"), - SupportedMethods = new(new[] { HttpMethods.Get }), + Path = new("/send-email"), + SupportedMethods = new(new[] { HttpMethods.Post }), CanStartWorkflow = true }, - new WriteHttpResponse + new SendEmail { - StatusCode = new(HttpStatusCode.OK), - Content = new("Hello world!") + From = new("alic@acme.com"), + To = new(new[]{ "bob@acme.com" }), + Subject = new("Your workflow has been triggered!"), + Body = new("Hello!") } } }; @@ -260,405 +127,8 @@ public class HelloWorldHttpWorkflow : WorkflowBase } ``` -The above example demonstrates how to: +## Designed Workflows -- Create an HTTP endpoint that listens for GET requests on the `/workflows/hello-world` path. -- Respond to the request with a `200 OK` status code and a `Hello world!` message. -- The `CanStartWorkflow` property is set to `true` to indicate that this endpoint can start a workflow. -- The `HttpEndpoint` activity is followed by a `WriteHttpResponse` activity that writes the response to the client. +Elsa allows you to define workflows using a visual designer. The following example shows how to receive HTTP requests and send an email in response: -Run the application using the following command: - -```shell -dotnet run -``` - -The application should now be accessible at https://localhost:5001/workflows/hello-world. The port number might vary based on your configuration. -The response should look like this: - -```shell -Hello world! -``` - -> The prefix `/workflows` is added by the Elsa HTTP module. This prefix can be configured via the `ElsaOptions.Http` property. For example: -> `elsa.UseHttp(http => http.ConfigureHttpOptions = options => options.BasePath = "/my-workflows");` - -### Timer - -Let's take a look at another workflow that automatically executes every 5 seconds. - -First, add the following package: - -```shell -dotnet add package Elsa.Scheduling --prerelease -``` - -Then update the `Program.cs` file as follows by adding the `UseScheduling()` method inside the `AddElsa()` method: - -```csharp -// Enable timer based activities. -.UseScheduling() -``` - -Next, create a new file called `HeartbeatWorkflow.cs` and add the following code: - -```csharp -using Elsa.Common.Contracts; -using Elsa.Workflows.Core; -using Elsa.Workflows.Core.Activities; -using Elsa.Workflows.Core.Contracts; - -namespace ElsaWeb; - -public class HeartbeatWorkflow : WorkflowBase -{ - protected override void Build(IWorkflowBuilder builder) - { - builder.Root = new Sequence - { - Activities = - { - new Elsa.Scheduling.Activities.Timer(TimeSpan.FromSeconds(5)) - { - CanStartWorkflow = true - }, - new WriteLine(context => $"Heartbeat at {context.GetRequiredService().UtcNow}"), - } - }; - } -} -``` - -Run the application using the following command: - -```shell -dotnet run -``` - -You should see the output similar to the following: - -```shell -Heartbeat at 2021-10-10 12:00:00Z -Heartbeat at 2021-10-10 12:00:05Z -Heartbeat at 2021-10-10 12:00:10Z -... -``` - -The above example demonstrates how to: - -- Create a timer that executes every 5 seconds. -- The `CanStartWorkflow` property is set to `true` to indicate that this timer can start a workflow. -- The `Timer` activity is followed by a `WriteLine` activity that writes the current time to the console. -- The `ISystemClock` service is used to get the current time. -- The `context` parameter is used to access the service. - -## Elsa Server + Elsa Studio - -While we've explored how to run workflows using simple Console and ASP.NET Core applications, these applications don't provide a way to design workflows. To bridge this gap, we introduce: - -Elsa Server: An ASP.NET Core application that exposes API endpoints for designing workflows. -Elsa Studio: A Blazor application tailored for designing workflows with ease. -To set up a simple Elsa Server application, follow these step-by-step instructions: - -1. Create a new ASP.NET Core application. -2. Add the necessary packages -3. Make the necessary changes in Program.cs - -Let's go through the above steps in detail. - -### Create Elsa Server - -Create a new ASP.NET Core application using the following command: - -```shell -dotnet new web -n "ElsaServer" -f net8.0 -cd ElsaServer -dotnet add package Elsa --prerelease -dotnet add package Elsa.EntityFrameworkCore --prerelease -dotnet add package Elsa.EntityFrameworkCore.Sqlite --prerelease -dotnet add package Elsa.Identity --prerelease -dotnet add package Elsa.Scheduling --prerelease -dotnet add package Elsa.Workflows.Api --prerelease -dotnet add package Elsa.CSharp --prerelease -``` - -Next, open Program.cs file and replace its contents with the following code: - -```csharp -using Elsa.EntityFrameworkCore.Modules.Management; -using Elsa.EntityFrameworkCore.Modules.Runtime; -using Elsa.Extensions; - -var builder = WebApplication.CreateBuilder(args); -builder.Services.AddElsa(elsa => -{ - // Configure Management layer to use EF Core. - elsa.UseWorkflowManagement(management => management.UseEntityFrameworkCore()); - - // Configure Runtime layer to use EF Core. - elsa.UseWorkflowRuntime(runtime => runtime.UseEntityFrameworkCore()); - - // Default Identity features for authentication/authorization. - elsa.UseIdentity(identity => - { - identity.TokenOptions = options => options.SigningKey = "sufficiently-large-secret-signing-key"; //This key needs to be at least 256 bits long. - identity.UseAdminUserProvider(); - }); - - // Configure ASP.NET authentication/authorization. - elsa.UseDefaultAuthentication(auth => auth.UseAdminApiKey()); - - // Expose Elsa API endpoints. - elsa.UseWorkflowsApi(); - - // Setup a SignalR hub for real-time updates from the server. - elsa.UseRealTimeWorkflows(); - - // Enable C# workflow expressions - elsa.UseCSharp(); - - // Enable HTTP activities. - elsa.UseHttp(); - - // Use timer activities. - elsa.UseScheduling(); - - // Register custom activities from the application, if any. - elsa.AddActivitiesFrom(); - - // Register custom workflows from the application, if any. - elsa.AddWorkflowsFrom(); -}); - -// Configure CORS to allow designer app hosted on a different origin to invoke the APIs. -builder.Services.AddCors(cors => cors - .AddDefaultPolicy(policy => policy - .AllowAnyOrigin() // For demo purposes only. Use a specific origin instead. - .AllowAnyHeader() - .AllowAnyMethod() - .WithExposedHeaders("x-elsa-workflow-instance-id"))); // Required for Elsa Studio in order to support running workflows from the designer. Alternatively, you can use the `*` wildcard to expose all headers. - -// Add Health Checks. -builder.Services.AddHealthChecks(); - -// Build the web application. -var app = builder.Build(); - -// Configure web application's middleware pipeline. -app.UseCors(); -app.UseRouting(); // Required for SignalR. -app.UseAuthentication(); -app.UseAuthorization(); -app.UseWorkflowsApi(); // Use Elsa API endpoints. -app.UseWorkflows(); // Use Elsa middleware to handle HTTP requests mapped to HTTP Endpoint activities. -app.UseWorkflowsSignalRHubs(); // Optional SignalR integration. Elsa Studio uses SignalR to receive real-time updates from the server. - -app.Run(); -``` - -To run the application on port 5001, execute the following command: - -```shell -dotnet run --urls "https://localhost:5001" -``` - -The above example demonstrates how to: - -- Configure Elsa to use Entity Framework Core for persistence. -- Configure Elsa to use ASP.NET Core Identity for authentication/authorization. -- Configure Elsa to use ASP.NET Core authentication/authorization. -- Expose Elsa API endpoints. -- Setup a SignalR hub for real-time updates from the server. -- Enable C# workflow expressions. -- Enable HTTP activities. -- Enable timer activities. -- Register custom activities from the application, if any. -- Register custom workflows from the application, if any. -- Configure CORS to allow designer app hosted on a different origin to invoke the APIs. -- Add Health Checks. -- Configure ASP.NET's middleware pipeline. -- Use Elsa API endpoints. -- Use Elsa middleware to handle HTTP requests mapped to HTTP Endpoint activities. -- Use SignalR integration. Elsa Studio uses SignalR to receive real-time updates from the server. -- Run the application on port 5001. - -Now that we have an Elsa Server running, let's create an Elsa Studio application. - -### Create Elsa Studio - -Create a new Blazor WebAssembly application using the following command: - -```shell -dotnet new blazorwasm-empty -n "ElsaStudio" -f net8.0 -cd ElsaStudio -dotnet add package Elsa.Studio --prerelease -dotnet add package Elsa.Studio.Core.BlazorWasm --prerelease -dotnet add package Elsa.Studio.Login.BlazorWasm --prerelease -``` - -Next, open Program.cs file and replace its contents with the following code: - -```csharp -using Elsa.Studio.Dashboard.Extensions; -using Elsa.Studio.Shell; -using Elsa.Studio.Shell.Extensions; -using Elsa.Studio.Workflows.Extensions; -using Elsa.Studio.Contracts; -using Elsa.Studio.Core.BlazorWasm.Extensions; -using Elsa.Studio.Extensions; -using Elsa.Studio.Login.BlazorWasm.Extensions; -using Elsa.Studio.Login.HttpMessageHandlers; -using Elsa.Studio.Workflows.Designer.Extensions; -using Microsoft.AspNetCore.Components.Web; -using Microsoft.AspNetCore.Components.WebAssembly.Hosting; - -// Build the host. -var builder = WebAssemblyHostBuilder.CreateDefault(args); - -// Register root components. -builder.RootComponents.Add("#app"); -builder.RootComponents.Add("head::after"); -builder.RootComponents.RegisterCustomElsaStudioElements(); - -// Register shell services and modules. -builder.Services.AddCore(); -builder.Services.AddShell(); -builder.Services.AddRemoteBackend( - options => configuration.GetSection("Backend").Bind(options), - configureElsaClientBuilderOptions: elsaClient => elsaClient.ConfigureHttpClientBuilder = httpClientBuilder => httpClientBuilder.AddHttpMessageHandler()); -builder.Services.AddLoginModule(); -builder.Services.AddDashboardModule(); -builder.Services.AddWorkflowsModule(); - -// Build the application. -var app = builder.Build(); - -// Run each startup task. -var startupTaskRunner = app.Services.GetRequiredService(); -await startupTaskRunner.RunStartupTasksAsync(); - -// Run the application. -await app.RunAsync(); -``` - -For a cleaner project structure, delete the following directories and files: - -- wwwroot/css -- Pages -- App.razor -- MainLayout.razor - -Within the wwwroot directory, create a new appsettings.json file and populate it with the subsequent content: - -```json -{ - "Backend": { - "Url": "https://localhost:5001/elsa/api" - } -} -``` - -Finally, open the wwwroot/index.html file and replace its content with the code showcased below: - -```html - - - - - - - MyApplication - - - - - - - - - - - - - - - - - - - -
-
-
Loading...
-
-
- -
- An unhandled error has occurred. - Reload - 🗙 -
- - - - - - - - - - -``` - -Run the following command to start the application on port 6001: - -```shell -dotnet run --urls "https://localhost:6001" -``` - -Your application should now be accessible at https://localhost:6001. - -![Elsa Studio Login](./design/screenshots/elsa-studio-login.png) - -By default, you can log in using: - -``` -Username: admin -Password: password -``` - -In the above example, we have: - -- Created and configured an Elsa Studio Blazor WebAssembly application. -- Configured the backend URL to point to the Elsa Server application. -- Configured the application to use the `AuthenticatingApiHttpMessageHandler` to authenticate requests to the backend. -- Configured the application to use the `Elsa.Studio.Login.BlazorWasm` module for authentication. -- Configured the application to use the `Elsa.Studio.Dashboard` module for the dashboard. -- Configured the application to use the `Elsa.Studio.Workflows` module for workflows. -- Run the application on port 6001. - -## Building from Source - -To build Elsa from source, you'll need: - -- .NET 6 SDK or later - -To build the solution, run the following command: - -```shell -dotnet build Elsa.sln -``` - -To run the tests, run the following command: - -```shell -dotnet test Elsa.sln -``` - -To run the Elsa.AllInOne.Web project, run the following command: - -```shell -dotnet run --project src/Elsa.AllInOne.Web/Elsa.AllInOne.Web.csproj -``` - -The AllInOne project is a sample application that demonstrates how to use Elsa Server + Elsa Studio in a single application. \ No newline at end of file +![Elsa ships with a powerful visual designer](./design/screenshots/http-send-email-workflow-designer.png) \ No newline at end of file diff --git a/design/screenshots/http-send-email-workflow-designer.png b/design/screenshots/http-send-email-workflow-designer.png new file mode 100644 index 0000000000000000000000000000000000000000..994a03ebf4c8d69dd105a200f91720e9e419641c GIT binary patch literal 36304 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�!>?q5_85JZ73D5xMs z1QDc2?^TL473ozG=^#==kEj%B0@6b-BE7eeAXOps5?Vkh2>~HOfDl^Fa&Ou9zV8`# zjQinyJAXbgvetUmTyxDipWm#@FG4{Ah0zC5cU__u>zvv>G-(B`(<;DBb~s1x%9lGY zZDxFqp`@g|=eub!U2Plgq>k_(3K0o8#{$o1Kl7MT_$e55Kb)`E`cJ8rJ8*(IN9YjJdPo$Bqj=MEsoX z3R}@+m}M~;&2dd|IE{kC#u;73>H3jCPQ{+_XQ`ZUQR`JghR~*jF3Lq+0^+Y>UCnraTQJcOcyfuc>!fmG7D7aeI zf_5pqRpP7Sz(K7}{4!9kFx9!@QVSijzyKw^{gZ0MWUpcFPXMqPD%Uy9bd|KsSzq>$&pWUn%gT z?$Yj;BlnrpP6RsOhRz&|gR;1tba#uFUns$zckbT(sEvqk^{GoO&hmed6}YWs3J-2$ z^)Zq93Pg!d3?$s=1>8dpXWL#yMMXi+^tv{pcv?0V-wV+#f9qIfpjK>E@2!9Jk-9*~ zCfO0410U6p%orvYJClQD8Dsk5llMuN%c^l(ix^F;aT{~iy-0QZx^h7123wE^|B_9&^M)M!nuqbB-xmt*ov>f>FlXA` zod_x+C!P4t76%1M7xTOJZ3j5bGb+e7hl=v)Wl@M3eV;NApM4~dlW&{pHJ6*G>P43n zg-<^)N_jIIL?~x@Uh&*)fe!TpZW+WsDr@h2-(iCaf=ntWi_l8siB!-`V+Jx%Ns9>y zi0la5g(H!Otl01Natm%}hnz4qs2}VZRP&tP&f5N{^o&k2&GL^q^<1%vC;I>m+G8VP zbyS^wANkML^LSp|qf^3}HTbuf9`fbd@oO zr)#wpW8rb0Vu$$vQWV(%H|vmpepnkgHU3a)U}r05fLTzi{?-lAV~*995J}ueJ?oJ3 zw7Pie<7X9}dItv0G-n*r&BmE6ez`Z|QRpc;{4aX_5;AJtb=|RuFQXTW9DDs38LF_w zMGc+wI;1NaI})?QX4g{E(&|L4|tCZEGy)q#c#tHW;pGHiNW5x9q=#ZTPa8EC&$Dt#l97z zi%M#~7FrwUQWkH@;zmdBjcDu@dT>SWK*38_qp)7eT z68%}%#zN*R@8D)L?XP_nTLK7fBcb6E*j15ibJyYwpbKTbX0rWL1)T)Eo+vV4`P;_} zaBse+K|ZtmBardU@C?;8>IgkE*&hZOR`;yYrOOw_o~Rr;3?J7Iy@|`%z3%VK?QkY% zKrMu{?mY8-$k|h)$?(9W(8H@Tw4c!mME~tgEG-jM|AHjLJGlUL*_kT8XS5*h6?9eMk z)Dd=q{BVx5+>ePfT|(xBMn1UEZC7KvS56rYtI|{Hf2GN>_o;I{A|q*ZLK99D(Om-? z*5Sk-=_MWn?Jw#Z4<9>=Oy#_0+wG=eIJ&=j`&v5H40=Jx-%7S%yge*-SOgVqlXtA@ zAWDBd0(i)f^ME9AP>URFN*l}RkZn*uKGfaM$6}u5JaK?YJ3BmUc6^)@m!S)%E>0i0 zQ`gfuQ55zyZa4O4&KGLegj|S*+xiCW)10FO)5dPG)?u%*t0P>K#Ob4>W8Eol8PwEu zZqQ~sEEwW;K+v8zI>$Sh)Mg3UezcUQE9^3A#&x2&>?8kof)lI&MsHqye6t^VS^ki8 z6U4YM(&!N{&30|LDC?+8R;Z!3DeHyvFJ)Q$m|EfmEUyGZY%{!X6siBh`8BLmoC#7{-fUaxW2J#kh*b|?BbyoO zP}0)y_B)7ARMYSqE+C`XaPSCsgyjZlO%)v9bZC3)sjEv9GWvpg#=7%i!sO#A+k*nB zidUHc#7`fZdd-!#wl2$MHQzAyP12Cyj`NSADWZ_Eh)Q|%de#Z?m2&`PIl4%zBp_C= zc}EA%QX84ZAmW2RB3QmW2tuL# zWB6pV>uc5ob;11{z$f-e`@vOv*V~scku*>WvY#8HJ^n5|626=!gt7AkHv6a;r#&S6 zWTJH9 z!UKV~i;eBS+z{ZqXE>H6u1vELv6bgxFc6>B{pv?L<{$?8G%iNmRdPT!*h#&3I9E1A z&NCM&^1Pl#$wDmnGm>+8b6!u>maTHVe(zl@Iv3*;=E&m#$KEzLEE(q1(wB_mmk`9i zJC07#xHk*5-}d5(4Oc&?YS5**%Pa?G(Cj$GB=Ge_|6Q{JwEVgtn6S5H4WiOXL$f6T zn94%lA+eE9($Z*U`51jo!X*2-Mocd*{C1P5Hc*eL&++^q*a4 zxI;{2o@o)E`U2*LYfpSsLB6#d=?Fhxm45N!#TuUtGe>v#6j~wZurt@w{$VpZ4L0v2 z0n3&rzbg_G*4e^GYW ztWI&9?+%@DNv}_;0*j!is*RPbT?KT(iySZ)rg_S5?0BeOVp|He&T;%C&bhw6UI-#? ze@Rb!HMiqY)b_IRsO9N3my0^lsd9{PFI@sx;${n%v7Z2sz@<*7WMP{vph~mtV3*6TuD{RihNVZgGfFT-Egk&3Fc(b{|9;c08%s7~HrjdGh(~fttSkD6_$5E46P~z7-$kO&C-lqIQsWIb*PsO6a+coQtKNbVkHy`S(se|HcG?W$;e}?C-a=bZF zuE&+6`DItz*{i&-8LLz<8))2|Vy01gV*If`x;B4}-s}^jB&T419GaRZu*2+4!u(*e%cyZ_QIWZ@c?KM@_$|oJ z!b{ulMAkjl;{8RHDLqz$<1~d2geS6I_6w0kFDml#xNH~nFEwwDTiB5-Zp%76OSdex z7cet-`E0Ewv7lDeY|+pbw|8wr>@Vg$Eghu{?(yE$=zGkJ)Em5c3zC(Vx>i0`!Xp$+8;1}*@%usn{Ncpx0ngOw3)q)^H!jUq(eTO+i%&=46G4eqh0Tq5gy#T_*hf=Y$s1#K@Y8I4uWP5r0^reb? zv@&>q;+^qowWFDd;u$c*EP|}l>EAmWkk4RL@1!Gqn1>RwjzrR0E>yBp&+@9tkW-w{ z%0GMBq!krnc?a#9&5+2m%ibq*nV6`tNbc%dJ~}c23{K)aG9I@}7j3Ao&p5f#cW+YQ zONavECQz?7cJuuIdkC&1Ie<=E5|f)>{`i0uOx_+97@nTCbGot@@uUUiabduz{$$e~S)7 zo_RPmcj03j9lOG-Lj7L%G*vh#$>kY=#K8guX9G~}OvY;(%>Y2$o6G7R=>TPa;@^O0 zQu*oYk=9G9EF~ZwpP%&0VxP2uqK)Ua4`TV{?rTq&=S5*JLl~0J&_35@VxX2{xgN&I zK?aVvn50a_D@aXE&FMpJ)B7y^XKM_4WFF~t zdvt+!fhGu-;VXS&?%X+QQY5s&TTul(sbbnrY|;b7oEOkJD$3HNZ|`KZWK`hKsH zf2*pgDe1~!Hha0cGeF%p2m>AYKji;DEPi=E8%{dJo*d$4>%0vN46xlo&30pQ5|=oX zas&Z#ysy%1a44NV@-XKwYsJH~ofRRHa_`LEG6E6Jp(Y#21T1ug;mxP5?+(}gFd$T^ zje?F%Ml6X6wbxmxD~Ss9M7EgIOZ;rPC z_kPY<+PJw@9KK6HD(qFq=}ImfEhji%EnlQ(m5N^!?;Gn7YU9z>4T%1EJ1)0@AjCmE z0#B3w{YHM%S%1Z(Z7aR5rY>o;??L%&iANZ71V&?y*ez7ltFSjadQoyNUV%hh&?4c6 zNOEn9hLsPH7WmX1#b5$0_RBeT9ihOH1x<~(c?j&_V`V{qWfRwNJN?mje_NyU-T@>$ zSpT52b<=4jXm067O4iAaeF5BScVZp1-C@+%4;qj>UpD8*t*b8y=l?!c9do^$Q@9A= zqpeI;%b(ZEz#;4hUh0i&JkK`SdrxpO-*({rG=1=Q<1v6uNjKaYb~ECv=7Mpa@XE_? z_7V09kj;}sMXiPXo;Iu}{CKu}(G9vKI~m5ntDmK#ctU>?+(MWSFrQrnF?tve0F^3Z z3qea8*h=_!N>|+`6Oe1#Er2(}Ou*0|mOnfKxIUHF-qF!<#gk5Q775#{_d4E5sqzUd7!wbFv6y=(ZttGKExL zXFrtXg|xKR#T|EBYvKZMLPh-PzPfU|j{460{FhLDv+<7Y{AdhjEK=i!R$TMm3|UGU zP;lG_kaXL?c=}WZIH|>g(TR>P?8G5Ky$h@=8=nPKzlX8!D;-Sr2Io7E;0~GLnTyUc z@5g?0hL7pPG4j~q+|KTa_5RA>0at9e)p7c+mq6g2XtraJ+7fYrgdANDUUsi^516cl z@weeoiXY~8lj*Q8;0@e)lzlWl$NbKACdF7OQa^ z*Qt`R+yu`q93}7k#0Be>$hTltM~sL_33z1w?2hX|oR=EI;*?~pE47MOzdIX1UkgC1 zmqB&xze=yf3@)u``P@G+07UKE<5@m(z;D>3hTm$wf<-=469zD&>fQCnm%sGW~J<;eO|9w3t|hZl~4eracZ{x4K+jC2Pr5xebB~-ZI#)U?@f@f+-sVl zO63$r%*Tr5D1<6T`j1epbkSD%^{HpTx#!C=r8A6DlE*xSc9Dg-bZ`1-ek$2uQ9|071!4kQ zk`2;|9Pmi2qmWX1iu+N<4X~0Q`Rv4({>%GYyMh%GxY)yA;lXzy3PCbK1kbG69~mN( zqDIiFy1JynY(;C2^00EZElVL?4_G?2PC}@?O7t&>UTfZ^aFt3vx6;Fk=Cj!8R=Oe~ z2rk&%vNEWgSIOocrO{xPc0VtAERkTH?$*30!hHW_O4t3!=N!UJ;Ey=aV>36aoI*6_ zNOy_z*H#?qMGJmVHoym69)fdqT!7WfPWiuR`TCAm9^13Cm@=23aBQvcasD8AcFYrw z17W{^3B#6JA3r#-4%yMb7G=2WHNuJI%zT9{1AzAF@&Z-w1vrFB@F1hX(O_0ATPdBM zF2y?mKxCK6Sf1<>RXFCmWX>|;6!K1%PNR$i~QQ}9X}J@#e*M3=JfD@ zV`3;xR72ZMsJjA`@t*Ca80OK70dxh~Et|6DD5v9R;}%hb)FXvNjO~a!1TeVm5!9?f zJL{qW;sl@r$G}OQ)8BP|`#=(g-D4UG+$XRfzdRTsVQtHgV_BsWtd15_3Xrf(jnSV! ze$q)pZ>y91Lbdw%~tt%fT11J^lUt1B$_A1rZFr z_tgYQ;faL8p{zg-RDh2{xtNgHW4wv$s>!w zFA?2n(VL6Ma_9J7T{T4X?j9dK^Er_B7RdvQAjjiW?Q%-Ch|p#7zzqoc1Vnk^uqS?DkfT z6ywd3*ive2Zxw=fBl`}m7&+pJPSe2oM9`-C(MK8|Z6_}1N5QGPTT-`A4EGdb>!0eb zRaj*ay9bu+eS_Z`Ltl_Ka7AfokpE`=ke&hmK%8AF6%PY*MB+U*IX|rj=XeVnC-y{N z6Sr!;7Q$iU2c|9Ci@f!tTcT3I^F2%$Z>t;QL*}@WiCE9^p1^!i{+jt`t~|+4i4L~D z64s)z-ppZCTk6RnG?6Qd_f;s)Ztuwr9ioY7|6}(U$&pXKEKB8^Yxxj_#*kcghDe+- z-Mub3E25CFGz9n{T92$dj)Z!O35Z@gBpN;03E+PaHXwQ)-JN|*l*>9^o@u-;aJ1@~ z;j3~1Lr)&Y7I~250}S0b5PQ*KUIXaDBo3DUl>v8mEB$cXvK+0yu+3JU-L}>034LY` z3j?AZY)=$5egwHb47!_~zi>asDLEibaxtgk)wLb1asAoew$1(So8%WjI-Vg*F#_)V zZbM(fkNUM0lg+C8kGm>8^)R!yAu|?Qor!1ek8m~A zTdQ~+P%enxl^n8V!pqes(_*3Xne9^4U6guqQl3o3fiRy2`N|=Thkc7E$!D|~vGKEY zENHyV;L8c2GQatp!JcAl{rpY38tOYt7>|+ovvl2I!h+ZENsX8t4z$PmNY!hGHP|oO zRgRul{C2|ZckzBgUk#udT}fvzhzJQ{pr9;*C@-L$+~=3$?&**A-sADe+)X2KH?@DS;XSOy=&LKcUmZmqYt9&J|A{az8EP)*rD?s zvlb*5k2#7odtX7fUkx(ip_%vwpKW$P>v%N3?{6)Y&+B!B@vSSAVFn?(w6yPU21u%* zg6iXxOabg;_l>T4uE{Tgwj*`>ts2ZPfKIoxaBdW2!2F# z2uJIou<~66fj?A7;Gb9wt|MrEgO+w-$}7w%qu&^Lfer;}>NTFKi@?U|nls^=(&P|f zqoMZ8-VVR5hES(2Z?^;UX94{37(Oba`1{k?>oZAhopS8Es}k?JU8^&#KQuO#o41&QCjSEb4+~1Vp9|UP>~3txO)N9; zG9EAkhziowa(+=ImqqC-Gad06SHtB-f|KcdC33I4!uOFG>HTPV?26I$Rouu8T;M#0 z@LmoL3aa$7a@PZPd9A;uTHO~4yy}4oeYN)b+jno(v-4c!u2Kft2hM(TsEnX}_beyZ zkL(e&={7p@hHufi-1v3=hNlcGZiN@TjYE_XfprMkq5eUyOnb<>%$T_}^9rXD&|N0V zPI`rZ`mo>eM{@DSVlt;&55Y=-wB}HCkW=6yzq6uyHt2a$YwiZc!6lZB+J?#sJw0^O z!`oDsxgbI}whuA~??AB7U|!FVtCc5tNz!;oW^J{5CE>Nzy02OGF%83Q4IA`vw!Y{< z9wjFgE&#oQo$M9a+n80{@AxR?K^`LutD3~v&r5g&A%A?k-1O_%Inh}-Sw4>Tog4E- zP!J|i;4iPJGvF+82#!n|)vQ{%3n2pVgF~2)9AB(gXi%)D|G?K7H3Zbe79HZ?@JZKk z0KrO}Z(@9w|IMU)dW}+T`T9=Mx?uj#_w|OTFm`=3in3?d`0tkAwQr zkOyDAp`oRNnmp0aDZGU#YrXt4Fd_WYtR+kLQZ8cU=?!PQJ?&F0O-8=N56CXew$%O~ zblv{u{BMDD^tSU>39xo+q-T?P;zs!(`!=}HJbQju+KusTPAwxZaE*s*MdzPunrH>! zKZuTwjwM8K2>;UjMBkyLq@*zja_6Vu%kS-ArpiZI$yOvN(}G(vP~f)W<{%4(Q3T4W zTU*>?{C~X0zme_iWrjCX6`9AUZW;xT-fzRfXT|fIH&a=makef)16HTLz|47_1(1Ha zsi_`+$nLE3Y|kUtDZpR(BoXv;MqW`dTTgCV(;rcfjCEOf5sX`R9(v<<BUuju5;CM+uGl*v1s&$OIaOsp|Hh0Sfg-J?GqKJxtF7gL23f zVny!UEQI_a0ATyy=(LNHf>S;4jCl6H`1yBOp8Z~-7`SXfu{IM|NSs56XS zF7?V4=Ftx~HF(M}yX%{2qV|vTM~*am<}8k{HFjUQ3tKOA^lu@i!fbmRn!;Tu)UDgY z_%uQ;?4COLN;zC$%U0jQm6gJJ4*mPypI_v+106~JtGVH$0N&||nPlL2=nPn2Gy1q5 zzzqF!-ME$w&`nnkx9Fv;a`Yp2{t`Y>7eWFi7pM$SP`dyq{+YRpc$Zfvu*S}hhd zB)LA@{+FBSoJE$h@#rA{HJ7m3PhNH}DPlLbYeZGY@)Uy6${{*qruyYh8(d&$xRY-V| zVF}uoT*xdkN*{VBeDR45Za%2o-OeE>8E(1_;JGpESn=#y)4^IPa%|yXvT-uSmNV<= z%W1om`pItGBE;8_)#1cDgakfYzEPacE}5$6{kcAq^gamh$?$ApZ~@a>zd2V4l(S02 z;kC!WXU~a#`#QkP%$yPDVybmGe==e;YaF~gQSK$ze~aDN!wR!fQc?om@pv+iq#B)8 z;XJTx|K#8yitqX9auo5|Eh@bC!W#ElTjhx#`*$KDHAR-N&JZ4 z^ny(gk|C30t|8vO27JDjYy;Q3C97Yx!i^4c^z(ve$~J@Rs1j3%HmrwyZ$XM?Vc+@# zg=3GCI-u<3UzY6@SbBpWV3Bf|I8c^Z|65?2Q7{3AZ7~z;uQRt?2_&u zI$n3!Ok+5X%l|k0b80|bsi{?5&JGCvr#^=&k;s`9BF0Iuy;H$u_>|ke7K5z2VPx7_ z=+_sF_c&yn^hDhfHY2Bn z@1)new@aa&Wi*_Z>wI_tV^Ym1e|W0Zr#8S{oIjM&yOH+7YNT^9PyMzH(atx4Ne3zhDmTqEPd{+s!}J zf?dx83}hU1`!8aZLI6Z}4Em<~uetc=9~T3_j5N~NOa5axLzOHkjVh($N1ZIqi!CXD zIYJZt8JM*vdTETQ7XX%iW3g{LWvQmkR(@k~VIkVstD;P-()|U`CrrzOoOyEoe*Sgk za6nhQPHwvEjExOsjK#5)`gYdGwx6K{SQeTZ^{+*_pX2>>%mvXmUeO|^B}=VS*Zx5C zwjYoK6BE5DEH!fO^&qb@^*ORryPipzt{hQlDH-cYzZ(OfwM;3GJR)Do#5j z@v6mx5>YN(!k5UiXhbe`7JN9B%5qvn+jopv+ECzLZ+hHY6Rm#FIPGFOxcr7Z5jVOs z8dmOFTB|YoYDv>9vsng`5v*b+6D)VP*OOa^g8G7vjh*)`h++uLaK56sxz2Yei%B_B zZX?_Ik z8Io^(=NMY6d~%sU;oc$zn``uj=#>oIe0?kNuW0Nf8-s`2W$TOyg);ohT8U|O8wTLL zhdq2kb;?0aa*y0g%n2giR&`85K9kACV_r*2=^0jz8;pl5LAE3lE0_6;B4Z9NxA_}V zKOFFWO@(u~@VB?L(bzB{cyJSl~z!-dNn2@Le#XQRW5WoO9Mt^RJV3R4AC4RY{W!@E0-3d)L>XPTMdfDitEC^09d4s{iCft)@w>r?hU-{u61I434jEex ztZ@^lOsIP~CN7;ONF*x%+#dlzhk3V`HOct*^=O2QR_Rpu=eXdSd&t(bh}XsF<{O2C`0qb5~cQJi>1&@Q$q%s zs=!dqbFW?n!CIUp*hssQb)(W#p5K!R74AZU%k63&5IgdvJ1>6}_c!f5grC|{My_~L z!c1waM=qnmvNMWiSYK6@rbnr`TuEZ8&In>cy z;Br6N$ALa`lnTh>DZ49TY{x6kzu4Z4EaK~RZ+(5sCTDKkb-crZQNQyLG9QZeQ-iU* zPsMEUO-_F%j0A#?Ib3&a8P1%!$fc#G`~-g=HB#wj;8(w!ZwxCkHis42H+Sw~XP7uQru| zIbRejyM~Af%VX&ts0E%?=PO3PUEg?>bNB+u++hG?&>p33LY+qb+duAzFsfvL&%?C zRTfC(%!d@)tf3*3LGU{u$^|NW?+VJ^Hv9CPyz?(W^J81hPB)>m%wL%WJvbAK19KTe zOk+Y-EzWe0Uk&_9T&jqi3SnVZTB|q_Dn#^)3uS2#kD^0uM5Z2IP-8+e69zEFfFWT3 zmJ5G0e(sMUS)^Q4;UT}^@#9keU(dfbdiB25ZTzk(!T^v%TEw7A-x&ISoN@LRVUGq$ zp-YgjT;g2++W*G>D9$T*<%}APkqa}llFrD&3~XE;SGA7+KnEVH9KS6_X0Z>0WRcYO zmW}_qbB=wxWs3JTLwC(~Lk(uc$UCKc&PoAK`z6dL4N@G1d5C#M$AI1y0YXY9gX_NY z=Wj85%2v90!|2fjQ{#<`&X0X}w-IT^x4xT{J~&X3M+libsqcc`!P4$Ve+G#R$Dh3b zS>HZbb@h-2Y8DL;?CYP?$1SJvi^%XK5C|vxI3)d=>=VhUiqciMr3*7vmoV zS&!j1XvV#v*FE?jejKaHn;p^cHkKX*p4i^%W2kNU?>h*?Z5~Zr!hbFh8W;VHM!lw% zo{Gmbr$DexhH?k;(ORg9QcgUMt_YA;M= z<%}u<-?DgMR1`~E6tX8a{EF2rTh)&~}6JP=3W7 zAnIU^`W?MncTmU__7$IZ;{1c2bn28UX=AL`&+=Qdx+WJ3Jn>EmQJ$0bL6l0ydGgPN zd&GLj!o|Q(0f2Zx)$-Kg1D~hd?$(2e=5>5FydT=0PfnCWcnSki8(=$qtYHQJgR~+U zSE2iVC8aj0Duweit;#LjDKj&qaJmb4=<7d5fRMo7_DKmujuK3GW*Pj^*prap*@l{# z2#WhsZb*2kkQ|RXCz)W*&xe$awsm#B3w$YL|Gb6YwZ8qmM?g z*sv7D`(&t3kbyr{uE}_&Oh9gZ&Je8}ltFgMX+M#)w}NP)-4$E0*_Fc zAn(a$9<*s*i!^?%%u^Rp+ch&M$~hxn@Zai?07S1Jyfzg013^zckYPcf0$`K#-}L$) zJCMW;DCMQHXQzA0sZ#j>R@{f4?~kgUYE}+6@N^ z$^W&A0}$PHAjF@#Jg2$*2bX}LFO5<4f3MOS%AwX84%BA+$AO0lz|UG$QK!D<=_)fo zXz71g{=c)_0f1h0m3$)gP^iT-YzA}r=0H&2R3G%h#6bUZShN0B^R$%Q7El^OlE7!n zkH7asQYev#RY%R&U8}9Fy^c(7DjIPp0Q}lZ&a0Mn zE&m^CG%sQ2`qV1f1@|hA(7@+Ri~rv?(+!E3&u7UWSx