From 90609f758d26b7f931e379daeaf6703d7d30e5cd Mon Sep 17 00:00:00 2001 From: sunkaixuan <610262374@qq.com> Date: Tue, 28 Nov 2017 13:17:18 +0800 Subject: [PATCH] Update Core --- .../SqlSeverTest/Demos/1_Query.cs | 183 ++++++++++++++++-- .../SqlSeverTest/Demos/2_Update.cs | 12 +- .../SqlSeverTest/Demos/3_Insert.cs | 4 + .../SqlSeverTest/Demos/4_Delete.cs | 3 + .../SqlSeverTest/Demos/5_CodeFirst.cs | 4 +- .../SqlSeverTest/Demos/8_JoinSql.cs | 44 ++++- .../SqlSeverTest/SqlSeverTest/Demos/9_Aop.cs | 46 +++++ .../SqlSeverTest/Demos/D_QueryableView.cs | 33 ++++ .../SqlSeverTest/Demos/DemoBase.cs | 2 +- .../SqlSeverTest/SqlSeverTest/Program.cs | 18 +- .../SqlSeverTest/UnitTest/Delete.cs | 14 ++ .../SqlSeverTest/UnitTest/EnumTest.cs | 2 +- .../UnitTest/ExpressionTest/Method.cs | 15 ++ .../UnitTest/ExpressionTest/Select.cs | 58 +++++- .../UnitTest/ExpressionTest/Where.cs | 86 +++++++- .../SqlSeverTest/UnitTest/Insert.cs | 2 +- .../SqlSeverTest/UnitTest/Mapping .cs | 2 +- .../UnitTest/Query/SelectQuery.cs | 16 +- .../UnitTest/Query/SingleQuery.cs | 16 ++ .../SqlSeverTest/UnitTest/UnitTestBase.cs | 6 + .../SqlSeverTest/UnitTest/Update.cs | 27 ++- .../Abstract/AdoProvider/AdoProvider.cs | 2 +- .../DbBindProvider/DbBindAccessory.cs | 34 +++- .../Abstract/DbBindProvider/DbBindProvider.cs | 4 +- .../IDataReaderEntityBuilder.cs | 23 +-- .../QueryableProvider/QueryableProvider.cs | 2 +- .../SqlBuilderProvider/SqlBuilderProvider.cs | 1 + .../MemberInitExpressionResolve.cs | 60 +++++- .../MethodCallExpressionResolve.cs | 87 ++++++--- .../Infrastructure/SqlSugarAccessory.cs | 24 +-- .../SqlSugar/Interface/IDbBind.cs | 2 +- .../SqlSugar/Interface/ISqlBuilder.cs | 8 +- .../SqlSeverTest/SqlSugar/SqlSugar.csproj | 2 +- .../SqlSeverTest/SqlSugar/SqlSugarClient.cs | 49 ++++- .../SqlSugar/SqlSugarForCore.nuspec | 2 +- .../SqliteTest/DataBase/SqlSugar4xTest.sqlite | Bin 241664 -> 241664 bytes 36 files changed, 781 insertions(+), 112 deletions(-) create mode 100644 Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/9_Aop.cs create mode 100644 Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/D_QueryableView.cs diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/1_Query.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/1_Query.cs index 230bc5649..645122b11 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/1_Query.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/1_Query.cs @@ -26,6 +26,80 @@ namespace OrmTest.Demo StoredProcedure(); Enum(); Simple(); + Async(); + Subqueryable(); + SqlQueryable(); + } + + private static void SqlQueryable() + { + var db = GetInstance(); + var list = db.SqlQueryable("select * from student").ToPageList(1, 2); + } + + private static void Subqueryable() + { + var db = GetInstance(); + var getAll11 = db.Queryable().Where(it => SqlFunc.Subqueryable().Where(s => s.Id == it.Id).Max(s=>s.Id)==1).ToList(); + + var getAll7 = db.Queryable().Where(it => SqlFunc.Subqueryable().Where(s => s.Id == it.Id).Any()).ToList(); + + var getAll9 = db.Queryable().Where(it => SqlFunc.Subqueryable().Where(s => s.Id == it.Id).Count()==1).ToList(); + + var getAll10 = db.Queryable().Where(it => SqlFunc.Subqueryable().Where(s => s.Id == it.Id).OrderBy(s=>s.Id).Select(s=>s.Id) == 1).ToList(); + var getAll14 = db.Queryable().Where(it => SqlFunc.Subqueryable().Where(s => s.Id == it.Id).OrderByDesc(s => s.Id).Select(s => s.Id) == 1).ToList(); + + var getAll8= db.Queryable().Where(it => SqlFunc.Subqueryable().Where(s => s.Id == it.Id).Where(s=>s.Name==it.Name).NotAny()).ToList(); + + var getAll1 = db.Queryable().Where(it => it.Id == SqlFunc.Subqueryable().Where(s => s.Id == it.Id).Select(s => s.Id)).ToList(); + + var getAll2 = db.Queryable((st, sc) => new object[] { + JoinType.Left,st.Id==sc.Id + }) + .Where(st => st.Id == SqlFunc.Subqueryable().Where(s => s.Id == st.Id).Select(s => s.Id)) + .ToList(); + + var getAll3 = db.Queryable((st, sc) => new object[] { + JoinType.Left,st.Id==sc.Id + }) + .Select(st => + new + { + name = st.Name, + id = SqlFunc.Subqueryable().Where(s => s.Id == st.Id).Select(s => s.Id) + }) + .ToList(); + + var getAll4 = db.Queryable().Select(it => + new + { + name = it.Name, + id = SqlFunc.Subqueryable().Where(s => s.Id == it.Id).Select(s => s.Id) + }).ToList(); + + var getAll5 = db.Queryable().Select(it => + new Student + { + Name = it.Name, + Id = SqlFunc.Subqueryable().Where(s => s.Id == it.Id).Select(s => s.Id) + }).ToList(); + + } + + private static void Async() + { + var db = GetInstance(); + var list = db.Queryable().Where(it => it.Id == 1).SingleAsync(); + list.Wait(); + + var list2 = db.Queryable().SingleAsync(it => it.Id == 1); + list2.Wait(); + + var list3 = db.Queryable().Where(it => it.Id == 1).ToListAsync(); + list3.Wait(); + + var list4 = db.Queryable().Where(it => it.Id == 1).ToPageListAsync(1, 2); + list4.Wait(); } private static void Simple() @@ -40,10 +114,10 @@ namespace OrmTest.Demo sdb.DeleteById(1); sdb.Insert(new Student() { Name = "xx" }); sdb.Update(it => new Student { Name = "newvalue" }, it => it.Id == 1);//only update name where id=1 - sdb.Update(new Student() { Name="newavalue" ,Id=1});//update all where id=1 + sdb.Update(new Student() { Name = "newavalue", Id = 1 });//update all where id=1 //SimpleClient Get SqlSugarClient - var student3=sdb.FullClient.Queryable().InSingle(1); + var student3 = sdb.FullClient.Queryable().InSingle(1); } @@ -75,15 +149,25 @@ namespace OrmTest.Demo outPutValue = p2.Value; return dbResult; }); + + + //3 + var dt = db.Ado.UseStoredProcedure().GetDataTable("sp_school", new { p1 = 1, p2 = 2 }); + + + var p11 = new SugarParameter("@p1", "1"); + var p22 = new SugarParameter("@p2", null, true);//isOutput=true + //4 + var dt2 = db.Ado.UseStoredProcedure().SqlQuery("sp_school", p11, p22); } private static void Tran() { var db = GetInstance(); - var x=db.Insertable(new Student() { CreateTime = DateTime.Now, Name = "tran" }).ExecuteCommand(); + var x = db.Insertable(new Student() { CreateTime = DateTime.Now, Name = "tran" }).ExecuteCommand(); //1. no result var result = db.Ado.UseTran(() => { - + var beginCount = db.Queryable().ToList(); db.Ado.ExecuteCommand("delete student"); var endCount = db.Queryable().Count(); @@ -128,11 +212,13 @@ namespace OrmTest.Demo // group id,name take first var list3 = db.Queryable() .PartitionBy(it => new { it.Id, it.Name }).Take(1).ToList(); + var list31 = db.Queryable() + .PartitionBy(it => new { it.Id, it.Name }).Take(1).Count(); int count = 0; var list4 = db.Queryable((st, sc) => st.SchoolId == sc.Id) - .PartitionBy(st => new { st.Name }).Take(1).OrderBy(st => st.Id,OrderByType.Desc).Select(st => st).ToPageList(1, 1000, ref count); + .PartitionBy(st => new { st.Name }).Take(2).OrderBy(st => st.Id, OrderByType.Desc).Select(st => st).ToPageList(1, 1000, ref count); //SqlFunc.AggregateSum(object thisValue) //SqlFunc.AggregateAvg(TResult thisValue) @@ -148,6 +234,7 @@ namespace OrmTest.Demo var t2 = db.Ado.GetInt("select 1"); var t3 = db.Ado.GetDataTable("select 1 as id"); db.Ado.CommitTran(); + var t11 = db.Ado.SqlQuery("select * from student"); //more //db.Ado.GetXXX... } @@ -160,14 +247,16 @@ namespace OrmTest.Demo var getNew = db.Queryable().Where(it => it.Id == 1).Select(it => new { id = SqlFunc.IIF(it.Id == 0, 1, it.Id), it.Name, it.SchoolId }).ToList(); var getAllNoLock = db.Queryable().With(SqlWith.NoLock).ToList(); var getByPrimaryKey = db.Queryable().InSingle(2); - var getSingleOrDefault = db.Queryable().Where(it=>it.Id==1).Single(); + var getSingleOrDefault = db.Queryable().Where(it => it.Id == 1).Single(); var getFirstOrDefault = db.Queryable().First(); var getByWhere = db.Queryable().Where(it => it.Id == 1 || it.Name == "a").ToList(); var getByFuns = db.Queryable().Where(it => SqlFunc.IsNullOrEmpty(it.Name)).ToList(); var sum = db.Queryable().Select(it => it.SchoolId).ToList(); - var sum2 = db.Queryable((st,sc)=>st.SchoolId==sc.Id).Sum((st,sc) => sc.Id); + var sum2 = db.Queryable((st, sc) => st.SchoolId == sc.Id).Sum((st, sc) => sc.Id); var isAny = db.Queryable().Where(it => it.Id == -1).Any(); var isAny2 = db.Queryable().Any(it => it.Id == -1); + var count = db.Queryable().Count(it => it.Id > 0); + var date = db.Queryable().Where(it => it.CreateTime.Value.Date == DateTime.Now.Date).ToList(); var getListByRename = db.Queryable().AS("Student").ToList(); var in1 = db.Queryable().In(it => it.Id, new int[] { 1, 2, 3 }).ToList(); var in2 = db.Queryable().In(new int[] { 1, 2, 3 }).ToList(); @@ -183,11 +272,28 @@ namespace OrmTest.Demo var joinSql = db.Queryable("student", "s").OrderBy("id").Select("id,name").ToPageList(1, 2); - var getDay1List = db.Queryable().Where(it=>it.CreateTime.Value.Hour==1).ToList(); - var getDateAdd = db.Queryable().Where(it => it.CreateTime.Value.AddDays(1)==DateTime.Now).ToList(); - var getDateIsSame= db.Queryable().Where(it => SqlFunc.DateIsSame(DateTime.Now,DateTime.Now,DateType.Hour)).ToList(); + var getDay1List = db.Queryable().Where(it => it.CreateTime.Value.Hour == 1).ToList(); + var getDateAdd = db.Queryable().Where(it => it.CreateTime.Value.AddDays(1) == DateTime.Now).ToList(); + var getDateIsSame = db.Queryable().Where(it => SqlFunc.DateIsSame(DateTime.Now, DateTime.Now, DateType.Hour)).ToList(); var getSqlList = db.Queryable().AS("(select * from student) t").ToList(); + + + var getUnionAllList = db.UnionAll(db.Queryable().Where(it => it.Id == 1), db.Queryable().Where(it => it.Id == 2)).ToList(); + + var getUnionAllList2 = db.UnionAll(db.Queryable(), db.Queryable()).ToList(); + + var test1 = db.Queryable((st, sc) => st.SchoolId == sc.Id).Where(st=>st.CreateTime>SqlFunc.GetDate()).Select((st, sc) => SqlFunc.ToInt64(sc.Id)).ToList(); + var test2 = db.Queryable((st, sc) => st.SchoolId == sc.Id) + .Where(st => + SqlFunc.IF(st.Id > 1) + .Return(st.Id) + .ElseIF(st.Id == 1) + .Return(st.SchoolId).End(st.Id) == 1).Select(st=>st).ToList(); + var test3 = db.Queryable().Select(it => it.Bool1).ToSql(); + var test4 = db.Queryable().Select(it => new { b=it.Bool1 }).ToSql(); + DateTime? result = DateTime.Now; + var test5 = db.Queryable().Where(it=>it.CreateTime> result.Value.Date).ToList(); } public static void Page() { @@ -245,8 +351,19 @@ namespace OrmTest.Demo var list4 = db.Queryable((st, sc) => new object[] { JoinType.Left,st.SchoolId==sc.Id }) - .Select((st, sc) => new { id=st.Id,school=sc }).ToList(); + .Select((st, sc) => new { id = st.Id, school = sc }).ToList(); + + var list5 = db.Queryable((st, sc) => new object[] { + JoinType.Left,st.SchoolId==sc.Id + }).AS("STUDENT").AS("SCHOOL") +.Select((st, sc) => new { id = st.Id, school = sc }).ToList(); + + + var list6 = db.Queryable((st, sc) => new object[] { + JoinType.Left,st.SchoolId==sc.Id + }).With(SqlWith.NoLock).AS("STUDENT").AS("SCHOOL") +.Select((st, sc) => new { id = st.Id, school = sc }).ToList(); } public static void Join() { @@ -262,7 +379,7 @@ namespace OrmTest.Demo JoinType.Left,st.SchoolId==sc.Id, JoinType.Left,st.SchoolId==st2.Id }) - .Where((st, sc, st2) => st2.Id == 1 || sc.Id == 1 || st.Id == 1).ToList(); + .Where((st, sc, st2) => st2.Id == 1 || sc.Id == 1 || st.Id == 1).With(SqlWith.NoLock).ToList(); //join return List var list3 = db.Queryable((st, sc) => new object[] { @@ -285,25 +402,49 @@ namespace OrmTest.Demo //The simple use of Join 2 table - var list5 = db.Queryable((st, sc) => st.SchoolId == sc.Id).Select((st,sc)=>new {st.Name,st.Id,schoolName=sc.Name}).ToList(); + var list5 = db.Queryable((st, sc) => st.SchoolId == sc.Id).Select((st, sc) => new { st.Name, st.Id, schoolName = sc.Name }).ToList(); //join 3 table - var list6 = db.Queryable((st, sc,sc2) => st.SchoolId == sc.Id&&sc.Id==sc2.Id) - .Select((st, sc,sc2) => new { st.Name, st.Id, schoolName = sc.Name,schoolName2=sc2.Name }).ToList(); + var list6 = db.Queryable((st, sc, sc2) => st.SchoolId == sc.Id && sc.Id == sc2.Id) + .Select((st, sc, sc2) => new { st.Name, st.Id, schoolName = sc.Name, schoolName2 = sc2.Name }).ToList(); //join 3 table page - var list7= db.Queryable((st, sc, sc2) => st.SchoolId == sc.Id && sc.Id == sc2.Id) - .Select((st, sc, sc2) => new { st.Name, st.Id, schoolName = sc.Name, schoolName2 = sc2.Name }).ToPageList(1,2); + var list7 = db.Queryable((st, sc, sc2) => st.SchoolId == sc.Id && sc.Id == sc2.Id) + .Select((st, sc, sc2) => new { st.Name, st.Id, schoolName = sc.Name, schoolName2 = sc2.Name }).ToPageList(1, 2); //join 3 table page var list8 = db.Queryable((st, sc, sc2) => st.SchoolId == sc.Id && sc.Id == sc2.Id) - .OrderBy(st=>st.Id) + .OrderBy(st => st.Id) .Select((st, sc, sc2) => new { st.Name, st.Id, schoolName = sc.Name, schoolName2 = sc2.Name }).ToPageList(1, 2); + + //In + var list9 = db.Queryable("it") + .OrderBy(it => it.Id) + .In(it => it.Id, db.Queryable().Where("it.id=schoolId").Select(it => it.Id)) + .ToList(); + //SELECT [ID],[SchoolId],[Name],[CreateTime] FROM [STudent] it WHERE [ID] + //IN (SELECT [Id] FROM [School] WHERE it.id=schoolId ) ORDER BY [ID] ASC + + var list10 = db.Queryable((st, sc) => st.SchoolId == sc.Id) + .In(st => st.Name, db.Queryable("sc2").Where("id=st.schoolid").Select(it => it.Name)) + .OrderBy(st => st.Id) + .Select(st => st) + .ToList(); + //SELECT st.* FROM [STudent] st ,[School] sc WHERE ( [st].[SchoolId] = [sc].[Id] ) AND [st].[Name] + //IN (SELECT [Name] FROM [School] sc2 WHERE id=st.schoolid ) ORDER BY [st].[ID] ASC + + var list11 = db.Queryable((st, sc) => st.SchoolId == sc.Id) + .In(st => st.Name, db.Queryable("sc2").Where(it => it.Id == 1).Where("id=st.schoolid").Select(it => it.Name)) + .OrderBy(st => st.Id) + .Select(st => st) + .ToList(); } public static void Funs() { var db = GetInstance(); var t1 = db.Queryable().Where(it => SqlFunc.ToLower(it.Name) == SqlFunc.ToLower("JACK")).ToList(); + var t2 = db.Queryable().Where(it => SqlFunc.IsNull(it.Name,"nullvalue")=="nullvalue").ToList(); + var t3 = db.Queryable().Where(it => SqlFunc.MergeString("a",it.Name) == "nullvalue").ToList(); //SELECT [Id],[SchoolId],[Name],[CreateTime] FROM [Student] WHERE ((LOWER([Name])) = (LOWER(@MethodConst0)) ) /***More Functions***/ @@ -343,10 +484,11 @@ namespace OrmTest.Demo { var db = GetInstance(); db.IgnoreColumns.Add("TestId", "Student"); - var s1 = db.Queryable().Select(it => new ViewModelStudent2 { Name = it.Name, Student = it }).ToList(); + var s1 = db.Queryable().Where(it => it.Id == 136915).Single(); var s2 = db.Queryable().Select(it => new { id = it.Id, w = new { x = it } }).ToList(); var s3 = db.Queryable().Select(it => new { newid = it.Id }).ToList(); var s4 = db.Queryable().Select(it => new { newid = it.Id, obj = it }).ToList(); + var s41 = db.Queryable().Select("*").ToList(); var s5 = db.Queryable().Select(it => new ViewModelStudent2 { Student = it, Name = it.Name }).ToList(); var s6 = db.Queryable((st, sc) => new object[] { JoinType.Left,st.SchoolId==sc.Id @@ -366,6 +508,9 @@ namespace OrmTest.Demo .OrderBy((st, sc) => st.SchoolId) .Select((st, sc) => sc) .Take(1).ToList(); + + var s9 = db.Queryable().Select(it=>new Student() { Id=it.Id, TestId=1, Name=it.Name, CreateTime=it.CreateTime }).First(); + var s10 = db.Queryable().Select(it => new Student() { Id = it.Id}).First(); } private static void Sqlable() { diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/2_Update.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/2_Update.cs index 2f9a678a2..13a5bc9d5 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/2_Update.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/2_Update.cs @@ -24,7 +24,7 @@ namespace OrmTest.Demo //Only update Name var t3 = db.Updateable(updateObj).UpdateColumns(it => new { it.Name }).ExecuteCommand(); - var t3_1 = db.Updateable(updateObj).UpdateColumns(it => it=="Name").ExecuteCommand(); + var t3_1 = db.Updateable(updateObj).UpdateColumns(it => it == "Name").ExecuteCommand(); //Ignore Name and TestId @@ -58,6 +58,16 @@ namespace OrmTest.Demo //Column is null no update db.Updateable(updateObj).Where(true).ExecuteCommand(); + + + var t12 = db.Updateable().AS("Student").UpdateColumns(it => new School() { Name = "jack" }).Where(it => it.Id == 1).ExecuteCommandAsync(); + t12.Wait(); + + //update one columns + var count = db.Updateable().UpdateColumns(it => it.SchoolId == 1).Where(it => it.Id == 1).ExecuteCommand(); + + + } } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/3_Insert.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/3_Insert.cs index f3d162dae..4e2de445d 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/3_Insert.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/3_Insert.cs @@ -55,6 +55,10 @@ namespace OrmTest.Demo var t10 = db.Insertable(insertObjs.ToArray()).InsertColumns(it => new { it.Name }).ExecuteCommand(); var t11 = db.Insertable(insertObjs.ToArray()).ExecuteCommand(); + + + var t12 = db.Insertable(insertObj).IgnoreColumns(it => it == "Name" || it == "TestId").ExecuteReturnIdentityAsync(); + t12.Wait(); } } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/4_Delete.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/4_Delete.cs index 1276ea3ee..3258548d1 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/4_Delete.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/4_Delete.cs @@ -28,6 +28,9 @@ namespace OrmTest.Demo //by expression id>1 and id==1 var t5 = db.Deleteable().Where(it => it.Id > 1).Where(it => it.Id == 1).ExecuteCommand(); + + var t6 = db.Deleteable().AS("student").Where(it => it.Id > 1).Where(it => it.Id == 1).ExecuteCommandAsync(); + t6.Wait(); } } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/5_CodeFirst.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/5_CodeFirst.cs index 165dfd999..965991457 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/5_CodeFirst.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/5_CodeFirst.cs @@ -22,8 +22,10 @@ namespace OrmTest.Demo public DateTime? DateTime { get; set; } [SugarColumn(IsNullable = true,OldColumnName = "Dob")] public double? Dob2 { get; set; } - [SugarColumn(Length =110)] + [SugarColumn(Length =11000)] public string A1 { get; set; } + [SugarColumn(Length = 18,DecimalDigits=2)] + public decimal Dec { get; set; } } public class CodeTable2 { public int Id { get; set; } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/8_JoinSql.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/8_JoinSql.cs index 78adb85b8..e0f054608 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/8_JoinSql.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/8_JoinSql.cs @@ -1,5 +1,6 @@ using OrmTest.Demo; using OrmTest.Models; +using SqlSugar; using System; using System.Collections.Generic; using System.Linq; @@ -16,8 +17,47 @@ namespace OrmTest.Demo { Where(); OrderBy(); + SelectMerge(); + ConditionalModel(); + JoinExp(); } + private static void JoinExp() + { + var db = GetInstance(); + + var exp= Expressionable.Create() + .OrIF(1==1,it => it.Id == 11) + .And(it=>it.Id==1) + .AndIF(2==2,it => it.Id == 1) + .Or(it =>it.Name == "a1").ToExpression(); + var list=db.Queryable().Where(exp).ToList(); + } + + private static void ConditionalModel() + { + var db = GetInstance(); + List conModels = new List(); + conModels.Add(new ConditionalModel() { FieldName = "id", ConditionalType = ConditionalType.Equal, FieldValue = "1" }); + conModels.Add(new ConditionalModel() { FieldName = "id", ConditionalType = ConditionalType.Like, FieldValue = "1" }); + conModels.Add(new ConditionalModel() { FieldName = "id", ConditionalType = ConditionalType.IsNullOrEmpty }); + conModels.Add(new ConditionalModel() { FieldName = "id", ConditionalType = ConditionalType.In,FieldValue="1,2,3" }); + conModels.Add(new ConditionalModel() { FieldName = "id", ConditionalType = ConditionalType.NotIn, FieldValue = "1,2,3" }); + conModels.Add(new ConditionalModel() { FieldName = "id", ConditionalType = ConditionalType.NoEqual, FieldValue = "1,2,3" }); + var student = db.Queryable().Where(conModels).ToList(); + } + + private static void SelectMerge() + { + var db = GetInstance(); + //page join + var pageJoin = db.Queryable((st, sc) => new object[] { + JoinType.Left,st.SchoolId==sc.Id + }) + .Select((st, sc) => new { id = st.Id, name = sc.Name }) + .MergeTable().Where(XXX => XXX.id == 1).OrderBy("name asc").ToList();// Prefix, is, not, necessary, and take the columns in select + + } private static void Where() { var db = GetInstance(); @@ -32,14 +72,14 @@ namespace OrmTest.Demo var db = GetInstance(); //propertyName is valid string propertyName = "Id"; - string dbColumnName = db.EntityProvider.GetDbColumnName(propertyName); + string dbColumnName = db.EntityMaintenance.GetDbColumnName(propertyName); var list = db.Queryable().OrderBy(dbColumnName).ToList(); //propertyName is invalid try { propertyName = "Id'"; - dbColumnName = db.EntityProvider.GetDbColumnName(propertyName); + dbColumnName = db.EntityMaintenance.GetDbColumnName(propertyName); var list2 = db.Queryable().OrderBy(dbColumnName).ToList(); } catch (Exception ex) diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/9_Aop.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/9_Aop.cs new file mode 100644 index 000000000..7a1dbc3db --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/9_Aop.cs @@ -0,0 +1,46 @@ +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OrmTest.Demo +{ + public class Aop + { + + public static void Init() + { + SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() { ConnectionString = Config.ConnectionString, DbType = DbType.SqlServer, IsAutoCloseConnection = true }); + db.Aop.OnLogExecuted = (sql, pars) => + { + + }; + db.Aop.OnLogExecuting = (sql, pars) => + { + + }; + db.Aop.OnError = (exp) => + { + + }; + db.Aop.OnExecutingChangeSql = (sql, pars) => + { + return new KeyValuePair(sql,pars); + }; + + db.Queryable().ToList(); + + try + { + db.Queryable().AS(" ' ").ToList(); + } + catch (Exception) + { + + + } + } + +} +} \ No newline at end of file diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/D_QueryableView.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/D_QueryableView.cs new file mode 100644 index 000000000..4facf86ca --- /dev/null +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/D_QueryableView.cs @@ -0,0 +1,33 @@ +using OrmTest.Models; +using SqlSugar; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OrmTest.Demo +{ + public class D_QueryableViewn : DemoBase + { + public static void Init() + { + var db = GetInstance(); + var q1 = db.Queryable((st,sc)=>new object[] { + JoinType.Left,st.SchoolId==sc.Id + }).Select((st, sc) => new ViewModelStudent4() { Id=st.Id, Name=st.Name,SchoolName=sc.Name }); + + var q2 = db.Queryable(); + + + var innerJoinList = db.Queryable(q1, q2, (j1, j2) => j1.Id == j2.Id).Select((j1, j2) => j1).ToList();//inner join + + var leftJoinList = db.Queryable(q1, q2,JoinType.Left, (j1, j2) => j1.Id == j2.Id).Select((j1, j2) => j1).ToList();//left join + } + } + + public class ViewModelStudent4 { + public int Id { get; set; } + public string SchoolName { get; set; } + public string Name { get; set; } + } +} diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/DemoBase.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/DemoBase.cs index db605776a..46e139686 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/DemoBase.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Demos/DemoBase.cs @@ -14,7 +14,7 @@ namespace OrmTest.Demo db.Ado.IsEnableLogEvent = true; db.Ado.LogEventStarting = (sql, pars) => { - Console.WriteLine(sql + "\r\n" + db.Utilities.SerializeObject(pars.ToDictionary(s => s.ParameterName, s => s.Value))); + Console.WriteLine(sql + "\r\n" + db.Utilities.SerializeObject(pars.ToDictionary(it => it.ParameterName, it => it.Value))); Console.WriteLine(); }; return db; diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Program.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Program.cs index bf77f7c1e..5061a4745 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Program.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/Program.cs @@ -1,9 +1,17 @@ -using OrmTest; -using OrmTest.PerformanceTesting; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using System.Linq.Expressions; +using SqlSugar; +using OrmTest.Models; +using System.Data.SqlClient; using OrmTest.UnitTest; -using System; +using OrmTest.PerformanceTesting; -namespace SqlSeverTest +namespace OrmTest { class Program { @@ -37,9 +45,11 @@ namespace SqlSeverTest OrmTest.Demo.Filter.Init(); OrmTest.Demo.ComplexModel.Init(); OrmTest.Demo.CodeFirst.Init(); + OrmTest.Demo.Aop.Init(); OrmTest.Demo.MasterSlave.Init(); OrmTest.Demo.SharedConnection.Init(); OrmTest.Demo.ExtSqlFun.Init(); + OrmTest.Demo.D_QueryableViewn.Init(); } } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Delete.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Delete.cs index 0243b5596..28c408944 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Delete.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Delete.cs @@ -56,6 +56,20 @@ namespace OrmTest base.Check(@"DELETE FROM [STudent] WHERE id=@id", new List() { new SugarParameter("@id",1) }, t6.Key, t6.Value, "Delte t6 error"); + + var t7 = base.GetInstanceByAttribute().Deleteable().Where(new List() { + new DeleteTestTable() { Id=1, Id2="x" }, + new DeleteTestTable() { Id=2, Id2="x1" } + }).ToSql(); + base.Check("DELETE FROM [DeleteTestTable] WHERE (([Id]=N'1'AND [Id2]=N'x')OR ([Id]=N'2'AND [Id2]=N'x1')) ",null, t7.Key, null, + "Delte t7 error"); } } + + public class DeleteTestTable { + [SugarColumn(IsPrimaryKey =true)] + public int Id { get; set; } + [SugarColumn(IsPrimaryKey = true)] + public string Id2 { get; set; } + } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/EnumTest.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/EnumTest.cs index 8da966c05..768a10b5a 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/EnumTest.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/EnumTest.cs @@ -20,7 +20,7 @@ namespace OrmTest.UnitTest var db = GetInstance(); var shoolValue = SchoolEnum.HarvardUniversity; var enums = new SchoolEnum[] { shoolValue, SchoolEnum.UniversityOfOxford }; - var list = db.Queryable().AS("student").Where(it => it.SchoolId == shoolValue).ToList(); + var list = db.Queryable().AS("student").Where(it => it.SchoolId == shoolValue).Select(it=>it.SchoolId).ToList(); var x = new StudentEnum() { diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/ExpressionTest/Method.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/ExpressionTest/Method.cs index 813c44807..f670ec85e 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/ExpressionTest/Method.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/ExpressionTest/Method.cs @@ -74,10 +74,25 @@ namespace OrmTest.UnitTest Replace(); Length(); Time(); + + Test1(); } base.End("Method Test"); } + private void Test1() + { + var ids = new int[] { 1, 2, 3 }; + Expression> exp = it => ids.Contains(it.Id)&&!SqlFunc.IsNullOrEmpty(it.Name); + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "(([Id] IN ('1','2','3')) AND NOT( [Name]='' OR [Name] IS NULL ))", new List() { + + }, "Test1 error"); + } + private void ExtendToString() { Expression> exp = it => it.Id.ToString() == "a"; diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/ExpressionTest/Select.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/ExpressionTest/Select.cs index f99a76133..9a5ff983f 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/ExpressionTest/Select.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/ExpressionTest/Select.cs @@ -26,6 +26,9 @@ namespace OrmTest.UnitTest single3(); single4(); single5(); + single6(); + single7(); + single8(); Multiple(); Multiple2(); singleDynamic(); @@ -34,6 +37,44 @@ namespace OrmTest.UnitTest base.End("Select Test"); } + private void single7() + { + Expression> exp =it => new DataTestInfo2() { Bool1=it.Bool1 , Bool2=it.Bool2 }; + ExpressionContext expContext = new ExpressionContext(); + expContext.IsSingle = false; + expContext.Resolve(exp, ResolveExpressType.SelectSingle); + var selectorValue = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check( + selectorValue, + pars, + @"[Bool1] AS [Bool1] , [Bool2] AS [Bool2] ", + new List() + { + + }, + "Select.single7 Error"); + } + + private void single8() + { + Expression> exp = it => new { Bool1 = it.Bool1, Bool2 = it.Bool2 }; + ExpressionContext expContext = new ExpressionContext(); + expContext.IsSingle = false; + expContext.Resolve(exp, ResolveExpressType.SelectSingle); + var selectorValue = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check( + selectorValue, + pars, + @"[Bool1] AS [Bool1] , [Bool2] AS [Bool2] ", + new List() + { + + }, + "Select.single8 Error"); + } + private void Multiple() { Expression> exp = (it, school) => new Student() { Name = "a", Id = it.Id, SchoolId = school.Id, TestId = it.Id + 1 }; @@ -161,7 +202,22 @@ namespace OrmTest.UnitTest @"( @constant0<>'' AND @constant0 IS NOT NULL )", new List() { new SugarParameter("@constant0",p) }, selectorValue, pars, - "Select.single4 Error"); + "Select.single5 Error"); + } + private void single6() + { + var p = (DateTime?)DateTime.Now; + Expression> exp = it => p.Value; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.IsSingle = false; + expContext.Resolve(exp, ResolveExpressType.FieldSingle); + var selectorValue = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check( + @" @Const0 ", new List() { + new SugarParameter("@Const0",p) + }, selectorValue, pars, + "Select.single6 Error"); } private void singleDynamic() diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/ExpressionTest/Where.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/ExpressionTest/Where.cs index f6476cb51..0942a94f4 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/ExpressionTest/Where.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/ExpressionTest/Where.cs @@ -21,7 +21,12 @@ namespace OrmTest.UnitTest base.Begin(); for (int i = 0; i < base.Count; i++) { - + whereSingle29("22"); + whereSingle28(); + whereSingle27(); + whereSingle26(); + whereSingle25(); + whereSingle24(); whereSingle23(); whereSingle22(); whereSingle21(); @@ -52,6 +57,45 @@ namespace OrmTest.UnitTest } base.End("Where Test"); } + public string Get28(string a) { + return a + "1"; + } + + private void whereSingle29(string p2) + { + Expression> exp = it => Get28("22") == p2; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereMultiple); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, " (@constant0 = @Const1 )", new List() { + new SugarParameter("@constant0","221"), + new SugarParameter("@Const1","22") + }, "whereSingle28"); + } + private void whereSingle28() + { + Expression> exp = it => Get28("22")=="22"; + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereMultiple); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, " (@constant0 = @Const1 )", new List() { + new SugarParameter("@constant0","221"), + new SugarParameter("@Const1","22") + }, "whereSingle28"); + } + private void whereSingle27() { + var schoolData = new School() { Id = 100, Name = "x" }; + Expression> exp = it => it.Name.Contains(schoolData.Name); + ExpressionContext expContext = new ExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereMultiple); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, " ([it].[Name] like '%'+@MethodConst0+'%') ", new List() { + new SugarParameter("@MethodConst0","x") + }, "whereSingle27"); + } private void WhereMultiple1() { Expression> exp = it => it.Id > 1; @@ -378,6 +422,46 @@ namespace OrmTest.UnitTest new SugarParameter("@Const0",val) }, "whereSingle23"); } + private void whereSingle24() + { + Expression> exp = it => it.Datetime1 > DateTime.Now.Date; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "( [Datetime1] > @Datetime10 )", new List() + { + new SugarParameter("@Datetime10",DateTime.Now.Date) + }, "whereSingle24"); + } + private void whereSingle26() + { + var p = DateTime.Now; + Expression> exp = it => it.Bool1&&it.Bool1; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "( ( [Bool1]=1 ) AND ( [Bool1]=1 ) )", new List() + { + + + }, "whereSingle26"); + } + private void whereSingle25() + { + var p = DateTime.Now; + Expression> exp = it => it.Datetime1.Date > p.Date; + SqlServerExpressionContext expContext = new SqlServerExpressionContext(); + expContext.Resolve(exp, ResolveExpressType.WhereSingle); + var value = expContext.Result.GetString(); + var pars = expContext.Parameters; + base.Check(value, pars, "( CAST( DateName(Year,[Datetime1]) +'-'+ DateName(Month,[Datetime1]) +'-'+ DateName(Day,[Datetime1]) AS DATETIME) > @Date0 )", new List() + { + new SugarParameter("@Date0",DateTime.Now.Date), + + }, "whereSingle25"); + } } public class WhereConst diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Insert.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Insert.cs index ecd4ccb8a..c8e2d4aa0 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Insert.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Insert.cs @@ -37,7 +37,7 @@ namespace OrmTest.UnitTest //Insert reutrn Command Count - var t2 = db.Insertable(insertObj).ExecuteCommand(); + var t2 = db.Insertable(insertObj).ExecuteReturnEntity(); db.IgnoreColumns = null; //Only insert Name diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Mapping .cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Mapping .cs index f1ef5314c..b5be0d75c 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Mapping .cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Mapping .cs @@ -60,7 +60,7 @@ namespace OrmTest.UnitTest db.Ado.IsEnableLogEvent = true; db.Ado.LogEventStarting = (sql, pars) => { - Console.WriteLine(sql + "\r\n" + db.RewritableMethods.SerializeObject(pars)); + Console.WriteLine(sql + "\r\n" + db.Utilities.SerializeObject(pars)); Console.WriteLine(); }; return db; diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Query/SelectQuery.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Query/SelectQuery.cs index 73f44cfbb..fc2769d33 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Query/SelectQuery.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Query/SelectQuery.cs @@ -91,7 +91,21 @@ namespace OrmTest.UnitTest var t4 = db.Queryable((st, sc, sc2) => new object[] { JoinType.Left,st.SchoolId==sc.Id, JoinType.Left,sc2.Id==sc.Id - }).GroupBy(st => st.Id).Select(st=>st.Id).Count(); + }).GroupBy(st => st.Id).Select(st => st.Id).Count(); + + DateTime? result = DateTime.Now; + var t5 = db.Queryable().Where(it => it.CreateTime > result.Value.Date).ToSql(); + base.Check("SELECT [ID],[SchoolId],[Name],[CreateTime] FROM [STudent] WHERE ( [CreateTime] > @Const0 )", + new List() { + new SugarParameter("@Const0",result.Value.Date) + }, t5.Key, t5.Value, "select t5 Error"); + db.Ado.IsEnableLogEvent = false; + + var t6 = db.Queryable().Where(it => SqlFunc.HasValue(it.Bool2) == false).ToSql(); + base.Check("SELECT [PK],[Bool1],[Bool2],[Text1] FROM [DataTestInfo2] WHERE (( CASE WHEN ( [Bool2]<>'' AND [Bool2] IS NOT NULL ) THEN 1 ELSE 0 END ) = @Const0 )", + new List() { + new SugarParameter("@Const0",false) + }, t6.Key, t6.Value, "select t6 Error"); #endregion diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Query/SingleQuery.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Query/SingleQuery.cs index 4bf37e5d4..c06102a0c 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Query/SingleQuery.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Query/SingleQuery.cs @@ -116,6 +116,22 @@ namespace OrmTest.UnitTest var t12 = db.Queryable().Where(it=>it.Id!=null).ToSql(); base.Check("SELECT [ID],[SchoolId],[Name],[CreateTime] FROM [STudent] WHERE ( [ID] IS NOT NULL )", null, t12.Key, t12.Value, "single t12 error"); + + var id = 1; + var t13 = db.Queryable().Where(it => SqlFunc.Subqueryable().Where(s => s.Id == it.Id&&s.Id==id).Max(s => s.Id) == 1).ToSql(); + base.Check("SELECT [ID],[SchoolId],[Name],[CreateTime] FROM [STudent] it WHERE ((SELECT MAX([Id]) FROM [School] WHERE (( [Id] = [it].[ID] ) AND ( [Id] = @Id0 ))) = @Const1 )", + new List() { + new SugarParameter("@Id0",1), + new SugarParameter("@Const1",1) + }, t13.Key, t13.Value, "single t13 error "); + + + var t14 = db.Queryable() + .Where(it => it.Name == "a" && SqlFunc.HasValue(it.Name)).ToSql(); + base.Check("SELECT [ID],[SchoolId],[Name],[CreateTime] FROM [STudent] WHERE (( [Name] = @Name0 ) AND ( [Name]<>'' AND [Name] IS NOT NULL ))", + new List() { + new SugarParameter("@Name0","a") + }, t14.Key, t14.Value, "single t14 error "); } } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/UnitTestBase.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/UnitTestBase.cs index 1aeea8b30..899eadaea 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/UnitTestBase.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/UnitTestBase.cs @@ -51,5 +51,11 @@ namespace OrmTest.UnitTest SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() { ConnectionString = Config.ConnectionString, DbType = DbType.SqlServer, IsAutoCloseConnection = true }); return db; } + + public SqlSugarClient GetInstanceByAttribute() + { + SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() { InitKeyType=InitKeyType.Attribute, ConnectionString = Config.ConnectionString, DbType = DbType.SqlServer, IsAutoCloseConnection = true }); + return db; + } } } \ No newline at end of file diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Update.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Update.cs index 62a1fa491..ba18882e8 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Update.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSeverTest/UnitTest/Update.cs @@ -151,14 +151,37 @@ namespace OrmTest.UnitTest [Name]=@Name WHERE [Id]=@Id", new List() { new SugarParameter("@Name","a"), new SugarParameter("@ID",1) - }, t13.Key, t13.Value, "Insert t13 error"); + }, t13.Key, t13.Value, "Update t13 error"); var t14 = db.Updateable(new Dictionary() { { "id", 0 }, { "name", "2" } }).ToSql(); base.Check(@"UPDATE [STudent] SET [Name]=@Name WHERE [Id]=@Id", new List() { new SugarParameter("@Name", "2"), new SugarParameter("@ID", 0) - }, t14.Key, t14.Value, "Insert t14 error"); + }, t14.Key, t14.Value, "Update t14 error"); + + + // var t15 = db.Updateable(new StudentTest() { Id = 1, Name = "1" }).AS("student").ToSql(); + // base.Check(@"UPDATE [student] SET + //[SchoolId]=@SchoolId,[Name]=@Name,[CreateTime]=@CreateTime WHERE [Id]=@Id", null, t15.Key, null, "Update t15 error"); + + + var t16= db.Updateable().UpdateColumns(it => new Student() + { + SchoolId = SqlFunc.Subqueryable().Where(s => s.Id == it.SchoolId).Select(s => s.Id), + Name = "newname" + }).Where(it => it.Id == 1).ToSql(); + + var t17 = db.Updateable().UpdateColumns(it => new Student() + { + SchoolId = SqlFunc.Subqueryable().Where(s => s.Id == it.SchoolId).Select(s => s.Id), + Name = "newname" + }).Where(it => it.Id == 1).ToSql(); + base.Check(@"UPDATE [STudent] SET + [SchoolId] = (SELECT TOP 1 [Id] FROM [School] WHERE ( [Id] =[STudent].[SchoolId] )) , [Name] = @Const0 WHERE ( [ID] = @Id1 )", new List() { + new SugarParameter("@Const0","newname"), + new SugarParameter("@Id1","1") + }, t17.Key, t17.Value, "Update t17 error"); } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/AdoProvider/AdoProvider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/AdoProvider/AdoProvider.cs index cfe661c45..b1978041b 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/AdoProvider/AdoProvider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/AdoProvider/AdoProvider.cs @@ -472,7 +472,7 @@ namespace SqlSugar if (parameters != null && parameters.Any()) builder.SqlQueryBuilder.Parameters.AddRange(parameters); var dataReader = this.GetDataReader(builder.SqlQueryBuilder.ToSqlString(), builder.SqlQueryBuilder.Parameters.ToArray()); - List result = this.DbBind.DataReaderToList(typeof(T), dataReader, builder.SqlQueryBuilder.Fields); + List result = this.DbBind.DataReaderToList(typeof(T), dataReader); builder.SqlQueryBuilder.Clear(); if (this.Context.Ado.DataReaderParameters != null) { diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbBindProvider/DbBindAccessory.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbBindProvider/DbBindAccessory.cs index d5a1a1462..06f8d3440 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbBindProvider/DbBindAccessory.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbBindProvider/DbBindAccessory.cs @@ -7,13 +7,14 @@ namespace SqlSugar { public partial class DbBindAccessory { - protected List GetEntityList(SqlSugarClient context, IDataReader dataReader, string fields) + protected List GetEntityList(SqlSugarClient context, IDataReader dataReader) { Type type = typeof(T); - string key = "DataReaderToList." + fields+ dataReader.FieldCount+ context.CurrentConnectionConfig.DbType + type.FullName; - IDataReaderEntityBuilder entytyList = context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(key, () => + var fieldNames = GetDataReaderNames(dataReader); + string cacheKey = GetCacheKey(type,fieldNames); + IDataReaderEntityBuilder entytyList = context.Utilities.GetReflectionInoCacheInstance().GetOrCreate(cacheKey, () => { - var cacheResult = new IDataReaderEntityBuilder(context, dataReader).CreateBuilder(type); + var cacheResult = new IDataReaderEntityBuilder(context, dataReader,fieldNames).CreateBuilder(type); return cacheResult; }); List result = new List(); @@ -32,6 +33,29 @@ namespace SqlSugar return result; } + private string GetCacheKey(Type type,List keys) + { + StringBuilder sb = new StringBuilder("DataReaderToList."); + sb.Append(type.FullName); + sb.Append("."); + foreach (var item in keys) + { + sb.Append(item); + } + return sb.ToString(); + } + + private List GetDataReaderNames(IDataReader dataReader) + { + List keys = new List(); + var count = dataReader.FieldCount; + for (int i = 0; i < count; i++) + { + keys.Add(dataReader.GetName(i)); + } + return keys; + } + protected List GetKeyValueList(Type type, IDataReader dataReader) { List reval = new List(); @@ -125,7 +149,7 @@ namespace SqlSugar } else if (type.IsEnum) { - reval.Add((T)Enum.Parse(type,value.ObjToString())); + reval.Add((T)Enum.Parse(type, value.ObjToString())); } else { diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbBindProvider/DbBindProvider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbBindProvider/DbBindProvider.cs index d49547c53..67e17c8b2 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbBindProvider/DbBindProvider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbBindProvider/DbBindProvider.cs @@ -175,7 +175,7 @@ namespace SqlSugar return propertyTypes.First().Value.ToString(); } } - public virtual List DataReaderToList(Type type, IDataReader dataReader, string fields) + public virtual List DataReaderToList(Type type, IDataReader dataReader) { using (dataReader) { @@ -193,7 +193,7 @@ namespace SqlSugar } else { - return GetEntityList(Context, dataReader, fields); + return GetEntityList(Context, dataReader); } } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbBindProvider/IDataReaderEntityBuilder.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbBindProvider/IDataReaderEntityBuilder.cs index 4c8ad3757..ec3e51be8 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbBindProvider/IDataReaderEntityBuilder.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/DbBindProvider/IDataReaderEntityBuilder.cs @@ -74,12 +74,12 @@ namespace SqlSugar } - public IDataReaderEntityBuilder(SqlSugarClient context, IDataRecord dataRecord) + public IDataReaderEntityBuilder(SqlSugarClient context, IDataRecord dataRecord,List fieldNames) { this.Context = context; this.DataRecord = dataRecord; this.DynamicBuilder = new IDataReaderEntityBuilder(); - this.ReaderKeys = new List(); + this.ReaderKeys = fieldNames; } #endregion @@ -91,10 +91,6 @@ namespace SqlSugar public IDataReaderEntityBuilder CreateBuilder(Type type) { - for (int i = 0; i < this.DataRecord.FieldCount; i++) - { - this.ReaderKeys.Add(this.DataRecord.GetName(i)); - } DynamicMethod method = new DynamicMethod("SqlSugarEntity", type, new Type[] { typeof(IDataRecord) }, type, true); ILGenerator generator = method.GetILGenerator(); @@ -121,14 +117,13 @@ namespace SqlSugar } } } - if (Context.IgnoreColumns != null && Context.IgnoreColumns.Any(it => it.PropertyName.Equals(propertyInfo.Name, StringComparison.CurrentCultureIgnoreCase) - && it.EntityName.Equals(type.Name, StringComparison.CurrentCultureIgnoreCase))) + if (IsIgnore(type, propertyInfo)&&!this.ReaderKeys.Any(it=>it==fileName)) { continue; } if (propertyInfo != null && propertyInfo.GetSetMethod() != null) { - if (propertyInfo.PropertyType.IsClass() && propertyInfo.PropertyType != UtilConstants.ByteArrayType&&propertyInfo.PropertyType!=UtilConstants.ObjType) + if (propertyInfo.PropertyType.IsClass() && propertyInfo.PropertyType != UtilConstants.ByteArrayType && propertyInfo.PropertyType != UtilConstants.ObjType) { BindClass(generator, result, propertyInfo); } @@ -146,9 +141,15 @@ namespace SqlSugar DynamicBuilder.handler = (Load)method.CreateDelegate(typeof(Load)); return DynamicBuilder; } + #endregion #region Private methods + private bool IsIgnore(Type type, PropertyInfo propertyInfo) + { + return Context.IgnoreColumns != null && Context.IgnoreColumns.Any(it => it.PropertyName.Equals(propertyInfo.Name, StringComparison.CurrentCultureIgnoreCase) + && it.EntityName.Equals(type.Name, StringComparison.CurrentCultureIgnoreCase)); + } private void BindClass(ILGenerator generator, LocalBuilder result, PropertyInfo propertyInfo) { @@ -253,9 +254,9 @@ namespace SqlSugar case CSharpDataType.@float: case CSharpDataType.@double: CheckType(bind.DoubleThrow, bindProperyTypeName, validPropertyName, propertyName); - if (bindProperyTypeName == "double") + if (bindProperyTypeName.IsIn( "double", "single")&&dbTypeName!="real") method = isNullableType ? getConvertDouble : getDouble; - if (bindProperyTypeName == "single") + else method = isNullableType ? getConvertFloat : getFloat; break; case CSharpDataType.Guid: diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs index bbd72d5a2..375348c71 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/QueryableProvider/QueryableProvider.cs @@ -1085,7 +1085,7 @@ namespace SqlSugar } else { - result = this.Bind.DataReaderToList(entityType, dataReader, QueryBuilder.SelectCacheKey); + result = this.Bind.DataReaderToList(entityType, dataReader); } SetContextModel(result, entityType); return result; diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/SqlBuilderProvider/SqlBuilderProvider.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/SqlBuilderProvider/SqlBuilderProvider.cs index d8526a8f1..8951d0b0d 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/SqlBuilderProvider/SqlBuilderProvider.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Abstract/SqlBuilderProvider/SqlBuilderProvider.cs @@ -110,6 +110,7 @@ namespace SqlSugar public abstract string SqlTranslationRight { get; } public virtual string SqlFalse { get { return "1=2 "; } } public virtual string SqlDateNow { get { return "GETDATE()"; } } + public virtual string SqlSelectAll { get { return "*"; } } #endregion } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MemberInitExpressionResolve.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MemberInitExpressionResolve.cs index 435ffb2e4..048cca63b 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MemberInitExpressionResolve.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MemberInitExpressionResolve.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; namespace SqlSugar { @@ -48,7 +49,7 @@ namespace SqlSugar } MemberAssignment memberAssignment = (MemberAssignment)binding; var type = memberAssignment.Member.ReflectedType; - var memberName =this.Context.GetDbColumnName(type.Name, memberAssignment.Member.Name); + var memberName = this.Context.GetDbColumnName(type.Name, memberAssignment.Member.Name); var item = memberAssignment.Expression; if ((item is MemberExpression) && ((MemberExpression)item).Expression == null) { @@ -56,21 +57,21 @@ namespace SqlSugar string parameterName = AppendParameter(paramterValue); this.Context.Result.Append(base.Context.GetEqString(memberName, parameterName)); } - else if (item is UnaryExpression || item.NodeType == ExpressionType.Constant || (item is MemberExpression) && ((MemberExpression)item).Expression.NodeType == ExpressionType.Constant) + else if (IsMethod(item)) + { + if (item is UnaryExpression) + item = (item as UnaryExpression).Operand; + MethodCall(parameter, memberName, item); + } + else if (IsConst(item)) { base.Expression = item; base.Start(); - string parameterName = this.Context.SqlParameterKeyWord + ExpressionConst.Const+ this.Context.ParameterIndex; + string parameterName = this.Context.SqlParameterKeyWord + ExpressionConst.Const + this.Context.ParameterIndex; parameter.Context.Result.Append(base.Context.GetEqString(memberName, parameterName)); this.Context.Parameters.Add(new SugarParameter(parameterName, parameter.CommonTempData)); this.Context.ParameterIndex++; } - else if (item is MethodCallExpression) - { - base.Expression = item; - base.Start(); - parameter.Context.Result.Append(base.Context.GetEqString(memberName, parameter.CommonTempData.ObjToString())); - } else if (item is MemberExpression) { if (base.Context.Result.IsLockCurrentParameter == false) @@ -87,12 +88,46 @@ namespace SqlSugar } else if (item is BinaryExpression) { - var result=GetNewExpressionValue(item); + var result = GetNewExpressionValue(item); this.Context.Result.Append(base.Context.GetEqString(memberName, result)); } } } + private static bool IsConst(Expression item) + { + return item is UnaryExpression || item.NodeType == ExpressionType.Constant || (item is MemberExpression) && ((MemberExpression)item).Expression.NodeType == ExpressionType.Constant; + } + + private static bool IsMethod(Expression item) + { + return item is MethodCallExpression || (item is UnaryExpression && (item as UnaryExpression).Operand is MethodCallExpression); + } + + private void MethodCall(ExpressionParameter parameter, string memberName, Expression item) + { + if (IsSubMethod(item as MethodCallExpression)) + { + UtilMethods.GetOldValue(parameter.CommonTempData, () => + { + parameter.CommonTempData = CommonTempDataType.Result; + base.Expression = item; + base.Start(); + var subSql = base.Context.GetEqString(memberName, parameter.CommonTempData.ObjToString()); + if (ResolveExpressType.Update == this.Context.ResolveType) { + subSql = Regex.Replace(subSql,@" \[\w+?\]\.",this.Context.GetTranslationTableName(parameter.CurrentExpression.Type.Name,true) +"."); + } + parameter.Context.Result.Append(subSql); + }); + } + else + { + base.Expression = item; + base.Start(); + parameter.Context.Result.Append(base.Context.GetEqString(memberName, parameter.CommonTempData.ObjToString())); + } + } + private void Select(MemberInitExpression expression, ExpressionParameter parameter, bool isSingle) { foreach (MemberBinding binding in expression.Bindings) @@ -107,5 +142,10 @@ namespace SqlSugar ResolveNewExpressions(parameter, item, memberName); } } + + private bool IsSubMethod(MethodCallExpression express) + { + return SubTools.SubItemsConst.Any(it =>express.Object != null && express.Object.Type.Name == "Subqueryable`1"); + } } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs index fd30e7c6c..1fe6b24b7 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/ExpressionsToSql/ResolveItems/MethodCallExpressionResolve.cs @@ -45,7 +45,7 @@ namespace SqlSugar //Check.Exception(!(parameter.BaseExpression is BinaryExpression), "Current expressions are not supported"); SubResolve subResolve = new SubResolve(express, this.Context, parameter.OppsiteExpression); var appendSql = subResolve.GetSql(); - if (this.Context.ResolveType.IsIn(ResolveExpressType.SelectMultiple, ResolveExpressType.SelectSingle)) + if (this.Context.ResolveType.IsIn(ResolveExpressType.SelectMultiple, ResolveExpressType.SelectSingle)||(parameter.BaseParameter!=null&¶meter.BaseParameter.CommonTempData!=null&¶meter.BaseParameter.CommonTempData.Equals(CommonTempDataType.Result))) { parameter.BaseParameter.CommonTempData = appendSql; } @@ -105,32 +105,61 @@ namespace SqlSugar private void SqlFuncMethod(ExpressionParameter parameter, MethodCallExpression express, bool? isLeft) { - CheckMethod(express); - var method = express.Method; - string name = method.Name; - var args = express.Arguments.Cast().ToList(); - MethodCallExpressionModel model = new MethodCallExpressionModel(); - model.Args = new List(); - switch (this.Context.ResolveType) + if (!CheckMethod(express)) { - case ResolveExpressType.WhereSingle: - case ResolveExpressType.WhereMultiple: - Check.Exception(name == "GetSelfAndAutoFill", "SqlFunc.GetSelfAndAutoFill can only be used in Select."); - Where(parameter, isLeft, name, args, model); - break; - case ResolveExpressType.SelectSingle: - case ResolveExpressType.SelectMultiple: - case ResolveExpressType.Update: - Select(parameter, isLeft, name, args, model); - break; - case ResolveExpressType.FieldSingle: - case ResolveExpressType.FieldMultiple: - Field(parameter, isLeft, name, args, model); - break; - default: - break; + CusMethod(parameter, express, isLeft); + } + else + { + var method = express.Method; + string name = method.Name; + var args = express.Arguments.Cast().ToList(); + MethodCallExpressionModel model = new MethodCallExpressionModel(); + model.Args = new List(); + switch (this.Context.ResolveType) + { + case ResolveExpressType.WhereSingle: + case ResolveExpressType.WhereMultiple: + Check.Exception(name == "GetSelfAndAutoFill", "SqlFunc.GetSelfAndAutoFill can only be used in Select."); + Where(parameter, isLeft, name, args, model); + break; + case ResolveExpressType.SelectSingle: + case ResolveExpressType.SelectMultiple: + case ResolveExpressType.Update: + Select(parameter, isLeft, name, args, model); + break; + case ResolveExpressType.FieldSingle: + case ResolveExpressType.FieldMultiple: + Field(parameter, isLeft, name, args, model); + break; + default: + break; + } } } + + private void CusMethod(ExpressionParameter parameter, MethodCallExpression express, bool? isLeft) + { + try + { + var constValue = ExpressionTool.DynamicInvoke(express); + parameter.BaseParameter.CommonTempData = constValue; + var parameterName = base.AppendParameter(constValue); + if (parameter.BaseParameter.CommonTempData != null && parameter.BaseParameter.CommonTempData.Equals(CommonTempDataType.Result)) + { + this.Context.Result.Append(parameterName); + } + else + { + base.AppendValue(parameter, isLeft, parameterName); + } + } + catch + { + Check.Exception(true, string.Format(ErrorMessage.MethodError, express.Method.Name)); + } + } + private void NativeExtensionMethod(ExpressionParameter parameter, MethodCallExpression express, bool? isLeft, string name, List appendArgs = null) { var method = express.Method; @@ -521,10 +550,14 @@ namespace SqlSugar { return SubTools.SubItemsConst.Any(it => it.Name == methodName) && express.Object != null && express.Object.Type.Name == "Subqueryable`1"; } - private void CheckMethod(MethodCallExpression expression) + private bool CheckMethod(MethodCallExpression expression) { - if (IsExtMethod(expression.Method.Name)) return; - Check.Exception(expression.Method.ReflectedType().FullName != ExpressionConst.SqlFuncFullName, string.Format(ErrorMessage.MethodError, expression.Method.Name)); + if (IsExtMethod(expression.Method.Name)) + return true; + if (expression.Method.ReflectedType().FullName != ExpressionConst.SqlFuncFullName) + return false; + else + return true; } } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/SqlSugarAccessory.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/SqlSugarAccessory.cs index 49e6803fe..1eb788dbe 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/SqlSugarAccessory.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Infrastructure/SqlSugarAccessory.cs @@ -140,33 +140,33 @@ namespace SqlSugar } private void InitMppingInfo(EntityInfo entityInfo) { - if (this.MappingTables == null) - this.MappingTables = new MappingTableList(); - if (this.MappingColumns == null) - this.MappingColumns = new MappingColumnList(); - if (this.IgnoreColumns == null) - this.IgnoreColumns = new IgnoreColumnList(); - if (!this.MappingTables.Any(it => it.EntityName == entityInfo.EntityName)) + if (this.Context.MappingTables == null) + this.Context.MappingTables = new MappingTableList(); + if (this.Context.MappingColumns == null) + this.Context.MappingColumns = new MappingColumnList(); + if (this.Context.IgnoreColumns == null) + this.Context.IgnoreColumns = new IgnoreColumnList(); + if (!this.Context.MappingTables.Any(it => it.EntityName == entityInfo.EntityName)) { if (entityInfo.DbTableName != entityInfo.EntityName && entityInfo.DbTableName.HasValue()) { - this.MappingTables.Add(entityInfo.EntityName, entityInfo.DbTableName); + this.Context.MappingTables.Add(entityInfo.EntityName, entityInfo.DbTableName); } } if (entityInfo.Columns.Any(it => it.EntityName == entityInfo.EntityName)) { - var mappingColumnInfos = this.MappingColumns.Where(it => it.EntityName == entityInfo.EntityName); + var mappingColumnInfos = this.Context.MappingColumns.Where(it => it.EntityName == entityInfo.EntityName); foreach (var item in entityInfo.Columns.Where(it => it.IsIgnore == false)) { if (!mappingColumnInfos.Any(it => it.PropertyName == item.PropertyName)) if (item.PropertyName != item.DbColumnName && item.DbColumnName.HasValue()) - this.MappingColumns.Add(item.PropertyName, item.DbColumnName, item.EntityName); + this.Context.MappingColumns.Add(item.PropertyName, item.DbColumnName, item.EntityName); } - var ignoreInfos = this.IgnoreColumns.Where(it => it.EntityName == entityInfo.EntityName); + var ignoreInfos = this.Context.IgnoreColumns.Where(it => it.EntityName == entityInfo.EntityName); foreach (var item in entityInfo.Columns.Where(it => it.IsIgnore)) { if (!ignoreInfos.Any(it => it.PropertyName == item.PropertyName)) - this.IgnoreColumns.Add(item.PropertyName, item.EntityName); + this.Context.IgnoreColumns.Add(item.PropertyName, item.EntityName); } } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IDbBind.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IDbBind.cs index 7fb780149..03811c309 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IDbBind.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/IDbBind.cs @@ -20,6 +20,6 @@ namespace SqlSugar string GetDbTypeName(string csharpTypeName); string GetCsharpTypeName(string dbTypeName); List> MappingTypes { get; } - List DataReaderToList(Type type, IDataReader reader, string fields); + List DataReaderToList(Type type, IDataReader reader); } } diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/ISqlBuilder.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/ISqlBuilder.cs index f39a6d777..cec2a55fc 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/ISqlBuilder.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/Interface/ISqlBuilder.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Generic; using System.Data; +using System.Dynamic; using System.Linq; +using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; namespace SqlSugar @@ -12,8 +14,7 @@ namespace SqlSugar CommandType CommandType { get; set; } String AppendWhereOrAnd(bool isWhere, string sqlString); string AppendHaving(string sqlString); - string SqlTranslationLeft { get; } - string SqlTranslationRight { get; } + SqlQueryBuilder SqlQueryBuilder { get; set; } QueryBuilder QueryBuilder { get; set; } InsertBuilder InsertBuilder { get; set; } @@ -23,6 +24,9 @@ namespace SqlSugar string SqlParameterKeyWord { get; } string SqlFalse { get; } string SqlDateNow { get; } + string SqlTranslationLeft { get; } + string SqlTranslationRight { get; } + string SqlSelectAll { get; } string GetTranslationTableName(string name); string GetTranslationColumnName(string entityName, string propertyName); diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugar.csproj b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugar.csproj index 0e93431fa..fc4be8d95 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugar.csproj +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugar.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 4.6.0.6 + 4.6.0.9 sun_kai_xuan https://github.com/sunkaixuan/SqlSugar diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarClient.cs b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarClient.cs index d5fc40bd7..fcb82cd50 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarClient.cs +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarClient.cs @@ -310,6 +310,51 @@ namespace SqlSugar queryable.Where(joinExpression); return queryable; } + public virtual ISugarQueryable Queryable( + ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, Expression> joinExpression) where T : class, new() where T2 : class, new() + { + return Queryable(joinQueryable1, joinQueryable2, JoinType.Inner, joinExpression); + } + public virtual ISugarQueryable Queryable( + ISugarQueryable joinQueryable1, ISugarQueryable joinQueryable2, JoinType joinType, Expression> joinExpression) where T : class, new() where T2 : class, new() + { + Check.Exception(joinQueryable1.QueryBuilder.Take != null || joinQueryable1.QueryBuilder.Skip != null || joinQueryable1.QueryBuilder.OrderByValue.HasValue(), "joinQueryable1 Cannot have 'Skip' 'ToPageList' 'Take' Or 'OrderBy'"); + Check.Exception(joinQueryable2.QueryBuilder.Take != null || joinQueryable2.QueryBuilder.Skip != null || joinQueryable2.QueryBuilder.OrderByValue.HasValue(), "joinQueryable2 Cannot have 'Skip' 'ToPageList' 'Take' Or 'OrderBy'"); + + var sqlBuilder = InstanceFactory.GetSqlbuilder(base.Context.CurrentConnectionConfig); + + sqlBuilder.Context = base.Context; + InitMppingInfo(); + var types = new Type[] { typeof(T2) }; + var queryable = InstanceFactory.GetQueryable(base.CurrentConnectionConfig); + queryable.Context = base.Context; + queryable.SqlBuilder = sqlBuilder; + queryable.QueryBuilder = InstanceFactory.GetQueryBuilder(base.CurrentConnectionConfig); + queryable.QueryBuilder.JoinQueryInfos = new List(); + queryable.QueryBuilder.Builder = sqlBuilder; + queryable.QueryBuilder.Context = base.Context; + queryable.QueryBuilder.EntityType = typeof(T); + queryable.QueryBuilder.LambdaExpressions = InstanceFactory.GetLambdaExpressions(base.CurrentConnectionConfig); + + //master + var shortName1 = joinExpression.Parameters[0].Name; + var sqlObj1 = joinQueryable1.ToSql(); + string sql1 = sqlObj1.Key; + UtilMethods.RepairReplicationParameters(ref sql1, sqlObj1.Value.ToArray(), 0); + queryable.QueryBuilder.EntityName = sqlBuilder.GetPackTable(sql1, shortName1); ; + queryable.QueryBuilder.Parameters.AddRange(sqlObj1.Value); + + //join table 1 + var shortName2 = joinExpression.Parameters[1].Name; + var sqlObj2 = joinQueryable2.ToSql(); + string sql2 = sqlObj2.Key; + UtilMethods.RepairReplicationParameters(ref sql2, sqlObj2.Value.ToArray(), 1); + queryable.QueryBuilder.Parameters.AddRange(sqlObj2.Value); + var exp = queryable.QueryBuilder.GetExpressionValue(joinExpression, ResolveExpressType.WhereMultiple); + queryable.QueryBuilder.JoinQueryInfos.Add(new JoinQueryInfo() { JoinIndex = 0, JoinType = joinType, JoinWhere = exp.GetResultString(), TableName = sqlBuilder.GetPackTable(sql2,shortName2)}); + + return queryable; + } #endregion public virtual ISugarQueryable UnionAll(params ISugarQueryable[] queryables) where T : class, new() @@ -333,7 +378,7 @@ namespace SqlSugar var allParameters = allItems.SelectMany(it => it.Value).ToArray(); var resulut = base.Context.Queryable().AS(UtilMethods.GetPackTable(allSql, "unionTable")); resulut.AddParameters(allParameters); - return resulut.Select("*"); + return resulut.Select(sqlBuilder.SqlSelectAll); } public virtual ISugarQueryable UnionAll(List> queryables) where T : class, new() { @@ -521,7 +566,7 @@ namespace SqlSugar public virtual EntityMaintenance EntityProvider { get { return base.Context.EntityMaintenance; } - set { base.Context.EntityMaintenance = value; } + set { base.Context.EntityMaintenance = value; } } public virtual EntityMaintenance EntityMaintenance { diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarForCore.nuspec b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarForCore.nuspec index 9e054cb07..706938cac 100644 --- a/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarForCore.nuspec +++ b/Src/Asp.NetCore2/SqlSeverTest/SqlSugar/SqlSugarForCore.nuspec @@ -2,7 +2,7 @@ sqlSugarCore - 4.6.0.6 + 4.6.0.9 sunkaixuan Landa http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/Src/Asp.NetCore2/SqlSeverTest/SqliteTest/DataBase/SqlSugar4xTest.sqlite b/Src/Asp.NetCore2/SqlSeverTest/SqliteTest/DataBase/SqlSugar4xTest.sqlite index a9088fff8c1042768214ff8c32a0362884c71724..88d6a78c34c2253559829e8a9467ef28d32e9bba 100644 GIT binary patch literal 241664 zcmeFa3v^`Fz2+yWB$cGrqcO%9V`Bk+fXzdv9_LiyS7VHAYz&RTzJAjUv@td`4GlJa z(|C4nO_I3_FDH}0`trlFY0bJkBJOWUU0p$>gzCW}15F;nJgholGWK zD>vD{tyB883~JB4b1%8>wYlyKpGw{O>aW)RegA#Vf1kVWy8WRij!l30(Z?S-`owg; z?_ghlf8U|$>At?P_w@Dk@vC5e9qj8H_@Mpwp#9bRr@!|f`~Tbi88=M4ZpeN@|J47@ zr;YFYYyaO7UI`Tl6$ljw6$ljw6$ljw6$ljw6$ljw6$ljw75EFTz=2awP4GwB?%w`$ z!_@yZ^(Rx^srJcB$>K6l{b2i|+&`U6)Sm^#om_Up0c*e}Qa^RY8y|KZrbGgcY<=Ga%qK0kK* z*!#wA7<=p3!Lk0)KN)R}{tu)7XtX~1AC3OIqknz$Tccka{le%cM&CbryBR?Ja$;gjJelT)!IBl?;gHoI6r*#@WsQK zq2CO(hJHEp^P!&({bcAzLq8ZgIduQf-9xtw<%g~wx_Brv_?yAj;4cS%KKRqYpA7zJ z@CSn@2k#%ed+?UQ{NUAt7Y}AKzsa;Rzs&qR^V7^vGC#`vAagQvf9CGYEt!1g>deKN z%)oC3S_8iv`1!z32Yxc}qk$g`oE*4+;O>E22J!<}4_rKu>HkfCtN)kz@jv`KPmWi{ zE6vy2EtkvtjvsyGST4$2eX*x=RiYfT!`-?`iz?dD{AW z`TL%>{$Bo`r>(!2zw2r1@8$1Em#n{+zwK%3@8xfK+WLF>o1V7*UVh5c*5AwD@U->! z^4C3$zb8G7zb8D6zmuNE-{aB={vPu*{!Vxre~)?^f5$zIzehZczlS}Izpr^3e_!=9 z{vPr){=Om|0~4@1vf^-$y)+zYlvFf46!Xe;@KR z{%-L!{yykw{N3zn{2h|c;qL>U#^3urjlcJK8h`KgH2&V>Y5d*fY5bKvjlYto@t1fS zf3b9gzoMt{SMW6c@}90z3e=|(SCBrHxB~R4#1))RC9c4HDsctnQ;91e zpGsW8_*CKw#HSKh5PnC-xB~F0#1(u`C9c4GDsctfQ)ykD1@5V|uFk^tR9aVOL3=8# ztFw?jmDbf+z@AF$>MUH}kwxq3ELcyab#)f1r_#DQ3)E9-U7dyLsl*jXPbID(dMa@R z&{K&kc%DjJf%8=23Yzc80Jpqkf#z?a6FZ`0^_N~6%E9jj{TmkP?;tF=B5?7!*mAHc3 zJ2HnWz@185!R=Jy3T&qmS5P~ZxB}X##1+g=C9XhrDscs|Q;92pol0E6>m3>43S6fW zSI|0@xB}Lx#1*VgC9XhqDscs=Q;91;ol0E6=~UthOs8^Yta27gU%Io3S_PwbRLLp` zy`vJV;PZ}(t%A-ws%RB#-cbdsAoGsOTLqVQRL&}>yrUwkVDgTdd1K`)MDEMyW}=zv zXCnK*>6w|E-2dKOIcw=WdP)APNALgItGsT1uch_qtNvd5nkDzEzcyMqYbic@Ngsc% z6&B&CuwT*gd;hO!U$;Ep|MhI;EPTJH@2RJ*s+*RN-BC(XS$~K9*Nv6c_t}5VR63ut|B5QD zZ`gmm%QlK$|8GAM{s|Qb6$ljw6$ljw6$ljw6$ljw6$ljw6$ljw6}S*95c>ZM@w*z{ zQ>Z|wK&U{dK&U{dK&U{dK&U{dK&U{dK&Zgp3ef-ePkp}6{xAF!DiA6VDiA6VDiA6V zDiA6VDiA6VDiA6VDiA90XRpAit8RZ?U;kyJ{kPn5@ZhID)!)zAdc!B5c>JN`4-UAS z`De=4N6GX|?xvaerefiSTrSR+iiLe%if3}A{(*ta1EpMCI+`52{%G!j==wrFSH8Yn zF3((FzVCt3Oq46<3Q_T2=5w+mgF}OZ;rjod{Tmy8N2oxkK&U{dK&U{dK&U{dK&U{d zK&U{dK&Zg)TLpHm|9`G;igN+NKcNDl0-*w-0-*w-0-*w-0-*w-0-*w-0-*w-0)NH| zoVxn|1*{`e0r!rs6ePds6ePds6ePds6ePds6ePds6ePdsKCE+1;YLR z|H>r{e?X`}s6ePds6ePds6ePds6ePds6ePds6eQ|U-=5`-2eZDzNs(#mA4uUh6;oV zgbIWTgbIWTgbIWTgbIWTgbIWTgbMuCtH7zZojP^p1Fv@z05^X?2LSf%9RY}<>vN^) zD1TEF-;^)iz~O&|vO59rm9ONYznt^`4)#6Wm;KX`!y~^Kt&Ek&mnPmZ@h6jCnJQ!} z!+&q^#{PfU_s{Jo{3ZQ!^3+qqm%i_P{oj7#=zR|#yXDabj@`q5oUaebzO%JurRS9rs*!$I(ZQP2Y3tXYRT7)JIQ!J$vbU z-qZigJAdoz?(=2$e0XA?ue#@xt{I!2PQR}GuiY**DrDJ z#r~$F_Z&O<#BImF{HXumV|!d*<-c^*^feP>SKW5}iRh~7>4%O#aqPikk53=|xwrSG;ojqsJe_-^2Fb{26FI z5j`<>trv@6M!SkXuIx|CL7{eR${p5AXQ{uG;zFRSrB4T(wJ`-YT^} zepr>j=~cUnY&63vZ2yi-PfuTas_=pArSE)akL>>Xl-nal_xjoMnzMEI+!wSkmP4Gv4yNv+kxJKDf_U-SbJWA!$Cje+A30d@CtK z()V)FKJR7kXT53#Kl8gP80TYsOH>^D;Y;@Us(U`^HLIZg+wg_o^`{q<(V0QBF_y66#6Mw!9f#GMa8g{?)MZnUod_A+I@<+ z_p@H@ui-OS?E9_LAFnUF=c`_`&sW|1Np$!-8xHor{t_GiC!cwH_R=e_>_1g>0G4O{ z*Wez*SLucQbC*juzm>22@H2hw$!Fetp6}d@-MT3zx!+oXBfFQg^YM4?u_Q-3-?`pr zz4ANvO!1kkvzNa0t^I$ky!Y+y{t=lyf3n`}{_l0)xTHMPi)*<(d5zcE#qr`Cue%7! zYitAPwVby}uoDu~y^X70v9poByqmasfy?`|KV&z7u1XvC-7k2vzFM^BtJy&O(P!Rt zp1<FKddy2ZxC%tB?)yZexxc^^0`+SrrpG$H%xpePk_v3Hh=e_LxtXKZk zvlV>9{uSK)loV{9enkb-kH2-F_mWmH{j685;Mn;p_=+#PQ=Ig}SM2ju_k7Z8 zSizC=RWKjL`C=h@MFrE3U%t+&puKWe@S33A z+PIIuVW0Q1_p@HDf~UTB{tEuqm+ckDefahJeAPXl^x9SM)OUVo1@pyM`6;&VC11RF zpZDTdFkgJt3V!Q%R?z>lUUBlpseQico=9*p9G2Srz#-H*R}pZBu& zvtF%&&s?>C1=Bx1U)DE{;_QC-UHg31J)iWNRWQu||M~VY!tV+d2o(qw2o(qw2o(qw z2o(qw2o(qw2o(qw_LD8zFWa-s6ePds6ePds6ePds6ePds6ePds6ePdsKB4E z0-^u^^VKc;D(T z-<0qsLIpwvLIpwvLIpwvLIpwvLIpwvLIpwvLIuuSfzbb-w>;s+P=Qc^P=Qc^P=Qc^ zP=Qc^P=Qc^P=Qc^P=O1g0-^uEAij;^O@s=B3WN%T3WN%T3WN%T3WN%T3WN%T3WN%r zw*sO6KW}-$i=hIc0-*w-0-*w-0-*w-0-*w-0-*w-0-*vILt&B@ofxmB2*w$AXFe!AXFe!AXFe! zAXFe!AXFe!AXMPI6$t(RdCL=C3>63!2o(qw2o(qw2o(qw2o(qw2o(qw2o<;>DiHer z3*y@t-bAQCs6ePds6ePds6ePds6ePds6ePds6eQ|c`Fe5|MQk7ycjAFDiA6VDiA6V zDiA6VDiA6VDiA6VDiA7gK~y00{};r!F}#UTflz@^flz@^flz@^flz@^flz@^flz@^ zf%8@%^#A8APk1p@AXFe!AXFe!AXFe!AXFe!AXFe!AXFe!;DV??=>IQ>Z)129p#q@- zp#q@-p#q@-p#q@-p#q@-p#q@-p#tZvK51wsWv1wsWv1wsWv1wsWv1wsWv1wsYRTY=F3pSL{W z#ZZAzflz@^flz@^flz@^flz@^flz@^flz@9q5`4+zaYMi;Z1}JgbIWTgbIWTgbIWT zgbIWTgbIWTgbIWToVNm@|37be!i%8-p#q@-p#q@-p#q@-p#q@-p#q@-p#q@-7eoa@ z|9?Sz8^fCj6$ljw6$ljw6$ljw6$ljw6$ljw6$ljw6*zANLjQl>@`M*d1wsWv1wsWv z1wsWv1wsWv1wsWv1wsWv1ulpRg#Q16_%?<&5h@TW5GoKV5GoKV5GoKV5GoKV5GoKV z5Gruq3WWauyyXcmh6;oVgbIWTgbIWTgbIWTgbIWTgbIWTgbG{`6$t(R1@UbRZz5D6 zR3KC!R3KC!R3KC!R3KC!R3KC!R3KE~ycMATZ}q>_H+636?9@wBFHS8@y)gCc)YDTZ zrjAS!HK@{bK_^nUmAaLd};iJ@n^@M9zQXD zWc={>q4AmV>G6Z(eFx4RID6ow11}y}I`G1QXAeAm;KYF=2M!-NbYSMd^nrs1`o_+U zogI5=?8ULAu@}ak9eaB0#MqIs!()fWX2zz+4vzJWo*O+o`qJo&qf4VNj6OU1^yrDv zBcq2$4~@=@PLCcO?Hf5aa(3jUkrzjnMqU_scI4@i6C+1P4v!ofnHiZLIXKdnJ(oS3 zeJT55b}9Qp_Sx*y*%R3#*~8gG*_rHg_F%Se_}uW>;g^PA99|lJVffkMr-x4r9~nM8 zd}w%PczXEYaNp3mp|e9T4ZS$DH1xvIvqMi0oftYYba?2{(9F>E(7~a;!E=LW2VWX| zad2tyg~4YBpB_9hcx3SK;Gw~p!Rf(+gMFEEnX{RfGB0M9GB0GF%{-kskvWn%oH>-4 z$xLSsX8H!s4V)c#Y2d|yrGXa)o*j64;Kaa@fx`ob24)7P2M!MO^`GlMYrlB% zH2%KmY5aXbdIo==_cZ=K=V||s8h>|q8h@YgH2!Y)H2yyBY5aZ6)A+m1)A;+SbP0bS@ihKE>}mYn z>S_Fa$kX_{#nbrvpr`S7v#0TQ$kX`yfT!{Ie(3~%@AEYN-s@@ny~oq|yUEk|D|;G$ zB~Rlo@ihKoPvfuXY5WzWWBlbkjlZ0y@fUd-e>0xO-;JKe-wmF|-}Rox-*ukG-@84H zzjsL&@prAK@pp}<@%K(oe=dhV@jsWtpZK54;ZOX}1;B1;>4F1Ib+zkH2 z|J)4z#Q)q3{>1;>4F1Ib+zkH2{|J7pi~ms>f8u{s#-I2fmGLM3M`iqp|4|u#;(t`e zpZFh@@hARAW&DZ%Q5k>Ye*{0)#s8>;Kk+{*;ZOXJO8681qZ0na|EPpN@joizPyCNc z_!Ix568^;hsDwZ9KY}0Y;(wIjPyCM({E7cjf1;NfIsm+D&SB2j|%t`|Dyu_#Q&&(Kk+|;AM4_O zl*ga=ALa2U{zrNIiT_a^f8u|X$DjBgRbJD6(E|h!;iH%MJ0O$a=XUUKCj`H^hq~>*a=cQDnW`5HE_XmmA_m zk@a#zyeP6>Zip8}*2@j?qR4u=Azl<&FE_-CBJ1Ubcu{1%+z>B{td|?&MUnM#L%b-m zUT%mNMb^s=@uJ9jxglN@SuZ!liz4gghImnAz1$ElimaC#;zg15aznf*vR-b87e&^~ z4e_GLdbuH96j?7f#ET;9<%W1sWWC%FFN&;}8{$Qg^>RbJD6(E|h!;iH%MJ0O$a=XU zUKCj`H^hq~>*a=cQDnW`5HE_XmmA_mk@a#zyeP6>Zip8}*2@j?qR4u=Azl<&FE_-C zBJ1Ubcu{1%+z>B{td|?&MUnM#L%b-mUT%mNMb^s=@uJ9jxglN@SuZ!li((Fc;zcos zKk=eS-rf)|isbDL@uEoH-ViT}2ZQ<7!Xi z?phLXi#?6M*LfO$7kL_g2c^l|8&jUf-=wGUH{oggje8n@2Rx0xF;C-f z)YJGI@ihLjp2pv>wByH+r|~!FY5Zk8jlTg;(#4_dIR=b-(Lr z>#zGAY539owx_MX?zcQ`{dK?TY3r~1l&7t~?l(Mb{dK?YY5YCuY5YCmY5bk^H2xl! zh9BL>JdM8-p2pv!p2pvCPvh?qPvcMgFTjtk_+Nk@UGcvFKf2<70e*DF|AO1^7yk?J zqbvRw;73>dFTjtk_+Nk@UGcvFKf2<70e*DF{{sBzivI=p(G~v-@S`jK7vM)%{4clu@Uw|K7@xK5+y5fHUessnE0{rNT z{{{Hb75@wHqbvRw;73>dFTjtk_+Nk@UGcvFKf2<70e*DF{{s6pUGcvFKf2<7f&H4U z_+MbZrYrsz*stk|{{{AIy5fI<{hF@$UtqtcEB+VQujz{a1@>#Y;(vktny&bthaX+> zKhJ(mSNzYjU(*%;^X%7j#s56}HC^#P&wfo;{Liyr(-r^o?ALU~|2+FOUGYE9eoa^W z&%=+d_@8ILrYrvE*{|t}|9SRny5fJH{hF@$pJ%_OEB@!%ujz{adG>3%;(wn0qbvUB z=|8&Se;$5x#s570M_2sM(|>fu|2+LiSNzY@e{{wFJpD&k{Lj;WbjANX{YO{)&(nW& z#s570M_2sMJAR1&dHRp8_@Af$=!*Y&`j4*opQr!mivM}~kFNNir~l}R|9Se4uK1s) z|LBVUdHRp8_@8(D5dZV^A6@Z3Pyf*s|MT=8UGYC(EYkn~gTaG+;rjpopV$A-dy7VR zF;w6+tH5~WoYt2zd^@N0r3~NBX?-cfw{u!w%JA)+)|WDTJE#7l4ByVFzbM1EbLub3 z@a>%Xi!yvWr~aZ0-_EJOD8sjN>MzRh?VS3HGJHFy{-O-u&Z)mB!?$hq7iIXit^T46 z-?r6Xl;PX9`inAr+g5*3hHu;IFUs(3Tm3~DzHO_&D8sjH^%rIMwypl64BxiZUzFk7 zw)%@QeA`xkQHF2Z>MzRhZCm|C8NO|+zbM1EZS@yr__lp~x1T7(x9vwfjlYLIjlZvX z8h>B)H2&0Il;PX9`inAr+g5*3hHu;IFUs(3Tm3~DzHO_&D8sjH^%rIMwypl6%>LT8 z`inCAYuoBC%JfIu>MzRlN89Qz%JfIu>MzRlN89Qz%JfIu>MzRlN89Qz%JfIu>MzRl zN89Qz%JfIu>MzRlN89Qz%JfIu>MzRlN89Qz%JfIu>MzRlN89Qz%JfIu>MzRlN89Qz z%JfIu>MzRlN85Mk`$vDY{RvOw?{-h)@8h1v-^Vb?_`A;2 z_U4kFm>Mu(0V_W@234Uy=zbL_vZS@x=__3}2q69y-)nAn0$F};568zX! ze^G)T+v+b$@MBy3MG1avtG_70k8SlACHS$e{-Ojww$)#h96!`wlpH_QUz8j_)L)bw zKh$5896!`wlpH_QUz8j_)L)bwKh$5896!`wlpH_QUz8j_)L)bwKh$5896!`wlpH_A z|B~Z}_+N7T5dTY#AL4(>@k9JCIev)$CHkXn@xMfWv@QOZ=#RF={}TPtw)kIi{1E?3 zjvwNG$?-${FFAgQ|0Tx{@xKH=w#5Gu{MZuzOYmb${4c?eE%CnuKeojG68zW_|4Z;= zOZ+dvk1g@P1V6UK{}TMz68}r^V@v!m!H+HRzXU(F#Qzff*b@Is@MBB-FTsy3@xKH= zw#5Gu{MZuzOYmb${4c?eE%CnuKeojG68zW_|4Z;=OZ+dfzqTd*m)Kw168}r=uWgC{ zCHB|0#Qzff*b@Is@MBB-FTsy3@xKH=w#5Gu{MZuzOYmb${4c?eE%CnuKeojG68zW_ z|4Z;=OZ+dvk1g@P1V6UK{}TMz68}r^V@v!m!H+HRzXU(F#Qzff*b@Is@MBB-FTsy3 z@xKH=w#5Gu{MZuzOEcwg{r^I{{=cfc;&{2LyyAGds=VTOxvIS4c)6;);&{2LyyAGd zs=VTOxvIS4c)6;);&{2LyyAGds=VTOxvIS4c)6;);&{2LyyAGds=VTOxvIS4c)6;) z;&{2LyyAGds=VTOx$5N=c)9B36?nPog5%9x$5N=c)9B36?nPog5%9 zx$5N=c)9B36?nPog5%9x$5N=c)9B36?nPog5%9x$5N=c)9B36?nPo zg5%9x$5N=c)9B36?nPog5%9x$5N=c)9B36?nPog5%9x$5N= zc)9B36?nPog5%9x$5N=c)9B36?nPog5%9x$5N=c)9B36?nPog5%9x$5N=c)9B36?nPo@NFg??+r%PaI- zD_&lq-&*nV3jNlKmsjYwR=m8z^{5puuW&tT#mg&Pk6KY)N$9s$lvfh^trg{!gnny9 zc_pFWT2Wp}=(kpsR}%WI73GzLerrW}C86J1QC>;tw^o!_68fzb<&}hfYejh_q2F3j zUP@=`-G?Qce|(Y_i<0-?_<*RTPwGD8h;=4 zH2yx~Y5aZI)A+m9)A;+4r}1}-r}6hePvh@qPvh^9H2hfkfT!{Ieoy01{7>M=iuj+v zj}`Ghfgda4e*!;N#Qy|-tcd>!{8$nH6Zo+r{wMHbMf^|T$BOu$z>gL2KY<@B;(r1^ zR>c1VeyoW93H(^OQSTRitcd>!{8$nH6Zo+r{wMHbMf^|T$BOu$z>gL2KY<@B;(r1^ zR>c1VeyoW93H(?Q{}cGJBK{}vV@3Q=;Kz#ipTLh5@jrndE8>3wKUT#51b(cD{|Wq9 z5&skTu_FE_jvwNG;`kx{CypQDf8zKd{wIzf;(y}!A^shxng3 zeu)2xjdKu38lCJ%I!=VJ0e zM|mzL4|J60V)8&oc`haobd={}@<2yjdKu38lCJ%I!=VJ0eM|mzL4|J60 zV)8&oc`haobd={}@<2yjdKu38lCJ%I!=VJ0eM|mzL4|J60V)8&oc`hao zbd={}@<2yjdKu38lCJ%I!=VJ0eM|mzL4|J60V)8&oc`haobd={}@<2y< zE+!9jl;>jdKu38lCJ%I!=VJ0eM|mzL4|J60V)8&oc`haobd={}@<2yjd zKu38lCJ%I!=VJ0eM|mzL4|J60V)8&oc`haobd={}@<2yjdKu38lCJ%I! z=VJ0eM|mzL4|J60V)8&oc`haobd={}@<2yjdKu38lCJ%I!=VJ0eM|mzL z4|J60VwVS$=VF%!l;>iX2bAYxmj{&RVwVS$=VF%!l;?^r4=B$ST^>-LE4ne>Y#%7XRIRRa^Xb^Hpu}-_2LG#eX+n)fWHVd{tZgck@+k@!!o?wZ(ro zU)2`>-F#JB{CD$JZSmjDSGC1|H(%8j|J{65Tl{zPRc-O#%~!R>e>Y#%7XRIRRa^Xb z^Hpu}-_2LG#eX+n)fWHVd{tZgck@+k@!!o?wZ(roU)2`>-F#JB{4c_fw)kI!A8ql! z2tV55e-VDP#s4DwXp8?v_|X>si}0f@{ukj#Tl_D=kGA+s3-F^Y{ukg!Tl_D;kGA+l{0Uw|KN@xK5++Two!eze8^0{m!;{{{Hb7XJ(MlWp<8KtI_Q{|oe!ZSlWA zKiL-l3-pt1@xMSn*%to`^pkDzzd%3P7XJ(MlWp<8KtI_Q{|oe!ZSlWAKiL-l3-pt1 z@xQ?JthV@Hp#Nx#{{{Mww)kJ5|7cI`_VWe$kGA+^`j58wU!ebJi~j}skGA+nfo3Cn%|8BmjE&jXt zs%dCtwtwUp=Fyj)9p&dtlUl;_;MTuXV*&C9iv=iIzpOL@-C%e9o}+`L>% zdCtwtwUp=Fyj)9p&dtlUl;_;MTuXV*&C9iv=iIzpOL@-C%e9o}+`L>%dCtwtwUp=F zyj)9p&dtlUl;_;MTuXV*&C9iv=iIzpOL@-C%e9o}+`L>%dCtwtwUp=Fyj)9p&dtlU zl;_;MTuXV*&C9iv=iIzp>rQ?D$pbCrIX5rYQl4}3axLXKH!s&xo^$hZE#)~kFV|9@ zbMta7F%5!dBuBANZ=H*(-b8cR)r99{6F%5!dB zuBANZ=H*(-b9P?N{(V-SbLXqJl;`s7N4Avb^6W>pl;`s7N4Avb^6W>pl;`s7N4Avb z^6W>pl;`s7N4Avb^6W>pl;`s7N4Avb^6W>pl;`s7N4Avb^6W>pl;`s7N4Avb^6W>p zl;`s7N4Avb^6W>pl;`s7N4Avb^6W>pl;`s7N4Avb^6W>pl;`s7N4Avb@{S+Mb9we7 zTgr2J_9I)$b9we7Tgr2J_9I)$b9we7Tgr2J_9I)$b9we7Tgr2J_9I)$b9we7Tgr2J z_9I)$b9we7o62)}_9L6hb9we7o62)}_9L6hb9we7o62)}_9L6hb9we7o62)}_9L6h zb9we7o8o_-{m7>HpJzX^DgNi_C!6Abo_?|^{^#i@o8o_-ezGb4=jkV#;(wlgvMK)O z=_i}wf1ZA_DgNi_C!6Abo_?|^{^#LGQ~Y=5t2V{|9Q|Zd{Lj%(HpTxO{bW=8&(Tjd z#s3`rWK;al(N8wT{~Y~fQ~b}-Pd3H>9Q|Zd{Lj%(HpTxO{bW=8&(Tjd#s3`rWK;al z(N8wT{~Y~fQ~b}-Pd3H>9Q|Zd{Lj%(HpTxO{bW=8&(Tjd#s3`rWK;al(N8wT{~Y~f zQ~b}-Pd3H>9Q|Zd{Lj%(HpTxO{bW=8&(Tjd#s3`rWK;al(N8wT{~Y~fQ~b}-Pd3H> z9Q|Zd{Lj%(HpTxO{bW=8&(Tjd#s3`rWK;al(N8wT{~Y~fQ~b}-Pd3H>9Q|Zd{Lj%( zHpTxO{bW=8&%uwT_@ASnY>NLm_|X*qbMT`n{^#IFQ~b}tkEZyagC9-tKL4 z6#sMZqbdI9;73#Z&%uwT_@9FxP4PbmKbqoy4t_Mn{~Y{iivKzI(G>r4@S`dI=ioVs15vh;D-aJ1|AzYI&jy(%>&WEl>-+I^!NX||KRc$z+Cg3 z0u~46n&%X-I55{dr+~$Qx#l?qEDp>y&naMWV6J&i0gD53&2tJ^9GGjKQ^4ZDT=Sd) z76;~<=M=CwFxNb%fW?8i<~ao{4$L*rDPVD6u6a%Yivx4ba|&1-m}{O>z~aDM^PB<} z2j-gR6tFlj*F2|y#euozIRz}6KTSjVhxvcgQ2t^5-!znenEy8orhxvcgQ2t^5-!znenEy8or zhxvcgQ2r^~yk#27KV_S@OhfsnZ1a|BDF2jg-ZBm4ALjo}L-~jKf74L@VgBDVlz*82 zHx1<<=KoDY`G@&`(@_3l{@*l|f0+L_4dox^|4l>rhxvcgQ2t^5-!znenEy8orhxvcgQ2t^5-!zne$~JGAhVoC@<}K4u{wdqMWg5yq zWt+E5L;0s{^Ok8S|1ke=8p=P+|C@&L5A*+~q5Q-AziBA{F#m5F%0JBin}+fa^Z%xy z{KNdeX(<0N|8E+~Kg|D|#_McTVg|E4ZHGyiYu!ZY*#rY<}) z&uHqxGxLn5E<7{OXzIc<^Ngl0JTuQ|>cTVgjHWI;GtX%1!ZY)XrY<})&uHqxGxLn5 zE<7{OXzIc<^Ngl0JTuQ|>cTVgjHWI;GtX%1!ZY)XrY<})&uHoo?f!jYp3&65;%WRn z=xO|Y+0*zt=4t#r;A#Ac|IGiJy7SFZ_|N>msf+*2|C_q_&-}lsi~r33 zo4WYV{J*J-|IGiJy7SFZ_|N>msf+*2|C_q_&-}lsi~r33o4WYV{J*J- z|IGiJy7SFZ_|N>msf+*2|C_q_&-}lsi~r33o4WYV{J*J-|IGiJy7SFZ_|N>msf+*2|C_q_&-}lsi~r33o4WYV{J*J-|IGiJy7SFZ z_|N>msf+*2|C_q_&-}lsi~r33o4WYV{J*J-|IGiJy7SFZ_|N>msf+*2 z|C_q_&-}lsi~r33o4WYV{J*J-|IGiJy7SFZ_|N>msf+*2|C_q_&-}ls zi~r33o4WYV{J*J-|IGiJy7SFZ_|N>msf+*2|C_q_&-}lsi~s5T|9byF zy%5j;yKnTK(GQQ7M&C91=F!Q~zL7r}X^;GmBmc!nW90P6b0h!y$hSux9{J+P9U~vG z&j7q~?L>neSzeXTFrVBlG^u4Vf!4lLLP`ur=^c z2mafEzdx`r@V5v4XyAJT#|OSNaL2&=2W}X+VqmiWPy4s*x77Y)pZ1{de#Gw8y1x4n zS3lO3{vxh^tSkLRT>V&A`ir>wv99zNarI+e=`Z5y$GXyA#MO^=rN4-)AL~kg5m!If zmHr~Geyl6~MO^(@SNe;%`mwI`7jgAtUFk34>c_g$U&Pgqb)~Qh`BG_Jt&#XrXX;<1 z$aU!_FKY zB)FYd^SC0wr4m=Y9k`&R1O%k=^;KYa+5cUv*7H zcIT_EiOBAJ)in{>ov*qkBD?cd*Fn8c6PGzP~Uz)m+bB1Ij&Z6U7=-?rEDS*1&R4+eEPjmwVbKiZ#I8(>778LFS&e ziDC^j_q0tEYp}VeZK7BO&OL4YtwQHib3J<%JomKqw+f$o+WK1s&^>MatwQLYw*FQ@ zbWdA%bx-3DUiUQq0CrE~4`Qd9>)ERyyQlF7vwIqUK)a{$2eo?|e_*?(@dvki z8h?Phr|}25dm4YByQlF7yHm~e>{a01)A)nlJ&ix`-P8Dk-#v{#0N&I1gWx@lKM>y2 z_=Dj+jXxmX)A)npsiq@X1>-%9KRDjg_ygoUjXy}<)A$4BJ&iwD-qZL4<~@x+Xx`KK z1Lr-BKX{&MI)YVz-qZMl=sk@;klxeygXukuKcL>z_=D;_jX$v7)A)nyJ&ixW-qZMl z>^s_>ueu7_dm4YRy{GX9+A~Vt_TOduE3v;y_7@+I?XUOPUpLubIs5Ad z`zx})X6&yU?XSH3b)Efnz5O+4e`Wp>|2=8{?5pgrY5VI6`)l8?HTpM4|8VrF(T7Gq zH~R6>_l{madd29J?fri}^76@TuE%hs|#&i*iaD*IUWX!fq`&9?8qGJ8?BfB4tKFAx7>_-Dhl;U5qGaQM{lW5Y*> z@3LKgG<@aoMZ^6=zaDyd=odpj8>$Wcc<6^ir-mLII%<3Vn}?#ID~B!`>L2{|;LC%* z82s5_ZSco~KO8(Y_?YeZ?;5;$FdDpa@S?%~ztHRdvs#ec_5WEdNbdUotQI79{eM;q zlDqyts|Cqj|DV-@|7W!zx$FP4T9DlJ|5+_a?)v|%79@B5e^v{UyZ%3` z1<76ipVflouK&+!L2}psXSE=?>;JP_klgkESuIHJ`v0sJBzOIPRtu85{y(b)$zA`S z)q>=%|Icbca@YT7wII3c|Fc?<-1YxiElBSA|Ev}ycm01>3zED3KdS}FUH_leg5<9M z&uT$(*Z*g=Ai3-Rvs#ec_5WEdNbdUotQI79{eM;q5)aHZvs#dNV6K_fg2V%J&8!wA z9++!pwIK1pTr;Z$i3jGISuIFBFxSj#LE?eAW>yOl56m^Q@7rCVcwnxXeXpnS_a0B< z?9eYH{xmh zWj&3*VNc_4$kX^6^fdl5p2pvRr}5V>%?0Y&K2KYJr@!xM>+kgUJZ=4*{;sF3zti9G zwDouT+n%=mPJheO*5B!GdfNIs{gkI?4w%#5uzF{2z;3CU(_fb?S^1=7V&xN(v6Uw! zi&j1^S+Mdk$-I>(By(0iDj8XMToPB0>`J?(YEC~aiL0+k;_9oCxPtgQ@2G?;fS*cS z!TVI=3f!j>SI|C{xB~X6#1*XHk#rxI6? zJ(aiu?5V^RT;Gv)OVykP>#4*QR8J+YfO;x%1=CZBE0CT_TtW0y;tHUr5?Am%mAC@u zsl*jD-;s7p)tmxPRzc_; zl~@IzcT{W@bly=#t6=kvDp&=XcU0agxV)osRzc+*6And@gF z`@iX#nVa1I-fT`=I*(qG|LW2EzxFDx+uv(xJ^HG@*S==S{pzocn$wozqnGsY=UQPA zo(lUFEx-5wiuQHO^Zj4Xn$z(8qQ0k|dYd^7+Aq1~iN}u~x8{@UXG+)SO4BpBn+nlQ z`I#H+ypBE6reKX)gZrJlB7Yl*zn(>4q)5tvdS_FuntB?4#HOCcAGxWg@kem#Y5b9#dK!O3r&JSGm&i^%jX%OuPvejD z)YJGQKJ_&I$WJ|uKLS)wy~xRlt=(Q~_5CQH0ec zg{VBP6r%FDQi#gqN+BwbD}|^$t_V>(nJSMfQdBB&MT|-%uEl}cO@r&5V4o1l6US2i&9B(7{m>PcMLSd>b_>XHpcJ&7wD zjd~JSHVO44t_VImUpK-P;U|^2vKgl*ab;soPvR;oiK}5r8&;QwtlWuBC?yWS`?ApeAS|e?B=T$MPxT$wJ0LH`Km<`+09oiipXxhYEeXX^Hqx? zvYW436p`J0)uM>(=BpM(WH(>6C?dQ0sznjm%~vgo$Zo!BQABq0Rf{6Bo3C0Fk==aN zqKNF~s}@CMH(#|VBD?vjMG@J}S1pRjZoX3n5j^)a{@`;@;}1ahH2xrTPvZ|n_cZ=sbWh_CNcS}U zpma~;4@~zo{@`?~*}h%`)IE(qNZr%;1Jyl^KUm$<_yg8GjX!AJ)A$3|J&iwj-P8C3 z*gcIuh@EP-uNOgfPvZ|}_cZ>1c2DCEYWFn$z;;jL4{rA~{s4DR;}3H8H2y$$PvZ}E zr<(2SMd01j_=Da(jX&_+)A)nmJ&ivA-qZMl;605$5Z=@HgW)}mKOo-I_=Do9rXyGc z<2{W(INsCv1LQr8KS`jX%KN)A)nzJKD`xErRx*#vg3&Y5W2A zp2i<^@9APV|L?ED{QqEI=3M4%=B3PwnWfANnP)RkXHH~}WDaKzWo9zdnS+_WfpY_A z2VNR@abRiSg@I=Wo*piWbgPl%i#IG@Tai$|PKWtPPw&ZjcV;t}UlnPu^a^Qp|Tc*OZs zW?4Mqd@8dn9&tXESr(5tpUNzYN1RV(mc=8^r!vdp5$98xW$}pfsm!u?#Q9WaSv=x= zDzhveaXyt<7LPce$}EdVoKIzz#UswAGRxu-=Tn(w@rd)O%(8gI`BY|EJmP#Rvn(EQ zK9yM(k2s&oEQ?2+Pi2# zIG@Tai$|PKWtPPw&ZjcV;t}UlnPu^a^Qp|Tc*OZsW?4Mqd@8dn9&tXESr(5tpUNzY zN1RV(mc=8^r!vdp5$98xW$}pfsm!u?#Q9WaSv=x=DzhveaXyt<7LPce$}EdVoKIzz z#UswAGRxu-=Tn(w@rd)O%(8gI`BY|EJmP#Rvn(EQK9yM(k2s&oEQ?2+Pi2#IG@Tai$|PKWtPPw&ZjcV;t}Ul znPu^a^Qp|Tc*OZsW?4Mqd@8g2x?MhTK9yO%$kX^c=xO{-c^ZF{p2pvVr|~!LY5X1V zH2%gsjlWT8^8E6Mr}3BdH2#J?jlUsJ<8RQ@_{(@2e*>PzU%#jE*XL>Lul9Xu@_g-k zp0@sK-}SWhSNo2qt-sp0J#GEfzU67_ul7w(TYt5uJZ=5ezTs)>ul99MAth99-BdK!NZc^ZFT@ihJ( z^fdmy>}mWR^ECb*@HGDJ_cZ?Q^ECdBO2d!Z5l`dqUQgps{O5csQxpF=pUTw4f6k{e zHSwSGsZ34$=X@$t6aP7%%GAVv&Zjap@t^alOildfd@55D|2dz^)Wmx@js&fsEPj({YOpw zj~qY5|A_vhCjLkCA2snmqW`Fg{}KI1P5h7OKWgHCME_9}|0DX3CGkI^|5y_LBl?de z@jrqeOX7c&3(x<%(4PNis#*_u{-3F8J>>a+rmFRj=l_|i)>a+rmFRj=l_|i)>a+rmFRj=l_|i)H&zOJ0)A&2-Y5YCzY5YCrY5bk=H2xm-H2#iz8h?*?8h;Oa z8h>Bg)ja>t%zxF>_}Sm1?rHpe+|&5`n5Xe~o2T*jQBULV zBc8_JhdqtITRn}x4|y7Yw@AZ}`44&;e>Zy?e}_DczYlmCfA9A+{@&+l{Jq!H_x5cV6zIc;U{=T@)|edAWH+y(K%otL|CLf?PZ%LVbmotL{H zUbype7sLy9UhaZ;;m*rl5HH+$xeMZjJ1=)Zym05`E{GTIyxaxx!kw49AYQohau>u4 zcV6y-c;U{=T@WwadASSXg*z{ILA-G1x=jASl7w){=1@Xe2m%AWdxbt!s#0z&`?t*yX&dXg8FWh;# z3*v=4FLyz_aOdSN9M<=ryuBb^xbt!s#0z&`?t*yX&dXi6-TVFge0dm4X-JdM8(cp882 z_cZ?ACr#d7c(14N_a0Bl^ECe6?P>hI%hUL~R+_xMaE+(&_fAja?;W1T-`hQn zzqffBe^+}Ne^+@Le^+`Mf771E-&>{0+Y48C8h>x`H2&V~Y5ZO8Y5cv()A+m0)A)O% zr}1~Gr}6g&Pvh?rY4Y~M>phLXi#?4$@joGNFNpsMd3!~JJI!jf_@9us7sUUByuBd)C*9|zxbcH{eJO3ar^z^f8zH0#s9?Z_ly6D+wT|u z6Sv<{hF%ypRiw375`)SQ5FAV_G_x*f6RVORs4_Huc?avG5a-D@jqt2rYio& z?AKJq|Cs%ns`wwXUsDzTWASXs zRK@?8{hF%yAG2Rm75`)QYpUXZ%zjN({Ey*BRs4_Huc?avG5a-D@js^jsEYqF{YO>& zkLf?E;(tv4Q5FAV`j4vkAG2Rm75`)QYpUXZ3_q&ke;kMF{})>SU)j>nbBPn|xAgN| z;spCG{XCaA!G23W&m~T<-_p->i4*L%^z&Te1p6)hJeN4ZeoH^kB~Gy4($90rt}m4> z{XCOTD_i<`PVD+p+0xH*V%L|-mVTZSyS`Mm^z)q9^`)|J&nIBq-{Q}Y`w+P_?V@3^P&_lT$Q_pr3h zrNNf&sf%Gn&;5**P4S=m87rIOKld|MHpPGLXRK_B|J=`5*%be|pRuwj{&PQL zWmEj;e#XkC_|N@}l}+)V`xz^n;y?E@RyM_d?q{rQivQftSlJZ+xu3DJDgJXmV`WqP z=YGb@rufhOjFnCCpZggro8mwBGgdamf9_|jY>NNf&sf%Gn z&;5**P4S=m87rIOKld|MHpPGLXRK_B|J=`5*%be|pRuwj{&PQLWmEj;e#XkC_#fN- zjmoC@AM*sQP4PeG30j-tf6NoKHpTy#CunVo|FPqT_#e}MY>NLe{l}*GAJczqivKbF z$ENrn(|>G=|1tf?ruZMze{72XG5yDe_#e}MY>5Bd&sfl>Xn;wVu-do4VFh`hQc`dg`uE)wQ0||C_qjQ~G~X*Lq6- zZ|Yi4>Hke#>nZ)escSu@|2K85r}Y1(uJx4u-_*69(*K*f)>Ha_Q`dS*|8MGAPwD?n zUF#|Rzo~0IrT;f|t*7+=rmppr{@>KKp3?uDy4F+re^b|bO8;-_T2JZ!O@U`}o+j)s*0r7{>@S|tdYZ7mct-1K!v5kJt)~h5 zi)XZ+CfpBpM(b(9{a|Obp1SK(XSANW>r-d6p1SK(XSANW>r-d6p1SK(XSANW>r-d6 zp1SK(XSANW>r-d6p1SK(XSANW>r-d6p1SK(XSANW>r-d6p1SK(XSANW>r-bQ-p%9g z`qY`Pd7Aot)zj4PA!)8po%xEVso#U1rhZ@cwEg~`Ip%5m{XO%5r|tLm%>ACW-`_L$ zd7AIO6zxR6@ zfA8}&{@&|p{JqE1_`Au|_$zxFe_}}-b2mkv%_27T@|9SAgJ>!G_?HM2Z zZ_oJPe|yFU|JyS@_}`xK!T-=5L% zzdfVje|tv5|MrZA|LqwK|JySf{V#|BvB+_Wv>b&;CD#|Jnb?@IU+i z82)GfAH)Cb|6}-{{eKMqv;U9bfA;?|{BO@__@DiM4F9wLkKupz|1tc}{y&EQ+5gAz zKl}d}{%8Lm!~g96WB8x_e+>V#|BvB+_Wv>b&;CD#|Jnb?@IU+i82)GfAH)Cb|6}<7 zfB*l3_y5M{cJ`$4xt%>}d~Rn?8lT(Qlg8(E_N4K-ojqxMZf8##pWE4!#^-kSr180( zJ!yPyXHOcR+u4)G=XUm_@wpuzFg~}lCymeT+&dbd+qri%KDTr4Xnbzx-qHBn&b_1Y zxt)7Q<8wRrj>hM9?j4QK?c6&WpWC^2G(NX;?`V8(=ibry-1lc5-)DSo=ibry+|IqD z@wuIQN8@ul_m0NrcJ`$4xt)7Q<8wRrj>hM9?j4QK?c6&WpZor6DhxbL~@&&$UlAKG#0g_+0x`<8$p(jnB1DH9prq)%aZdRO55) zQ;pBHPc=T*KGpbK`&8p|?Ng1DhxbL~@&&$UlAKG#0g_+0x`<8$p( zjnB1DH9prqRrp-{RN-^&Q-#m9PZd7bK2`W!`&8j`?Nf!%wNDj3*FIJFT>DhvbL~@w z&$Uk#KG!}~_+0x`;dAX%h0nE56+YKKRrp-{RN-^&Q-#m9PZd7bK2`W!`&8j`?Nf!% zwNDj3*FIJFT>DhvbL~@w&$Uk#KG!}~_+0x`;dAX%h0nE56+YKKRrp-{RN-^&Q-#m9 zPZd7bK2`W!`&8j`?Nf!%wNDj3*FIJFT>DhvbL~@w&$Uk#KG!}~_+0x`;dAX%h0nE5 z6+YKKRrp-{RN-^&Q-#m9PZd7bK2`W!`&8j`?Nf!%wNDj3*FIJFT>DhvbL~@w&$Uk# zKG!}~_+0x`;dAX%1^?Tp3jViG75s0XD)`?%Rq(%ks^EY7RKfrDse=FQQw9IqrwabJ zPZj)cpDOs@K2`Al>r;P@;QtCg1pillj}-i0xtACGU%8hT{9n137yMtjmlynBxtACG zU%8hT{9n137yMtjmlynBxtACGU->;!@PFlAUhseAUS9Bjn|DrKThGPCBu%v#ALS!6TcuXL^_BRZZ}0v6-~ZLS?|ksY(di#N^4P;iPE6+q z_6-aU4jh=C9vB#Z@4&#o$Lv?ZeqAvzkovg&bI5-6{~7H6%kF>LpK;6N6~p!$2KWA7 zeA~qKAG`mJ@Jxt6h(L%yh(L%yh(L%yh(L%yh(L%yh(L%yh`^t71ooVKVv--Z&;8u$ z-v4v&*53bV??2ev-TU|V{=L0_XX=lq{`S;=H1+RKJva52rhYy3$kdUkuTI@QRi3(G z>guWS$^U!uf1d14{@uwxnruwIIQg$m{tJ^QCXY^jee!dYmB||?-!-{s;{TcWUnVvu z{@%n(6U~W#d*WZ4_=AZjCVnvSjfu}sR3|<>am~cUp8t2xpX~YLJ!kj4yk~jOzq99G z-(&Xtbk7g>d~?qodv4wHkv;F;GdcdJ``crGZS3D0`^#g|*pp)qj(vOVi(?-jyLs%|vAtsh zqrK7BN6(GEJlY(6arD{IlcSH09vQuR^x$ZA^t#dgql1}V=Jm|E%*&Z(=EcmjnUk4E zGet9GlL_&k=IAgjl4Y49C>l%*^!eYkB%G}xqIZ`NOt79k^Lis!@c3x zhtCbaJlq_9aroKclf#b=9~r)T_~3AM_`2c!!-GS;q1T7b4ZS?n9C~r+*`bp|j}9Ff zx_jv0P0bKv^ttrQ>1O)H^t0)c=||H?(s!p1rnBkm()-hcsb1>!)Vb8l zsb=cM)U&CRsYg>sQg^2grn0H)Qu|YbgT2Am2hZgvqQCaUM7&zD8!p!j96R#x(Ofof zb=lK7t4p5FT3z(?jMW9{nX1)!PgktYdAe+M*3%`cXFOfB`lFsMSbdA9@prSQ@pqG_ z@%Ir=eI$Ooxjh@Ee4W7o|hdhnH4|*DZAMiB(-tTGrz0cG5yWZ3IyUx@2o0hKN z@4cSJ-?g5`-+Mfbzju2Yf7f^#fA8`%{;u{k{@&?n{9WZ~{JlfEjK3>AjlZ{h8h>x| zH2&Do+y4E^mhrdW)A-xxY5eW=H2$VMjlW4x<8MN`gugwW#^1Q7@i*pa{Ed1Ve;H5X zZ^YC18}>B*hCGeGw5Rcxk}l$J(9`%E@U-=J?rBe3f9Ia^wDouH*Pgci&i%^M*5A2b zdfNIs_X|&3f9HPgY3uLYlhOt2@7&KkZT+45si*Pxgs1U$!qfPB+|&4b%+vUL)YJGo z?rHoz;%WRHlg{JsVNc`lAy4D)C!WUNk3EgQ2R)6yA9)&oKlC*Ie&A{R9rZN+9+1xA z?|x6??>B&H2&`KH2%KoY5aY~)A+mF)A&0i4L{C(+0*#D%hUM#lBe-^r>F7vMNi}J z3!cW`9iGPD=RJ+T&v|-gPkipPR$uM-Sgl%lyJW@6&q$W7yiKxX<)Xb5?#*GHc~0Bysie9a+KE$0Tuet0b)J~*z zbrxtR(z-eevlD4uodwy6w64xV>_l2uX90F1t*f)}dRu031+Ei`D`=faTmkDu;tEzL z5?7!)k+_1?iNqD4P9(12bRuyDrV}|c9-oEMS8Zoet6=oDs#pb~w^i9H_`I!3Rzc@& zRkR8=Z>xe;ka=6>t%A$jDrXf`-d0(wVDh$_d1rhUA`j$qGufG&XR`Kx(=#)-y8pd9 zK5OYbc4hv@NACa08$56SuBG+Z8~$DUoF(@gKQ|ViwG?>M+@BWJR zdCT+NpU=c+;rsr9C!c(Od=|7{dE1G{jvTY*%Qt7UH)r$H+5D~9+^sXETdI{xrCKUj zqu=EH$D5DaKRz6HSr}t;XQ>2gb0KPgb0KP zgb0KPgb0KPgb0KPgb0KPTpR(`|ATwKGhqK0{s|EX5eN|o5eN|o5eN|o5eN|o5eN|o z5eN|o5%{N%z{%_HykcPR>aoGwZriu-YhN22WVYVO<0l?_@YoMiuAP6TdULisJwq@5 zt;NDExm+nt(mu|DtcZbJk@1VRKt z1VRKt1VRKt1VRKt1VRKt1pZ=1Ak6>!i}|^ScO4=SA`l`FA`l`FA`l`FA`l`FA`l`F zBJk%Ffs^k)dHwxwcNYMB%A5Z;aPbuY+3d~P{B$;dYnCB^x7cZZGdVZ^?+u z_%B|0;>dju9sSIa6G!ej`uK@Ej{V>f|KG=N`^xPH@40>Yo`avh^Y-cM{im*4RUp=gW88Wq-hzZoliE>ASvc zzrJ?ooi}a&rJVPd{HMO^CSBSme|qGx`+s!gu^X~CUi4Q#bM*cPA3pLBuld0CzrNAa z{PZ_``pAi+CmwwGsQc^5zhC_KlLy@oc%yH)eQWsT48NR7vhja8?JwiW&!2oCbJfQ_Hu#$l zxy*OlBM%(ChZM-~;7m1}&E^Z)LVlNr-*eHg;4a^E!}#>{9S=<3ao0UJ*?+t1$iqjc z@45Y(PTcYMmw&P&`0sv4B#F)D$S?7??0+Ih@3EO`M?Z33ZrbMJJ9+Y;`&;8TK7R7P zk*hxOiNRm~);rmLD>KDxKAX=M{7rn%9J$b`18=0Hz-@NhZeCDdFuO2+P{Ug76|BoJd zm7I=xPFH^eSqwaAF>kf;QE~;YtxO*!uEG$dV2cClZ8)ZuKLi2 z`o9x?e#%`W#xC}A(R0q$p)Yzbp)@}|je}3y_hs|seGi`4NvwLpCd^Bpxaa7TB;!6A zJQzCLw|qKt)iu`){wD7}i?5z|;(?>bP9%S%F1DIHnj}UWyq)O%lQDZc^mllFQ8AT2 z8&n>?%_3s^_t(D80|`g%e|&%N_{qJQs}3FG=&g8w6?=s-dH!EgSq2$u3Cy{v*`AHH&z zSH0+)-m(bV--hr0uJ=;TzTt0!efX;1`CjZdy=Cu(^Z$1a{Cr?JcZmC^rk^hD-#CO7hf;S0m>ANs55|2mZ)_(!R^fu9fl^*{51`0?LN@A_*< zoQke zcirI0;&0WAazAvD;p_Fp?sb=|Zhou2@{6D88z2A8yWixKWB;mH&iz&j&Sv|Mf9N7h zagD{T?xu_EC=*l&f6r|E)tU!!u6NzY$Q+bR9yXn%lp}%vCD_+lZE@v3m(*~WiNU) zTM&Q#H}86rU-^E-cfxq_2l2s+g1XB$y=B?z@!!02_g_7Gf0S%KSI*_+(!H0R$3L*k zd%5_#F8$TB5q!t)5#0IldRg+p&cpBD=MD5>vnlB7e#R94I?=9yCdkm ztRI}2>0Ms+qHlT&BRKJ95iDlQ1zS&F62av0_wMpuk_aZ>^@b4~f3pZ)^0M2(Nglp- zmsh>$o8H0*j=ot0^Vw3qSjb)y!Q}C4c6l#J1e5Q2!w8PNSp+Y6+3nyY55H@dSH0+) z-ogkD{jLb+i;-xH=h>Hb}0XL9>S(;pc0Z^wFnIRC%gerdw{ z2@wbp2oVSo2oVSo2oVSo2oVSo2oVSo2obn60%84sX-vW+Ap#)+Ap#)+Ap#)+Ap#)+ zAp#)+Ap#)+Ap)0M1j73Na{ENX`w0;U5eN|o5eN|o5eN|o5eN|o5eN|o5eN~uGy-A$ ze`!p@BOwAI0wDq+0wDq+0wDq+0wDq+0wDq+0wDsITLi-T|8o08!}|#l2oVSo2oVSo z2oVSo2oVSo2oVSo2oVSoxHJM`{eNjp!XqI9Ap#)+Ap#)+Ap#)+Ap#)+Ap#)+Ap#)+ zms~FYRgU zd124&o@e$P-*b4+p*;uo%gJ}`D+?6tA8V=s+0#$Fhk9eZZ%_}JmGLt_WVX2zz+_KgjUUKo9C^z7(Mqm9uQ zMrTK#89hFFc=XWdfzg@K>Ct_o1DOk%*D_}_FJ&5;7c#S%XEMh#hckyV2Qo96>CC>& zz{rJ>*GA5cyfo4nd0}LB z`1tVQ;X}g*hG&MShxZK+3|$y{ZRqUKOGAyJ7lvkso*6nmba?2{(1D?uq3NN0Lj&mx z>DSU{(=VkP=@-(o>1Wc%(}&ZC(g)Hr>FM;o^g!xD>b2C_)Jv&G>V?#7>Y3E>)Zx^j z)PdAYYC5$qH86N#@HP7}4ot*d`)UK%3>-W1@X=x=YxQ1F&saSrU9MU^>FJ8q6P_+x zy~ooftH(WEw0g|b1*=CrowqvU>73Ogp2pv>r|~x=UBX}5)A&ny8h?YH#@~Rat-n{F z_O$i)>QkP!{$BmHr>(zNf8}ZG@6}&=+WLF-7t%%R@714s+WLF-Nl#mUul~%_*59i? z^)&vT@HGBTcp86?dm4X_c^ZF@dK!Pnr3?6b#MAgY=4t#r>}mWxJL+ltJ>Y5l-S27q-REii9q}~&4tpAZ_j($C-}f~BzUOKD zeOEe%zwdY&f8X{r{=VgD{C(5Y`1^*Z@%MF4L8-v#0TQlc(|b5l`dq!_x5M z)f+vHzZ*P_zYlpDe;@QT{yyMo{Jr1P_|3U$O;(wul zKk>g%z@PYEDBw^0FBI@6{udlS#Q#Dbf8u{3Z~bkE|AoBuw;}!)^48ym_+Q9de;eX| zA#eR{i2sGW^|vAZ7xLEMhWKB|TYnqke*u1Mi2sG0^|vAZ7jpO${|h<%iT{Nh{>1-6 z4u9f*A%{QlzmUV9_+QB3Py8?B@F)Hk;KzpeU&!K5{4ZqjC;k_*_!IvNS^SCrg)IKW z|3Vgj;(sBFKk>hi#h>_J$l_1@FTjrt@xL&GKk>gXgFo@VFoQqwzc7P8@xL&GKk>gX zgFo@VFoQqwzc7P8@xL&GKk+{gKQ_ewd=-D1-$6@TJ?9)4_y|M?33#Q%H+f8u|>f5B)GXBK>d>Mb@f4+=A@jqY2pZK3I<4^q0m+>e5=gasL z|MO-1iU0XB{>1-0{MZox^CkR=|M?RB#Q%H=f8u|>gg@~=U&5dGpD*E0{Lh#0C;sP4 z_!Iy0CH#s1dHAs*{^yJM6aVu?{E7ehBL2kxe6bkT|CibNKWZx9R&2hEn##8on=hlL z@@>WD%c!Y*Te0~vYAWAWY`%<|%C{ApFQcaNZN=uxsHuEgvH3D;D&JOYzKoj6w`H3z zqo(q0+2+frseD_u`7&xM-mTkQqHI;A6 zw%(4K%C}`(Z%56Wck1=Bt+%7*P13gBj+!6wH2yy9Y5d*jY5d*bY5aZ2)A;+Kr}6gz zPvh_Xp2pw%JdMBWrER?(HLvqD{-!;RzxR3?f7f~%fA8@${@(3r{9WT|{JqQ5_`BNE z_D9xzcEkaZ`9NH%Xk`pBc8_Ju&41iByH>MsG0UO{!*UC-=L@QH{faO zuko~}t-r=op0@rPzxK5C*Z7sEt-r=EJ#GCpezBuV@T2i_Pg{SDCp~TbHGbx4>#y-s zPvh?iPvh@|r}6i=r}6igr}6iwr}1}O8h$h$@ihL9c^ZEYdm4Wac^ZE|@ihK^>}mWx z=xO}@$kX@}|4ZzXU%T z;(rN#G{pZB{Ah^(CHT=0|4VkiCTfWPCA(h}HN^jt-LHun;(y8R*F+8Rzhw7oqK5ci zvimhrL;Nq<{hFvD{+H~2P1F$oOLo5|YKZ?O_|XvmOLo5|YKZ?OyI&JE#Q&1ruZbGs zf64CGL=Ex3WcO>LhWKBy`!!KR{4d%4ny4ZEm+XE`)DZtmcE2WSi2o({(GdSjcE2WS zi2o(KUlTRN|B~IWi5lX6$?n%g4e`HZ_iLht_+PU7HBm$SFWLQ?s3HEB?0!wu5dTYd zzb0yk|0Vd*5dTYdzb0yk|0TO$6E(#DlHIR~8sdM+?$<;O@xNsEYodnuU$Xl(QA7MM z+5MWRA^w-_eofR6|4VkiCTfWPCHT=0|4Xbt8sdM6^+!YeFR}h;i2o(l9}V%p#QLKl z{+C#PG{pZB>yL)`Ut;~y5dTZ8KN{kH(eXq4FS7nyL)`Uu6B!5dVv;KN{kHk@ZJI{4cWpXo&ws#}Dzp$oiup{ufz)G{pZR>yL)`Uu6B! z5dVv;KN{kHk@ZJI{4Z8=Vf}xZt^ebW>MeK~cT{h|%ebR@3tq+@)m!i~?s)YU`%@jS z-eP~MMhPUI$piS`9{a9w>aPEc=Z%O=Nlcb-r{_tMhPUI$piS`9{a9 zw>aPEc=Z%O z=Nlcb-r{_tMeK~cT{h|%ebR@3tq+@)m!i~?x@~^mvKk+7QBo*s<+@}+)=#+ zFXN8tEqEDsRByq{xTAUtUdA2OTktaOsNRB?aYyx*<)ziCw_JZ!NA*^b^No(`ts>_e z9o1V!&Nn)$w~Cx^bX0E@Ip650-YRmw(NVosa8N@8y(eK zMb0-ms<(=qZ*){|6*=GNsNO0%eyH9mI)13$Dms3s-YPnNc=eX!hgWYoet7kkdy z;YVBiFT#(u_+Nw{ZSlVdKicAd5q`AA|04Woi~mLV(H8%U@S`pM7vV=+{4c_fw)kI! zA8ql!2tV55e-VDP#s4DwXp8?v_|X>si}0f@{ukj#Tl_D=kGA+dy;YVBiFT#(u_+Nw{ZSlVdKicAd5q`AA|04Woi~mLV(H8$*e^p!jFTjts z_+Nk@ZSlVVKicAd0e-Z_{{sAIi~j}q(H8#;@S`pM7vM)*{4c^_|X>s3-F^Y{ukg!Tl_D;kGA+<;C#F-{ukg!Tl_D;kGA+l{0Uw|KN@xK5++Two!eze8^ z0{m!;{{{Hb7XJ(Iqb>dy;742hFTjts_+Nk@ZSlVVKicAd0e-Z_{{sAIi~j}q(H8#; z@S`pM7vM)*{4cU4K&9bFN>mt$NP&%e7U{ zxqi8}>N(dh*H%5}`sLcH=Ul&BTlJjlmust@bNzB{)pM?2uC02`^~<$Y&$)iNw(2?8 zFV|K*=lbQ^s^?t4TwC>=>z8Y*o^$issh)HFaxK+!u3xUDdd~IBwN%f!ez}(FIoB`OQa$JTmrFzcw%e7R`xqi8p>N(dh*HS&_`sG@x=Ul&BOZA-Vmusn> zbNzBH)pM?2uBCd;^~<$X&$)iNmg+gzFV|8%=lbPZs^?t4Tub$w>z8Y(o^$issh)HFaxK+!u3xUDdd~IB zwN%f!ez}(FIoB`OQa$JTmrFzcw%e7R`xqi8p z>N(dh*HS&_`sG@x=Ul&BOZA-Vmusn>bNzBH)pM?2uBCd;^~<$X&$)iNmg+gzFV|8% zXZz(Q;+E>UJoP|J^<19yWJ~p2p7mr)^<19yWJ~p2p7mr)^<19yWJ~p2p7mr)^<19y zWJ~p2p7mr)^<19yWJ~p2p8d#{>bX4okuBA8dG;e)s^{|TN48YY<=KyHsh-QTo@}X} z%d?(rsh-QTo@}X}%d?(rsh-QTo@}X}%d?(rsh-QTo@}X}%d?(rsh-QTo@}X}%d?(r zsh-QTo@}X}%d?(rsh-QTo@}X}%d?(rsh-QTo@}X}%d?(rsh-QTo@}X}%d?(rsh-QT zo@}X}%d?(rsh-QTo@}X}%d?(rsh-QTo@}X}%d?(rsh-QTo@}X}%d?(rsh-QTo@|N# zdDfFH@juUcvL*iKSx>ga|2*r-miV7%J=qff^Q&ce*pJP4Q6903oCtKowj`d_q{LitT zY>EFl){`yqKgW8qCI07FPqxJW9P7!J_@84v*%JSAtS4LIe~$HJOZ?BVo@|N#Io6Y_ z;(w0yu`J4X#+LrP+{r|Ns zHn{7DSy-dU)xgtrvJaTrTk6*e{Du`J4X#+LrP+{r|NsNLzl_wm#%({C&{V`1^pT@%MgD#z4K zPg{SzUwYd5>;1yh)?e@Ep0@saPkP$=>xuvL|JQorKmGr;p7>Ayf2}9})Bj)ViU0Kf z*LvbV{r|O|_)q_TttbA||6l8g|MdUYdg4F*|Fxd@Pyc_dC;rp_U+ang^#9j-;y?Y2 zwVwD-KVz*Y{?pG`>xuvLGuC?IKmGr;p7>Ayf2}9})Bj)ViU0Kf*LvbV{r|O|_)q_T zttbA||6l8g|MdUYdg4F*|Fxd@Pyc_dC;rp_U+ang^#9j-;y?ZWwVwD-|9`C~{?q?o z>xuvL|JQorKmGr;p7>Ayf2}9})Bj)ViU0Kf*LvbV{r|O|_)q_TttbA||6l8g|MdUY zdg4F*|Fxd@Pyc_dC;rp_U+ang^#9j-;y?ZWwVwD-|9`C~{?q?o>xuvL|JQorKmGr; zp7>Ayf2}9})Bj)ViU0Kf*LvbV{r|O|_)q_TttbA||6l8g|MdUYdg4F*|Fxd@Pyc_d zC;rp_U+ang^#9j-;y?ZWwVwD-|9`C~{?q?o>xuvL|JQorKmGr;p7>Ayf2}9})Bj)V ziU0Kf*LvbV{r|O|_)q_TttbA||6l8g|MdUYdg4F*|Fxd@Pyc_dC;rp_U+ang^#9j- z;y?ZWwVwD-|9`C~{?q?o>xuvL|JQorKmClgp7>8cW34Ct)6ZDziU0I7)_USU{fxDq z_)kA$ttbA|&sgh;|MWA~dg4F*jJ2NlPd{U=C;rpVSnG-Z^fT6a;y?Y2wVwD-KVz*Y z{?pG`>xuvLGuC?IKmClgp7@{i|Nq0m&4J5s{@;CL_l$jZtTOiDv3HM6jSY-$jsAnt z&gg$OdS>+W=yRk0(&#To9~%AM=v||qvNHg$8@*yQo%vrg|83^)Xa4idf1H`iJfHbX znO|id&U`=fWjh5ho4G#ow#?AT|2Fd9jl44QcSin`k^f-i-yHduM}9qWY~)@$2k_uX zZsdIz|!%q!AVkZIKJ^bn6{P6pSuN)p3`ag#L zhoQBh|8nTB4=oJ+;n1m}r|m4jBST*qx^1X1^nsyw3}w>)IQ*@b0{WsE!>A#Xb zm3}IHEdBlTUFlDzZ%JR9o=W{`>Q7ReslS{0o2kE=`YWkZsi#uMQr}PAmHK4rmejSW zslh)T{1f|;+J7eEHD%8%yH{(_LU)|5T7>|U)YduG|aT2uDSvU|0r?3rcvYE9WQ z%kI^hvS*gvt2JfMEW1~0%AQ$vuhx`3v+Q22DSKwwy;@WD%(8p6rtF#J^kYrgGt246 znzCn>(~mV}&n%}OYs#KkPCwR^J+qvCtSNhDIsI5u_RMnnv8L>q<@94s*)z-O$C|Qd zmeY?lWzQ_9A8X2N!Cnc)=H9QB5_5|+?EwwkunpBD>7yxaYe#R zB(BJpiNqD@GLg6mUT#+ghi7PVYwk+d{M43ojktY+0E7D{laYdF) zB(6x3iNw|0C2{pONnBkaiL3pRxZ1ZPOSsxAiK{6|Tun;iYC;lMdn9o+E{Ur#NnDLe z;wmGFtC1a9#MQ7Qu7)IWm6pU+N)lItlDHa>w64xSEoohye@fE2I{#})>+1Zkc4Wc2 zI{!;a>+1Y3B(1CSKbN$w&Oa$>U7i1#q;+-vr;@mOLK0UeBysh)B(5IYk$GG_Dv7J( zlDK+A5?9A0arLkyt{#%a)lVdG^>Zl~H9+1S<{gSx4 zPZC#0Byn|E5?A+1;_CZ5GK;J4N#g3elDPVgB(A&x^=a&a=;p$W_j>&x^=a&a=;p$W_j>&x^=a&a=;p$W_j> z&x^=a&a=;p$W_j>&x^=a&a=;p$W_j>&x^=a&a=;p$W_j>&x^=a&a=;p$W_j>&x^=a z&a=;p$W_j>&x^=a&a=;p$W_j>&x^=a&a=;p$W_j>&x^=a&a=;p$W_j>&x^=a&a=;p z$W_j>&x^=a&a=;p$W_j>&qL(x`N~z!v(JO%zQ!L+PBiD)=Yeux;}0tLHU7YIU*iuh z_ci_ib6?{RGWRw9KyzQ?4>tET{(y5|;}1F~n)B@Q;JL5y2cP>Ie*n6#@du&%8h;?V zukiig-Pibo)P0RVP~F$~gVlYFKVaS0_=DDc zjX!YR*Z70ieT_eW-Pibo*oo#m`#i|*Yy83NzQ!NW?rZ!(?Y_nz*zRlm!R@}rAK>n5 z{6X%%#vkbJYy83PM01{f9(eaP{-AeX;}3lIHU8jtUt52#0Pw!H{$7FLeQo`{0>b;+ z`g;Y2_qFx+3J~vW>+cmPo@iDCuYmEsw*Fp$<9%)Yy#mPl+WLD1lJ_{e z{(yO3;}4qmHU7YPU*iv+Cz=((D*(N(@dwfS8h;?Yuki=d`x<{hy|3{H)%zNMV7;&L z2iN-=e}KKO@dw$rbp?LB0^0i;f3Ur;@dw=d8h_BeufzPm%WnSvhIr)qQ#ZsT*Ppr} z9=ZP14e`kJr*4Qxu0M4{JaYZ18{(1cPu&oYTz~3@c;xz1H^d{?pSmF)x&G7*@yPY3 zZiq*&KXpSqa{Z|r;*sl5-4Kslf9i&KV|ma`cpT=BiEn0As)H@)D7{-^`~x#N3K70Lp*Z*sT<;v>rdSf zk6eH1hIr)qQ#ZsT*Ppr}9=ZP14e`kJr*4Qxu0M4{JaYZ18{(1cPu&oYTz~3@c;xz1 zH^d{?pSmF)x&G7*@yPY3Ziq*&KXpSqa{a06;*sl5T^EmBf9kq;biL3`cv1%BiEn0E*`o5)OGR5^{1|j zN3K70T|9FAsq5mA>rY)5k6eH1x_IRJQ`f~K*PpsB9=ZP1b@9mcr>=`fu0M5MJaYZ1 z>*A5?PhA&}Tz~4ic;xz1*To~(pSms{x&G93@yPY3t{>Uqlj~1iKkRACv-NvDZF#o- zeNS87u7A(dmbdHQ^|a;f`gc5SdAt5?Pg~xuf6LRBx9i`Ork-E_hNmrW*T3#*{C&;S z_`Ao``1`7-@%I%^iP9Ac^ZFrdK!OU^fdmy;A#Bb;c5JR z-qZN|oTu^kSx@8dc2DE)Gt$)a>$iCtf1ma={tkK?e+N8`zfXA@f1mU;{yyPp{C(Wh z`1_cr@pr2<_56C()A*}+8h>R^rY)5|6PCTy7=$=|tu0M5M{CEAS>*BxdPqpty{Lit&zb^jg*x_Fn|8wl{uZ#aVcKFxD{~Y!F zy7-@ChksrC&#}Y5F8=4(;a?a3bL{Z1i~l)x_}9h%96S8$;(v}E{&n#`#}5Cx_@CqY zhIR2jOFh3X{%6?_S{MJb><6uj|5^5f*2VuU`$6mCf0q5Ab@4yTe$cx3pJhL2UHs3o zAG9w1XW0*07yq;D2d#_$S@wh0#s4h(LF?jwmi?f0@juIc(7O1aWj|`>OS*~wb6aTYZ->@eBXW_@1_@CwahBfg&%k>Rw;(wOw z8`i}CEY~-ziT_!yZ&(xmvs~Y>CjMu+zF|%L&vJdkn)sjP`i3>}KMOzB#Q!YUH>`>O zS*~wb6aTYZ->@eBXSu#%P5jSteZ!jgpXK_7HSs^o^$ly{f0pYT*2MoT*Eg(*|5^C4 zCjMu+zF|%L&vJdkn)sjP`i3>}Kg;zEYvO;F>l@a@|18%xtcm|wu5VZq|Fc}*uqOUz zxxQgd{LjLVHSs^2tAzgl%dG!Dn$_pce5zxPopDLPFy~lj2Xjb(e^Qod))qBjRie^>sF`p`$RlUc2s%TdA z9`mW9S=D>Yr;27(?=hb$npM5We5z_xPMZN7|VRqqvTzKmv7?-gynjAm8u6>YwZW>xPMZN7|VRqrvMDwxPopDLPFy~lj2Xjb(e^Qod))qBjRie^>sF`p`$RlUc2s%TdA z9`mW9S=D>Yr;27(?=hb$npM5We5zxPopDLPFy~lj2Xm&!Mx9zBjX7_j+f2#MGPZiCo-eW#hG^=`#`Bc%Y z>OJODMYF2+m`@eWs@`KhRWz%5kNH&5tm-}HQ$@3?_n1!=&8psGK23QC;;O z^Qoe`>OJODMRnDC%%_U#s`r>r71dSmF`p``tKMTiRa95K$9$@&u6mF8R8d{^9`mW9 zy6QdVQ$=;vd(5Yb>ZZSG~u4s;I7dkNH$lUG*OGsiL~-J?2wI zb=7;!r;6&T_n1!=)m85?pDL=W-eW#hR9C&ne5$CfdXM>3QC;;O^Qoe`>OJODMRoC? z`BYI|{AWH@R2To5PZib0f96v~b@8A1R8d|0XFgR_7yp@071hOm=2Jy=@t^rrQC<9J zK2=l~|Cvt})y042Q$=<0pZotsb@88hMp0e-XP!}17yp@O6xGFl<{3qG@t=7{QC<9J zo>5d6|CwhL)y0428AWyRpLs@6UHoUBQB)WInP(K$#ee1*MRoC?c}7uP{AZp~R2To5 zXB5@Nf94rQb@88hMp0e-XP!}17yp@O6xGFl<{3qG@t=7{QC<9Jo>5d6|CwhL)y042 z8AWyRpLs@6UHoUBQB)WInP(K$#ee1*MRoC?c}7uP{AZp~R2To5XB5@Nf94rQb@88h zMp0e-XP!}17yp@O6xGFl<{3qG@t=7{QC<9Jo>5d6|CwhL)y0428AWyRpLs@6UHoUB zQB)WInP(K$#ee1*MRoC?c}7uP{AZp~R2To5XB5@Nf94rQb@88hMp0e-XP!}17yp@O z6xGFl<{3qG@t=7{QC<9Jo>5d6|CwhL)y0428AWyRpLs@6UHoUBQB)WInP(K$#ee1* zMRoC?c}7uP{AZp~R2To5XB5@Nf94rQr^J8e8AYeWf94rQr^J8e8AYeWf94rQr^J8e z8AYeWf94rQr^J8e8AYeWf94rQr^J8e8AYeWf94rQr^J8e8AYeWf94rQr^J8e8AYeW zf94rQr^J8e8AYeWf94rQr^J8e8AYeWf94rQr^J8e8AYeWf94rQr^J8e8AYeW|K$FE ze>Al3a_s*#^w>Vz{eNNfwb8SqFO4=vUl^SoeP;Cd=;6^rqX%s7|Mcj- z(Sgi`%xjsmnU^w+%nO;>%rlwenZubww)1}`Go9I&85p@R^4iGRk(WjqBQK21jyyAR zeB`k0`#&%;GcrB0Z)9Nj!tiUuXNO-JZVbOLJUjf%@NwJqe`xr?@XYY^u>CK3=)%xz zLuZFx8fpx^Ff=>#jP3b9JalO2z|hRl^w7R^Fa3J@T>9m7GyP)v+4RZuqv<2*yVD2L z+4Obk{prC}FZFurTxL(!`wWtgusTmd0q*D4RiCn5&|3M=6NLqHq6cQN(gM2o9C4f*f2NGDyb=N%=H_`N1UAggb4mzon49O65ZEv`&nY3WVQ!vN zLSVz(Jg0=fhPio834slB^PCa_8|LOYB?LCi&2vf!Y?zzpln~f3H_s^{uwibVQ$k?F z+&rg*z=pYbP6>exbMu@M0vqP$x#K$pJR9cbIVA)(%*}I32yB>}=adlGFgMRBA+TX? zo>M|#!`wWlgkX7Z&fLHAa`dN~GxvGg+COu|(|rG7Ph0zE?)9{_f9Ct1w)W3_&(qfa zneTeq+CTFhPh0zEzU^si|ID|f3GbP2dK!P<@HGCu?rHpe&C~e1$J6-xs;BYy6;I>u zZcpRykf-tYWog2D<}Od;?@OM>-<_Vu-xocNzb|+if2!B%Pc>&$uhXAu&Zu6eKh>O3 zyq7oPvh^Pr}1~d)A;+8r}6hmPvh?sp2pwD zJ&nJQNn5^|Gq-vge^pQ8ui|O^l|7BWlBe-k^fdkop2lC^)A-AI8h=@7yFM~!W;~6* zk9rz^w|E+VH+vd?H+dR=AMrH)KJ01ysa~(z^^rNFdcA7bN9K&`^{QPTnKP=_t9E^4 z&Zu6m+Vzn+qk6q+*GJ~e`}BHtePqsD?`iy9=V|;+dm4Z5^)&vj^)&w8BW>45=FGc2 zjlXL=jlXw!8h=-N8h`KfH2$vgH2&Vow z72&x8o>zqD3V2=-o-5#aMR=}&=M~|(0-jfd=L&dU5uPjXV?}tbfaewAxdNV7gy#x) zUJ;%v;CV%Ou7Kwi;kg2ySA^#ZcwP~nE8uxWc&>ow72&x8KURe2id`R>l?QizpDK2J zWLAFUY5e`r)A;*=r}1~x)A)P9)A$qrEAV4Q{I9@|74g3UKUT#53jA0R|10ogMf|VW z^^sW-|0{NVWLCugid`R>74g4f*GFbW{IA&cky#P{D|UTkR>c2`T_2eh@xKB;R>c2` zT_2eh@xNl%M`lI*uh{jGSrPv$c7M&Ri2oJ4zh+j%|BBsTGb`eM#qO_}74g4f_t(sd z_+PR6Yi33KufUHL@xNmC*UXCeU$OgZW<~t3*!?xLBK}wG{+d}4|0{NX&8&$36}!J? zR>c2`-Cr{+;(rBxtcd>=_^~4XSK!Br_+Nn^E8>3zeyoW975K3t{#W3~iuhl#`)g)J z{IA&kHM1iASM2_pSrPv$c7M&Ri2oJ4zh+j%{|fwA5&tW8f6c6j{}sExW>&=iirrr` zE8>5}?ys2@@xNmC*UXCeU$OgZW<~t3*!?xLBK}wG{+d}4|0{NX&8&$375K3t{#We& znpqM5E7aR7;(x{NubCC`zhd{-%!>G5vHNRgMf|V8j}`I10zX#7{|fwA5&tXjV@3S0 z%v8hq|L?>4e`p|mA^lqVZ2F~iBmF{pHvLTcc=~YqQ2Ic6COw_rmmWx6NWGRin|dkL zNWGAnO+Ax3o;sX5lsb@_NlmBrr3MBs48AsamMi`@J$~7GAl~%&W$S@>)8m(|2jb1+ z%Kx?=h&Mfc*?J(}^!R1#fq2v7m#qilO^;u;9*8$Re%X2;-W0!>{}*qHU(ElDH^ndJ z|HYf)7xVw(P4SEQfAOaH#r(f`Q~YB7U%V-PG5;^#6u+4N7jKGR%>Row#V_Xn#hc<6 z^Z(*a@r(I?@uv92{J(fp{9^uJyeWP$|1aJYznK3QZ;D^c|BE-pFXsQno8lMq|Kd&Y zi}`=?rufDDzj#ypV*X#eDSk2kFWwZtnEw}VieJqCi#HGLeE!V;i#NqD=KsZ;;urJ( z;!W|3`G4`I_{IFccvJjh{$IQ)elh{}*qHU(ElDH^ndJ|HYf)7xVw(P4SEQ zfAOaH#r(f`Q~YB7U%V-PG5;^#6u+4N7jKGR%>Row#V_Xn#hc<6^Z(*a@r(I?@uv92 z{J(fp{9^uJyeWP$|1aJYznK3QZ;D^c|BE-pFXsQno8lMq|Kd&Yi}`=?rufDDzj#yp zD%0P#DSnmdZ`%~V%JjEw&gk>E^+3ESewA%K5O0cKWm^x#o8nj5)&udT_*J&`K)fk_ zm2Eu`Z;D@KTMxvW;#ZmewoUP?On=*^_*JIAZBzUz)8Do!ewFEO+kC(L+j=10e4nTB zcfF_acb%v4H|=Tsz1P$DyVleAdyl8__ij()?;20z?_JWi9*8%u_B8(9>1q63iY$c|?IU%WZ&Y5Wa&8h>d|<1giD{0({Pj{<=?l+WPB0 z|1a)}|IGi3yW&6d|KhIr&-}l*EB-V8FYb!}%>RqK;y?5M;;#75{J*#>{xknC?u!4+ z|BJigKlA_MuK3UVzql*@GygB{ivR9@#$EB>-Osoy{=54bcg25qKjW_W&-}l*EB-V8 zFYb!}%>RqK;y?5M;;#75{J*#>{xknC?u!4+|BJigKlA_MuK3UVzql*@GygB{ivP_2 zi@V}K^Z(+m_|N>mxGVlM|1a)}|IGi3yW&6d|KhIr&-}l*EB-V8FYb!}%>RqK;y?5M z;;#75{J*#>{xknC?u!4+|BJigKlA_MuK3UVzql*@GygB{ivP_2i@V}K^Z(+m_|N>m zxGVlM|1a)}|IGi3yW&6d|KhIr&-}l*EB-V8FYb!}%>RqK;y?5M;;#75{J*#>{xknC z?u!4+|BJigKlA_MuK3UVzql*@GygB{ivP_2i@V}K^Z(+m_|N>mxGVlM|1a)}|IGi3 zyW&6d|KhIr&-}l*EB-V8FYb!}%>RqK;y?5M;;#75{J*#>{xknC?u!4+|BJigKlA_M zuK3UVzql*@GygB{ivP_2i@V}K^Z(+m_|N>mxGVlM|1a)}|IGi3yW&6d|KhIr@9t;Z z760A+jJx8$yPt7a{CD>=?u!5Je#Tw#-`&r+EB?Ft8F$5hcR%B<`0ws#+!g=b{fxWf zzq_AtSNwPPGwzE2?taEy@!#FgxGVm<`x$q|e|JCQuK4fnXWSM4?fgG?W;`&k-~O4k zUuFAMv0p{|RkB|nvtPH`FTU?1_Ujh=RkdF?+pnAKSKfYo)PBv_uMgX=A^Vm7XYl8g z{h8O>uW9>rt^L~dHOBt(STy$J*n?x=9{b|h$H#6SyLN1^J^k;EzCLJz zj-DKSbo9vR-J=Ibvv%^|{?WlqFY|ilT;}CWGxK8R+04nzqnRU_yE6yv+`sEG`!jwy?jAZglpVTmX#ddQpX>Sm zoB-?2|K|i)cm6*oz`FDQIRVz4|IZ1q?)-mFfOY5pa{{b8|DO|J-TD8V0PD{G=LA@H z{y!(cy7T`z0oI-W&k3;Z{C`e>b?5(c0<1g#pA%r+`Tv{%>(2k@1Xy?eKPSMt^Zz*k z)}8;)39#<`e@=jP=l^p8tULdo6JXu>|C|8p&j05GSa<$EC&0S%|2YBHo&V1Xu1OL6JWVu&ddq0Trg+m1XwPZGjjqg7tEPC0hSBq%$xwr1#@OjfaQWYGbg}u!JL^B zV7Xw<%n7huFlXijST2||a{??E%$Yd>mJ8<0oB+!Ob7oF}<$^ggC%|&SoS73~xnR!B z39wu+XXXT0E|@cO0xTEInK=QL3+Bw60Luk)W=??Rf;lrMz;eNynG;~SV9v}5uv{=_ z<^)(Sm@{(%EEmj~IRTan=FFS`%LQ|0PJrctIWs4~a>1OL6JWVu&ddq0Trg+m1XwPZ zGjjqg7tEPC0hSBq%$xwr1#@OjfaQWYGbg}u!JL^BV7Xw<%n7huFlXijST2||a{??E z%$Yd>mJ8<0oB+!Ob7oF}wHM4;Exs3<8R8- z_?z@J{w6$)zdh0%FwBj68h>M+#^0!?@t5&5{zg2FzhO_~Z^+a5OM4oBDNo~XP?`hk zxdBgGf2W`JwDouTDNkE}r+@8f>+kfhJZ=4*{-vj_ztg|)wDouT=bpCyPCx1CnLXz8 z&#c~_?P*7TOm}J4qM0q{iP3VtUNSKvF5 zxPsn^#1-&PB(7k0B5?(}6NxLxy)ErXRdX6}ClXh1JCV2o+lj;#)J`O>fOaBr1+x>0 zE0CQ?TtVza;tF6V5?AngTiTJT<}|oYB(9)!B5?(*6NxKWok(1P>O|rSQYR8ufI5-5 zg42n_6_`%s%(yuXrTZgQ&1o3Dtt$382)(V!R>9|ORk8{?Z>yqJuz6b*tb)wjDsL5B z-c~uQpz^lLS_PB0)yzB1X^1>vr&(oZZl1~7|4q-#-0J@KZgbkwdF;ykkB{8{lQ($Y z{#{G!u{Zp?_Bl)LH-2u+oVFAnyK;b^YlTI4BJ3+#e((N@_Ib`nD z-<$^RSKfBwu_MQ<`SQ&(m78;w>6zTEh3u{QnOp4rI_)LH1#8qIfAkICgnc=S|Iu9o z!1;fe|9{!e|2GY% zR76#9r6Q_=D-}@`s|^)VWn8I#1*AfB5_46l}KDsOeGRm zR8xt>73EYSab+v0zQmO+nEDb|wnpkpT-mZHkrb;9TNw2vu54-4m$uk=^xGOCmD!|ILz!%=~|| zBqB5a-zOq_A~N&;&60@B{C~3~A~XNrEQ!d>|2In_GV}kOq_ zA~N&;&60@B{C~3~A~XNrEQ!d>|2In_GV}k?)s`Fklfe! zgUN|z`+5l|_ci{Ya$n;QEcZ43;BsH%4>0#N{vdN-6F<=0*TfGt_cieY&V7wP=$vS_ zub04cU*iux_ci_ibYJ5SLiaWPKy+W@4@UPj{(y8};}1&rHU7YKU*iu>Cz|c+B|zQR z_=D7ajXzM`*Z70geT_e0-Pibo)_sjXaNXDVgV%kHKY-oW_=DJqX8U>xWcM}xV0K^Q z4`}x_{-AbW;}2~2HU8jsU*ivO_ci_?cVFWVboVv>V0WU~zFq>}eT_fp-Pia7-+hfg z_}$m|1K@p)KM3B}_ygg6jXxOP*Z2eCeT_dTo@iDCOJKaO@dwBI8h?Piuki=T`x<|s zysz;G%ljICz`U>V2hIB$f8e~Y@dwWn&5B?Np!YTYAbMZp52W`s{$P4v;}59!HU6M_ zU*iv~_ci|DdSBxYu=h3oAp5p<*HOsb;t})z&9ZpJ{C~479x?ylEQ?3X|2NCx5%d4evUtS&f3qweG5_Bz zi$~1=H_PG?^Z(7Vc*OjFvn(Dl|KBW&N6h~>%iOsb z;t})z&9ZpJ{C~479x?ylEQ?3X|2NCx5%d4evUtS&f3qweG5_Bzi$~1=H_PG?^Z(7V zc*OjFvn(Dl|KBW&N6h~>%iOsb;t})z&9ZpJ{C~47 z9x?ylEQ?3X|2NCx5%d4evUtS&f3qweG5_Bzi$~1=H_PG?^Z(7Vc*OjFvn(Dl|KBW& zN6h~>%iOsb;t})z&9ZpJ{C~479x?ylEQ?3X|2NCx z5%d4evUtS&f3qweG5_Bzi$~1=H_PG?^Z(7Vc*OjFvn(Dl|KBW&N6h~>%iOsb;t})z&9ZpJ{C~479x?ylEQ?3X|2NCx5%d4evUtS&f3qwe zG5_Bzi$~1=H_PG?^Z(7Vc*OjFvwX!4pP2t|miK!afBQU*zrCKu-;}5EH|c5oO?VoA zdpwQ5aZlrKOqzOrdDPSR%Xk`pBc8_Ju&41iS_EvAq_v8 zCp?Y6$32a|$2^U{M?HFzaMxSe@8uyzXv>xzxzFnzxzCmza!G{qj}iV_`BEB_!Iw`|8JV&KlA@hQ~YQC zziEp9%>Oq{@t^tsrYZh2|KBvlf9C(2rufhNf72BIng4H^;y?5MO;h}5{=aF8|IGh4 zP4S=k|E4MayLQH=`0v^oo8rG~XKaf9uAQ+d{=0U@rugsL8Jpt2YiDeV|E`^}DgL{5 z#-{l1+8LYTziVe~ivO;iu_^w$cE+ao@7fug;=gNWY>NM`ov|tYyLQH=`0v^oo8rG~ zXKaf9uAQ+d{=0U@rugsL8Jpt2YiDeV|E`^}DgL{5#-{l1+8LYTziVe~ivO;iu_^w$ zcE+ao@7fug;=gNWY>NM`ov|tYyLQH=`0v^oo8rG~XKaf9uAQ+d{=0U@rugsL8Jpt2 zYiDeV|E`^}DgL{5#-{l1+8LYTziVe~ivO;iu_^w$cE+ao@7fug;=gNWY>NM`ov|tY zyLQH=`0v^oo8rG~XKaf9uAQ+d{=0U@rugsL8Jpt2YiDeV|E`^}DgL{5#-{l1+8LYT zziVe~ivO;iu_^w$cE+ao@7fug;=gNWY>NM`ov|tYyLQH=`0v^oo8rG~XKaf9uAQ+d z{=0U@rugsL8Jpt2YiDeV|E`^}DgL{5#-{l1+8LYTziVe~ivO;iu_^w$cE+ao@7fug z;=gNWY>NM`ov|tYyLQH=`0v^o8{)rfXKaZ7uAQ+V{=0U@hWH=m|NoxM|NHY?|1T;Z za=n~cR6gW-IkTvI$n|n&QTdST<;gb7L^aVUd}8kA9B5% zSyVpcdO5SGe8}~3W>NW&>*dU%@*&sDnMLJ8u9q{5%7xva%NHakn82lqVgfv%b7*xL#~%Ii^_*wFJ~5&54m2>EGi#zy_{K8KID2i zv#5N?^>SuW`H<`7%%buk*UOnjgb7L^aVUd}8kA9B5%SyVpcdO5SGe8}~3 zW>NW&>*dU%@*&sDnMLJ8u9q{5%7qHn9rHB)9`-c;9`ZE)ezK#vUd}B1*wgrX(9`()k*D$ZLr>%H z2cE{?QBULV0Z-%aeoy1?K2PKCh&1~d3x_?8zk5B6zwdh*f8X;o{=VyJ{C&sM`1`h} z@%JrH?P>fS z^fdkscp877@-+TF>1q6Z!qfQsxTo>=F;C;~R!`%vDh)ptDxSt)+0*zdc^ZF3PvfuP zY5e6qjlZ0y@t5^9{$@OlKk=XYtC$7xpZlwr1@WKztC$7xpZlwr1@WKztC$7xpZlwr z1@WKztC$7xpZlwr1@WKztC$7xpZlwr1@WKztC$7xpZlwr1@WKztC$7xpZlwr1@WKz ztC$7xpZlwr1@WKztC$7xpZlwr1@WKztC$7xpZlwr1@WKztC$7xpZlwr1@XV=_#yrm z9Y4f>?yq7N#DDIuViv@I?yq7N#DDIuViv@I?yq7N#DDIuViv@I?yq7N#DDIuViv@I z?yq7N#DDIuViv@I?yq7N#DDIuViv@I?yq7N#DDIuViv@I?yq7N#DDIuViv@I?yq7N z#DDIuViv@I?yq7N#DDIuViv@I?yq7N#DDIuViv@I?yq7N#DDIuV&=tv?yq9z#eeRv zV&=tv?yq9z#eeRvV&=tv?yq9z#eeRvV&=tv?yq9z#s32P;q&4@_g69V;y?FSG4tX- z_g69V;y?FSG4tX-_g69V;y?FSG4tX-_g69V;y?FSG4tX-_g69V;y?FSG4tX-_g69V z;y?FSG4tX-_g69V;y?FSG4tX-_g69V;y?FSG4tX-_g69V;y?FSG4tX-_g69V;y?FS zG4tX-_g69V;y?FSG4tX-_g69V;y?FSG4tX-_g69V;y?FSG4tX-_g69V;y?FSG4tX- z_g69V;y?FSG4tX-_g69V;y?FSG4tX-_g69V;y?FSG4tX-_g69V;y?FSG4tX-_g69V z;y?FSG4tX-_g69V;y?FSG4tX-_g69V;y?FSG4tZTy}wGB|96?q|1(SCg`1bVBwo0A zxl7`Oo0q#JUbuO=OX7u_m%AihxOurt;)R=+yChz?dAUpCg`1bVBwo0Axl7`Oo0q#J zUbuO=OX7u_m%AihxOurt;)R=+yChz?dAUpCg`1bVBwo0Ax&MEA=anQ&Z=BH$@Il^t ziQcoirf<=EFNvhQ_ui4z8W542DJY_W>g5b-DXNnX_h1K7F#dVVw~U%-ocxgZGXFn8vr|ldpE0K1uAiP_^83^jliw$&nEbXWCcigROn&z%Ccl>{ zCckxx$?rDBfmH*6FEmi(AU$s>E&wSNVj<{D0xTW|#lW zS1r5zXTECLIeL(ajGBi zr^cy%z@HkY`T>7xoazVssd1_w@TbP9e!!m^r}_bZYMkl^{HbxOAMmHfseZtp8mIaJ ze`=iS2mGmVsvq#D#;Jb5pBkt70e@IeL(ajGBir^cy%VEIe4!#i@Q^|6iOx z@m5c4>}xoGe2U5M$EKM4)DPRGC*o8;Y?q#hQ~j`AdLmBs!*=P3IMol^r6=N4KWvwt zh*SNrU3wx;^}}}Qi8$2{+odPsR6lH&o`_TZuw8m0PW8if>4`Yi58I_D;#5Cum!61I z{jgnnB2M+gcIk;2>WA&p6EV~e+odOBs2{dVPsC6^Y?q#hp?=sdJrP6wuw8m0hWcT< z^h6Bx1N;ACs2|w>7eoEP{=XRN2loHPP(QH$FNXSo{eLlj=>PZ96ES`;#pL(>DJDPl z!*=P380v@Z(i1V%58I_DVyGXsOHag5KWvwth@pPiE4_NX zhwai6G1L#+r6*#jAK3pFL;b-1zZmKV_W#9DKd}EVhWdg1e=*b#?Ej0QeqjG!4D|#1 z|6-^g*#8$p{lNae7~k{%%e?LJ-6f&G6m)DP_ci=lpC z|6dIC1N;ACs2}KO#85xb&xoOZpq~*#{Xjn>hWdeiMhx`>{frpu2l^Q?)DQGCVyGYJ zXT(rH(9ejWexRQbL;XNMBZm5cent%S1O1E`>IeE6G1L$AGh(P8=x4-GKhV#Jp?;vB z5kvhzKO=_vfqq5|^#lEk80rW588PHP{frp$pMFLR`A1V`{ z|MW9r$bb47G2}n}j2QBtent%WPd_7u{HLE0L;lmxh#~*!XT*^I^fO|}fBG3Q1V`{ z|MW9r$bb47G2}n}j2QBtent%WPd_7u{HLE0L;lmxh#~*!XT*^I^fO|}fBG3QS^>SDv14?EfoI z&o}n}m8a($`~S+*^Nsy~<>~px{=f3{d}IG#d3wIF|F1kf-`M|Go}O>)|0_?=H}?OP zr{^2{|H{+zjs1V+>G{U~zw-2aWB*@ydcLv$uRJ~9*#B3ao^R~`D^Jfi_WzZq=NtR~ z%G2|W{eR`@`Nsag^7MRT|6h4}zOnzWJU!po|5u)#Z|wgohvysn|H|R{#{R!@c)qd! zuNiF-s z^=kH~jvr1j`Tbyu$?yA9e0{&;zoz*5e#d`K@%8?izdxU1^82$XCci(OV)FZwDJH)^o?`O*qbVl8Kb&In`vYV8Q^)U5G5P)8 z6qDcgrkMP`JH_Ppohc^2-<@Le`<*E!zu%r>^85A_li#3OnzUSV)FZfG5x9I^HWTIpPORx`|K2x-)E+n{60O! zlBmUZHmcnnPT$$#1xa?$ETS5J~qYV z_t7aPzmH5Y`F+?JejFc~V)Fao6qDZvrkMQRKgHztz9}ZZ_f9eSy=RKa@7+^Oe)2#2 zQ-}P|{?sA=vp;pn|Ljj4@<01ihy2g})FJ<~KXu6e>`xu?Kl@XM{LlW>A^)>Kb;$qh zPaX1~{eR_<|LJEu1RCTfBG2@`JaBqL;k0q@sR)NXFTM8 z`WX-TpMJ(e{->YukpJmtJmi1+84vlNe#S%or=RhV|LJEu1RCTfBG2@`JaBqL;k0qvCIGTGj{o(e#S2U)6dxDfBG4_{7*k)m;dQ!?D9YTj9vbx zpRvpT^fPw(pMJ(J|I^Rd<$wAayZlc-W0(KwXYBGn{fu4yr=PLQ|MW9<`JaBqF8|Zd z*yVrv8N2*XKVz5w>1XWnKmCkd{->X@%m4HGrOSWz|CKKP+5cC%{Ad4P z>GGfbf2GTR_WzYG|Jnany8LJVU+MCn{ePv)fA;^CF8|s8SGxRX|6l3ypZ$NO%YXL& zl`j9;|5v*FzxMyV^Zx%w?frkZo?FqA-Fj|CPj>6M6+PLl=T`J&x1L+klihl5MNf9? zxfMOxt>;$sWVfDM(UaYJZbeUa>$w#@*{$bR^klc5ThWua z)^jWG9lQ11%6rFdJ-71Sv0Klrym#!@b1Uy1yY<}4d&h1)xANYxThFb$ckI@4EAJh< z_1wyP$8J5h^4_sq&t1zruGo5R<-KFKo?ChE*sbSQ-aB^dxs~^h-Fj|CPj>6MmG_R_ zdT!;tW4E4LdGFY*=T_c3cI&xo*T@xH&#k<7?ACKD?;X4K+{$~$Zaug1-mzQHr9ZV> z&!s=LThFCGwOh}nKeb!Wr9ZV>&!s=LThFCGwOh}nKeb!Wr9ZV>&!s=LThFCGwOh}n zKeb!Wr9ZV>&!s=LThFCGwOh}nKeb!Wr9ZV>&!s=LThFCGwOh}nKeb!Wr9ZV>&!s=L zThFCGwOh}nKebuUr9ZV<&!s=LSs)^zo0)J@_#{pJmmj^{&>j$1^w}m{|ox#A^#Wj$3y-v z=#Pi|U(g>9`M;n)9`b)de>~*>g8q2O{{{W=kpBz%<01bS^v6T~FX)el{9n)?5Ba~K zKOXXbL4Q2t|APK_$o~cX@sR%u`r{%07xc$N{x9f{hx}jA9}oGzpg$h+e_7Z61)!li Al>h($