From abd71db13d9ff9c0bd6b5f5e83ef11d69749dbfa Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Sun, 15 Nov 2020 20:37:53 +0000 Subject: [PATCH] Migrate to .net5 from .netcore2.1 --- .vscode/launch.json | 2 +- Program.cs | 49 ++++++--- Startup.cs | 239 +++++++++++++++++++++++++++++++------------- db/pecklist.sqlite | Bin 45056 -> 69632 bytes pecklist.csproj | 15 +-- 5 files changed, 215 insertions(+), 90 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index d7d6a30..234ccb5 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -10,7 +10,7 @@ "request": "launch", "preLaunchTask": "build", // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceRoot}/bin/Debug/netcoreapp2.1/pecklist.dll", + "program": "${workspaceRoot}/bin/Debug/net5.0/pecklist.dll", "args": [], "cwd": "${workspaceRoot}", "stopAtEntry": false, diff --git a/Program.cs b/Program.cs index 4cc7a5b..9057cd9 100644 --- a/Program.cs +++ b/Program.cs @@ -1,30 +1,47 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Hosting; + namespace GZTW.Pecklist { + + public class Program { public static void Main(string[] args) { - BuildWebHost(args).Run(); + CreateHostBuilder(args).Build().Run(); } - public static IWebHost BuildWebHost(string[] args) => - WebHost.CreateDefaultBuilder(args) - .UseUrls("http://*:3000") + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup() + .UseUrls("http://*:3000") .CaptureStartupErrors(true) .UseSetting("detailedErrors", "true") .UseKestrel() - .UseContentRoot(System.IO.Directory.GetCurrentDirectory()) - .UseStartup() - .Build(); + .UseContentRoot(System.IO.Directory.GetCurrentDirectory()); + }); } + + + // public class Program + // { + // public static void Main(string[] args) + // { + // BuildWebHost(args).Run(); + // } + + // public static IWebHost BuildWebHost(string[] args) => + // WebHost.CreateDefaultBuilder(args) + // .UseUrls("http://*:3000") + // .CaptureStartupErrors(true) + // .UseSetting("detailedErrors", "true") + // .UseKestrel() + // .UseContentRoot(System.IO.Directory.GetCurrentDirectory()) + // .UseStartup() + // .Build(); + // } } diff --git a/Startup.cs b/Startup.cs index 03cb747..5e33f2e 100644 --- a/Startup.cs +++ b/Startup.cs @@ -1,121 +1,226 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.HttpOverrides; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; +using Microsoft.Extensions.Hosting; -using Microsoft.EntityFrameworkCore; using GZTW.Pecklist.Models; using GZTW.Pecklist.Util; +using Microsoft.EntityFrameworkCore; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; -using Microsoft.AspNetCore.Authentication; + + namespace GZTW.Pecklist { public class Startup { - public Startup(IHostingEnvironment env) + public Startup(IConfiguration configuration) { - var builder = new ConfigurationBuilder() - .SetBasePath(env.ContentRootPath) - .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) - .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) - .AddEnvironmentVariables(); - Configuration = builder.Build(); + Configuration = configuration; } - public IConfigurationRoot Configuration { get; } + public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { + services.AddControllers().AddNewtonsoftJson(); + services.AddDbContext(options => + { + options.UseSqlite(Configuration.GetConnectionString("thedb")).EnableSensitiveDataLogging(false); - services.AddDbContext(options => options.UseSqlite(Configuration.GetConnectionString("thedb"))); - - //Added this so that can access configuration from anywhere else - //See authcontroller for usage - services.AddSingleton(Configuration); - - services.AddMvc(); + }); - - //get the key from the appsettings.json file var secretKey = Configuration.GetSection("JWT").GetValue("secret"); var signingKey = new SymmetricSecurityKey(System.Text.Encoding.ASCII.GetBytes(secretKey)); services.AddAuthentication(options => - { - options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - }).AddJwtBearer(options => - { - // options.AutomaticAuthenticate = true; - // options.AutomaticChallenge = true; - options.TokenValidationParameters = new TokenValidationParameters - { - // Token signature will be verified using a private key. - ValidateIssuerSigningKey = true, - RequireSignedTokens = true, - IssuerSigningKey = signingKey, - ValidateIssuer = true, - ValidIssuer = "GZTW_Pecklist", - ValidateAudience = false, - // ValidAudience = "https://yourapplication.example.com", + { + options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + }).AddJwtBearer(options => + { + options.TokenValidationParameters = new TokenValidationParameters + { + // Token signature will be verified using a private key. + ValidateIssuerSigningKey = true, + RequireSignedTokens = true, + IssuerSigningKey = signingKey, + ValidateIssuer = true, + ValidIssuer = "GZTW_Pecklist", + ValidateAudience = false, + + //Note: these are all enabled in AyaNOva but were origionally disabled in rf + // // Token will only be valid if not expired yet, with 5 minutes clock skew. + // ValidateLifetime = true, + // RequireExpirationTime = true, + // ClockSkew = new TimeSpan(0, 5, 0), + }; + }); + + - // Token will only be valid if not expired yet, with 5 minutes clock skew. - // ValidateLifetime = true, - // RequireExpirationTime = true, - // ClockSkew = new TimeSpan(0, 5, 0), - }; - }); } - public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, PecklistContext dbContext) + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env, PecklistContext dbContext) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } - loggerFactory.AddConsole(Configuration.GetSection("Logging")); - loggerFactory.AddDebug(); - - - app.UseForwardedHeaders(new ForwardedHeadersOptions - { - ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto - }); - app.UseDefaultFiles(); app.UseStaticFiles(new StaticFileOptions { OnPrepareResponse = context => { - if (context.File.Name == "index.html" || context.File.Name == "sw.js" ) + if (context.File.Name == "default.htm") { - context.Context.Response.Headers.Add("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0"); - // context.Context.Response.Headers.Add("Expires", "-1"); + context.Context.Response.Headers.Add("Cache-Control", "no-cache, no-store"); + context.Context.Response.Headers.Add("Expires", "-1"); } } }); - app.UseAuthentication(); - app.UseMvc(); - //Check schema - Schema.CheckAndUpdate(dbContext); + Schema.CheckAndUpdate(dbContext); + // app.UseHttpsRedirection(); + + app.UseRouting(); + + app.UseAuthorization(); + app.UseEndpoints(endpoints => + { + endpoints.MapControllers(); + + }); + + //server ready + System.Diagnostics.Debug.WriteLine("BOOT COMPLETED - OPEN"); } } } + +// using Microsoft.AspNetCore.Builder; +// using Microsoft.IdentityModel.Tokens; +// using Microsoft.AspNetCore.HttpOverrides; +// using Microsoft.Extensions.Configuration; +// using Microsoft.Extensions.DependencyInjection; +// using Microsoft.Extensions.Logging; +// using Microsoft.EntityFrameworkCore; +// using Microsoft.Extensions.Hosting; +// using Microsoft.AspNetCore.Authentication.JwtBearer; +// using GZTW.Pecklist.Models; +// using GZTW.Pecklist.Util; + + + +// namespace GZTW.Pecklist +// { +// public class Startup +// { +// public Startup(Microsoft.AspNetCore.Hosting.IWebHostEnvironment env) +// { +// var builder = new ConfigurationBuilder() +// .SetBasePath(env.ContentRootPath) +// .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) +// .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) +// .AddEnvironmentVariables(); +// Configuration = builder.Build(); +// } + +// public IConfigurationRoot Configuration { get; } + +// // This method gets called by the runtime. Use this method to add services to the container. +// public void ConfigureServices(IServiceCollection services) +// { + +// services.AddDbContext(options => options.UseSqlite(Configuration.GetConnectionString("thedb"))); + +// //Added this so that can access configuration from anywhere else +// //See authcontroller for usage +// services.AddSingleton(Configuration); + +// services.AddMvc(); + + + +// //get the key from the appsettings.json file +// var secretKey = Configuration.GetSection("JWT").GetValue("secret"); +// var signingKey = new SymmetricSecurityKey(System.Text.Encoding.ASCII.GetBytes(secretKey)); + +// services.AddAuthentication(options => +// { +// options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; +// options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; +// }).AddJwtBearer(options => +// { +// // options.AutomaticAuthenticate = true; +// // options.AutomaticChallenge = true; +// options.TokenValidationParameters = new TokenValidationParameters +// { +// // Token signature will be verified using a private key. +// ValidateIssuerSigningKey = true, +// RequireSignedTokens = true, +// IssuerSigningKey = signingKey, +// ValidateIssuer = true, +// ValidIssuer = "GZTW_Pecklist", +// ValidateAudience = false, +// // ValidAudience = "https://yourapplication.example.com", + +// // Token will only be valid if not expired yet, with 5 minutes clock skew. +// // ValidateLifetime = true, +// // RequireExpirationTime = true, +// // ClockSkew = new TimeSpan(0, 5, 0), +// }; +// }); + +// } + +// public void Configure(IApplicationBuilder app, IHostEnvironment env, PecklistContext dbContext) +// {//ILoggerFactory loggerFactory, +// if (env.IsDevelopment()) +// { +// app.UseDeveloperExceptionPage(); +// } +// var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole()); +// // loggerFactory.AddConsole(Configuration.GetSection("Logging")); +// // loggerFactory.AddDebug(); + + +// app.UseForwardedHeaders(new ForwardedHeadersOptions +// { +// ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto +// }); + +// app.UseDefaultFiles(); +// app.UseStaticFiles(new StaticFileOptions +// { +// OnPrepareResponse = context => +// { +// if (context.File.Name == "index.html" || context.File.Name == "sw.js") +// { +// context.Context.Response.Headers.Add("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0"); +// // context.Context.Response.Headers.Add("Expires", "-1"); +// } +// } +// }); + +// app.UseAuthentication(); +// //app.UseMvc(); + +// //Check schema +// Schema.CheckAndUpdate(dbContext); + + +// } +// } +// } diff --git a/db/pecklist.sqlite b/db/pecklist.sqlite index 4cd89a1efdd8a8e7bbbf6846a9ee13c8ede6043a..56f3ad49b4a633fc9aac85c0ab576641a80c961b 100644 GIT binary patch literal 69632 zcmeHwOOxYRc3$<&^o(Y#o|YElSturiE`_b?>dY$eO?FI2n-B1jd?raG$($K$Kma5` zJc$QEQZbHbd2KJWv3FW{5$OBB78hBcrmC zFA(>hd+xdC`JK^iM{#9lVcNRjGMQ(8@a&_Hp8X4kdG@UM>u1lN{ULt;34VWw-;eS8 z1N@$TJ~};k_g{R+tHyu)u&Tc3Sl2)cZQD?i7W22UT?!#Aiu{L#;U@r#eX`J4_>QyfkAJI3zx{EmH|84L@Cr}el}z6M?T^RYbc`1U!&bLEoH1=~_JVx&^PhbFP5OI3 z`uWd(_R(K7=-oU=w#o1J-?$5Tg?XV!%<;RKi!Zuj2q73(-noon;@8u(D@HSyit+6i zEx~bo)0V#dx+7@rw_lSqRo>GVuNeAR-dT)dxbjlAKVN?Iqo4orAAj`CFX)&B%W}k( ztPAG{-+N>9=a=6-h2Z-0^m_d<)8jjx&p*MceDvx6dWL_=PeOr&0tp2Y3M3RrD3DMf zp+G``gaQc#5(*>~NGR}+jsidU==;w;`rao$<)3~3lfQZP)BpL&-+cO)|L7)}Oemp1 zLV<(=2?Y`gBos&}kWe6@Kth3p0{>4_;L~q@@x32E`}xnm`Rc3E57y>hl<9v~-Jev) z)z@`#F}N+*%NCnyyyolG348BO*LJzQdA)FJ<@rF6J#SXb7xm__ncDg78(Hv+4r}Zy z=DM&E#f7Ple3{=`HNA2B)mPh5L7SHDzgXs8cXEAhIFSn3b@{8Wlvcj*x|CCWPBBaM zvea3rD(?%w`j`LV)Bp7Bub%zvXBb}r<69Zzw=gZ0=Jj+{?7Xh^I%2b;^OKyN$wmRA%>*`2|MT z5-WbEKAh;AO1f6c)TPwet@&SlHO-e7+xzLA$@i7p%(N_&1}p#1{`{|NpMLtyAAR)W zV0eUle?P;Prv_r&;IC-K0#n!7YqT(0LMRI z*}F%u?aOeVrSbpY|5wlO?=3%{{`Y6kKE=QP`th^B_&*>2>L(2I=lErq=OiQI`IpS| zinnx_*UUl|T+fyrh9qM=zY0F1NaPb+emx$G?X0S91g%)E6&6kZ^a=7Uf40S^QpMvn zHv3Y{#LU~?SpO&)2G?f zd5ETNX|gL5QY{3{k%Otz_ejDCUVh%NP0wP?1%pH$-C+btk|oAh+!bRQGP5)pUD(fM zMxexJ+!g9L6nu8=!GN#627TzN}Ug(OpUj6Zcjdly6a{MXOP+qS&)G~q~W3<%jt zwoDeoFqvQdhQY!(u3)=gzkdDNvyk#6e@WiCn2+hXjv~oSc~ot+7~k|XiNVs&Wpa~O z4DZNfnari39F7S|is87jAjP(9%Dy?9*K2N`SBzEt;Eyx+bME%?>rcG%K9()d6{MXZ zy9vx`Zb1TYE_os#e+o3Y6cZofw9E%NZB%e?v+ezj!8ba?gJ@5-!;V^h?2reFNJZFZ zpIu)0o-Od0`I%++dlwD7A703wC47**H6xXz48)3^(r+l|L zQTL^dFr1Vojp?Je=t#f>mxQhhTY(5Pg zcv(@)6QTWRx?c!1M;2^x#ptJfY0IvlXyh~^v!If0r7Tw(esQj2GLMmV=@TE(zrVr% z^n?vg*R$4j1Euvypra;aclP7GJ!rFicVE$RjmFwINg8?;)w0qj#fmaA%a#J(eopm@ z_vu;A{bA^?hGkaS?tAv5hU= z>lBRIsI74Q-fd+!AGRM&vY~8gf+*{<;W8^zB#F$HV7Ot&c$P-r{FnJhA3yuo|EBS) zPr&MbPX7C#adG_6`>czL?>U(l$Cn7_!@f9u$H~A5o}WiRNAZS<@of$MbOA>D-P7jc z&A%rd{$d2dp>^@X>6jy0{ORT29VzlQ3cO2^KV2J^1c@piR+Yb??2}jTUHUw^2Mqq7 z;P(^4?#%NOtJW09G96Mo!Ynn^Gr+cj2|~^`9~$Ttj2KN8V2b4!(<2onj6-xK!GR#a zUk8>6u}+C)8eDzFz@iZ}ZBL6QAU7OW5nnw&a~y8{zFDSD)c9TS;5Xz?z^^BH5$sgW z>=p*&R@f)^r0_7r49^x zYLq%x)Dr-^kuhNC6EDGBSV9h8+%Ft;&sQ9&dLaXQYN2%7DywR`Dy%A&+AB@65vJ5P zzyq>jdP{gN7O({aWeMi71Di&c=-dc1?{h7gMrEK1#Cn-8nAdD zJ;mUHcQVj++%$*EjGysoxz{X~IVsm#LsJYcJ2OxZE{MCgvd!s}gy7l795O{moi6LS zIagJ(^KE&{oBs5CW4aKb4w=ac{COHLz3jJ(;VUxl%vE$g8HVn^cYwKU3f+x?&)p6=L3+ z%tG10M@7oY41w5I7W_{RBfDa}(`jU_+P*Yi*j%I6clzU5`o0}OL||W0hk-|AbVo6~ z9g)yXf5ZsztLe-ZM+tQ)zz-Vx99(IwSMJJp{HC|fq(r}z?i?bp`b4P{XQ~C4I3{76 zRMdg|hJZ;p7`?1%%-l5Lw}ZI|Ik<)SNRHchS0rC=byK6loz3dy^uQ`}>t+=G;xriQ zwjyF#Oc=Q+Fa#5M4wGi#e-@$tdp0Rz6jz3cipc%vOe(!)B$4i%RGJk;<_paf1!C(5 zyU8@wYq+yXAtli%91Cve1-{?iTW}*Sj`#UIUShaA<4!kr9Zs)F*`iYK-nI1z?AcaC z6`GDiC%H0lNHNYH>!=6rcu6J%fm#6%F%~!8DJWgNI5xX`Uaxkllig0es}v&0i#v=E z>_*ok82c4t5w{IFe~H5m4sEQ)oGdB?AXexk{~$^<%nC|I>^o2J^6YNb6ncmeEsg1X zzW2K62ayUcEzia`H?V5>y&Gzj39 z2KI*;9kaStE$H|8`}%&(a<0&j_v~~jMHp!rVk(F=%{>Ki2t*nf0m>Nms1D%;uNE9! zzD)inQ4rZyFdt!oO)bSQ&HQ`A>o(++!1h(vx)G`eKLUSLFcGpp30vcc+(TE!hK82~ z#n~oI7ngx#B1(WSxNz~oRq2{myxX|k9e0;dk8sM=HF>8H8;$7B zh!RtQ>YA7Z5vZu8hZz>{$c5Bxckd7DTV5Hi@@d5#_w5J+AHiyb`E+$L5psJqrnbf1R7`sW1PZz7sg^d+VzSp6~M|_Zm(wNGqb?Sju(Ng zQy8uXel3fTB@SU_*hxpDirQG%xW*nvlr4Yu*=J1e7|)!`2y2q~KS2MIpM(Ml1riD* z6i6tLP#~c|LV<(=2?Y`gBos&}kWk|#`F6=|yo<#8IR6I>(DuQh=E8!q( z26C9Mn2IeN6b)F3#J_zaSZHNN3k#juNC7u#Z=0b8N>HRRSwvrHF}TW7V(mUou*p+u&}yO^KD%NSn4c!#^$h;4S^_H|n|DnNqt6xC#ikhsER$d(E{k@RU#yf4QMt6vz7OH)>#_^#RRuPT}sK@tw- zAUXI;hHflU|6mb!EMXNxaaPEFktm=mnI&EaRID0=4p#_=`XmP(p*f^f=_soTJ;O|x z8S1x^WG`mTE-N3_r54w2@*YW*JzX0%FR3aRV+9)|$mC^Ku4_48zJBfd{wopXYLbF9 zP`r;PuVv%4C0Vb5Jd1QNPR@6x>hKio`uK{Yg+mHd&8Wmo;b+VR~&2HM_2}uC~?g=q77jOIAatRStjy2 z5X&XG9?T0@G4?bHfUIUa=3u(0*1V>)Qaft8VS5{K)*7|45q5nr2UkE|ILTl0Q3!DL z5J{x9YGnUNUXTihiS1D~AUNhZW$%Mgm-__@7o|}yF?p#%rD1r4R z6d3_IdI&8_wnA#eNQwh3fk6U|e zHO^8-gZf-+@Pd28A~xn(j`ij}LghyVlUtZ`FkLXzAorW(97c*WzH@s9xt!g;Gp~tU zC8G+XLB`2>`P+_j9``vFuPW%)1)GWfJ=q`TZQmn)E>t;fpA z0f{VI2#Px^no7GMWiBZ8qxp=qHYUSJ!u~9N;#u$Jfw$LX!7ZvAwd+?3^4w=vXYobv z5o*0rQuud}M{107lYx?&=Ttpo_`167xDiC(+}x2I1d@nC(v06&nkVa{erF)f)mbUS zd-nZ7NiNtIbX;vf&TrB#D(YHDNH#@6t3)h||V|f7db&75DZm=flgZNf#glof?uw9TXm;_Q3T}vv90TLPC7#QHNp-BoFd4RV`-N zjgifkE8|9Y6N=bmLJx%&7&Iw{Mluz(O4qcg@8X5FGAJn5?wgv zvb+dA$WXeXp2`;&SwmH}Lp3)museGYeTbqh3wn5mN~i%ItktUJ8k*0_GsDjFgR+^8 z;!we&SIq^$BaUgGF)Jz+aW59``qeSp=(j4RyX8DPk5ck*T-#3)FbmJKrph z%x1P$<-Fo#n4WZnonDWy*F9aHn+{MmEX_miI?h~LZ~8TpMZW6D1(1cNgy)1%K8?db zm^MZ=zsR?B-}kDM#v~VkSMMNBm%y}eEKJPR+I&-qlsX&Em;q*L&wXX5& z<(_SBIo-V7Yi{#?CyXO3f8BI&Fu^~r>tNH@ASU23V52V~S&^(9vs-SRO5L=1X}{;% zj$5qhMYnI%Bj|`YP)F3+2E`EmH)sTqSIGS*Zn{^mUcpv}={{GMR{)kFHGtO)^s*(` zV*qy+PBkQvTPuQ5lPd1gSw_*3ry6>DhB}E$eq)r&s_ZT2d96<8aC5I0&MXjKedx$r zg~_E-@cw34X2)dG@eZ?ksCQPGmd))K{LMT+E7#a!gkcV7&B*IzfK`E#9tk8LuVjYX z$_8PkvSPypRENz;QKPPymVqOayfcEUK_?4Rg%1w#7R#G!*trtY{T29BNhJdTEg+fD z1jdOjRrnnpYOO>k$Je%pd7JfEBja%Mv6f9mphDF{IV7W@_H>1vG!{_wrZ6s!QsO^0 zRM>^_E?zOaD)X7WBe7Mp-Yn*(ecy~yJaY1!&IJ!L;HaBIe(o5yn7J+#Gg)SYWrTJ$ zBsul*PQqKz=Cir|DeMi$kGt?&9hdl+GWT@2Z=_Iu-UtH+26BA2cVfU6y9=P82dFH;q(+e&Wad z{Ef~n@AMjsZh-$d<1#lMl_H#5H1B0@3U#NJ!LH4J;eFS5(ij_hcqXbiofXYDQfv;hOqD+ZA1FQ*+ z_Ylw%Oh^!8KCQOf_F=Z(%@4fN+--Ov+rFO>49UmpoK@6}QrSqL?TD_1|B%>%@zZ)! z;as727NWF_7H9^v&fYW>5$ZvJccNjQ(w>y7V(vr~BcKe#(BR5I0^>cbevr#V>sEmZ zdm_-0Xm8Bn$x4H>vI>jzzOm#s{Z4I^84U8Z2%H=2P_m?g<|7J9mK0OPIp@UftWO)f z$*KCd%=URR=gRDUU5^rC7}Mhq$Vd(?yIlauB!J`zP<4^w2<;pxFtm)Aa4(r0IaNuB zid-A-LafJzo*wnQ7B@+ka{4Ge*hQIDQ$dj{j0>tlAh1fq(~53^X~|hm1J#a;+_)t@ zk%$HWhfdtelT;ke(u=&z%I2^=E8flL>j-lpqb{=)^IRrwkvQ1yfMvCmj9RtLD*8{X!ov3;vF$@DL?^H zn{f`pZDC@I;v7L-GiJkTp02Xqg5NY*x$PYetx{i`Xc2_u$>0sN5x80b)NLB@t6rZn zA>-Czz5Hm^(z7LzS3I+j9gQYU{w~7E?__NYC*_&wBxFeJS!9S)&=k=WV)k$KvUVq3 zbw@7mXA6~0cHeb+5g4ZfG!9@a6Lb3wu6y#i+3zoWNnLli^lnpbEC#8D>_-?Mytj~T z50s5C$V&uMGUGUx)_Xs5vE&;wTu6^?O z-huLcaf?vHdppke#kV|ppl=8JzPLlEafXKbzWCxN5B*)3-xv1?HFz#G>i5Mrzi;%R zoI~$|{=T?JsL{U#{QKf7o;=LABY{9<;Y2>J#x_{GKVBTcC6 zvUkCQU)&@708aqn7Z*QyfbT#Fzqm!H@qHU7{Nnm25Am&F;TJauHNbbngk$Vq~j2?x0qwp(N+iQ+}k(+MD@q)rqnsHH}#Fm=vN8 zB)v2A7(?;R4uvRc`hF?0>4jmJ*_m?_VJ*sAMIiMYUB$K$wpj`ATZSHIC`EXsuk$ra z@i|#38J)rA;N+(f0t}a%5l&YT1|`WTA;8`7j(3*Vo$jzMl)38YUTQ4N!r<;9K`Xq; zF%lIAUR2~AA-;!r7q+Idgkv9t!=VQpiV>`$Kg{h8Q=9WzQ)8O3ZaVuYPBm2U!F6`} zFZ386aoi&f<82vnOCyylN!l`{=I-aW0O`BwG|v+7!97z-70(rGbcd(2>|?w%sMhUn zH|E;nM#w2{q}aPdeICJ@?Tk>OY6$RZK-k*w$Zb5?v*F%=jf;>b@y;+L*8zCOt^nA& zZD>-4l1-^arNjC5QectGG3D)+qt+hC6`ntlDqFV?$mv7&M%;0U)^63`daaVB3QjgX zm6ak}8l9Ik{1}5g*{_)iDlti`nrnunn6hx1G z?7@)uDE@!)Q3Mj_J>WHo{r~=^aiLDO#Qs0p|4IJ;`~2LY&h;e!Kgs`3^8deNPMLqy zS@&2aC&~Xm`u9RM6;AU1PyWy+%kL!rp9yu&CHenJ{(qAH|D;nc$^Sn&)V>SFndJXp z;DaUk|7f}lmGZx?_wT{S{p6>WyF z6-3X|3DyWLtd73|mE{_nyg%RFtGC`^QPQi+LKLXs0kAm$m(7r>%VT5eubHup^hpXa zfr4fNa^s?x1F$EtZBN^QAl~?-l{(D|q;FmHxsR9A3|aTGhE!2m{UA=*hA=LV7ZG+# z3niuKg^oOw0NR7JQzoUiapPpL>1wZ(H>S4QuihFhzBtk}DFPz}xvZq~bATB{B+;>Q z7P-b01MtlveZYiD%nJg1OnOF>R?AmN>qF@xfr=yeBBTn}iFwI53QTkxYb`Yr)*ys z2&yzJ+}D{iNvK8{_)`Yvy zE+VLGLm5yUA_aQ@><7_B1)tzD#>?i#nx;*=#f+oMje}gv7;ZUIO$EAYP_*xWBf#sF zGk{SJ2swtRI#}XVBg8M-FchNc+jeuHUujmxV0EPes3bQFqNY|9V6Kum` ze}~6&DPdvd-;8o8V*iy2yDfv-MbT1NL(?h0UTst{{$$#CYBKMpsj|;W5!ak zganiXz}PYGA)~zBIitQY!`vlx9@sVvExKRBW%F%Av}Zsjxq@-xZt)UCh`^F>F5VY?SdHZPU#qS&X=30!ssup z&0W#lKMh7e5AZtMn$%-u;;EfKR030`X08ni~5_Cm4 zzCrQ}0OP^DAg#R-v)5vFDmFz#h#f_qseIk7)@K`2j1UkQ`7&a_t_eKqD|mPn!$&Vi z^@^c5=x`HCrhmn}eCgVXEWLbbo4N<&pev>d1X)C9(5##(mEv^))i;*fE=zZHeloi& zt?%z{YUNA>XDMw{PID#X1p%NYC@aK^wI&TgUFU12E9?QDi>V{diU!5<*D=RHoEupa zhcL+x4S8GW0RhK55V&8Ej_V{gjK4Ba-X+rTfTAUl*`Zq%+J_Kq zr#e7M@lMTV&;gzxV<6UJkr-!{bT&gSK&l7`_3IQKfrs~a`n_C>3ob_e}hgmr!Svad-1SK02FNq+(d_a1W@BeN&o;chl!n_aj)T~#_d zd+=>@-z!9L`c5DR(0hh97Q=E3(6{4?>0tW^q@|yXjwwC#A3LGm(w1bQC-Q)*b1uyP zu8xP*FAT?}DXUL>*KGG!70rtv35V!ME7;-+9e7CaiUj2>5||^bVh|W&wArBHAp*dH z*L~AgAwQ7fKtpp7GT3AQ4g%WMBiaUsLZ{GgCCOgQnq5{ttV=Df-Q>L}op(=NtX8sy zMnufYbuH)1*ROrwe+BS!K|)&_7pXCL@>(`tTaxwK0md>=XRa;ep_tCKyhDPPMAA{N z=g17W4!-DGkUY)324b))U$X@?=_?kkS1VW7{=~7Z(2M;*iVwOLw(?35!CR;AKB6XS z(x$JA%8YO4o7$i@To>=n^9Fo?Bse+0o|AmB!ej6VnpXb)-Y{pXCk`_86~`L)5jYKy zWndu(otrJjCP3%NOhSIl6|&!ek;S|~Z$SizAOT4vE9N+_sMfruv{E~2x?y`8an>5O zvJrNDFb9`35hOjXe574nU0_Dz9Hsk5LiQUXb>!SdP#A&jM}YA?@WXpHzrEzvclCLi z=O&}PJ69E@a9;87K7=L|8G+{Y1nov_(yk%En>lyYp-pkfWUdM3yhk&ENMj$;|9~8? zvB!!zOBoI7bFIM(?hUI-ThDT=2ul@AZeh+b@?fZFLj*n}gO8NF^v>;h#G&sy^P0$2 zGH7x>$T&GKf7@}+<376wt3hb@yoJxGrf+P|%o*Y|1YAgGT-vn?hmygkRU?g9Z7x@6 zMbH@sq$9Zn^hF>6lB7b?Yn}ABpbZviTZIgoZtc(FhceoelTVum-d>jlx2SH^u3st0 zbDxcpl!tT?64{J-bjCP087QfFPSrDpudCaR8$t9TZ;0dpLa8GW`k0fS{LVm{tFuyu z_w4(F$aN-CDjPu>0Bl?(X>jr~ZX&7%-_+E`u#K(Z>8f9>+(bzlsv&ud@FeX;OcI`e z3WqkYo{Rr!gL>$}i-i+&oBG*)mf5yOn<>BHQ+2+y)Nu zu%XbPj`aRTHtveHI|7VourW_pU!98z$bopwk9ZYfsXlOKXlA!C7`J*&PVU_dZ|a>* zBilaH;CyD37bHIpwz@?!f{@jB8p(xnSInINrl>?N5SNJ zQ^?ICoFA1y>G9^I*B=_*9-9pzlMkH_QHTM%f)s3Ew-Wn-=ufmmAgODJU2gZ(Lg}_u zR@HP>SXC^wSDIuaOsNm|&Z%7^#t99Ukds04Qrbuc${*%NT8g8SDY_=1=b*O_&dZ=5 z7SWhUZOY%3(y<*k%^@`Z8K0JW&0?98a;^1um5v^;p`p6Ig>6n;LYOA|7^S1=sMBRV zH|MHKcD^lddDEYsZ%j95s4y1wN1et+FMF~=QLS#x`Y@&USkLNB1YWbo<0xG`f0<&L zJ)BF(-i&vE?OJ!r*^SnLYk2o#Gq>M}5sqsl=A+jpO^w4=qL0TioJk~CE=VVgyZ)wZ z%dVeu9F8A#MNj7HX0FtaFmfbu!G%iX7}-bxVk>gakp4@goQWzNH1#4jp=?l(7wPef zZgX+xq&2cuZC@HMY_8GkJN@x2ecz5CB8W*ySe@XO69=9I>VhIP_(ag(SHL9D%vB^sD|3_f za%U9C!L5M07aX_oZj5}r)lH2GcQ&h+(*vu_t(#H!i=%xB0lj`q41R&`jF8UgQ4Oz^ z2piCYB8i%>m0@b;a{oD#N^coSq&p{-W(AS?0_LyaqM2#1o1g<-0o~Ba+cO4#e%!(K_aZ3-u%d@*#Q|PH1v_zlI=X*XPeg3|_U$dMm zG~_)yT}lx~T85ZHnvBhq7m6&0w6(**)m(1;lp@5qJJZFlbv>swwK zqP2kHj{8xH*ha7#(VUrz&3Femy0J5L_&9fLwKSJ*w?em@il9X|!O_s1zzCH2p+nj7 z5)obd(pZc~yI!%S0$4fA?bYmjW)?Wv@glHw3d8llujO+=2=V*}MisTONYTfhmI{9M z*=J~^5Y+n55dkp>&VN$>|Bx^EWQ!@O|4-`wiFAmNx0}@eBl-KEyYRC5q}crf*eU7K`<` zrFw{u!7McE00FX@Y=T*3Gub4YAiMqnL00n*@&^(GSw(L?_otf?wA&O+N z$U67jbI(1G?;P^ohUyYDqPBrul#2anY-=m_R|v&o_q|vw_G7r;f%`4Ef3$jp2miLU zesc9Ae8;n&{L{Vre-XQN@3*lBzq|Ub4bD!LOa+dty_M?Xnw|-giujV<#X7>*- zU4G}@RsiK;%9<;FIOsOrudfdUf`|2@S*T~#I zxP$!XWM(1NbcsUjC(73CM?d}P*4d{%&DgRWX-o{fdGf&}>Nkh49>VhTo8h(Eebf>f zjVJeDR<<7eE(U+mE#g4LfrtYU2O&0Rap2b0hq0{> z?mhTT?8E#0*!}+f|9!1X5OE;lzz>!K4}P5CU%9z9xdXfBZn zg@0CgIwE>*u7Ee`ng>rEaKX#8Mc0PZyJ90~Tv4e@{4fnEpMzvQ>%%=4N zf~R{<+?*HaBzGc7BWmzdBAi+!qXIlS<#YPc{_z(|X19@PbG?C_OHcAIUR1OFr0#0N z6gQvsl%qw_;VJIE{OK>h{PPcg6#L|pdytqnu!#W-uzCQIJ-mk4{$;Rp{rvykpTywr zs@u1{ty{6*f7|%>fIYIa9{hXk_jkU!cNd|bvwsL}GlazUbF^LX6bJ315y7r!69+MH z#`ezYBvodooC=eEU#h1y?F8$4`BH9Foo-HH-}AFmI4!Za{uFza&8}Yon8k45h<|l< z=@kV&70V0oqStIo&6$?%>h^wpVOYK7<_i9K5;ZKHxP;L&!n#9N-|oN3a2{}cyJAz% zLUe@uOCl`GL`GB99V2QIq)=qwxkwQ9$B5i9luxJ*yj1+pjR=teQo_cMMm9AN_FTHY z?lV;5kfs{aSVcCGREw+`;8Wm_{~}42tx{Wc=Rj6`$xDQOu{q&&4lL@kPOVHQ2ZC2x z=y`p=Hb2QKm#(oU<*h8JxyTt)PnUh%OU(q3j0+=_Jxf<53}qvXH3$X{FdPJLo)Y`B z|N8Y`|I2^=>)%|u*n1DCl5co~mUWfOiU)kWxYwEKe26*Ciz>jO0CfYiM^9Ju!wU?! zp7CnBZkF;!f8MJIImzQHqCF@lgp#AzLQvjNVcq?S5Ig(l2fpa9CjC2Kc)4idMGNl_ zzwp?ub7v4c`-eY^r2jkHc4D#H{}Vg=b@Pvr#X#Fp?CkF!{xQ<#n>F7Xt0NZs_;=!I+s`5t{`%%2jPAgc||#-vW7}qmizfU{l>@hE-s{vNXz1 zIi+Sbh4xseX}zJj$O<9+$^v%BHU+2HT5=0LMH1FQs1;-p;tQVV%9Mh*gFHcGVdLvU zsNua?dAzXjV3iA-W95AsxCAwr&5ONz^4oagjl~`Gag=Obvsg~!( zX3l9Wc&?q|a`A&s(G-dycwd7G6Nt>XjLXhgwcQ)0v#-xN#qCq!WI;uzlh)K+H^e&P z5bA)=lT}#%HAly$yektOqcH|GfY1R3-t*dg*U*rs1M_c|*}5=M=JDz&XVC6kcdN%U z+z%lkW$HMp4m2AED9~NxK-|RjIS-K^hv+v;G&xPtS?|b>du7fR^{Jl3$q<|`v>R>K z4+K@QuG1+YCX%S*dQbud0*@V7tbPjf(w zVi3H>BpX;RgRBFU$npF+cMQT>0t933o{UDCpp>89qxDc;<(;*CS_M`WKKhn#xFTJ!Jz0|(0{grT~#L_7P_j8 zT_|R=@f7qSQ!rBu@y{Jlid0q!tC=$u_|Hz8688UQnJ*56o>@KWmN{cIAibU=NHoj< zrx3jc4GuGarpRIn{if%l$k+BHtDj}3P+em#y?x{emORW$LU5fQf z_OOg8|9p956IyIR8bUSb`m48>QTC)%z%wO^6iB{7hVpm*>=Q| z#1&E+<~u1T<7K-IXEQe&t`xCh0qZx!oo6mCT{ymewHfhRjjY)0NBoyp&I^^1S9I0B zpb8B#osgp}*Ii%0KQE98TE$R+s;eg+=y2FK(MVk^=CBlD-$$Un4GeXwGAvKce^;U= zv%hVyxS4ywJ|MBz@YJ`yK6gOpQxk^zIdUkPc;J$V{^G{IYofr~zVKNxlZdVp)7^Xv zd?C0K4$Gumq6ChESF@p1^uV)#eMX-nD6G9S>i4$zCW=5y_Ka%9(!r3V60?I64xt!C zI%A`-{XCEf`fQm2a;QPp%aCm{b5w+JsV3IZv1*QhqeTDmW(Sm6B&wyViMhHs>WWF7 z5lMM$Tslmii=T=ar#u(0F}NDIJbF z+3Gk1^&QyBZDhe#ey$_lnLi8UY^CR1La9hXGd>@jwmXyNet*7M>A@Fb8D!anJ#r}= z%%t+Gxfx?6$UfO%Wx?9`f`KQQkDSpi9IBvnrr1y55` z>2%JKx~H|{5MwJ~L!^}1iJF5nQ#}P6i|G!>qM%T2mS$x?)##Xs_yK3={XM>2=~cTY z8nB#pLgO3RUGlG;dGFW~cEG;lfLdwR) z?f%}~mn{DeP5+`>#DRzd5eFg;L>!1X5OE;lK*WKF0}%%z4n!P?IPk;fz()*MaSqde zX9z91j$r@dVl2UrbHAE8IDqPtbu4I=H?SM?{@m`=<860d&@&aN)7ZrRE~E`M0ecqw z-MbD7x#o72+)0NM=G4lYo;cpigb5Z^u?oROo64T#qQ{o!y7L_**#sLtDhAJ3I&119 z$%(9b1|+$3d3g-d>MS}eQhAPuImV_0(evPm#z2YE6VL5cXI-(*@rAZgnvTdxmk$vW z;{lx`dJ+WjmJue$9~Fia0DA0D&jy^4^W-^dKq43d|Lpj4RDqGg>6m2#Ak+_|F5A#t zbc}lJ*bZtg8L~Y2kl573I|$N-81nQx2yu?ZlCpFM)u};c$`XdkHDb(x_~TSM39ixB zY24$@4&)o%qC_`>7CdIyUqK}XfKLG&6Qn*^l(PVG02LoFdO$O={J87Fg9nj*80(=^B zrx5Ojli2!zw9>P{%n1}_op_>4_Kn6QURiKCMarA;dWdi~$TvU)6accVvpX;dR<^?s z5FqEQU}P!P(A|~T&ru(nCI(sOu>ukSm<|x<;#g%**~*8Lum>uF$EKn}tRG5@0OBMP zSWm1T2vha zWCe9x9dL;jmu*`l-jpYbUc6eOUE6zOfmT7)02`jkd z#5UESRAbGfDJm56d8V7$14}sqzLq7e!IC*up#eBRqF90+Sz}hk=%*n;r3aqyKq|<_ z*q!n{D#ullB;Ed=QIYmS49bCo7bHSA+bZbQ83QIXV5ERb0Obs31Y}pSiLwmH3}(fM z*sv?lQ3}w>tCLVFyPMiuLXlwW(&wPh84|)zR>FTWgH3(Cod;$_pv`GMKT(YhmZkBOyGw}5pVB|_;u$-61&XW7PO=`;chBu)ur!)$}+{g&oPPJEV zH)%fE4Y8a+fL}|G)=xx2*EcWt6NqH_+u;JxkBN06u?9eia%$ejR^lA;s2Q`gxmX9S48-K zw7qU25#j%@+qojb|1X=5MEHNuMHhr8khvY<|0DeW6)^mbkG}EA-%xlE;r}E2KZJ0u z43S0n|C=!pBmDm|@CK2C2>&0T$wh?!|L*YrD`>-q@OT&QKZg5{R?lzWOy`Hd0h~aw z$z5(f3`B$><^rWisJ3eX6Yp+Oi|2E|R4AprG1;x;{L`EtU*vcwYd|o5d zA85UOKU=20JJZpwwh+q_tOe^@D7;N3n`O4IgTYgzaaQdQ`9p4yJ{Z(^MNMcSo(u%-uQUXmb0cmAOD%`B3d@4abl|EdRa=b>F+7 zS}mk_3?lV-?7G(T-QDSQ`i!;2GAR5kwB|g6m9SeJlTjXeW*M(T0@pdDP(vxDlR{=8 zrA@9rJQ-G!V()a|hTu9>oC2@?{ugVh+4y~HAqYj_D3dAWhdfW>*}hqu<@Q<}Cx#%9 zhYa}ZD4O>otxoqGtA2c}2m^1Jk_Y{26^Cil+oR&^w#vIHd-pm9AniuWu4iSnmIESH za+_8ZY&EC$_BXFLF|j2XZ$cRznYrPiCsU4Z37lD%jym;Bh?y(UsSceW0F?q;q6k1k zQ2aK55`NfHn0jZ2{pLbC;7{3x&-3i;L32IijUcX7)2o6QNZDukcDzHe~0x zkc=ONaUu?2ILL3J5SYF|N@+562079c`26f>e%N+udKl0d0Gq%iC{mO4=mGl#_FmSD z&jAPtTj1z1^wyKVL<7|{;e;<=*G5Y2XjOQj6 z-BZVn5EiaZPF3{S$I`B#N=)Qg%Lisxf%S-`@e^>;Ook@6Rm)=b4p{8~CPx#3O$R+r zrB^tn8A>JD%76o`sZ#j417APN|404*m>OlbDF5#_bB_A|fo_TV|6M-?9rgc<`u_#U zXhi-0)<5I(hBQ12%!7xr9rgc<`v2XGO%nD0d-G3RMg9Mne7)X?GwT2M&R<81`u{P} zdE1Y$eLwpDv3x(eD$sLYfEXx1xekI|E60%BK=b@c|8)d>J3vq}s`O_v2u^#Tw!lBs zN`G@$TNK-3B2Gp^EMwMg;VfddzQD1_k%$^rX zM12X~0y+KR^d*?J=rLb{9~+LlW;VH~7gJ%<0pYq51gakB7WHYoZ60elp~ZQ(g6oaL z5K;dBgRTS}O))vXr^nT_C=O=DdaV~C7Z?q<-Q&%iR%AXDbw$3 H{r~?0+}3(L diff --git a/pecklist.csproj b/pecklist.csproj index 827a517..ca19501 100644 --- a/pecklist.csproj +++ b/pecklist.csproj @@ -1,17 +1,20 @@ - netcoreapp2.1 + net5.0 - - - - - + + + + + + + +