From fbd63efa89ab90f28f0bb8f145f39b109908bb62 Mon Sep 17 00:00:00 2001 From: Mikhalkovich Stanislav Date: Sun, 3 Nov 2024 16:59:48 +0300 Subject: [PATCH] =?UTF-8?q?NewSets=20=D0=9D=D0=B5=D0=BA=D0=BE=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D1=8B=D0=B5=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D0=BD?= =?UTF-8?q?=D0=B0=D0=B4=D0=BE=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Configuration/GlobalAssemblyInfo.cs | 2 +- Configuration/Version.defs | 4 +- Localization/DefaultLang.resources | Bin 102244 -> 102037 bytes StringConstants/StringConstants.cs | 4 +- TestSuite/arrayofset2.pas | 2 +- TestSuite/nested2.pas | 2 +- .../SystemLib/SystemLibInitializer.cs | 4 +- .../convertion_data_and_alghoritms.cs | 4 +- .../TreeConversion/syntax_tree_visitor.cs | 270 +++++++++++---- TreeConverter/TreeRealization/type_table.cs | 3 +- bin/Lib/PABCExtensions.pas | 206 +++++++++++- bin/Lib/PABCSystem.pas | 308 ++++++++++++++++++ bin/PascalABCNET.chw | Bin 141066 -> 143330 bytes bin/TestRunner.exe | Bin 47616 -> 49664 bytes 14 files changed, 728 insertions(+), 81 deletions(-) diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index 0a5ea77f6..2ed178f6e 100644 --- a/Configuration/GlobalAssemblyInfo.cs +++ b/Configuration/GlobalAssemblyInfo.cs @@ -15,7 +15,7 @@ internal static class RevisionClass public const string Major = "3"; public const string Minor = "10"; public const string Build = "0"; - public const string Revision = "3552"; + public const string Revision = "3555"; public const string MainVersion = Major + "." + Minor; public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision; diff --git a/Configuration/Version.defs b/Configuration/Version.defs index 62ba1afa9..02975e3e2 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ -%COREVERSION%=0 -%REVISION%=3552 %MINOR%=10 +%REVISION%=3555 +%COREVERSION%=0 %MAJOR%=3 diff --git a/Localization/DefaultLang.resources b/Localization/DefaultLang.resources index a43b04c94a0905098a13b408d974ecb27d88b4db..3a7dc55fd4819149f25fba0007d390d4d8dee6da 100644 GIT binary patch delta 24 gcmaDdk8SE)wh0fIHui3O^w+O>UBLEr0gT)10HCT2dH?_b delta 219 zcmbO_m+i?swh0fI8u~Uq`s-(xnx0u)l3L`Lm*SkCS5lOp6OdDyo|&hYl32par5X_A z>gE}tYRk)|uO9?es*sqMq5xGqIgnAJKFHPGGdRRGDBjV}CEnTJFC@s{CqBR@)ZNoB zo|ntd(bv`Xz@ty^KD>DT;M!OlUR0U@6Le#jD53Xi_Nd!q36slub*@87+C k`}C~>FPEEtkT0eQyj)-hmFAUX=B743_22%~pK*g708M9O6#xJL diff --git a/StringConstants/StringConstants.cs b/StringConstants/StringConstants.cs index 3958ded8b..5c834a805 100644 --- a/StringConstants/StringConstants.cs +++ b/StringConstants/StringConstants.cs @@ -248,8 +248,8 @@ public static string get_pointer_type_name_by_type_name(string type_name) public static string subtract_of_set = "Subtract"; public static string in_set = "InSet"; public static string CreateSetProcedure = "CreateSet"; - public static string IncludeProcedure = "Include"; - public static string ExcludeProcedure = "Exclude"; + //public static string IncludeProcedure = "Include"; + //public static string ExcludeProcedure = "Exclude"; public static string DiapasonType = "Diapason"; public static string CreateDiapason = "CreateDiapason"; public static string CreateObjDiapason = "CreateObjDiapason"; diff --git a/TestSuite/arrayofset2.pas b/TestSuite/arrayofset2.pas index 843c56921..0fc90ff92 100644 --- a/TestSuite/arrayofset2.pas +++ b/TestSuite/arrayofset2.pas @@ -1,4 +1,4 @@ -const c : array of set of char = (['a','b'],[],['k','l']); +const c : array of set of char = (['a','b'],[],['k','l']); var a : array of set of char := (['a','b'],[],['k','l']); b : array of set of 1..4 := ([1,2,7],[2,3],[]); d : array[1..3] of set of 1..4; diff --git a/TestSuite/nested2.pas b/TestSuite/nested2.pas index 9b4bf36fb..dc42f5cd9 100644 --- a/TestSuite/nested2.pas +++ b/TestSuite/nested2.pas @@ -1,4 +1,4 @@ -type TClass = class +type TClass = class procedure Meth; end; diff --git a/TreeConverter/SystemLib/SystemLibInitializer.cs b/TreeConverter/SystemLib/SystemLibInitializer.cs index b0d2a44e3..8e04ae611 100644 --- a/TreeConverter/SystemLib/SystemLibInitializer.cs +++ b/TreeConverter/SystemLib/SystemLibInitializer.cs @@ -263,8 +263,8 @@ public class initialization_properties public static UnitDefinitionItem SetSubtractProcedure; public static UnitDefinitionItem InSetProcedure; public static UnitDefinitionItem CreateSetProcedure; - public static UnitDefinitionItem IncludeProcedure; - public static UnitDefinitionItem ExcludeProcedure; + //public static UnitDefinitionItem IncludeProcedure; + //public static UnitDefinitionItem ExcludeProcedure; public static UnitDefinitionItem DiapasonType; public static UnitDefinitionItem CreateDiapason; public static UnitDefinitionItem CreateObjDiapason; diff --git a/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs b/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs index 4ff5d9398..575f0b361 100644 --- a/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs +++ b/TreeConverter/TreeConversion/convertion_data_and_alghoritms.cs @@ -1893,7 +1893,9 @@ private void check_single_possible_convertion(ILocation loc,possible_type_conver { if (ptc.first.from is null_type_node || ptc.second.to == null || ptc.second.from is null_type_node || ptc.second.from.is_generic_parameter) continue; // SSM 9/12/20 fix 2363 - AddError(new PossibleTwoTypeConversionsInFunctionCall(loc,ptc.first,ptc.second)); + if (ptc.first.from == ptc.second.from && ptc.first.to == ptc.second.to) // SSM fix 03/08/24 - непонятно, как до этого могло дойти + continue; + AddError(new PossibleTwoTypeConversionsInFunctionCall(loc,ptc.first,ptc.second)); } } diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index ab4dec249..479a1d84e 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -313,8 +313,8 @@ private void release_system_module() SystemLibrary.SystemLibInitializer.InSetProcedure = null; SystemLibrary.SystemLibInitializer.CreateSetProcedure = null; SystemLibrary.SystemLibInitializer.TypedSetInitProcedure = null; - SystemLibrary.SystemLibInitializer.IncludeProcedure = null; - SystemLibrary.SystemLibInitializer.ExcludeProcedure = null; + //SystemLibrary.SystemLibInitializer.IncludeProcedure = null; + //SystemLibrary.SystemLibInitializer.ExcludeProcedure = null; SystemLibrary.SystemLibInitializer.DiapasonType = null; SystemLibrary.SystemLibInitializer.CreateDiapason = null; SystemLibrary.SystemLibInitializer.CreateObjDiapason = null; @@ -402,8 +402,8 @@ public static void init_system_module(common_unit_node psystem_unit) SystemLibrary.SystemLibInitializer.SetSubtractProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.subtract_of_set); SystemLibrary.SystemLibInitializer.InSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.in_set); SystemLibrary.SystemLibInitializer.CreateSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.CreateSetProcedure); - SystemLibrary.SystemLibInitializer.IncludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.IncludeProcedure); - SystemLibrary.SystemLibInitializer.ExcludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.ExcludeProcedure); + //SystemLibrary.SystemLibInitializer.IncludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.IncludeProcedure); + //SystemLibrary.SystemLibInitializer.ExcludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.ExcludeProcedure); SystemLibrary.SystemLibInitializer.DiapasonType = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.DiapasonType); SystemLibrary.SystemLibInitializer.CreateDiapason = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.CreateDiapason); SystemLibrary.SystemLibInitializer.CreateObjDiapason = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.CreateObjDiapason); @@ -496,8 +496,8 @@ public static void init_system_module_from_dll(dot_net_unit_node psystem_unit) SystemLibrary.SystemLibInitializer.SetSubtractProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.subtract_of_set); SystemLibrary.SystemLibInitializer.InSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.in_set); SystemLibrary.SystemLibInitializer.CreateSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.CreateSetProcedure); - SystemLibrary.SystemLibInitializer.IncludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.IncludeProcedure); - SystemLibrary.SystemLibInitializer.ExcludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.ExcludeProcedure); + //SystemLibrary.SystemLibInitializer.IncludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.IncludeProcedure); + //SystemLibrary.SystemLibInitializer.ExcludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.ExcludeProcedure); SystemLibrary.SystemLibInitializer.DiapasonType = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.DiapasonType); SystemLibrary.SystemLibInitializer.CreateDiapason = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.CreateDiapason); SystemLibrary.SystemLibInitializer.CreateObjDiapason = new SystemLibrary.UnitDefinitionItem(psystem_unit, StringConstants.CreateObjDiapason); @@ -3738,8 +3738,32 @@ public override void visit(SyntaxTree.record_const_definition _record_const_defi public override void visit(SyntaxTree.set_type_definition _set_type_definition) { - // throw new NotSupportedError(get_location(_set_type_definition)); - if (SystemLibrary.SystemLibInitializer.TypedSetType == null || SystemLibrary.SystemLibInitializer.CreateSetProcedure == null) + // PABCSystem.NewSet + // + var ntr = new named_type_reference(new List { new ident("PABCSystem"), new ident("NewSet") }); + type_node el_type = convert_strong(_set_type_definition.of_type); + + if (el_type.type_special_kind == SemanticTree.type_special_kind.diap_type) + { + if (el_type is common_type_node ctn) + el_type = ctn.base_type; + } + + /* Не буду это делать! + * if (el_type == SystemLibrary.SystemLibrary.byte_type + || el_type == SystemLibrary.SystemLibrary.sbyte_type + || el_type == SystemLibrary.SystemLibrary.short_type + || el_type == SystemLibrary.SystemLibrary.ushort_type + ) + el_type = SystemLibrary.SystemLibrary.integer_type; + */ + + var el_sem_type = new SyntaxTree.semantic_type_node(el_type, _set_type_definition.of_type.source_context); + var tpr = new template_param_list(el_sem_type); + var ttr = new SyntaxTree.template_type_reference(ntr, tpr); + ProcessNode(ttr); + + /*if (SystemLibrary.SystemLibInitializer.TypedSetType == null || SystemLibrary.SystemLibInitializer.CreateSetProcedure == null) AddError(new NotSupportedError(get_location(_set_type_definition))); type_node el_type = convert_strong(_set_type_definition.of_type); if (el_type.IsPointer) @@ -3748,7 +3772,7 @@ public override void visit(SyntaxTree.set_type_definition _set_type_definition) // AddError(new VoidNotValid(get_location(_set_type_definition.of_type))); check_for_type_allowed(el_type, get_location(_set_type_definition.of_type)); check_using_static_class(el_type, get_location(_set_type_definition.of_type)); - return_value(context.create_set_type(el_type, get_location(_set_type_definition))); + return_value(context.create_set_type(el_type, get_location(_set_type_definition)));*/ } public override void visit(SyntaxTree.known_type_definition _known_type_definition) @@ -5110,6 +5134,39 @@ private void add_set_initializer(expression_node cnfc, expressions_list exprs) set_intls[cnfc] = exprs; } + private System.Tuple convert_diap_for_new_set(SyntaxTree.diapason_expr _diapason_expr, out type_node elem_type) + { + expression_node left = convert_strong(_diapason_expr.left); + if (left is typed_expression) left = convert_typed_expression_to_function_call(left as typed_expression); + expression_node right = convert_strong(_diapason_expr.right); + if (right is typed_expression) right = convert_typed_expression_to_function_call(right as typed_expression); + internal_interface ii = left.type.get_internal_interface(internal_interface_kind.ordinal_interface); + if (ii == null) + { + AddError(new OrdinalTypeExpected(left.location)); + } + internal_interface iir = right.type.get_internal_interface(internal_interface_kind.ordinal_interface); + if (iir == null) + { + AddError(new OrdinalTypeExpected(right.location)); + } + type_node_list tnl = new type_node_list(); + tnl.AddElement(left.type); + tnl.AddElement(right.type); + elem_type = convertion_data_and_alghoritms.select_base_type(tnl, true); + if (elem_type == SystemLibrary.SystemLibrary.object_type) + AddError(new SimpleSemanticError(get_location(_diapason_expr), "BAD_DIAPASON_IN_SET_TYPE")); + // До этого момента совпадает с convert_diap_for_set + + // если элементы - какого то целого типа, то привести к типу integer + if (elem_type != PascalABCCompiler.SystemLibrary.SystemLibrary.char_type && elem_type != PascalABCCompiler.SystemLibrary.SystemLibrary.bool_type && !elem_type.IsEnum) + { + left = convertion_data_and_alghoritms.explicit_convert_type(left, PascalABCCompiler.SystemLibrary.SystemLibrary.integer_type); + right = convertion_data_and_alghoritms.explicit_convert_type(right, PascalABCCompiler.SystemLibrary.SystemLibrary.integer_type); + } + return Tuple.Create(left, right); + } + private expression_node convert_diap_for_set(SyntaxTree.diapason_expr _diapason_expr, out type_node elem_type) { expression_node left = convert_strong(_diapason_expr.left); @@ -5175,24 +5232,25 @@ private expression_node convert_diap_for_set(SyntaxTree.diapason_expr _diapason_ public override void visit(SyntaxTree.pascal_set_constant _pascal_set_constant) { - //throw new NotSupportedError(get_location(_pascal_set_constant)); - if (SystemLibrary.SystemLibInitializer.TypedSetType == null || SystemLibrary.SystemLibInitializer.CreateSetProcedure == null) - AddError(new NotSupportedError(get_location(_pascal_set_constant))); + // надо разбить на 2 списка констант expressions_list consts = new expressions_list(); - type_node el_type = null; - type_node_list types = new type_node_list(); + expressions_list consts_diap = new expressions_list(); + + type_node el_type = null; // вывод самого общего типа элемента + type_node_list types = new type_node_list(); // этот список - единый. Он нужен только для вывода самого общего типа if (_pascal_set_constant.values != null && _pascal_set_constant.values.expressions != null) foreach (SyntaxTree.expression e in _pascal_set_constant.values.expressions) { - if (e is SyntaxTree.nil_const) - ErrorsList.Add(new SimpleSemanticError(get_location(e), "NIL_IN_SET_CONSTRUCTOR_NOT_ALLOWED")); - else - if (e is SyntaxTree.diapason_expr) + if (e is SyntaxTree.nil_const) + AddError(new SimpleSemanticError(get_location(e), "NIL_IN_SET_CONSTRUCTOR_NOT_ALLOWED")); + else + if (e is SyntaxTree.diapason_expr) { - expression_node en = convert_diap_for_set((e as SyntaxTree.diapason_expr), out el_type); - consts.AddElement(en); + var pair = convert_diap_for_new_set((e as SyntaxTree.diapason_expr), out el_type); + consts_diap.AddElement(pair.Item1); + consts_diap.AddElement(pair.Item2); if (el_type.IsPointer) - ErrorsList.Add(new SimpleSemanticError(get_location(e), "POINTERS_IN_SETS_NOT_ALLOWED")); + AddError(new SimpleSemanticError(get_location(e), "POINTERS_IN_SETS_NOT_ALLOWED")); types.AddElement(el_type); } else @@ -5200,57 +5258,116 @@ public override void visit(SyntaxTree.pascal_set_constant _pascal_set_constant) expression_node en = convert_strong(e); if (en is typed_expression) en = convert_typed_expression_to_function_call(en as typed_expression); if (en.type.type_special_kind == SemanticTree.type_special_kind.short_string) - en.type = SystemLibrary.SystemLibrary.string_type; + en.type = SystemLibrary.SystemLibrary.string_type; consts.AddElement(en); + if (en.type.IsPointer) + AddError(new SimpleSemanticError(get_location(e), "POINTERS_IN_SETS_NOT_ALLOWED")); types.AddElement(en.type); } } - type_node ctn = null; - if (consts.Count > 0) + // Константы и типы заполнены + // Выводим самый общий тип + + //type_node ctn = null; + if (types.Count > 0) { - el_type = convertion_data_and_alghoritms.select_base_type(types, true); + el_type = convertion_data_and_alghoritms.select_base_type(types, true); // !! if (el_type == null) AddError(new SimpleSemanticError(get_location(_pascal_set_constant), "IMPOSSIBLE_TO_INFER_SET_TYPE")); - - ctn = context.create_set_type(el_type, get_location(_pascal_set_constant)); - - } - else ctn = SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node; - - /*if (el_type == SystemLibrary.SystemLibrary.string_type) - { - for (int i = 0; i < consts.Count; i++) - if (consts[i].type == SystemLibrary.SystemLibrary.char_type) - { - consts[i] = convertion_data_and_alghoritms.convert_type(consts[i], el_type); - } - } */ // Не работает ! SSM 19.03.19 - - expressions_list consts_copy = new expressions_list(); - consts_copy.AddRange(consts); - - function_node fn = convertion_data_and_alghoritms.select_function(consts, SystemLibrary.SystemLibInitializer.CreateSetProcedure.SymbolInfo, (SystemLibrary.SystemLibInitializer.CreateSetProcedure.sym_info is common_namespace_function_node)?(SystemLibrary.SystemLibInitializer.CreateSetProcedure.sym_info as common_namespace_function_node).loc:null); - - - if (fn is common_namespace_function_node) - { - common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, get_location(_pascal_set_constant)); - add_set_initializer(cnfc, consts_copy); - cnfc.ret_type = ctn; - for (int i = 0; i < consts.Count; i++) - cnfc.parameters.AddElement(consts[i]); - return_value(cnfc); + // Делаю невозможным базовый тип object - не нравится это, и в массивах нет + if (el_type == SystemLibrary.SystemLibrary.object_type) + AddError(new SimpleSemanticError(get_location(_pascal_set_constant), "IMPOSSIBLE_TO_INFER_SET_TYPE")); + // если есть диапазоны, то базовый тип не может быть int64 и проч - только integer!!! + if (consts_diap.Count > 0) + if (el_type != PascalABCCompiler.SystemLibrary.SystemLibrary.char_type + && el_type != PascalABCCompiler.SystemLibrary.SystemLibrary.integer_type + && el_type != PascalABCCompiler.SystemLibrary.SystemLibrary.bool_type + && !el_type.IsEnum) + AddError(new SimpleSemanticError(get_location(_pascal_set_constant), "IMPOSSIBLE_TO_INFER_SET_TYPE")); + } + + // Теперь базовый тип известен (он может быть null), и надо сгенерировать + // EmptySet + // NSet(consts) или + // NSet(Arr(consts), Arr(consts_diap)) + // и обойти его + // Для el_type, consts и consts_diap надо делать обёртку semantic_type_node + // и semantic_addr_value (тут не знаю - это константы вроде, хотя там к expression_node приводится так что всё хорошо) + // new semantic_addr_value() + + var p = _pascal_set_constant; + var psc = p.source_context; + if (el_type == null) + { + var dn = new dot_node(new ident("PABCSystem", psc), new ident("EmptySet", psc)); + ProcessNode(dn); + } + else if (consts_diap.Count == 0) + { + // Это прямо очень хорошо! Просто вызываем NSet(consts) + var nset_type = new semantic_type_node(el_type, psc); + var dn = new ident("__NewSetCreatorInternal", psc); + var td = new semantic_type_node(el_type, psc); + var tpl = new template_param_list(new List { td }, psc); + var method_name = new ident_with_templateparams(dn, tpl, psc); + var m_el = new expression_list(); + foreach (var el in consts) + m_el.Add(new semantic_addr_value(el, el.location)); + // Добавим все обёрнутые константы + var mc = new method_call(method_name, m_el, psc); + ProcessNode(mc); } else { - compiled_static_method_call cnfc = new compiled_static_method_call(fn as compiled_function_node, get_location(_pascal_set_constant)); - add_set_initializer(cnfc, consts_copy); - cnfc.ret_type = ctn; - for (int i = 0; i < consts.Count; i++) - cnfc.parameters.AddElement(consts[i]); - return_value(cnfc); + _pascal_set_constant = _pascal_set_constant; + // Ну теперь самый общий NSet(Arr(consts), Arr(consts_diap)) + var nset_type = new semantic_type_node(el_type, psc); + var dnNSetInt = new dot_node(new ident("PABCSystem", psc), new ident("__NSetInteger", psc)); + var dnNSetChar = new dot_node(new ident("PABCSystem", psc), new ident("__NSetChar", psc)); + var dnNSetEnum = new dot_node(new ident("PABCSystem", psc), new ident("__NSetEnum", psc)); + var dnNSetBool = new dot_node(new ident("PABCSystem", psc), new ident("__NSetBoolean", psc)); + + // PABCSystem.Arr нельзя использовать - кидает странную ошибку + var dnArr = new dot_node(new ident("PABCSystem", psc), new ident("Arr", psc)); + var td = new semantic_type_node(el_type, psc); + var tpl = new template_param_list(new List { td }, psc); + var method_name_Arr = new ident_with_templateparams(dnArr, tpl, psc); + + var m_el_Arr1 = new expression_list(); + foreach (var el in consts) + m_el_Arr1.Add(new semantic_addr_value(el, el.location)); + + var m_el_Arr2 = new expression_list(); + foreach (var el in consts_diap) + m_el_Arr2.Add(new semantic_addr_value(el, el.location)); + + + var cnt1 = new expression_list(new int32_const(m_el_Arr1.Count), p.values.source_context); + var cnt2 = new expression_list(new int32_const(m_el_Arr2.Count), p.values.source_context); + var arr1_init = new SyntaxTree.array_const(m_el_Arr1, p.values.source_context); + var arr2_init = new SyntaxTree.array_const(m_el_Arr2, p.values.source_context); + var new_arr1 = new new_expr(td, cnt1, true, arr1_init, p.values.source_context); + var new_arr2 = new new_expr(td, cnt2, true, arr2_init, p.values.source_context); + + //var mc1 = new method_call(method_name_Arr, m_el_Arr1, psc); + //var mc2 = new method_call(method_name_Arr, m_el_Arr2, psc); + + var m_el_NSet = new expression_list(); + m_el_NSet.Add(new_arr1); + m_el_NSet.Add(new_arr2); + method_call mc_NSet = null; + + if (el_type == PascalABCCompiler.SystemLibrary.SystemLibrary.integer_type) + mc_NSet = new method_call(dnNSetInt, m_el_NSet, psc); + else if (el_type == PascalABCCompiler.SystemLibrary.SystemLibrary.char_type) + mc_NSet = new method_call(dnNSetChar, m_el_NSet, psc); + else if (el_type.IsEnum) + mc_NSet = new method_call(dnNSetEnum, m_el_NSet, psc); + else if (el_type == PascalABCCompiler.SystemLibrary.SystemLibrary.bool_type) + mc_NSet = new method_call(dnNSetBool, m_el_NSet, psc); + else AddError(new SimpleSemanticError(get_location(_pascal_set_constant), "IMPOSSIBLE_TO_INFER_SET_TYPE")); + ProcessNode(mc_NSet); } - //return_value(new common_namespace_function_call_as_constant(cnfc,cnfc.location)); } public override void visit(SyntaxTree.array_const_new acn) @@ -7031,7 +7148,7 @@ internal void visit_method_call(SyntaxTree.method_call _method_call) } } } - else if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(sil) + /*else if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(sil) || SystemLibrary.SystemLibInitializer.ExcludeProcedure.Equal(sil)) { if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 2) @@ -7083,9 +7200,9 @@ internal void visit_method_call(SyntaxTree.method_call _method_call) AddError(en_cnfn.location, "EXPRESSION_IS_NOT_ADDRESSED"); return; } - } */ + } } - } + }*/ else if (SystemLibrary.SystemLibInitializer.IncProcedure.Equal(sil)) { expression_node bfcint = make_inc_call(sil?.FirstOrDefault(), _method_call.parameters, subloc2); @@ -8029,7 +8146,7 @@ private void CheckSpecialFunctionCall(List sil, expressions_list exp else ConvertPointersForWriteFromDll(exprs); } - else if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(sil) + /*else if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(sil) || SystemLibrary.SystemLibInitializer.ExcludeProcedure.Equal(sil)) { if (exprs.Count != 2) AddError(new NoFunctionWithSameArguments(FunctionName, loc, true)); @@ -8042,7 +8159,7 @@ private void CheckSpecialFunctionCall(List sil, expressions_list exp convertion_data_and_alghoritms.check_convert_type(exprs[1], element_type, exprs[1].location); else convertion_data_and_alghoritms.check_convert_type(exprs[1], exprs[0].type, exprs[0].location); if (!exprs[0].is_addressed) AddError(new ThisExpressionCanNotBePassedAsVarParameter(exprs[0])); - } + }*/ else if (SystemLibrary.SystemLibInitializer.InSetProcedure.Equal(sil)) { if (exprs.Count != 2) AddError(new NoFunctionWithSameArguments(FunctionName, loc, true)); @@ -15238,7 +15355,9 @@ private constant_node convert_strong_to_constant_node(expression_node expr, type if (csmc.type != null && csmc.type != SystemLibrary.SystemLibrary.void_type && (csmc.function_node.IsSpecialName && csmc.function_node.is_readonly || NetHelper.NetHelper.PABCSystemType != null && csmc.function_node.cont_type.compiled_type.Assembly == NetHelper.NetHelper.PABCSystemType.Assembly || !is_const_section)) constant = new compiled_static_method_call_as_constant(csmc, expr.location); } - else if (expr is common_namespace_function_call && SystemLibrary.SystemLibInitializer.CreateSetProcedure != null && (expr as common_namespace_function_call).function_node == SystemLibrary.SystemLibInitializer.CreateSetProcedure.sym_info as common_namespace_function_node) + else if (expr is common_namespace_function_call + && SystemLibrary.SystemLibInitializer.CreateSetProcedure != null + && (expr as common_namespace_function_call).function_node == SystemLibrary.SystemLibInitializer.CreateSetProcedure.sym_info as common_namespace_function_node) { common_namespace_function_call cnfc = expr as common_namespace_function_call; expressions_list exprs = get_set_initializer(cnfc); @@ -15255,6 +15374,23 @@ private constant_node convert_strong_to_constant_node(expression_node expr, type } constant = new common_namespace_function_call_as_constant(cnfc, loc); } + else if (expr is common_namespace_function_call cnfc1 + && cnfc1.function_node.attributes.Count > 0 + && cnfc1.function_node.attributes[0].attribute_type.name.ToLower() == "SetCreatorFunctionAttribute".ToLower() + ) + { + // Надо компоненты проверять на константность + constant = new common_namespace_function_call_as_constant(cnfc1, loc); + return constant; + } + else if (expr is common_namespace_function_call cnfc2 + && cnfc2.function_node.name.StartsWith("__NewSetCreatorInternal") + ) + { + // Надо компоненты проверять на константность + constant = new common_namespace_function_call_as_constant(cnfc2, loc); + return constant; + } else if (is_const_section_and_userfuncall && (expr is basic_function_call || expr is common_namespace_function_call)) // только в разделе const { AddError(loc, "CONSTANT_EXPRESSION_EXPECTED"); diff --git a/TreeConverter/TreeRealization/type_table.cs b/TreeConverter/TreeRealization/type_table.cs index a30cbde46..c24a0fe13 100644 --- a/TreeConverter/TreeRealization/type_table.cs +++ b/TreeConverter/TreeRealization/type_table.cs @@ -859,7 +859,8 @@ private static void add_conversion(possible_type_convertions ptc, function_node } else { - ptc.second = new type_conversion(fn); + if (ptc.first.convertion_method != fn) // SSM 04/08/24 !!! - это когда есть op_implicit(Typ): Typ + ptc.second = new type_conversion(fn); } ptc.from = from; ptc.to = to; diff --git a/bin/Lib/PABCExtensions.pas b/bin/Lib/PABCExtensions.pas index ad6c12794..595c9e67d 100644 --- a/bin/Lib/PABCExtensions.pas +++ b/bin/Lib/PABCExtensions.pas @@ -409,9 +409,9 @@ function SSet(s: set of T): SortedSet; Result += x; end;} -///-- -function operator implicit(a: array of integer): set of integer; extensionmethod := TypedSet.InitBy(a); {///-- +function operator implicit(a: array of integer): set of integer; extensionmethod := TypedSet.InitBy(a); +///-- function operator implicit(a: array of real): set of real; extensionmethod := TypedSet.InitBy(a); ///-- function operator implicit(a: array of string): set of string; extensionmethod := TypedSet.InitBy(a); @@ -433,9 +433,9 @@ function operator implicit(a: array of BigInteger): set of BigInteger; extension function operator implicit(a: array of decimal): set of decimal; extensionmethod := TypedSet.InitBy(a); ///-- function operator implicit(a: array of single): set of single; extensionmethod := TypedSet.InitBy(a); -} ///-- function operator implicit(a: array of T): set of T; extensionmethod := TypedSet.InitBy(a); +} //------------------------------------------------------------------------------ // Операции для procedure @@ -452,6 +452,206 @@ function operator*(n: integer; p: procedure): procedure; extensionmethod; Result := () -> for var i:=1 to n do p end; +// Важнейший для новых множеств !!! +procedure operator:=(var Self: NewSet; st: NewSet); extensionmethod; +begin + Self._hs := new HashSet(st.hs); +end; + +// Extension-vtnjls для новых множеств +function operator implicit(n: NewSet): NewSet; extensionmethod; +begin + foreach var x in n._hs do + Result._hs.Add(x); +end; + +function operator implicit(n: NewSet): NewSet; extensionmethod; +begin + foreach var x in n._hs do + Result._hs.Add(x); +end; + +function operator implicit(n: NewSet): NewSet; extensionmethod; +begin + foreach var x in n._hs do + Result._hs.Add(x); +end; + +function operator implicit(n: NewSet): NewSet; extensionmethod; +begin + foreach var x in n._hs do + Result._hs.Add(x); +end; + +function operator implicit(n: NewSet): NewSet; extensionmethod; +begin + foreach var x in n._hs do + Result._hs.Add(x); +end; + +function operator implicit(n: NewSet): NewSet; extensionmethod; +begin + foreach var x in n._hs do + Result._hs.Add(x); +end; + +function operator implicit(n: NewSet): NewSet; extensionmethod; +begin + foreach var x in n._hs do + Result._hs.Add(x); +end; + +function NSToInts(ns: NewSet) := ns._hs.Select(x -> integer(x)); +function NSToInts(ns: NewSet) := ns._hs.Select(x -> integer(x)); +function NSToInts64(ns: NewSet) := ns._hs.Select(x -> int64(x)); +function NSToInts64(ns: NewSet) := ns._hs.Select(x -> int64(x)); +function NSToBytes(ns: NewSet) := ns._hs.Select(x -> byte(x)); +function NSToBytes(ns: NewSet) := ns._hs.Select(x -> byte(x)); + +// и для массивов столько же +function operator=(a: NewSet; b: NewSet); extensionmethod := a._hs.SetEquals(NSToInts(b)); +function operator=(a: NewSet; b: NewSet): boolean; extensionmethod := b._hs.SetEquals(NSToInts(a)); +function operator=(a: NewSet; b: NewSet); extensionmethod := a._hs.SetEquals(NSToInts64(b)); +function operator=(a: NewSet; b: NewSet): boolean; extensionmethod := b._hs.SetEquals(NSToInts64(a)); + +function operator=(a: NewSet; b: array of byte); extensionmethod := a._hs.SetEquals(b.Select(x -> integer(x))); +function operator=(a: array of byte; b: NewSet): boolean; extensionmethod := b = a; +function operator=(a: array of int64; b: NewSet); extensionmethod := a.ToHashSet.SetEquals(NSToInts64(b)); +function operator=(a: NewSet; b: array of int64): boolean; extensionmethod := b = a; + +//function operator=(a: NewSet; b: NewSet); extensionmethod := a._hs.SetEquals(NSToInts64(b)); +//function operator=(a: NewSet; b: NewSet): boolean; extensionmethod := a = b; + +// Следующие функции предназначены для сравнения массива целых со множеством. +// Массив должен интерпретироваться как множество +// Не пойму - что использовать - эту строку или предыдущие. Все типы массивов сравнивать с NewSet +// или наоборот все типы множеств - с array of integer +function operator=(a: NewSet; b: array of integer): boolean; extensionmethod := NSToInts(a).ToHashSet.SetEquals(b); + +function operator<>(a: NewSet; b: NewSet); extensionmethod := not(a = b); +function operator<>(a: NewSet; b: NewSet); extensionmethod := not(a = b); +function operator<>(a: NewSet; b: NewSet); extensionmethod := not(a = b); +function operator<>(a: NewSet; b: NewSet); extensionmethod := not(a = b); +//function operator<>(a: NewSet; b: NewSet); extensionmethod := not(a = b); +//function operator<>(a: NewSet; b: NewSet); extensionmethod := not(a = b); + +function operator<(a: NewSet; b: NewSet); extensionmethod := a._hs.IsProperSubsetOf(NSToInts(b)); +function operator<(a: NewSet; b: NewSet); extensionmethod := a._hs.IsProperSubsetOf(NSToInts64(b)); +//function operator<(a: NewSet; b: NewSet); extensionmethod := a._hs.IsProperSubsetOf(NSToInts64(b)); + +function operator>(a: NewSet; b: NewSet); extensionmethod := a._hs.IsProperSupersetOf(NSToInts(b)); +function operator>(a: NewSet; b: NewSet); extensionmethod := a._hs.IsProperSupersetOf(NSToInts64(b)); +//function operator>(a: NewSet; b: NewSet); extensionmethod := a._hs.IsProperSupersetOf(NSToInts64(b)); + +function operator<(a: NewSet; b: NewSet); extensionmethod := b > a; +function operator<(a: NewSet; b: NewSet); extensionmethod := b > a; +//function operator<(a: NewSet; b: NewSet); extensionmethod := b > a; + +function operator>(a: NewSet; b: NewSet); extensionmethod := b < a; +function operator>(a: NewSet; b: NewSet); extensionmethod := b < a; +//function operator>(a: NewSet; b: NewSet); extensionmethod := b < a; + +function operator<=(a: NewSet; b: NewSet); extensionmethod := a._hs.IsSubsetOf(NSToInts(b)); +function operator<=(a: NewSet; b: NewSet); extensionmethod := a._hs.IsSubsetOf(NSToInts64(b)); +//function operator<=(a: NewSet; b: NewSet); extensionmethod := a._hs.IsSubsetOf(NSToInts64(b)); + +function operator>=(a: NewSet; b: NewSet); extensionmethod := a._hs.IsSupersetOf(NSToInts(b)); +function operator>=(a: NewSet; b: NewSet); extensionmethod := a._hs.IsSupersetOf(NSToInts64(b)); +//function operator>=(a: NewSet; b: NewSet); extensionmethod := a._hs.IsSupersetOf(NSToInts64(b)); + +function operator<=(a: NewSet; b: NewSet); extensionmethod := b >= a; +function operator<=(a: NewSet; b: NewSet); extensionmethod := b >= a; +//function operator<(a: NewSet; b: NewSet); extensionmethod := b >= a; + +function operator>=(a: NewSet; b: NewSet); extensionmethod := b <= a; +function operator>=(a: NewSet; b: NewSet); extensionmethod := b <= a; +//function operator>(a: NewSet; b: NewSet); extensionmethod := b <= a; + +procedure operator*=(var a: NewSet; b: NewSet); extensionmethod := a._hs.IntersectWith(NSToBytes(b)); +procedure operator*=(var a: NewSet; b: NewSet); extensionmethod := a._hs.IntersectWith(NSToInts(b)); +procedure operator*=(var a: NewSet; b: NewSet); extensionmethod := a._hs.IntersectWith(NSToInts64(b)); +procedure operator*=(var a: NewSet; b: NewSet); extensionmethod := a._hs.IntersectWith(NSToInts(b)); + +//procedure operator*=(var a: NewSet; b: NewSet); extensionmethod := a._hs.IntersectWith(NSToBytes(b)); +//procedure operator*=(var a: NewSet; b: NewSet); extensionmethod := a._hs.IntersectWith(NSToInts64(b)); +procedure operator+=(var a: NewSet; b: NewSet); extensionmethod := a._hs.UnionWith(NSToBytes(b)); +procedure operator+=(var a: NewSet; b: NewSet); extensionmethod := a._hs.UnionWith(NSToInts(b)); +procedure operator+=(var a: NewSet; b: NewSet); extensionmethod := a._hs.UnionWith(NSToInts64(b)); +procedure operator+=(var a: NewSet; b: NewSet); extensionmethod := a._hs.UnionWith(NSToInts(b)); +procedure operator+=(var a: NewSet; b: NewSet); extensionmethod := a._hs.UnionWith(NSToBytes(b)); +procedure operator+=(var a: NewSet; b: NewSet); extensionmethod := a._hs.UnionWith(NSToInts64(b)); + +procedure operator-=(var a: NewSet; b: NewSet); extensionmethod := a._hs.ExceptWith(NSToBytes(b)); +procedure operator-=(var a: NewSet; b: NewSet); extensionmethod := a._hs.ExceptWith(NSToInts(b)); +procedure operator-=(var a: NewSet; b: NewSet); extensionmethod := a._hs.ExceptWith(NSToInts64(b)); +procedure operator-=(var a: NewSet; b: NewSet); extensionmethod := a._hs.ExceptWith(NSToInts(b)); + + +// Нет операции между set of byte и set of int64. Один из операндов должен быть set of integer +function operator*(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result *= b +end; + +function operator*(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result *= b +end; + +function operator*(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result *= b +end; + +function operator*(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result *= b +end; +//----- + +function operator+(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result += b +end; + +function operator+(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result += b +end; + +function operator+(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result += b +end; + +function operator+(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result += b +end; + +//----- +function operator-(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result -= b +end; + +function operator-(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result -= b +end; + +function operator-(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result -= b +end; + +function operator-(a: NewSet; b: NewSet): NewSet; extensionmethod; +begin + Result += a; Result -= b +end; + + + var __initialized: boolean; {procedure __InitModule; diff --git a/bin/Lib/PABCSystem.pas b/bin/Lib/PABCSystem.pas index a7f234979..f01d360a2 100644 --- a/bin/Lib/PABCSystem.pas +++ b/bin/Lib/PABCSystem.pas @@ -481,6 +481,125 @@ {TypedSetComparer = class(System.Collections.IEqualityComparer) public function Equals(x: System.Object; y: System.Object): boolean; public function GetHashCode(obj: System.Object): integer; end;} + +type + /// Тип нового встроенного множества + NewSet = record(IEnumerable) + private + public + ///-- + _hs := new HashSet; + ///-- + function hs: HashSet; + begin + if _hs = nil then + _hs := new HashSet; + Result := _hs; + end; + constructor (params a: array of T); + begin + hs.UnionWith(a); + end; + function GetEnumerator: IEnumerator := hs.GetEnumerator; + function System.Collections.IEnumerable.GetEnumerator: System.Collections.IEnumerator := GetEnumerator; + static function operator implicit(a: array of T): NewSet; + begin + Result._hs := new HashSet(a); + end; + function ToString: string; override; + function Count: integer := hs.Count; + function Clone: NewSet; begin Result.hs.UnionWith(hs) end; + function Add(elem: T): boolean := hs.Add(elem); + procedure AddRange(elems: sequence of T) := hs.UnionWith(elems); + function Remove(elem: T): boolean := hs.Remove(elem); + static procedure operator +=(Self: NewSet; elem: T) := Self.hs.Add(elem); + static procedure operator -=(Self: NewSet; elem: T) := Self.hs.Remove(elem); + function Contains(elem: T): boolean := hs.Contains(elem); + static function operator in(elem: T; Self: NewSet): boolean; + begin + Result := Self.hs.Contains(elem); + end; + static procedure operator+=(Self, another: NewSet) := Self.hs.UnionWith(another.hs); + static procedure operator-=(Self, another: NewSet) := Self.hs.ExceptWith(another.hs); + static procedure operator*=(Self, another: NewSet) := Self.hs.IntersectWith(another.hs); + static function operator+(first, second: NewSet): NewSet; + begin + Result += first; Result += second; + end; + static function operator*(first, second: NewSet): NewSet; + begin + Result += first; Result *= second; + end; + static function operator-(first, second: NewSet): NewSet; + begin + Result += first; Result -= second; + end; + static function operator=(first, second: NewSet) := first.hs.SetEquals(second.hs); + static function operator<>(first, second: NewSet) := not (first = second); + static function operator<(first, second: NewSet) := first.hs.IsProperSubsetOf(second.hs); + static function operator<=(first, second: NewSet) := first.hs.IsSubsetOf(second.hs); + static function operator>(first, second: NewSet) := first.hs.IsProperSupersetOf(second.hs); + static function operator>=(first, second: NewSet) := first.hs.IsSupersetOf(second.hs); + + static function operator implicit(ns: NewSet): HashSet := ns.ToHashSet; + static function operator implicit(ns: HashSet): NewSet; + begin + Result.hs.UnionWith(ns); + end; + end; + + NewSetEmpty = record + static function operator implicit(ns: NewSetEmpty): NewSet; begin end; + + static function operator=(s1: NewSet; s2: NewSetEmpty): boolean := s1.Count = 0; + static function operator=(s2: NewSetEmpty; s1: NewSet): boolean := s1.Count = 0; + static function operator<>(s1: NewSet; s2: NewSetEmpty): boolean := not (s1 = s2); + static function operator<>(s2: NewSetEmpty; s1: NewSet): boolean := not (s1 = s2); + static function operator>(s1: NewSet; s2: NewSetEmpty): boolean := s1.Count > 0; + static function operator>(s2: NewSetEmpty; s1: NewSet): boolean := False; + static function operator<(s1: NewSet; s2: NewSetEmpty): boolean := False; + static function operator<(s2: NewSetEmpty; s1: NewSet): boolean := s1.Count > 0; + static function operator>=(s1: NewSet; s2: NewSetEmpty): boolean := s1.Count >= 0; + static function operator>=(s2: NewSetEmpty; s1: NewSet): boolean := False; + static function operator<=(s1: NewSet; s2: NewSetEmpty): boolean := False; + static function operator<=(s2: NewSetEmpty; s1: NewSet): boolean := s1.Count >= 0; + // ToDo: определить то же для массивов на будущее + + static function operator+(first, second: NewSetEmpty): NewSetEmpty; begin end; + static function operator-(first, second: NewSetEmpty): NewSetEmpty; begin end; + static function operator*(first, second: NewSetEmpty): NewSetEmpty; begin end; + static function operator+(first: NewSetEmpty; second: array of T): NewSet; + begin + Result._hs.UnionWith(second); + end; + static function operator+(first: array of T; second: NewSetEmpty): NewSet; + begin + Result._hs.UnionWith(first); + end; + static function operator+(first: NewSet; second: NewSetEmpty): NewSet := first; + static function operator+(first: NewSetEmpty; second: NewSet): NewSet := second; + static function operator*(first: NewSet; second: NewSetEmpty): NewSet; begin end; + static function operator*(first: NewSetEmpty; second: NewSet): NewSet; begin end; + static function operator-(first: NewSet; second: NewSetEmpty): NewSet := first; + static function operator-(first: NewSetEmpty; second: NewSet): NewSet; begin end; + + static function operator*(first: NewSetEmpty; second: array of T): NewSet; begin end; + static function operator*(first: array of T; second: NewSetEmpty): NewSet; begin end; + static function operator-(first: NewSetEmpty; second: array of T): NewSet; begin end; + static function operator-(first: array of T; second: NewSetEmpty): NewSet; + begin + Result._hs.UnionWith(first); + end; + function ToString: string; override := '{}'; + static function operator implicit(Self: NewSetEmpty): array of T; + begin + Result := new T[0]; + end; + static function operator implicit(Self: NewSetEmpty): HashSet; + begin + Result := new HashSet; + end; + end; type // Вспомогательный тип для множества @@ -528,6 +647,20 @@ TypedSet = class (System.Collections.IEnumerable) procedure Println(delim: string := ' '); end; +/// Значение пустого множества +function EmptySet: NewSetEmpty; + +/// Генератор множества +function __NewSetCreatorInternal(params a: array of T): NewSet; +/// Генератор множества +function __NSetInteger(a: array of integer; dd: array of integer): NewSet; +/// Генератор множества +function __NSetChar(a: array of char; dd: array of char): NewSet; +/// Генератор множества +function __NSetEnum(a: array of T; dd: array of T): NewSet; +/// Генератор множества +function __NSetBoolean(a: array of boolean; dd: array of boolean): NewSet; + type // Base class for typed and binary files ///-- @@ -1872,6 +2005,30 @@ procedure Include(var s: TypedSet; el: object); ///- procedure Exclude(var s: set of T; element: T); ///Удаляет элемент element из множества s procedure Exclude(var s: TypedSet; el: object); +///- procedure Include(var s: set of T; element: T); +///Добавляет элемент element во множество s +procedure Include(var s: NewSet; el: T); +///- procedure Exclude(var s: set of T; element: T); +///Удаляет элемент element из множества s +procedure Exclude(var s: NewSet; el: T); + +procedure Include(var s: NewSet; el: byte); +procedure Exclude(var s: NewSet; el: byte); +procedure Include(var s: NewSet; el: word); +procedure Exclude(var s: NewSet; el: word); +procedure Include(var s: NewSet; el: integer); +procedure Exclude(var s: NewSet; el: integer); +procedure Include(var s: NewSet; el: longword); +procedure Exclude(var s: NewSet; el: longword); +procedure Include(var s: NewSet; el: shortint); +procedure Exclude(var s: NewSet; el: shortint); +procedure Include(var s: NewSet; el: smallint); +procedure Exclude(var s: NewSet; el: smallint); +procedure Include(var s: NewSet; el: int64); +procedure Exclude(var s: NewSet; el: int64); +procedure Include(var s: NewSet; el: uint64); +procedure Exclude(var s: NewSet; el: uint64); + // ----------------------------------------------------- //>> Подпрограммы для работы с символами # Subroutines for char @@ -2970,6 +3127,8 @@ function DQNToNullable(v: T): Nullable; where T: record; implementation +function NewSet.ToString: string := $'{ObjectToString(hs)}'; + var rnd: System.Random; nfi: NumberFormatInfo; @@ -3821,6 +3980,25 @@ procedure Exclude(var s: TypedSet; el: object); s.ExcludeElement(el); end; +procedure Include(var s: NewSet; el: T) := s.Add(el); +procedure Exclude(var s: NewSet; el: T) := s.Remove(el); +procedure Include(var s: NewSet; el: byte) := s.Add(el); +procedure Exclude(var s: NewSet; el: byte) := s.Remove(el); +procedure Include(var s: NewSet; el: word) := s.Add(el); +procedure Exclude(var s: NewSet; el: word) := s.Remove(el); +procedure Include(var s: NewSet; el: integer) := s.Add(el); +procedure Exclude(var s: NewSet; el: integer) := s.Remove(el); +procedure Include(var s: NewSet; el: longword) := s.Add(el); +procedure Exclude(var s: NewSet; el: longword) := s.Remove(el); +procedure Include(var s: NewSet; el: shortint) := s.Add(el); +procedure Exclude(var s: NewSet; el: shortint) := s.Remove(el); +procedure Include(var s: NewSet; el: smallint) := s.Add(el); +procedure Exclude(var s: NewSet; el: smallint) := s.Remove(el); +procedure Include(var s: NewSet; el: int64) := s.Add(el); +procedure Exclude(var s: NewSet; el: int64) := s.Remove(el); +procedure Include(var s: NewSet; el: uint64) := s.Add(el); +procedure Exclude(var s: NewSet; el: uint64) := s.Remove(el); + [System.Diagnostics.DebuggerStepThrough] function Union(s1, s2: TypedSet): TypedSet; begin @@ -15206,6 +15384,136 @@ function GetRuntimeSize: integer; result := System.Runtime.InteropServices.Marshal.SizeOf(val); end; +// Функции для новых множеств + +{procedure operator:=(var Self: NewSet; st: NewSet); extensionmethod; +begin + Self.hs := new HashSet(st.hs); +end;} + +// Присваивание реализовано в PABCExtensions. Здесь не работает + +var _emptyset: NewSetEmpty; + +type + SetCreatorFunctionAttribute = class(Attribute) + end; + +function EmptySet := _emptyset; + +[SetCreatorFunction] +function __NewSetCreatorInternal(params a: array of T): NewSet; +begin + Result._hs := new HashSet; + Result._hs.UnionWith(a); +end; + +[SetCreatorFunction] +function __NSetInteger(a: array of integer; dd: array of integer): NewSet; +begin + Result._hs.UnionWith(a); + var n := dd.Length; + for var i:=0 to n-1 step 2 do + begin + for var j := dd[i] to dd[i+1] do + Result.Add(j); + end +end; + +[SetCreatorFunction] +function __NSetChar(a: array of char; dd: array of char): NewSet; +begin + Result._hs.UnionWith(a); + var n := dd.Length; + for var i:=0 to n-1 step 2 do + begin + for var j := dd[i] to dd[i+1] do + Result.Add(j); + end +end; + +[SetCreatorFunction] +function __NSetBoolean(a: array of boolean; dd: array of boolean): NewSet; +begin + Result._hs.UnionWith(a); + var n := dd.Length; + for var i:=0 to n-1 step 2 do + begin + for var j := dd[i] to dd[i+1] do + Result.Add(j); + end +end; + +[SetCreatorFunction] +function __NSetEnum(a: array of T; dd: array of T): NewSet; +begin + Result._hs.UnionWith(a); + var vals := System.Enum.GetValues(typeof(T)).Cast&.ToArray; + var n := dd.Length; + for var i:=0 to n-1 step 2 do + begin + var ind1 := vals.IndexOf(dd[i]); + var ind2 := vals.IndexOf(dd[i+1]); + for var j := ind1 to ind2 do + Result.Add(T(vals[j])); + end +end; + +function operator implicit(a: set of integer): set of BigInteger; extensionmethod; +begin + foreach var x in a do + Result.Add(x); +end; + +//------------------ +function operator implicit(n: array of integer): set of byte; extensionmethod; +begin + foreach var x in n do + Result._hs.Add(x); +end; + +function operator implicit(n: array of integer): set of shortint; extensionmethod; +begin + foreach var x in n do + Result._hs.Add(x); +end; + +function operator implicit(n: array of integer): set of smallint; extensionmethod; +begin + foreach var x in n do + Result._hs.Add(x); +end; + +function operator implicit(n: array of integer): set of word; extensionmethod; +begin + foreach var x in n do + Result._hs.Add(x); +end; + +function operator implicit(n: array of integer): set of longword; extensionmethod; +begin + foreach var x in n do + Result._hs.Add(x); +end; + +function operator implicit(a: array of integer): set of int64; extensionmethod; +begin + foreach var x in a do + Result._hs.Add(x); +end; + +function operator implicit(a: array of integer): set of uint64; extensionmethod; +begin + foreach var x in a do + Result._hs.Add(x); +end; + +function operator implicit(a: array of integer): set of BigInteger; extensionmethod; +begin + foreach var x in a do + Result._hs.Add(x); +end; + // ----------------------------------------------------------------------------- // Внутренние вспомогательные функции // ----------------------------------------------------------------------------- diff --git a/bin/PascalABCNET.chw b/bin/PascalABCNET.chw index 119999ab92764fc23d458dc6ed46320ff5b77db7..f45317f9359fa9e048ad5ab8f3629ad8961e0580 100644 GIT binary patch delta 16844 zcmeHud019e*Y{cH<`$3}L;(>{1}6}i2SEe`R0L#HR0Ic1$q7ZAQZq#@Q=`;Q`ZF`r z2GcUf9COSvHA^%b9Mc9fv(g5e^Zo6^P(4rI`@Y}x{qg+q#dRIlo`*HTdh;|u*c7D8zY@dj1;{_qK)SUE{H7SfK53{HDNQt zO@wZQX9(R1e$o!DBlXwB@6a`Am;&R~CMSFJq@G>yy9?n2YP z;$!3wu|xiPv2EKkbDh=LJlM{%Rdd}|cE6LpZPGlKB1cVYr!`^ornq=Zx^6pu$;JNB zvv!hcT=}#D{@+NLvG=Njhl>`dxw4f)>bD|DvTvpJdCPWY}>xNI>#QpzmX{8 z;8zYUT(v7~D{Sdb%sFUnOtQFX+m3v-!`^u0cDzS@T?FS=BP#M_8Ua6sZ@Yc_s2%1w zNOL3QK0D*`FU^g;zl1mkwPn3IXPGt?V_S-ss+K)Q-mji;agZQMGXj2%l{};WuLYKY zZ8c-ao2^iDTUr>Gf3=fQ#;3nV%M`=ww`iGbr!!*QdmVYWi0Z9-KXP0kx=^w z&Bl2+6(y0D$J%LVdP+RqLP-|&DfF)~TTH|&Yovp9qsm}OwRjjQdtBuejMXL7a+Lil z-;{Q^*+N>#yEv~)tbBx~7KxUx(ZeE<_P^GRQt=Eir#Q`K6`P}Dd$sb3T8^=0jt?%o zi_N}yZ4vSUq@8`6y3D=+=_(P(w3CjKgvoZ&L$dISorFq%d~PSTPg$r6J&2W}-5lO4FtT&!211Q#77 z&S~VI#=P>L*RsZ9vrG=uF!USo#9&9skU4nXkrY{ki;l$3N;o$rSdXN}(#~mz*}IIg zT4Btt@-S*P+2k-5HI|`LgIkS>_lt;hl5hms#0BG=q&51f)GDSdc0rm^vZ9S~`97Q8 zGzi~0NsR6rgkYP5=pBPlL}-nt+RHX7Kk-mvW{0P3(!$z9m0@VtI$pS76PxtL=Qa{_ z2t1u7+)^H-!8uJ@88^?`noLv8wNaF*GR4zICphj+koSBa8Dyy+?(95ZX{wGp^tVT;AvZPE{ZO(~?q(7!2{KOPI3N*Blb*sffw zAOhAr=i!`4mQtVM)P?xEDfb8XH6wTydCjDYb&DFdVIQ&|o0>@nc@t*|EFW-jcbu62 z6ya{tS-!z2H|ZjG@SK~(VTU^@eBDiab+2GFc9&$meK4}zB}|VF#&mZ{loWjF&W*n9 zF20hZ(s7pJV9iMVsg2<})*1ah$e)w&kcV{8X9pucQha^?P5>jcw&oGrLcrEXG%p z#JjfqHs0|hGg&%n#_V6}7|@qG%HrBl!z>5s;M|IbZw>`=s+OirGb)$5VZ4vDzzi>G zjAvU&Fp+Vx1@Y4zj$RbN0`&AEy$9nyFX@aG-fVTyOFH44O1)|)-pkr>IS(Mvn}YKw zMtBnqPvHrb+ko@l#PDu-`f$7>DDWYH-@yVOZtF63tHLi8@PSK939|mI7KX@u7J4Vzm@l;d3uBl!7{1uM|XS2|i}uym}Ey2ukD?^Dez2+@p+xjv|BP0hW` z>``IJvu;X{8YxxomS@-?^={f0uiC-EPuj|6g!*yA`!Gm><9Jws_p#59$oK@``$?$d zt=e(4De!Zq6#kAr{t~G>g<_t+bk|#i;)K5>Tiek}%Eg*Y3XB>&C_vikQK85UkoM9Q zlLL4}WaE_pNtFTkEr2_?8{w@v*F+3yO%AHU!>uLI`mj05lGbFV#n)`I0vA=A=i%Ij zSbG_%ZAiF7nB9h}dmFpkaG3M>qKyPvu7zq?<3gQr@VZUDM^anqqU&Lp-j*7$Nf4b|-=+matf z!(%X~tV3>-K^!wzo2-r1?xJFxfUz}7huvq_@%cKnF#4|zv~((u32Z)8n`BxjcPm|b zpPS>;b?xs#llI)={YY&u9W6_^w%Pmqlvad$khtP#d!_tU>gVNh|CKB)LDt`9L!E4R{2R57jJxP(%ky5BqUuySt4g zU(@KKfw3Z(Jb5n*E6A}_m?#RTXwJvUU}+~y@qMuLl&6u@kzf-Z=qSBpFHUuo961KR z5Ej0N5h0Q%A7dv$#7z#QX*-E1^(meEcj_#dLgd9d9}Nznk|n>PPpG8ojU%uuR8lOS z5t?!9)i$W=EH=Gu1R95tTOuQnqF{0as>38g?-halVLbAS@LL#BSBAK7^6LbYg_AV1 zfN*kVHQo%DB+KI*ui&j(jsv&=DF~kcsv^bpK zsx6^uuK4DbFZ+;h9Ou++?Hs<2Ame|A@JNF1P!TDyG~zUjnNiDrI1(xDx=SQ3MDk4V ziG(eRFenm=;_kJ5}EJaIYtVx01ZCVRj7F z-zl@(P;Iy}f_!jrso3H#u}snJe@97IdTZWn-BQD~7>Tg|qIN_h@`9J)|FO;TBe8L^ z5!D7w1l<~i^jMOvSrn$mO1!fleXo2<*#v%LjZH6k8CCOL^^hoBiH>8{7FZ|xi-x-aJ`hRDw9>E8%B1e1vrPJ)LG;-zBhFxCRXBn zSIM-jkI`_iopiPCP=lcI8OjwcLt5TXq)_N<&^48my`DnKUaU>~ri#B@SLs-%AIzC2 z5NlINjZk|#`uX|V1Tv=wj;3-OO=F>_DO)@i@oAE)cZ|jSG-}mrY^**-snzJyohtPutm!V1VSCti7`aA$s`l^b89^1Q!YjTS&U7c|zXAImp?Ym1!X-b0AJzp9@5$I7jy23T6cA@dZM}qDeBN^Svqx*M<+z2bH}Yap<3m`J7KSa ziJfpGofydM1n-_SC;D|lX-^5ErTuVE3A7*INnvubk@r~}xep)qq|v{yt|;~MHcqHb z^Z3j+u3Yz{r9CKvva|(@GH6Qg$8G}WH_b-V>ZJeH1f^ST@&QsaDeL!FHFI|7_SL6Q z@Tn^9M)UiDOi6OQ!>$E9(aQ{Zm|o>on{JE4%}lvp_lm=mEa{}TkHba zIkY3QvU%z}fz)iCtIIdGP-@BeYNIWA9fvICDC$!q{cot)m{O@E(oe&QYza1Mez7?p zVE2ZZq=9S|f(U<<^hFo#gTg794F74#tcwAR7E*{PEBpyHJ)4eFpBfSf7 zD32_&DoGA=MzndD!VtIp3hVGDW5dofQ|)R z*KVvSAX(GryP&Fo5_&}CqiNTxVq9YpHuquI4F!x2wCv3mUm~eDMf_*n(_5l3u#lA* zeHhuP8tsBk#U!PBXC(Kb57M#^JMXWn4_nr^t|1n)T<=oX=y)HA(la{a_deWa-_8gw zq|DrfL4{ld9o0e!Z84)W31L!BMcG_wRjP2MzlMW_k|GNreaV2!(4#ML@C@emrOPwF zKev3muLR+UO6mQW`dy_i^^-yIcV z9Wn;0*2Oea4&fvVXzp7|=tG=GW(h-18H4B$_bZWRSX;t2-{WKn(X?w2JDn?GmH$8< zmQA`KYoN0GP1q7ov(UFg7lr-5(!iIIP8BK+pmYqB?oOT9rha7yiX>F;#t{Y)6Zu^* zhfoG#_aLrmG`<|fL;fCw50)O*``K#(#GA5kGk_=W5^Nt##$1KZ2J--Z5v_(WG`FjZ zW^@JRqsC61i}E@S4dKbMVhG)&(<&WJ8{I5wTuOWWMs2$JI&nu)DF^+jwqQCd^+t(U zT`H~Z-4e~^8j;`nJ^Hy#_fN#_QmWF>L?jO7_7f5@btn&?o{88vl;(V4ZF6meu||c; zt}2V&`7SPToC2OGzKbk-FCM;&QZXNID6kYVjN1NbgbyQcZozSz#7*( zVZD-2eYeCo6|t#0vd3#>xbhVeo1(}6=N05fqcxeRp|2WPo zuojLZY3^-9=14|?4%SV14;H=6QL;wR`+v(U>#3y~sjt#<9w}|D=Twn#Xc*&MqbL-g zpKJLxB0E*H6rOLbhW3V=?l4`O= z1u@yDD{?EOSTF607b+y)X{>hktS0A6wI6`F^5|A*N`soCEPNq(YN?|vPA1zDsE1uLW`dwVOHlr|g`9p0&Ud5TQe15*)k4;eou z73B)1reYmolU(*vIG9BG)8aRlZ1T}dQsFX{_!(JWXB^t*fzqiw2_~mv;Z(_G;Qj1W z9wLk2H%+>DuB>mUb>~pS$VMs@Q;w%zlK|7^saF~6Q8JAJzXMN9qm_HOzMFCClAp55 zmQClzYv4Sc^uLH6)49{@m^EGc%MW;;g}PlDT95+C0&jh7mA zJN}>Pl*lux4ROQEoy%&J_%sDuB7TMhd-UK?wFvpU2vn2$o%F74W;EI1VS36#(lC4m z&xG>&?x>(os!vNp%?zS)UPCeW6s{X-NWPE9;OaC?xsM|M5;ol@(T;l>THQ*bPEx@h z6$@~DqrRL@mxp;5rJqT|{_iEmDCI5D6}&!E=F)e_oW-E~FZGR)S5bEj@p~i(ap+dJ zF=O^Y^Vr1ES<+JX=m!5PhIgwN6K`#%llAa!D6Nu2J+T{BRdJb_CTxMPs;El){gJUD zc{cYvtbSw+QKskO*;48_zM*W>Z8Cw{idqGIkIK0`rc>t7LRnawo;QclXw;^U%%NHH zY;D?gE|2mpwdw4+(l%>9$JDeNq_g^j>Hj;ryOQEcHrs2MFqcQuo7gg!;`f09o@jhO zE#^;ar#pUv*IQN3y3&0ab3bn$?{Mac+DJ->3jS;G~K^TL$;g zaM4pSBLmu13#qcl^uXGM-1XER_+X(V*gs(QsxXFbs}1sv|K44HvPs`o@QjtDWJZHci3Hz^NMS%t8-Xg*#shltdPJc zTuKGStBYA)$xy+X8aG5eLea`dNA)9;VdCjHaJ^nVMulIuMhjq}MdSb&88fYzgs+~=uO6J|{wN~bOo!YUGm$hbL<;R{) zN0Kwtr^G5s)uHlH+8w2ja>-qLV%(#&D6;DYsvs+z8XT$*=!u#~CCYMlPx`m@*YTE# z%$>TQ25q*%zEwR@Y)DGj!|c0>;<8B$)v5XRspMg)7Q6vXtpe4AR(HSU$ zggD=mq3}7)L?4;_?P&e}47e_*+jj%fT3=#j((PB7&8Ghm!+jC6m-EHIE|wRnNJc&< zu5qJMd>!YPa~G%K^f*KKA0qN`iFCSA+l-P|_E!{&d~gQxO?R5z2a=XxN0ZmApvYi#03B)5marC6V$ToSvi^{4p}0B&BX* z_LDRRf6L_ag!@|Y-HWTHKDFA$S-AWpspXl47ONz|+BQq0fG%34A}XuMh>=;SUd5S{ zSzbt1FGFQZ62SE-*7aiFRn&b&S@3;I(j3doHZ)_5$}%sPzMMgQYL*FESo{>Fa#j}h z5?ZTOOB{Gg`38*0Hd-w$t&f{!^_OV++AQR+rl4;#2dywthqxJUAF|0oJh7S^d<$=` z<_6EfaSeC<8M>|EKEK1g%<0k#JJ!&Wb?JqxYZwIc>7~|QVGR1Fl~P9bLA7}t`c48+ z^)z`nwilK?Es6GNbv1lyU@GS($|q49$g8Vp;=;hTx--!S_JYeZWT8>L5dVxscu!#q z^`}~^z>2!c4q`f3!{}#-;JLl<^fQv{w77O8^3E_US;iAI@db|dWH0zX%O$_i3;EAV zl>N@S`OLt?>SuXF_!@RU%PpS5t!EiJzXY%6_+00Ux@M`1xL)NA{D_{<(c-gaqv|rHhzAN%L&Ow)LM#m=WJ}eEeYzmlO;V{Gq$|g&J3PaKQHc< zK4yU@+CEQpRa%!B|GY#vjWq{W7aHS?O$S?<*Xxec>k3C<(GU}VHvPeD*sYT&r^o86 z$Q-vW2kL9GF?t>MyD=Lp*6}G%;s(ZmPOoDm?kMi8lW6;QYdfgGr}+wvF3q6zj81%w zCF^+@{i=W)d|zOo^5%N+)*W+Tdx5;zJO^1XNV>I6j^g8jFb3mPEO5gM;_ev1vO?M- z({P{@z22l8{Q3f~D6?`j^FnaoGh+KUGWt@rb|4w~Kp^Br$=CbmVCIXGr4P@+@fWGx zDszy$flj9H23mqM%}j#+P!6VVpvG99gO@i*qVse06Ps*UIXb|6+oW&JLC8y_!GRo< zzQicT2|Vx;nfWXZyd=@qtL6@72a|HH8!6}CqSZzTpugHoS<~vPXHH&xS8t@|bI>`YJ1#pX?v(%f8J*d*<(C8~u{@S7L>H&u)qc_twn_~_zj;G-$BXyKVZ2)6YE-r88jmgSf>YBrz>T*n9pNqsT65_an z9r}{-hZ~g-^T8N{B8Th5>oAAhLff(i>$gZ3`-|qt6Cob**ZYI(XtI^p^gpn^A0n4Z z8{IAsrCX^{n&xS|{Yaf(OYXH>#og-5qJBoeSuYi~wstggYmT-uR=sSCjb~2Np5XNA zQ!@Ln^6N{<4Q6?Ws-s;tfo|fdA-uYK#isYjL-%b&XYV}B+(yI?$-{{qLQv2~-F)@(8m!nSK%~7jVYAsWIiF9nYbi{QQ zaM*Zr5@)Z1hVEKtvq*1WfZRP?;>>+SYewx_HZpC^APvh+IahNy=QMQ9;K@*VrVjc3 z`^7Huzh?}cYP}Xb zo_rx>BL9M_n$IfTwKq2J<4s4zA(nizj|O{i@4981ugkFb5JT&Q`$_b-Rg=f|OUSZU znfTxUS@FI7WSHcJtnC1^;~TPRD!ZZ~JC#}ef!?S&Kn=4|Wgay%G5S+=h295QxS=kS z&kR-^uAge2syk9wx0e~-nOr<59T4^!37K#1i!MmyA)bLhW7HwW=xbPmwTCDY?tM^m zNFnESmNb5qcrI6|j8|!Wcj;44rUG*iJ);j+vH~tgIB;(h_pW!bkvg*5o8rzVD|Uw| z7!`dGf0$ zN4VdpLL?laICU*VHS>`#WD%YIDX+V7u6{X?{{q928-XK0EHdGYVR#X+Dlok5J zg;=N>tYCxwJlM-AE(LsT|9m07dV|XDZ@Ve z90^nb-qJbZY8lOf-E;W-=AOP-_a^PV($t1+OMl6tCMb)8(iNaf1XCEjQ23)6vHDQvu0|;OCrn7eteX6fZiU*wf@Gs0XS46 z0oKO-RkC4VtEZWFKE>y7ZTr*Ldfdl+2priTRi~*Gllx=CX-Ty9Qq9!+%Z7P9i&&)o zTr_|4R}OrRqz$Nj?#TNJuFO)_pU!I+Zoyo{1hy}Rnn|D4ACJ7lP+_$y;u$+$y$x#q z0J%>^Hr3-Sl~$bicz@h@hr+bBKYY(fT9a+;;c6FUmu8pD|GjYK3Qyp9XC%RP@J}^x zc~^XK{R|QJR)73>hF7HL(D_|@AfI8>yXJGK_3uiiy%h165O!TqaE_#|8EeyBis1X6 zr0G6IsD4lG(u0a{^F6+5i!DOJ`=o1H5yrny?=r6lTi>TaIj{)7zc0P@Q6>z=j1Nfk zDMi@z0W0Sg!R{>Y)D{;Z>n!*1WD#bZB@?_*ggpxGEW(dx$qcU*A>y2LcRa<_cynJ# z==wgFdI>L`<5IuCm**t3<&UhaMM*v0)svZUqKJ=}TAr6|-8ulH&&zPV*#Oj>=N|k9 z!2JSwGGqX9FR;Gz0Ia;gY10Sb+yzG2`V4^gMFyBl2Vl}gE_dtz9K6WoP9K0qm*j5! z!2zhg#Qb9eaQYJauNeUU52;``n$R61Kjh%A48YSLauj4_0`F_|TT0mW8c8(LgdzCmnxyNKOOWt6 zH!!CJGe0NY7M0-m=j73qC2+qkVNUBgV0#KjY~5mE4!NTQ@TuKD#v*1Di8FHUvOFfV6>L}e~VGif5m7s^WudMc78S8 zrkziJB{MCK|N3((2fe9g9Qi5=_kSbJjIbYl9obGYx5;OUmIuWdX zt^Ro6)42YD51(%FX-T549{&ua#`8Dt*JtQ_?!cSd7^l`8O5Gj(`Qp!^WgC|M``^=c zE{vF%Mt?qr9CR8NRFD}~r7ZqX6#aB6PS-DFJe?^17Ova> zmy|h3sprd2UI})Z6+`s=2mfaM2j^B(|1S?eXzTeshte)q6-|Ks?>-+QLx;FP3@3q!Fui>0M?KJz4 zlShx@qD+gXY5n=BzpH!J`_*{F>zf+XWc#`bOB%M;%^Izy+N)+(Q(qUYV8Hl614gE% zb<4{r&Ty`JNqs&JnpU%My>-79WSg~Ngmmg7amK{H&%_R9?sw5oQ?C{Q^6E!<-*;_Xzz7Lx?_rFq^PB;V8mD!g+*2glh?d3BNRE_KVJa z%c^N%%zaK6PWTgH1fg#OO>0A#K^RFmlCUjd4Pg}F7Q$%4F9~A^ZxF^B&JPB-$1)es z?;ii!6IwKVLzf2wgT!M)pT|#IjkV_;Hl#h(P}g&0L-tI!GE1BmvZ3$kB1hxKyAIYK znwz%Sc<=leBkXjXYg4T?^LA=Soqt1 z2V?&22=Ozn-tJ%t3(@d_P1;F&qtBf}Ni*KL(?#-)i+9?|14h8zc2a2+-VK*Y#?-q> zGQ-$;kaO)BFs>B&@2{i7`aFJ6BhDaCva>#;LC0_qMWWhHQBUac%GNdW;MLI~J0-jhb z5^9TVrD;91(b@#04v^N4o$Og7|5O{vL@Ql-ND;>9?9?ACb!qE3%50Et+&dF%d8Czw z!mq^3I5@(^ai&=@9%EmZaN7%JrbruN>>lW8-01Hj%kiv5+FI7I%b2I7m0}vILd8Sg z$DbByFZ&VeK*D{6Ar2Djc-D?=L9Fg$>>A`?)7$%F(*-LWvW>-4KFy7)~{nP@yUAJbCh7&iC`yb zXE{jh4-O-#maTDUIHwNdx1reKB)&%2?NI%^nQn#xn>ZNzCpAKlO}w3d<~(w=0or(N zf^q$Jd(p7L#wokvCZ!A=ZQ_EMh7u;NQQnX|ibqXDt}hk48_EFZywsIwZrg?0u!;-Sz5^xIPENLEYG#puydODAHW#BsdSbDMS&uJ2Cd$7J2);-V31wBr@BXOs( zc;WCH(o{)S_QPy*h7|pppMpwt{x|%Kps`Tq(M!YK#*!#cql+80%1}e&p1TBFm#L&t zbK4XBM{`-%(!|a34yPE{gACm@%mK&TBt*91PdBc2A7Y!Z``N>6*x;t4}Sz1Owd3u|cR&pbER)rHed7aiTjsj1K(0>TWqn?ti{}hhxo)V?s z3&#~t(#!=9HX~0`nn`oqbE_rhwIR}WIM9sxmx4RZB-}Zdo+6i0JwY31 z?EKW!@P$5XRRMUh)kFByOFDF&p!~`IwH7v_7AoiF&CkSbG#MVCu-dBYM>A4~`$!$~*Klcr|zoA!LIw?xW&DxD;I(9?%9`Z?DUO!j{qApZKv2(0xXEiOjj zq>m)%zed2rm;AG!+E?6B;VX10DxD+&*y$_nZ4vZ{YEDzoxHrkOwkdgi!(ZH_1ET$? zXXzN@M?Mu|smk@kX+Kh71l;|lD@OZCL+SnR9iPH;{$$egIN(pYSPBVX|J8^MVBuB; z{P1)D?ZU@+H-OgXi#8gf8%nrd+XimUCC+x$oDsDV`MwgX|Ir51nv;!=c)z)HarB_) z&ZSFfQXwXDaFQIh1=~y6=gwNX5LG5oKp=zM0p;A>L6O|N3k!6t9S;#DXA*7A{e4g zMolW|Y|>#oR)&yg({Un%9DEjjtvKmLC~8Gtwo)O}Dvg>Eo>CZVb5olNSvc#VIB6)vzs0A}s|`n(_7rEpg*Z za-=VO!ljdKID6)61GV88JBF-Y8_cT7m>DifmM7V~=9d6`A5N2316zc2!uc=?e6I)+ z(L0=}7a}A~-x7r#5tN9hRY|ip(itDARDY)Q(@|L5M&k4pn;~c^eMe*@ zNz@>kVS<&qVwyj942YBr#~=od`Pxvt+l6G`&t{HoSu#c&Wg0--P#rr*Yer$EmsdJ@ zrar~D?qFzq9u0c;a%ZH8Fb6$UIG8*^VO0G;r zZj^MFSy&Jy`LX~%5a_Q)-IWay@+ePG4>}<ajNa-zh^ zIP_uj=l8ql$D%PbhVj|CXe=gdd4t{liuZ!(l9aBf_&i^$BC63^rcrpz2UW4+;(W&( z!z?x)-_l+h;z$eyqa;>BUA-7p*LTUqfW34fiZER9+p!XhMKQG17h-7|lF=lNCaNd$ zcr1?cKLqb6Fb?0vQJ)`&tsTK!v~NeLehCu^Y;TwYjMD}iGP^BSE5EgIs`$bs zUObxYs;jKj9#XzuE5m?z3DiG}L9cj;az0*HJ%JTxTv_pB3|7ZWnDf8xS5%l4B4C`` z!_p{L!*hlxJ$tr2B|8i|6=;u}?K!bD1SD|o`RGYteSkZN0#p~$7dB-~uRg{7N-Rx~ z)-nnE5~v|Fa3?{cZSz%ITI9hvvYJ*pr~`#*iM`B_(LP4bITz-e{21z@K!w3iSuuYBb^wd4&T%C`OPj=P3F2v zB${-l_35O5Cn`Eiq+@2BiPmT`&&R0h?_w#6(?EswG-6IWdA1>GzTxB)R3z%J8XHMB zgHb!3Iy5RyGwyvDOfj`Q!frdKGklwA;-efQ@TEGZpxVj{SlNa2TwY&ooH^&EI<8^I zw$&2t{C<6nR%WalMC-*~`u;fdPo$CfDh{&~rK9z%If32tJxyzBxy}iEH!DCz{%}d+ zjBXR#*cQ^-HJdY5pPID|`ALiwo3*3H@AovOAN01hY^PRTsZ}9(4MQ{EdoJ7uoJk`4 zxerLDU~?a!Kq)E}7>t*asRCp1b+UA`PE(zgVYbduDWonFccr{W${~Nti|rWhy~&j; zZQj;Z{B5tZQ5CIEB~nHAGcCKmz8#!W7#{6xhpZIo=zP$e58IG#N5Y9t?Rs8K5f96^ zob_Yhw%5D01{c!<@97!ux^Sz&OV}%R1 z0y9&o5x&@}KxD_#>5``(j>naB z8lUg%4Y}U&6z0@vo{ikeEcGddU5ZCqh9tZG_V-q}*^?^lfcG=#F`MA$3{IjsT4$0y zZBVK}N6b_p1Di8xhoxcCU_Ly=H$>6XnzRr8{vM z2+yKNTc+A@R_V%zdYKLNciLlq7RkG4B};*?(2Us8ei)V`!}J{qIGV#K_0t42%$0;D-w<6dW%XD<2=2^g14 zZ~RjNR^&>u<2|;dRWgpO_HoUmwNRfTw+kBQk-k1i$|GAsF-n1USdvHon4*9W?&eXs zb35S8I})J|ZklXi-);O9R5&WIGM~(O2q*ICPA8yE0e9fl9W>+d5iQjg8S@InN#+3s zZ1pleEs&P_n;meYK*E~5*MSJgjh5zd6_2QJkIIh2rSwFd3&l;}(*Ze!4A4LCfGG-| z?0^-8l-i3OaH>!R>>W_hi^m0#y`%-B_WWM74&H_Ii!b(Kq^JWB9glhTZ=fMez;mhpELr|#mr5?AO)TR2#{PvM8}FHicz_>Hw(6?g6tA*jf0B# zuYYfvq$~H!R`r%3{o{^EDG_hHQO?X4b(!WR%+#8hZ2f9S%q`(k{^*D;C5*E=_9oI_ zOX$Wu5Lha0@rf$<>5jxLEMb(jwp2PYD1Wd_ycU*GTC&U}lFKBBdkGeIz@-v)7+%JI zYgFkNe9lt+(M}5s#oNtJVihT>lfWPihs!un|8i2;Tm)(DjTNOF=~S6CP!(ag@b|2f zxfX<${jG@;)RNFom3dTf>%gfoY^-44Ln<|!DgEnC*jPaxecuUDeQ4FLH6YE*;bxVy zO=2H9yN~NqF8KXHB6O&*SGZtTAFjk3XZp}|wSw0JG;(n$eSp@jD{3B)Ldj8pTeJ#x z8`g(wU;F@<6w#O6hT5z8F^$^$Rfpc?#%?%eyMa=G6P>Z@L9X*cXPi~=m(K9* zFA0q63;Rnu=f++B>U_kXu1s~_RY^O!rayxLf9&fo8Q$S+rI6X#6{WQ>4{U=qG#bD; zCZNLr%4|1O4j?@Wuyg>=-}-i895BX?P&qakj&%cReiDy|GQw9$lnvx2{z-d!?m#oj zXL);h#a?uqMV7aTW}T}9+qTqAbg+?nGu*cKey(t@Cr?J)uwoE5Ge^5%#~>B=cflWn z=r*o&LCj$8LT}YIf5^D`r?=UBe{NaxPIrlMxd9Z&Xj#LZ~1b zX^+m8>~Zb6XZ~3dB1Vx*$CEI0 zl*HJ6tZO>K*uCBdTSoB!{a;BqG>TFxu#TpUY=qR&w0wS;IGQ#x3?GcXD`MVNtRRWriC1c3L2k`Y6DpDmpt0c)fDVb|D#twIy3~?rN z^R)cDd*D_&3>U@^>Qk7O+^^^1vNqPJS>va#O2*wPiE!V{x{ug?Z=I8==a}C=^~9ST z3nr?T{E8N=qr|6;RZ)F1wvQzljwItJ<}Ig^=~$+c{F&nxF1_hjrDC-Dr& ze;Y@6YKrLb1c7*HJjFH=OBCpYTjTlf##m`!9i*fc(bW=+f>{hsiZEgV+20>8O`vX$ z!lx?t2yRWFRL<;*#EFa^U+9WQCvwc?U9n>#gN!v@acv@b_i`!+JB0KT9Q&U+&aeUVNh zDd_wN1#^80CK1|pDzsex1Y`LV?ev2wxb_I`@3$%No=X0mPeI;PhGIXP&>w53(uiot zohktfAEjAzMfjtfurJVVLEj&6f>y9;#(H{1}XOBrK zgXLD!Xe%bBqTe(r)1OGimT8>XbE){(G)l+fRP=Y$6L9z`anRpN#j?jGQ{R+|oar@=Md{Vo;PRQ^&bLaPaXBhqT=Xmd!bAH8~i8-~Q6R+Aacaj#n1>uu6d z`?7e4{!jFbpchcG&6}2lCm08G#F!^!hI2+e+P^7XF9gg`!E_o5W>D}(reXdJF5_Vn z`r`W;5~4p{mkD`NTIfa^raws++y6;vt}in)Y5F@R48esbxyo&6@PA6C>HE^K_$lK0 zG7Ukq7(85hiV}RLE)(-KW0`ApnX0Erj6dr#QHL3>IN{9GWQwN(o|rO|cRVfZ=`AxU zjM4V=;=?rWiS~5-EONF7`p)83uLMuc;-Ut1!~84wj3nylhWXD(mcF7Jjz7aWuImPu+0wb=4z}lwC+&{qaaCu=sb zeA*3<%;xCdbi?}DB*PEgaAh`kNI%(U!O(lCHq@vdY3?wQFh~5I@0nGVjLe6aS25=H z_t81jF&8{Dhd#^)pUvUTLTEY{V$_Uw$1*qZwzgw-JnpS!;Cjf)V~iA4&ErNnU|u%a z=GG})E*_uDd%=oyY@aJ(mWR?cW6V!pxI33Ln2?UdXX&)6(=q&6@_b%8=07Vj&M%v| zM%Z`MD$+@rO3T-Fi8wmHX;zJ-8V)g!-_)^%{$4to&yzIQJ!($cD8@b`wUMZqC9N!< zr_*K4poe~Qo`mWr({Xqn2e@crQD>hMP)(DgHpoV!Up@3+)3NxT#F*a0f|s7-J)|4X zJtwKo0U2t2_AW;nbGs9f!L!1*B-rfh|FZ{!Tg+#8o{n$lv$`;Ymm5?4P&<((rC$bO zYH069WT1ZyWpGLc=BoTt8Q5M!>3u!}H)%d&qU5;_!k(8b*VX1k z$CA}N-7&___QQ+M^DJX4ryE?w`1BxiwvWw5v}Q)^&H(+3jD-egRhxlGLfcidasrQ) z2DD+1Kj|@C%@W9s*M+~|e4>-O+$p}Wz7Z_VaVd@Lin=W|o1=eNZvMTHizXj4p zADD@(1yr;#nV7af;#?oiR4gKHewD_Vqn?e1QBc&UME#je)GnY=U6_f63khG#MEpXE z^V&>|Tqtpt4>C2LRkgByqOf2<35Bm=E$RDpCVpK=*Y$lS4&9Rkqw04D{bnYXfg|6| z#4$)`9>_O&k+bwh&lfq%R;YfFjw4P1cg$PMEm>Dwe32$E2LUfhH|O&1ir*7?8eKP# zI;^t|tuMvW*XqurPR-^7#&^g5muN(%*VT_wQ3U)KiCfsSEc)-gkWRkwvXze-5VeRa zUeq0BizL!{rHN=V=~TsY?_jK5#8EbO$Bsp``@6g24>r;dbw}9CG@vKCW7x~IB^OK> zif>+)Aje-!438kS5kuO7P2%FJXK7k7F%IOiMk08D`0y~#v9Z0>sJ`rps>M`$e>}FB z3=GFRi=~wFq46c!j67Tg*=Mw-n>$zlH02 zv*5Ipr*=nKJ^?jLxqVP4b<>wpx=(XpndXJ*TWH1CEaevVN)`?;CAM2x_+u%9^9BfC zM*r)MANgcPoQBRyWGoYc+16e7W3+QBa|GqKTavGtK~tczMuz2zRDBlSIseo zag@U8;>kUEm3a&R6J6Dhh$+)$G z(MM0jzAl~gvTTfeoi=GmHWt55p&FNsldsb@J)RA>Hz;&-O~~!|8xrRDlETg_;Cqef zDG$Fvulzq*kPY9J^hCR|7ewlDj!LUP%cd!u>526#$>rnOxU!P6`y<=E$&<8y z*)dVfV@J2KNKXwnUu0-s^#=Ewjj-WOPS6jR-{c`|SWk0I8f_jRsZ%~&T1WP@N99}6 z!J4LOak>F-^wp;I658I07BMCkZVznB9bD}Xl)Rxxn0ux=V0C%GImrB zcB~->9?8M)DnB!4L4Q35LAp5DUa0H#Fsl1XH{0_2*<6}LeN7IM*OFlGo6y@dm$v=) z+gzq4)xXNYm9_NgXLAs-j+XHH{c7?vP(7Tn-8PG8QbA7=!1psBtmD?YS+1J#L}lmp zdZF2R@vydJ(FCmPLi%K_r`3%yn>@@W%fIkZ{x)PK9fo=!QxBDxC9##8cBsyk{GF*T zWNA2C@H%?#ddgmQF18UWOwH;s)I)`-G#9tmlTw3ok+6ZG^w?ZX+rWO)aKCW%! zj`TtHG3$)o+XL-YBlA)AKDGYge9V2H(|I}{+uxTkn^E5sreZ2I3%BwSM27vMMdcC2 z0>o7@{xP%tRCdaCZcz5+WAS#<@XLIBqTrc){7&e6tsW`wQB%*`Cx?PZ}jRqOcF?{O1*7`iJCFKW31<%U&0$zgbuO ziE8tnJ+ts5ruWoUBrpTt-SxOes%*~v?5nEj#k!{7sLZc*nMQlruvRtfs8Viwm>Q^3 z*(x=6FQq&J@9*WY{AyM3`(6_2BvY0G#x}h8wbQb&7m7cY#K!%4)l-bs^epR++tmuw zJ|r&+?KGRx3)em-noBH0&_2>2=p&|_L=QE&ZChH8#eUa3{UZ|b=sxmzYcJg1$6LaW z>lLN2BnOTxp_2}oQu_O7Gc>zwSy?av4i#<#Aj4fZzL(u z3YDMnX;WM=Uige_>ROB)pGkxzr&u!vEbuWOwOPuUDg46+k%wf8WhgVJkNcS~_dY(v z?e6$uTsg$ZYI-qZM2|OL{p!ya1?^cMyq5ayCdB4_@nVr zf^eiB5oDiO^JSgey1U3dneK4o?5xMk{JbLwAPmhrvJ z!J}M4-`;Tgf^c|mq<=w@PVS9qUvOei_Qpn4Ueg;lzF-9LN^gXH$<@8x8$-WjeoJq> z@+HIAy&TVeQLo+u=|_9x?w1l`J#7{%!>OKN>Q{Or`zwjC-ZG2%GS0pMP_I54VCh$M znC>MSpSu?`CeaXxW*54?_`IC}u-9Yr-IC7B( z$Gb`~S1M=D|(iBJJr4n>rcyIJ*^DhwWLFS86K#mG(Av;g|(8SSC--XS`IL&3@y&6 z;Jge2&+t5Sei^o(QNei`oX+wLc2ybj&dSiB%^dhI`JF(oqW%;)q6zuNhpn37;8~ic zkIHcStmIgauuC8UukoC@>KsMxR2in7BmEU;MHCvGJcQ@y;C{n{y=JEmgA!zh@q$)4(Fvx?_Z8d=Q-I?<=B3n zi+!Yg;g3}5ndLYp`bexj%d^}UnE8=?mY1X11-4mJjtT|eFUKnvNQnLAIH~eql_TgP z1?Fryre7pSua{%fMR`EKT@H^+lEqNF?I#q7rd6QiiWKN`Sbv3l zdC`QCh`P!k`t=G-y2`n(ufVpeWY*3KG`L17JXnE(YvjPU6_|dFgPgCxs%tV*|G5I* z*CozD>!WEHdR@jjxT=)PWyS$c7s#6br$q7juZiNVg>LTqo4jn1`@iRK)0=39+x2+# z`jaog!+vX_yQ`l^#ONO8L;OhH(|pj~(bkN_{QHw&C#!OF<~!7e>Iszkyv^5;VXo@c zUH$X9`!DXCT-8ghe}ARrr2Cogb0Tzq^HoTMC4gl4$6Ev!oexI-^X}Y34>a#+L-Zi? z)-c8zO#JunqT(IZb;#eYLY(xL=2?Ec&YyhncsWw%**?!0`Q!%69d$qF^VWvuVaHzw z9ZotAvbb^XtcRO>tuUL4(Ek~oJL%kqF=~rha93AvjOmO05G8s896m|~h%&8IKb@|n zUOgkMN-#~K47c!!+UD`MZzh+vJ7TRPcL04G>uVbO z+oD7A)3STy6%}i7RDYBL&E aZ}Ro{kGkB{06r_b1M{k9;Ge!uPMbH%SNNIq!YHFWTqU|D02&&N+3e zZr$6h4L>LiE7TiSdc&ZXR5|WwV6ZANg>h&e;#iqaO zlSPlgP5{2cIR#X6l|^1ezuLZxmc)HTE-eoCw3_&xe4Oj))5>D*_NSFib?3u!y?X)Z z$L?85~ZtHPdY+Ud(-(ydZ{qTNF8`xu83B4{;!AHUR}!|vxd`3s@3$G^}eGK#>B zE?syJqd$9vFE%b6rBGk6Lts-~CAzybB zim1!F@}ELktel545(B#;FJ^Az{a}7wOysFQTH)h1VJmKRk!m92>1upSq{9VIs8CUt ziL8c>tD;YaV8jOqbAsy^gPT>cEN!?J`F}rLnwl7Hcvo|{G(!W$KxMz_cbb|s^s1;w zBtu3fvKJpD40ZoaLuqQ#(1KG84Hkw_z`v2nG&O0+eu|+X!VsqYHw>kz!BAoPqz)Ap zP+q@bAx%xXGFZ%6o8$}=hESisVJJ;a8af0!Z4I3v4E6adYS7sK51DNOVaiu&e+=3y2lT-P1nc3&IU4!Ew z#~Ks^lHy2W-`2{@Whc22St~75a2)YhAPw5m7G=T-zUFXPOIB!!b?VCMZ?xUll;m_i zHLKKD1$9zX=?}KC4Ov~=iINoCn7G)JReXO|mL_~m_U2z_We=Q%9`3pk!ohIRrYEt$ zT;=CrAYFPb>)Kk6oyGXIn9(JsEdCxJncbnU2rh}e##Lytlf`IzaGxI~>yqc|0q0^x+<3nwsX@jr5w zm(6#z-@^SR+1<^tFM+ZghmmfnD#KE#DF=DO``HExsQPk>N7j$8F`}mSeag(}S+WtP>|r*gAAhUdz9a zbz=K@G(Wea^e61DyB-~}T4Wssb#fSb@&>R7*A2WXKPPn~P|%rJB+NOJTp$M-4rg+_ zXhPAI+$dU}1a@IEJjt5`!i}*UX8<_cp(H8CN+>`Px8YWjH$y|U#o;r&^~hDw?|Jxm z*kM}u9pr~Fm{=ZD`d!;1aVDk25wsKTtkSV|iT6aGcBW%KGJMYDCgFge41e+#(F!DP z6)J(`W`PVcjO4Anq98AIo4`RM7>fTMt#VNvho^v;tLfL>CnKm_nTxQJw~OAP!(zb% z!(@bm5hIek1I*+WQvv}Qp_VuUW}H*2l7DcBKc=zz!PT47Q=7hFjovdc-P-D&Q7JJJWXIo=TkYfZjLrdO^ zj@ITI6I_ecoEls0ePS_~-dghe&?RCU9$zEeNepW?uO(#?#HJq6%p_p@Wbv_3k52^Y z7lA0OB@w@?_7QW9{nRNNt1D92DfIxj<=JuwM@t#Xh!YRkS|WfWGNDC6(WWdFIOsB5 zp)0YK+mhR0#Bz3Nb0<865LKQO5hNcH$YXd8FySSCs<1oz1OKXU7<-tP z6-BYmD~j^bUMSnw6cuR?qr-J2{L!L8YzP0YC=z`H46J5RW`^I$ydKLs+sKYT%Jbr5 z(SK3Az|jO1kxRZQ9xIUgN-)pJ6Q?@3P7$M>5!e`iRJalg#Nv#4!UpmLU zq8U1_t;0Ok?dFay1r@Spj3Rk14t5C#i;XU_z{{~#o6Tu%}zat0tcYR!nPR7lhNZ zipQ}V__pFRRcvnDpIgp0;`SBiGfK*|5=>3qJbpt-Z&u#)LP-{5ckqu&8@j$ILc)IF zy38CiJ{4_`BmOe@VhfjBrZ{A{+&b=e*LQtMe^pd#{7rsNw>ms^z12-TfgSC(&}>Jg zK^zU54PNd+If;j^+sfkXHU6ivx2e6qsb6~mZ$6boIGY&|&- ze3K^Uqe+SPF;(VG%tq%zak#K$KBZX?Y3ZhhK||G-VL&EKrCdoYTdlmPb%Yj~t5wZq zjRh@AG_?$<5^f2<<$PDsNwHj(gNYSug_Dx;B+rwP2*t#UruAT%K?|^kMj)C9ZdYbf z&WE0rAJH^t+$;KpU5WlsHz)4Y3@#HoN_s%T6R(;&nH97-%P~t>L*l`z`H{>V!jtF* zNum>oQxvW^;y~|YC2?Dkek2+Yi^HmN+&$h>rlo@iElWoS~SawFrT8Ag6 z$bC{EI${)I$_%9~>t?%QZ@Og_mVe#w$r(zWaJprR^yUcKr0A4-Z9B)OpNX*NqyR*5 z$th4MiYt~XHoOU;afrzStjG;u>EFV(EBk1VSAn16d4qG6}K{1<0}_jU!H1znFBttvshyK1aS7 ziu4nS3di5VlC(JGI0zuLw}>C?F_2xvBRwkvcSB5hKVZ~&Eo@U=9lxyS(7;mB7Bi4t z<{_MmX)J%eXSY1;i>~IqLC!<`VsOl8mCX1hJf~Mq{-t0wps!6%&y}KOK0YMtAt_Yi z7xNjt+OsjdzSk6X8GoZ!9=n`>+v_Z}2lp23Ila5EE5Hxum7?$E*kEkQ<>+c|ldu;o z^AbFyaeQy@f$U0tqIYQqM%7$$M6F9Uww@x$$Md0mf_M`% zIU8Wot%u@`{Fy#^nT`D7Hy_T;E)F zHNUWL_uemJ^tv$g&9gw*qv(;U+bI;dLSM~+y?=al<^ljS`?UH$UqYu>u_!$U}BCM*(Yq-DvLNCrchI|9zqWDXEb^kNiGyHYXY1|kPVSnVE z2NdDSq;fzs{(wlXSZTU>s$QCj*>K4xz7TR6Eb~)ml;BLhVL&Im!+c^u&)@)bk#8DZ ziRaJ}Pb0nfF9RYIOJq;8_=X9c-jcD-)Db|Oy<)gcV6!ATu84h5+@lOzjb#sWM~W*^ zCFIIIefW6;+vA=8H3RcmZ+`#4yeW9nG3ZJRgomYj#rlvXr;<2%!b|abpzc`=9e>>v ziW^0%tZpwvs`>ER1?y)RJ!~U7hvyFJ5`F_6+L$KZFQC;=>~~=$`69n+aB1o#aN^j!idFMvLBiE+)$&#- zxRj)@eE{2?^=Jj9VtKocD9KkKYThI+Gb4$ckAdM}JI#FXz7aaXpgbTMLG#%>fT#3w z-gQWBN`?bAMs)T26K2wU?hl$zy{dRo0SUf$!9-eKiICjN0r6}ppY@VBX}ii%4VdBD zaU#^$zzAj-86h!iF8Ml}jEt~qJwdvgZ6)L(RY}4Lm-%j8Nn+aYKCGLZ zf??~y{!XF(jvP-ub|yuhf|*7*`4Z0@+Br)&Xk;0=o8=px_?tpqK6~urvxfF_zXgnU z1V(o9ZGPv_(rgpwm>Zgb7oajHYKLN!#1}(j-Tw^zh{H;(2;F?-lJzJClM+=oM>dnwtbs?v7L6{% za*!tanT;5#IAD?S4~K==Y<_fD0Uo3>&!}OizOk6fHxAG9v@SrrW_WgZ*!>=?)^^u1 zjqmf1hUcD(L}OKEmj!4A=3-hlLG3jnlFx)hs@ARsuKO>c{<&ZtSkzp`wKoaP1~5I2 zQ2Yq4@+G$;WOc#Xc7>8(@PQ)>*xz~e$moQBfU_LCqb(H264eUD@^>|0A=tWz>40I% z2vb1Z4Ur3)cp2&DozYHWwN%UPEfoI}z1%9U{N<6cqOXADtq*rzA~}~rFTP7oL$J(8 zx1#U4+!!^Eea&Z&%E-aq>yj^xYhOnM=Ii4`9+W8lHNRn06gTAuMiumy2~R@z30=c z3XJjNV@ef;@zOK9^i_oz!DL*9UCx8KGxot45p&@5;j7F6H4GTO4of~;CdRPijmo02 z!wbX+r%`Y5Vm{@sLS2BYH3xXrB#WBx|3C6DWFQ0Ov>iFD|1gf&0kd(pLhCcwrUD-IGG z`~PD0dj3bV=V-GY_?Z(sMJ{L!T1&QrU*YBWg@B8*sadYp+6TM zHzsXg6Gg2#tb%Ud*-js=wWFoiYT~qY`o~Gd^Z%nrorcYtYG-7+H}N9gaGM)|IpJ>F z);!_yEzNh2xPic}#n1Q7%F@jEd2({>S7yJnTgGh7cek@TB&_+i_VUw5{J)vsoc}Ir z{_K>Tn5=R{mtCgQ9jNMsVq(*SikWO3eC#M+33q4^N-#-sV z7ra^z^7p0|cWyBqiHC)42(XS^{dTrIGuX_dEnhSoh%)jgk=Pwyf2twqygy0vfdo2CzKS0EH{`_QQo0WRU6O~0Nk;mfKvvyMo3 z`;1POT%i?^+vKDa%Bh$(qlZImD)>cM5#KN)zu(E*A&$v9;XFnciC#)P4pZW8<^n5$ zb!%=t_{LitVe+FQr?oxZnA$gCRX#b3qfBRBG_yAw({%Ps&d#ot<8NuM_}Zi5jMoJn zadO%&x{9_}JpAf(1x7H7$PWG18{w%%GYFcZXvUpgTyXNtT2=Ezdez)|c5dG~;R(fy zF&@Q{7Og>4Pf9pi!;Ui(w_l>>UZmu`nU1kOJ$;TT*dv!m&sTooo z@|MVXeOp+Hf5@w=FC3T?BPzI(XcewUve2Hiw6iCp%OWC_kSD&l1;oWT- zRog~0jn20{2U;iFDM?pJdYzpq(A=x!^d ziyaND3#|pGknTdeYYE-Pnj9LvEIa(wAzb-hQpG9Km?>!=rzEZNjgGb7?hB)I_@^Dxe!AdQPG)v=LSm`ZIlq zUqKbq@1(2{R_s(vzX$TuH$VpUq~}voxJh>GN&76}CJ6h{U#09rn6U#LvScs{^fxIx zPRFI}150*X%05QzcXYo5+THysXkXbLfwoF}-TjzK``m*-Uw02$Sz>@;?c&-KwOX~0leN$(VXC>N8JZnJfJnNZ87kjp${gmeq zpx1gH0ew;G`@N!9$onb$F@Au&UQ>warvV)|VlIBPn zleEYuBI^Yjq`|&l(5u=n;$G^1R0-4Nk~T`Z*8ey-w@T>_|C4B^p7lS2%U6a|4byjq z7xbuMfSxdf32#8qPLd`9hHAqNP;4z1I5#8ZB^F9bG{8d3owq}FgN0T&w*noo&_;0_=fZT@`3Q~&yOx=BbU0)>l~`!D>j|Je7P=TH<)pF8P1UQQ>ZTPI`kh1}Y{SCL1FmNv+hL*S zA@h>00V2rWkSJlHze%*fLf=ayk3!HqA<^^|W6=hBTIuhCJAmS~UYq98JWZuo7ia6G+saWu~Ey*xs!1N7~Oryz=Ktvg0Cm zF>6H^w?Pf~g@3E8!QIPz8z}p&gOyzRGGC0M(ME}S6-XpAnoF}xM7K)Wt^ygqM)yhh zvlNbGBHg*PsiWvPl8JQZ(me6&2O!~0E|nFTNF+a(qFtKNA!<*F7W6T7pb0JL2<6ca zE$C~Ck-u2RKaz>$=Tk{>vzdQW0gY}!#5&Tv7NoIG)X;)FtdMSNK>=1oyIN3`#p(SP z)Sh*wvXbTzI^w=D0SNJrWFq;+w8avNUQ(#hckW77N_$KsJ9ec{E!he8RMwT^ zWx|YDBQt>}x1c$!8?9*J?X)|0^x>TKh6JdyjtT!EMLA9(8Ma8L#&SR52m$7n6NHmhFJ;gxN`wN*FVL2^mgD#cG z%uG40GEquKSWb7hQGKk9>T4!~=8YJlWPlh#qw77lvH>*2LbrMD0Ge(hXx_~R(khAU za)d#2w?w9+gXn#UR7!1!nL+fe*^wTHnL*?bPrX(YgDKhu#oHkHeB7crx{Yjl8?>Me zy0jUkP&9*SRWp=mQyX-D8?;LzGl_%gB@@XA2h*pPOk`#-{b(VPnZe{ABtkNyA3`M( zskGgbx|I!~;Sy>x`XMw+B6ALh()}^f(Hw9n?Xu8&sF|Vkl7$X?_5&TV(3dE-q4ceV zn0GfDMmBRxf}>9ZiQjIR1-vhXpREm$@McG@_jxv))>)_&Xe1qy$aH2jEwmgJJKJcw zLZUELdf#TF>Cz#>XqYbX9%5(G{liRjz4r(^i$1l`7RbiatO`@M9Vj)C_DENQ4mGz+SVCP-xVtD-p)nf0CT$6012I@*lC-)im8gdwgA$YFc5T=X|}Dx%5s8>Zi=3 zd1skcUhxf4=F`s>I^Y|noKNxbrtAaXSY-iiw9q%ciAoK9n6ltcfEUt)38t#O-9%*( zJ!m0cyO~Oo@+O+H4nP;t01Nd1s-vGRG!$qV&6;FtP64`vawePTe4u)|!a`TJo2y(- zTPDl=hiPrQ3zRD;XNswMbGyYrn=EuEWXtJ*h5pd44yfZaQ}eBMmn)5Q$U+~q+e}wc zRL)zNzHis4Tt%BK6!2fGte`^{D)!$_E9r(A^8Od5vHtbSO1gW7X>@|0E7#J8vrJUw z-=wUf(Px|JanJ3_YT99;D*rvoS_+-hEZeTEqe~_7%iGau;q3l$lkD>u{h7WB2UiIxhK!teu)qsnF)d!E^GqVbDz8yz^`MCThv*zM%O z*D%7-i;T^9ml?Ov)yC~W6D+h^%H~<<7K!{9nEmcGUQq6!$rgGHvO8&kM5!=6XN*$r zB>#n`>T3{g6-{cOoAVADc6BSQk}@-;TWMaNkeVsoN{?CnL`t{PzBZbdw$Xg2jpnB& zN|Eq;EB(->sS}h@ zrfe6=wwMlP#V0~)4$O@HRE}5$DTQ8_odsxaKPd;(@OHB~ALhX3)TGa-*%ql*teH-4 zn{%9Qd8ONi|3F>CeXdwgRR=n# zIN1j}ss>x+-b$HlQD7^@Sbd;Gjj@J65A|hQhaZx4X6@a5)i-6YH)*?f0NUb^?qt6U z3{$&HX*o*?rJ?NZz$nm%0^>m+3rq&x6Q}~+7dQv>^}t-vcLNJR{}xyT`gx!hgMAw) zW-*rQy-e*)KL#4)U^DU9A)cUOOgIt4Fe~BcE57xh#{-+G5_CO+aRj+qPySSJH>;%V z;3l<_ItDA*P{cY)sgzzl9VAvm`fZP3>PsrPYtH*gsAZ-I~1 zYIOTt-7N>+&HBJZJ(YUD1n1h|e%j481owev2Y&$nW;x`&!DH${wkw#A!^IyZ=Zzq< z?PUki-pf9hQRc!zJsl0Y!O!&uY+uOaf5(mob5gc?@`kv2jOB##ZO2$?C~jlQkWewJ zMkX*@%Ct~dn^UO??W1x!9uV{uUtcwoEe_pI4?w4vO=$MARU#|pwoIilB(k+SB(im5 zs2iwoy^3yug-muwXt3=VJsKKriz$0UXW3FBMH6kE6;TJ7?7h%5TX*HN(Al=3%J-p4 zR>}U*Zmz9DITot1RYC_xR7G$?cuZYv+e;@xmn(uU1xH9jn5M-xL$PNpx0O>UV;@zJ zXjjN~J!NHFZHuvhe*?lU%DB~5pHgzYTW$49&x{8l7?9CqtCml8)g+!(7*wqCM5K(_a?RL_h}>TcyOcv?@}GyZNHF2!S|xL(-})Ah=089&%oQ?BX{L< z&!WxY-E0=!7yisfxWx(UgT4Iwfae9KUJ$=fgYrPMgDHbSM$+t>|aRNE0kdL zsJ%w*6#dCwq4bI>+IN!w9aTj8sx`3FSFKRa1;1V?mDRQ^>eLK&Wz^7823v`XlWvHH zwWYKrnuE^UqD9(8G6#(9iN2=@PfN6V_4R0Xtx@tfsP9UCO-6|pV;@Ho+G_9zffn0d zrPb=^7WZay0W z%(fQPkenF1E$e1vaU19c^${UuyHZ&tYNqX3bnsy7xK-1t<< zyDP1AE&;7`&IP^PnG%-^orBz;uqHbi* zw?u`xXCQDN9{T=;XFKLP7C06;mN_0_^^U6?D;;Yb|8zK5Mt!&YsTx&SB0m&PwM@=WORZ zXN_~Q^D^f(&Q;EJ&OwYjf9Jf{x!u|1eB8O)`MmQr=bO%Mu8FQ0t~suSu3Fb6t}9%P zuA5yCyPiJB^_uG)*T=5UU0=F%x8EIc=eaRoI3S7th+jnp_Iq|>4o%wM`zqQay>Flr z=0nQpJV`IZw_pl(K|vew4F|(xxQ_PKd~idl+Jyh)GTCrpDIS36Bb*V%-%QvM=jn9b zyfoh5xZYTuSj*nP;gIM$>$)A+b*!^{4L%p)vkaeYtSgG3v->)HI6e>H)3mj5q>cAq znaht{Gl@@Mc~z)lc+K3UHOa-*we=$wFIzOfwt8u@>HU>EHOCnXlZ)q1n!mJZ-E~Kl z)Re_gqPp%>*Mlk+FP&doH-GL@nzZcPrM1;)oRM6#q`Fq9kGN=A^}@O|M#bV&SYzkc zrE3T%b<%o`s-0hrQJOh9uxznR&B^sk=FbDOVsXvVrn(#MRqfJW9^E*RFWLC--1Fxz zoqgu~daA>UMkxZPai9iKBlBq)M&mWiArx;?0t0bC2~@Bg2*ky{xzL71z`zI@*oXjh;ZkQi zv34v+M>Jv-H!+b^{?)^o=i#W1Z+?P)rYJIP?S;{sl=h@J^ORg)uFq(^#gV7Le}9mP zfde%{xmDLR5CTtj6|mWY$Inbu#TV}AGF*rdg+rBTdH~HF9~=uTa-hi+>FFajq;L_q zU`w@5n3+K1P9M@DuKX`MvRD;Ax+6C7b(c(lnEpSvHV;G57ijzwx*3gM_~0=zFKrwJ zKrW7Hq%xmRF%AC0XFY;1_xR>vqZG9Utvm zFv6w<8b=iA!N9=W9Atb%ZVqOx`5%V^9De1axqU^M+qGPjHaawXEx~LYD69-@ zW;PDQ(9&=chBOb+`Czinqnn{b%#+c{ahOK$#O z+bL+vZ&Ps{`wY>+c!S&f5?RD?1Kth=rPNe0)4}9x(r3cn1bF8N0q=8_M+m3+H=`LI3~& delta 18166 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